From 43448430a5ae694b5f4b72ef6f6ac49a3485886c Mon Sep 17 00:00:00 2001 From: "lixuefei.1313" Date: Tue, 18 Jul 2023 17:18:15 +0800 Subject: [PATCH] fix: correctly update global-scale when updateSpec --- ...color-is-not-updated_2023-07-18-09-17.json | 10 +++++ packages/vchart/src/chart/base-chart.ts | 24 +++++++++--- packages/vchart/src/scale/global-scale.ts | 37 +++++++++++++++++-- packages/vchart/src/scale/interface.ts | 5 ++- 4 files changed, 67 insertions(+), 9 deletions(-) create mode 100644 common/changes/@visactor/vchart/fix-216-bug-the-updatespec-method-does-not-handle-the-globalscale-cause-color-is-not-updated_2023-07-18-09-17.json diff --git a/common/changes/@visactor/vchart/fix-216-bug-the-updatespec-method-does-not-handle-the-globalscale-cause-color-is-not-updated_2023-07-18-09-17.json b/common/changes/@visactor/vchart/fix-216-bug-the-updatespec-method-does-not-handle-the-globalscale-cause-color-is-not-updated_2023-07-18-09-17.json new file mode 100644 index 0000000000..8673bd59fc --- /dev/null +++ b/common/changes/@visactor/vchart/fix-216-bug-the-updatespec-method-does-not-handle-the-globalscale-cause-color-is-not-updated_2023-07-18-09-17.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@visactor/vchart", + "comment": "fix(global-scale): Correctly update global-scale when updateSpec", + "type": "patch" + } + ], + "packageName": "@visactor/vchart" +} \ No newline at end of file diff --git a/packages/vchart/src/chart/base-chart.ts b/packages/vchart/src/chart/base-chart.ts index c092f1136e..e7417580c1 100644 --- a/packages/vchart/src/chart/base-chart.ts +++ b/packages/vchart/src/chart/base-chart.ts @@ -214,7 +214,7 @@ export class BaseChart extends CompilableBase implements IChart { this.initSeries(); // global scale 应当在series初始化完成后,组件初始化之前 // 此时 globalScale 已经生效组件可以获取到正确的映射 - this.initGlobalScale(); + this.updateGlobalScaleDomain(); // component this.initComponent(); // event @@ -705,8 +705,7 @@ export class BaseChart extends CompilableBase implements IChart { return this._spec.data[0]; } - // 全局通道 - createGlobalScale() { + private _transformSpecScale() { const scales: IChartSpec['scales'] = this._spec.scales ?? []; let colorScaleSpec: IVisualSpecScale = scales.find(s => s.id === 'color'); if (!colorScaleSpec) { @@ -739,11 +738,16 @@ export class BaseChart extends CompilableBase implements IChart { // @ts-ignore colorScaleSpec.rangeTheme = true; } - this._globalScale = new GlobalScale(scales, this); + return scales; + } + + // 全局通道 + createGlobalScale() { + this._globalScale = new GlobalScale(this._transformSpecScale(), this); this._modelOption.globalScale = this._globalScale; } - initGlobalScale() { + updateGlobalScaleDomain() { const domainSet = new Set(); this._series.forEach(s => { const keys = s.getSeriesKeys(); @@ -758,6 +762,10 @@ export class BaseChart extends CompilableBase implements IChart { this._globalScale.updateScaleDomain(domain); } + updateGlobalScale(result: IUpdateSpecResult) { + this._mergeUpdateResult(result, this._globalScale.updateSpec(this._transformSpecScale())); + } + updateGlobalScaleTheme() { const colorSpec = this._globalScale.getScaleSpec('color'); // eslint-disable-next-line @typescript-eslint/ban-ts-comment @@ -795,10 +803,16 @@ export class BaseChart extends CompilableBase implements IChart { return result; } this._spec = spec; + this.updateGlobalScale(result); + if (result.reMake) { + return result; + } this.updateDataSpec(result); if (result.reMake) { return result; } + // ensure that the domain of the scale follows the data change + this.updateGlobalScaleDomain(); // region 变化 this.updateRegionSpec(result); if (result.reMake) { diff --git a/packages/vchart/src/scale/global-scale.ts b/packages/vchart/src/scale/global-scale.ts index 47231b70d6..abfe36c277 100644 --- a/packages/vchart/src/scale/global-scale.ts +++ b/packages/vchart/src/scale/global-scale.ts @@ -88,8 +88,39 @@ export class GlobalScale implements IGlobalScale { return result; } result.change = true; + for (let i = 0; i < spec.length; i++) { + const s = spec[i]; + const scale = this._scaleMap.get(s.id); + if (!scale) { + // new global scale need remake chart + result.reMake = true; + return result; + } + const lastSpec = this._spec.find(_s => _s.id === s.id); + if (!lastSpec.id) { + // new global scale need remake chart + result.reMake = true; + return result; + } + if (lastSpec.type !== s.type) { + // scale cannot change type, need remake chart + result.reMake = true; + return result; + } + if (s.range && !isEqual(s.range, scale.range())) { + scale.range(s.range); + result.reRender = true; + } + if (isDataDomainSpec(s.domain)) { + result.reRender = true; + } else if (!isEqual(s.domain, scale.domain())) { + scale.domain(s.domain); + result.reRender = true; + } + // replace specMap, this use for data domain + this._scaleSpecMap.set(s.id, s); + } this._spec = spec; - this._setAttrFromSpec(); return result; } @@ -228,7 +259,7 @@ export class GlobalScale implements IGlobalScale { }); } - private _updateMarkScale(id: string, scale: IBaseScale, domain: any[] | Set) { + private _updateMarkScale(id: string, scale: IBaseScale, domain: unknown[] | Set) { const list = this._markAttributeScaleMap.get(id); if (!list || list.length === 0) { return; @@ -243,7 +274,7 @@ export class GlobalScale implements IGlobalScale { !info.dataStatistics || !info.dataStatistics.latestData[info.field] ) { - isContinuous(scale.type) ? info.markScale.domain(domain as any[]) : scale.domain(Array.from(domain)); + isContinuous(scale.type) ? info.markScale.domain(domain as unknown[]) : scale.domain(Array.from(domain)); return; } diff --git a/packages/vchart/src/scale/interface.ts b/packages/vchart/src/scale/interface.ts index 5312fc6de1..985c6ed0a5 100644 --- a/packages/vchart/src/scale/interface.ts +++ b/packages/vchart/src/scale/interface.ts @@ -1,7 +1,8 @@ import type { DataView } from '@visactor/vdataset'; import type { IBaseScale } from '@visactor/vscale'; import type { StatisticOperations } from '../data/transforms/dimension-statistics'; -import type { IVisualScale, IVisualSpecScale } from '../typings'; +import type { IChartSpec, IVisualScale, IVisualSpecScale } from '../typings'; +import type { IUpdateSpecResult } from '../model/interface'; export interface IGlobalScale { color?: any; @@ -21,4 +22,6 @@ export interface IGlobalScale { */ registerModelScale: (spec: IVisualSpecScale) => void; removeModelScale: (filter: (spec: IVisualSpecScale) => boolean) => void; + + updateSpec: (spec: IChartSpec['scales']) => IUpdateSpecResult; }