@opendata-ai/openchart-core 6.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.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 CHART_ENCODING_RULES = {
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("quantitative"),
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
- color: optional("nominal", "ordinal"),
20
- size: optional("quantitative"),
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
- bar: {
46
+ point: {
24
47
  x: required("quantitative"),
25
- y: required("nominal", "ordinal"),
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
- column: {
31
- x: required("nominal", "ordinal", "temporal"),
32
- y: required("quantitative"),
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
- pie: {
69
+ arc: {
38
70
  x: optional(),
39
71
  y: required("quantitative"),
40
72
  color: required("nominal", "ordinal"),
41
- size: optional("quantitative"),
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
- donut: {
82
+ text: {
45
83
  x: optional(),
46
- y: required("quantitative"),
47
- color: required("nominal", "ordinal"),
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
- dot: {
52
- x: required("quantitative"),
53
- y: required("nominal", "ordinal"),
54
- color: optional("nominal", "ordinal"),
55
- size: optional("quantitative"),
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
- scatter: {
59
- x: required("quantitative"),
60
- y: required("quantitative"),
61
- color: optional("nominal", "ordinal"),
62
- size: optional("quantitative"),
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
- var CHART_TYPES = /* @__PURE__ */ new Set([
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
- "bar",
79
- "column",
80
- "pie",
81
- "donut",
82
- "dot",
83
- "scatter"
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 CHART_TYPES.has(spec.type);
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 chartName = CHART_TYPE_NAMES[spec.type] ?? `${spec.type} chart`;
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(type, data, encoding, options) {
2472
- const spec = { type, data, encoding };
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("column", data, encoding, options);
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("pie", data, encoding, options);
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("donut", data, encoding, options);
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("dot", data, encoding, options);
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("scatter", data, encoding, options);
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