@opendata-ai/openchart-engine 8.0.0-rc.8 → 8.0.0
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/index.d.ts +149 -12
- package/dist/index.js +894 -171
- package/dist/index.js.map +1 -1
- package/package.json +3 -4
- package/src/__test-fixtures__/specs.ts +0 -182
- package/src/__tests__/__snapshots__/compile-snapshot.test.ts.snap +0 -2339
- package/src/__tests__/annotation-behavior.test.ts +0 -852
- package/src/__tests__/axes.test.ts +0 -1579
- package/src/__tests__/compile-animation.test.ts +0 -161
- package/src/__tests__/compile-chart.test.ts +0 -1303
- package/src/__tests__/compile-footnotes.test.ts +0 -277
- package/src/__tests__/compile-layer.test.ts +0 -969
- package/src/__tests__/compile-snapshot.test.ts +0 -156
- package/src/__tests__/compound-labels.test.ts +0 -147
- package/src/__tests__/dimensions.test.ts +0 -918
- package/src/__tests__/encoding-sugar.test.ts +0 -390
- package/src/__tests__/facet.test.ts +0 -215
- package/src/__tests__/helpers/invariants.ts +0 -299
- package/src/__tests__/known-bugs.test.ts +0 -566
- package/src/__tests__/layout-fuzz.test.ts +0 -358
- package/src/__tests__/layout-invariants.test.ts +0 -535
- package/src/__tests__/legend.test.ts +0 -721
- package/src/__tests__/mark-keys.test.ts +0 -294
- package/src/__tests__/ranking-recipes.test.ts +0 -260
- package/src/__tests__/rotation.test.ts +0 -83
- package/src/__tests__/scales.test.ts +0 -323
- package/src/__tests__/series-search.test.ts +0 -92
- package/src/__tests__/spec-sugar.test.ts +0 -801
- package/src/__tests__/you-draw-it.test.ts +0 -160
- package/src/annotations/__tests__/compute.test.ts +0 -1672
- package/src/annotations/__tests__/geometry.test.ts +0 -66
- package/src/annotations/__tests__/placement-fuzz.test.ts +0 -256
- package/src/annotations/__tests__/placement-invariants.test.ts +0 -345
- package/src/annotations/__tests__/placement.test.ts +0 -316
- package/src/annotations/__tests__/resolve-text.test.ts +0 -788
- package/src/annotations/__tests__/rich-text.test.ts +0 -91
- package/src/annotations/__tests__/thinning.test.ts +0 -285
- package/src/annotations/collisions.ts +0 -326
- package/src/annotations/compute.ts +0 -333
- package/src/annotations/constants.ts +0 -162
- package/src/annotations/geometry.ts +0 -376
- package/src/annotations/move.ts +0 -135
- package/src/annotations/placement.ts +0 -636
- package/src/annotations/position.ts +0 -131
- package/src/annotations/resolve-range.ts +0 -117
- package/src/annotations/resolve-refline.ts +0 -157
- package/src/annotations/resolve-text.ts +0 -545
- package/src/annotations/rich-text.ts +0 -65
- package/src/annotations/thinning.ts +0 -190
- package/src/barlist/__tests__/compile-barlist.test.ts +0 -200
- package/src/barlist/compile-barlist.ts +0 -391
- package/src/barlist/types.ts +0 -28
- package/src/charts/__tests__/post-process.test.ts +0 -237
- package/src/charts/__tests__/registry.test.ts +0 -116
- package/src/charts/__tests__/utils.test.ts +0 -195
- package/src/charts/_shared/__tests__/density-filter.test.ts +0 -32
- package/src/charts/_shared/density-filter.ts +0 -26
- package/src/charts/_shared/format-label-value.ts +0 -16
- package/src/charts/bar/__tests__/compute.test.ts +0 -934
- package/src/charts/bar/__tests__/gradient-orient.test.ts +0 -127
- package/src/charts/bar/__tests__/labels.test.ts +0 -292
- package/src/charts/bar/compute.ts +0 -539
- package/src/charts/bar/index.ts +0 -60
- package/src/charts/bar/labels.ts +0 -311
- package/src/charts/beeswarm/__tests__/compute.test.ts +0 -280
- package/src/charts/beeswarm/__tests__/dodge.test.ts +0 -148
- package/src/charts/beeswarm/compute.ts +0 -203
- package/src/charts/beeswarm/dodge.ts +0 -155
- package/src/charts/beeswarm/index.ts +0 -32
- package/src/charts/builtin.ts +0 -75
- package/src/charts/calendar/__tests__/compute.test.ts +0 -417
- package/src/charts/calendar/compute.ts +0 -319
- package/src/charts/calendar/index.ts +0 -32
- package/src/charts/column/__tests__/compute.test.ts +0 -540
- package/src/charts/column/__tests__/labels.test.ts +0 -179
- package/src/charts/column/compute.ts +0 -493
- package/src/charts/column/index.ts +0 -53
- package/src/charts/column/labels.ts +0 -229
- package/src/charts/dot/__tests__/compute.test.ts +0 -380
- package/src/charts/dot/__tests__/labels.test.ts +0 -98
- package/src/charts/dot/compute.ts +0 -285
- package/src/charts/dot/index.ts +0 -62
- package/src/charts/dot/labels.ts +0 -121
- package/src/charts/line/__tests__/compute.test.ts +0 -1194
- package/src/charts/line/__tests__/curves.test.ts +0 -51
- package/src/charts/line/__tests__/labels.test.ts +0 -94
- package/src/charts/line/__tests__/mark-options.test.ts +0 -175
- package/src/charts/line/area.ts +0 -484
- package/src/charts/line/compute.ts +0 -356
- package/src/charts/line/curves.ts +0 -85
- package/src/charts/line/index.ts +0 -176
- package/src/charts/line/labels.ts +0 -177
- package/src/charts/parliament/__tests__/compute.test.ts +0 -411
- package/src/charts/parliament/compute.ts +0 -313
- package/src/charts/parliament/index.ts +0 -32
- package/src/charts/pie/__tests__/compute.test.ts +0 -384
- package/src/charts/pie/__tests__/labels.test.ts +0 -132
- package/src/charts/pie/compute.ts +0 -324
- package/src/charts/pie/index.ts +0 -49
- package/src/charts/pie/labels.ts +0 -143
- package/src/charts/post-process.ts +0 -229
- package/src/charts/range/__tests__/compute.test.ts +0 -486
- package/src/charts/range/compute.ts +0 -273
- package/src/charts/range/index.ts +0 -82
- package/src/charts/range/labels.ts +0 -169
- package/src/charts/rect/__tests__/compute.test.ts +0 -120
- package/src/charts/rect/index.ts +0 -127
- package/src/charts/registry.ts +0 -72
- package/src/charts/rule/index.ts +0 -139
- package/src/charts/scatter/__tests__/compute.test.ts +0 -488
- package/src/charts/scatter/__tests__/trendline.test.ts +0 -191
- package/src/charts/scatter/compute.ts +0 -192
- package/src/charts/scatter/index.ts +0 -46
- package/src/charts/scatter/trendline.ts +0 -100
- package/src/charts/text/__tests__/compute.test.ts +0 -307
- package/src/charts/text/index.ts +0 -141
- package/src/charts/tick/__tests__/compute.test.ts +0 -75
- package/src/charts/tick/index.ts +0 -99
- package/src/charts/utils.ts +0 -170
- package/src/charts/waffle/__tests__/compute.test.ts +0 -305
- package/src/charts/waffle/compute.ts +0 -197
- package/src/charts/waffle/index.ts +0 -31
- package/src/compile/__tests__/color-scale-range.test.ts +0 -158
- package/src/compile/__tests__/color-scale-reverse.test.ts +0 -89
- package/src/compile/__tests__/data-clip.test.ts +0 -127
- package/src/compile/__tests__/fill-patterns.test.ts +0 -154
- package/src/compile/__tests__/size-scale.test.ts +0 -108
- package/src/compile/__tests__/watermark-obstacle.test.ts +0 -93
- package/src/compile/color-scale-range.ts +0 -101
- package/src/compile/data-clip.ts +0 -48
- package/src/compile/fill-patterns.ts +0 -74
- package/src/compile/layer.ts +0 -626
- package/src/compile/size-scale.ts +0 -141
- package/src/compile/spec-sugar.ts +0 -758
- package/src/compile/watermark-obstacle.ts +0 -54
- package/src/compile/you-draw-it.ts +0 -123
- package/src/compile.ts +0 -1450
- package/src/compiler/__tests__/a11y-warnings.test.ts +0 -148
- package/src/compiler/__tests__/animation.test.ts +0 -177
- package/src/compiler/__tests__/compile.test.ts +0 -87
- package/src/compiler/__tests__/fixtures/vl-parity/axis-null.json +0 -19
- package/src/compiler/__tests__/fixtures/vl-parity/color-value.json +0 -20
- package/src/compiler/__tests__/fixtures/vl-parity/count-aggregate.json +0 -22
- package/src/compiler/__tests__/fixtures/vl-parity/data-values.json +0 -19
- package/src/compiler/__tests__/fixtures/vl-parity/layer-axis-null.json +0 -14
- package/src/compiler/__tests__/fixtures/vl-parity/layer-count.json +0 -34
- package/src/compiler/__tests__/fixtures/vl-parity/layer-data-values.json +0 -22
- package/src/compiler/__tests__/fixtures/vl-parity/layer-legend-null.json +0 -41
- package/src/compiler/__tests__/fixtures/vl-parity/layer-scheme.json +0 -38
- package/src/compiler/__tests__/fixtures/vl-parity/layer-sort.json +0 -28
- package/src/compiler/__tests__/fixtures/vl-parity/layer-theta.json +0 -28
- package/src/compiler/__tests__/fixtures/vl-parity/layer-title.json +0 -30
- package/src/compiler/__tests__/fixtures/vl-parity/layer-value-def.json +0 -29
- package/src/compiler/__tests__/fixtures/vl-parity/legend-null.json +0 -32
- package/src/compiler/__tests__/fixtures/vl-parity/scheme.json +0 -25
- package/src/compiler/__tests__/fixtures/vl-parity/sort-by-value.json +0 -19
- package/src/compiler/__tests__/fixtures/vl-parity/theta-arc.json +0 -19
- package/src/compiler/__tests__/fixtures/vl-parity/title-subtitle.json +0 -21
- package/src/compiler/__tests__/fixtures/vl-parity/width-height.json +0 -23
- package/src/compiler/__tests__/keys.test.ts +0 -83
- package/src/compiler/__tests__/normalize-highlight.test.ts +0 -103
- package/src/compiler/__tests__/normalize.test.ts +0 -399
- package/src/compiler/__tests__/sparkline-defaults.test.ts +0 -153
- package/src/compiler/__tests__/validate-did-you-mean.test.ts +0 -170
- package/src/compiler/__tests__/validate-highlight.test.ts +0 -112
- package/src/compiler/__tests__/validate-near-miss.test.ts +0 -251
- package/src/compiler/__tests__/validate.test.ts +0 -629
- package/src/compiler/__tests__/vl-parity.test.ts +0 -68
- package/src/compiler/a11y-warnings.ts +0 -110
- package/src/compiler/animation.ts +0 -142
- package/src/compiler/index.ts +0 -47
- package/src/compiler/keys.ts +0 -55
- package/src/compiler/normalize.ts +0 -734
- package/src/compiler/sparkline-defaults.ts +0 -138
- package/src/compiler/types.ts +0 -241
- package/src/compiler/validate.ts +0 -2041
- package/src/endpoint-labels/__tests__/compute.test.ts +0 -587
- package/src/endpoint-labels/compute.ts +0 -621
- package/src/endpoint-labels/constants.ts +0 -54
- package/src/endpoint-labels/format.ts +0 -60
- package/src/endpoint-labels/predict.ts +0 -139
- package/src/format/__tests__/field-format.test.ts +0 -164
- package/src/format/field-format.ts +0 -27
- package/src/geo/__tests__/compile-map.test.ts +0 -1004
- package/src/geo/compile-map.ts +0 -1341
- package/src/geo/join.ts +0 -115
- package/src/geo/projections.ts +0 -45
- package/src/geo/types.ts +0 -26
- package/src/graphs/__tests__/community.test.ts +0 -228
- package/src/graphs/__tests__/compile-graph.test.ts +0 -396
- package/src/graphs/__tests__/encoding.test.ts +0 -415
- package/src/graphs/community.ts +0 -92
- package/src/graphs/compile-graph.ts +0 -329
- package/src/graphs/encoding.ts +0 -356
- package/src/graphs/types.ts +0 -106
- package/src/index.ts +0 -177
- package/src/layout/__tests__/metrics.test.ts +0 -97
- package/src/layout/__tests__/scales-highlight.test.ts +0 -192
- package/src/layout/axes/rotation.ts +0 -152
- package/src/layout/axes/thinning.ts +0 -98
- package/src/layout/axes/ticks.ts +0 -409
- package/src/layout/axes.ts +0 -757
- package/src/layout/dimensions.ts +0 -912
- package/src/layout/facet.ts +0 -91
- package/src/layout/gridlines.ts +0 -84
- package/src/layout/metrics.ts +0 -132
- package/src/layout/plan.ts +0 -631
- package/src/layout/scales.ts +0 -1053
- package/src/layout/shared.ts +0 -44
- package/src/legend/__tests__/continuous.test.ts +0 -318
- package/src/legend/__tests__/redundancy.test.ts +0 -108
- package/src/legend/__tests__/size.test.ts +0 -348
- package/src/legend/__tests__/suppression.test.ts +0 -382
- package/src/legend/compute.ts +0 -747
- package/src/legend/continuous.ts +0 -327
- package/src/legend/size.ts +0 -407
- package/src/legend/suppression.ts +0 -226
- package/src/legend/wrap.ts +0 -117
- package/src/sankey/__tests__/compile-sankey.test.ts +0 -458
- package/src/sankey/__tests__/layout.test.ts +0 -165
- package/src/sankey/__tests__/node-label-wrap.test.ts +0 -114
- package/src/sankey/__tests__/node-sort.test.ts +0 -45
- package/src/sankey/compile-sankey.ts +0 -706
- package/src/sankey/layout.ts +0 -184
- package/src/sankey/types.ts +0 -41
- package/src/tables/__tests__/bar-column.test.ts +0 -147
- package/src/tables/__tests__/category-colors.test.ts +0 -230
- package/src/tables/__tests__/compile-table.test.ts +0 -236
- package/src/tables/__tests__/format-cells.test.ts +0 -143
- package/src/tables/__tests__/heatmap.test.ts +0 -148
- package/src/tables/__tests__/pagination.test.ts +0 -78
- package/src/tables/__tests__/search.test.ts +0 -94
- package/src/tables/__tests__/sort.test.ts +0 -107
- package/src/tables/__tests__/sparkline.test.ts +0 -122
- package/src/tables/bar-column.ts +0 -94
- package/src/tables/category-colors.ts +0 -78
- package/src/tables/compile-table.ts +0 -427
- package/src/tables/format-cells.ts +0 -115
- package/src/tables/heatmap.ts +0 -141
- package/src/tables/pagination.ts +0 -46
- package/src/tables/search.ts +0 -66
- package/src/tables/sort.ts +0 -69
- package/src/tables/sparkline.ts +0 -113
- package/src/tables/utils.ts +0 -16
- package/src/tilemap/__tests__/compile-tilemap.test.ts +0 -576
- package/src/tilemap/compile-tilemap.ts +0 -755
- package/src/tilemap/layout.ts +0 -172
- package/src/tilemap/types.ts +0 -33
- package/src/tooltips/__tests__/compute.test.ts +0 -582
- package/src/tooltips/compute.ts +0 -700
- package/src/transforms/__tests__/aggregate.test.ts +0 -159
- package/src/transforms/__tests__/bin.test.ts +0 -88
- package/src/transforms/__tests__/calculate.test.ts +0 -146
- package/src/transforms/__tests__/conditional.test.ts +0 -127
- package/src/transforms/__tests__/filter-relative.test.ts +0 -202
- package/src/transforms/__tests__/filter.test.ts +0 -59
- package/src/transforms/__tests__/fold.test.ts +0 -79
- package/src/transforms/__tests__/index.test.ts +0 -93
- package/src/transforms/__tests__/predicates.test.ts +0 -193
- package/src/transforms/__tests__/timeunit.test.ts +0 -129
- package/src/transforms/__tests__/window.test.ts +0 -286
- package/src/transforms/aggregate.ts +0 -131
- package/src/transforms/bin.ts +0 -87
- package/src/transforms/calculate.ts +0 -60
- package/src/transforms/conditional.ts +0 -46
- package/src/transforms/filter.ts +0 -122
- package/src/transforms/fold.ts +0 -49
- package/src/transforms/index.ts +0 -60
- package/src/transforms/predicates.ts +0 -123
- package/src/transforms/timeunit.ts +0 -88
- package/src/transforms/window.ts +0 -185
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Integration snapshot test: the backstop for Step 7 refactor.
|
|
3
|
-
*
|
|
4
|
-
* Compiles three representative ChartSpecs that exercise the extracted paths
|
|
5
|
-
* (legend-heavy, clipped-domain, watermark + gradient) and snapshots the full
|
|
6
|
-
* ChartLayout. Pre-refactor snapshots are captured before helper extraction;
|
|
7
|
-
* post-refactor snapshots must match exactly without --update-snapshots.
|
|
8
|
-
*
|
|
9
|
-
* Non-serializable fields (Map, Function) are normalized into plain structures
|
|
10
|
-
* so the snapshot can round-trip through the default serializer.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import type { ChartLayout } from '@opendata-ai/openchart-core';
|
|
14
|
-
import { describe, expect, it } from 'vitest';
|
|
15
|
-
import { compileChart } from '../compile';
|
|
16
|
-
|
|
17
|
-
type AxisTick = { label?: string; value?: unknown; position?: unknown };
|
|
18
|
-
type AxisShape = Record<string, unknown> & { ticks?: AxisTick[] };
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Whether an axis carries temporal (Date) ticks. D3 time scales produce
|
|
22
|
-
* midnight-local Date objects, so tick positions and values shift by hours
|
|
23
|
-
* between macOS (CDT/PDT) and Linux CI (UTC). We strip temporal axes from
|
|
24
|
-
* the main snapshot and assert their labels separately.
|
|
25
|
-
*/
|
|
26
|
-
function isTemporalAxis(axis: AxisShape | undefined): boolean {
|
|
27
|
-
return Array.isArray(axis?.ticks) && axis.ticks.some((t) => t.value instanceof Date);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/** Convert ChartLayout into a fully serializable shape for snapshot comparison. */
|
|
31
|
-
function serializeLayout(
|
|
32
|
-
layout: ChartLayout,
|
|
33
|
-
{ stripTemporalAxes = false } = {},
|
|
34
|
-
): Record<string, unknown> {
|
|
35
|
-
const { tooltipDescriptors, measureText: _measure, ...rest } = layout;
|
|
36
|
-
const axes = rest.axes as { x?: AxisShape; y?: AxisShape } | undefined;
|
|
37
|
-
|
|
38
|
-
let serializedAxes = axes;
|
|
39
|
-
if (axes && stripTemporalAxes) {
|
|
40
|
-
serializedAxes = {
|
|
41
|
-
...axes,
|
|
42
|
-
x: isTemporalAxis(axes.x) ? undefined : axes.x,
|
|
43
|
-
y: isTemporalAxis(axes.y) ? undefined : axes.y,
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return {
|
|
48
|
-
...rest,
|
|
49
|
-
axes: serializedAxes,
|
|
50
|
-
tooltipDescriptors: Array.from(tooltipDescriptors.entries()),
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
describe('compileChart snapshot (Step 7 oracle)', () => {
|
|
55
|
-
it('legend-heavy multi-series line chart', () => {
|
|
56
|
-
const spec = {
|
|
57
|
-
mark: 'line' as const,
|
|
58
|
-
data: [
|
|
59
|
-
{ date: '2020-01-01', value: 10, country: 'US' },
|
|
60
|
-
{ date: '2021-01-01', value: 40, country: 'US' },
|
|
61
|
-
{ date: '2020-01-01', value: 15, country: 'UK' },
|
|
62
|
-
{ date: '2021-01-01', value: 35, country: 'UK' },
|
|
63
|
-
{ date: '2020-01-01', value: 8, country: 'FR' },
|
|
64
|
-
{ date: '2021-01-01', value: 22, country: 'FR' },
|
|
65
|
-
{ date: '2020-01-01', value: 12, country: 'DE' },
|
|
66
|
-
{ date: '2021-01-01', value: 28, country: 'DE' },
|
|
67
|
-
],
|
|
68
|
-
encoding: {
|
|
69
|
-
x: { field: 'date', type: 'temporal' as const },
|
|
70
|
-
y: { field: 'value', type: 'quantitative' as const },
|
|
71
|
-
color: { field: 'country', type: 'nominal' as const },
|
|
72
|
-
},
|
|
73
|
-
chrome: {
|
|
74
|
-
title: 'GDP Growth',
|
|
75
|
-
subtitle: 'Four-country comparison',
|
|
76
|
-
source: 'World Bank',
|
|
77
|
-
},
|
|
78
|
-
legend: { show: true },
|
|
79
|
-
watermark: false,
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
const layout = compileChart(spec, { width: 800, height: 500 });
|
|
83
|
-
|
|
84
|
-
// Temporal x-axis positions shift with timezone (macOS CDT vs Linux UTC),
|
|
85
|
-
// so we strip it from the structural snapshot and assert just the labels.
|
|
86
|
-
expect(serializeLayout(layout, { stripTemporalAxes: true })).toMatchSnapshot();
|
|
87
|
-
|
|
88
|
-
const xAxes = (layout.axes as { x?: AxisShape } | undefined)?.x;
|
|
89
|
-
const tickLabels = (xAxes?.ticks ?? []).map((t: AxisTick) => t.label);
|
|
90
|
-
expect(tickLabels.length).toBeGreaterThanOrEqual(3);
|
|
91
|
-
expect(tickLabels.length).toBeLessThanOrEqual(6);
|
|
92
|
-
expect(tickLabels.every((l) => typeof l === 'string' && l.length > 0)).toBe(true);
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it('clipped-domain bar chart (data outside scale.domain filtered)', () => {
|
|
96
|
-
const spec = {
|
|
97
|
-
mark: 'bar' as const,
|
|
98
|
-
data: [
|
|
99
|
-
{ name: 'A', value: 10 },
|
|
100
|
-
{ name: 'B', value: 25 },
|
|
101
|
-
{ name: 'C', value: 40 },
|
|
102
|
-
{ name: 'D', value: 75 },
|
|
103
|
-
{ name: 'E', value: 90 },
|
|
104
|
-
],
|
|
105
|
-
encoding: {
|
|
106
|
-
x: {
|
|
107
|
-
field: 'value',
|
|
108
|
-
type: 'quantitative' as const,
|
|
109
|
-
scale: { domain: [0, 50], clip: true },
|
|
110
|
-
},
|
|
111
|
-
y: { field: 'name', type: 'nominal' as const },
|
|
112
|
-
},
|
|
113
|
-
chrome: {
|
|
114
|
-
title: 'Clipped Values',
|
|
115
|
-
},
|
|
116
|
-
watermark: false,
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
const layout = compileChart(spec, { width: 600, height: 400 });
|
|
120
|
-
expect(serializeLayout(layout)).toMatchSnapshot();
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
it('watermarked column chart with gradient fill', () => {
|
|
124
|
-
const spec = {
|
|
125
|
-
mark: {
|
|
126
|
-
type: 'bar' as const,
|
|
127
|
-
fill: {
|
|
128
|
-
type: 'linear' as const,
|
|
129
|
-
stops: [
|
|
130
|
-
{ offset: 0, color: '#ff0000' },
|
|
131
|
-
{ offset: 1, color: '#0000ff' },
|
|
132
|
-
],
|
|
133
|
-
},
|
|
134
|
-
},
|
|
135
|
-
data: [
|
|
136
|
-
{ category: 'A', score: 30 },
|
|
137
|
-
{ category: 'B', score: 55 },
|
|
138
|
-
{ category: 'C', score: 70 },
|
|
139
|
-
{ category: 'D', score: 45 },
|
|
140
|
-
],
|
|
141
|
-
encoding: {
|
|
142
|
-
x: { field: 'category', type: 'nominal' as const },
|
|
143
|
-
y: { field: 'score', type: 'quantitative' as const },
|
|
144
|
-
},
|
|
145
|
-
chrome: {
|
|
146
|
-
title: 'Gradient Columns',
|
|
147
|
-
source: 'Test data',
|
|
148
|
-
byline: 'By the engine',
|
|
149
|
-
},
|
|
150
|
-
watermark: true,
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
const layout = compileChart(spec, { width: 600, height: 400 });
|
|
154
|
-
expect(serializeLayout(layout)).toMatchSnapshot();
|
|
155
|
-
});
|
|
156
|
-
});
|
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { compileChart } from '../compile';
|
|
3
|
-
|
|
4
|
-
// ---------------------------------------------------------------------------
|
|
5
|
-
// Test data
|
|
6
|
-
// ---------------------------------------------------------------------------
|
|
7
|
-
|
|
8
|
-
const albumData = [
|
|
9
|
-
{ album: 'Abbey Road', artist: 'The Beatles', sales: 31 },
|
|
10
|
-
{ album: 'Thriller', artist: 'Michael Jackson', sales: 66 },
|
|
11
|
-
{ album: 'Back in Black', artist: 'AC/DC', sales: 50 },
|
|
12
|
-
{ album: 'The Dark Side of the Moon', artist: 'Pink Floyd', sales: 45 },
|
|
13
|
-
{ album: 'Rumours', artist: 'Fleetwood Mac', sales: 40 },
|
|
14
|
-
];
|
|
15
|
-
|
|
16
|
-
function makeBarSpec(axisConfig?: Record<string, unknown>) {
|
|
17
|
-
return {
|
|
18
|
-
mark: 'bar' as const,
|
|
19
|
-
data: albumData,
|
|
20
|
-
encoding: {
|
|
21
|
-
x: { field: 'sales', type: 'quantitative' as const },
|
|
22
|
-
y: {
|
|
23
|
-
field: 'album',
|
|
24
|
-
type: 'nominal' as const,
|
|
25
|
-
axis: axisConfig,
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const compileOpts = { width: 600, height: 400 };
|
|
32
|
-
|
|
33
|
-
// ---------------------------------------------------------------------------
|
|
34
|
-
// Tests
|
|
35
|
-
// ---------------------------------------------------------------------------
|
|
36
|
-
|
|
37
|
-
describe('compound axis labels (labelField)', () => {
|
|
38
|
-
it('populates subtitle on ticks when labelField is set', () => {
|
|
39
|
-
const spec = makeBarSpec({ labelField: 'artist' });
|
|
40
|
-
const layout = compileChart(spec, compileOpts);
|
|
41
|
-
|
|
42
|
-
const yTicks = layout.axes.y?.ticks ?? [];
|
|
43
|
-
expect(yTicks.length).toBeGreaterThan(0);
|
|
44
|
-
|
|
45
|
-
// Every tick should have a subtitle matching the artist for that album
|
|
46
|
-
for (const tick of yTicks) {
|
|
47
|
-
const row = albumData.find((r) => r.album === tick.label);
|
|
48
|
-
expect(row).toBeDefined();
|
|
49
|
-
expect(tick.subtitle).toBe(row!.artist);
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it('does not add subtitle when labelField is omitted', () => {
|
|
54
|
-
const spec = makeBarSpec();
|
|
55
|
-
const layout = compileChart(spec, compileOpts);
|
|
56
|
-
|
|
57
|
-
const yTicks = layout.axes.y?.ticks ?? [];
|
|
58
|
-
expect(yTicks.length).toBeGreaterThan(0);
|
|
59
|
-
|
|
60
|
-
for (const tick of yTicks) {
|
|
61
|
-
expect(tick.subtitle).toBeUndefined();
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it('handles missing labelField value gracefully', () => {
|
|
66
|
-
const dataWithMissing = [
|
|
67
|
-
{ album: 'Abbey Road', artist: 'The Beatles', sales: 31 },
|
|
68
|
-
{ album: 'Unknown Album', sales: 20 }, // no artist field
|
|
69
|
-
];
|
|
70
|
-
const spec = {
|
|
71
|
-
mark: 'bar' as const,
|
|
72
|
-
data: dataWithMissing,
|
|
73
|
-
encoding: {
|
|
74
|
-
x: { field: 'sales', type: 'quantitative' as const },
|
|
75
|
-
y: {
|
|
76
|
-
field: 'album',
|
|
77
|
-
type: 'nominal' as const,
|
|
78
|
-
axis: { labelField: 'artist' },
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
const layout = compileChart(spec, compileOpts);
|
|
84
|
-
const yTicks = layout.axes.y?.ticks ?? [];
|
|
85
|
-
|
|
86
|
-
// Abbey Road should have a subtitle
|
|
87
|
-
const abbeyRoad = yTicks.find((t) => t.label === 'Abbey Road');
|
|
88
|
-
expect(abbeyRoad?.subtitle).toBe('The Beatles');
|
|
89
|
-
|
|
90
|
-
// Unknown Album has no artist field, so subtitle should be undefined
|
|
91
|
-
const unknown = yTicks.find((t) => t.label === 'Unknown Album');
|
|
92
|
-
expect(unknown?.subtitle).toBeUndefined();
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it('maps subtitle correctly across multiple ticks', () => {
|
|
96
|
-
const spec = makeBarSpec({ labelField: 'artist' });
|
|
97
|
-
const layout = compileChart(spec, compileOpts);
|
|
98
|
-
|
|
99
|
-
const yTicks = layout.axes.y?.ticks ?? [];
|
|
100
|
-
expect(yTicks.length).toBe(5);
|
|
101
|
-
|
|
102
|
-
// Verify specific mappings
|
|
103
|
-
const thrillerTick = yTicks.find((t) => t.label === 'Thriller');
|
|
104
|
-
expect(thrillerTick?.subtitle).toBe('Michael Jackson');
|
|
105
|
-
|
|
106
|
-
const rumoursTick = yTicks.find((t) => t.label === 'Rumours');
|
|
107
|
-
expect(rumoursTick?.subtitle).toBe('Fleetwood Mac');
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
it('preserves subtitle mapping with sort: descending', () => {
|
|
111
|
-
const spec = {
|
|
112
|
-
mark: 'bar' as const,
|
|
113
|
-
data: albumData,
|
|
114
|
-
encoding: {
|
|
115
|
-
x: { field: 'sales', type: 'quantitative' as const },
|
|
116
|
-
y: {
|
|
117
|
-
field: 'album',
|
|
118
|
-
type: 'nominal' as const,
|
|
119
|
-
sort: 'descending' as const,
|
|
120
|
-
axis: { labelField: 'artist' },
|
|
121
|
-
},
|
|
122
|
-
},
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
const layout = compileChart(spec, compileOpts);
|
|
126
|
-
const yTicks = layout.axes.y?.ticks ?? [];
|
|
127
|
-
|
|
128
|
-
// Regardless of sort order, each tick should still map to the right artist
|
|
129
|
-
for (const tick of yTicks) {
|
|
130
|
-
const row = albumData.find((r) => r.album === tick.label);
|
|
131
|
-
expect(row).toBeDefined();
|
|
132
|
-
expect(tick.subtitle).toBe(row!.artist);
|
|
133
|
-
}
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
it('reserves wider dimension with labelField than without', () => {
|
|
137
|
-
const specWith = makeBarSpec({ labelField: 'artist' });
|
|
138
|
-
const specWithout = makeBarSpec();
|
|
139
|
-
|
|
140
|
-
const layoutWith = compileChart(specWith, compileOpts);
|
|
141
|
-
const layoutWithout = compileChart(specWithout, compileOpts);
|
|
142
|
-
|
|
143
|
-
// Chart area x (left edge) should be larger with labelField because more
|
|
144
|
-
// left margin is reserved for the wider compound labels
|
|
145
|
-
expect(layoutWith.area.x).toBeGreaterThanOrEqual(layoutWithout.area.x);
|
|
146
|
-
});
|
|
147
|
-
});
|