@loidolt/theme-charts 0.7.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 (77) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +124 -0
  3. package/dist/components/BarChart.svelte +64 -0
  4. package/dist/components/BarChart.svelte.d.ts +14 -0
  5. package/dist/components/CandlestickChart.svelte +58 -0
  6. package/dist/components/CandlestickChart.svelte.d.ts +21 -0
  7. package/dist/components/Chart.svelte +282 -0
  8. package/dist/components/Chart.svelte.d.ts +73 -0
  9. package/dist/components/ChartDataTable.svelte +79 -0
  10. package/dist/components/ChartDataTable.svelte.d.ts +23 -0
  11. package/dist/components/FunnelChart.svelte +50 -0
  12. package/dist/components/FunnelChart.svelte.d.ts +18 -0
  13. package/dist/components/GaugeChart.svelte +54 -0
  14. package/dist/components/GaugeChart.svelte.d.ts +18 -0
  15. package/dist/components/HeatmapChart.svelte +51 -0
  16. package/dist/components/HeatmapChart.svelte.d.ts +14 -0
  17. package/dist/components/LineChart.svelte +66 -0
  18. package/dist/components/LineChart.svelte.d.ts +14 -0
  19. package/dist/components/PieChart.svelte +62 -0
  20. package/dist/components/PieChart.svelte.d.ts +18 -0
  21. package/dist/components/RadarChart.svelte +48 -0
  22. package/dist/components/RadarChart.svelte.d.ts +14 -0
  23. package/dist/components/SankeyChart.svelte +48 -0
  24. package/dist/components/SankeyChart.svelte.d.ts +18 -0
  25. package/dist/components/ScatterChart.svelte +61 -0
  26. package/dist/components/ScatterChart.svelte.d.ts +18 -0
  27. package/dist/components/TreemapChart.svelte +48 -0
  28. package/dist/components/TreemapChart.svelte.d.ts +17 -0
  29. package/dist/core/builders/category.d.ts +37 -0
  30. package/dist/core/builders/category.js +109 -0
  31. package/dist/core/builders/more.d.ts +119 -0
  32. package/dist/core/builders/more.js +530 -0
  33. package/dist/core/builders/slices.d.ts +36 -0
  34. package/dist/core/builders/slices.js +117 -0
  35. package/dist/core/describe.d.ts +27 -0
  36. package/dist/core/describe.js +69 -0
  37. package/dist/core/format.d.ts +15 -0
  38. package/dist/core/format.js +39 -0
  39. package/dist/core/index.d.ts +11 -0
  40. package/dist/core/index.js +12 -0
  41. package/dist/core/theme.d.ts +30 -0
  42. package/dist/core/theme.js +137 -0
  43. package/dist/core/types.d.ts +98 -0
  44. package/dist/core/types.js +1 -0
  45. package/dist/core/validate.d.ts +4 -0
  46. package/dist/core/validate.js +10 -0
  47. package/dist/echarts/all.d.ts +3 -0
  48. package/dist/echarts/all.js +23 -0
  49. package/dist/echarts/bar.d.ts +3 -0
  50. package/dist/echarts/bar.js +2 -0
  51. package/dist/echarts/base.d.ts +3 -0
  52. package/dist/echarts/base.js +13 -0
  53. package/dist/echarts/candlestick.d.ts +3 -0
  54. package/dist/echarts/candlestick.js +3 -0
  55. package/dist/echarts/funnel.d.ts +3 -0
  56. package/dist/echarts/funnel.js +2 -0
  57. package/dist/echarts/gauge.d.ts +3 -0
  58. package/dist/echarts/gauge.js +2 -0
  59. package/dist/echarts/heatmap.d.ts +3 -0
  60. package/dist/echarts/heatmap.js +3 -0
  61. package/dist/echarts/line.d.ts +3 -0
  62. package/dist/echarts/line.js +2 -0
  63. package/dist/echarts/pie.d.ts +3 -0
  64. package/dist/echarts/pie.js +2 -0
  65. package/dist/echarts/radar.d.ts +3 -0
  66. package/dist/echarts/radar.js +3 -0
  67. package/dist/echarts/sankey.d.ts +3 -0
  68. package/dist/echarts/sankey.js +2 -0
  69. package/dist/echarts/scatter.d.ts +3 -0
  70. package/dist/echarts/scatter.js +2 -0
  71. package/dist/echarts/treemap.d.ts +3 -0
  72. package/dist/echarts/treemap.js +2 -0
  73. package/dist/echarts.d.ts +22 -0
  74. package/dist/echarts.js +24 -0
  75. package/dist/index.d.ts +16 -0
  76. package/dist/index.js +15 -0
  77. package/package.json +67 -0
@@ -0,0 +1,27 @@
1
+ import { type FormatOptions } from './format.js';
2
+ import type { CategoryData, SliceDatum } from './types.js';
3
+ /** `rises`, `falls` or `holds steady`, comparing the first and last values. */
4
+ export declare function describeTrend(values: Array<number | null>): string;
5
+ /** The highest and lowest value and where each falls. */
6
+ export declare function extremes(values: Array<number | null>, labels: string[]): {
7
+ high: {
8
+ label: string;
9
+ value: number;
10
+ };
11
+ low: {
12
+ label: string;
13
+ value: number;
14
+ };
15
+ } | null;
16
+ declare const list: (items: string[]) => string;
17
+ /** "3 series over 12 categories. Revenue rises, peaking at 40 in Dec; …" */
18
+ export declare function describeCategories(data: CategoryData, { kind, format }?: {
19
+ kind?: string;
20
+ format?: FormatOptions;
21
+ }): string;
22
+ /** "Pie of 5 slices totalling 120. Largest: A 40 (33%), B 30 (25%) and C 20 (17%)." */
23
+ export declare function describeSlices(data: SliceDatum[], { kind, format }?: {
24
+ kind?: string;
25
+ format?: FormatOptions;
26
+ }): string;
27
+ export { list as joinList };
@@ -0,0 +1,69 @@
1
+ import { formatNumber } from './format.js';
2
+ /*
3
+ * Plain-language summaries for a chart's accessible description. They say what a sighted
4
+ * reader takes in at a glance — the trend, the extremes, the biggest share — and leave the
5
+ * detail to the data table. Pass your own `description` to a chart to replace them.
6
+ */
7
+ const finite = (values) => values.filter((value) => value != null && Number.isFinite(value));
8
+ /** `rises`, `falls` or `holds steady`, comparing the first and last values. */
9
+ export function describeTrend(values) {
10
+ const present = finite(values);
11
+ if (present.length < 2)
12
+ return 'holds steady';
13
+ const [first, last] = [present[0], present[present.length - 1]];
14
+ const scale = Math.max(Math.abs(first), Math.abs(last), 1e-9);
15
+ if (Math.abs(last - first) / scale < 0.02)
16
+ return 'holds steady';
17
+ return last > first ? 'rises' : 'falls';
18
+ }
19
+ /** The highest and lowest value and where each falls. */
20
+ export function extremes(values, labels) {
21
+ let high = null;
22
+ let low = null;
23
+ values.forEach((value, index) => {
24
+ if (value == null || !Number.isFinite(value))
25
+ return;
26
+ const label = labels[index] ?? String(index + 1);
27
+ if (!high || value > high.value)
28
+ high = { label, value };
29
+ if (!low || value < low.value)
30
+ low = { label, value };
31
+ });
32
+ return high && low ? { high, low } : null;
33
+ }
34
+ const list = (items) => items.length <= 1
35
+ ? (items[0] ?? '')
36
+ : `${items.slice(0, -1).join(', ')} and ${items[items.length - 1]}`;
37
+ /** "3 series over 12 categories. Revenue rises, peaking at 40 in Dec; …" */
38
+ export function describeCategories(data, { kind = 'chart', format } = {}) {
39
+ const { categories, series } = data;
40
+ if (!series.length || !categories.length)
41
+ return `Empty ${kind}.`;
42
+ const parts = series.slice(0, 4).map((one) => {
43
+ const range = extremes(one.data, categories);
44
+ if (!range)
45
+ return `${one.name} has no values`;
46
+ const high = `${formatNumber(range.high.value, format)} in ${range.high.label}`;
47
+ const low = `${formatNumber(range.low.value, format)} in ${range.low.label}`;
48
+ return `${one.name} ${describeTrend(one.data)}, from a low of ${low} to a high of ${high}`;
49
+ });
50
+ const more = series.length > 4 ? ` ${series.length - 4} more series in the data table.` : '';
51
+ const span = `${categories[0]} to ${categories[categories.length - 1]}`;
52
+ const count = `${series.length} series`;
53
+ return `${kind[0].toUpperCase()}${kind.slice(1)} of ${count} over ${categories.length} categories, ${span}. ${parts.join('; ')}.${more}`;
54
+ }
55
+ /** "Pie of 5 slices totalling 120. Largest: A 40 (33%), B 30 (25%) and C 20 (17%)." */
56
+ export function describeSlices(data, { kind = 'chart', format } = {}) {
57
+ if (!data.length)
58
+ return `Empty ${kind}.`;
59
+ const total = data.reduce((sum, slice) => sum + slice.value, 0);
60
+ const top = [...data]
61
+ .sort((a, b) => b.value - a.value)
62
+ .slice(0, 3)
63
+ .map((slice) => {
64
+ const share = total ? Math.round((slice.value / total) * 100) : 0;
65
+ return `${slice.name} ${formatNumber(slice.value, format)} (${share}%)`;
66
+ });
67
+ return `${kind[0].toUpperCase()}${kind.slice(1)} of ${data.length} ${data.length === 1 ? 'part' : 'parts'} totalling ${formatNumber(total, format)}. Largest: ${list(top)}.`;
68
+ }
69
+ export { list as joinList };
@@ -0,0 +1,15 @@
1
+ export interface FormatOptions extends Intl.NumberFormatOptions {
2
+ locale?: string | string[];
3
+ }
4
+ /** `1234.5` → `1,234.5`. Non-finite values format as an empty string. */
5
+ export declare function formatNumber(value: number | null | undefined, options?: FormatOptions): string;
6
+ /** `12500` → `12.5K`, in the locale's own compact notation. */
7
+ export declare function formatCompact(value: number | null | undefined, options?: FormatOptions): string;
8
+ /** `0.256` → `25.6%`. The value is a fraction, as `Intl` expects. */
9
+ export declare function formatPercent(value: number | null | undefined, options?: FormatOptions): string;
10
+ /** `1234` with `USD` → `$1,234.00`. */
11
+ export declare function formatCurrency(value: number | null | undefined, currency: string, options?: FormatOptions): string;
12
+ /** A date or timestamp in the locale's medium date style. Invalid dates format as `''`. */
13
+ export declare function formatDate(value: Date | number | string, { locale, ...options }?: Intl.DateTimeFormatOptions & {
14
+ locale?: string | string[];
15
+ }): string;
@@ -0,0 +1,39 @@
1
+ /*
2
+ * Number and date formatting for axes, tooltips and descriptions. Every formatter takes a
3
+ * `locale`: leaving it out uses the runtime default, which differs between the server and the
4
+ * browser — pass one explicitly when a chart is server-rendered.
5
+ */
6
+ const cache = new Map();
7
+ function numberFormat({ locale, ...options } = {}) {
8
+ const key = JSON.stringify([locale ?? null, options]);
9
+ let format = cache.get(key);
10
+ if (!format) {
11
+ format = new Intl.NumberFormat(locale, options);
12
+ cache.set(key, format);
13
+ }
14
+ return format;
15
+ }
16
+ /** `1234.5` → `1,234.5`. Non-finite values format as an empty string. */
17
+ export function formatNumber(value, options) {
18
+ return value == null || !Number.isFinite(value) ? '' : numberFormat(options).format(value);
19
+ }
20
+ /** `12500` → `12.5K`, in the locale's own compact notation. */
21
+ export function formatCompact(value, options) {
22
+ return formatNumber(value, { notation: 'compact', maximumFractionDigits: 1, ...options });
23
+ }
24
+ /** `0.256` → `25.6%`. The value is a fraction, as `Intl` expects. */
25
+ export function formatPercent(value, options) {
26
+ return formatNumber(value, { style: 'percent', maximumFractionDigits: 1, ...options });
27
+ }
28
+ /** `1234` with `USD` → `$1,234.00`. */
29
+ export function formatCurrency(value, currency, options) {
30
+ return formatNumber(value, { style: 'currency', currency, ...options });
31
+ }
32
+ /** A date or timestamp in the locale's medium date style. Invalid dates format as `''`. */
33
+ export function formatDate(value, { locale, ...options } = {}) {
34
+ const date = value instanceof Date ? value : new Date(value);
35
+ if (Number.isNaN(date.getTime()))
36
+ return '';
37
+ const settings = Object.keys(options).length ? options : { dateStyle: 'medium' };
38
+ return new Intl.DateTimeFormat(locale, settings).format(date);
39
+ }
@@ -0,0 +1,11 @@
1
+ export * from './types.js';
2
+ export * from './format.js';
3
+ export { applyTheme, axisStyle, chartFont, inkOn, seriesColor, tooltipCss, withDefaults, } from './theme.js';
4
+ export type { ThemeOptions } from './theme.js';
5
+ export { describeCategories, describeSlices, describeTrend, extremes } from './describe.js';
6
+ export { buildBarOption, buildLineOption, categoryTable, describeBar, describeLine, } from './builders/category.js';
7
+ export type { BarOptions, LineOptions } from './builders/category.js';
8
+ export { buildFunnelOption, buildPieOption, describeFunnel, describePie, sliceTable, } from './builders/slices.js';
9
+ export type { FunnelOptions, PieOptions } from './builders/slices.js';
10
+ export { buildCandlestickOption, buildGaugeOption, buildHeatmapOption, buildRadarOption, buildSankeyOption, buildScatterOption, buildTreemapOption, candlestickTable, describeCandlestick, describeGauge, describeHeatmap, describeRadar, describeSankey, describeScatter, describeTreemap, gaugeTable, heatmapTable, linearFit, nodeValue, radarTable, sankeyTable, scatterTable, treemapTable, } from './builders/more.js';
11
+ export type { CandlestickOptions, GaugeData, GaugeOptions, HeatmapOptions, RadarOptions, SankeyOptions, ScatterOptions, TreemapOptions, } from './builders/more.js';
@@ -0,0 +1,12 @@
1
+ /*
2
+ * Everything here is plain TypeScript with no Svelte and no ECharts import, so it runs anywhere:
3
+ * the server, a worker, a test. Build an option here and hand it to `<Chart>`, or to ECharts
4
+ * directly.
5
+ */
6
+ export * from './types.js';
7
+ export * from './format.js';
8
+ export { applyTheme, axisStyle, chartFont, inkOn, seriesColor, tooltipCss, withDefaults, } from './theme.js';
9
+ export { describeCategories, describeSlices, describeTrend, extremes } from './describe.js';
10
+ export { buildBarOption, buildLineOption, categoryTable, describeBar, describeLine, } from './builders/category.js';
11
+ export { buildFunnelOption, buildPieOption, describeFunnel, describePie, sliceTable, } from './builders/slices.js';
12
+ export { buildCandlestickOption, buildGaugeOption, buildHeatmapOption, buildRadarOption, buildSankeyOption, buildScatterOption, buildTreemapOption, candlestickTable, describeCandlestick, describeGauge, describeHeatmap, describeRadar, describeSankey, describeScatter, describeTreemap, gaugeTable, heatmapTable, linearFit, nodeValue, radarTable, sankeyTable, scatterTable, treemapTable, } from './builders/more.js';
@@ -0,0 +1,30 @@
1
+ import type { ChartColors, ChartOption } from './types.js';
2
+ type Plain = Record<string, unknown>;
3
+ /** Fills in what `target` leaves unset from `defaults`, recursively. Never overwrites a value. */
4
+ export declare function withDefaults<T extends Plain>(target: T, defaults: Plain): T;
5
+ /** Inline styles that dress an ECharts tooltip as a loidolt popover. */
6
+ export declare const tooltipCss: string;
7
+ /** Text in charts uses the utility face, as every other label in the system does. */
8
+ export declare const chartFont: "\"Archivo\", \"Helvetica Neue\", sans-serif";
9
+ /** Axis styling from the theme: hairline axes, soft gridlines, muted labels. */
10
+ export declare function axisStyle(colors: ChartColors): Plain;
11
+ export interface ThemeOptions {
12
+ /** Turn transitions off, e.g. for `prefers-reduced-motion`. */
13
+ animation?: boolean;
14
+ /** Patterns on fills, so series stay apart without colour (WCAG 1.4.1). */
15
+ decal?: boolean;
16
+ }
17
+ /**
18
+ * Themes an option: the categorical palette, text in the utility face, axes, legend and tooltip —
19
+ * everything the option leaves unset. Anything the option sets itself wins, so a caller can
20
+ * override a single colour without restating the theme.
21
+ */
22
+ export declare function applyTheme(option: ChartOption, colors?: ChartColors, { animation, decal }?: ThemeOptions): ChartOption;
23
+ /** The palette colour for the `index`th series, wrapping round after eight. */
24
+ export declare const seriesColor: (colors: ChartColors, index: number) => string;
25
+ /**
26
+ * Whichever of the theme's text or surface colour reads better on `fill` — for labels printed on
27
+ * a slice or a funnel stage. Falls back to the text colour when any of them is not hex.
28
+ */
29
+ export declare function inkOn(fill: string, colors: ChartColors): string;
30
+ export {};
@@ -0,0 +1,137 @@
1
+ import { chartColors, getContrastTextColor, typography } from '@loidolt/theme-tokens';
2
+ const isPlain = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
3
+ /** Fills in what `target` leaves unset from `defaults`, recursively. Never overwrites a value. */
4
+ export function withDefaults(target, defaults) {
5
+ const out = { ...target };
6
+ for (const [key, fallback] of Object.entries(defaults)) {
7
+ const own = out[key];
8
+ if (own === undefined)
9
+ out[key] = fallback;
10
+ else if (isPlain(own) && isPlain(fallback))
11
+ out[key] = withDefaults(own, fallback);
12
+ }
13
+ return out;
14
+ }
15
+ /** Applies `defaults` to one component, or to each when the option holds a list of them. */
16
+ const eachComponent = (value, defaults) => Array.isArray(value)
17
+ ? value.map((item) => (isPlain(item) ? withDefaults(item, defaults) : item))
18
+ : isPlain(value)
19
+ ? withDefaults(value, defaults)
20
+ : value;
21
+ /** Inline styles that dress an ECharts tooltip as a loidolt popover. */
22
+ export const tooltipCss = [
23
+ 'border-radius: 0',
24
+ 'border-color: var(--loidolt-border-strong)',
25
+ 'background-color: var(--loidolt-surface)',
26
+ 'color: var(--loidolt-text)',
27
+ 'box-shadow: var(--loidolt-shadow-popover)',
28
+ 'font-family: var(--loidolt-font-utility)',
29
+ ].join('; ');
30
+ /** Text in charts uses the utility face, as every other label in the system does. */
31
+ export const chartFont = typography.utility;
32
+ /** Axis styling from the theme: hairline axes, soft gridlines, muted labels. */
33
+ export function axisStyle(colors) {
34
+ return {
35
+ axisLine: { lineStyle: { color: colors.axis } },
36
+ axisTick: { lineStyle: { color: colors.axis } },
37
+ axisLabel: { color: colors.muted, fontFamily: chartFont, fontSize: 11 },
38
+ splitLine: { lineStyle: { color: colors.grid } },
39
+ nameTextStyle: { color: colors.muted, fontFamily: chartFont },
40
+ };
41
+ }
42
+ /**
43
+ * Themes an option: the categorical palette, text in the utility face, axes, legend and tooltip —
44
+ * everything the option leaves unset. Anything the option sets itself wins, so a caller can
45
+ * override a single colour without restating the theme.
46
+ */
47
+ export function applyTheme(option, colors = chartColors(), { animation = true, decal = false } = {}) {
48
+ const axis = axisStyle(colors);
49
+ const themed = withDefaults(option, {
50
+ color: colors.categorical,
51
+ backgroundColor: 'transparent',
52
+ textStyle: { color: colors.text, fontFamily: chartFont, fontSize: 12 },
53
+ animation,
54
+ // Descriptions are supplied by the component, so ECharts' generated label stays off; its
55
+ // decal patterns are the part of `aria` worth having.
56
+ aria: { enabled: decal, label: { enabled: false }, decal: { show: decal } },
57
+ });
58
+ if (!animation)
59
+ themed.animation = false;
60
+ for (const key of ['xAxis', 'yAxis', 'singleAxis']) {
61
+ if (key in themed)
62
+ themed[key] = eachComponent(themed[key], axis);
63
+ }
64
+ if ('radar' in themed) {
65
+ themed.radar = eachComponent(themed.radar, {
66
+ axisName: { color: colors.muted, fontFamily: chartFont },
67
+ axisLine: { lineStyle: { color: colors.grid } },
68
+ splitLine: { lineStyle: { color: colors.grid } },
69
+ splitArea: { show: false },
70
+ });
71
+ }
72
+ if ('legend' in themed) {
73
+ themed.legend = eachComponent(themed.legend, {
74
+ textStyle: { color: colors.text, fontFamily: chartFont },
75
+ inactiveColor: colors.grid,
76
+ icon: 'rect',
77
+ itemWidth: 12,
78
+ itemHeight: 12,
79
+ });
80
+ }
81
+ if ('tooltip' in themed) {
82
+ themed.tooltip = eachComponent(themed.tooltip, {
83
+ className: 'ldt-chart-tooltip',
84
+ backgroundColor: colors.surface,
85
+ borderColor: colors.text,
86
+ borderWidth: 1,
87
+ padding: [7, 10],
88
+ // The tooltip is DOM, so it can wear a popover's tokens directly; these come after the
89
+ // inline styles ECharts writes, and follow the theme without a repaint.
90
+ extraCssText: tooltipCss,
91
+ textStyle: { color: colors.text, fontFamily: chartFont },
92
+ axisPointer: { lineStyle: { color: colors.axis }, crossStyle: { color: colors.axis } },
93
+ });
94
+ }
95
+ if ('visualMap' in themed) {
96
+ themed.visualMap = eachComponent(themed.visualMap, {
97
+ inRange: { color: colors.sequential },
98
+ textStyle: { color: colors.muted, fontFamily: chartFont },
99
+ });
100
+ }
101
+ if ('dataZoom' in themed) {
102
+ themed.dataZoom = eachComponent(themed.dataZoom, {
103
+ backgroundColor: 'transparent',
104
+ borderColor: colors.axis,
105
+ fillerColor: `${colors.accent.slice(0, 7)}29`,
106
+ textStyle: { color: colors.muted, fontFamily: chartFont },
107
+ dataBackground: { lineStyle: { color: colors.axis }, areaStyle: { color: colors.grid } },
108
+ selectedDataBackground: {
109
+ lineStyle: { color: colors.accent },
110
+ areaStyle: { color: colors.accent, opacity: 0.2 },
111
+ },
112
+ handleStyle: { color: colors.surface, borderColor: colors.text },
113
+ moveHandleStyle: { color: colors.axis, opacity: 1 },
114
+ emphasis: {
115
+ handleStyle: { borderColor: colors.accent },
116
+ moveHandleStyle: { color: colors.accent },
117
+ },
118
+ });
119
+ }
120
+ return themed;
121
+ }
122
+ /** The palette colour for the `index`th series, wrapping round after eight. */
123
+ export const seriesColor = (colors, index) => colors.categorical[index % colors.categorical.length];
124
+ /**
125
+ * Whichever of the theme's text or surface colour reads better on `fill` — for labels printed on
126
+ * a slice or a funnel stage. Falls back to the text colour when any of them is not hex.
127
+ */
128
+ export function inkOn(fill, colors) {
129
+ const hex = /^#[0-9a-f]{6}/i;
130
+ if (![fill, colors.text, colors.surface].every((value) => hex.test(value)))
131
+ return colors.text;
132
+ // `getContrastTextColor` just picks the better of two inks; which is "dark" does not matter.
133
+ return getContrastTextColor(fill.slice(0, 7), {
134
+ dark: colors.text.slice(0, 7),
135
+ light: colors.surface.slice(0, 7),
136
+ });
137
+ }
@@ -0,0 +1,98 @@
1
+ import type { ChartColors } from '@loidolt/theme-tokens';
2
+ export type { ChartColors };
3
+ /**
4
+ * An ECharts option object. Kept structural rather than tied to ECharts' own `EChartsOption`, so
5
+ * the pure builders in `/core` stay importable without the chart library installed.
6
+ */
7
+ export type ChartOption = Record<string, unknown>;
8
+ /** An option, or a function that builds one from the resolved theme colours. */
9
+ export type ChartOptionSource = ChartOption | ((colors: ChartColors) => ChartOption);
10
+ /** A cell in a chart's data-table alternative. */
11
+ export type ChartCell = string | number | null;
12
+ /** The data behind a chart as a table — its non-visual alternative. */
13
+ export interface ChartTable {
14
+ /** Column headings; the first usually names the category or row. */
15
+ columns: string[];
16
+ rows: ChartCell[][];
17
+ }
18
+ /** One named series over shared categories (line, bar, area). */
19
+ export interface CategorySeries {
20
+ name: string;
21
+ /** One value per category; `null` leaves a gap. */
22
+ data: Array<number | null>;
23
+ /** Overrides the palette colour for this series. */
24
+ color?: string;
25
+ }
26
+ export interface CategoryData {
27
+ categories: string[];
28
+ series: CategorySeries[];
29
+ }
30
+ /** One slice of a part-to-whole chart (pie, donut, funnel). */
31
+ export interface SliceDatum {
32
+ name: string;
33
+ value: number;
34
+ color?: string;
35
+ }
36
+ export interface ScatterSeries {
37
+ name: string;
38
+ /** `[x, y]` points. */
39
+ data: Array<[number, number]>;
40
+ color?: string;
41
+ }
42
+ export interface RadarData {
43
+ /** The spokes. `max` defaults to the largest value on that spoke. */
44
+ indicators: Array<{
45
+ name: string;
46
+ max?: number;
47
+ min?: number;
48
+ }>;
49
+ series: Array<{
50
+ name: string;
51
+ values: number[];
52
+ color?: string;
53
+ }>;
54
+ }
55
+ export interface HeatmapData {
56
+ x: string[];
57
+ y: string[];
58
+ /** `[xIndex, yIndex, value]` cells; missing cells stay empty. */
59
+ values: Array<[number, number, number | null]>;
60
+ }
61
+ export interface TreeNode {
62
+ name: string;
63
+ /** Leaf size. A branch without one is the sum of its children. */
64
+ value?: number;
65
+ children?: TreeNode[];
66
+ color?: string;
67
+ }
68
+ export interface CandlestickDatum {
69
+ /** Category label, usually a date. */
70
+ date: string;
71
+ open: number;
72
+ close: number;
73
+ low: number;
74
+ high: number;
75
+ volume?: number;
76
+ }
77
+ export interface SankeyData {
78
+ nodes: Array<{
79
+ name: string;
80
+ color?: string;
81
+ }>;
82
+ links: Array<{
83
+ source: string;
84
+ target: string;
85
+ value: number;
86
+ }>;
87
+ }
88
+ /** What a click or keyboard activation on a data point reports. */
89
+ export interface ChartItemEvent {
90
+ /** `series`, `legend`, … as ECharts reports it. */
91
+ componentType: string;
92
+ seriesName?: string;
93
+ seriesIndex?: number;
94
+ /** The category, slice or node name. */
95
+ name: string;
96
+ dataIndex?: number;
97
+ value: unknown;
98
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ import type { CategoryData } from './types.js';
2
+ /** Throws a `RangeError` naming the builder, so a bad dataset fails where it is built. */
3
+ export declare function invariant(condition: unknown, builder: string, message: string): asserts condition;
4
+ export declare function checkCategories(data: CategoryData, builder: string): void;
@@ -0,0 +1,10 @@
1
+ /** Throws a `RangeError` naming the builder, so a bad dataset fails where it is built. */
2
+ export function invariant(condition, builder, message) {
3
+ if (!condition)
4
+ throw new RangeError(`${builder}: ${message}`);
5
+ }
6
+ export function checkCategories(data, builder) {
7
+ for (const series of data.series) {
8
+ invariant(series.data.length === data.categories.length, builder, `series "${series.name}" has ${series.data.length} values for ${data.categories.length} categories`);
9
+ }
10
+ }
@@ -0,0 +1,3 @@
1
+ import { BarChart } from 'echarts/charts';
2
+ declare const _default: (typeof BarChart)[];
3
+ export default _default;
@@ -0,0 +1,23 @@
1
+ /*
2
+ * Every chart type and component the wrappers use, for the generic `<Chart>` whose option can
3
+ * hold anything. Pass narrower `extensions` to `<Chart>` to ship less.
4
+ */
5
+ import { BarChart, CandlestickChart, FunnelChart, GaugeChart, HeatmapChart, LineChart, PieChart, RadarChart, SankeyChart, ScatterChart, TreemapChart, } from 'echarts/charts';
6
+ import { DataZoomComponent, MarkLineComponent, RadarComponent, VisualMapComponent, } from 'echarts/components';
7
+ export default [
8
+ BarChart,
9
+ CandlestickChart,
10
+ FunnelChart,
11
+ GaugeChart,
12
+ HeatmapChart,
13
+ LineChart,
14
+ PieChart,
15
+ RadarChart,
16
+ SankeyChart,
17
+ ScatterChart,
18
+ TreemapChart,
19
+ DataZoomComponent,
20
+ MarkLineComponent,
21
+ RadarComponent,
22
+ VisualMapComponent,
23
+ ];
@@ -0,0 +1,3 @@
1
+ import { BarChart } from 'echarts/charts';
2
+ declare const _default: (typeof BarChart)[];
3
+ export default _default;
@@ -0,0 +1,2 @@
1
+ import { BarChart } from 'echarts/charts';
2
+ export default [BarChart];
@@ -0,0 +1,3 @@
1
+ import { AriaComponent } from 'echarts/components';
2
+ declare const _default: (typeof AriaComponent)[];
3
+ export default _default;
@@ -0,0 +1,13 @@
1
+ /* The components and renderers every chart shares. */
2
+ import { AriaComponent, DatasetComponent, GridComponent, LegendComponent, TitleComponent, TooltipComponent, } from 'echarts/components';
3
+ import { CanvasRenderer, SVGRenderer } from 'echarts/renderers';
4
+ export default [
5
+ AriaComponent,
6
+ DatasetComponent,
7
+ GridComponent,
8
+ LegendComponent,
9
+ TitleComponent,
10
+ TooltipComponent,
11
+ CanvasRenderer,
12
+ SVGRenderer,
13
+ ];
@@ -0,0 +1,3 @@
1
+ import { BarChart } from 'echarts/charts';
2
+ declare const _default: (typeof BarChart)[];
3
+ export default _default;
@@ -0,0 +1,3 @@
1
+ import { BarChart, CandlestickChart } from 'echarts/charts';
2
+ import { AxisPointerComponent, DataZoomComponent } from 'echarts/components';
3
+ export default [CandlestickChart, BarChart, DataZoomComponent, AxisPointerComponent];
@@ -0,0 +1,3 @@
1
+ import { FunnelChart } from 'echarts/charts';
2
+ declare const _default: (typeof FunnelChart)[];
3
+ export default _default;
@@ -0,0 +1,2 @@
1
+ import { FunnelChart } from 'echarts/charts';
2
+ export default [FunnelChart];
@@ -0,0 +1,3 @@
1
+ import { GaugeChart } from 'echarts/charts';
2
+ declare const _default: (typeof GaugeChart)[];
3
+ export default _default;
@@ -0,0 +1,2 @@
1
+ import { GaugeChart } from 'echarts/charts';
2
+ export default [GaugeChart];
@@ -0,0 +1,3 @@
1
+ import { HeatmapChart } from 'echarts/charts';
2
+ declare const _default: (typeof HeatmapChart)[];
3
+ export default _default;
@@ -0,0 +1,3 @@
1
+ import { HeatmapChart } from 'echarts/charts';
2
+ import { VisualMapComponent } from 'echarts/components';
3
+ export default [HeatmapChart, VisualMapComponent];
@@ -0,0 +1,3 @@
1
+ import { LineChart } from 'echarts/charts';
2
+ declare const _default: (typeof LineChart)[];
3
+ export default _default;
@@ -0,0 +1,2 @@
1
+ import { LineChart } from 'echarts/charts';
2
+ export default [LineChart];
@@ -0,0 +1,3 @@
1
+ import { PieChart } from 'echarts/charts';
2
+ declare const _default: (typeof PieChart)[];
3
+ export default _default;
@@ -0,0 +1,2 @@
1
+ import { PieChart } from 'echarts/charts';
2
+ export default [PieChart];
@@ -0,0 +1,3 @@
1
+ import { RadarChart } from 'echarts/charts';
2
+ declare const _default: (typeof RadarChart)[];
3
+ export default _default;
@@ -0,0 +1,3 @@
1
+ import { RadarChart } from 'echarts/charts';
2
+ import { RadarComponent } from 'echarts/components';
3
+ export default [RadarChart, RadarComponent];
@@ -0,0 +1,3 @@
1
+ import { SankeyChart } from 'echarts/charts';
2
+ declare const _default: (typeof SankeyChart)[];
3
+ export default _default;
@@ -0,0 +1,2 @@
1
+ import { SankeyChart } from 'echarts/charts';
2
+ export default [SankeyChart];
@@ -0,0 +1,3 @@
1
+ import { LineChart } from 'echarts/charts';
2
+ declare const _default: (typeof LineChart)[];
3
+ export default _default;
@@ -0,0 +1,2 @@
1
+ import { LineChart, ScatterChart } from 'echarts/charts';
2
+ export default [ScatterChart, LineChart];
@@ -0,0 +1,3 @@
1
+ import { TreemapChart } from 'echarts/charts';
2
+ declare const _default: (typeof TreemapChart)[];
3
+ export default _default;
@@ -0,0 +1,2 @@
1
+ import { TreemapChart } from 'echarts/charts';
2
+ export default [TreemapChart];
@@ -0,0 +1,22 @@
1
+ /** The slice of an ECharts instance the components use. */
2
+ export interface EChartsInstance {
3
+ setOption(option: Record<string, unknown>, options?: Record<string, unknown>): void;
4
+ on(event: string, handler: (params: Record<string, unknown>) => void): void;
5
+ off(event: string, handler?: (params: Record<string, unknown>) => void): void;
6
+ resize(options?: Record<string, unknown>): void;
7
+ dispatchAction(action: Record<string, unknown>): void;
8
+ dispose(): void;
9
+ isDisposed(): boolean;
10
+ }
11
+ /** The slice of `echarts/core` the components use. */
12
+ export interface EChartsCore {
13
+ init(element: HTMLElement, theme?: string | object | null, options?: Record<string, unknown>): EChartsInstance;
14
+ use(extensions: unknown[]): void;
15
+ }
16
+ export type EChartsLoader = () => Promise<EChartsCore> | EChartsCore;
17
+ /** Replaces how `echarts/core` is loaded. `null` restores the default dynamic import. */
18
+ export declare function setEChartsLoader(loader: EChartsLoader | null): void;
19
+ /** Loads the ECharts core once. Resolves `null` rather than rejecting when it cannot. */
20
+ export declare function loadECharts(): Promise<EChartsCore | null>;
21
+ /** Chart extensions: resolves to the ECharts modules one chart type needs. */
22
+ export type ChartExtensions = () => Promise<unknown[]>;