Commit 320f15b626d931c7763b3051660d7edb508b0caf

Authored by fengwotao
1 parent 4d78bfbd

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

@@ -29,8 +29,11 @@ import { useChartDataFetch } from '@/hooks' @@ -29,8 +29,11 @@ import { useChartDataFetch } from '@/hooks'
29 import { isPreview } from '@/utils' 29 import { isPreview } from '@/utils'
30 import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components' 30 import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components'
31 import isObject from 'lodash/isObject' 31 import isObject from 'lodash/isObject'
  32 +import cloneDeep from 'lodash/cloneDeep'
32 import dataJson from './data.json' 33 import dataJson from './data.json'
33 import { useFullScreen } from '../../utls/fullScreen' 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 const props = defineProps({ 38 const props = defineProps({
36 themeSetting: { 39 themeSetting: {
@@ -87,11 +90,24 @@ watch( @@ -87,11 +90,24 @@ watch(
87 if (!isObject(newData) || !('dimensions' in newData)) return 90 if (!isObject(newData) || !('dimensions' in newData)) return
88 if (Array.isArray(newData?.dimensions)) { 91 if (Array.isArray(newData?.dimensions)) {
89 const seriesArr = [] 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 replaceMergeArr.value = ['series'] 110 replaceMergeArr.value = ['series']
94 - props.chartConfig.option.series = seriesArr  
95 nextTick(() => { 111 nextTick(() => {
96 replaceMergeArr.value = [] 112 replaceMergeArr.value = []
97 }) 113 })
@@ -178,17 +194,38 @@ watch( @@ -178,17 +194,38 @@ watch(
178 ) 194 )
179 195
180 //fix 修复v-chart图表绑定联动组件视图不更新问题 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 const {vChartRef} = useChartDataFetch(props.chartConfig, useChartEditStore, (newData) => { 228 const {vChartRef} = useChartDataFetch(props.chartConfig, useChartEditStore, (newData) => {
191 - // addPieInterval(newData)  
192 updateVChart(newData) 229 updateVChart(newData)
193 }) 230 })
194 231
@@ -15,7 +15,7 @@ @@ -15,7 +15,7 @@
15 </template> 15 </template>
16 16
17 <script setup lang="ts"> 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 import VChart from 'vue-echarts' 19 import VChart from 'vue-echarts'
20 import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook' 20 import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook'
21 import { use, graphic } from 'echarts/core' 21 import { use, graphic } from 'echarts/core'
@@ -31,6 +31,9 @@ import { isPreview, colorGradientCustomMerge } from '@/utils' @@ -31,6 +31,9 @@ import { isPreview, colorGradientCustomMerge } from '@/utils'
31 import dataJson from './data.json' 31 import dataJson from './data.json'
32 import { useFullScreen } from '../../utls/fullScreen' 32 import { useFullScreen } from '../../utls/fullScreen'
33 import isObject from 'lodash/isObject' 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 const props = defineProps({ 38 const props = defineProps({
36 themeSetting: { 39 themeSetting: {
@@ -99,7 +102,6 @@ watch( @@ -99,7 +102,6 @@ watch(
99 ]) 102 ])
100 }) 103 })
101 } 104 }
102 - // option.value = mergeTheme(props.chartConfig.option, props.themeSetting, includes)  
103 props.chartConfig.option = option.value 105 props.chartConfig.option = option.value
104 } catch (error) { 106 } catch (error) {
105 console.log(error) 107 console.log(error)
@@ -110,12 +112,6 @@ watch( @@ -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 let seriesDataNum = -1 115 let seriesDataNum = -1
120 let seriesDataMaxLength = 0 116 let seriesDataMaxLength = 0
121 let intervalInstance: any = null 117 let intervalInstance: any = null
@@ -188,16 +184,6 @@ watch( @@ -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 const replaceMergeArr = ref<string[]>() 187 const replaceMergeArr = ref<string[]>()
202 188
203 // dataset 无法变更条数的补丁 189 // dataset 无法变更条数的补丁
@@ -205,15 +191,27 @@ watch( @@ -205,15 +191,27 @@ watch(
205 () => props.chartConfig.option.dataset, 191 () => props.chartConfig.option.dataset,
206 (newData: { dimensions: any }, oldData) => { 192 (newData: { dimensions: any }, oldData) => {
207 try { 193 try {
208 - // option.value = mergeTheme(props.chartConfig.option, props.themeSetting, includes)  
209 if (!isObject(newData) || !('dimensions' in newData)) return 194 if (!isObject(newData) || !('dimensions' in newData)) return
210 if (Array.isArray(newData?.dimensions)) { 195 if (Array.isArray(newData?.dimensions)) {
211 const seriesArr = [] 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 replaceMergeArr.value = ['series'] 214 replaceMergeArr.value = ['series']
216 - props.chartConfig.option.series = seriesArr  
217 nextTick(() => { 215 nextTick(() => {
218 replaceMergeArr.value = [] 216 replaceMergeArr.value = []
219 }) 217 })
@@ -227,8 +225,39 @@ watch( @@ -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 const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, newData => { 260 const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, newData => {
231 - // addPieInterval(newData)  
232 updateVChart(newData) 261 updateVChart(newData)
233 }) 262 })
234 263