WXL
4 天以前 4c9fdc87987140e8b2c3f0dfc2f6608cdb6be774
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
<!-- G2Plot 通用图表包装组件(Vue 2 兼容) -->
<template>
  <div ref="container" class="g2plot-chart" :style="{ height: height + 'px', width: '100%' }"></div>
</template>
 
<script>
import { Line, Area, Column, Bar, Pie, Ring, Gauge } from '@antv/g2plot';
 
const PLOTS = {
  line: Line,
  area: Area,
  column: Column,
  bar: Bar,
  pie: Pie,
  ring: Ring,
  gauge: Gauge
};
 
export default {
  name: 'G2PlotChart',
  props: {
    // 图表类型:line / area / column / bar / pie / ring / gauge
    type: {
      type: String,
      required: true
    },
    // G2Plot 配置对象(含 data)
    options: {
      type: Object,
      required: true
    },
    height: {
      type: [String, Number],
      default: 280
    }
  },
  data() {
    return {
      plot: null,
      key: ''
    };
  },
  watch: {
    options: {
      deep: true,
      handler(val) {
        const key = JSON.stringify(val || {});
        if (key !== this.key) {
          this.key = key;
          this.$nextTick(() => this.render());
        }
      }
    },
    type() {
      this.render();
    }
  },
  mounted() {
    this.render();
    window.addEventListener('resize', this.handleResize);
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.handleResize);
    this.destroy();
  },
  methods: {
    render() {
      if (!this.$refs.container) return;
      const data = (this.options && this.options.data) || [];
      // 仪表盘等百分比类图表没有 data,只有 percent;两者皆无时不渲染,避免 G2Plot 抛异常
      const hasPercent =
        this.options && typeof this.options.percent === 'number';
      if (!data.length && !hasPercent) {
        this.destroy();
        return;
      }
      const Ctor = PLOTS[this.type];
      if (!Ctor) {
        console.warn('[G2PlotChart] 未知图表类型:', this.type);
        return;
      }
      this.destroy();
      this.plot = new Ctor(this.$refs.container, this.options);
      this.plot.render();
    },
    destroy() {
      if (this.plot) {
        try {
          this.plot.destroy();
        } catch (e) {
          // ignore
        }
        this.plot = null;
      }
    },
    handleResize() {
      if (this.plot && this.$refs.container) {
        this.plot.changeSize(
          this.$refs.container.clientWidth,
          this.$refs.container.clientHeight
        );
      }
    }
  }
};
</script>
 
<style scoped>
.g2plot-chart {
  position: relative;
}
</style>