张延森 vor 2 Jahren
Ursprung
Commit
3c52079af1

+ 1
- 1
src/components/Typography/Title.vue Datei anzeigen

@@ -42,7 +42,7 @@ export default {
42 42
 
43 43
   &.title-stub {
44 44
     border-left: 5px solid #298CF7;
45
-    padding-left: 1em;
45
+    padding-left: 0.6em;
46 46
   }
47 47
 }
48 48
 </style>

+ 115
- 0
src/views/hazard/StatisticAnalysis/charts/classify.vue Datei anzeigen

@@ -0,0 +1,115 @@
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/bar'
15
+// 其他组件
16
+import 'echarts/lib/component/title'
17
+import 'echarts/lib/component/tooltip'
18
+//
19
+import { LinearGradient } from './util'
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
+        xAxis: {
51
+          type: 'category',
52
+        },
53
+        yAxis: {
54
+          type: 'value'
55
+        },
56
+        series: [
57
+          {
58
+            type: 'bar',
59
+            barMaxWidth: 40,
60
+            label: {
61
+              show: true,
62
+              position: 'top',
63
+            },
64
+            itemStyle: {
65
+              color: LinearGradient([{ offset: 0, color: 'rgba(69, 141, 240, 1)' }, { offset: 1, color: 'rgba(69, 141, 240, 0.4)' }])
66
+            },
67
+          }
68
+        ],
69
+      },
70
+      myChart: null,
71
+    }
72
+  },
73
+  mounted() {
74
+    this.$nextTick(() => {
75
+      this.renderChart(this.dataSource)
76
+    })
77
+  },
78
+  beforeDestroy() {
79
+    if (this.myChart) {
80
+      this.myChart.dispose()
81
+      this.myChart = null
82
+    }
83
+  },
84
+  methods: {
85
+    renderChart(source) {
86
+      if (!this.$refs.chart) return;
87
+
88
+      if (!this.myChart) {
89
+        this.myChart = echarts.init(this.$refs.chart, null, {renderer: 'svg'})
90
+      }
91
+
92
+      // const keyProp = this.dimensions[0]
93
+      const valProp = this.dimensions[1]
94
+
95
+      const option = {
96
+        ...this.options,
97
+        tooltip: {
98
+          ...this.options.tooltip,
99
+          formatter: (params) => {
100
+            return `${params.name}: ${params.data[valProp]}个`
101
+          }
102
+        },
103
+        dataset: {
104
+          source,
105
+          dimensions: this.dimensions,
106
+        }
107
+      }
108
+
109
+      console.log(option)
110
+
111
+      this.myChart.setOption(option)
112
+    },
113
+  }
114
+}
115
+</script>

+ 168
- 0
src/views/hazard/StatisticAnalysis/charts/enterprise.vue Datei anzeigen

@@ -0,0 +1,168 @@
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/bar'
15
+// 其他组件
16
+import 'echarts/lib/component/title'
17
+import 'echarts/lib/component/tooltip'
18
+import 'echarts/lib/component/legend'
19
+//
20
+import { LinearGradient } from './util'
21
+
22
+// 默认颜色集合
23
+const colors = [
24
+  LinearGradient([{ offset: 0, color: 'rgba(69, 141, 240, 1)' }, { offset: 1, color: 'rgba(69, 141, 240, 0.4)' }]),
25
+  LinearGradient([{ offset: 0, color: 'rgba(162, 69, 240, 1)' }, { offset: 1, color: 'rgba(162, 69, 240, 0.4)' }]),
26
+  LinearGradient([{ offset: 0, color: 'rgba(161, 240, 75, 1)' }, { offset: 1, color: 'rgba(161, 240, 75, 0.4)' }]),
27
+  LinearGradient([{ offset: 0, color: 'rgba(241, 186, 70, 1)' }, { offset: 1, color: 'rgba(241, 186, 70, 0.4)' }]),
28
+  LinearGradient([{ offset: 0, color: 'rgba(246, 151, 151, 1)' }, { offset: 1, color: 'rgba(246, 151, 151, 0.4)' }]),
29
+]
30
+
31
+export default {
32
+  name: 'StatisticEnterprise',
33
+  components: {
34
+    Title: () => import('@/components/Typography/Title.vue'),
35
+  },
36
+  props: {
37
+    dimensions: {
38
+      type: Array,
39
+      default: () => (['label', 'value'])
40
+    },
41
+    dataSource: {
42
+      type: Array,
43
+      default: () => ([])
44
+    }
45
+  },
46
+  watch: {
47
+    dataSource: {
48
+      handler(val) {
49
+        this.renderChart(val)
50
+      },
51
+      immediate: true
52
+    }
53
+  },
54
+  data() {
55
+    return {
56
+      options: {
57
+        title: {
58
+          subtext: '单位: 个',
59
+        },
60
+        legend: {
61
+          right: '5%',
62
+        },
63
+        tooltip: {
64
+          trigger: 'axis',
65
+          backgroundColor: '#ffffff',
66
+          formatter: (params) => {
67
+            if (!params || !params.length) return '';
68
+
69
+            let htmlStr = `<div style="text-align: left">${params[0].name}</div>`
70
+            htmlStr += params.map((item) => {
71
+              const color = item.color.colorStops[0].color
72
+              const seriesName = item.seriesName
73
+              const value = item.value[seriesName]
74
+
75
+              return `
76
+                <div style="display: flex; justify-content: space-between; align-items: center">
77
+                  <div style="flex: 1;">
78
+                    <span style="display: inline-block; width: 0.8em; height: 0.8em; background-color: ${color};"></span>
79
+                    <span style="display: inline-block; margin-left: 0.8em">${seriesName}</span>
80
+                  </div>
81
+                  <div style="flex: 1; margin-left: 1em">${value}个</div>
82
+                </div>
83
+              `
84
+            }).join('')
85
+          
86
+            return `<div style="box-sizing: border-box; padding: 0.6em 1em">${htmlStr}</div>`;
87
+          },
88
+          textStyle: {
89
+            color: '#333',
90
+            lineHeight: 28,
91
+          },
92
+          extraCssText: 'box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);',
93
+          axisPointer: {
94
+            type: 'shadow',
95
+            shadowStyle: {
96
+              color: LinearGradient([{ offset: 0, color: 'rgba(153, 205, 255, 0.2)' }, { offset: 1, color: 'rgba(153, 205, 255, 0.05)' }]),
97
+            }
98
+          }
99
+        },
100
+        xAxis: {
101
+          type: 'category',
102
+        },
103
+        yAxis: {
104
+          type: 'value'
105
+        },
106
+        series: [
107
+          {
108
+            type: 'bar',
109
+            barMaxWidth: 40,
110
+            itemStyle: {
111
+              color: LinearGradient([{ offset: 0, color: 'rgba(69, 141, 240, 1)' }, { offset: 1, color: 'rgba(69, 141, 240, 0.4)' }])
112
+            },
113
+          }
114
+        ],
115
+      },
116
+      myChart: null,
117
+    }
118
+  },
119
+  mounted() {
120
+    this.$nextTick(() => {
121
+      this.renderChart(this.dataSource)
122
+    })
123
+  },
124
+  beforeDestroy() {
125
+    if (this.myChart) {
126
+      this.myChart.dispose()
127
+      this.myChart = null
128
+    }
129
+  },
130
+  methods: {
131
+    renderChart(source) {
132
+      if (!this.$refs.chart) return;
133
+
134
+      if (!this.myChart) {
135
+        this.myChart = echarts.init(this.$refs.chart, null, {renderer: 'svg'})
136
+      }
137
+
138
+      // const keyProp = this.dimensions[0]
139
+      // const valProp = this.dimensions[1]
140
+
141
+      const option = {
142
+        ...this.options,
143
+        // tooltip: {
144
+        //   ...this.options.tooltip,
145
+        //   formatter: (params) => {
146
+        //     return `${params.name}: ${params.data[valProp]}个`
147
+        //   }
148
+        // },
149
+        dataset: {
150
+          source,
151
+          dimensions: this.dimensions,
152
+        },
153
+        series: source.map((item, index) => ({
154
+            type: 'bar',
155
+            barMaxWidth: 25,
156
+            itemStyle: {
157
+              color: colors[index % colors.length]
158
+            },
159
+        }))
160
+      }
161
+
162
+      console.log(option)
163
+
164
+      this.myChart.setOption(option)
165
+    },
166
+  }
167
+}
168
+</script>

src/views/hazard/StatisticAnalysis/charts/classification.vue → src/views/hazard/StatisticAnalysis/charts/grading.vue Datei anzeigen

@@ -19,7 +19,7 @@ import 'echarts/lib/component/legend'
19 19
 
20 20
 
21 21
 export default {
22
-  name: 'StatisticClassification',
22
+  name: 'StatisticGrading',
23 23
   components: {
24 24
     Title: () => import('@/components/Typography/Title.vue'),
25 25
   },
@@ -44,6 +44,7 @@ export default {
44 44
   data() {
45 45
     return {
46 46
       options: {
47
+        color: ['#F69A9A', '#FDE174', '#88DCA1', '#60B2FF', '#A647F0', '#A1EF4E'],
47 48
         title: {
48 49
           subtext: '单位: 个',
49 50
         },

+ 8
- 0
src/views/hazard/StatisticAnalysis/charts/util.js Datei anzeigen

@@ -0,0 +1,8 @@
1
+import echarts from 'echarts/lib/echarts'
2
+
3
+// 获取渐变色, 默认竖向
4
+export function LinearGradient(colorStops, pos = {}, globalCoord = false) {
5
+  const { x = 0, y = 0, x2 = 0, y2 = 1 } = pos
6
+
7
+  return new echarts.graphic.LinearGradient(x, y, x2, y2, colorStops, globalCoord)
8
+}

+ 20
- 5
src/views/hazard/StatisticAnalysis/index.vue Datei anzeigen

@@ -3,13 +3,13 @@
3 3
     <el-card></el-card>
4 4
     <el-row :gutter="48">
5 5
       <el-col :span="12">
6
-        <StatisticClassification :data-source="classificationData" />
6
+        <StatisticGrading :data-source="gradingData" />
7 7
       </el-col>
8 8
       <el-col :span="12">
9
-        <el-card></el-card>
9
+        <StatisticClassify :data-source="classifyData" />
10 10
       </el-col>
11 11
     </el-row>
12
-    <el-card></el-card>    
12
+    <StatisticEnterprise :data-source="enterpriseData" :dimensions="enterpriseDimensions" />    
13 13
   </div>
14 14
 </template>
15 15
 
@@ -17,16 +17,31 @@
17 17
 export default {
18 18
   name: 'StatisticAnalysis',
19 19
   components: {
20
-    StatisticClassification: () => import('./charts/classification.vue'),
20
+    StatisticGrading: () => import('./charts/grading.vue'),
21
+    StatisticClassify: () => import('./charts/classify.vue'),
22
+    StatisticEnterprise: () => import('./charts/enterprise.vue'),
21 23
   },
22 24
   data() {
23 25
     return {
24
-      classificationData: [
26
+      gradingData: [
25 27
         { label: '一级', value: 16 },
26 28
         { label: '二级', value: 17 },
27 29
         { label: '三级', value: 18 },
28 30
         { label: '四级', value: 49 },
29 31
       ],
32
+      classifyData: [
33
+        { label: '储罐区', value: 100 },
34
+        { label: '生产装置', value: 260 },
35
+        { label: '油气管道', value: 700 },
36
+        { label: '压力容器', value: 1000 },
37
+      ],
38
+      enterpriseDimensions: ['name', '储罐区', '生产装置', '油气管道', '压力容器'],
39
+      enterpriseData: [
40
+        { name: '分公司1', '储罐区': 100, '生产装置': 520, '油气管道': 250, '压力容器': 780 },
41
+        { name: '分公司2', '储罐区': 100, '生产装置': 520, '油气管道': 250, '压力容器': 780 },
42
+        { name: '分公司3', '储罐区': 100, '生产装置': 520, '油气管道': 250, '压力容器': 780 },
43
+        { name: '分公司4', '储罐区': 100, '生产装置': 520, '油气管道': 250, '压力容器': 780 },
44
+      ]
30 45
     }
31 46
   }
32 47
 }