张延森 2 anos atrás
pai
commit
cc03cb361d

+ 1
- 0
package.json Ver arquivo

@@ -9,6 +9,7 @@
9 9
   },
10 10
   "dependencies": {
11 11
     "core-js": "^3.8.3",
12
+    "echarts": "4.7.0",
12 13
     "element-ui": "^2.15.9",
13 14
     "sass": "^1.53.0",
14 15
     "vue": "^2.6.14",

+ 48
- 0
src/components/Typography/Title.vue Ver arquivo

@@ -0,0 +1,48 @@
1
+<template>
2
+  <div :class="['typography-title', { 'title-stub' : stub }]">
3
+    <slot></slot>
4
+  </div>
5
+</template>
6
+
7
+<script>
8
+
9
+export default {
10
+  name: 'Title',
11
+  props: {
12
+    stub: {
13
+      type: Boolean,
14
+      default: true,
15
+    },
16
+    size: {
17
+      type: String,
18
+      default: '18px'
19
+    },
20
+    color: {
21
+      type: String,
22
+      default: '#333',
23
+    }
24
+  },
25
+  computed: {
26
+    cmpStyle () {
27
+      return {
28
+        fontSize: this.size,
29
+        color: this.color,
30
+      }
31
+    },
32
+  }
33
+}
34
+</script>
35
+
36
+<style lang="scss" scoped>
37
+.typography-title {
38
+  box-sizing: border-box;
39
+  font-weight: bold;
40
+  letter-spacing: 1.2px;
41
+  text-align: left;
42
+
43
+  &.title-stub {
44
+    border-left: 5px solid #298CF7;
45
+    padding-left: 1em;
46
+  }
47
+}
48
+</style>

+ 151
- 0
src/views/hazard/StatisticAnalysis/charts/classification.vue Ver arquivo

@@ -0,0 +1,151 @@
1
+<template>
2
+  <el-card>
3
+    <Title>分级统计</Title>
4
+    <div ref="chart" class="chart-div"></div>
5
+  </el-card>
6
+</template>
7
+
8
+<script>
9
+// 主模块
10
+import echarts from 'echarts/lib/echarts'
11
+// 引入 svg 主要解决文字锯齿问题, zrender 为 echart 底层
12
+import 'zrender/lib/svg/svg'
13
+// 饼图
14
+import 'echarts/lib/chart/pie'
15
+// 其他组件
16
+import 'echarts/lib/component/title'
17
+import 'echarts/lib/component/tooltip'
18
+import 'echarts/lib/component/legend'
19
+
20
+
21
+export default {
22
+  name: 'StatisticClassification',
23
+  components: {
24
+    Title: () => import('@/components/Typography/Title.vue'),
25
+  },
26
+  props: {
27
+    dimensions: {
28
+      type: Array,
29
+      default: () => (['label', 'value'])
30
+    },
31
+    dataSource: {
32
+      type: Array,
33
+      default: () => ([])
34
+    }
35
+  },
36
+  watch: {
37
+    dataSource: {
38
+      handler(val) {
39
+        this.renderChart(val)
40
+      },
41
+      immediate: true
42
+    }
43
+  },
44
+  data() {
45
+    return {
46
+      options: {
47
+        title: {
48
+          subtext: '单位: 个',
49
+        },
50
+        tooltip: {
51
+          trigger: 'item',
52
+        },
53
+        legend: {
54
+          orient: 'vertical',
55
+          bottom: '5%',
56
+          right: '5%'
57
+        },
58
+        series: [
59
+          {
60
+            type: 'pie',
61
+            radius: ['40%', '70%'],
62
+            label: {
63
+              normal: {
64
+                show: true,
65
+                position: 'center',
66
+                color:'#454c5c',
67
+                padding: [0, 0, 20, 0],  //设置字angular的边距
68
+                fontSize: 24,
69
+              },
70
+            },
71
+            labelLine: {
72
+              show: false
73
+            },
74
+          }
75
+        ],
76
+      },
77
+      myChart: null,
78
+    }
79
+  },
80
+  mounted() {
81
+    this.$nextTick(() => {
82
+      this.renderChart(this.dataSource)
83
+    })
84
+  },
85
+  beforeDestroy() {
86
+    if (this.myChart) {
87
+      this.myChart.dispose()
88
+      this.myChart = null
89
+    }
90
+  },
91
+  methods: {
92
+    renderChart(source) {
93
+      if (!this.$refs.chart) return;
94
+
95
+      if (!this.myChart) {
96
+        this.myChart = echarts.init(this.$refs.chart, null, {renderer: 'svg'})
97
+      }
98
+
99
+      const keyProp = this.dimensions[0]
100
+      const valProp = this.dimensions[1]
101
+
102
+      const total = source.reduce((acc, item) => acc + item[valProp], 0)
103
+      const legendData = source.reduce((acc, item) => {
104
+        const name = item[keyProp]
105
+        const value = item[valProp]
106
+        const percent = total > 0 ? value * 100 / total : 0
107
+
108
+        return {
109
+          ...acc,
110
+          [name]: `  ${name}  ${value}个  ${percent}%`
111
+        }
112
+      }, {})
113
+
114
+      const first = this.options.series[0]
115
+      const option = {
116
+        ...this.options,
117
+        tooltip: {
118
+          ...this.options.tooltip,
119
+          formatter: (params) => {
120
+            return `${params.name}: ${params.data[valProp]}个`
121
+          }
122
+        },
123
+        series: [
124
+          {
125
+            ...first,
126
+            label: {
127
+              ...first.label,
128
+              normal: {
129
+                ...first.label.normal,
130
+                formatter: `${total} 个`
131
+              }
132
+            }
133
+          }
134
+        ],
135
+        legend: {
136
+          ...this.options.legend,
137
+          formatter: name => legendData[name],
138
+        },
139
+        dataset: {
140
+          source,
141
+          dimensions: this.dimensions,
142
+        }
143
+      }
144
+
145
+      console.log(option)
146
+
147
+      this.myChart.setOption(option)
148
+    },
149
+  }
150
+}
151
+</script>

+ 44
- 2
src/views/hazard/StatisticAnalysis/index.vue Ver arquivo

@@ -1,3 +1,45 @@
1 1
 <template>
2
-  <div>统计分析</div>
3
-</template>
2
+  <div class="statistic-analysis-page">
3
+    <el-card></el-card>
4
+    <el-row :gutter="48">
5
+      <el-col :span="12">
6
+        <StatisticClassification :data-source="classificationData" />
7
+      </el-col>
8
+      <el-col :span="12">
9
+        <el-card></el-card>
10
+      </el-col>
11
+    </el-row>
12
+    <el-card></el-card>    
13
+  </div>
14
+</template>
15
+
16
+<script>
17
+export default {
18
+  name: 'StatisticAnalysis',
19
+  components: {
20
+    StatisticClassification: () => import('./charts/classification.vue'),
21
+  },
22
+  data() {
23
+    return {
24
+      classificationData: [
25
+        { label: '一级', value: 16 },
26
+        { label: '二级', value: 17 },
27
+        { label: '三级', value: 18 },
28
+        { label: '四级', value: 49 },
29
+      ],
30
+    }
31
+  }
32
+}
33
+</script>
34
+
35
+<style lang="scss">
36
+.statistic-analysis-page {
37
+  & > div + div {
38
+    margin-top: 2em;
39
+  }
40
+
41
+  .chart-div {
42
+    min-height: 360px;
43
+  }
44
+}
45
+</style>

+ 12
- 0
yarn.lock Ver arquivo

@@ -2725,6 +2725,13 @@ easy-stack@1.0.1:
2725 2725
   resolved "https://registry.npmmirror.com/easy-stack/-/easy-stack-1.0.1.tgz#8afe4264626988cabb11f3c704ccd0c835411066"
2726 2726
   integrity sha512-wK2sCs4feiiJeFXn3zvY0p41mdU5VUgbgs1rNsc/y5ngFUijdWd+iIN8eoyuZHKB8xN6BL4PdWmzqFmxNg6V2w==
2727 2727
 
2728
+echarts@4.7.0:
2729
+  version "4.7.0"
2730
+  resolved "https://registry.npmmirror.com/echarts/-/echarts-4.7.0.tgz#5b3875a4c2f91e3929425fabab9eace7e4098b3f"
2731
+  integrity sha512-NlOTdUcAsIyCCG+N4uh0ZEvXtrPW2jvcuqf03RyqYeCKzyPbiOQ4I3MdKXMhxG3lBdqQNdNXVT71SB4KTQjN0A==
2732
+  dependencies:
2733
+    zrender "4.3.0"
2734
+
2728 2735
 ee-first@1.1.1:
2729 2736
   version "1.1.1"
2730 2737
   resolved "https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
@@ -6082,3 +6089,8 @@ yorkie@^2.0.0:
6082 6089
     is-ci "^1.0.10"
6083 6090
     normalize-path "^1.0.0"
6084 6091
     strip-indent "^2.0.0"
6092
+
6093
+zrender@4.3.0:
6094
+  version "4.3.0"
6095
+  resolved "https://registry.npmmirror.com/zrender/-/zrender-4.3.0.tgz#9f056121b20bbae44414d287bf6a119ff7042661"
6096
+  integrity sha512-Dii6j2bDsPkxQayuVf2DXJeruIB/mKVxxcGRZQ9GExiBd4c3w7+oBuvo1O/JGHeFeA1nCmSDVDs/S7yKZG1nrA==