From 6de9e3399cd4cc1205e2ee2ea2efcacc0f512ffb Mon Sep 17 00:00:00 2001 From: MiniPear Date: Fri, 26 May 2023 12:37:07 +0800 Subject: [PATCH] fix(data): render empty data (#5098) --- .../api-chart-change-data-empty.spec.ts | 25 +++++++++++++++ .../api/chart-change-data-empty/step0.png | Bin 0 -> 1289 bytes .../plots/api/chart-change-data-empty.ts | 29 ++++++++++++++++++ __tests__/plots/api/index.ts | 1 + src/mark/area.ts | 2 +- src/mark/line.ts | 2 +- src/runtime/scale.ts | 23 ++++++++------ 7 files changed, 71 insertions(+), 11 deletions(-) create mode 100644 __tests__/integration/api-chart-change-data-empty.spec.ts create mode 100644 __tests__/integration/snapshots/api/chart-change-data-empty/step0.png create mode 100644 __tests__/plots/api/chart-change-data-empty.ts diff --git a/__tests__/integration/api-chart-change-data-empty.spec.ts b/__tests__/integration/api-chart-change-data-empty.spec.ts new file mode 100644 index 0000000000..f29048820c --- /dev/null +++ b/__tests__/integration/api-chart-change-data-empty.spec.ts @@ -0,0 +1,25 @@ +import { chartChangeDataEmpty as render } from '../plots/api/chart-change-data-empty'; +import { createNodeGCanvas } from './utils/createNodeGCanvas'; +import { sleep } from './utils/sleep'; +import { kebabCase } from './utils/kebabCase'; +import './utils/useSnapshotMatchers'; +import './utils/useCustomFetch'; + +describe('chart.options.autoFit', () => { + const dir = `${__dirname}/snapshots/api/${kebabCase(render.name)}`; + const canvas = createNodeGCanvas(800, 500); + + it('chart({ autoFit: true }) should fit parent container', async () => { + const { finished } = render({ + canvas, + container: document.createElement('div'), + }); + await finished; + await sleep(20); + await expect(canvas).toMatchCanvasSnapshot(dir, 'step0'); + }); + + afterAll(() => { + canvas?.destroy(); + }); +}); diff --git a/__tests__/integration/snapshots/api/chart-change-data-empty/step0.png b/__tests__/integration/snapshots/api/chart-change-data-empty/step0.png new file mode 100644 index 0000000000000000000000000000000000000000..5bcd9e9bed3547416bf1272c84e454230d708479 GIT binary patch literal 1289 zcmeAS@N?(olHy`uVBq!ia0y~yU}|7sV0^&A1{5*9c;^X_VoUONcVYMsf(!O8pUl9( zvd`1SF{EP7+k=d}K>0%pzWe9$nJ)k`N5N chart.changeData([])); + + return { chart, finished }; +} diff --git a/__tests__/plots/api/index.ts b/__tests__/plots/api/index.ts index d73a20a58b..1dc39c3a75 100644 --- a/__tests__/plots/api/index.ts +++ b/__tests__/plots/api/index.ts @@ -24,3 +24,4 @@ export { chartRenderUpdateAttributes } from './chart-render-update-attributes'; export { chartRenderUpdateNonAnimation } from './chart-render-update-non-animation'; export { chartEmitBrushHighlightX } from './chart-emit-brush-highlight-x'; export { chartRenderBrushEnd } from './chart-render-brush-end'; +export { chartChangeDataEmpty } from './chart-change-data-empty'; diff --git a/src/mark/area.ts b/src/mark/area.ts index 1604d2dd71..3e1adfee67 100644 --- a/src/mark/area.ts +++ b/src/mark/area.ts @@ -42,7 +42,7 @@ export const Area: MC = () => { // Group data by series field. const series = S ? Array.from(group(index, (i) => S[i]).values()) : [index]; - const I = series.map((group) => group[0]); + const I = series.map((group) => group[0]).filter((i) => i !== undefined); // A group of data corresponds to one area. const P = Array.from(series, (SI) => { diff --git a/src/mark/line.ts b/src/mark/line.ts index 4bf63b9ce2..af59f8c6a1 100644 --- a/src/mark/line.ts +++ b/src/mark/line.ts @@ -26,7 +26,7 @@ const line: Mark = (index, scale, value, coordinate) => { // Group data into series. // There is only one series without specified series encode. const series = S ? Array.from(group(index, (i) => S[i]).values()) : [index]; - const I = series.map((group) => group[0]); + const I = series.map((group) => group[0]).filter((i) => i !== undefined); // A group of data corresponds to one line. const xoffset = (x?.getBandWidth?.() || 0) / 2; diff --git a/src/runtime/scale.ts b/src/runtime/scale.ts index 860a1e49f2..40b3aa77b5 100644 --- a/src/runtime/scale.ts +++ b/src/runtime/scale.ts @@ -190,7 +190,6 @@ function inferScaleDomain( ): Primitive[] { const { domain } = options; if (domain !== undefined) return domain; - const { domainMax, domainMin } = options; switch (type) { case 'linear': case 'time': @@ -198,20 +197,16 @@ function inferScaleDomain( case 'pow': case 'sqrt': case 'quantize': - case 'threshold': { - const [d0, d1] = inferDomainQ(values, options); - return [domainMin ?? d0, domainMax ?? d1]; - } + case 'threshold': + return maybeMinMax(inferDomainQ(values, options), options); case 'band': case 'ordinal': case 'point': return inferDomainC(values); case 'quantile': return inferDomainO(values); - case 'sequential': { - const [d0, d1] = inferDomainS(values); - return [domainMin ?? d0, domainMax ?? d1]; - } + case 'sequential': + return maybeMinMax(inferDomainS(values), options); default: return []; } @@ -403,6 +398,16 @@ function asQuantitativeType(name: string, range: Primitive[]) { return range ? 'linear' : 'sequential'; } +function maybeMinMax( + domain: Primitive[], + options: G2ScaleOptions, +): Primitive[] { + if (domain.length === 0) return domain; + const { domainMin, domainMax } = options; + const [d0, d1] = domain; + return [domainMin ?? d0, domainMax ?? d1]; +} + function inferDomainQ(values: Primitive[][], options: G2ScaleOptions) { const { zero = false } = options; let min = Infinity;