@blotch/dolan 22.2.1 → 22.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/add.d.ts +6 -2
- package/dist/commands/add.js +32 -10
- package/dist/commands/add.js.map +1 -1
- package/dist/commands/add.test.js +129 -9
- package/dist/commands/add.test.js.map +1 -1
- package/dist/commands/diff.d.ts +2 -1
- package/dist/commands/diff.js +38 -25
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/diff.test.js +72 -11
- package/dist/commands/diff.test.js.map +1 -1
- package/dist/commands/doctor.js +41 -27
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/doctor.test.js +93 -9
- package/dist/commands/doctor.test.js.map +1 -1
- package/dist/commands/eject.js +7 -0
- package/dist/commands/eject.js.map +1 -1
- package/dist/commands/eject.test.js +39 -0
- package/dist/commands/eject.test.js.map +1 -1
- package/dist/commands/info.js +3 -2
- package/dist/commands/info.js.map +1 -1
- package/dist/commands/init.d.ts +37 -1
- package/dist/commands/init.js +149 -40
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/init.test.js +285 -26
- package/dist/commands/init.test.js.map +1 -1
- package/dist/commands/install-packages.d.ts +6 -0
- package/dist/commands/install-packages.js +20 -0
- package/dist/commands/install-packages.js.map +1 -0
- package/dist/commands/install-packages.test.d.ts +1 -0
- package/dist/commands/install-packages.test.js +55 -0
- package/dist/commands/install-packages.test.js.map +1 -0
- package/dist/commands/list.js +21 -14
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/list.test.js +62 -5
- package/dist/commands/list.test.js.map +1 -1
- package/dist/commands/outdated.js +11 -10
- package/dist/commands/outdated.js.map +1 -1
- package/dist/commands/outdated.test.js +20 -5
- package/dist/commands/outdated.test.js.map +1 -1
- package/dist/commands/remove.d.ts +4 -0
- package/dist/commands/remove.js +17 -4
- package/dist/commands/remove.js.map +1 -1
- package/dist/commands/remove.test.js +53 -2
- package/dist/commands/remove.test.js.map +1 -1
- package/dist/commands/update.d.ts +6 -0
- package/dist/commands/update.js +59 -24
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/update.test.js +273 -31
- package/dist/commands/update.test.js.map +1 -1
- package/dist/index.js +10 -3
- package/dist/index.js.map +1 -1
- package/dist/registry.d.ts +8 -0
- package/dist/registry.js +32 -24
- package/dist/registry.js.map +1 -1
- package/dist/registry.test.js +76 -37
- package/dist/registry.test.js.map +1 -1
- package/dist/testing/set-input-signal.d.ts +13 -0
- package/dist/testing/set-input-signal.js +20 -0
- package/dist/testing/set-input-signal.js.map +1 -0
- package/dist/testing/set-input-signal.test.d.ts +1 -0
- package/dist/testing/set-input-signal.test.js +20 -0
- package/dist/testing/set-input-signal.test.js.map +1 -0
- package/dist/ui/components/action-sheet/action-sheet.test.ts +48 -1
- package/dist/ui/components/action-sheet/action-sheet.ts +37 -9
- package/dist/ui/components/alert-dialog/alert-dialog.test.ts +49 -2
- package/dist/ui/components/alert-dialog/alert-dialog.ts +43 -12
- package/dist/ui/components/area-chart/area-chart-render.test.ts +52 -110
- package/dist/ui/components/area-chart/area-chart.test.ts +59 -146
- package/dist/ui/components/area-chart/area-chart.ts +100 -315
- package/dist/ui/components/area-chart/index.ts +2 -3
- package/dist/ui/components/bar-chart/bar-chart-render.test.ts +47 -163
- package/dist/ui/components/bar-chart/bar-chart.test.ts +82 -58
- package/dist/ui/components/bar-chart/bar-chart.ts +140 -294
- package/dist/ui/components/bar-chart/index.ts +3 -3
- package/dist/ui/components/bottom-sheet/bottom-sheet.test.ts +191 -9
- package/dist/ui/components/bottom-sheet/bottom-sheet.ts +136 -20
- package/dist/ui/components/button/button-render.test.ts +19 -0
- package/dist/ui/components/button/button.test.ts +2 -15
- package/dist/ui/components/button/button.ts +18 -2
- package/dist/ui/components/button-group/button-group.test.ts +2 -21
- package/dist/ui/components/candlestick-chart/candlestick-chart-render.test.ts +48 -163
- package/dist/ui/components/candlestick-chart/candlestick-chart.test.ts +107 -85
- package/dist/ui/components/candlestick-chart/candlestick-chart.ts +150 -323
- package/dist/ui/components/candlestick-chart/index.ts +3 -4
- package/dist/ui/components/chart/chart-focus.test.ts +132 -0
- package/dist/ui/components/chart/chart-focus.ts +115 -0
- package/dist/ui/components/chart/chart-presets.test.ts +139 -0
- package/dist/ui/components/chart/chart-presets.ts +271 -0
- package/dist/ui/components/chart/chart-render.test.ts +730 -0
- package/dist/ui/components/chart/chart-scene.test.ts +589 -0
- package/dist/ui/components/chart/chart-scene.ts +483 -0
- package/dist/ui/components/chart/chart-theme.test.ts +85 -0
- package/dist/ui/components/chart/chart-theme.ts +198 -0
- package/dist/ui/components/chart/chart-zoom.test.ts +159 -0
- package/dist/ui/components/chart/chart-zoom.ts +162 -0
- package/dist/ui/components/chart/chart.ts +921 -0
- package/dist/ui/components/chart/index.ts +24 -0
- package/dist/ui/components/dialog/dialog.test.ts +49 -2
- package/dist/ui/components/dialog/dialog.ts +43 -12
- package/dist/ui/components/icon/icon-theme.test.ts +133 -0
- package/dist/ui/components/icon/icon-theme.ts +204 -0
- package/dist/ui/components/icon/icon.test.ts +51 -2
- package/dist/ui/components/icon/icon.ts +38 -21
- package/dist/ui/components/line-chart/index.ts +2 -3
- package/dist/ui/components/line-chart/line-chart-render.test.ts +69 -107
- package/dist/ui/components/line-chart/line-chart.test.ts +63 -67
- package/dist/ui/components/line-chart/line-chart.ts +83 -241
- package/dist/ui/components/list/list.test.ts +69 -2
- package/dist/ui/components/list/list.ts +21 -15
- package/dist/ui/components/nav-drawer/nav-drawer.test.ts +80 -1
- package/dist/ui/components/nav-drawer/nav-drawer.ts +66 -11
- package/dist/ui/components/pagination/pagination.test.ts +62 -0
- package/dist/ui/components/pagination/pagination.ts +55 -8
- package/dist/ui/components/scatter-chart/index.ts +2 -3
- package/dist/ui/components/scatter-chart/scatter-chart-render.test.ts +51 -144
- package/dist/ui/components/scatter-chart/scatter-chart.test.ts +57 -47
- package/dist/ui/components/scatter-chart/scatter-chart.ts +104 -250
- package/dist/ui/components/scroll-area/scroll-area.test.ts +37 -2
- package/dist/ui/components/scroll-area/scroll-area.ts +8 -8
- package/dist/ui/components/spinner/spinner.test.ts +27 -0
- package/dist/ui/components/spinner/spinner.ts +33 -23
- package/dist/ui/components/toast/toast.test.ts +37 -0
- package/dist/ui/components/toast/toast.ts +20 -4
- package/dist/ui/theme/chart-colors.test.ts +30 -0
- package/dist/ui/theme/dark.css +8 -0
- package/dist/ui/theme/default.css +8 -0
- package/dist/ui/theme/icon-colors.test.ts +30 -0
- package/dist/ui/theme/tailwind-plugin.ts +10 -1
- package/dist/utils/installed.d.ts +17 -0
- package/dist/utils/installed.js +27 -0
- package/dist/utils/installed.js.map +1 -0
- package/dist/utils/installed.test.d.ts +1 -0
- package/dist/utils/installed.test.js +41 -0
- package/dist/utils/installed.test.js.map +1 -0
- package/dist/utils/interactive.d.ts +9 -0
- package/dist/utils/interactive.js +10 -0
- package/dist/utils/interactive.js.map +1 -0
- package/dist/utils/interactive.test.d.ts +1 -0
- package/dist/utils/interactive.test.js +24 -0
- package/dist/utils/interactive.test.js.map +1 -0
- package/dist/utils/packages.d.ts +36 -0
- package/dist/utils/packages.js +70 -0
- package/dist/utils/packages.js.map +1 -0
- package/dist/utils/packages.test.d.ts +1 -0
- package/dist/utils/packages.test.js +89 -0
- package/dist/utils/packages.test.js.map +1 -0
- package/dist/utils/resolve-paths.d.ts +17 -1
- package/dist/utils/resolve-paths.js +23 -3
- package/dist/utils/resolve-paths.js.map +1 -1
- package/dist/utils/resolve-paths.test.js +34 -2
- package/dist/utils/resolve-paths.test.js.map +1 -1
- package/package.json +5 -1
- package/dist/ui/components/cartesian-chart/cartesian-chart-render.test.ts +0 -188
- package/dist/ui/components/cartesian-chart/cartesian-chart.test.ts +0 -549
- package/dist/ui/components/cartesian-chart/cartesian-chart.ts +0 -1140
- package/dist/ui/components/cartesian-chart/index.ts +0 -18
|
@@ -1,121 +1,63 @@
|
|
|
1
|
-
import { render
|
|
1
|
+
import { render } from '@blotch/angular-lynx-testing-library';
|
|
2
|
+
import { createChartRuntime } from '@tanstack/charts/runtime';
|
|
3
|
+
import type {
|
|
4
|
+
ChartDefinition,
|
|
5
|
+
ChartPoint,
|
|
6
|
+
SceneNode,
|
|
7
|
+
} from '@tanstack/charts/types';
|
|
2
8
|
import { describe, expect, it, vi } from 'vitest';
|
|
3
9
|
import { setInputSignal } from '../../../test-utils/set-input-signal';
|
|
4
|
-
import {
|
|
5
|
-
|
|
10
|
+
import { UiAreaChart } from './area-chart';
|
|
11
|
+
|
|
12
|
+
const data = [
|
|
13
|
+
{ x: 0, y: 4 },
|
|
14
|
+
{ x: 1, y: -2 },
|
|
15
|
+
{ x: 2, y: 6 },
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Every drawn shape in a definition's scene, labels excluded.
|
|
20
|
+
*/
|
|
21
|
+
const shapes = (definition: ChartDefinition<any, any, any>) => {
|
|
22
|
+
const scene = createChartRuntime().render(definition, {
|
|
23
|
+
width: 300,
|
|
24
|
+
height: 200,
|
|
25
|
+
});
|
|
26
|
+
const found: SceneNode[] = [];
|
|
27
|
+
const walk = (nodes: readonly SceneNode[]) => {
|
|
28
|
+
for (const node of nodes) {
|
|
29
|
+
if (node.kind === 'group') {
|
|
30
|
+
if (!node.focus) walk(node.children);
|
|
31
|
+
} else if (node.kind !== 'label') found.push(node);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
walk(scene.nodes);
|
|
35
|
+
return { scene, found };
|
|
36
|
+
};
|
|
6
37
|
|
|
7
38
|
describe('UiAreaChart', () => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
it('folds the baseline into the y-axis domain', async () => {
|
|
14
|
-
const { componentRef } = await render(UiAreaChart);
|
|
15
|
-
const inst = componentRef.instance as UiAreaChart;
|
|
16
|
-
setInputSignal(inst.data, [
|
|
17
|
-
{ x: 0, y: 5 },
|
|
18
|
-
{ x: 5, y: 10 },
|
|
19
|
-
{ x: 10, y: 8 },
|
|
20
|
-
]);
|
|
21
|
-
setInputSignal(inst.baseline, 0);
|
|
22
|
-
await waitForUpdate();
|
|
23
|
-
const cast = inst as unknown as {
|
|
24
|
-
xAxis: () => { domain: readonly [number, number]; ticks: number[] };
|
|
25
|
-
yAxis: () => { domain: readonly [number, number]; ticks: number[] };
|
|
26
|
-
};
|
|
27
|
-
expect(cast.xAxis().domain[0]).toBeLessThanOrEqual(0);
|
|
28
|
-
expect(cast.xAxis().domain[1]).toBeGreaterThanOrEqual(10);
|
|
29
|
-
expect(cast.yAxis().domain[0]).toBeLessThanOrEqual(0);
|
|
30
|
-
expect(cast.yAxis().domain[1]).toBeGreaterThanOrEqual(10);
|
|
31
|
-
});
|
|
39
|
+
type Internals = {
|
|
40
|
+
definition: () => ChartDefinition<any, any, any>;
|
|
41
|
+
onSelect(point: ChartPoint | null): void;
|
|
42
|
+
};
|
|
32
43
|
|
|
33
|
-
it('
|
|
44
|
+
it('builds its definition from its inputs', async () => {
|
|
34
45
|
const { componentRef } = await render(UiAreaChart);
|
|
35
|
-
const
|
|
36
|
-
setInputSignal(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
]);
|
|
40
|
-
setInputSignal(inst.xMin, -5);
|
|
41
|
-
setInputSignal(inst.xMax, 20);
|
|
42
|
-
setInputSignal(inst.yMin, -1);
|
|
43
|
-
setInputSignal(inst.yMax, 15);
|
|
44
|
-
await waitForUpdate();
|
|
45
|
-
const cast = inst as unknown as {
|
|
46
|
-
xAxis: () => { domain: readonly [number, number] };
|
|
47
|
-
yAxis: () => { domain: readonly [number, number] };
|
|
48
|
-
};
|
|
49
|
-
expect(cast.xAxis().domain[0]).toBeLessThanOrEqual(-5);
|
|
50
|
-
expect(cast.xAxis().domain[1]).toBeGreaterThanOrEqual(20);
|
|
51
|
-
expect(cast.yAxis().domain[0]).toBeLessThanOrEqual(-1);
|
|
52
|
-
expect(cast.yAxis().domain[1]).toBeGreaterThanOrEqual(15);
|
|
46
|
+
const chart = componentRef.instance as UiAreaChart;
|
|
47
|
+
setInputSignal(chart.data, data);
|
|
48
|
+
setInputSignal(chart.baseline, -20);
|
|
49
|
+
const { scene } = shapes((chart as unknown as Internals).definition());
|
|
50
|
+
expect(scene.scales['y']!.domain[0]).toBeLessThanOrEqual(-20);
|
|
53
51
|
});
|
|
54
52
|
|
|
55
|
-
it('
|
|
53
|
+
it('emits the tapped datum', async () => {
|
|
56
54
|
const { componentRef } = await render(UiAreaChart);
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
describe('UiAreaSeries', () => {
|
|
66
|
-
const renderSeries = async () => {
|
|
67
|
-
const parentResult = await render(UiCartesianChart);
|
|
68
|
-
const parent = parentResult.componentRef.instance as UiCartesianChart;
|
|
69
|
-
setInputSignal(parent.xDomain, [0, 10]);
|
|
70
|
-
setInputSignal(parent.yDomain, [0, 10]);
|
|
71
|
-
await waitForUpdate();
|
|
72
|
-
const seriesResult = await render(UiAreaSeries, {
|
|
73
|
-
providers: [{ provide: UiCartesianChart, useValue: parent }],
|
|
74
|
-
});
|
|
75
|
-
const series = seriesResult.componentRef.instance as UiAreaSeries;
|
|
76
|
-
setInputSignal(series.data, [
|
|
77
|
-
{ x: 0, y: 0 },
|
|
78
|
-
{ x: 5, y: 5 },
|
|
79
|
-
{ x: 10, y: 10 },
|
|
80
|
-
]);
|
|
81
|
-
await waitForUpdate();
|
|
82
|
-
return { parent, series };
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
it('renders fill columns and a translucent fill layer', async () => {
|
|
86
|
-
const { series } = await renderSeries();
|
|
87
|
-
const cast = series as unknown as {
|
|
88
|
-
columns: () => { style: string }[];
|
|
89
|
-
fillLayerStyle: () => string;
|
|
90
|
-
};
|
|
91
|
-
expect(cast.columns().length).toBeGreaterThan(0);
|
|
92
|
-
expect(cast.fillLayerStyle()).toContain('opacity');
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it('smooth mode densely resamples the fill columns', async () => {
|
|
96
|
-
const { series } = await renderSeries();
|
|
97
|
-
const cast = series as unknown as { columns: () => { style: string }[] };
|
|
98
|
-
const straight = cast.columns().length;
|
|
99
|
-
setInputSignal(series.smooth, true);
|
|
100
|
-
await waitForUpdate();
|
|
101
|
-
// Smoothed curve produces at least as many columns as the straight one.
|
|
102
|
-
expect(cast.columns().length).toBeGreaterThanOrEqual(straight);
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
it('emits pointTap when the nested line series taps', async () => {
|
|
106
|
-
const { series } = await renderSeries();
|
|
107
|
-
const cb = vi.fn();
|
|
108
|
-
series.pointTap.subscribe(cb);
|
|
109
|
-
series.pointTap.emit({ x: 1, y: 2 });
|
|
110
|
-
expect(cb).toHaveBeenCalledWith({ x: 1, y: 2 });
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
it('clamps the baseline into the plot when it lies outside the domain', async () => {
|
|
114
|
-
const { series } = await renderSeries();
|
|
115
|
-
// baseline > yDomain upper bound → clamp to top of plot; columns still render
|
|
116
|
-
setInputSignal(series.baseline, 999);
|
|
117
|
-
await waitForUpdate();
|
|
118
|
-
const cast = series as unknown as { columns: () => { style: string }[] };
|
|
119
|
-
expect(Array.isArray(cast.columns())).toBe(true);
|
|
55
|
+
const chart = componentRef.instance as UiAreaChart;
|
|
56
|
+
const tapped = vi.fn();
|
|
57
|
+
chart.pointTap.subscribe(tapped);
|
|
58
|
+
const internals = chart as unknown as Internals;
|
|
59
|
+
internals.onSelect({ datum: data[0] } as ChartPoint);
|
|
60
|
+
internals.onSelect(null);
|
|
61
|
+
expect(tapped.mock.calls).toEqual([[data[0]]]);
|
|
120
62
|
});
|
|
121
63
|
});
|
|
@@ -1,158 +1,71 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createChartRuntime } from '@tanstack/charts/runtime';
|
|
2
|
+
import type { ChartDefinition, SceneNode } from '@tanstack/charts/types';
|
|
3
|
+
import { describe, expect, it } from 'vitest';
|
|
4
|
+
import { areaChartDefinition } from './area-chart';
|
|
2
5
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
ViewEncapsulation: { None: 0 },
|
|
9
|
-
computed: () => () => {},
|
|
10
|
-
inject: () => ({}),
|
|
11
|
-
input: () => () => {},
|
|
12
|
-
output: () => () => {},
|
|
13
|
-
}));
|
|
6
|
+
const data = [
|
|
7
|
+
{ x: 0, y: 4 },
|
|
8
|
+
{ x: 1, y: -2 },
|
|
9
|
+
{ x: 2, y: 6 },
|
|
10
|
+
];
|
|
14
11
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}));
|
|
23
|
-
|
|
24
|
-
const { computeAreaColumns } = await import('./area-chart');
|
|
25
|
-
|
|
26
|
-
describe('computeAreaColumns', () => {
|
|
27
|
-
it('fills a flat line down to the baseline with uniform columns', () => {
|
|
28
|
-
// Horizontal line at pixel y=20, baseline at y=100, 30px plot, 10px strips.
|
|
29
|
-
const columns = computeAreaColumns(
|
|
30
|
-
[
|
|
31
|
-
{ x: 0, y: 20 },
|
|
32
|
-
{ x: 30, y: 20 },
|
|
33
|
-
],
|
|
34
|
-
100,
|
|
35
|
-
30,
|
|
36
|
-
10,
|
|
37
|
-
);
|
|
38
|
-
expect(columns.map((c) => c.x)).toEqual([0, 10, 20]);
|
|
39
|
-
for (const column of columns) {
|
|
40
|
-
expect(column.top).toBeCloseTo(20);
|
|
41
|
-
expect(column.height).toBeCloseTo(80);
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it('fills on both sides when the line crosses the baseline', () => {
|
|
46
|
-
// Line y = x from (0,0) to (100,100); baseline pixel y = 50.
|
|
47
|
-
const columns = computeAreaColumns(
|
|
48
|
-
[
|
|
49
|
-
{ x: 0, y: 0 },
|
|
50
|
-
{ x: 100, y: 100 },
|
|
51
|
-
],
|
|
52
|
-
50,
|
|
53
|
-
100,
|
|
54
|
-
50,
|
|
55
|
-
);
|
|
56
|
-
expect(columns).toHaveLength(2);
|
|
57
|
-
// Strip centered at x=25 → line above the baseline: top at the line, down to it.
|
|
58
|
-
expect(columns[0].top).toBeCloseTo(25);
|
|
59
|
-
expect(columns[0].height).toBeCloseTo(25);
|
|
60
|
-
// Strip centered at x=75 → line below the baseline: top at the baseline.
|
|
61
|
-
expect(columns[1].top).toBeCloseTo(50);
|
|
62
|
-
expect(columns[1].height).toBeCloseTo(25);
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it('skips strips whose center falls outside the data x-range', () => {
|
|
66
|
-
// Data spans x=[40,60] but the plot is 100 wide → only strips inside fill.
|
|
67
|
-
const columns = computeAreaColumns(
|
|
68
|
-
[
|
|
69
|
-
{ x: 40, y: 10 },
|
|
70
|
-
{ x: 60, y: 10 },
|
|
71
|
-
],
|
|
72
|
-
100,
|
|
73
|
-
100,
|
|
74
|
-
10,
|
|
75
|
-
);
|
|
76
|
-
expect(columns.map((c) => c.x)).toEqual([40, 50]);
|
|
77
|
-
expect(columns.every((c) => c.x >= 40 && c.x <= 60)).toBe(true);
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it('skips columns where the line sits on the baseline', () => {
|
|
81
|
-
// Flat line exactly at the baseline → zero height everywhere, nothing to fill.
|
|
82
|
-
const columns = computeAreaColumns(
|
|
83
|
-
[
|
|
84
|
-
{ x: 0, y: 50 },
|
|
85
|
-
{ x: 30, y: 50 },
|
|
86
|
-
],
|
|
87
|
-
50,
|
|
88
|
-
30,
|
|
89
|
-
10,
|
|
90
|
-
);
|
|
91
|
-
expect(columns).toEqual([]);
|
|
12
|
+
/**
|
|
13
|
+
* Every drawn shape in a definition's scene, labels excluded.
|
|
14
|
+
*/
|
|
15
|
+
const shapes = (definition: ChartDefinition<any, any, any>) => {
|
|
16
|
+
const scene = createChartRuntime().render(definition, {
|
|
17
|
+
width: 300,
|
|
18
|
+
height: 200,
|
|
92
19
|
});
|
|
20
|
+
const found: SceneNode[] = [];
|
|
21
|
+
const walk = (nodes: readonly SceneNode[]) => {
|
|
22
|
+
for (const node of nodes) {
|
|
23
|
+
if (node.kind === 'group') {
|
|
24
|
+
if (!node.focus) walk(node.children);
|
|
25
|
+
} else if (node.kind !== 'label') found.push(node);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
walk(scene.nodes);
|
|
29
|
+
return { scene, found };
|
|
30
|
+
};
|
|
93
31
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
32
|
+
describe('areaChartDefinition', () => {
|
|
33
|
+
it('fills to the baseline under the line, with dots', () => {
|
|
34
|
+
const { found } = shapes(areaChartDefinition({ data, fillOpacity: 0.3 }));
|
|
35
|
+
const area = found.find((n) => n.kind === 'area')!;
|
|
36
|
+
expect(area.style).toMatchObject({
|
|
37
|
+
fill: 'var(--primary)',
|
|
38
|
+
fillOpacity: 0.3,
|
|
39
|
+
});
|
|
40
|
+
expect(found.filter((n) => n.kind === 'polyline')).toHaveLength(1);
|
|
41
|
+
expect(found.filter((n) => n.kind === 'dot')).toHaveLength(3);
|
|
97
42
|
});
|
|
98
43
|
|
|
99
|
-
it('
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
[
|
|
103
|
-
{ x: 0, y:
|
|
104
|
-
{ x:
|
|
44
|
+
it('keeps the baseline in view', () => {
|
|
45
|
+
const { scene } = shapes(
|
|
46
|
+
areaChartDefinition({
|
|
47
|
+
data: [
|
|
48
|
+
{ x: 0, y: 5 },
|
|
49
|
+
{ x: 1, y: 8 },
|
|
105
50
|
],
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
10,
|
|
109
|
-
),
|
|
110
|
-
).toEqual([]);
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
it('handles duplicate consecutive x values without dividing by zero', () => {
|
|
114
|
-
// Two points share x=10 → span === 0 branch. Choose plotWidth/stripWidth
|
|
115
|
-
// so that a strip's center lands exactly on x=10: stripWidth=20 puts the
|
|
116
|
-
// very first strip's center at x=0 + 20/2 = 10.
|
|
117
|
-
const columns = computeAreaColumns(
|
|
118
|
-
[
|
|
119
|
-
{ x: 10, y: 20 },
|
|
120
|
-
{ x: 10, y: 40 },
|
|
121
|
-
],
|
|
122
|
-
100,
|
|
123
|
-
21,
|
|
124
|
-
20,
|
|
51
|
+
baseline: -10,
|
|
52
|
+
}),
|
|
125
53
|
);
|
|
126
|
-
|
|
127
|
-
expect(columns.length).toBeGreaterThan(0);
|
|
128
|
-
expect(columns[0].top).toBeCloseTo(20);
|
|
54
|
+
expect(scene.scales['y']!.domain[0]).toBeLessThanOrEqual(-10);
|
|
129
55
|
});
|
|
130
56
|
|
|
131
|
-
it('
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
// The fallback is only reachable if points contains a "gap": e.g. after the
|
|
145
|
-
// duplicate, but that violates the sorted-input contract. Accept as
|
|
146
|
-
// defensive — see the v8 ignore in the source.
|
|
147
|
-
const columns = computeAreaColumns(
|
|
148
|
-
[
|
|
149
|
-
{ x: 0, y: 0 },
|
|
150
|
-
{ x: 10, y: 10 },
|
|
151
|
-
],
|
|
152
|
-
100,
|
|
153
|
-
10,
|
|
154
|
-
10,
|
|
155
|
-
);
|
|
156
|
-
expect(columns.length).toBeGreaterThan(0);
|
|
57
|
+
it('can leave out the dots, curve the line and drop the tooltip', () => {
|
|
58
|
+
const definition = areaChartDefinition({
|
|
59
|
+
data,
|
|
60
|
+
showDots: false,
|
|
61
|
+
smooth: true,
|
|
62
|
+
tooltip: false,
|
|
63
|
+
});
|
|
64
|
+
const { found } = shapes(definition);
|
|
65
|
+
expect(found.some((n) => n.kind === 'dot')).toBe(false);
|
|
66
|
+
expect(
|
|
67
|
+
(found.find((n) => n.kind === 'polyline') as { path?: string }).path,
|
|
68
|
+
).toContain('C');
|
|
69
|
+
expect(definition.tooltip).toBe(false);
|
|
157
70
|
});
|
|
158
71
|
});
|