@open-tomato/charts 0.0.0-stage → 0.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/README.md +283 -2
- package/dist/engine/BarChart/BarChart.d.ts +4 -0
- package/dist/engine/BarChart/BarChart.option.d.ts +4 -0
- package/dist/engine/BarChart/index.d.ts +2 -0
- package/dist/engine/BoxPlot/BoxPlot.d.ts +4 -0
- package/dist/engine/BoxPlot/BoxPlot.option.d.ts +4 -0
- package/dist/engine/BoxPlot/index.d.ts +2 -0
- package/dist/engine/Bullet/Bullet.d.ts +4 -0
- package/dist/engine/Bullet/Bullet.option.d.ts +4 -0
- package/dist/engine/Bullet/index.d.ts +2 -0
- package/dist/engine/Donut/Donut.d.ts +4 -0
- package/dist/engine/Donut/Donut.option.d.ts +4 -0
- package/dist/engine/Donut/index.d.ts +2 -0
- package/dist/engine/Gauge/Gauge.d.ts +4 -0
- package/dist/engine/Gauge/Gauge.option.d.ts +4 -0
- package/dist/engine/Gauge/index.d.ts +2 -0
- package/dist/engine/HeatmapGrid/HeatmapGrid.d.ts +4 -0
- package/dist/engine/HeatmapGrid/HeatmapGrid.option.d.ts +4 -0
- package/dist/engine/HeatmapGrid/index.d.ts +2 -0
- package/dist/engine/Histogram/Histogram.d.ts +4 -0
- package/dist/engine/Histogram/Histogram.option.d.ts +4 -0
- package/dist/engine/Histogram/index.d.ts +2 -0
- package/dist/engine/LineChart/LineChart.d.ts +19 -0
- package/dist/engine/LineChart/LineChart.option.d.ts +4 -0
- package/dist/engine/LineChart/index.d.ts +2 -0
- package/dist/engine/NetworkGraph/NetworkGraph.d.ts +4 -0
- package/dist/engine/NetworkGraph/NetworkGraph.option.d.ts +8 -0
- package/dist/engine/NetworkGraph/index.d.ts +2 -0
- package/dist/engine/Nightingale/Nightingale.d.ts +4 -0
- package/dist/engine/Nightingale/Nightingale.option.d.ts +4 -0
- package/dist/engine/Nightingale/index.d.ts +2 -0
- package/dist/engine/Radar/Radar.d.ts +4 -0
- package/dist/engine/Radar/Radar.option.d.ts +4 -0
- package/dist/engine/Radar/index.d.ts +2 -0
- package/dist/engine/Sankey/Sankey.d.ts +4 -0
- package/dist/engine/Sankey/Sankey.option.d.ts +6 -0
- package/dist/engine/Sankey/index.d.ts +2 -0
- package/dist/engine/ScatterChart/ScatterChart.d.ts +4 -0
- package/dist/engine/ScatterChart/ScatterChart.option.d.ts +6 -0
- package/dist/engine/ScatterChart/index.d.ts +2 -0
- package/dist/engine/Sunburst/Sunburst.d.ts +4 -0
- package/dist/engine/Sunburst/Sunburst.option.d.ts +19 -0
- package/dist/engine/Sunburst/index.d.ts +2 -0
- package/dist/engine/Treemap/Treemap.d.ts +4 -0
- package/dist/engine/Treemap/Treemap.option.d.ts +4 -0
- package/dist/engine/Treemap/index.d.ts +2 -0
- package/dist/engine/chrome.d.ts +90 -0
- package/dist/engine/core.d.ts +58 -0
- package/dist/engine/echartsEngine.d.ts +3 -0
- package/dist/engine/fixtures.d.ts +61 -0
- package/dist/engine/headless/headless.d.ts +86 -0
- package/dist/engine/headless/index.d.ts +10 -0
- package/dist/engine/headless/index.js +142 -0
- package/dist/engine/index.d.ts +1 -0
- package/dist/engine/shared.d.ts +59 -0
- package/dist/engine/shared.variants.d.ts +40 -0
- package/dist/index-4bxmxw89.js +1786 -0
- package/dist/index-85mb21rn.js +69 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +618 -0
- package/dist/lib/cn.d.ts +7 -0
- package/dist/lib/index.d.ts +2 -0
- package/dist/seam/ChartEngineProvider.d.ts +12 -0
- package/dist/seam/FormatProvider.d.ts +25 -0
- package/dist/seam/format.d.ts +171 -0
- package/dist/seam/format.schema.d.ts +14 -0
- package/dist/seam/height.d.ts +15 -0
- package/dist/seam/index.d.ts +12 -0
- package/dist/seam/tones.d.ts +49 -0
- package/dist/seam/types.d.ts +322 -0
- package/dist/seam/useResolvedTokens.d.ts +7 -0
- package/dist/theme/index.d.ts +3 -0
- package/dist/theme/index.js +30 -0
- package/dist/theme/tokens.d.ts +40 -0
- package/package.json +82 -4
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// src/theme/tokens.ts
|
|
2
|
+
var SERIES_TOKENS = [
|
|
3
|
+
"--color-series-1",
|
|
4
|
+
"--color-series-2",
|
|
5
|
+
"--color-series-3",
|
|
6
|
+
"--color-series-4",
|
|
7
|
+
"--color-series-5",
|
|
8
|
+
"--color-series-6",
|
|
9
|
+
"--color-series-7",
|
|
10
|
+
"--color-series-8"
|
|
11
|
+
];
|
|
12
|
+
var STATUS_TOKENS = [
|
|
13
|
+
"--color-good",
|
|
14
|
+
"--color-warning",
|
|
15
|
+
"--color-serious",
|
|
16
|
+
"--color-critical"
|
|
17
|
+
];
|
|
18
|
+
var SURFACE_TOKENS = [
|
|
19
|
+
"--color-surface",
|
|
20
|
+
"--color-plane",
|
|
21
|
+
"--color-ink",
|
|
22
|
+
"--color-ink-2",
|
|
23
|
+
"--color-muted",
|
|
24
|
+
"--color-grid",
|
|
25
|
+
"--color-baseline",
|
|
26
|
+
"--color-ring"
|
|
27
|
+
];
|
|
28
|
+
var SEQUENTIAL_TOKENS = [
|
|
29
|
+
"--color-seq-100",
|
|
30
|
+
"--color-seq-200",
|
|
31
|
+
"--color-seq-300",
|
|
32
|
+
"--color-seq-400",
|
|
33
|
+
"--color-seq-500",
|
|
34
|
+
"--color-seq-600",
|
|
35
|
+
"--color-seq-700",
|
|
36
|
+
"--color-diverge-mid"
|
|
37
|
+
];
|
|
38
|
+
var POLE_TOKENS = [
|
|
39
|
+
"--color-pole-ship",
|
|
40
|
+
"--color-pole-ship-core",
|
|
41
|
+
"--color-pole-fail",
|
|
42
|
+
"--color-pole-fail-core",
|
|
43
|
+
"--color-pole-base",
|
|
44
|
+
"--color-pole-base-core"
|
|
45
|
+
];
|
|
46
|
+
var DELTA_TOKENS = [
|
|
47
|
+
"--color-delta-up"
|
|
48
|
+
];
|
|
49
|
+
var THEME_TOKENS = [
|
|
50
|
+
...SERIES_TOKENS,
|
|
51
|
+
...STATUS_TOKENS,
|
|
52
|
+
...SURFACE_TOKENS,
|
|
53
|
+
...SEQUENTIAL_TOKENS,
|
|
54
|
+
...POLE_TOKENS,
|
|
55
|
+
...DELTA_TOKENS
|
|
56
|
+
];
|
|
57
|
+
var THEME_ATTRIBUTE = "data-theme";
|
|
58
|
+
var DARK_THEME = "dark";
|
|
59
|
+
function tokenVar(token) {
|
|
60
|
+
return `var(${token})`;
|
|
61
|
+
}
|
|
62
|
+
var TOKEN_PREFIX = "--color-";
|
|
63
|
+
function tokenName(token) {
|
|
64
|
+
return token.slice(TOKEN_PREFIX.length);
|
|
65
|
+
}
|
|
66
|
+
function tokenNames(tokens) {
|
|
67
|
+
return tokens.map((token) => tokenName(token));
|
|
68
|
+
}
|
|
69
|
+
export { SERIES_TOKENS, STATUS_TOKENS, SURFACE_TOKENS, SEQUENTIAL_TOKENS, POLE_TOKENS, DELTA_TOKENS, THEME_TOKENS, THEME_ATTRIBUTE, DARK_THEME, tokenVar, TOKEN_PREFIX, tokenName, tokenNames };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@open-tomato/charts`: the root barrel. The seam (primitive types, tones,
|
|
3
|
+
* formatters, the engine provider), the ECharts engine's React adapter,
|
|
4
|
+
* `cn` and the theme token names. `./theme` is also a subpath export, and
|
|
5
|
+
* `./engine` is the headless engine (`src/engine/headless/`): option
|
|
6
|
+
* builders and an SVG renderer with no React and no DOM.
|
|
7
|
+
*/
|
|
8
|
+
export * from './engine/index.js';
|
|
9
|
+
export * from './lib/index.js';
|
|
10
|
+
export * from './seam/index.js';
|
|
11
|
+
export * from './theme/index.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,618 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ALL_TONES,
|
|
3
|
+
CHROME_ROLES,
|
|
4
|
+
DATE_PATTERNS,
|
|
5
|
+
DEFAULT_CHART_HEIGHT,
|
|
6
|
+
DEFAULT_FORMAT_CONTEXT,
|
|
7
|
+
DEFAULT_HEIGHT,
|
|
8
|
+
DOTS_SERIES,
|
|
9
|
+
DURATION_UNITS,
|
|
10
|
+
HIT_SERIES,
|
|
11
|
+
PERCENT_BASES,
|
|
12
|
+
SEQUENTIAL_STEPS,
|
|
13
|
+
UNIT_POSITIONS,
|
|
14
|
+
VALUE_FORMAT_KINDS,
|
|
15
|
+
buildOption,
|
|
16
|
+
buildOption1 as buildOption2,
|
|
17
|
+
buildOption10 as buildOption11,
|
|
18
|
+
buildOption11 as buildOption12,
|
|
19
|
+
buildOption12 as buildOption13,
|
|
20
|
+
buildOption13 as buildOption14,
|
|
21
|
+
buildOption14 as buildOption15,
|
|
22
|
+
buildOption2 as buildOption3,
|
|
23
|
+
buildOption3 as buildOption4,
|
|
24
|
+
buildOption4 as buildOption5,
|
|
25
|
+
buildOption5 as buildOption6,
|
|
26
|
+
buildOption6 as buildOption7,
|
|
27
|
+
buildOption7 as buildOption8,
|
|
28
|
+
buildOption8 as buildOption9,
|
|
29
|
+
buildOption9 as buildOption10,
|
|
30
|
+
chartFrameVariants,
|
|
31
|
+
chartRootVariants,
|
|
32
|
+
chartTone,
|
|
33
|
+
finishOption,
|
|
34
|
+
formatCompact,
|
|
35
|
+
formatContextSchema,
|
|
36
|
+
formatDate,
|
|
37
|
+
formatDay,
|
|
38
|
+
formatElapsed,
|
|
39
|
+
formatMeasured,
|
|
40
|
+
formatMinutes,
|
|
41
|
+
formatPercent,
|
|
42
|
+
formatRelative,
|
|
43
|
+
formatWeek,
|
|
44
|
+
formatterFor,
|
|
45
|
+
nodeIdOf,
|
|
46
|
+
pathsById,
|
|
47
|
+
plotHeightOf,
|
|
48
|
+
readTokens,
|
|
49
|
+
resolveFormatContext,
|
|
50
|
+
tokensFrom,
|
|
51
|
+
toneVar,
|
|
52
|
+
valueFormatSchema
|
|
53
|
+
} from "./index-4bxmxw89.js";
|
|
54
|
+
import {
|
|
55
|
+
DARK_THEME,
|
|
56
|
+
DELTA_TOKENS,
|
|
57
|
+
POLE_TOKENS,
|
|
58
|
+
SEQUENTIAL_TOKENS,
|
|
59
|
+
SERIES_TOKENS,
|
|
60
|
+
STATUS_TOKENS,
|
|
61
|
+
SURFACE_TOKENS,
|
|
62
|
+
THEME_ATTRIBUTE,
|
|
63
|
+
THEME_TOKENS,
|
|
64
|
+
TOKEN_PREFIX,
|
|
65
|
+
tokenName,
|
|
66
|
+
tokenNames,
|
|
67
|
+
tokenVar
|
|
68
|
+
} from "./index-85mb21rn.js";
|
|
69
|
+
|
|
70
|
+
// src/engine/shared.tsx
|
|
71
|
+
import * as echarts from "echarts/core";
|
|
72
|
+
import { CanvasRenderer } from "echarts/renderers";
|
|
73
|
+
import { useEffect as useEffect2, useLayoutEffect, useMemo, useRef } from "react";
|
|
74
|
+
|
|
75
|
+
// src/lib/cn.ts
|
|
76
|
+
import { clsx } from "clsx";
|
|
77
|
+
import { twMerge } from "tailwind-merge";
|
|
78
|
+
function cn(...inputs) {
|
|
79
|
+
return twMerge(clsx(inputs));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// src/seam/useResolvedTokens.ts
|
|
83
|
+
import { useEffect, useState } from "react";
|
|
84
|
+
function sameTokens(a, b) {
|
|
85
|
+
const names = Object.keys(a);
|
|
86
|
+
return names.length === Object.keys(b).length && names.every((name) => a[name] === b[name]);
|
|
87
|
+
}
|
|
88
|
+
function useResolvedTokens() {
|
|
89
|
+
const [tokens, setTokens] = useState(() => readTokens());
|
|
90
|
+
useEffect(() => {
|
|
91
|
+
const observer = new MutationObserver(() => {
|
|
92
|
+
const next = readTokens();
|
|
93
|
+
setTokens((previous) => sameTokens(previous, next) ? previous : next);
|
|
94
|
+
});
|
|
95
|
+
observer.observe(document.documentElement, { attributes: true, attributeFilter: [THEME_ATTRIBUTE] });
|
|
96
|
+
return () => observer.disconnect();
|
|
97
|
+
}, []);
|
|
98
|
+
return tokens;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// src/engine/shared.tsx
|
|
102
|
+
import { jsx } from "react/jsx-runtime";
|
|
103
|
+
echarts.use([CanvasRenderer]);
|
|
104
|
+
function useBuiltOption(props, build) {
|
|
105
|
+
const tokens = useResolvedTokens();
|
|
106
|
+
return useMemo(() => finishOption(build(props, tokens), props.animate), [build, props, tokens]);
|
|
107
|
+
}
|
|
108
|
+
function EChart({ option, ariaLabel, height, className, cursor, onEvents, replaceMerge, transform }) {
|
|
109
|
+
const hostRef = useRef(null);
|
|
110
|
+
const chartRef = useRef(null);
|
|
111
|
+
const hostHeight = height === "fill" ? "100%" : `${height ?? DEFAULT_HEIGHT}px`;
|
|
112
|
+
useLayoutEffect(() => {
|
|
113
|
+
const host = hostRef.current;
|
|
114
|
+
if (!host)
|
|
115
|
+
return;
|
|
116
|
+
host.style.height = hostHeight;
|
|
117
|
+
chartRef.current?.resize();
|
|
118
|
+
}, [hostHeight]);
|
|
119
|
+
useLayoutEffect(() => {
|
|
120
|
+
const host = hostRef.current;
|
|
121
|
+
if (!host)
|
|
122
|
+
return;
|
|
123
|
+
const chart = echarts.init(host, undefined, { renderer: "canvas" });
|
|
124
|
+
chartRef.current = chart;
|
|
125
|
+
let width = chart.getWidth();
|
|
126
|
+
let height2 = chart.getHeight();
|
|
127
|
+
let frame = 0;
|
|
128
|
+
const observer = new ResizeObserver(() => {
|
|
129
|
+
cancelAnimationFrame(frame);
|
|
130
|
+
frame = requestAnimationFrame(() => {
|
|
131
|
+
const next = { width: host.clientWidth, height: host.clientHeight };
|
|
132
|
+
if (next.width === width && next.height === height2)
|
|
133
|
+
return;
|
|
134
|
+
width = next.width;
|
|
135
|
+
height2 = next.height;
|
|
136
|
+
chart.resize();
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
observer.observe(host);
|
|
140
|
+
return () => {
|
|
141
|
+
cancelAnimationFrame(frame);
|
|
142
|
+
observer.disconnect();
|
|
143
|
+
chart.dispose();
|
|
144
|
+
chartRef.current = null;
|
|
145
|
+
};
|
|
146
|
+
}, []);
|
|
147
|
+
useEffect2(() => {
|
|
148
|
+
const chart = chartRef.current;
|
|
149
|
+
if (!chart)
|
|
150
|
+
return;
|
|
151
|
+
const next = transform ? transform(option, chart) : option;
|
|
152
|
+
chart.setOption(next, replaceMerge ? { replaceMerge: [...replaceMerge] } : { notMerge: true });
|
|
153
|
+
}, [option, replaceMerge, transform]);
|
|
154
|
+
useEffect2(() => {
|
|
155
|
+
const chart = chartRef.current;
|
|
156
|
+
if (!chart || !onEvents)
|
|
157
|
+
return;
|
|
158
|
+
const bound = Object.entries(onEvents).map(([name, handler]) => {
|
|
159
|
+
const listener = (event) => handler(event, chart);
|
|
160
|
+
chart.on(name, listener);
|
|
161
|
+
return [name, listener];
|
|
162
|
+
});
|
|
163
|
+
return () => {
|
|
164
|
+
for (const [name, listener] of bound)
|
|
165
|
+
chart.off(name, listener);
|
|
166
|
+
};
|
|
167
|
+
}, [onEvents]);
|
|
168
|
+
return /* @__PURE__ */ jsx("div", {
|
|
169
|
+
ref: hostRef,
|
|
170
|
+
role: "img",
|
|
171
|
+
"aria-label": ariaLabel,
|
|
172
|
+
className: cn(chartRootVariants({ cursor }), className)
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// src/engine/BarChart/BarChart.tsx
|
|
177
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
178
|
+
function BarChart(props) {
|
|
179
|
+
const { className } = props;
|
|
180
|
+
const option = useBuiltOption(props, buildOption);
|
|
181
|
+
return /* @__PURE__ */ jsx2(EChart, {
|
|
182
|
+
option,
|
|
183
|
+
ariaLabel: props.ariaLabel,
|
|
184
|
+
height: props.height,
|
|
185
|
+
className
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
// src/engine/BoxPlot/BoxPlot.tsx
|
|
189
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
190
|
+
function BoxPlot(props) {
|
|
191
|
+
const { className } = props;
|
|
192
|
+
const option = useBuiltOption(props, buildOption2);
|
|
193
|
+
return /* @__PURE__ */ jsx3(EChart, {
|
|
194
|
+
option,
|
|
195
|
+
ariaLabel: props.ariaLabel,
|
|
196
|
+
height: props.height,
|
|
197
|
+
className
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
// src/engine/Bullet/Bullet.tsx
|
|
201
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
202
|
+
function Bullet(props) {
|
|
203
|
+
const { className } = props;
|
|
204
|
+
const option = useBuiltOption(props, buildOption3);
|
|
205
|
+
return /* @__PURE__ */ jsx4(EChart, {
|
|
206
|
+
option,
|
|
207
|
+
ariaLabel: props.ariaLabel,
|
|
208
|
+
height: props.height,
|
|
209
|
+
className
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
// src/engine/Donut/Donut.tsx
|
|
213
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
214
|
+
function Donut(props) {
|
|
215
|
+
const { className } = props;
|
|
216
|
+
const option = useBuiltOption(props, buildOption4);
|
|
217
|
+
return /* @__PURE__ */ jsx5(EChart, {
|
|
218
|
+
option,
|
|
219
|
+
ariaLabel: props.ariaLabel,
|
|
220
|
+
height: props.height,
|
|
221
|
+
className
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
// src/engine/Gauge/Gauge.tsx
|
|
225
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
226
|
+
function Gauge(props) {
|
|
227
|
+
const { className } = props;
|
|
228
|
+
const option = useBuiltOption(props, buildOption5);
|
|
229
|
+
return /* @__PURE__ */ jsx6(EChart, {
|
|
230
|
+
option,
|
|
231
|
+
ariaLabel: props.ariaLabel,
|
|
232
|
+
height: props.height,
|
|
233
|
+
className
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
// src/engine/HeatmapGrid/HeatmapGrid.tsx
|
|
237
|
+
import { useMemo as useMemo2 } from "react";
|
|
238
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
239
|
+
function cellOf(event) {
|
|
240
|
+
if (typeof event !== "object" || event === null || !("value" in event))
|
|
241
|
+
return null;
|
|
242
|
+
const value = event.value;
|
|
243
|
+
if (!Array.isArray(value))
|
|
244
|
+
return null;
|
|
245
|
+
const [col, row, count] = value.map(Number);
|
|
246
|
+
if (col === undefined || row === undefined || count === undefined)
|
|
247
|
+
return null;
|
|
248
|
+
return { row, col, value: count };
|
|
249
|
+
}
|
|
250
|
+
function HeatmapGrid(props) {
|
|
251
|
+
const { className } = props;
|
|
252
|
+
const option = useBuiltOption(props, buildOption6);
|
|
253
|
+
const { onCellClick } = props;
|
|
254
|
+
const onEvents = useMemo2(() => onCellClick ? {
|
|
255
|
+
click: (event) => {
|
|
256
|
+
const cell = cellOf(event);
|
|
257
|
+
if (cell)
|
|
258
|
+
onCellClick(cell);
|
|
259
|
+
}
|
|
260
|
+
} : undefined, [onCellClick]);
|
|
261
|
+
return /* @__PURE__ */ jsx7(EChart, {
|
|
262
|
+
option,
|
|
263
|
+
ariaLabel: props.ariaLabel,
|
|
264
|
+
height: props.height,
|
|
265
|
+
className,
|
|
266
|
+
cursor: onCellClick ? "auto" : "default",
|
|
267
|
+
onEvents
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
// src/engine/Histogram/Histogram.tsx
|
|
271
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
272
|
+
function Histogram(props) {
|
|
273
|
+
const { className } = props;
|
|
274
|
+
const option = useBuiltOption(props, buildOption7);
|
|
275
|
+
return /* @__PURE__ */ jsx8(EChart, {
|
|
276
|
+
option,
|
|
277
|
+
ariaLabel: props.ariaLabel,
|
|
278
|
+
height: props.height,
|
|
279
|
+
className
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
// src/engine/LineChart/LineChart.tsx
|
|
283
|
+
import { useMemo as useMemo3, useRef as useRef2 } from "react";
|
|
284
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
285
|
+
var REPLACE_MERGE = ["series"];
|
|
286
|
+
function readZoomWindow(instance) {
|
|
287
|
+
const live = instance.getOption();
|
|
288
|
+
const zoom = live?.dataZoom?.[0];
|
|
289
|
+
if (!zoom)
|
|
290
|
+
return null;
|
|
291
|
+
const full = (zoom.start ?? 0) <= 0 && (zoom.end ?? 100) >= 100;
|
|
292
|
+
if (full || zoom.startValue === undefined || zoom.endValue === undefined)
|
|
293
|
+
return null;
|
|
294
|
+
return { from: zoom.startValue, to: zoom.endValue };
|
|
295
|
+
}
|
|
296
|
+
function carryZoom(option, instance) {
|
|
297
|
+
const zoomWindow = readZoomWindow(instance);
|
|
298
|
+
if (zoomWindow === null || !Array.isArray(option.dataZoom))
|
|
299
|
+
return option;
|
|
300
|
+
const dataZoom = option.dataZoom.map((entry) => {
|
|
301
|
+
const rest = Object.fromEntries(Object.entries(entry).filter(([key]) => key !== "start" && key !== "end"));
|
|
302
|
+
return { ...rest, startValue: zoomWindow.from, endValue: zoomWindow.to };
|
|
303
|
+
});
|
|
304
|
+
return { ...option, dataZoom };
|
|
305
|
+
}
|
|
306
|
+
function LineChart(props) {
|
|
307
|
+
const { className } = props;
|
|
308
|
+
const reportedRef = useRef2(null);
|
|
309
|
+
const option = useBuiltOption(props, buildOption8);
|
|
310
|
+
const { onRangeChange, zoom } = props;
|
|
311
|
+
const onEvents = useMemo3(() => zoom ? {
|
|
312
|
+
datazoom: (_event, instance) => {
|
|
313
|
+
const next = readZoomWindow(instance);
|
|
314
|
+
const previous = reportedRef.current;
|
|
315
|
+
if (next?.from === previous?.from && next?.to === previous?.to)
|
|
316
|
+
return;
|
|
317
|
+
reportedRef.current = next;
|
|
318
|
+
onRangeChange?.(next === null ? null : { from: new Date(next.from), to: new Date(next.to) });
|
|
319
|
+
}
|
|
320
|
+
} : undefined, [zoom, onRangeChange]);
|
|
321
|
+
return /* @__PURE__ */ jsx9(EChart, {
|
|
322
|
+
option,
|
|
323
|
+
ariaLabel: props.ariaLabel,
|
|
324
|
+
height: props.height,
|
|
325
|
+
className,
|
|
326
|
+
onEvents,
|
|
327
|
+
replaceMerge: zoom ? REPLACE_MERGE : undefined,
|
|
328
|
+
transform: zoom ? carryZoom : undefined
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
// src/engine/NetworkGraph/NetworkGraph.tsx
|
|
332
|
+
import { useMemo as useMemo4 } from "react";
|
|
333
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
334
|
+
function NetworkGraph(props) {
|
|
335
|
+
const { className } = props;
|
|
336
|
+
const { nodes, links, groupTones, onNodeClick, animate } = props;
|
|
337
|
+
const optionProps = useMemo4(() => ({ nodes, links, groupTones, onNodeClick, animate }), [nodes, links, groupTones, onNodeClick, animate]);
|
|
338
|
+
const option = useBuiltOption(optionProps, buildOption9);
|
|
339
|
+
const onEvents = useMemo4(() => onNodeClick ? {
|
|
340
|
+
click: (event) => {
|
|
341
|
+
const data = typeof event === "object" && event !== null && "data" in event ? event.data : undefined;
|
|
342
|
+
const node = nodes.find((entry) => entry.id === nodeIdOf(data));
|
|
343
|
+
if (node)
|
|
344
|
+
onNodeClick(node);
|
|
345
|
+
}
|
|
346
|
+
} : undefined, [nodes, onNodeClick]);
|
|
347
|
+
return /* @__PURE__ */ jsx10(EChart, {
|
|
348
|
+
option,
|
|
349
|
+
ariaLabel: props.ariaLabel,
|
|
350
|
+
height: props.height,
|
|
351
|
+
className,
|
|
352
|
+
onEvents
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
// src/engine/Nightingale/Nightingale.tsx
|
|
356
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
357
|
+
function Nightingale(props) {
|
|
358
|
+
const { className } = props;
|
|
359
|
+
const option = useBuiltOption(props, buildOption10);
|
|
360
|
+
return /* @__PURE__ */ jsx11(EChart, {
|
|
361
|
+
option,
|
|
362
|
+
ariaLabel: props.ariaLabel,
|
|
363
|
+
height: props.height,
|
|
364
|
+
className
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
// src/engine/Radar/Radar.tsx
|
|
368
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
369
|
+
function Radar(props) {
|
|
370
|
+
const { className } = props;
|
|
371
|
+
const option = useBuiltOption(props, buildOption11);
|
|
372
|
+
return /* @__PURE__ */ jsx12(EChart, {
|
|
373
|
+
option,
|
|
374
|
+
ariaLabel: props.ariaLabel,
|
|
375
|
+
height: props.height,
|
|
376
|
+
className
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
// src/engine/Sankey/Sankey.tsx
|
|
380
|
+
import { useMemo as useMemo5 } from "react";
|
|
381
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
382
|
+
function Sankey(props) {
|
|
383
|
+
const { className } = props;
|
|
384
|
+
const { nodes, links, groupTones, groupOrder, valueFormat, animate } = props;
|
|
385
|
+
const optionProps = useMemo5(() => ({ nodes, links, groupTones, groupOrder, valueFormat, animate }), [nodes, links, groupTones, groupOrder, valueFormat, animate]);
|
|
386
|
+
const option = useBuiltOption(optionProps, buildOption12);
|
|
387
|
+
return /* @__PURE__ */ jsx13(EChart, {
|
|
388
|
+
option,
|
|
389
|
+
ariaLabel: props.ariaLabel,
|
|
390
|
+
height: props.height,
|
|
391
|
+
className,
|
|
392
|
+
cursor: "default"
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
// src/engine/ScatterChart/ScatterChart.tsx
|
|
396
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
397
|
+
var liftDot = {
|
|
398
|
+
mouseover: (event, instance) => {
|
|
399
|
+
const index = dataIndexOf(event);
|
|
400
|
+
if (index !== undefined)
|
|
401
|
+
instance.dispatchAction({ type: "highlight", seriesId: DOTS_SERIES, dataIndex: index });
|
|
402
|
+
},
|
|
403
|
+
mouseout: (event, instance) => {
|
|
404
|
+
const index = dataIndexOf(event);
|
|
405
|
+
if (index !== undefined)
|
|
406
|
+
instance.dispatchAction({ type: "downplay", seriesId: DOTS_SERIES, dataIndex: index });
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
function dataIndexOf(event) {
|
|
410
|
+
if (typeof event !== "object" || event === null)
|
|
411
|
+
return;
|
|
412
|
+
const { seriesId, dataIndex } = event;
|
|
413
|
+
return seriesId === HIT_SERIES && typeof dataIndex === "number" ? dataIndex : undefined;
|
|
414
|
+
}
|
|
415
|
+
function ScatterChart(props) {
|
|
416
|
+
const { className } = props;
|
|
417
|
+
const option = useBuiltOption(props, buildOption13);
|
|
418
|
+
return /* @__PURE__ */ jsx14(EChart, {
|
|
419
|
+
option,
|
|
420
|
+
ariaLabel: props.ariaLabel,
|
|
421
|
+
height: props.height,
|
|
422
|
+
className,
|
|
423
|
+
onEvents: liftDot
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
// src/engine/Sunburst/Sunburst.tsx
|
|
427
|
+
import {
|
|
428
|
+
useCallback,
|
|
429
|
+
useMemo as useMemo6,
|
|
430
|
+
useState as useState2
|
|
431
|
+
} from "react";
|
|
432
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
433
|
+
function idOf(event) {
|
|
434
|
+
if (typeof event !== "object" || event === null || !("data" in event))
|
|
435
|
+
return;
|
|
436
|
+
const data = event.data;
|
|
437
|
+
return typeof data === "object" && data !== null && "id" in data ? String(data.id) : undefined;
|
|
438
|
+
}
|
|
439
|
+
var UNMEASURED = { width: 0, height: 0 };
|
|
440
|
+
function useSize() {
|
|
441
|
+
const [size, setSize] = useState2(UNMEASURED);
|
|
442
|
+
const ref = useCallback((element) => {
|
|
443
|
+
if (!element)
|
|
444
|
+
return;
|
|
445
|
+
const observer = new ResizeObserver(([entry]) => {
|
|
446
|
+
const width = Math.round(entry?.contentRect.width ?? 0);
|
|
447
|
+
const height = Math.round(entry?.contentRect.height ?? 0);
|
|
448
|
+
setSize((current) => current.width === width && current.height === height ? current : { width, height });
|
|
449
|
+
});
|
|
450
|
+
observer.observe(element);
|
|
451
|
+
return () => observer.disconnect();
|
|
452
|
+
}, []);
|
|
453
|
+
return [ref, size];
|
|
454
|
+
}
|
|
455
|
+
function Sunburst(props) {
|
|
456
|
+
const { className } = props;
|
|
457
|
+
const [measure, size] = useSize();
|
|
458
|
+
const fill = props.height === "fill";
|
|
459
|
+
const { width } = size;
|
|
460
|
+
const height = fill ? size.height : 0;
|
|
461
|
+
const tokens = useResolvedTokens();
|
|
462
|
+
const option = useMemo6(() => finishOption(buildOption14(props, tokens, width, height), props.animate), [props, tokens, width, height]);
|
|
463
|
+
const { onNodeClick, nodes } = props;
|
|
464
|
+
const onEvents = useMemo6(() => onNodeClick ? {
|
|
465
|
+
click: (event) => {
|
|
466
|
+
const id = idOf(event);
|
|
467
|
+
const path = id === undefined ? undefined : pathsById(nodes).get(id);
|
|
468
|
+
if (path)
|
|
469
|
+
onNodeClick(path);
|
|
470
|
+
}
|
|
471
|
+
} : undefined, [nodes, onNodeClick]);
|
|
472
|
+
return /* @__PURE__ */ jsx15("div", {
|
|
473
|
+
ref: measure,
|
|
474
|
+
className: chartFrameVariants({ fill }),
|
|
475
|
+
children: /* @__PURE__ */ jsx15(EChart, {
|
|
476
|
+
option,
|
|
477
|
+
ariaLabel: props.ariaLabel,
|
|
478
|
+
height: props.height,
|
|
479
|
+
className,
|
|
480
|
+
cursor: onNodeClick ? "auto" : "default",
|
|
481
|
+
onEvents
|
|
482
|
+
})
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
// src/engine/Treemap/Treemap.tsx
|
|
486
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
487
|
+
function Treemap(props) {
|
|
488
|
+
const { className } = props;
|
|
489
|
+
const option = useBuiltOption(props, buildOption15);
|
|
490
|
+
return /* @__PURE__ */ jsx16(EChart, {
|
|
491
|
+
option,
|
|
492
|
+
ariaLabel: props.ariaLabel,
|
|
493
|
+
height: props.height,
|
|
494
|
+
className
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
// src/engine/echartsEngine.ts
|
|
498
|
+
var echartsEngine = {
|
|
499
|
+
id: "echarts",
|
|
500
|
+
label: "ECharts 6",
|
|
501
|
+
notes: [
|
|
502
|
+
"All fifteen primitives are native ECharts series (bar, line, scatter, boxplot, gauge, pie, treemap, heatmap, graph, sankey, sunburst, radar); structural: canvas cannot read CSS variables, so every option is rebuilt from useResolvedTokens() and set with notMerge on a theme flip (the zoomable line chart merges instead, replacing only its series, so the zoom window survives a legend toggle).",
|
|
503
|
+
"Line zoom: native dataZoom (slider + inside, pinch or ctrl+wheel); the window is read back from the instance on each datazoom event and fed into every rebuilt option.",
|
|
504
|
+
"Gauge compare and overflow: a second gauge series is the inner arc; the max marker is a third, zero-span gauge whose only split line sits at the arc end, since the gauge has no marker of its own.",
|
|
505
|
+
"Donut compare: a second pie series is the inner ring; the shared tooltip matches the slice across rings by id.",
|
|
506
|
+
"Heatmap click: native click event and a per-item ink border for the selected cell (drawn last so no neighbour gap paints over it). Keyboard is a canvas gap: cells cannot take focus, so Enter/Space are not supported. The heatmap view ignores the series cursor, so a root class removes the pointer when cells are not buttons.",
|
|
507
|
+
"Sankey: columns come from groupOrder via node depth, spread over ECharts' own column count (the longest path), which it uses whatever depths the nodes carry; links inside one layer have no column to cross and draw as short back-curves.",
|
|
508
|
+
"Bar stacked100: no built-in percent stack; the values are normalised to category shares before the option, with a percent formatter.",
|
|
509
|
+
"Bullet: no bullet series; composed from three stacked bar series (the bands) and an 8px bar on a second hidden category axis, the target as a markLine, the value text as graphic elements.",
|
|
510
|
+
"Box plot: one borderColor strokes box, whiskers and median; it is set to ink-2 and a custom series redraws the median as a 2px ink line on top.",
|
|
511
|
+
"Treemap: native labels truncate rather than hide; a labelLayout hook measures the text against the node rect and parks unfit labels off the canvas.",
|
|
512
|
+
"Scatter: dots are hit-tested at their drawn size; an invisible 24px scatter series takes the hover and highlights the visible dot.",
|
|
513
|
+
"Histogram: ticks at bin edges come from a second category axis with n+1 entries and no boundary gap over the band axis.",
|
|
514
|
+
`Nightingale: native pie with roseType "area" (equal angles, radius by value; ECharts' "radius" rose sizes the angles too); labels under 4% of the total are switched off per item.`,
|
|
515
|
+
"Sunburst: native sunburst; the two rings are levels with their own radii, labels hide natively under 18 degrees (minAngle), nodeClick is off and a click maps the item id to its root-to-node path for onNodeClick.",
|
|
516
|
+
"Radar: native radar and radar series; the sectors are a silent pie behind it whose wedges span each sector's axes, labelled outside with icon and name; the baseline is a second one-axis radar sized to the baseline value, its ring in ink-2 and its axis name as the label; the per-axis tooltip comes from a transparent pie with one slice per axis on top, since the radar series only reports whole shapes."
|
|
517
|
+
],
|
|
518
|
+
BarChart,
|
|
519
|
+
LineChart,
|
|
520
|
+
ScatterChart,
|
|
521
|
+
Histogram,
|
|
522
|
+
BoxPlot,
|
|
523
|
+
Gauge,
|
|
524
|
+
Bullet,
|
|
525
|
+
Donut,
|
|
526
|
+
Treemap,
|
|
527
|
+
HeatmapGrid,
|
|
528
|
+
NetworkGraph,
|
|
529
|
+
Sankey,
|
|
530
|
+
Nightingale,
|
|
531
|
+
Sunburst,
|
|
532
|
+
Radar
|
|
533
|
+
};
|
|
534
|
+
// src/seam/FormatProvider.tsx
|
|
535
|
+
import { createContext, useContext, useMemo as useMemo7 } from "react";
|
|
536
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
537
|
+
var FormatContextState = createContext({});
|
|
538
|
+
function FormatProvider({ context, children }) {
|
|
539
|
+
return /* @__PURE__ */ jsx17(FormatContextState.Provider, {
|
|
540
|
+
value: context,
|
|
541
|
+
children
|
|
542
|
+
});
|
|
543
|
+
}
|
|
544
|
+
function useFormatContext() {
|
|
545
|
+
return useContext(FormatContextState);
|
|
546
|
+
}
|
|
547
|
+
function useFormatter(spec) {
|
|
548
|
+
const context = useFormatContext();
|
|
549
|
+
const key = spec === undefined ? undefined : JSON.stringify(spec);
|
|
550
|
+
return useMemo7(() => key === undefined ? undefined : formatterFor(JSON.parse(key), context), [key, context]);
|
|
551
|
+
}
|
|
552
|
+
// src/seam/ChartEngineProvider.tsx
|
|
553
|
+
import { createContext as createContext2, useContext as useContext2 } from "react";
|
|
554
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
555
|
+
var EngineContext = createContext2(null);
|
|
556
|
+
function ChartEngineProvider({ engine, children }) {
|
|
557
|
+
return /* @__PURE__ */ jsx18(EngineContext.Provider, {
|
|
558
|
+
value: engine,
|
|
559
|
+
children
|
|
560
|
+
});
|
|
561
|
+
}
|
|
562
|
+
function useChartEngine() {
|
|
563
|
+
const engine = useContext2(EngineContext);
|
|
564
|
+
if (!engine)
|
|
565
|
+
throw new Error("useChartEngine needs a ChartEngineProvider above it");
|
|
566
|
+
return engine;
|
|
567
|
+
}
|
|
568
|
+
export {
|
|
569
|
+
valueFormatSchema,
|
|
570
|
+
useResolvedTokens,
|
|
571
|
+
useFormatter,
|
|
572
|
+
useFormatContext,
|
|
573
|
+
useChartEngine,
|
|
574
|
+
toneVar,
|
|
575
|
+
tokensFrom,
|
|
576
|
+
tokenVar,
|
|
577
|
+
tokenNames,
|
|
578
|
+
tokenName,
|
|
579
|
+
resolveFormatContext,
|
|
580
|
+
readTokens,
|
|
581
|
+
plotHeightOf,
|
|
582
|
+
formatterFor,
|
|
583
|
+
formatWeek,
|
|
584
|
+
formatRelative,
|
|
585
|
+
formatPercent,
|
|
586
|
+
formatMinutes,
|
|
587
|
+
formatMeasured,
|
|
588
|
+
formatElapsed,
|
|
589
|
+
formatDay,
|
|
590
|
+
formatDate,
|
|
591
|
+
formatContextSchema,
|
|
592
|
+
formatCompact,
|
|
593
|
+
echartsEngine,
|
|
594
|
+
cn,
|
|
595
|
+
chartTone,
|
|
596
|
+
VALUE_FORMAT_KINDS,
|
|
597
|
+
UNIT_POSITIONS,
|
|
598
|
+
TOKEN_PREFIX,
|
|
599
|
+
THEME_TOKENS,
|
|
600
|
+
THEME_ATTRIBUTE,
|
|
601
|
+
SURFACE_TOKENS,
|
|
602
|
+
STATUS_TOKENS,
|
|
603
|
+
SERIES_TOKENS,
|
|
604
|
+
SEQUENTIAL_TOKENS,
|
|
605
|
+
SEQUENTIAL_STEPS,
|
|
606
|
+
POLE_TOKENS,
|
|
607
|
+
PERCENT_BASES,
|
|
608
|
+
FormatProvider,
|
|
609
|
+
DURATION_UNITS,
|
|
610
|
+
DELTA_TOKENS,
|
|
611
|
+
DEFAULT_FORMAT_CONTEXT,
|
|
612
|
+
DEFAULT_CHART_HEIGHT,
|
|
613
|
+
DATE_PATTERNS,
|
|
614
|
+
DARK_THEME,
|
|
615
|
+
ChartEngineProvider,
|
|
616
|
+
CHROME_ROLES,
|
|
617
|
+
ALL_TONES
|
|
618
|
+
};
|
package/dist/lib/cn.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type ClassValue } from 'clsx';
|
|
2
|
+
/**
|
|
3
|
+
* Joins class values and resolves Tailwind conflicts, the later class
|
|
4
|
+
* winning. A component calls it as `cn(xVariants({ ... }), className)`, so
|
|
5
|
+
* the passthrough `className` merges last and can override layout only.
|
|
6
|
+
*/
|
|
7
|
+
export declare function cn(...inputs: ClassValue[]): string;
|