@opendata-ai/openchart-core 3.0.0 → 6.1.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 +495 -46
- package/dist/index.js +157 -56
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/accessibility/__tests__/alt-text.test.ts +4 -4
- package/src/accessibility/alt-text.ts +13 -16
- package/src/helpers/__tests__/spec-builders.test.ts +8 -6
- package/src/helpers/spec-builders.ts +9 -8
- package/src/types/__tests__/encoding.test.ts +267 -0
- package/src/types/__tests__/spec.test.ts +61 -22
- package/src/types/encoding.ts +116 -35
- package/src/types/index.ts +32 -0
- package/src/types/layout.ts +131 -1
- package/src/types/spec.ts +492 -45
package/dist/index.js
CHANGED
|
@@ -5,64 +5,129 @@ function required(...types) {
|
|
|
5
5
|
function optional(...types) {
|
|
6
6
|
return { required: false, allowedTypes: types };
|
|
7
7
|
}
|
|
8
|
-
var
|
|
8
|
+
var MARK_ENCODING_RULES = {
|
|
9
|
+
bar: {
|
|
10
|
+
x: required("quantitative", "nominal", "ordinal", "temporal"),
|
|
11
|
+
y: required("quantitative", "nominal", "ordinal"),
|
|
12
|
+
x2: optional("quantitative"),
|
|
13
|
+
y2: optional("quantitative"),
|
|
14
|
+
color: optional("nominal", "ordinal", "quantitative"),
|
|
15
|
+
size: optional(),
|
|
16
|
+
opacity: optional("quantitative"),
|
|
17
|
+
tooltip: optional(),
|
|
18
|
+
href: optional(),
|
|
19
|
+
order: optional("quantitative", "ordinal"),
|
|
20
|
+
detail: optional("nominal")
|
|
21
|
+
},
|
|
9
22
|
line: {
|
|
10
23
|
x: required("temporal", "ordinal"),
|
|
11
24
|
y: required("quantitative"),
|
|
12
|
-
color: optional("nominal", "ordinal"),
|
|
13
|
-
size: optional(
|
|
25
|
+
color: optional("nominal", "ordinal", "quantitative"),
|
|
26
|
+
size: optional(),
|
|
27
|
+
opacity: optional("quantitative"),
|
|
28
|
+
strokeDash: optional("nominal", "ordinal"),
|
|
29
|
+
tooltip: optional(),
|
|
30
|
+
href: optional(),
|
|
31
|
+
order: optional("quantitative", "ordinal"),
|
|
14
32
|
detail: optional("nominal")
|
|
15
33
|
},
|
|
16
34
|
area: {
|
|
17
35
|
x: required("temporal", "ordinal"),
|
|
18
36
|
y: required("quantitative"),
|
|
19
|
-
|
|
20
|
-
|
|
37
|
+
y2: optional("quantitative"),
|
|
38
|
+
color: optional("nominal", "ordinal", "quantitative"),
|
|
39
|
+
size: optional(),
|
|
40
|
+
opacity: optional("quantitative"),
|
|
41
|
+
tooltip: optional(),
|
|
42
|
+
href: optional(),
|
|
43
|
+
order: optional("quantitative", "ordinal"),
|
|
21
44
|
detail: optional("nominal")
|
|
22
45
|
},
|
|
23
|
-
|
|
46
|
+
point: {
|
|
24
47
|
x: required("quantitative"),
|
|
25
|
-
y: required("
|
|
48
|
+
y: required("quantitative"),
|
|
26
49
|
color: optional("nominal", "ordinal", "quantitative"),
|
|
27
50
|
size: optional("quantitative"),
|
|
51
|
+
shape: optional("nominal", "ordinal"),
|
|
52
|
+
opacity: optional("quantitative"),
|
|
53
|
+
tooltip: optional(),
|
|
54
|
+
href: optional(),
|
|
55
|
+
order: optional("quantitative", "ordinal"),
|
|
28
56
|
detail: optional("nominal")
|
|
29
57
|
},
|
|
30
|
-
|
|
31
|
-
x: required("
|
|
32
|
-
y: required("
|
|
58
|
+
circle: {
|
|
59
|
+
x: required("quantitative"),
|
|
60
|
+
y: required("nominal", "ordinal"),
|
|
33
61
|
color: optional("nominal", "ordinal", "quantitative"),
|
|
34
62
|
size: optional("quantitative"),
|
|
63
|
+
opacity: optional("quantitative"),
|
|
64
|
+
tooltip: optional(),
|
|
65
|
+
href: optional(),
|
|
66
|
+
order: optional("quantitative", "ordinal"),
|
|
35
67
|
detail: optional("nominal")
|
|
36
68
|
},
|
|
37
|
-
|
|
69
|
+
arc: {
|
|
38
70
|
x: optional(),
|
|
39
71
|
y: required("quantitative"),
|
|
40
72
|
color: required("nominal", "ordinal"),
|
|
41
|
-
size: optional(
|
|
73
|
+
size: optional(),
|
|
74
|
+
opacity: optional("quantitative"),
|
|
75
|
+
tooltip: optional(),
|
|
76
|
+
href: optional(),
|
|
77
|
+
order: optional("quantitative", "ordinal"),
|
|
78
|
+
theta: optional("quantitative"),
|
|
79
|
+
radius: optional("quantitative"),
|
|
42
80
|
detail: optional("nominal")
|
|
43
81
|
},
|
|
44
|
-
|
|
82
|
+
text: {
|
|
45
83
|
x: optional(),
|
|
46
|
-
y:
|
|
47
|
-
color:
|
|
84
|
+
y: optional(),
|
|
85
|
+
color: optional(),
|
|
48
86
|
size: optional("quantitative"),
|
|
87
|
+
opacity: optional("quantitative"),
|
|
88
|
+
text: required(),
|
|
89
|
+
tooltip: optional(),
|
|
90
|
+
href: optional(),
|
|
49
91
|
detail: optional("nominal")
|
|
50
92
|
},
|
|
51
|
-
|
|
52
|
-
x:
|
|
53
|
-
y:
|
|
54
|
-
|
|
55
|
-
|
|
93
|
+
rule: {
|
|
94
|
+
x: optional(),
|
|
95
|
+
y: optional(),
|
|
96
|
+
x2: optional(),
|
|
97
|
+
y2: optional(),
|
|
98
|
+
color: optional(),
|
|
99
|
+
size: optional(),
|
|
100
|
+
opacity: optional("quantitative"),
|
|
101
|
+
strokeDash: optional("nominal", "ordinal"),
|
|
102
|
+
tooltip: optional(),
|
|
103
|
+
href: optional(),
|
|
56
104
|
detail: optional("nominal")
|
|
57
105
|
},
|
|
58
|
-
|
|
59
|
-
x: required(
|
|
60
|
-
y: required(
|
|
61
|
-
color: optional(
|
|
62
|
-
size: optional(
|
|
106
|
+
tick: {
|
|
107
|
+
x: required(),
|
|
108
|
+
y: required(),
|
|
109
|
+
color: optional(),
|
|
110
|
+
size: optional(),
|
|
111
|
+
opacity: optional("quantitative"),
|
|
112
|
+
tooltip: optional(),
|
|
113
|
+
href: optional(),
|
|
114
|
+
detail: optional("nominal")
|
|
115
|
+
},
|
|
116
|
+
rect: {
|
|
117
|
+
x: required(),
|
|
118
|
+
y: required(),
|
|
119
|
+
x2: optional(),
|
|
120
|
+
y2: optional(),
|
|
121
|
+
color: optional(),
|
|
122
|
+
size: optional(),
|
|
123
|
+
opacity: optional("quantitative"),
|
|
124
|
+
tooltip: optional(),
|
|
125
|
+
href: optional(),
|
|
126
|
+
order: optional("quantitative", "ordinal"),
|
|
63
127
|
detail: optional("nominal")
|
|
64
128
|
}
|
|
65
129
|
};
|
|
130
|
+
var CHART_ENCODING_RULES = MARK_ENCODING_RULES;
|
|
66
131
|
var GRAPH_ENCODING_RULES = {
|
|
67
132
|
nodeColor: { required: false, allowedTypes: ["nominal", "ordinal"] },
|
|
68
133
|
nodeSize: { required: false, allowedTypes: ["quantitative"] },
|
|
@@ -72,24 +137,44 @@ var GRAPH_ENCODING_RULES = {
|
|
|
72
137
|
};
|
|
73
138
|
|
|
74
139
|
// src/types/spec.ts
|
|
75
|
-
|
|
140
|
+
function isEncodingChannel(def) {
|
|
141
|
+
if (!def) return false;
|
|
142
|
+
return "field" in def && !("condition" in def);
|
|
143
|
+
}
|
|
144
|
+
function isConditionalDef(def) {
|
|
145
|
+
if (!def) return false;
|
|
146
|
+
return "condition" in def;
|
|
147
|
+
}
|
|
148
|
+
var MARK_TYPES = /* @__PURE__ */ new Set([
|
|
149
|
+
"bar",
|
|
76
150
|
"line",
|
|
77
151
|
"area",
|
|
78
|
-
"
|
|
79
|
-
"
|
|
80
|
-
"
|
|
81
|
-
"
|
|
82
|
-
"
|
|
83
|
-
"
|
|
152
|
+
"point",
|
|
153
|
+
"circle",
|
|
154
|
+
"arc",
|
|
155
|
+
"text",
|
|
156
|
+
"rule",
|
|
157
|
+
"tick",
|
|
158
|
+
"rect"
|
|
84
159
|
]);
|
|
160
|
+
var CHART_TYPES = MARK_TYPES;
|
|
161
|
+
function resolveMarkType(mark) {
|
|
162
|
+
return typeof mark === "string" ? mark : mark.type;
|
|
163
|
+
}
|
|
164
|
+
function resolveMarkDef(mark) {
|
|
165
|
+
return typeof mark === "string" ? { type: mark } : mark;
|
|
166
|
+
}
|
|
85
167
|
function isChartSpec(spec) {
|
|
86
|
-
return
|
|
168
|
+
return "mark" in spec && !("layer" in spec);
|
|
169
|
+
}
|
|
170
|
+
function isLayerSpec(spec) {
|
|
171
|
+
return "layer" in spec && Array.isArray(spec.layer);
|
|
87
172
|
}
|
|
88
173
|
function isTableSpec(spec) {
|
|
89
|
-
return spec.type === "table";
|
|
174
|
+
return "type" in spec && spec.type === "table";
|
|
90
175
|
}
|
|
91
176
|
function isGraphSpec(spec) {
|
|
92
|
-
return spec.type === "graph";
|
|
177
|
+
return "type" in spec && spec.type === "graph";
|
|
93
178
|
}
|
|
94
179
|
function isTextAnnotation(annotation) {
|
|
95
180
|
return annotation.type === "text";
|
|
@@ -100,6 +185,19 @@ function isRangeAnnotation(annotation) {
|
|
|
100
185
|
function isRefLineAnnotation(annotation) {
|
|
101
186
|
return annotation.type === "refline";
|
|
102
187
|
}
|
|
188
|
+
var MARK_DISPLAY_NAMES = {
|
|
189
|
+
bar: "Bar chart",
|
|
190
|
+
line: "Line chart",
|
|
191
|
+
area: "Area chart",
|
|
192
|
+
point: "Scatter plot",
|
|
193
|
+
circle: "Dot plot",
|
|
194
|
+
arc: "Pie chart",
|
|
195
|
+
// overridden to "Donut chart" when innerRadius > 0
|
|
196
|
+
text: "Text chart",
|
|
197
|
+
rule: "Rule chart",
|
|
198
|
+
tick: "Tick plot",
|
|
199
|
+
rect: "Heatmap"
|
|
200
|
+
};
|
|
103
201
|
|
|
104
202
|
// ../../node_modules/.bun/d3-color@3.1.0/node_modules/d3-color/src/define.js
|
|
105
203
|
function define_default(constructor, factory, prototype) {
|
|
@@ -2312,18 +2410,13 @@ function inferGranularity(date) {
|
|
|
2312
2410
|
}
|
|
2313
2411
|
|
|
2314
2412
|
// src/accessibility/alt-text.ts
|
|
2315
|
-
var CHART_TYPE_NAMES = {
|
|
2316
|
-
line: "Line chart",
|
|
2317
|
-
area: "Area chart",
|
|
2318
|
-
bar: "Bar chart",
|
|
2319
|
-
column: "Column chart",
|
|
2320
|
-
pie: "Pie chart",
|
|
2321
|
-
donut: "Donut chart",
|
|
2322
|
-
dot: "Dot plot",
|
|
2323
|
-
scatter: "Scatter plot"
|
|
2324
|
-
};
|
|
2325
2413
|
function generateAltText(spec, data) {
|
|
2326
|
-
const
|
|
2414
|
+
const markType = resolveMarkType(spec.mark);
|
|
2415
|
+
const markDef = resolveMarkDef(spec.mark);
|
|
2416
|
+
let chartName = MARK_DISPLAY_NAMES[markType] ?? `${markType} chart`;
|
|
2417
|
+
if (markType === "arc" && markDef.innerRadius && markDef.innerRadius > 0) {
|
|
2418
|
+
chartName = "Donut chart";
|
|
2419
|
+
}
|
|
2327
2420
|
const parts = [chartName];
|
|
2328
2421
|
const title = spec.chrome?.title;
|
|
2329
2422
|
if (title) {
|
|
@@ -2351,7 +2444,7 @@ function generateAltText(spec, data) {
|
|
|
2351
2444
|
}
|
|
2352
2445
|
}
|
|
2353
2446
|
}
|
|
2354
|
-
if (spec.encoding.color && data.length > 0) {
|
|
2447
|
+
if (spec.encoding.color && "field" in spec.encoding.color && data.length > 0) {
|
|
2355
2448
|
const colorField = spec.encoding.color.field;
|
|
2356
2449
|
const uniqueSeries = [...new Set(data.map((d) => String(d[colorField])).filter(Boolean))];
|
|
2357
2450
|
if (uniqueSeries.length > 0) {
|
|
@@ -2366,8 +2459,8 @@ function generateDataTable(spec, data) {
|
|
|
2366
2459
|
const encoding = spec.encoding;
|
|
2367
2460
|
if (encoding.x) fields.push(encoding.x.field);
|
|
2368
2461
|
if (encoding.y) fields.push(encoding.y.field);
|
|
2369
|
-
if (encoding.color) fields.push(encoding.color.field);
|
|
2370
|
-
if (encoding.size) fields.push(encoding.size.field);
|
|
2462
|
+
if (encoding.color && "field" in encoding.color) fields.push(encoding.color.field);
|
|
2463
|
+
if (encoding.size && "field" in encoding.size) fields.push(encoding.size.field);
|
|
2371
2464
|
const uniqueFields = [...new Set(fields)];
|
|
2372
2465
|
if (uniqueFields.length === 0) return [];
|
|
2373
2466
|
const headers = uniqueFields;
|
|
@@ -2468,8 +2561,8 @@ function buildEncoding(channels, options, data) {
|
|
|
2468
2561
|
}
|
|
2469
2562
|
return encoding;
|
|
2470
2563
|
}
|
|
2471
|
-
function buildChartSpec(
|
|
2472
|
-
const spec = {
|
|
2564
|
+
function buildChartSpec(mark, data, encoding, options) {
|
|
2565
|
+
const spec = { mark, data, encoding };
|
|
2473
2566
|
if (options?.chrome) spec.chrome = options.chrome;
|
|
2474
2567
|
if (options?.annotations) spec.annotations = options.annotations;
|
|
2475
2568
|
if (options?.responsive !== void 0) spec.responsive = options.responsive;
|
|
@@ -2493,7 +2586,7 @@ function columnChart(data, x, y, options) {
|
|
|
2493
2586
|
const xChannel = resolveField(x, data);
|
|
2494
2587
|
const yChannel = resolveField(y, data);
|
|
2495
2588
|
const encoding = buildEncoding({ x: xChannel, y: yChannel }, options, data);
|
|
2496
|
-
return buildChartSpec("
|
|
2589
|
+
return buildChartSpec({ type: "bar" }, data, encoding, options);
|
|
2497
2590
|
}
|
|
2498
2591
|
function pieChart(data, category, value, options) {
|
|
2499
2592
|
const categoryChannel = resolveField(category, data);
|
|
@@ -2505,7 +2598,7 @@ function pieChart(data, category, value, options) {
|
|
|
2505
2598
|
if (options?.size && data) {
|
|
2506
2599
|
encoding.size = resolveField(options.size, data);
|
|
2507
2600
|
}
|
|
2508
|
-
return buildChartSpec("
|
|
2601
|
+
return buildChartSpec("arc", data, encoding, options);
|
|
2509
2602
|
}
|
|
2510
2603
|
function areaChart(data, x, y, options) {
|
|
2511
2604
|
const xChannel = resolveField(x, data);
|
|
@@ -2523,19 +2616,19 @@ function donutChart(data, category, value, options) {
|
|
|
2523
2616
|
if (options?.size && data) {
|
|
2524
2617
|
encoding.size = resolveField(options.size, data);
|
|
2525
2618
|
}
|
|
2526
|
-
return buildChartSpec("
|
|
2619
|
+
return buildChartSpec({ type: "arc", innerRadius: 40 }, data, encoding, options);
|
|
2527
2620
|
}
|
|
2528
2621
|
function dotChart(data, x, y, options) {
|
|
2529
2622
|
const xChannel = resolveField(x, data);
|
|
2530
2623
|
const yChannel = resolveField(y, data);
|
|
2531
2624
|
const encoding = buildEncoding({ x: xChannel, y: yChannel }, options, data);
|
|
2532
|
-
return buildChartSpec("
|
|
2625
|
+
return buildChartSpec("circle", data, encoding, options);
|
|
2533
2626
|
}
|
|
2534
2627
|
function scatterChart(data, x, y, options) {
|
|
2535
2628
|
const xChannel = resolveField(x, data);
|
|
2536
2629
|
const yChannel = resolveField(y, data);
|
|
2537
2630
|
const encoding = buildEncoding({ x: xChannel, y: yChannel }, options, data);
|
|
2538
|
-
return buildChartSpec("
|
|
2631
|
+
return buildChartSpec("point", data, encoding, options);
|
|
2539
2632
|
}
|
|
2540
2633
|
function dataTable(data, options) {
|
|
2541
2634
|
let columns = options?.columns;
|
|
@@ -2574,6 +2667,9 @@ export {
|
|
|
2574
2667
|
DEFAULT_THEME,
|
|
2575
2668
|
DIVERGING_PALETTES,
|
|
2576
2669
|
GRAPH_ENCODING_RULES,
|
|
2670
|
+
MARK_DISPLAY_NAMES,
|
|
2671
|
+
MARK_ENCODING_RULES,
|
|
2672
|
+
MARK_TYPES,
|
|
2577
2673
|
SEQUENTIAL_PALETTES,
|
|
2578
2674
|
abbreviateNumber,
|
|
2579
2675
|
adaptColorForDarkMode,
|
|
@@ -2602,7 +2698,10 @@ export {
|
|
|
2602
2698
|
getLayoutStrategy,
|
|
2603
2699
|
inferFieldType,
|
|
2604
2700
|
isChartSpec,
|
|
2701
|
+
isConditionalDef,
|
|
2702
|
+
isEncodingChannel,
|
|
2605
2703
|
isGraphSpec,
|
|
2704
|
+
isLayerSpec,
|
|
2606
2705
|
isRangeAnnotation,
|
|
2607
2706
|
isRefLineAnnotation,
|
|
2608
2707
|
isTableSpec,
|
|
@@ -2611,6 +2710,8 @@ export {
|
|
|
2611
2710
|
meetsAA,
|
|
2612
2711
|
pieChart,
|
|
2613
2712
|
resolveCollisions,
|
|
2713
|
+
resolveMarkDef,
|
|
2714
|
+
resolveMarkType,
|
|
2614
2715
|
resolveTheme,
|
|
2615
2716
|
scatterChart,
|
|
2616
2717
|
simulateColorBlindness
|