张延森 5 年之前
父節點
當前提交
ed98952b82
共有 2 個文件被更改,包括 130 次插入125 次删除
  1. 124
    121
      src/components/charts/Line.js
  2. 6
    4
      src/pages/person/customerAnalysis/analysis.js

+ 124
- 121
src/components/charts/Line.js 查看文件

@@ -2,19 +2,115 @@ import Taro, { Component } from '@tarojs/taro'
2 2
 import echarts from '../ec-canvas/echarts'
3 3
 import './style.scss'
4 4
 
5
-function initChart(callback, options) {
5
+function initChart(options, callback) {
6 6
   return function (canvas, width, height) {
7 7
     const chart = echarts.init(canvas, null, {
8 8
       width: width,
9 9
       height: height
10 10
     });
11 11
     canvas.setChart(chart);
12
-    chart.setOption(options);
12
+    chart.setOption(options);    
13 13
     callback && callback(chart);
14 14
     return chart;
15 15
   }
16 16
 }
17 17
 
18
+function createLineOptions(source = []) {
19
+  const colorWithOpacity = op => `rgba(187,156,121, ${op})`
20
+
21
+  const defaultOpt = {
22
+    color: [colorWithOpacity(1)],
23
+    xAxis: {
24
+      type: 'category',
25
+      boundaryGap: false,
26
+      axisLabel: {
27
+        textStyle: {
28
+          color: '#666'
29
+        }
30
+      }
31
+
32
+    },
33
+    yAxis: {
34
+      type: 'value',
35
+      axisLabel: {
36
+        textStyle: {
37
+          color: '#666'
38
+        }
39
+      }
40
+    },
41
+    grid: {
42
+      left: '10%',
43
+      right: '8%',
44
+      bottom: '12%',
45
+      top: '10%',
46
+    },
47
+    series: [],
48
+  }
49
+
50
+  // 数据展示只展示 5 个
51
+  const endValue = source.length - 1 > 0 ? source.length - 1 : 0
52
+  const startValue = endValue - 5 > 0 ? endValue - 5 : 0
53
+
54
+  return {
55
+    ...defaultOpt,
56
+    dataset: { source },
57
+    dataZoom: [{
58
+      type: 'slider',
59
+      startValue, endValue,
60
+      show: true,
61
+      xAxisIndex: [0],
62
+      handleSize: 10,//滑动条的 左右2个滑动条的大小  
63
+      height: 20,//组件高度  
64
+      left: 30, //左边的距离  
65
+      right: 30,//右边的距离  
66
+      bottom: 0,//下边的距离  
67
+      handleColor: 'rgba(0,0,0,0.1)',//h滑动图标的颜色  
68
+      realtime : true,
69
+      handleStyle: {
70
+        borderColor: "#999",
71
+        borderWidth: "1",
72
+        shadowBlur: 2,
73
+        background: "rgba(0,0,0,0.1)",
74
+        shadowColor: "rgba(0,0,0,0.1)",
75
+      },
76
+      backgroundColor: 'rgba(0,0,0,0.1)',//两边未选中的滑动条区域的颜色  
77
+      showDataShadow: false,//是否显示数据阴影 默认auto  
78
+      showDetail: false,
79
+
80
+    }],
81
+    series: [{
82
+      type: 'line',
83
+      dimensions: ['name', 'value'],
84
+      symbolSize: 6,
85
+      smooth: true,
86
+      label: {
87
+        show: true,
88
+        formatter: '{@value}人'
89
+      },
90
+      lineStyle: {
91
+        shadowColor: colorWithOpacity(0.5),
92
+        shadowBlur: 5,
93
+        shadowOffsetY: 7
94
+      },
95
+      areaStyle: {
96
+        color: {
97
+          type: 'linear',
98
+          x: 0,
99
+          y: 0,
100
+          x2: 0,
101
+          y2: 1,
102
+          colorStops: [{
103
+            offset: 0, color: colorWithOpacity(0.2) // 0% 处的颜色
104
+          }, {
105
+            offset: 1, color: colorWithOpacity(0) // 100% 处的颜色
106
+          }],
107
+          global: false,
108
+        }
109
+      },
110
+    }],
111
+  }
112
+}
113
+
18 114
 /**
19 115
  * 传入 source 的格式为 [{ name: xxx, value: xxx }, {}]
20 116
  */
@@ -25,148 +121,55 @@ export default class LineChart extends Component {
25 121
     }
26 122
   }
27 123
 
28
-  // this.echart
29
-  echart = null
124
+  // this.ecComponent
125
+  chart = null;
30 126
   ecComponent = null
31 127
 
32 128
   state = {
33 129
     ec: { lazyLoad: true },
130
+    isDisposed: false,
34 131
   }
35 132
 
36
-  // 禁止 props 变更时渲染
37
-  shouldComponentUpdate(nextProps) {
38
-    console.log('--nextProps--->', nextProps)
39
-
40
-    this.refreshChart(nextProps.source)
41
-
42
-    return false
133
+  componentDidShow() {
134
+    this.setState({ isDisposed: false })
43 135
   }
44 136
 
45
-  handleEcComponent(ref) {
46
-    this.ecComponent = ref
137
+  componentDidHide() {
138
+    this.setState({ isDisposed: true })
47 139
   }
48 140
 
49
-  handleChart(chart) {
50
-    this.echart = chart
141
+  componentDidMount() {
142
+    this.ecComponent = this.$scope.selectComponent(`#${this.props.lid}`)
143
+    this.init(this.props)
51 144
   }
52 145
 
53
-  createOptions(source = []) {
54
-    const colorWithOpacity = op => `rgba(187,156,121, ${op})`
55
-
56
-    const defaultOpt = {
57
-      color: [colorWithOpacity(1)],
58
-      xAxis: {
59
-        type: 'category',
60
-        boundaryGap: false,
61
-        axisLabel: {
62
-          textStyle: {
63
-            color: '#666'
64
-          }
65
-        }
146
+  componentWillReceiveProps(nextProps) {
147
+    // 简单优化, 不显示的组件不更新
148
+    // 但是有个 bug 。如果此时有 props 更新, 会导致页面绘制的数据错误
149
+    if (this.state.isDisposed) return
66 150
 
67
-      },
68
-      yAxis: {
69
-        type: 'value',
70
-        axisLabel: {
71
-          textStyle: {
72
-            color: '#666'
73
-          }
74
-        }
75
-      },
76
-      grid: {
77
-        left: '10%',
78
-        right: '8%',
79
-        bottom: '12%',
80
-        top: '10%',
81
-      },
82
-      series: [],
83
-    }
84
-
85
-    // 数据展示只展示 5 个
86
-    const endValue = source.length - 1 > 0 ? source.length - 1 : 0
87
-    const startValue = endValue - 5 > 0 ? endValue - 5 : 0
88
-
89
-    return {
90
-      ...defaultOpt,
91
-      dataset: { source },
92
-      dataZoom: [{
93
-        type: 'slider',
94
-        startValue, endValue,
95
-        show: true,
96
-        xAxisIndex: [0],
97
-        handleSize: 10,//滑动条的 左右2个滑动条的大小  
98
-        height: 20,//组件高度  
99
-        left: 30, //左边的距离  
100
-        right: 30,//右边的距离  
101
-        bottom: 0,//下边的距离  
102
-        handleColor: 'rgba(0,0,0,0.1)',//h滑动图标的颜色  
103
-        realtime : true,
104
-        handleStyle: {
105
-          borderColor: "#999",
106
-          borderWidth: "1",
107
-          shadowBlur: 2,
108
-          background: "rgba(0,0,0,0.1)",
109
-          shadowColor: "rgba(0,0,0,0.1)",
110
-        },
111
-        backgroundColor: 'rgba(0,0,0,0.1)',//两边未选中的滑动条区域的颜色  
112
-        showDataShadow: false,//是否显示数据阴影 默认auto  
113
-        showDetail: false,
114
-
115
-      }],
116
-      series: [{
117
-        type: 'line',
118
-        dimensions: ['name', 'value'],
119
-        symbolSize: 6,
120
-        smooth: true,
121
-        label: {
122
-          show: true,
123
-          formatter: '{@value}人'
124
-        },
125
-        lineStyle: {
126
-          shadowColor: colorWithOpacity(0.5),
127
-          shadowBlur: 5,
128
-          shadowOffsetY: 7
129
-        },
130
-        areaStyle: {
131
-          color: {
132
-            type: 'linear',
133
-            x: 0,
134
-            y: 0,
135
-            x2: 0,
136
-            y2: 1,
137
-            colorStops: [{
138
-              offset: 0, color: colorWithOpacity(0.2) // 0% 处的颜色
139
-            }, {
140
-              offset: 1, color: colorWithOpacity(0) // 100% 处的颜色
141
-            }],
142
-            global: false,
143
-          }
144
-        },
145
-      }],
151
+    // 简单的性能优化, 只有数据改变了才重新绘图
152
+    if (JSON.stringify(nextProps.source) != JSON.stringify(this.props.source)) {
153
+      this.init(nextProps)
146 154
     }
147 155
   }
148 156
 
149
-  refreshChart(source) {
150
-    const options = this.createOptions(source)
151
-
152
-    if (!this.echart) {
153
-      if (this.ecComponent) {
154
-        const initFunc = initChart(this.handleChart.bind(this), options)
155
-        this.ecComponent.init(initFunc)
156
-      } else {
157
-        console.warn('echart componet not ready')
157
+  init = (props) => {
158
+    const tk = setTimeout(() => {
159
+      if (this.ecComponent && props.source && props.source.length) {
160
+        const options = createLineOptions(props.source)
161
+        this.ecComponent.init(initChart(options, chart => (this.chart = chart)))
158 162
       }
159
-    } else {
160
-      this.echart.setOption(options)
161
-    }
163
+
164
+      clearTimeout(tk)
165
+    }, 500)
162 166
   }
163 167
 
164 168
   render() {
165
-    // this.refreshChart(this.props.source)
166 169
     return (
167 170
       <View style="width:100vw;height:480rpx;position: relative;">
168 171
         <View className="map-container">
169
-          <ec-canvas ref={this.handleEcComponent} ec={this.state.ec}></ec-canvas>
172
+          <ec-canvas id={this.props.lid} ec={this.state.ec}></ec-canvas>
170 173
         </View>
171 174
       </View>
172 175
     )

+ 6
- 4
src/pages/person/customerAnalysis/analysis.js 查看文件

@@ -12,6 +12,7 @@ import { connect } from '@tarojs/redux'
12 12
 import LineChart from "../../../components/charts/Line";
13 13
 const nothing = require('@assets/person/nothing.png')
14 14
 
15
+const rand = n => Math.random().toString(36).substr(2, n)
15 16
 
16 17
 @connect(({ user, city }) => ({ user, city }))
17 18
 export default class analysis extends Taro.Component {
@@ -28,6 +29,7 @@ export default class analysis extends Taro.Component {
28 29
     chartInfo: [],
29 30
     chartInfo2: [],
30 31
     chartInfo3: [],
32
+    lineIds: [ rand(7), rand(7), rand(7) ],
31 33
   }
32 34
 
33 35
   componentWillUnmount() {
@@ -160,7 +162,7 @@ export default class analysis extends Taro.Component {
160 162
 
161 163
     const tabList = [{ title: '新增客户' }, { title: '跟进客户' }, { title: '到访客户' }]
162 164
     const dailyMonth = ['日', '月']
163
-    const { sexInfo, chartInfo, chartInfo2, chartInfo3, checkedWhich, current } = this.state
165
+    const { sexInfo, chartInfo, chartInfo2, chartInfo3, checkedWhich, current, lineIds } = this.state
164 166
 
165 167
     return (
166 168
       <View>
@@ -179,7 +181,7 @@ export default class analysis extends Taro.Component {
179 181
               </View>
180 182
               {
181 183
                 chartInfo.length &&
182
-                <LineChart source={chartInfo} />
184
+                <LineChart source={chartInfo} lid={lineIds[0]} />
183 185
               }
184 186
               {
185 187
                 !chartInfo.length &&
@@ -218,7 +220,7 @@ export default class analysis extends Taro.Component {
218 220
                 </View>
219 221
               </View>
220 222
               {chartInfo2.length &&
221
-                <LineChart source={chartInfo2} />
223
+                <LineChart source={chartInfo2} lid={lineIds[1]}/>
222 224
               }
223 225
               {
224 226
                 !chartInfo2.length &&
@@ -258,7 +260,7 @@ export default class analysis extends Taro.Component {
258 260
               </View>
259 261
               {
260 262
                 chartInfo3.length &&
261
-                <LineChart source={chartInfo3} />
263
+                <LineChart source={chartInfo3} lid={lineIds[2]} />
262 264
               }
263 265
               {
264 266
                 !chartInfo3.length &&