@pixerate/editor 0.166.0 → 0.168.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.
Files changed (58) hide show
  1. package/THIRD_PARTY_NOTICES.md +11 -0
  2. package/dist/agent/index.cjs +34 -34
  3. package/dist/agent/index.js +5 -5
  4. package/dist/canvas/index.cjs +6 -6
  5. package/dist/canvas/index.js +2 -2
  6. package/dist/chart/index.cjs +236 -185
  7. package/dist/chart/index.d.cts +1 -0
  8. package/dist/chart/index.d.ts +1 -0
  9. package/dist/chart/index.js +57 -6
  10. package/dist/chart/layout-families.d.cts +8 -0
  11. package/dist/chart/layout-families.d.ts +8 -0
  12. package/dist/chart/maps.d.cts +43 -0
  13. package/dist/chart/maps.d.ts +43 -0
  14. package/dist/chart/spec.d.cts +1 -1
  15. package/dist/chart/spec.d.ts +1 -1
  16. package/dist/chart/types.d.cts +10 -2
  17. package/dist/chart/types.d.ts +10 -2
  18. package/dist/chart-maps/europe.d.cts +7 -0
  19. package/dist/chart-maps/europe.d.ts +7 -0
  20. package/dist/chart-maps/index.cjs +66 -0
  21. package/dist/chart-maps/index.d.cts +1 -0
  22. package/dist/chart-maps/index.d.ts +1 -0
  23. package/dist/chart-maps/index.js +66 -0
  24. package/dist/{chunk-V5L2G22R.cjs → chunk-2F4GAZL5.cjs} +109 -95
  25. package/dist/{chunk-5UNQDC3Q.js → chunk-34UCPHYO.js} +5 -2
  26. package/dist/{chunk-6DM3PUQD.cjs → chunk-CYKWYP6D.cjs} +20 -2
  27. package/dist/{chunk-HXOBOHH2.cjs → chunk-E45AIIWY.cjs} +8 -8
  28. package/dist/{chunk-NQQDGGXY.js → chunk-FKYGM35R.js} +2 -2
  29. package/dist/{chunk-6FYIFGBW.cjs → chunk-GD34ICEX.cjs} +16 -16
  30. package/dist/{chunk-MZFZSVUJ.cjs → chunk-GTF4RYXJ.cjs} +25 -22
  31. package/dist/{chunk-ZGOHKS3X.js → chunk-HCC2LBCW.js} +20 -2
  32. package/dist/{chunk-ITANXMZD.js → chunk-M52UCHVZ.js} +127 -3
  33. package/dist/{chunk-YUFTVNLX.js → chunk-N3ACT6VJ.js} +16 -2
  34. package/dist/{chunk-XNU45TYA.js → chunk-OLCHKGGO.js} +4 -1
  35. package/dist/{chunk-FR432ROA.js → chunk-ORZF4JOO.js} +23 -4
  36. package/dist/{chunk-BPX4Z3N3.cjs → chunk-OUO3DSRT.cjs} +23 -4
  37. package/dist/{chunk-CHLV7UFP.cjs → chunk-SBAPXFPB.cjs} +51 -51
  38. package/dist/{chunk-VB2CY6EG.js → chunk-T62BRXMS.js} +3 -3
  39. package/dist/{chunk-SZWVMB3B.cjs → chunk-VKHJJUBK.cjs} +21 -18
  40. package/dist/{chunk-UUUTEVX6.cjs → chunk-WOIXNDHV.cjs} +172 -48
  41. package/dist/{chunk-DFCAR7AW.js → chunk-ZUPP4NKM.js} +3 -3
  42. package/dist/effects/authoring-session.d.cts +5 -0
  43. package/dist/effects/authoring-session.d.ts +5 -0
  44. package/dist/effects/authoring.d.cts +6 -0
  45. package/dist/effects/authoring.d.ts +6 -0
  46. package/dist/effects/index.cjs +12 -6
  47. package/dist/effects/index.js +10 -4
  48. package/dist/export/index.cjs +4 -4
  49. package/dist/export/index.js +3 -3
  50. package/dist/extensions/index.cjs +7 -7
  51. package/dist/extensions/index.js +6 -6
  52. package/dist/index.cjs +13 -13
  53. package/dist/index.js +7 -7
  54. package/dist/video-editor/index.cjs +2 -2
  55. package/dist/video-editor/index.js +1 -1
  56. package/package.json +11 -1
  57. package/skills/pixerate-chart/SKILL.md +18 -2
  58. package/skills/pixerate-effect-authoring/SKILL.md +11 -4
@@ -3,6 +3,7 @@ export * from './spec.cjs';
3
3
  export * from './tree.cjs';
4
4
  export * from './links.cjs';
5
5
  export * from './race.cjs';
6
+ export * from './maps.cjs';
6
7
  export * from './scale.cjs';
7
8
  export * from './numfmt.cjs';
8
9
  export * from './color.cjs';
@@ -3,6 +3,7 @@ export * from './spec.js';
3
3
  export * from './tree.js';
4
4
  export * from './links.js';
5
5
  export * from './race.js';
6
+ export * from './maps.js';
6
7
  export * from './scale.js';
7
8
  export * from './numfmt.js';
8
9
  export * from './color.js';
@@ -17,7 +17,7 @@ import {
17
17
  TRENDLINE_PROPS,
18
18
  VALUE,
19
19
  WIDTH
20
- } from "../chunk-5UNQDC3Q.js";
20
+ } from "../chunk-34UCPHYO.js";
21
21
  import {
22
22
  CHART_OOXML_CONTENT_TYPE,
23
23
  CHART_OOXML_NS,
@@ -25,7 +25,7 @@ import {
25
25
  chartFormatToCode,
26
26
  chartFromOoxml,
27
27
  chartToOoxml
28
- } from "../chunk-XNU45TYA.js";
28
+ } from "../chunk-OLCHKGGO.js";
29
29
  import {
30
30
  CHART_COLOR_SCHEMES,
31
31
  CHART_LAYOUT_PRESETS,
@@ -47,7 +47,7 @@ import {
47
47
  monochromeChartPalette,
48
48
  sparklineToSvg,
49
49
  summarizeChart
50
- } from "../chunk-YUFTVNLX.js";
50
+ } from "../chunk-N3ACT6VJ.js";
51
51
  import "../chunk-KGRZMHZB.js";
52
52
  import {
53
53
  CHART_DATE_STEPS,
@@ -58,6 +58,9 @@ import {
58
58
  chartDateLabels,
59
59
  chartDateToSerial,
60
60
  chartHistogram,
61
+ chartMapBreaks,
62
+ chartMapClass,
63
+ chartMapRamp,
61
64
  chartMovingAverage,
62
65
  chartQuantile,
63
66
  chartRaceMoment,
@@ -79,19 +82,23 @@ import {
79
82
  formatChartDate,
80
83
  formatChartNumber,
81
84
  formatChartValueWithCode,
85
+ getChartMap,
82
86
  layoutChart,
83
87
  linearMap,
88
+ listChartMaps,
89
+ matchChartMapRegions,
84
90
  niceLogScale,
85
91
  niceScale,
86
92
  niceStep,
87
93
  parseChartDate,
94
+ registerChartMap,
88
95
  sameChartSelection,
89
96
  snapChartValue,
90
97
  stepDecimals,
91
98
  suggestChartReferences,
92
99
  summarizeChartSeries,
93
100
  trendNumberText
94
- } from "../chunk-ITANXMZD.js";
101
+ } from "../chunk-M52UCHVZ.js";
95
102
  import {
96
103
  CHART_AXIS_KINDS,
97
104
  CHART_AXIS_SCALES,
@@ -185,7 +192,7 @@ import {
185
192
  shadeChartColor,
186
193
  simulateChartVision,
187
194
  uniqueChartSeriesId
188
- } from "../chunk-FR432ROA.js";
195
+ } from "../chunk-ORZF4JOO.js";
189
196
  import "../chunk-O6OGNDND.js";
190
197
  import "../chunk-II2WIF5Z.js";
191
198
  import {
@@ -899,6 +906,22 @@ function createChartCommands(controller, options = {}) {
899
906
  return { links: controller.getSpec().links };
900
907
  }
901
908
  },
909
+ {
910
+ ...base,
911
+ id: `${prefix}mapRegions`,
912
+ label: "Map Regions",
913
+ readOnly: true,
914
+ keywords: ["chart", "map", "choropleth", "regions", "countries", "codes"],
915
+ description: "Lists the regions of the chart's map (or another registered map) and which categories match none.",
916
+ params: object({ map: { type: "string", description: "Map id (default: the chart's map)." } }),
917
+ run: (_ctx, params = {}) => {
918
+ const id = params?.map ?? controller.getSpec().map;
919
+ const geometry = getChartMap(id);
920
+ if (!geometry) fail(`There is no map "${id}"; register it with registerChartMap.`);
921
+ const matches = matchChartMapRegions(geometry, controller.getSpec().categories);
922
+ return { regions: geometry.regions.map((r) => ({ id: r.id, name: r.name })), unmatched: controller.getSpec().categories.filter((_, i) => !matches[i]) };
923
+ }
924
+ },
902
925
  {
903
926
  ...base,
904
927
  id: `${prefix}raceRanking`,
@@ -1752,6 +1775,27 @@ function createChartToolProvider(controller, options = {}) {
1752
1775
  annotations: { title: "Read a bar race ranking", ...READ },
1753
1776
  handler: ({ time }) => raceAt(time !== void 0 ? raceFrameOf(time) : controller.getState().raceFrame)
1754
1777
  };
1778
+ const mapRegions = {
1779
+ name: "list_chart_map_regions",
1780
+ title: "List map regions",
1781
+ description: "Lists the maps a choropleth can draw and the regions of one (default: the chart's map), each with the id and name that categories may use, and how the chart's categories match them: matched (category \u2192 region id) and unmatched. Use it to pick category labels before set_chart_data, and to fix unmatched ones.",
1782
+ inputSchema: { type: "object", properties: { map: { type: "string", description: "Map id (default: the chart's map)." } }, additionalProperties: false },
1783
+ annotations: { title: "List map regions", ...READ },
1784
+ handler: ({ map }) => {
1785
+ const id = map ?? spec().map;
1786
+ const maps = listChartMaps().map((m) => ({ id: m.id, name: m.name, regions: m.regions.length }));
1787
+ const geometry = getChartMap(id);
1788
+ if (!geometry) fail2(maps.length ? `There is no map "${id}"; the host has ${maps.map((m) => `"${m.id}"`).join(", ")}.` : `There is no map "${id}": the host has not registered any maps (EUROPE_CHART_MAP in @pixerate/editor/chart-maps).`);
1789
+ const matches = matchChartMapRegions(geometry, spec().categories);
1790
+ return {
1791
+ maps,
1792
+ map: id,
1793
+ regions: geometry.regions.map((r) => ({ id: r.id, name: r.name })),
1794
+ matched: spec().categories.flatMap((c, i) => matches[i] ? [{ category: c, region: matches[i].id }] : []),
1795
+ unmatched: spec().categories.filter((_, i) => !matches[i])
1796
+ };
1797
+ }
1798
+ };
1755
1799
  const listPresets = {
1756
1800
  name: "list_chart_presets",
1757
1801
  title: "List chart presets",
@@ -2432,7 +2476,7 @@ function createChartToolProvider(controller, options = {}) {
2432
2476
  return { redone, ...redone ? { label } : {} };
2433
2477
  }
2434
2478
  };
2435
- const reads = [getChart, renderChart, checkColors, recommend, getTrendline, raceRanking, listPresets, exportMermaid, exportOoxml];
2479
+ const reads = [getChart, renderChart, checkColors, recommend, getTrendline, raceRanking, mapRegions, listPresets, exportMermaid, exportOoxml];
2436
2480
  const writes = [
2437
2481
  updateChart,
2438
2482
  setData,
@@ -3224,6 +3268,9 @@ export {
3224
3268
  chartLikertColor,
3225
3269
  chartLinksFromTable,
3226
3270
  chartLuminance,
3271
+ chartMapBreaks,
3272
+ chartMapClass,
3273
+ chartMapRamp,
3227
3274
  chartMermaidFamily,
3228
3275
  chartMovingAverage,
3229
3276
  chartPointAnchor,
@@ -3306,13 +3353,16 @@ export {
3306
3353
  formatChartDate,
3307
3354
  formatChartNumber,
3308
3355
  formatChartValueWithCode,
3356
+ getChartMap,
3309
3357
  handleChartKey,
3310
3358
  isCartesianChart,
3311
3359
  isXyChart,
3312
3360
  layoutChart,
3313
3361
  layoutSparkline,
3314
3362
  linearMap,
3363
+ listChartMaps,
3315
3364
  locateChartPoint,
3365
+ matchChartMapRegions,
3316
3366
  monochromeChartPalette,
3317
3367
  niceLogScale,
3318
3368
  niceScale,
@@ -3337,6 +3387,7 @@ export {
3337
3387
  realChartClock,
3338
3388
  recommendChartTypes,
3339
3389
  recommendForShape,
3390
+ registerChartMap,
3340
3391
  removeChartTreeRow,
3341
3392
  resolveChartSvgPaints,
3342
3393
  sameChartSelection,
@@ -52,3 +52,11 @@ export declare function layoutSankey(ctx: LayoutCtx, area: ChartRect, series: Ch
52
52
  * which match bars by series) animates the race. The time point is written large in a corner.
53
53
  */
54
54
  export declare function layoutBarRace(ctx: LayoutCtx, area: ChartRect, frame: number | null | undefined): FamilyResult;
55
+ /**
56
+ * Choropleth: the regions of a registered map (`spec.map`) shaded by the first series, one class
57
+ * per `mapSteps` (or `mapThresholds`), light to dark. Each category names a region by id or name;
58
+ * regions without data are grey and neighbouring land is drawn behind. Regions too small to see
59
+ * get a marker at their centre. The class legend runs along the bottom. The map must be
60
+ * registered and match a category (`layoutChart` draws bars otherwise).
61
+ */
62
+ export declare function layoutChoropleth(ctx: LayoutCtx, area: ChartRect, series: ChartSeries): FamilyResult;
@@ -52,3 +52,11 @@ export declare function layoutSankey(ctx: LayoutCtx, area: ChartRect, series: Ch
52
52
  * which match bars by series) animates the race. The time point is written large in a corner.
53
53
  */
54
54
  export declare function layoutBarRace(ctx: LayoutCtx, area: ChartRect, frame: number | null | undefined): FamilyResult;
55
+ /**
56
+ * Choropleth: the regions of a registered map (`spec.map`) shaded by the first series, one class
57
+ * per `mapSteps` (or `mapThresholds`), light to dark. Each category names a region by id or name;
58
+ * regions without data are grey and neighbouring land is drawn behind. Regions too small to see
59
+ * get a marker at their centre. The class legend runs along the bottom. The map must be
60
+ * registered and match a category (`layoutChart` draws bars otherwise).
61
+ */
62
+ export declare function layoutChoropleth(ctx: LayoutCtx, area: ChartRect, series: ChartSeries): FamilyResult;
@@ -0,0 +1,43 @@
1
+ /** One region of a map: an id (ISO 3166-1 alpha-3 for countries), a name and its outline. */
2
+ export interface ChartMapRegion {
3
+ id: string;
4
+ name: string;
5
+ /** SVG path data in the map's box (absolute M / L / Z commands). */
6
+ d: string;
7
+ /** Where a label or a marker goes, in the map's box. */
8
+ center: [number, number];
9
+ /** Area in square box units (0 for a region too small to outline, drawn as a marker). */
10
+ area: number;
11
+ }
12
+ export interface ChartMapGeometry {
13
+ /** What `spec.map` names, e.g. `europe`. */
14
+ id: string;
15
+ name: string;
16
+ width: number;
17
+ height: number;
18
+ regions: ChartMapRegion[];
19
+ /** Land in the frame that is not a region (neighbouring countries), drawn as background. */
20
+ land?: string;
21
+ /** Credit to show with the map (Natural Earth asks for none, but welcomes it). */
22
+ attribution?: string;
23
+ }
24
+ /** Makes a map available to choropleth charts (`spec.map` = its id). Registering an id again replaces it. */
25
+ export declare function registerChartMap(map: ChartMapGeometry): void;
26
+ /** A registered map by id, or undefined. */
27
+ export declare function getChartMap(id: string): ChartMapGeometry | undefined;
28
+ /** Every registered map. */
29
+ export declare function listChartMaps(): ChartMapGeometry[];
30
+ /**
31
+ * The region each category names, matched by id (any case) or by name (ignoring case and
32
+ * accents), or null. Several categories may not name the same region: the first wins.
33
+ */
34
+ export declare function matchChartMapRegions(map: ChartMapGeometry, categories: readonly string[]): (ChartMapRegion | null)[];
35
+ /**
36
+ * Class breaks for a choropleth: `thresholds` when given (ascending), else `steps` equal
37
+ * intervals between the smallest and largest value. Returns the inner breaks (one fewer than the classes).
38
+ */
39
+ export declare function chartMapBreaks(values: readonly number[], steps: number, thresholds: readonly number[]): number[];
40
+ /** The class (0-based) a value falls in: the number of breaks at or below it. */
41
+ export declare const chartMapClass: (value: number, breaks: readonly number[]) => number;
42
+ /** A light-to-dark ramp of `count` shades of `base`, one per class. */
43
+ export declare function chartMapRamp(base: string, count: number): string[];
@@ -0,0 +1,43 @@
1
+ /** One region of a map: an id (ISO 3166-1 alpha-3 for countries), a name and its outline. */
2
+ export interface ChartMapRegion {
3
+ id: string;
4
+ name: string;
5
+ /** SVG path data in the map's box (absolute M / L / Z commands). */
6
+ d: string;
7
+ /** Where a label or a marker goes, in the map's box. */
8
+ center: [number, number];
9
+ /** Area in square box units (0 for a region too small to outline, drawn as a marker). */
10
+ area: number;
11
+ }
12
+ export interface ChartMapGeometry {
13
+ /** What `spec.map` names, e.g. `europe`. */
14
+ id: string;
15
+ name: string;
16
+ width: number;
17
+ height: number;
18
+ regions: ChartMapRegion[];
19
+ /** Land in the frame that is not a region (neighbouring countries), drawn as background. */
20
+ land?: string;
21
+ /** Credit to show with the map (Natural Earth asks for none, but welcomes it). */
22
+ attribution?: string;
23
+ }
24
+ /** Makes a map available to choropleth charts (`spec.map` = its id). Registering an id again replaces it. */
25
+ export declare function registerChartMap(map: ChartMapGeometry): void;
26
+ /** A registered map by id, or undefined. */
27
+ export declare function getChartMap(id: string): ChartMapGeometry | undefined;
28
+ /** Every registered map. */
29
+ export declare function listChartMaps(): ChartMapGeometry[];
30
+ /**
31
+ * The region each category names, matched by id (any case) or by name (ignoring case and
32
+ * accents), or null. Several categories may not name the same region: the first wins.
33
+ */
34
+ export declare function matchChartMapRegions(map: ChartMapGeometry, categories: readonly string[]): (ChartMapRegion | null)[];
35
+ /**
36
+ * Class breaks for a choropleth: `thresholds` when given (ascending), else `steps` equal
37
+ * intervals between the smallest and largest value. Returns the inner breaks (one fewer than the classes).
38
+ */
39
+ export declare function chartMapBreaks(values: readonly number[], steps: number, thresholds: readonly number[]): number[];
40
+ /** The class (0-based) a value falls in: the number of breaks at or below it. */
41
+ export declare const chartMapClass: (value: number, breaks: readonly number[]) => number;
42
+ /** A light-to-dark ramp of `count` shades of `base`, one per class. */
43
+ export declare function chartMapRamp(base: string, count: number): string[];
@@ -19,7 +19,7 @@ export declare const CHART_NUMBER_STYLES: readonly NonNullable<ChartNumberFormat
19
19
  /** Labels for pickers, shared by the React and Svelte components. */
20
20
  export declare const CHART_TYPE_LABELS: Readonly<Record<ChartType, string>>;
21
21
  /** How a chart type is laid out. */
22
- export type ChartFamily = 'cartesian' | 'xy' | 'pie' | 'radar' | 'waterfall' | 'histogram' | 'box' | 'funnel' | 'treemap' | 'slope' | 'likert' | 'parliament' | 'sunburst' | 'sankey' | 'barrace';
22
+ export type ChartFamily = 'cartesian' | 'xy' | 'pie' | 'radar' | 'waterfall' | 'histogram' | 'box' | 'funnel' | 'treemap' | 'slope' | 'likert' | 'parliament' | 'sunburst' | 'sankey' | 'barrace' | 'choropleth';
23
23
  /** A colour-blind-friendly categorical palette (Okabe–Ito order, tuned for light and dark backgrounds). */
24
24
  export declare const DEFAULT_CHART_PALETTE: readonly string[];
25
25
  export declare const DEFAULT_CHART_THEME: ChartTheme;
@@ -19,7 +19,7 @@ export declare const CHART_NUMBER_STYLES: readonly NonNullable<ChartNumberFormat
19
19
  /** Labels for pickers, shared by the React and Svelte components. */
20
20
  export declare const CHART_TYPE_LABELS: Readonly<Record<ChartType, string>>;
21
21
  /** How a chart type is laid out. */
22
- export type ChartFamily = 'cartesian' | 'xy' | 'pie' | 'radar' | 'waterfall' | 'histogram' | 'box' | 'funnel' | 'treemap' | 'slope' | 'likert' | 'parliament' | 'sunburst' | 'sankey' | 'barrace';
22
+ export type ChartFamily = 'cartesian' | 'xy' | 'pie' | 'radar' | 'waterfall' | 'histogram' | 'box' | 'funnel' | 'treemap' | 'slope' | 'likert' | 'parliament' | 'sunburst' | 'sankey' | 'barrace' | 'choropleth';
23
23
  /** A colour-blind-friendly categorical palette (Okabe–Ito order, tuned for light and dark backgrounds). */
24
24
  export declare const DEFAULT_CHART_PALETTE: readonly string[];
25
25
  export declare const DEFAULT_CHART_THEME: ChartTheme;
@@ -19,8 +19,10 @@
19
19
  * - `sankey` draws `links` as flows between columns of nodes.
20
20
  * - `barrace` reads each category as a time point and each series as a name, and draws the
21
21
  * top `raceTopN` names at one moment as ranked horizontal bars (an animated ranking).
22
+ * - `choropleth` shades the regions of a registered map (`map`) by the first series, each
23
+ * category naming a region by id (ISO alpha-3 for countries) or name.
22
24
  */
23
- export type ChartType = 'bar' | 'line' | 'area' | 'scatter' | 'bubble' | 'pie' | 'donut' | 'radar' | 'waterfall' | 'histogram' | 'box' | 'funnel' | 'treemap' | 'slope' | 'likert' | 'parliament' | 'sunburst' | 'sankey' | 'barrace';
25
+ export type ChartType = 'bar' | 'line' | 'area' | 'scatter' | 'bubble' | 'pie' | 'donut' | 'radar' | 'waterfall' | 'histogram' | 'box' | 'funnel' | 'treemap' | 'slope' | 'likert' | 'parliament' | 'sunburst' | 'sankey' | 'barrace' | 'choropleth';
24
26
  /** How a series is drawn in a cartesian chart. */
25
27
  export type ChartSeriesType = 'bar' | 'line' | 'area' | 'scatter';
26
28
  /** One data value; `null` is a gap (missing value). */
@@ -303,6 +305,12 @@ export interface ChartSpec {
303
305
  sankeyLinkColor: ChartSankeyLinkColor;
304
306
  /** Bar race: how many bars each moment shows, 1–30. */
305
307
  raceTopN: number;
308
+ /** Choropleth: the registered map to draw (see `registerChartMap`; `@pixerate/editor/chart-maps` has `europe`). */
309
+ map: string;
310
+ /** Choropleth: number of equal colour classes between the smallest and largest value, 2–9. */
311
+ mapSteps: number;
312
+ /** Choropleth: class breaks in ascending order, instead of `mapSteps` ([] for none). */
313
+ mapThresholds: number[];
306
314
  }
307
315
  /** What a click selects. */
308
316
  export type ChartSelection = {
@@ -358,7 +366,7 @@ export interface ChartRect {
358
366
  height: number;
359
367
  }
360
368
  /** What a mark is, for styling and tests. */
361
- export type ChartMarkRole = 'background' | 'title' | 'subtitle' | 'grid' | 'axis' | 'tick' | 'tick-label' | 'axis-title' | 'bar' | 'line' | 'area' | 'point' | 'slice' | 'cell' | 'box' | 'whisker' | 'outlier' | 'connector' | 'trendline' | 'trendline-label' | 'error-bar' | 'data-label' | 'legend-swatch' | 'legend-label' | 'drag-readout' | 'reference-line' | 'reference-band' | 'reference-label' | 'callout' | 'node' | 'race-time' | 'link' | 'note' | 'selection' | 'empty';
369
+ export type ChartMarkRole = 'background' | 'title' | 'subtitle' | 'grid' | 'axis' | 'tick' | 'tick-label' | 'axis-title' | 'bar' | 'line' | 'area' | 'point' | 'slice' | 'cell' | 'box' | 'whisker' | 'outlier' | 'connector' | 'trendline' | 'trendline-label' | 'error-bar' | 'data-label' | 'legend-swatch' | 'legend-label' | 'drag-readout' | 'reference-line' | 'reference-band' | 'reference-label' | 'callout' | 'node' | 'race-time' | 'region' | 'map-land' | 'link' | 'note' | 'selection' | 'empty';
362
370
  interface ChartMarkBase {
363
371
  /** Unique within the scene (a stable key for frameworks). */
364
372
  key: string;
@@ -19,8 +19,10 @@
19
19
  * - `sankey` draws `links` as flows between columns of nodes.
20
20
  * - `barrace` reads each category as a time point and each series as a name, and draws the
21
21
  * top `raceTopN` names at one moment as ranked horizontal bars (an animated ranking).
22
+ * - `choropleth` shades the regions of a registered map (`map`) by the first series, each
23
+ * category naming a region by id (ISO alpha-3 for countries) or name.
22
24
  */
23
- export type ChartType = 'bar' | 'line' | 'area' | 'scatter' | 'bubble' | 'pie' | 'donut' | 'radar' | 'waterfall' | 'histogram' | 'box' | 'funnel' | 'treemap' | 'slope' | 'likert' | 'parliament' | 'sunburst' | 'sankey' | 'barrace';
25
+ export type ChartType = 'bar' | 'line' | 'area' | 'scatter' | 'bubble' | 'pie' | 'donut' | 'radar' | 'waterfall' | 'histogram' | 'box' | 'funnel' | 'treemap' | 'slope' | 'likert' | 'parliament' | 'sunburst' | 'sankey' | 'barrace' | 'choropleth';
24
26
  /** How a series is drawn in a cartesian chart. */
25
27
  export type ChartSeriesType = 'bar' | 'line' | 'area' | 'scatter';
26
28
  /** One data value; `null` is a gap (missing value). */
@@ -303,6 +305,12 @@ export interface ChartSpec {
303
305
  sankeyLinkColor: ChartSankeyLinkColor;
304
306
  /** Bar race: how many bars each moment shows, 1–30. */
305
307
  raceTopN: number;
308
+ /** Choropleth: the registered map to draw (see `registerChartMap`; `@pixerate/editor/chart-maps` has `europe`). */
309
+ map: string;
310
+ /** Choropleth: number of equal colour classes between the smallest and largest value, 2–9. */
311
+ mapSteps: number;
312
+ /** Choropleth: class breaks in ascending order, instead of `mapSteps` ([] for none). */
313
+ mapThresholds: number[];
306
314
  }
307
315
  /** What a click selects. */
308
316
  export type ChartSelection = {
@@ -358,7 +366,7 @@ export interface ChartRect {
358
366
  height: number;
359
367
  }
360
368
  /** What a mark is, for styling and tests. */
361
- export type ChartMarkRole = 'background' | 'title' | 'subtitle' | 'grid' | 'axis' | 'tick' | 'tick-label' | 'axis-title' | 'bar' | 'line' | 'area' | 'point' | 'slice' | 'cell' | 'box' | 'whisker' | 'outlier' | 'connector' | 'trendline' | 'trendline-label' | 'error-bar' | 'data-label' | 'legend-swatch' | 'legend-label' | 'drag-readout' | 'reference-line' | 'reference-band' | 'reference-label' | 'callout' | 'node' | 'race-time' | 'link' | 'note' | 'selection' | 'empty';
369
+ export type ChartMarkRole = 'background' | 'title' | 'subtitle' | 'grid' | 'axis' | 'tick' | 'tick-label' | 'axis-title' | 'bar' | 'line' | 'area' | 'point' | 'slice' | 'cell' | 'box' | 'whisker' | 'outlier' | 'connector' | 'trendline' | 'trendline-label' | 'error-bar' | 'data-label' | 'legend-swatch' | 'legend-label' | 'drag-readout' | 'reference-line' | 'reference-band' | 'reference-label' | 'callout' | 'node' | 'race-time' | 'region' | 'map-land' | 'link' | 'note' | 'selection' | 'empty';
362
370
  interface ChartMarkBase {
363
371
  /** Unique within the scene (a stable key for frameworks). */
364
372
  key: string;
@@ -0,0 +1,7 @@
1
+ import type { ChartMapGeometry } from '../chart/maps.cjs';
2
+ /**
3
+ * Europe, from Iceland to the Caucasus and from Cyprus to the North Cape, in Lambert azimuthal
4
+ * equal-area (centred on 10°E 52°N) within a 1000 × 873 box. Regions are countries keyed by
5
+ * ISO 3166-1 alpha-3 code (Kosovo: XKX). Register it with `registerChartMap(EUROPE_CHART_MAP)`.
6
+ */
7
+ export declare const EUROPE_CHART_MAP: ChartMapGeometry;
@@ -0,0 +1,7 @@
1
+ import type { ChartMapGeometry } from '../chart/maps.js';
2
+ /**
3
+ * Europe, from Iceland to the Caucasus and from Cyprus to the North Cape, in Lambert azimuthal
4
+ * equal-area (centred on 10°E 52°N) within a 1000 × 873 box. Regions are countries keyed by
5
+ * ISO 3166-1 alpha-3 code (Kosovo: XKX). Register it with `registerChartMap(EUROPE_CHART_MAP)`.
6
+ */
7
+ export declare const EUROPE_CHART_MAP: ChartMapGeometry;