Commit 320f15b626d931c7763b3051660d7edb508b0caf
1 parent
4d78bfbd
perf(src/packages): 优化图表和联动组件进行交互,图表不及时更新
Showing
2 changed files
with
100 additions
and
34 deletions
... | ... | @@ -29,8 +29,11 @@ import { useChartDataFetch } from '@/hooks' |
29 | 29 | import { isPreview } from '@/utils' |
30 | 30 | import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components' |
31 | 31 | import isObject from 'lodash/isObject' |
32 | +import cloneDeep from 'lodash/cloneDeep' | |
32 | 33 | import dataJson from './data.json' |
33 | 34 | import { useFullScreen } from '../../utls/fullScreen' |
35 | +import { useAssembleDataHooks } from '@/hooks/external/useAssembleData.hook' | |
36 | +import { SocketReceiveMessageType } from '@/store/external/modules/socketStore.d' | |
34 | 37 | |
35 | 38 | const props = defineProps({ |
36 | 39 | themeSetting: { |
... | ... | @@ -87,11 +90,24 @@ watch( |
87 | 90 | if (!isObject(newData) || !('dimensions' in newData)) return |
88 | 91 | if (Array.isArray(newData?.dimensions)) { |
89 | 92 | const seriesArr = [] |
90 | - for (let i = 0; i < newData.dimensions.length - 1; i++) { | |
91 | - seriesArr.push(seriesItem) | |
93 | + // 对oldData进行判断,防止传入错误数据之后对旧维度判断产生干扰 | |
94 | + // 此处计算的是dimensions的Y轴维度,若是dimensions.length为0或1,则默认为1,排除X轴维度干扰 | |
95 | + const oldDimensions = | |
96 | + Array.isArray(oldData?.dimensions) && oldData.dimensions.length >= 1 ? oldData.dimensions.length : 1 | |
97 | + const newDimensions = newData.dimensions.length >= 1 ? newData.dimensions.length : 1 | |
98 | + const dimensionsGap = newDimensions - oldDimensions | |
99 | + if (dimensionsGap < 0) { | |
100 | + props.chartConfig.option.series.splice(newDimensions - 1) | |
101 | + } else if (dimensionsGap > 0) { | |
102 | + if (!oldData || !oldData?.dimensions || !Array.isArray(oldData?.dimensions) || !oldData?.dimensions.length) { | |
103 | + props.chartConfig.option.series = [] | |
104 | + } | |
105 | + for (let i = 0; i < dimensionsGap; i++) { | |
106 | + seriesArr.push(cloneDeep(seriesItem)) | |
107 | + } | |
108 | + props.chartConfig.option.series.push(...seriesArr) | |
92 | 109 | } |
93 | 110 | replaceMergeArr.value = ['series'] |
94 | - props.chartConfig.option.series = seriesArr | |
95 | 111 | nextTick(() => { |
96 | 112 | replaceMergeArr.value = [] |
97 | 113 | }) |
... | ... | @@ -178,17 +194,38 @@ watch( |
178 | 194 | ) |
179 | 195 | |
180 | 196 | //fix 修复v-chart图表绑定联动组件视图不更新问题 |
181 | -const updateVChart = (newData: any) => { | |
182 | - if (!newData) return | |
183 | - vChartRef.value?.clear() | |
184 | - vChartRef.value?.setOption({ | |
185 | - ...option.value, | |
186 | - dataset: newData | |
187 | - }) | |
197 | +const updateVChart = (newData:SocketReceiveMessageType) => { | |
198 | + //区分是普通请求还是ws请求 | |
199 | + if (!isObject(newData) || !('dimensions' in newData)) { | |
200 | + const { data } = newData | |
201 | + const { keys, record } = useAssembleDataHooks(data) | |
202 | + vChartRef.value?.setOption({ | |
203 | + dataset: { | |
204 | + dimensions: ['ts', ...keys], | |
205 | + source: [record] | |
206 | + } | |
207 | + }) | |
208 | + } else { | |
209 | + //异步更新,同步更新会造成联动组件控制,图表不及时更新 | |
210 | + new Promise((resolve) => { | |
211 | + setTimeout(() => { | |
212 | + resolve( | |
213 | + vChartRef.value?.setOption( | |
214 | + { | |
215 | + ...option.value, | |
216 | + dataset: newData | |
217 | + }, | |
218 | + { | |
219 | + notMerge: true | |
220 | + } | |
221 | + ) | |
222 | + ) | |
223 | + }, 100) | |
224 | + }) | |
225 | + } | |
188 | 226 | } |
189 | 227 | |
190 | 228 | const {vChartRef} = useChartDataFetch(props.chartConfig, useChartEditStore, (newData) => { |
191 | - // addPieInterval(newData) | |
192 | 229 | updateVChart(newData) |
193 | 230 | }) |
194 | 231 | ... | ... |
... | ... | @@ -15,7 +15,7 @@ |
15 | 15 | </template> |
16 | 16 | |
17 | 17 | <script setup lang="ts"> |
18 | -import { reactive, watch, PropType, onMounted, ref, nextTick,computed } from 'vue' | |
18 | +import { watch, PropType, onMounted, ref, nextTick,computed } from 'vue' | |
19 | 19 | import VChart from 'vue-echarts' |
20 | 20 | import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook' |
21 | 21 | import { use, graphic } from 'echarts/core' |
... | ... | @@ -31,6 +31,9 @@ import { isPreview, colorGradientCustomMerge } from '@/utils' |
31 | 31 | import dataJson from './data.json' |
32 | 32 | import { useFullScreen } from '../../utls/fullScreen' |
33 | 33 | import isObject from 'lodash/isObject' |
34 | +import cloneDeep from 'lodash/cloneDeep' | |
35 | +import { useAssembleDataHooks } from '@/hooks/external/useAssembleData.hook' | |
36 | +import { SocketReceiveMessageType } from '@/store/external/modules/socketStore.d' | |
34 | 37 | |
35 | 38 | const props = defineProps({ |
36 | 39 | themeSetting: { |
... | ... | @@ -99,7 +102,6 @@ watch( |
99 | 102 | ]) |
100 | 103 | }) |
101 | 104 | } |
102 | - // option.value = mergeTheme(props.chartConfig.option, props.themeSetting, includes) | |
103 | 105 | props.chartConfig.option = option.value |
104 | 106 | } catch (error) { |
105 | 107 | console.log(error) |
... | ... | @@ -110,12 +112,6 @@ watch( |
110 | 112 | } |
111 | 113 | ) |
112 | 114 | |
113 | -// watch( | |
114 | -// () => props.chartConfig.option.dataset, | |
115 | -// () => { | |
116 | -// option.value = props.chartConfig.option | |
117 | -// } | |
118 | -// ) | |
119 | 115 | let seriesDataNum = -1 |
120 | 116 | let seriesDataMaxLength = 0 |
121 | 117 | let intervalInstance: any = null |
... | ... | @@ -188,16 +184,6 @@ watch( |
188 | 184 | } |
189 | 185 | ) |
190 | 186 | |
191 | -//fix 修复v-chart图表绑定联动组件视图不更新问题 | |
192 | -const updateVChart = (newData: any) => { | |
193 | - if (!newData) return | |
194 | - vChartRef.value?.clear() | |
195 | - vChartRef.value?.setOption({ | |
196 | - ...option.value, | |
197 | - dataset: newData | |
198 | - }) | |
199 | -} | |
200 | - | |
201 | 187 | const replaceMergeArr = ref<string[]>() |
202 | 188 | |
203 | 189 | // dataset 无法变更条数的补丁 |
... | ... | @@ -205,15 +191,27 @@ watch( |
205 | 191 | () => props.chartConfig.option.dataset, |
206 | 192 | (newData: { dimensions: any }, oldData) => { |
207 | 193 | try { |
208 | - // option.value = mergeTheme(props.chartConfig.option, props.themeSetting, includes) | |
209 | 194 | if (!isObject(newData) || !('dimensions' in newData)) return |
210 | 195 | if (Array.isArray(newData?.dimensions)) { |
211 | 196 | const seriesArr = [] |
212 | - for (let i = 0; i < newData.dimensions.length - 1; i++) { | |
213 | - seriesArr.push(seriesItem) | |
197 | + // 对oldData进行判断,防止传入错误数据之后对旧维度判断产生干扰 | |
198 | + // 此处计算的是dimensions的Y轴维度,若是dimensions.length为0或1,则默认为1,排除X轴维度干扰 | |
199 | + const oldDimensions = | |
200 | + Array.isArray(oldData?.dimensions) && oldData.dimensions.length >= 1 ? oldData.dimensions.length : 1 | |
201 | + const newDimensions = newData.dimensions.length >= 1 ? newData.dimensions.length : 1 | |
202 | + const dimensionsGap = newDimensions - oldDimensions | |
203 | + if (dimensionsGap < 0) { | |
204 | + props.chartConfig.option.series.splice(newDimensions - 1) | |
205 | + } else if (dimensionsGap > 0) { | |
206 | + if (!oldData || !oldData?.dimensions || !Array.isArray(oldData?.dimensions) || !oldData?.dimensions.length) { | |
207 | + props.chartConfig.option.series = [] | |
208 | + } | |
209 | + for (let i = 0; i < dimensionsGap; i++) { | |
210 | + seriesArr.push(cloneDeep(seriesItem)) | |
211 | + } | |
212 | + props.chartConfig.option.series.push(...seriesArr) | |
214 | 213 | } |
215 | 214 | replaceMergeArr.value = ['series'] |
216 | - props.chartConfig.option.series = seriesArr | |
217 | 215 | nextTick(() => { |
218 | 216 | replaceMergeArr.value = [] |
219 | 217 | }) |
... | ... | @@ -227,8 +225,39 @@ watch( |
227 | 225 | } |
228 | 226 | ) |
229 | 227 | |
228 | +//fix 修复v-chart图表绑定联动组件视图不更新问题 | |
229 | +const updateVChart = (newData:SocketReceiveMessageType) => { | |
230 | + //区分是普通请求还是ws请求 | |
231 | + if (!isObject(newData) || !('dimensions' in newData)) { | |
232 | + const { data } = newData | |
233 | + const { keys, record } = useAssembleDataHooks(data) | |
234 | + vChartRef.value?.setOption({ | |
235 | + dataset: { | |
236 | + dimensions: ['ts', ...keys], | |
237 | + source: [record] | |
238 | + } | |
239 | + }) | |
240 | + } else { | |
241 | + //异步更新,同步更新会造成联动组件控制,图表不及时更新 | |
242 | + new Promise((resolve) => { | |
243 | + setTimeout(() => { | |
244 | + resolve( | |
245 | + vChartRef.value?.setOption( | |
246 | + { | |
247 | + ...option.value, | |
248 | + dataset: newData | |
249 | + }, | |
250 | + { | |
251 | + notMerge: true | |
252 | + } | |
253 | + ) | |
254 | + ) | |
255 | + }, 100) | |
256 | + }) | |
257 | + } | |
258 | +} | |
259 | + | |
230 | 260 | const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, newData => { |
231 | - // addPieInterval(newData) | |
232 | 261 | updateVChart(newData) |
233 | 262 | }) |
234 | 263 | ... | ... |