Commit 320f15b626d931c7763b3051660d7edb508b0caf

Authored by fengwotao
1 parent 4d78bfbd

perf(src/packages): 优化图表和联动组件进行交互,图表不及时更新

... ... @@ -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
... ...