From c629cc0496877aaa12a636a12fbf0923bc8728f2 Mon Sep 17 00:00:00 2001 From: xile611 Date: Tue, 20 Aug 2024 14:46:17 +0800 Subject: [PATCH] fix: vchart should not throw error when the values of series data is empty, fix #3082 --- .../__tests__/unit/core/update-spec.test.ts | 93 ++++++++++++++++++- .../src/data/transforms/add-property.ts | 2 +- .../src/data/transforms/copy-data-view.ts | 2 +- .../data/transforms/dimension-statistics.ts | 11 ++- .../vchart/src/data/transforms/stack-split.ts | 43 ++++----- 5 files changed, 122 insertions(+), 29 deletions(-) diff --git a/packages/vchart/__tests__/unit/core/update-spec.test.ts b/packages/vchart/__tests__/unit/core/update-spec.test.ts index f52e8a5f24..6062d038ea 100644 --- a/packages/vchart/__tests__/unit/core/update-spec.test.ts +++ b/packages/vchart/__tests__/unit/core/update-spec.test.ts @@ -1,4 +1,4 @@ -import type { IBarChartSpec } from '../../../src'; +import type { IBarChartSpec, ICommonChartSpec } from '../../../src'; import { default as VChart } from '../../../src'; import { series } from '../../../src/theme/builtin/common/series'; import { createDiv, removeDom } from '../../util/dom'; @@ -1106,6 +1106,97 @@ describe('vchart updateSpec of same spec', () => { reTransformSpec: false }); }); + + it('should not throw error when data is empty in series', () => { + const spec: any = { + type: 'common', + seriesField: 'color', + data: [ + { + id: 'id0', + values: [ + { x: '周一', type: '早餐', y: 15 }, + { x: '周一', type: '午餐', y: 25 }, + { x: '周二', type: '早餐', y: 12 }, + { x: '周二', type: '午餐', y: 30 }, + { x: '周三', type: '早餐', y: 15 }, + { x: '周三', type: '午餐', y: 24 }, + { x: '周四', type: '早餐', y: 10 }, + { x: '周四', type: '午餐', y: 25 }, + { x: '周五', type: '早餐', y: 13 }, + { x: '周五', type: '午餐', y: 20 }, + { x: '周六', type: '早餐', y: 10 }, + { x: '周六', type: '午餐', y: 22 }, + { x: '周日', type: '早餐', y: 12 }, + { x: '周日', type: '午餐', y: 19 } + ] + }, + { + id: 'id1', + values: [ + { x: '周一', type: '饮料', y: 22 }, + { x: '周二', type: '饮料', y: 43 }, + { x: '周三', type: '饮料', y: 33 }, + { x: '周四', type: '饮料', y: 22 }, + { x: '周五', type: '饮料', y: 10 }, + { x: '周六', type: '饮料', y: 30 }, + { x: '周日', type: '饮料', y: 50 } + ] + } + ], + series: [ + { + type: 'bar', + id: 'bar', + data: { + id: 'id0' + }, + label: { visible: true }, + seriesField: 'type', + + xField: ['x', 'type'], + yField: 'y' + }, + { + type: 'line', + id: 'line', + data: { + id: 'id1' + }, + label: { visible: true }, + seriesField: 'type', + xField: 'x', + yField: 'y', + stack: false + } + ], + axes: [ + { orient: 'left', seriesIndex: [0] }, + { orient: 'right', seriesId: ['line'], grid: { visible: false } }, + { orient: 'bottom', label: { visible: true }, type: 'band' } + ], + legends: { + visible: true, + orient: 'bottom' + } + }; + + vchart = new VChart(spec, { + dom + }); + vchart.renderSync(); + const updateRes = (vchart as any)._updateSpec(spec, false); + + expect(updateRes).toEqual({ + change: false, + changeTheme: false, + reCompile: false, + reMake: false, + reRender: true, + reSize: false, + reTransformSpec: false + }); + }); }); describe('vchart updateSpec of different about label', () => { diff --git a/packages/vchart/src/data/transforms/add-property.ts b/packages/vchart/src/data/transforms/add-property.ts index 97b91e17d6..822b9bf1e7 100644 --- a/packages/vchart/src/data/transforms/add-property.ts +++ b/packages/vchart/src/data/transforms/add-property.ts @@ -12,7 +12,7 @@ export interface IAddVChartPropertyOpt { export const addVChartProperty = (data: Array, op: IAddVChartPropertyOpt) => { const context = op.beforeCall(); - data.forEach((d, i) => op.call(d, i, context)); + data && data.forEach((d, i) => op.call(d, i, context)); if (context.keyMap) { context.keyMap.clear(); diff --git a/packages/vchart/src/data/transforms/copy-data-view.ts b/packages/vchart/src/data/transforms/copy-data-view.ts index dc2801705c..89e6c56fd2 100644 --- a/packages/vchart/src/data/transforms/copy-data-view.ts +++ b/packages/vchart/src/data/transforms/copy-data-view.ts @@ -10,7 +10,7 @@ function copyOneDataView(d: DataView, deep = false) { return cloneDeep(d.latestData); } - return d.latestData.slice(); + return d.latestData && d.latestData.slice(); } /** diff --git a/packages/vchart/src/data/transforms/dimension-statistics.ts b/packages/vchart/src/data/transforms/dimension-statistics.ts index 2c5a6a06ee..fc6b249d7a 100644 --- a/packages/vchart/src/data/transforms/dimension-statistics.ts +++ b/packages/vchart/src/data/transforms/dimension-statistics.ts @@ -110,11 +110,12 @@ export const dimensionStatisticsOfSimpleData = ( let allValid = true; fValues.length = 0; - latestData.forEach((d: Datum) => { - if (d) { - fValues.push(d[key]); - } - }); + latestData && + latestData.forEach((d: Datum) => { + if (d) { + fValues.push(d[key]); + } + }); const len = fValues.length; if (isNumberField) { diff --git a/packages/vchart/src/data/transforms/stack-split.ts b/packages/vchart/src/data/transforms/stack-split.ts index 39245c0436..364e9a1819 100644 --- a/packages/vchart/src/data/transforms/stack-split.ts +++ b/packages/vchart/src/data/transforms/stack-split.ts @@ -20,31 +20,32 @@ export const stackSplit = (data: Array, op: IStackOption) => { let nextNode: ISeriesStackDataNode; let leaf: ISeriesStackDataLeaf; data.forEach(dv => { - dv.latestData.forEach((d: Datum) => { - temp = result; - for (let i = 0; i < fields.length; i++) { - const f = fields[i]; - const fV = d[f]; - if (isNil(fV)) { - break; - } - temp.groupField = f; - if (!temp.nodes[fV]) { + dv.latestData && + dv.latestData.forEach((d: Datum) => { + temp = result; + for (let i = 0; i < fields.length; i++) { + const f = fields[i]; + const fV = d[f]; + if (isNil(fV)) { + break; + } + temp.groupField = f; + if (!temp.nodes[fV]) { + if (i === lastFieldIndex) { + temp.nodes[fV] = { values: [] }; + } else { + nextNode = { nodes: {} }; + temp.nodes[fV] = nextNode; + } + } if (i === lastFieldIndex) { - temp.nodes[fV] = { values: [] }; + leaf = temp.nodes[fV] as ISeriesStackDataLeaf; + leaf.values.push(d); } else { - nextNode = { nodes: {} }; - temp.nodes[fV] = nextNode; + temp = temp.nodes[fV] as ISeriesStackDataNode; } } - if (i === lastFieldIndex) { - leaf = temp.nodes[fV] as ISeriesStackDataLeaf; - leaf.values.push(d); - } else { - temp = temp.nodes[fV] as ISeriesStackDataNode; - } - } - }); + }); }); return result; };