@classic-homes/charts-react 0.1.37 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1720 -899
- package/dist/index.d.cts +81 -13
- package/dist/index.d.ts +81 -13
- package/dist/index.js +1865 -917
- package/package.json +11 -6
package/dist/index.js
CHANGED
|
@@ -77,10 +77,11 @@ var ChartError = React2.forwardRef(
|
|
|
77
77
|
)
|
|
78
78
|
}
|
|
79
79
|
),
|
|
80
|
-
/* @__PURE__ */ jsx2("p", { className: "mb-2 text-sm font-medium text-
|
|
80
|
+
/* @__PURE__ */ jsx2("p", { className: "mb-2 text-sm font-medium text-foreground", children: message }),
|
|
81
81
|
onRetry && /* @__PURE__ */ jsx2(
|
|
82
82
|
"button",
|
|
83
83
|
{
|
|
84
|
+
type: "button",
|
|
84
85
|
onClick: onRetry,
|
|
85
86
|
className: "rounded-md bg-destructive px-3 py-1.5 text-xs font-medium text-destructive-foreground transition-colors hover:bg-destructive/90",
|
|
86
87
|
children: "Retry"
|
|
@@ -152,10 +153,13 @@ var ChartContainer = React4.forwardRef(
|
|
|
152
153
|
onRetry,
|
|
153
154
|
className,
|
|
154
155
|
wrapperClassName,
|
|
156
|
+
legend,
|
|
157
|
+
legendPosition = "bottom",
|
|
155
158
|
children,
|
|
156
159
|
...props
|
|
157
160
|
}, ref) => {
|
|
158
161
|
const heightStyle = typeof height === "number" ? `${height}px` : height;
|
|
162
|
+
const descriptionId = `${React4.useId()}-desc`;
|
|
159
163
|
if (loading) {
|
|
160
164
|
return /* @__PURE__ */ jsx4(ChartSkeleton, { height, className: wrapperClassName });
|
|
161
165
|
}
|
|
@@ -173,28 +177,99 @@ var ChartContainer = React4.forwardRef(
|
|
|
173
177
|
if (empty) {
|
|
174
178
|
return /* @__PURE__ */ jsx4(ChartEmpty, { message: emptyMessage, height, className: wrapperClassName });
|
|
175
179
|
}
|
|
176
|
-
|
|
180
|
+
const chart = /* @__PURE__ */ jsxs4(
|
|
177
181
|
"div",
|
|
178
182
|
{
|
|
179
183
|
ref,
|
|
180
184
|
role: "img",
|
|
181
185
|
"aria-label": title,
|
|
182
|
-
"aria-describedby": description ?
|
|
186
|
+
"aria-describedby": description ? descriptionId : void 0,
|
|
183
187
|
"data-testid": "chart-container",
|
|
184
|
-
className: cn("rounded-lg border border-border bg-card", wrapperClassName),
|
|
188
|
+
className: legend ? "min-h-0 min-w-0 flex-1" : cn("rounded-lg border border-border bg-card", wrapperClassName),
|
|
185
189
|
...props,
|
|
186
190
|
children: [
|
|
187
|
-
description && /* @__PURE__ */ jsx4("span", { id:
|
|
191
|
+
description && /* @__PURE__ */ jsx4("span", { id: descriptionId, className: "sr-only", children: description }),
|
|
188
192
|
/* @__PURE__ */ jsx4("div", { className: cn("h-full w-full", className), style: { height: heightStyle }, children })
|
|
189
193
|
]
|
|
190
194
|
}
|
|
191
195
|
);
|
|
196
|
+
if (!legend) return chart;
|
|
197
|
+
const side = legendPosition === "left" || legendPosition === "right";
|
|
198
|
+
const leading = legendPosition === "top" || legendPosition === "left";
|
|
199
|
+
const legendNode = /* @__PURE__ */ jsx4(
|
|
200
|
+
"div",
|
|
201
|
+
{
|
|
202
|
+
"data-testid": "chart-legend",
|
|
203
|
+
className: cn("flex shrink-0 p-2", side ? "items-center" : "justify-center"),
|
|
204
|
+
children: legend
|
|
205
|
+
}
|
|
206
|
+
);
|
|
207
|
+
return /* @__PURE__ */ jsxs4(
|
|
208
|
+
"div",
|
|
209
|
+
{
|
|
210
|
+
className: cn(
|
|
211
|
+
"flex rounded-lg border border-border bg-card",
|
|
212
|
+
side ? "flex-row" : "flex-col",
|
|
213
|
+
wrapperClassName
|
|
214
|
+
),
|
|
215
|
+
children: [
|
|
216
|
+
leading && legendNode,
|
|
217
|
+
chart,
|
|
218
|
+
!leading && legendNode
|
|
219
|
+
]
|
|
220
|
+
}
|
|
221
|
+
);
|
|
192
222
|
}
|
|
193
223
|
);
|
|
194
224
|
ChartContainer.displayName = "ChartContainer";
|
|
195
225
|
|
|
196
|
-
// src/components/
|
|
226
|
+
// src/components/base/ChartLegend.tsx
|
|
197
227
|
import * as React5 from "react";
|
|
228
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
229
|
+
var ChartLegend = React5.forwardRef(
|
|
230
|
+
({ items, toggle, position = "bottom", chartTitle, orientation, className }, ref) => {
|
|
231
|
+
const vertical = (orientation ?? (position === "left" || position === "right" ? "vertical" : "horizontal")) === "vertical";
|
|
232
|
+
return /* @__PURE__ */ jsx5(
|
|
233
|
+
"ul",
|
|
234
|
+
{
|
|
235
|
+
ref,
|
|
236
|
+
"aria-label": chartTitle ? `${chartTitle} legend` : "Chart legend",
|
|
237
|
+
className: cn(
|
|
238
|
+
"flex gap-1 text-sm",
|
|
239
|
+
vertical ? "flex-col" : "flex-wrap justify-center",
|
|
240
|
+
className
|
|
241
|
+
),
|
|
242
|
+
children: items.map((item) => /* @__PURE__ */ jsx5("li", { children: /* @__PURE__ */ jsxs5(
|
|
243
|
+
"button",
|
|
244
|
+
{
|
|
245
|
+
type: "button",
|
|
246
|
+
"aria-pressed": item.visible,
|
|
247
|
+
onClick: () => toggle(item.name),
|
|
248
|
+
className: cn(
|
|
249
|
+
"inline-flex items-center gap-2 rounded-md px-2 py-1 text-left hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
250
|
+
item.visible ? "text-foreground" : "text-muted-foreground line-through"
|
|
251
|
+
),
|
|
252
|
+
children: [
|
|
253
|
+
/* @__PURE__ */ jsx5(
|
|
254
|
+
"span",
|
|
255
|
+
{
|
|
256
|
+
"aria-hidden": "true",
|
|
257
|
+
className: "h-3 w-3 shrink-0 rounded-sm",
|
|
258
|
+
style: { backgroundColor: item.color, opacity: item.visible ? 1 : 0.35 }
|
|
259
|
+
}
|
|
260
|
+
),
|
|
261
|
+
item.name
|
|
262
|
+
]
|
|
263
|
+
}
|
|
264
|
+
) }, item.name))
|
|
265
|
+
}
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
);
|
|
269
|
+
ChartLegend.displayName = "ChartLegend";
|
|
270
|
+
|
|
271
|
+
// src/components/core/LineChart.tsx
|
|
272
|
+
import * as React6 from "react";
|
|
198
273
|
import * as echarts3 from "echarts/core";
|
|
199
274
|
import { LineChart as EChartsLineChart } from "echarts/charts";
|
|
200
275
|
import {
|
|
@@ -204,14 +279,28 @@ import {
|
|
|
204
279
|
TitleComponent
|
|
205
280
|
} from "echarts/components";
|
|
206
281
|
import { CanvasRenderer } from "echarts/renderers";
|
|
207
|
-
import {
|
|
282
|
+
import {
|
|
283
|
+
buildAxis,
|
|
284
|
+
buildDataLabel,
|
|
285
|
+
buildLegend,
|
|
286
|
+
buildTooltip,
|
|
287
|
+
generateLineChartDescription,
|
|
288
|
+
getChartColors,
|
|
289
|
+
hasPointLabels,
|
|
290
|
+
gridInset,
|
|
291
|
+
mergeChartOption,
|
|
292
|
+
seriesLabelLookup,
|
|
293
|
+
THEME_DARK as THEME_DARK2,
|
|
294
|
+
withPointLabels
|
|
295
|
+
} from "@classic-homes/charts-core";
|
|
208
296
|
|
|
209
297
|
// src/hooks/useChart.ts
|
|
210
|
-
import { useEffect as useEffect4, useRef
|
|
298
|
+
import { useEffect as useEffect4, useRef } from "react";
|
|
211
299
|
import * as echarts2 from "echarts/core";
|
|
300
|
+
import { getReplaceMerge } from "@classic-homes/charts-core";
|
|
212
301
|
|
|
213
302
|
// src/hooks/useChartTheme.ts
|
|
214
|
-
import { useEffect, useState
|
|
303
|
+
import { useEffect, useState } from "react";
|
|
215
304
|
import * as echarts from "echarts/core";
|
|
216
305
|
import { lightTheme, darkTheme, THEME_LIGHT, THEME_DARK } from "@classic-homes/charts-core";
|
|
217
306
|
var themesRegistered = false;
|
|
@@ -221,18 +310,18 @@ function registerClassicThemes() {
|
|
|
221
310
|
echarts.registerTheme(THEME_DARK, darkTheme);
|
|
222
311
|
themesRegistered = true;
|
|
223
312
|
}
|
|
313
|
+
function resolveTheme(preference) {
|
|
314
|
+
if (preference !== "auto") {
|
|
315
|
+
return preference === "dark" ? THEME_DARK : THEME_LIGHT;
|
|
316
|
+
}
|
|
317
|
+
if (typeof document === "undefined") return THEME_LIGHT;
|
|
318
|
+
return document.documentElement.classList.contains("dark") ? THEME_DARK : THEME_LIGHT;
|
|
319
|
+
}
|
|
224
320
|
function useChartTheme(preference = "auto") {
|
|
225
|
-
const [currentTheme, setCurrentTheme] = useState(
|
|
226
|
-
const updateTheme = useCallback(() => {
|
|
227
|
-
if (preference !== "auto") {
|
|
228
|
-
setCurrentTheme(preference === "dark" ? THEME_DARK : THEME_LIGHT);
|
|
229
|
-
return;
|
|
230
|
-
}
|
|
231
|
-
const isDark = document.documentElement.classList.contains("dark");
|
|
232
|
-
setCurrentTheme(isDark ? THEME_DARK : THEME_LIGHT);
|
|
233
|
-
}, [preference]);
|
|
321
|
+
const [currentTheme, setCurrentTheme] = useState(() => resolveTheme(preference));
|
|
234
322
|
useEffect(() => {
|
|
235
323
|
registerClassicThemes();
|
|
324
|
+
const updateTheme = () => setCurrentTheme(resolveTheme(preference));
|
|
236
325
|
updateTheme();
|
|
237
326
|
if (preference !== "auto") return;
|
|
238
327
|
const observer = new MutationObserver((mutations) => {
|
|
@@ -246,26 +335,29 @@ function useChartTheme(preference = "auto") {
|
|
|
246
335
|
attributes: true,
|
|
247
336
|
attributeFilter: ["class"]
|
|
248
337
|
});
|
|
249
|
-
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
250
|
-
const handleMediaChange = () => updateTheme();
|
|
251
|
-
mediaQuery.addEventListener("change", handleMediaChange);
|
|
252
338
|
return () => {
|
|
253
339
|
observer.disconnect();
|
|
254
|
-
mediaQuery.removeEventListener("change", handleMediaChange);
|
|
255
340
|
};
|
|
256
|
-
}, [preference
|
|
341
|
+
}, [preference]);
|
|
257
342
|
return currentTheme;
|
|
258
343
|
}
|
|
259
344
|
|
|
260
345
|
// src/hooks/useChartResize.ts
|
|
261
|
-
import { useEffect as useEffect2,
|
|
346
|
+
import { useEffect as useEffect2, useLayoutEffect, useState as useState2 } from "react";
|
|
347
|
+
var useIsomorphicLayoutEffect = typeof window === "undefined" ? useEffect2 : useLayoutEffect;
|
|
348
|
+
function useRefElement(ref) {
|
|
349
|
+
const [element, setElement] = useState2(null);
|
|
350
|
+
useIsomorphicLayoutEffect(() => {
|
|
351
|
+
setElement(ref.current);
|
|
352
|
+
});
|
|
353
|
+
return element;
|
|
354
|
+
}
|
|
262
355
|
function useChartResize(chartRef, containerRef) {
|
|
263
|
-
const
|
|
356
|
+
const container = useRefElement(containerRef);
|
|
264
357
|
useEffect2(() => {
|
|
265
|
-
const container = containerRef.current;
|
|
266
358
|
if (!container) return;
|
|
267
359
|
let resizeTimeout;
|
|
268
|
-
|
|
360
|
+
const observer = new ResizeObserver(() => {
|
|
269
361
|
clearTimeout(resizeTimeout);
|
|
270
362
|
resizeTimeout = setTimeout(() => {
|
|
271
363
|
const chart = chartRef.current;
|
|
@@ -274,18 +366,18 @@ function useChartResize(chartRef, containerRef) {
|
|
|
274
366
|
}
|
|
275
367
|
}, 100);
|
|
276
368
|
});
|
|
277
|
-
|
|
369
|
+
observer.observe(container);
|
|
278
370
|
return () => {
|
|
279
371
|
clearTimeout(resizeTimeout);
|
|
280
|
-
|
|
372
|
+
observer.disconnect();
|
|
281
373
|
};
|
|
282
|
-
}, [chartRef,
|
|
374
|
+
}, [chartRef, container]);
|
|
283
375
|
}
|
|
284
376
|
|
|
285
377
|
// src/hooks/useReducedMotion.ts
|
|
286
|
-
import { useState as
|
|
378
|
+
import { useState as useState3, useEffect as useEffect3 } from "react";
|
|
287
379
|
function useReducedMotion() {
|
|
288
|
-
const [reducedMotion, setReducedMotion] =
|
|
380
|
+
const [reducedMotion, setReducedMotion] = useState3(false);
|
|
289
381
|
useEffect3(() => {
|
|
290
382
|
const mediaQuery = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
291
383
|
setReducedMotion(mediaQuery.matches);
|
|
@@ -301,29 +393,39 @@ function useReducedMotion() {
|
|
|
301
393
|
}
|
|
302
394
|
|
|
303
395
|
// src/hooks/useChart.ts
|
|
304
|
-
var
|
|
396
|
+
var isComponentType = (mainType) => echarts2.ComponentModel.hasClass(mainType);
|
|
397
|
+
function applyOption(chart, prev, next) {
|
|
398
|
+
chart.setOption(next, {
|
|
399
|
+
replaceMerge: getReplaceMerge(prev, next, isComponentType),
|
|
400
|
+
lazyUpdate: true
|
|
401
|
+
});
|
|
402
|
+
}
|
|
305
403
|
function useChart({
|
|
306
404
|
option,
|
|
307
405
|
theme = "auto",
|
|
308
406
|
animation,
|
|
309
407
|
onReady
|
|
310
408
|
}) {
|
|
311
|
-
const containerRef =
|
|
312
|
-
const
|
|
409
|
+
const containerRef = useRef(null);
|
|
410
|
+
const container = useRefElement(containerRef);
|
|
411
|
+
const chartRef = useRef(null);
|
|
313
412
|
const currentTheme = useChartTheme(theme);
|
|
314
413
|
const reducedMotion = useReducedMotion();
|
|
315
|
-
const onReadyRef =
|
|
414
|
+
const onReadyRef = useRef(onReady);
|
|
316
415
|
onReadyRef.current = onReady;
|
|
317
|
-
const optionRef =
|
|
416
|
+
const optionRef = useRef(option);
|
|
318
417
|
optionRef.current = {
|
|
319
418
|
...option,
|
|
320
|
-
|
|
419
|
+
// Reduced motion always wins over the animation prop
|
|
420
|
+
animation: (animation ?? true) && !reducedMotion
|
|
321
421
|
};
|
|
422
|
+
const appliedRef = useRef(null);
|
|
322
423
|
useEffect4(() => {
|
|
323
|
-
if (!
|
|
324
|
-
const chart = echarts2.init(
|
|
424
|
+
if (!container) return;
|
|
425
|
+
const chart = echarts2.init(container, currentTheme);
|
|
325
426
|
chartRef.current = chart;
|
|
326
|
-
chart
|
|
427
|
+
applyOption(chart, null, optionRef.current);
|
|
428
|
+
appliedRef.current = optionRef.current;
|
|
327
429
|
onReadyRef.current?.(chart);
|
|
328
430
|
return () => {
|
|
329
431
|
chart.dispose();
|
|
@@ -331,11 +433,12 @@ function useChart({
|
|
|
331
433
|
chartRef.current = null;
|
|
332
434
|
}
|
|
333
435
|
};
|
|
334
|
-
}, [currentTheme]);
|
|
436
|
+
}, [container, currentTheme]);
|
|
335
437
|
useEffect4(() => {
|
|
336
438
|
const chart = chartRef.current;
|
|
337
439
|
if (!chart || chart.isDisposed()) return;
|
|
338
|
-
chart.
|
|
440
|
+
applyOption(chart, appliedRef.current, optionRef.current);
|
|
441
|
+
appliedRef.current = optionRef.current;
|
|
339
442
|
}, [option, animation, reducedMotion]);
|
|
340
443
|
useChartResize(chartRef, containerRef);
|
|
341
444
|
return {
|
|
@@ -345,8 +448,76 @@ function useChart({
|
|
|
345
448
|
};
|
|
346
449
|
}
|
|
347
450
|
|
|
451
|
+
// src/hooks/useChartLegend.ts
|
|
452
|
+
import { useCallback, useRef as useRef3, useState as useState4 } from "react";
|
|
453
|
+
import {
|
|
454
|
+
getLegendItems
|
|
455
|
+
} from "@classic-homes/charts-core";
|
|
456
|
+
|
|
457
|
+
// src/hooks/useLatestRef.ts
|
|
458
|
+
import { useRef as useRef2 } from "react";
|
|
459
|
+
function useLatestRef(value) {
|
|
460
|
+
const ref = useRef2(value);
|
|
461
|
+
ref.current = value;
|
|
462
|
+
return ref;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// src/hooks/useChartLegend.ts
|
|
466
|
+
var LEGEND_EVENTS = [
|
|
467
|
+
"legendselectchanged",
|
|
468
|
+
"legendselected",
|
|
469
|
+
"legendunselected",
|
|
470
|
+
"legendselectall",
|
|
471
|
+
"legendinverseselect"
|
|
472
|
+
];
|
|
473
|
+
function useChartLegend({
|
|
474
|
+
names,
|
|
475
|
+
colors,
|
|
476
|
+
palette,
|
|
477
|
+
config,
|
|
478
|
+
title,
|
|
479
|
+
onLegendChange
|
|
480
|
+
}) {
|
|
481
|
+
const chartRef = useRef3(null);
|
|
482
|
+
const [visible, setVisible] = useState4({});
|
|
483
|
+
const latest = useLatestRef({ onLegendChange });
|
|
484
|
+
const attach = useCallback(
|
|
485
|
+
(chart) => {
|
|
486
|
+
chartRef.current = chart;
|
|
487
|
+
setVisible({});
|
|
488
|
+
const handler = (params) => {
|
|
489
|
+
const selected = { ...params.selected };
|
|
490
|
+
setVisible(selected);
|
|
491
|
+
latest.current.onLegendChange?.(selected);
|
|
492
|
+
};
|
|
493
|
+
for (const event of LEGEND_EVENTS) chart.on(event, handler);
|
|
494
|
+
},
|
|
495
|
+
[latest]
|
|
496
|
+
);
|
|
497
|
+
const dispatch = (action) => {
|
|
498
|
+
const chart = chartRef.current;
|
|
499
|
+
if (chart && !chart.isDisposed()) chart.dispatchAction(action);
|
|
500
|
+
};
|
|
501
|
+
return {
|
|
502
|
+
attach,
|
|
503
|
+
renderProps: {
|
|
504
|
+
items: getLegendItems(names, palette, colors, visible),
|
|
505
|
+
position: config?.position ?? "bottom",
|
|
506
|
+
chartTitle: title,
|
|
507
|
+
toggle: (name) => dispatch({ type: "legendToggleSelect", name }),
|
|
508
|
+
setVisible: (name, show) => dispatch({ type: show ? "legendSelect" : "legendUnSelect", name }),
|
|
509
|
+
showOnly: (name) => {
|
|
510
|
+
for (const other of names) {
|
|
511
|
+
dispatch({ type: other === name ? "legendSelect" : "legendUnSelect", name: other });
|
|
512
|
+
}
|
|
513
|
+
},
|
|
514
|
+
showAll: () => dispatch({ type: "legendAllSelect" })
|
|
515
|
+
}
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
|
|
348
519
|
// src/components/core/LineChart.tsx
|
|
349
|
-
import { jsx as
|
|
520
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
350
521
|
echarts3.use([
|
|
351
522
|
EChartsLineChart,
|
|
352
523
|
GridComponent,
|
|
@@ -355,7 +526,7 @@ echarts3.use([
|
|
|
355
526
|
TitleComponent,
|
|
356
527
|
CanvasRenderer
|
|
357
528
|
]);
|
|
358
|
-
var LineChart =
|
|
529
|
+
var LineChart = React6.forwardRef(
|
|
359
530
|
({
|
|
360
531
|
title,
|
|
361
532
|
description,
|
|
@@ -373,63 +544,110 @@ var LineChart = React5.forwardRef(
|
|
|
373
544
|
areaFilled = false,
|
|
374
545
|
showDataPoints = false,
|
|
375
546
|
stacked = false,
|
|
547
|
+
showLabels = false,
|
|
548
|
+
labelFormatter,
|
|
549
|
+
xAxisConfig,
|
|
550
|
+
yAxisConfig,
|
|
551
|
+
tooltipFormatter,
|
|
552
|
+
tooltipValueFormatter,
|
|
553
|
+
legend: legendConfig,
|
|
554
|
+
renderLegend,
|
|
555
|
+
onLegendChange,
|
|
556
|
+
option: optionOverride,
|
|
376
557
|
onClick,
|
|
377
558
|
onHover,
|
|
378
559
|
class: className,
|
|
379
560
|
...props
|
|
380
561
|
}, ref) => {
|
|
381
562
|
const isEmpty = !data?.categories?.length || !data?.series?.length || data.series.every((s) => !s.data?.length);
|
|
382
|
-
const
|
|
563
|
+
const currentTheme = useChartTheme(theme);
|
|
564
|
+
const chartColors = getChartColors(currentTheme);
|
|
565
|
+
const legend = useChartLegend({
|
|
566
|
+
names: data?.series?.map((s) => s.name) ?? [],
|
|
567
|
+
colors: data?.series?.map((s) => s.color) ?? [],
|
|
568
|
+
palette: chartColors.series,
|
|
569
|
+
config: legendConfig,
|
|
570
|
+
title,
|
|
571
|
+
onLegendChange
|
|
572
|
+
});
|
|
573
|
+
const customLegend = renderLegend !== void 0;
|
|
574
|
+
const option = React6.useMemo(() => {
|
|
383
575
|
if (isEmpty) return {};
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
576
|
+
const getLabel = seriesLabelLookup(data.series);
|
|
577
|
+
const showSymbol = showDataPoints || showLabels || hasPointLabels(data.series);
|
|
578
|
+
return mergeChartOption(
|
|
579
|
+
{
|
|
580
|
+
grid: {
|
|
581
|
+
left: "3%",
|
|
582
|
+
right: "4%",
|
|
583
|
+
bottom: "3%",
|
|
584
|
+
containLabel: true,
|
|
585
|
+
...gridInset(legendConfig, showLegend && !customLegend, xAxisConfig, yAxisConfig)
|
|
586
|
+
},
|
|
587
|
+
tooltip: buildTooltip(
|
|
588
|
+
{
|
|
589
|
+
trigger: "axis",
|
|
590
|
+
axisPointer: {
|
|
591
|
+
type: "cross",
|
|
592
|
+
label: {
|
|
593
|
+
backgroundColor: chartColors.axisPointerLabel
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
},
|
|
597
|
+
{
|
|
598
|
+
show: showTooltip,
|
|
599
|
+
formatter: tooltipFormatter,
|
|
600
|
+
valueFormatter: tooltipValueFormatter,
|
|
601
|
+
getLabel
|
|
397
602
|
}
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
603
|
+
),
|
|
604
|
+
legend: buildLegend(
|
|
605
|
+
data.series.map((s) => s.name),
|
|
606
|
+
legendConfig,
|
|
607
|
+
{ show: showLegend, custom: customLegend }
|
|
608
|
+
),
|
|
609
|
+
xAxis: buildAxis(
|
|
610
|
+
{
|
|
611
|
+
type: "category",
|
|
612
|
+
boundaryGap: false,
|
|
613
|
+
data: data.categories,
|
|
614
|
+
splitLine: {
|
|
615
|
+
show: showGrid
|
|
616
|
+
}
|
|
617
|
+
},
|
|
618
|
+
xAxisConfig
|
|
619
|
+
),
|
|
620
|
+
yAxis: buildAxis(
|
|
621
|
+
{
|
|
622
|
+
type: "value",
|
|
623
|
+
splitLine: {
|
|
624
|
+
show: showGrid
|
|
625
|
+
}
|
|
626
|
+
},
|
|
627
|
+
yAxisConfig
|
|
628
|
+
),
|
|
629
|
+
series: data.series.map((series) => ({
|
|
630
|
+
name: series.name,
|
|
631
|
+
type: "line",
|
|
632
|
+
data: withPointLabels(series.data, series.labels, labelFormatter, { position: "top" }),
|
|
633
|
+
smooth,
|
|
634
|
+
showSymbol,
|
|
635
|
+
symbolSize: showDataPoints ? 6 : 0,
|
|
636
|
+
stack: stacked ? "Total" : void 0,
|
|
637
|
+
areaStyle: areaFilled ? { opacity: 0.3 } : void 0,
|
|
638
|
+
itemStyle: series.color ? { color: series.color } : void 0,
|
|
639
|
+
label: buildDataLabel({ show: true, position: "top" }, void 0, {
|
|
640
|
+
show: showLabels,
|
|
641
|
+
formatter: labelFormatter,
|
|
642
|
+
getLabel
|
|
643
|
+
}),
|
|
644
|
+
emphasis: {
|
|
645
|
+
focus: "series"
|
|
646
|
+
}
|
|
647
|
+
}))
|
|
417
648
|
},
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
type: "line",
|
|
421
|
-
data: series.data,
|
|
422
|
-
smooth,
|
|
423
|
-
showSymbol: showDataPoints,
|
|
424
|
-
symbolSize: showDataPoints ? 6 : 0,
|
|
425
|
-
stack: stacked ? "Total" : void 0,
|
|
426
|
-
areaStyle: areaFilled ? { opacity: 0.3 } : void 0,
|
|
427
|
-
itemStyle: series.color ? { color: series.color } : void 0,
|
|
428
|
-
emphasis: {
|
|
429
|
-
focus: "series"
|
|
430
|
-
}
|
|
431
|
-
}))
|
|
432
|
-
};
|
|
649
|
+
optionOverride
|
|
650
|
+
);
|
|
433
651
|
}, [
|
|
434
652
|
data,
|
|
435
653
|
isEmpty,
|
|
@@ -439,45 +657,57 @@ var LineChart = React5.forwardRef(
|
|
|
439
657
|
smooth,
|
|
440
658
|
areaFilled,
|
|
441
659
|
showDataPoints,
|
|
442
|
-
stacked
|
|
660
|
+
stacked,
|
|
661
|
+
chartColors,
|
|
662
|
+
showLabels,
|
|
663
|
+
labelFormatter,
|
|
664
|
+
xAxisConfig,
|
|
665
|
+
yAxisConfig,
|
|
666
|
+
tooltipFormatter,
|
|
667
|
+
tooltipValueFormatter,
|
|
668
|
+
legendConfig,
|
|
669
|
+
customLegend,
|
|
670
|
+
optionOverride
|
|
443
671
|
]);
|
|
672
|
+
const latest = useLatestRef({ onClick, onHover });
|
|
444
673
|
const { containerRef } = useChart({
|
|
445
674
|
option,
|
|
446
|
-
theme,
|
|
675
|
+
theme: currentTheme === THEME_DARK2 ? "dark" : "light",
|
|
447
676
|
animation,
|
|
448
677
|
onReady: (chart) => {
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
678
|
+
legend.attach(chart);
|
|
679
|
+
chart.on("click", (params) => {
|
|
680
|
+
const { onClick: onClick2 } = latest.current;
|
|
681
|
+
if (!onClick2) return;
|
|
682
|
+
onClick2({
|
|
683
|
+
type: params.type || "click",
|
|
684
|
+
componentType: params.componentType || "series",
|
|
685
|
+
seriesIndex: params.seriesIndex,
|
|
686
|
+
seriesName: params.seriesName || "",
|
|
687
|
+
dataIndex: params.dataIndex || 0,
|
|
688
|
+
name: params.name || "",
|
|
689
|
+
value: params.value,
|
|
690
|
+
color: params.color
|
|
461
691
|
});
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
692
|
+
});
|
|
693
|
+
chart.on("mouseover", (params) => {
|
|
694
|
+
const { onHover: onHover2 } = latest.current;
|
|
695
|
+
if (!onHover2) return;
|
|
696
|
+
onHover2({
|
|
697
|
+
type: params.type || "mouseover",
|
|
698
|
+
componentType: params.componentType || "series",
|
|
699
|
+
seriesIndex: params.seriesIndex,
|
|
700
|
+
seriesName: params.seriesName || "",
|
|
701
|
+
dataIndex: params.dataIndex || 0,
|
|
702
|
+
name: params.name || "",
|
|
703
|
+
value: params.value,
|
|
704
|
+
color: params.color
|
|
475
705
|
});
|
|
476
|
-
}
|
|
706
|
+
});
|
|
477
707
|
}
|
|
478
708
|
});
|
|
479
709
|
const accessibilityDescription = description || (!isEmpty ? generateLineChartDescription(title, data) : void 0);
|
|
480
|
-
return /* @__PURE__ */
|
|
710
|
+
return /* @__PURE__ */ jsx6(
|
|
481
711
|
ChartContainer,
|
|
482
712
|
{
|
|
483
713
|
ref,
|
|
@@ -489,8 +719,10 @@ var LineChart = React5.forwardRef(
|
|
|
489
719
|
empty: isEmpty,
|
|
490
720
|
emptyMessage,
|
|
491
721
|
className: cn(className),
|
|
722
|
+
legend: !isEmpty && renderLegend ? renderLegend(legend.renderProps) : void 0,
|
|
723
|
+
legendPosition: legendConfig?.position,
|
|
492
724
|
...props,
|
|
493
|
-
children: /* @__PURE__ */
|
|
725
|
+
children: /* @__PURE__ */ jsx6("div", { ref: containerRef, className: "h-full w-full" })
|
|
494
726
|
}
|
|
495
727
|
);
|
|
496
728
|
}
|
|
@@ -498,7 +730,7 @@ var LineChart = React5.forwardRef(
|
|
|
498
730
|
LineChart.displayName = "LineChart";
|
|
499
731
|
|
|
500
732
|
// src/components/core/BarChart.tsx
|
|
501
|
-
import * as
|
|
733
|
+
import * as React7 from "react";
|
|
502
734
|
import * as echarts4 from "echarts/core";
|
|
503
735
|
import { BarChart as EChartsBarChart } from "echarts/charts";
|
|
504
736
|
import {
|
|
@@ -508,8 +740,19 @@ import {
|
|
|
508
740
|
TitleComponent as TitleComponent2
|
|
509
741
|
} from "echarts/components";
|
|
510
742
|
import { CanvasRenderer as CanvasRenderer2 } from "echarts/renderers";
|
|
511
|
-
import {
|
|
512
|
-
|
|
743
|
+
import {
|
|
744
|
+
buildAxis as buildAxis2,
|
|
745
|
+
buildDataLabel as buildDataLabel2,
|
|
746
|
+
buildLegend as buildLegend2,
|
|
747
|
+
buildTooltip as buildTooltip2,
|
|
748
|
+
generateBarChartDescription,
|
|
749
|
+
getChartColors as getChartColors2,
|
|
750
|
+
gridInset as gridInset2,
|
|
751
|
+
mergeChartOption as mergeChartOption2,
|
|
752
|
+
seriesLabelLookup as seriesLabelLookup2,
|
|
753
|
+
withPointLabels as withPointLabels2
|
|
754
|
+
} from "@classic-homes/charts-core";
|
|
755
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
513
756
|
echarts4.use([
|
|
514
757
|
EChartsBarChart,
|
|
515
758
|
GridComponent2,
|
|
@@ -518,7 +761,7 @@ echarts4.use([
|
|
|
518
761
|
TitleComponent2,
|
|
519
762
|
CanvasRenderer2
|
|
520
763
|
]);
|
|
521
|
-
var BarChart =
|
|
764
|
+
var BarChart = React7.forwardRef(
|
|
522
765
|
({
|
|
523
766
|
title,
|
|
524
767
|
description,
|
|
@@ -535,13 +778,32 @@ var BarChart = React6.forwardRef(
|
|
|
535
778
|
orientation = "vertical",
|
|
536
779
|
stacked = false,
|
|
537
780
|
showValues = false,
|
|
781
|
+
labelFormatter,
|
|
782
|
+
xAxisConfig,
|
|
783
|
+
yAxisConfig,
|
|
784
|
+
tooltipFormatter,
|
|
785
|
+
tooltipValueFormatter,
|
|
786
|
+
legend: legendConfig,
|
|
787
|
+
renderLegend,
|
|
788
|
+
onLegendChange,
|
|
789
|
+
option: optionOverride,
|
|
538
790
|
onClick,
|
|
539
791
|
class: className,
|
|
540
792
|
...props
|
|
541
793
|
}, ref) => {
|
|
542
794
|
const isEmpty = !data?.categories?.length || !data?.series?.length || data.series.every((s) => !s.data?.length);
|
|
543
795
|
const isHorizontal = orientation === "horizontal";
|
|
544
|
-
const
|
|
796
|
+
const currentTheme = useChartTheme(theme);
|
|
797
|
+
const legend = useChartLegend({
|
|
798
|
+
names: data?.series?.map((s) => s.name) ?? [],
|
|
799
|
+
colors: data?.series?.map((s) => s.color) ?? [],
|
|
800
|
+
palette: getChartColors2(currentTheme).series,
|
|
801
|
+
config: legendConfig,
|
|
802
|
+
title,
|
|
803
|
+
onLegendChange
|
|
804
|
+
});
|
|
805
|
+
const customLegend = renderLegend !== void 0;
|
|
806
|
+
const option = React7.useMemo(() => {
|
|
545
807
|
if (isEmpty) return {};
|
|
546
808
|
const categoryAxis = {
|
|
547
809
|
type: "category",
|
|
@@ -556,64 +818,103 @@ var BarChart = React6.forwardRef(
|
|
|
556
818
|
show: showGrid
|
|
557
819
|
}
|
|
558
820
|
};
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
821
|
+
const getLabel = seriesLabelLookup2(data.series);
|
|
822
|
+
return mergeChartOption2(
|
|
823
|
+
{
|
|
824
|
+
grid: {
|
|
825
|
+
left: "3%",
|
|
826
|
+
right: "4%",
|
|
827
|
+
bottom: "3%",
|
|
828
|
+
containLabel: true,
|
|
829
|
+
...gridInset2(legendConfig, showLegend && !customLegend, xAxisConfig, yAxisConfig)
|
|
830
|
+
},
|
|
831
|
+
tooltip: buildTooltip2(
|
|
832
|
+
{
|
|
833
|
+
trigger: "axis",
|
|
834
|
+
axisPointer: {
|
|
835
|
+
type: "shadow"
|
|
836
|
+
}
|
|
837
|
+
},
|
|
838
|
+
{
|
|
839
|
+
show: showTooltip,
|
|
840
|
+
formatter: tooltipFormatter,
|
|
841
|
+
valueFormatter: tooltipValueFormatter,
|
|
842
|
+
getLabel
|
|
843
|
+
}
|
|
844
|
+
),
|
|
845
|
+
legend: buildLegend2(
|
|
846
|
+
data.series.map((s) => s.name),
|
|
847
|
+
legendConfig,
|
|
848
|
+
{ show: showLegend, custom: customLegend }
|
|
849
|
+
),
|
|
850
|
+
xAxis: buildAxis2(isHorizontal ? valueAxis : categoryAxis, xAxisConfig),
|
|
851
|
+
yAxis: buildAxis2(isHorizontal ? categoryAxis : valueAxis, yAxisConfig),
|
|
852
|
+
series: data.series.map((series) => ({
|
|
853
|
+
name: series.name,
|
|
854
|
+
type: "bar",
|
|
855
|
+
data: withPointLabels2(series.data, series.labels, labelFormatter, {
|
|
856
|
+
position: isHorizontal ? "right" : "top"
|
|
857
|
+
}),
|
|
858
|
+
stack: stacked ? "Total" : void 0,
|
|
859
|
+
itemStyle: series.color ? { color: series.color } : void 0,
|
|
860
|
+
label: buildDataLabel2(
|
|
861
|
+
{
|
|
862
|
+
show: true,
|
|
863
|
+
position: isHorizontal ? "right" : "top"
|
|
864
|
+
},
|
|
865
|
+
void 0,
|
|
866
|
+
{ show: showValues, formatter: labelFormatter, getLabel }
|
|
867
|
+
),
|
|
868
|
+
emphasis: {
|
|
869
|
+
focus: "series"
|
|
870
|
+
}
|
|
871
|
+
}))
|
|
565
872
|
},
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
} : void 0,
|
|
588
|
-
emphasis: {
|
|
589
|
-
focus: "series"
|
|
590
|
-
}
|
|
591
|
-
}))
|
|
592
|
-
};
|
|
593
|
-
}, [data, isEmpty, showTooltip, showLegend, showGrid, isHorizontal, stacked, showValues]);
|
|
873
|
+
optionOverride
|
|
874
|
+
);
|
|
875
|
+
}, [
|
|
876
|
+
data,
|
|
877
|
+
isEmpty,
|
|
878
|
+
showTooltip,
|
|
879
|
+
showLegend,
|
|
880
|
+
showGrid,
|
|
881
|
+
isHorizontal,
|
|
882
|
+
stacked,
|
|
883
|
+
showValues,
|
|
884
|
+
labelFormatter,
|
|
885
|
+
xAxisConfig,
|
|
886
|
+
yAxisConfig,
|
|
887
|
+
tooltipFormatter,
|
|
888
|
+
tooltipValueFormatter,
|
|
889
|
+
legendConfig,
|
|
890
|
+
customLegend,
|
|
891
|
+
optionOverride
|
|
892
|
+
]);
|
|
893
|
+
const latest = useLatestRef({ onClick });
|
|
594
894
|
const { containerRef } = useChart({
|
|
595
895
|
option,
|
|
596
896
|
theme,
|
|
597
897
|
animation,
|
|
598
898
|
onReady: (chart) => {
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
899
|
+
legend.attach(chart);
|
|
900
|
+
chart.on("click", (params) => {
|
|
901
|
+
const { onClick: onClick2 } = latest.current;
|
|
902
|
+
if (!onClick2) return;
|
|
903
|
+
onClick2({
|
|
904
|
+
type: params.type || "click",
|
|
905
|
+
componentType: params.componentType || "series",
|
|
906
|
+
seriesIndex: params.seriesIndex,
|
|
907
|
+
seriesName: params.seriesName || "",
|
|
908
|
+
dataIndex: params.dataIndex || 0,
|
|
909
|
+
name: params.name || "",
|
|
910
|
+
value: params.value,
|
|
911
|
+
color: params.color
|
|
611
912
|
});
|
|
612
|
-
}
|
|
913
|
+
});
|
|
613
914
|
}
|
|
614
915
|
});
|
|
615
916
|
const accessibilityDescription = description || (!isEmpty ? generateBarChartDescription(title, data) : void 0);
|
|
616
|
-
return /* @__PURE__ */
|
|
917
|
+
return /* @__PURE__ */ jsx7(
|
|
617
918
|
ChartContainer,
|
|
618
919
|
{
|
|
619
920
|
ref,
|
|
@@ -625,8 +926,10 @@ var BarChart = React6.forwardRef(
|
|
|
625
926
|
empty: isEmpty,
|
|
626
927
|
emptyMessage,
|
|
627
928
|
className: cn(className),
|
|
929
|
+
legend: !isEmpty && renderLegend ? renderLegend(legend.renderProps) : void 0,
|
|
930
|
+
legendPosition: legendConfig?.position,
|
|
628
931
|
...props,
|
|
629
|
-
children: /* @__PURE__ */
|
|
932
|
+
children: /* @__PURE__ */ jsx7("div", { ref: containerRef, className: "h-full w-full" })
|
|
630
933
|
}
|
|
631
934
|
);
|
|
632
935
|
}
|
|
@@ -634,15 +937,27 @@ var BarChart = React6.forwardRef(
|
|
|
634
937
|
BarChart.displayName = "BarChart";
|
|
635
938
|
|
|
636
939
|
// src/components/core/PieChart.tsx
|
|
637
|
-
import * as
|
|
940
|
+
import * as React8 from "react";
|
|
638
941
|
import * as echarts5 from "echarts/core";
|
|
639
942
|
import { PieChart as EChartsPieChart } from "echarts/charts";
|
|
640
943
|
import { TooltipComponent as TooltipComponent3, LegendComponent as LegendComponent3, TitleComponent as TitleComponent3 } from "echarts/components";
|
|
641
944
|
import { CanvasRenderer as CanvasRenderer3 } from "echarts/renderers";
|
|
642
|
-
import {
|
|
643
|
-
|
|
945
|
+
import {
|
|
946
|
+
buildDataLabel as buildDataLabel3,
|
|
947
|
+
buildLegend as buildLegend3,
|
|
948
|
+
buildTooltip as buildTooltip3,
|
|
949
|
+
escapeHtml,
|
|
950
|
+
formatTooltipValue,
|
|
951
|
+
generatePieChartDescription,
|
|
952
|
+
getChartColors as getChartColors3,
|
|
953
|
+
itemLabelLookup,
|
|
954
|
+
legendCenter,
|
|
955
|
+
mergeChartOption as mergeChartOption3,
|
|
956
|
+
pointLabel
|
|
957
|
+
} from "@classic-homes/charts-core";
|
|
958
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
644
959
|
echarts5.use([EChartsPieChart, TooltipComponent3, LegendComponent3, TitleComponent3, CanvasRenderer3]);
|
|
645
|
-
var PieChart =
|
|
960
|
+
var PieChart = React8.forwardRef(
|
|
646
961
|
({
|
|
647
962
|
title,
|
|
648
963
|
description,
|
|
@@ -658,73 +973,123 @@ var PieChart = React7.forwardRef(
|
|
|
658
973
|
showLabels = true,
|
|
659
974
|
labelPosition = "outside",
|
|
660
975
|
innerRadius = 0,
|
|
976
|
+
labelFormatter,
|
|
977
|
+
tooltipFormatter,
|
|
978
|
+
tooltipValueFormatter,
|
|
979
|
+
legend: legendConfig,
|
|
980
|
+
renderLegend,
|
|
981
|
+
onLegendChange,
|
|
982
|
+
option: optionOverride,
|
|
661
983
|
onClick,
|
|
662
984
|
class: className,
|
|
663
985
|
...props
|
|
664
986
|
}, ref) => {
|
|
665
987
|
const isEmpty = !data?.length;
|
|
666
|
-
const
|
|
988
|
+
const currentTheme = useChartTheme(theme);
|
|
989
|
+
const legend = useChartLegend({
|
|
990
|
+
names: data?.map((d) => d.name) ?? [],
|
|
991
|
+
colors: data?.map((d) => d.color) ?? [],
|
|
992
|
+
palette: getChartColors3(currentTheme).series,
|
|
993
|
+
config: legendConfig,
|
|
994
|
+
title,
|
|
995
|
+
onLegendChange
|
|
996
|
+
});
|
|
997
|
+
const customLegend = renderLegend !== void 0;
|
|
998
|
+
const option = React8.useMemo(() => {
|
|
667
999
|
if (isEmpty) return {};
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
1000
|
+
const valueFormatter = tooltipFormatter === void 0 ? tooltipValueFormatter : void 0;
|
|
1001
|
+
const tooltipBase = {
|
|
1002
|
+
trigger: "item",
|
|
1003
|
+
formatter: valueFormatter ? (params) => {
|
|
1004
|
+
const p = params;
|
|
1005
|
+
return `${escapeHtml(p.seriesName)} <br/>${escapeHtml(p.name)}: ${escapeHtml(formatTooltipValue(p.value, valueFormatter))} (${p.percent}%)`;
|
|
1006
|
+
} : "{a} <br/>{b}: {c} ({d}%)"
|
|
1007
|
+
};
|
|
1008
|
+
return mergeChartOption3(
|
|
1009
|
+
{
|
|
1010
|
+
tooltip: buildTooltip3(tooltipBase, {
|
|
1011
|
+
show: showTooltip,
|
|
1012
|
+
formatter: tooltipFormatter,
|
|
1013
|
+
valueFormatter: tooltipValueFormatter,
|
|
1014
|
+
getLabel: itemLabelLookup(data)
|
|
1015
|
+
}),
|
|
1016
|
+
legend: buildLegend3(
|
|
1017
|
+
data.map((d) => d.name),
|
|
1018
|
+
legendConfig,
|
|
1019
|
+
{ show: showLegend, custom: customLegend, defaults: { orient: "horizontal" } }
|
|
1020
|
+
),
|
|
1021
|
+
series: [
|
|
1022
|
+
{
|
|
1023
|
+
name: title,
|
|
1024
|
+
type: "pie",
|
|
1025
|
+
radius: innerRadius ? [innerRadius, "70%"] : "70%",
|
|
1026
|
+
center: legendCenter(legendConfig, showLegend && !customLegend, ["50%", "45%"]),
|
|
1027
|
+
data: data.map((item) => ({
|
|
1028
|
+
name: item.name,
|
|
1029
|
+
value: item.value,
|
|
1030
|
+
itemStyle: item.color ? { color: item.color } : void 0,
|
|
1031
|
+
label: pointLabel(item.label, labelFormatter, { position: labelPosition })
|
|
1032
|
+
})),
|
|
1033
|
+
label: buildDataLabel3(
|
|
1034
|
+
{
|
|
1035
|
+
show: true,
|
|
1036
|
+
position: labelPosition,
|
|
1037
|
+
formatter: labelPosition === "inside" ? "{d}%" : "{b}: {d}%"
|
|
1038
|
+
},
|
|
1039
|
+
{ show: false },
|
|
1040
|
+
{ show: showLabels, formatter: labelFormatter, getLabel: itemLabelLookup(data) }
|
|
1041
|
+
),
|
|
1042
|
+
emphasis: {
|
|
1043
|
+
itemStyle: {
|
|
1044
|
+
shadowBlur: 10,
|
|
1045
|
+
shadowOffsetX: 0,
|
|
1046
|
+
shadowColor: "rgba(0, 0, 0, 0.5)"
|
|
1047
|
+
}
|
|
701
1048
|
}
|
|
702
1049
|
}
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
1050
|
+
]
|
|
1051
|
+
},
|
|
1052
|
+
optionOverride
|
|
1053
|
+
);
|
|
1054
|
+
}, [
|
|
1055
|
+
data,
|
|
1056
|
+
isEmpty,
|
|
1057
|
+
showTooltip,
|
|
1058
|
+
showLegend,
|
|
1059
|
+
showLabels,
|
|
1060
|
+
labelPosition,
|
|
1061
|
+
innerRadius,
|
|
1062
|
+
title,
|
|
1063
|
+
labelFormatter,
|
|
1064
|
+
tooltipFormatter,
|
|
1065
|
+
tooltipValueFormatter,
|
|
1066
|
+
legendConfig,
|
|
1067
|
+
customLegend,
|
|
1068
|
+
optionOverride
|
|
1069
|
+
]);
|
|
1070
|
+
const latest = useLatestRef({ onClick });
|
|
707
1071
|
const { containerRef } = useChart({
|
|
708
1072
|
option,
|
|
709
1073
|
theme,
|
|
710
1074
|
animation,
|
|
711
1075
|
onReady: (chart) => {
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
1076
|
+
legend.attach(chart);
|
|
1077
|
+
chart.on("click", (params) => {
|
|
1078
|
+
const { onClick: onClick2 } = latest.current;
|
|
1079
|
+
if (!onClick2) return;
|
|
1080
|
+
onClick2({
|
|
1081
|
+
type: params.type || "click",
|
|
1082
|
+
componentType: params.componentType || "series",
|
|
1083
|
+
name: params.name || "",
|
|
1084
|
+
value: params.value,
|
|
1085
|
+
percent: params.percent,
|
|
1086
|
+
color: params.color
|
|
722
1087
|
});
|
|
723
|
-
}
|
|
1088
|
+
});
|
|
724
1089
|
}
|
|
725
1090
|
});
|
|
726
1091
|
const accessibilityDescription = description || (!isEmpty ? generatePieChartDescription(title, data, false) : void 0);
|
|
727
|
-
return /* @__PURE__ */
|
|
1092
|
+
return /* @__PURE__ */ jsx8(
|
|
728
1093
|
ChartContainer,
|
|
729
1094
|
{
|
|
730
1095
|
ref,
|
|
@@ -736,8 +1101,10 @@ var PieChart = React7.forwardRef(
|
|
|
736
1101
|
empty: isEmpty,
|
|
737
1102
|
emptyMessage,
|
|
738
1103
|
className: cn(className),
|
|
1104
|
+
legend: !isEmpty && renderLegend ? renderLegend(legend.renderProps) : void 0,
|
|
1105
|
+
legendPosition: legendConfig?.position,
|
|
739
1106
|
...props,
|
|
740
|
-
children: /* @__PURE__ */
|
|
1107
|
+
children: /* @__PURE__ */ jsx8("div", { ref: containerRef, className: "h-full w-full" })
|
|
741
1108
|
}
|
|
742
1109
|
);
|
|
743
1110
|
}
|
|
@@ -745,7 +1112,7 @@ var PieChart = React7.forwardRef(
|
|
|
745
1112
|
PieChart.displayName = "PieChart";
|
|
746
1113
|
|
|
747
1114
|
// src/components/core/AreaChart.tsx
|
|
748
|
-
import * as
|
|
1115
|
+
import * as React9 from "react";
|
|
749
1116
|
import * as echarts6 from "echarts/core";
|
|
750
1117
|
import { LineChart as EChartsLineChart2 } from "echarts/charts";
|
|
751
1118
|
import {
|
|
@@ -755,7 +1122,21 @@ import {
|
|
|
755
1122
|
TitleComponent as TitleComponent4
|
|
756
1123
|
} from "echarts/components";
|
|
757
1124
|
import { CanvasRenderer as CanvasRenderer4 } from "echarts/renderers";
|
|
758
|
-
import {
|
|
1125
|
+
import {
|
|
1126
|
+
buildAxis as buildAxis3,
|
|
1127
|
+
buildDataLabel as buildDataLabel4,
|
|
1128
|
+
buildLegend as buildLegend4,
|
|
1129
|
+
buildTooltip as buildTooltip4,
|
|
1130
|
+
colorWithAlpha,
|
|
1131
|
+
getChartColors as getChartColors4,
|
|
1132
|
+
hasPointLabels as hasPointLabels2,
|
|
1133
|
+
gridInset as gridInset3,
|
|
1134
|
+
mergeChartOption as mergeChartOption4,
|
|
1135
|
+
seriesLabelLookup as seriesLabelLookup3,
|
|
1136
|
+
THEME_DARK as THEME_DARK3,
|
|
1137
|
+
withPointLabels as withPointLabels3
|
|
1138
|
+
} from "@classic-homes/charts-core";
|
|
1139
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
759
1140
|
echarts6.use([
|
|
760
1141
|
EChartsLineChart2,
|
|
761
1142
|
GridComponent3,
|
|
@@ -764,7 +1145,7 @@ echarts6.use([
|
|
|
764
1145
|
TitleComponent4,
|
|
765
1146
|
CanvasRenderer4
|
|
766
1147
|
]);
|
|
767
|
-
var AreaChart =
|
|
1148
|
+
var AreaChart = React9.forwardRef(
|
|
768
1149
|
({
|
|
769
1150
|
title,
|
|
770
1151
|
description,
|
|
@@ -781,94 +1162,161 @@ var AreaChart = React8.forwardRef(
|
|
|
781
1162
|
smooth = false,
|
|
782
1163
|
stacked = false,
|
|
783
1164
|
gradient = true,
|
|
1165
|
+
showLabels = false,
|
|
1166
|
+
labelFormatter,
|
|
1167
|
+
xAxisConfig,
|
|
1168
|
+
yAxisConfig,
|
|
1169
|
+
tooltipFormatter,
|
|
1170
|
+
tooltipValueFormatter,
|
|
1171
|
+
legend: legendConfig,
|
|
1172
|
+
renderLegend,
|
|
1173
|
+
onLegendChange,
|
|
1174
|
+
option: optionOverride,
|
|
784
1175
|
onClick,
|
|
785
1176
|
class: className,
|
|
786
1177
|
...props
|
|
787
1178
|
}, ref) => {
|
|
788
1179
|
const isEmpty = !data?.categories?.length || !data?.series?.length || data.series.every((s) => !s.data?.length);
|
|
789
|
-
const
|
|
1180
|
+
const currentTheme = useChartTheme(theme);
|
|
1181
|
+
const chartColors = getChartColors4(currentTheme);
|
|
1182
|
+
const legend = useChartLegend({
|
|
1183
|
+
names: data?.series?.map((s) => s.name) ?? [],
|
|
1184
|
+
colors: data?.series?.map((s) => s.color) ?? [],
|
|
1185
|
+
palette: chartColors.series,
|
|
1186
|
+
config: legendConfig,
|
|
1187
|
+
title,
|
|
1188
|
+
onLegendChange
|
|
1189
|
+
});
|
|
1190
|
+
const customLegend = renderLegend !== void 0;
|
|
1191
|
+
const option = React9.useMemo(() => {
|
|
790
1192
|
if (isEmpty) return {};
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
1193
|
+
const getLabel = seriesLabelLookup3(data.series);
|
|
1194
|
+
const showSymbol = showLabels || hasPointLabels2(data.series);
|
|
1195
|
+
return mergeChartOption4(
|
|
1196
|
+
{
|
|
1197
|
+
grid: {
|
|
1198
|
+
left: "3%",
|
|
1199
|
+
right: "4%",
|
|
1200
|
+
bottom: "3%",
|
|
1201
|
+
containLabel: true,
|
|
1202
|
+
...gridInset3(legendConfig, showLegend && !customLegend, xAxisConfig, yAxisConfig)
|
|
1203
|
+
},
|
|
1204
|
+
tooltip: buildTooltip4(
|
|
1205
|
+
{
|
|
1206
|
+
trigger: "axis",
|
|
1207
|
+
axisPointer: {
|
|
1208
|
+
type: "cross",
|
|
1209
|
+
label: {
|
|
1210
|
+
backgroundColor: chartColors.axisPointerLabel
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
},
|
|
1214
|
+
{
|
|
1215
|
+
show: showTooltip,
|
|
1216
|
+
formatter: tooltipFormatter,
|
|
1217
|
+
valueFormatter: tooltipValueFormatter,
|
|
1218
|
+
getLabel
|
|
804
1219
|
}
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
type: "line",
|
|
825
|
-
data: series.data,
|
|
826
|
-
smooth,
|
|
827
|
-
stack: stacked ? "Total" : void 0,
|
|
828
|
-
areaStyle: gradient ? {
|
|
829
|
-
opacity: 0.8,
|
|
830
|
-
color: new echarts6.graphic.LinearGradient(0, 0, 0, 1, [
|
|
831
|
-
{
|
|
832
|
-
offset: 0,
|
|
833
|
-
color: series.color || `rgba(${60 + index * 40}, ${160 - index * 20}, ${180 - index * 30}, 0.8)`
|
|
834
|
-
},
|
|
835
|
-
{
|
|
836
|
-
offset: 1,
|
|
837
|
-
color: series.color || `rgba(${60 + index * 40}, ${160 - index * 20}, ${180 - index * 30}, 0.1)`
|
|
1220
|
+
),
|
|
1221
|
+
legend: buildLegend4(
|
|
1222
|
+
data.series.map((s) => s.name),
|
|
1223
|
+
legendConfig,
|
|
1224
|
+
{ show: showLegend, custom: customLegend }
|
|
1225
|
+
),
|
|
1226
|
+
xAxis: buildAxis3(
|
|
1227
|
+
{
|
|
1228
|
+
type: "category",
|
|
1229
|
+
boundaryGap: false,
|
|
1230
|
+
data: data.categories
|
|
1231
|
+
},
|
|
1232
|
+
xAxisConfig
|
|
1233
|
+
),
|
|
1234
|
+
yAxis: buildAxis3(
|
|
1235
|
+
{
|
|
1236
|
+
type: "value",
|
|
1237
|
+
splitLine: {
|
|
1238
|
+
show: showGrid
|
|
838
1239
|
}
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
1240
|
+
},
|
|
1241
|
+
yAxisConfig
|
|
1242
|
+
),
|
|
1243
|
+
series: data.series.map((series, index) => {
|
|
1244
|
+
const base = series.color || chartColors.series[index % chartColors.series.length];
|
|
1245
|
+
return {
|
|
1246
|
+
name: series.name,
|
|
1247
|
+
type: "line",
|
|
1248
|
+
data: withPointLabels3(series.data, series.labels, labelFormatter, {
|
|
1249
|
+
position: "top"
|
|
1250
|
+
}),
|
|
1251
|
+
smooth,
|
|
1252
|
+
stack: stacked ? "Total" : void 0,
|
|
1253
|
+
areaStyle: gradient ? {
|
|
1254
|
+
opacity: 0.8,
|
|
1255
|
+
color: new echarts6.graphic.LinearGradient(0, 0, 0, 1, [
|
|
1256
|
+
{ offset: 0, color: colorWithAlpha(base, 0.8) },
|
|
1257
|
+
{ offset: 1, color: colorWithAlpha(base, 0.1) }
|
|
1258
|
+
])
|
|
1259
|
+
} : { opacity: 0.5 },
|
|
1260
|
+
itemStyle: series.color ? { color: series.color } : void 0,
|
|
1261
|
+
label: buildDataLabel4({ show: true, position: "top" }, void 0, {
|
|
1262
|
+
show: showLabels,
|
|
1263
|
+
formatter: labelFormatter,
|
|
1264
|
+
getLabel
|
|
1265
|
+
}),
|
|
1266
|
+
emphasis: {
|
|
1267
|
+
focus: "series"
|
|
1268
|
+
},
|
|
1269
|
+
showSymbol
|
|
1270
|
+
};
|
|
1271
|
+
})
|
|
1272
|
+
},
|
|
1273
|
+
optionOverride
|
|
1274
|
+
);
|
|
1275
|
+
}, [
|
|
1276
|
+
data,
|
|
1277
|
+
isEmpty,
|
|
1278
|
+
showTooltip,
|
|
1279
|
+
showLegend,
|
|
1280
|
+
showGrid,
|
|
1281
|
+
smooth,
|
|
1282
|
+
stacked,
|
|
1283
|
+
gradient,
|
|
1284
|
+
chartColors,
|
|
1285
|
+
showLabels,
|
|
1286
|
+
labelFormatter,
|
|
1287
|
+
xAxisConfig,
|
|
1288
|
+
yAxisConfig,
|
|
1289
|
+
tooltipFormatter,
|
|
1290
|
+
tooltipValueFormatter,
|
|
1291
|
+
legendConfig,
|
|
1292
|
+
customLegend,
|
|
1293
|
+
optionOverride
|
|
1294
|
+
]);
|
|
1295
|
+
const latest = useLatestRef({ onClick });
|
|
849
1296
|
const { containerRef } = useChart({
|
|
850
1297
|
option,
|
|
851
|
-
theme,
|
|
1298
|
+
theme: currentTheme === THEME_DARK3 ? "dark" : "light",
|
|
852
1299
|
animation,
|
|
853
1300
|
onReady: (chart) => {
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
1301
|
+
legend.attach(chart);
|
|
1302
|
+
chart.on("click", (params) => {
|
|
1303
|
+
const { onClick: onClick2 } = latest.current;
|
|
1304
|
+
if (!onClick2) return;
|
|
1305
|
+
onClick2({
|
|
1306
|
+
type: params.type || "click",
|
|
1307
|
+
componentType: params.componentType || "series",
|
|
1308
|
+
seriesIndex: params.seriesIndex,
|
|
1309
|
+
seriesName: params.seriesName || "",
|
|
1310
|
+
dataIndex: params.dataIndex || 0,
|
|
1311
|
+
name: params.name || "",
|
|
1312
|
+
value: params.value,
|
|
1313
|
+
color: params.color
|
|
866
1314
|
});
|
|
867
|
-
}
|
|
1315
|
+
});
|
|
868
1316
|
}
|
|
869
1317
|
});
|
|
870
1318
|
const accessibilityDescription = description || (!isEmpty ? `${title}. Area chart with ${data.categories.length} data points across ${data.series.length} series.` : void 0);
|
|
871
|
-
return /* @__PURE__ */
|
|
1319
|
+
return /* @__PURE__ */ jsx9(
|
|
872
1320
|
ChartContainer,
|
|
873
1321
|
{
|
|
874
1322
|
ref,
|
|
@@ -880,8 +1328,10 @@ var AreaChart = React8.forwardRef(
|
|
|
880
1328
|
empty: isEmpty,
|
|
881
1329
|
emptyMessage,
|
|
882
1330
|
className: cn(className),
|
|
1331
|
+
legend: !isEmpty && renderLegend ? renderLegend(legend.renderProps) : void 0,
|
|
1332
|
+
legendPosition: legendConfig?.position,
|
|
883
1333
|
...props,
|
|
884
|
-
children: /* @__PURE__ */
|
|
1334
|
+
children: /* @__PURE__ */ jsx9("div", { ref: containerRef, className: "h-full w-full" })
|
|
885
1335
|
}
|
|
886
1336
|
);
|
|
887
1337
|
}
|
|
@@ -889,9 +1339,9 @@ var AreaChart = React8.forwardRef(
|
|
|
889
1339
|
AreaChart.displayName = "AreaChart";
|
|
890
1340
|
|
|
891
1341
|
// src/components/core/ScatterChart.tsx
|
|
892
|
-
import * as
|
|
1342
|
+
import * as React10 from "react";
|
|
893
1343
|
import * as echarts7 from "echarts/core";
|
|
894
|
-
import { ScatterChart as EChartsScatterChart } from "echarts/charts";
|
|
1344
|
+
import { ScatterChart as EChartsScatterChart, LineChart as EChartsLineChart3 } from "echarts/charts";
|
|
895
1345
|
import {
|
|
896
1346
|
GridComponent as GridComponent4,
|
|
897
1347
|
TooltipComponent as TooltipComponent5,
|
|
@@ -899,17 +1349,32 @@ import {
|
|
|
899
1349
|
TitleComponent as TitleComponent5
|
|
900
1350
|
} from "echarts/components";
|
|
901
1351
|
import { CanvasRenderer as CanvasRenderer5 } from "echarts/renderers";
|
|
902
|
-
import {
|
|
903
|
-
|
|
1352
|
+
import {
|
|
1353
|
+
buildAxis as buildAxis4,
|
|
1354
|
+
buildDataLabel as buildDataLabel5,
|
|
1355
|
+
buildLegend as buildLegend5,
|
|
1356
|
+
buildTooltip as buildTooltip5,
|
|
1357
|
+
escapeHtml as escapeHtml2,
|
|
1358
|
+
formatTooltipValue as formatTooltipValue2,
|
|
1359
|
+
generateScatterChartDescription,
|
|
1360
|
+
getChartColors as getChartColors5,
|
|
1361
|
+
gridInset as gridInset4,
|
|
1362
|
+
mergeChartOption as mergeChartOption5,
|
|
1363
|
+
seriesLabelLookup as seriesLabelLookup4,
|
|
1364
|
+
withPointLabels as withPointLabels4
|
|
1365
|
+
} from "@classic-homes/charts-core";
|
|
1366
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
904
1367
|
echarts7.use([
|
|
905
1368
|
EChartsScatterChart,
|
|
1369
|
+
// Trend lines are line series
|
|
1370
|
+
EChartsLineChart3,
|
|
906
1371
|
GridComponent4,
|
|
907
1372
|
TooltipComponent5,
|
|
908
1373
|
LegendComponent5,
|
|
909
1374
|
TitleComponent5,
|
|
910
1375
|
CanvasRenderer5
|
|
911
1376
|
]);
|
|
912
|
-
var ScatterChart =
|
|
1377
|
+
var ScatterChart = React10.forwardRef(
|
|
913
1378
|
({
|
|
914
1379
|
title,
|
|
915
1380
|
description,
|
|
@@ -925,19 +1390,45 @@ var ScatterChart = React9.forwardRef(
|
|
|
925
1390
|
showGrid = true,
|
|
926
1391
|
showTrendLine = false,
|
|
927
1392
|
symbolSize = 10,
|
|
1393
|
+
showLabels = false,
|
|
1394
|
+
labelFormatter,
|
|
1395
|
+
xAxisConfig,
|
|
1396
|
+
yAxisConfig,
|
|
1397
|
+
tooltipFormatter,
|
|
1398
|
+
tooltipValueFormatter,
|
|
1399
|
+
legend: legendConfig,
|
|
1400
|
+
renderLegend,
|
|
1401
|
+
onLegendChange,
|
|
1402
|
+
option: optionOverride,
|
|
928
1403
|
onClick,
|
|
929
1404
|
class: className,
|
|
930
1405
|
...props
|
|
931
1406
|
}, ref) => {
|
|
932
1407
|
const isEmpty = !data?.series?.length || data.series.every((s) => !s.data?.length);
|
|
933
|
-
const
|
|
1408
|
+
const currentTheme = useChartTheme(theme);
|
|
1409
|
+
const legend = useChartLegend({
|
|
1410
|
+
names: data?.series?.map((s) => s.name) ?? [],
|
|
1411
|
+
colors: data?.series?.map((s) => s.color) ?? [],
|
|
1412
|
+
palette: getChartColors5(currentTheme).series,
|
|
1413
|
+
config: legendConfig,
|
|
1414
|
+
title,
|
|
1415
|
+
onLegendChange
|
|
1416
|
+
});
|
|
1417
|
+
const customLegend = renderLegend !== void 0;
|
|
1418
|
+
const option = React10.useMemo(() => {
|
|
934
1419
|
if (isEmpty) return {};
|
|
1420
|
+
const getLabel = seriesLabelLookup4(data.series);
|
|
935
1421
|
const series = data.series.map((s) => ({
|
|
936
1422
|
name: s.name,
|
|
937
1423
|
type: "scatter",
|
|
938
|
-
data: s.data,
|
|
1424
|
+
data: withPointLabels4(s.data, s.labels, labelFormatter, { position: "top" }),
|
|
939
1425
|
symbolSize: typeof symbolSize === "function" ? symbolSize : symbolSize,
|
|
940
1426
|
itemStyle: s.color ? { color: s.color } : void 0,
|
|
1427
|
+
label: buildDataLabel5({ show: true, position: "top" }, void 0, {
|
|
1428
|
+
show: showLabels,
|
|
1429
|
+
formatter: labelFormatter,
|
|
1430
|
+
getLabel
|
|
1431
|
+
}),
|
|
941
1432
|
emphasis: {
|
|
942
1433
|
focus: "series",
|
|
943
1434
|
itemStyle: {
|
|
@@ -959,9 +1450,12 @@ var ScatterChart = React9.forwardRef(
|
|
|
959
1450
|
});
|
|
960
1451
|
const slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);
|
|
961
1452
|
const intercept = (sumY - slope * sumX) / n;
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
const
|
|
1453
|
+
let minX = Infinity;
|
|
1454
|
+
let maxX = -Infinity;
|
|
1455
|
+
for (const [x] of s.data) {
|
|
1456
|
+
if (x < minX) minX = x;
|
|
1457
|
+
if (x > maxX) maxX = x;
|
|
1458
|
+
}
|
|
965
1459
|
series.push({
|
|
966
1460
|
name: `${s.name} Trend`,
|
|
967
1461
|
type: "line",
|
|
@@ -982,63 +1476,103 @@ var ScatterChart = React9.forwardRef(
|
|
|
982
1476
|
});
|
|
983
1477
|
});
|
|
984
1478
|
}
|
|
985
|
-
return
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1479
|
+
return mergeChartOption5(
|
|
1480
|
+
{
|
|
1481
|
+
grid: {
|
|
1482
|
+
left: "3%",
|
|
1483
|
+
right: "4%",
|
|
1484
|
+
bottom: "3%",
|
|
1485
|
+
containLabel: true,
|
|
1486
|
+
...gridInset4(legendConfig, showLegend && !customLegend, xAxisConfig, yAxisConfig)
|
|
1487
|
+
},
|
|
1488
|
+
tooltip: buildTooltip5(
|
|
1489
|
+
{
|
|
1490
|
+
trigger: "item",
|
|
1491
|
+
formatter: (params) => {
|
|
1492
|
+
const p = params;
|
|
1493
|
+
if (!p.value) return "";
|
|
1494
|
+
const x = formatTooltipValue2(p.value[0], tooltipValueFormatter);
|
|
1495
|
+
const y = formatTooltipValue2(p.value[1], tooltipValueFormatter);
|
|
1496
|
+
return `${escapeHtml2(p.seriesName)}<br/>X: ${escapeHtml2(x)}<br/>Y: ${escapeHtml2(y)}`;
|
|
1497
|
+
}
|
|
1498
|
+
},
|
|
1499
|
+
{
|
|
1500
|
+
show: showTooltip,
|
|
1501
|
+
formatter: tooltipFormatter,
|
|
1502
|
+
valueFormatter: tooltipValueFormatter,
|
|
1503
|
+
getLabel
|
|
1504
|
+
}
|
|
1505
|
+
),
|
|
1506
|
+
legend: buildLegend5(
|
|
1507
|
+
data.series.map((s) => s.name),
|
|
1508
|
+
legendConfig,
|
|
1509
|
+
{ show: showLegend, custom: customLegend }
|
|
1510
|
+
),
|
|
1511
|
+
xAxis: buildAxis4(
|
|
1512
|
+
{
|
|
1513
|
+
type: "value",
|
|
1514
|
+
splitLine: {
|
|
1515
|
+
show: showGrid
|
|
1516
|
+
}
|
|
1517
|
+
},
|
|
1518
|
+
xAxisConfig
|
|
1519
|
+
),
|
|
1520
|
+
yAxis: buildAxis4(
|
|
1521
|
+
{
|
|
1522
|
+
type: "value",
|
|
1523
|
+
splitLine: {
|
|
1524
|
+
show: showGrid
|
|
1525
|
+
}
|
|
1526
|
+
},
|
|
1527
|
+
yAxisConfig
|
|
1528
|
+
),
|
|
1529
|
+
series
|
|
1530
|
+
},
|
|
1531
|
+
optionOverride
|
|
1532
|
+
);
|
|
1533
|
+
}, [
|
|
1534
|
+
data,
|
|
1535
|
+
isEmpty,
|
|
1536
|
+
showTooltip,
|
|
1537
|
+
showLegend,
|
|
1538
|
+
showGrid,
|
|
1539
|
+
showTrendLine,
|
|
1540
|
+
symbolSize,
|
|
1541
|
+
showLabels,
|
|
1542
|
+
labelFormatter,
|
|
1543
|
+
xAxisConfig,
|
|
1544
|
+
yAxisConfig,
|
|
1545
|
+
tooltipFormatter,
|
|
1546
|
+
tooltipValueFormatter,
|
|
1547
|
+
legendConfig,
|
|
1548
|
+
customLegend,
|
|
1549
|
+
optionOverride
|
|
1550
|
+
]);
|
|
1551
|
+
const latest = useLatestRef({ onClick });
|
|
1552
|
+
const { containerRef } = useChart({
|
|
1553
|
+
option,
|
|
1554
|
+
theme,
|
|
1555
|
+
animation,
|
|
1023
1556
|
onReady: (chart) => {
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1557
|
+
legend.attach(chart);
|
|
1558
|
+
chart.on("click", (params) => {
|
|
1559
|
+
const { onClick: onClick2 } = latest.current;
|
|
1560
|
+
if (!onClick2) return;
|
|
1561
|
+
onClick2({
|
|
1562
|
+
type: params.type || "click",
|
|
1563
|
+
componentType: params.componentType || "series",
|
|
1564
|
+
seriesIndex: params.seriesIndex,
|
|
1565
|
+
seriesName: params.seriesName || "",
|
|
1566
|
+
dataIndex: params.dataIndex || 0,
|
|
1567
|
+
name: params.name || "",
|
|
1568
|
+
value: params.value,
|
|
1569
|
+
color: params.color
|
|
1036
1570
|
});
|
|
1037
|
-
}
|
|
1571
|
+
});
|
|
1038
1572
|
}
|
|
1039
1573
|
});
|
|
1040
1574
|
const accessibilityDescription = description || (!isEmpty ? generateScatterChartDescription(title, data) : void 0);
|
|
1041
|
-
return /* @__PURE__ */
|
|
1575
|
+
return /* @__PURE__ */ jsx10(
|
|
1042
1576
|
ChartContainer,
|
|
1043
1577
|
{
|
|
1044
1578
|
ref,
|
|
@@ -1050,8 +1584,10 @@ var ScatterChart = React9.forwardRef(
|
|
|
1050
1584
|
empty: isEmpty,
|
|
1051
1585
|
emptyMessage,
|
|
1052
1586
|
className: cn(className),
|
|
1587
|
+
legend: !isEmpty && renderLegend ? renderLegend(legend.renderProps) : void 0,
|
|
1588
|
+
legendPosition: legendConfig?.position,
|
|
1053
1589
|
...props,
|
|
1054
|
-
children: /* @__PURE__ */
|
|
1590
|
+
children: /* @__PURE__ */ jsx10("div", { ref: containerRef, className: "h-full w-full" })
|
|
1055
1591
|
}
|
|
1056
1592
|
);
|
|
1057
1593
|
}
|
|
@@ -1059,15 +1595,29 @@ var ScatterChart = React9.forwardRef(
|
|
|
1059
1595
|
ScatterChart.displayName = "ScatterChart";
|
|
1060
1596
|
|
|
1061
1597
|
// src/components/core/DonutChart.tsx
|
|
1062
|
-
import * as
|
|
1598
|
+
import * as React11 from "react";
|
|
1063
1599
|
import * as echarts8 from "echarts/core";
|
|
1064
1600
|
import { PieChart as EChartsPieChart2 } from "echarts/charts";
|
|
1065
1601
|
import { TooltipComponent as TooltipComponent6, LegendComponent as LegendComponent6, TitleComponent as TitleComponent6 } from "echarts/components";
|
|
1066
1602
|
import { CanvasRenderer as CanvasRenderer6 } from "echarts/renderers";
|
|
1067
|
-
import {
|
|
1068
|
-
|
|
1603
|
+
import {
|
|
1604
|
+
buildDataLabel as buildDataLabel6,
|
|
1605
|
+
buildLegend as buildLegend6,
|
|
1606
|
+
buildTooltip as buildTooltip6,
|
|
1607
|
+
escapeHtml as escapeHtml3,
|
|
1608
|
+
formatTooltipValue as formatTooltipValue3,
|
|
1609
|
+
generatePieChartDescription as generatePieChartDescription2,
|
|
1610
|
+
getChartColors as getChartColors6,
|
|
1611
|
+
itemLabelLookup as itemLabelLookup2,
|
|
1612
|
+
anchorCenterGraphic,
|
|
1613
|
+
legendCenter as legendCenter2,
|
|
1614
|
+
mergeChartOption as mergeChartOption6,
|
|
1615
|
+
pointLabel as pointLabel2,
|
|
1616
|
+
THEME_DARK as THEME_DARK4
|
|
1617
|
+
} from "@classic-homes/charts-core";
|
|
1618
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
1069
1619
|
echarts8.use([EChartsPieChart2, TooltipComponent6, LegendComponent6, TitleComponent6, CanvasRenderer6]);
|
|
1070
|
-
var DonutChart =
|
|
1620
|
+
var DonutChart = React11.forwardRef(
|
|
1071
1621
|
({
|
|
1072
1622
|
title,
|
|
1073
1623
|
description,
|
|
@@ -1085,93 +1635,134 @@ var DonutChart = React10.forwardRef(
|
|
|
1085
1635
|
innerRadius = "50%",
|
|
1086
1636
|
centerLabel,
|
|
1087
1637
|
centerValue,
|
|
1638
|
+
labelFormatter,
|
|
1639
|
+
tooltipFormatter,
|
|
1640
|
+
tooltipValueFormatter,
|
|
1641
|
+
legend: legendConfig,
|
|
1642
|
+
renderLegend,
|
|
1643
|
+
onLegendChange,
|
|
1644
|
+
option: optionOverride,
|
|
1088
1645
|
onClick,
|
|
1089
1646
|
class: className,
|
|
1090
1647
|
...props
|
|
1091
1648
|
}, ref) => {
|
|
1092
1649
|
const isEmpty = !data?.length;
|
|
1093
|
-
const
|
|
1650
|
+
const currentTheme = useChartTheme(theme);
|
|
1651
|
+
const chartColors = getChartColors6(currentTheme);
|
|
1652
|
+
const legend = useChartLegend({
|
|
1653
|
+
names: data?.map((d) => d.name) ?? [],
|
|
1654
|
+
colors: data?.map((d) => d.color) ?? [],
|
|
1655
|
+
palette: chartColors.series,
|
|
1656
|
+
config: legendConfig,
|
|
1657
|
+
title,
|
|
1658
|
+
onLegendChange
|
|
1659
|
+
});
|
|
1660
|
+
const customLegend = renderLegend !== void 0;
|
|
1661
|
+
const option = React11.useMemo(() => {
|
|
1094
1662
|
if (isEmpty) return {};
|
|
1663
|
+
const pieCenter = legendCenter2(legendConfig, showLegend && !customLegend, ["50%", "45%"]);
|
|
1095
1664
|
const graphicElements = [];
|
|
1096
1665
|
if (centerLabel || centerValue) {
|
|
1097
|
-
graphicElements.push(
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
return {
|
|
1133
|
-
tooltip: showTooltip ? {
|
|
1134
|
-
trigger: "item",
|
|
1135
|
-
formatter: "{a} <br/>{b}: {c} ({d}%)"
|
|
1136
|
-
} : void 0,
|
|
1137
|
-
legend: showLegend ? {
|
|
1138
|
-
orient: "horizontal",
|
|
1139
|
-
bottom: 0,
|
|
1140
|
-
data: data.map((d) => d.name)
|
|
1141
|
-
} : void 0,
|
|
1142
|
-
graphic: graphicElements.length > 0 ? graphicElements : void 0,
|
|
1143
|
-
series: [
|
|
1144
|
-
{
|
|
1145
|
-
name: title,
|
|
1146
|
-
type: "pie",
|
|
1147
|
-
radius: [innerRadius, "70%"],
|
|
1148
|
-
center: ["50%", "45%"],
|
|
1149
|
-
avoidLabelOverlap: true,
|
|
1150
|
-
data: data.map((item) => ({
|
|
1151
|
-
name: item.name,
|
|
1152
|
-
value: item.value,
|
|
1153
|
-
itemStyle: item.color ? { color: item.color } : void 0
|
|
1154
|
-
})),
|
|
1155
|
-
label: showLabels ? {
|
|
1156
|
-
show: true,
|
|
1157
|
-
position: labelPosition,
|
|
1158
|
-
formatter: labelPosition === "inside" ? "{d}%" : "{b}: {d}%"
|
|
1159
|
-
} : {
|
|
1160
|
-
show: false
|
|
1161
|
-
},
|
|
1162
|
-
labelLine: {
|
|
1163
|
-
show: showLabels && labelPosition === "outside"
|
|
1666
|
+
graphicElements.push(
|
|
1667
|
+
anchorCenterGraphic(
|
|
1668
|
+
{
|
|
1669
|
+
type: "group",
|
|
1670
|
+
left: "center",
|
|
1671
|
+
top: "40%",
|
|
1672
|
+
children: [
|
|
1673
|
+
...centerValue !== void 0 ? [
|
|
1674
|
+
{
|
|
1675
|
+
type: "text",
|
|
1676
|
+
style: {
|
|
1677
|
+
text: String(centerValue),
|
|
1678
|
+
fontSize: 28,
|
|
1679
|
+
fontWeight: "bold",
|
|
1680
|
+
fill: chartColors.foreground,
|
|
1681
|
+
textAlign: "center"
|
|
1682
|
+
},
|
|
1683
|
+
top: 0,
|
|
1684
|
+
left: "center"
|
|
1685
|
+
}
|
|
1686
|
+
] : [],
|
|
1687
|
+
...centerLabel ? [
|
|
1688
|
+
{
|
|
1689
|
+
type: "text",
|
|
1690
|
+
style: {
|
|
1691
|
+
text: centerLabel,
|
|
1692
|
+
fontSize: 14,
|
|
1693
|
+
fill: chartColors.mutedForeground,
|
|
1694
|
+
textAlign: "center"
|
|
1695
|
+
},
|
|
1696
|
+
top: centerValue !== void 0 ? 35 : 0,
|
|
1697
|
+
left: "center"
|
|
1698
|
+
}
|
|
1699
|
+
] : []
|
|
1700
|
+
]
|
|
1164
1701
|
},
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1702
|
+
pieCenter,
|
|
1703
|
+
["50%", "45%"]
|
|
1704
|
+
)
|
|
1705
|
+
);
|
|
1706
|
+
}
|
|
1707
|
+
const valueFormatter = tooltipFormatter === void 0 ? tooltipValueFormatter : void 0;
|
|
1708
|
+
const tooltipBase = {
|
|
1709
|
+
trigger: "item",
|
|
1710
|
+
formatter: valueFormatter ? (params) => {
|
|
1711
|
+
const p = params;
|
|
1712
|
+
return `${escapeHtml3(p.seriesName)} <br/>${escapeHtml3(p.name)}: ${escapeHtml3(formatTooltipValue3(p.value, valueFormatter))} (${p.percent}%)`;
|
|
1713
|
+
} : "{a} <br/>{b}: {c} ({d}%)"
|
|
1714
|
+
};
|
|
1715
|
+
return mergeChartOption6(
|
|
1716
|
+
{
|
|
1717
|
+
tooltip: buildTooltip6(tooltipBase, {
|
|
1718
|
+
show: showTooltip,
|
|
1719
|
+
formatter: tooltipFormatter,
|
|
1720
|
+
valueFormatter: tooltipValueFormatter,
|
|
1721
|
+
getLabel: itemLabelLookup2(data)
|
|
1722
|
+
}),
|
|
1723
|
+
legend: buildLegend6(
|
|
1724
|
+
data.map((d) => d.name),
|
|
1725
|
+
legendConfig,
|
|
1726
|
+
{ show: showLegend, custom: customLegend, defaults: { orient: "horizontal" } }
|
|
1727
|
+
),
|
|
1728
|
+
graphic: graphicElements.length > 0 ? graphicElements : void 0,
|
|
1729
|
+
series: [
|
|
1730
|
+
{
|
|
1731
|
+
name: title,
|
|
1732
|
+
type: "pie",
|
|
1733
|
+
radius: [innerRadius, "70%"],
|
|
1734
|
+
center: pieCenter,
|
|
1735
|
+
avoidLabelOverlap: true,
|
|
1736
|
+
data: data.map((item) => ({
|
|
1737
|
+
name: item.name,
|
|
1738
|
+
value: item.value,
|
|
1739
|
+
itemStyle: item.color ? { color: item.color } : void 0,
|
|
1740
|
+
label: pointLabel2(item.label, labelFormatter, { position: labelPosition })
|
|
1741
|
+
})),
|
|
1742
|
+
label: buildDataLabel6(
|
|
1743
|
+
{
|
|
1744
|
+
show: true,
|
|
1745
|
+
position: labelPosition,
|
|
1746
|
+
formatter: labelPosition === "inside" ? "{d}%" : "{b}: {d}%"
|
|
1747
|
+
},
|
|
1748
|
+
{ show: false },
|
|
1749
|
+
{ show: showLabels, formatter: labelFormatter, getLabel: itemLabelLookup2(data) }
|
|
1750
|
+
),
|
|
1751
|
+
labelLine: {
|
|
1752
|
+
show: showLabels && labelPosition === "outside"
|
|
1753
|
+
},
|
|
1754
|
+
emphasis: {
|
|
1755
|
+
itemStyle: {
|
|
1756
|
+
shadowBlur: 10,
|
|
1757
|
+
shadowOffsetX: 0,
|
|
1758
|
+
shadowColor: "rgba(0, 0, 0, 0.5)"
|
|
1759
|
+
}
|
|
1170
1760
|
}
|
|
1171
1761
|
}
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1762
|
+
]
|
|
1763
|
+
},
|
|
1764
|
+
optionOverride
|
|
1765
|
+
);
|
|
1175
1766
|
}, [
|
|
1176
1767
|
data,
|
|
1177
1768
|
isEmpty,
|
|
@@ -1182,29 +1773,38 @@ var DonutChart = React10.forwardRef(
|
|
|
1182
1773
|
innerRadius,
|
|
1183
1774
|
centerLabel,
|
|
1184
1775
|
centerValue,
|
|
1185
|
-
title
|
|
1776
|
+
title,
|
|
1777
|
+
chartColors,
|
|
1778
|
+
labelFormatter,
|
|
1779
|
+
tooltipFormatter,
|
|
1780
|
+
tooltipValueFormatter,
|
|
1781
|
+
legendConfig,
|
|
1782
|
+
customLegend,
|
|
1783
|
+
optionOverride
|
|
1186
1784
|
]);
|
|
1785
|
+
const latest = useLatestRef({ onClick });
|
|
1187
1786
|
const { containerRef } = useChart({
|
|
1188
1787
|
option,
|
|
1189
|
-
theme,
|
|
1788
|
+
theme: currentTheme === THEME_DARK4 ? "dark" : "light",
|
|
1190
1789
|
animation,
|
|
1191
1790
|
onReady: (chart) => {
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1791
|
+
legend.attach(chart);
|
|
1792
|
+
chart.on("click", (params) => {
|
|
1793
|
+
const { onClick: onClick2 } = latest.current;
|
|
1794
|
+
if (!onClick2) return;
|
|
1795
|
+
onClick2({
|
|
1796
|
+
type: params.type || "click",
|
|
1797
|
+
componentType: params.componentType || "series",
|
|
1798
|
+
name: params.name || "",
|
|
1799
|
+
value: params.value,
|
|
1800
|
+
percent: params.percent,
|
|
1801
|
+
color: params.color
|
|
1202
1802
|
});
|
|
1203
|
-
}
|
|
1803
|
+
});
|
|
1204
1804
|
}
|
|
1205
1805
|
});
|
|
1206
1806
|
const accessibilityDescription = description || (!isEmpty ? generatePieChartDescription2(title, data, true) : void 0);
|
|
1207
|
-
return /* @__PURE__ */
|
|
1807
|
+
return /* @__PURE__ */ jsx11(
|
|
1208
1808
|
ChartContainer,
|
|
1209
1809
|
{
|
|
1210
1810
|
ref,
|
|
@@ -1216,8 +1816,10 @@ var DonutChart = React10.forwardRef(
|
|
|
1216
1816
|
empty: isEmpty,
|
|
1217
1817
|
emptyMessage,
|
|
1218
1818
|
className: cn(className),
|
|
1819
|
+
legend: !isEmpty && renderLegend ? renderLegend(legend.renderProps) : void 0,
|
|
1820
|
+
legendPosition: legendConfig?.position,
|
|
1219
1821
|
...props,
|
|
1220
|
-
children: /* @__PURE__ */
|
|
1822
|
+
children: /* @__PURE__ */ jsx11("div", { ref: containerRef, className: "h-full w-full" })
|
|
1221
1823
|
}
|
|
1222
1824
|
);
|
|
1223
1825
|
}
|
|
@@ -1225,7 +1827,7 @@ var DonutChart = React10.forwardRef(
|
|
|
1225
1827
|
DonutChart.displayName = "DonutChart";
|
|
1226
1828
|
|
|
1227
1829
|
// src/components/extended/RadarChart.tsx
|
|
1228
|
-
import * as
|
|
1830
|
+
import * as React12 from "react";
|
|
1229
1831
|
import * as echarts9 from "echarts/core";
|
|
1230
1832
|
import { RadarChart as EChartsRadarChart } from "echarts/charts";
|
|
1231
1833
|
import {
|
|
@@ -1235,7 +1837,15 @@ import {
|
|
|
1235
1837
|
RadarComponent
|
|
1236
1838
|
} from "echarts/components";
|
|
1237
1839
|
import { CanvasRenderer as CanvasRenderer7 } from "echarts/renderers";
|
|
1238
|
-
import {
|
|
1840
|
+
import {
|
|
1841
|
+
buildDataLabel as buildDataLabel7,
|
|
1842
|
+
buildLegend as buildLegend7,
|
|
1843
|
+
buildTooltip as buildTooltip7,
|
|
1844
|
+
getChartColors as getChartColors7,
|
|
1845
|
+
legendCenter as legendCenter3,
|
|
1846
|
+
mergeChartOption as mergeChartOption7
|
|
1847
|
+
} from "@classic-homes/charts-core";
|
|
1848
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
1239
1849
|
echarts9.use([
|
|
1240
1850
|
EChartsRadarChart,
|
|
1241
1851
|
TooltipComponent7,
|
|
@@ -1244,7 +1854,7 @@ echarts9.use([
|
|
|
1244
1854
|
RadarComponent,
|
|
1245
1855
|
CanvasRenderer7
|
|
1246
1856
|
]);
|
|
1247
|
-
var RadarChart =
|
|
1857
|
+
var RadarChart = React12.forwardRef(
|
|
1248
1858
|
({
|
|
1249
1859
|
title,
|
|
1250
1860
|
description,
|
|
@@ -1259,50 +1869,101 @@ var RadarChart = React11.forwardRef(
|
|
|
1259
1869
|
showLegend = true,
|
|
1260
1870
|
showTooltip = true,
|
|
1261
1871
|
shape = "polygon",
|
|
1872
|
+
showLabels = false,
|
|
1873
|
+
labelFormatter,
|
|
1874
|
+
tooltipFormatter,
|
|
1875
|
+
tooltipValueFormatter,
|
|
1876
|
+
legend: legendConfig,
|
|
1877
|
+
renderLegend,
|
|
1878
|
+
onLegendChange,
|
|
1879
|
+
option: optionOverride,
|
|
1262
1880
|
class: className,
|
|
1263
1881
|
...props
|
|
1264
1882
|
}, ref) => {
|
|
1265
1883
|
const isEmpty = !data?.series?.length || !indicators?.length || data.series.every((s) => !s.data?.length);
|
|
1266
|
-
const
|
|
1884
|
+
const currentTheme = useChartTheme(theme);
|
|
1885
|
+
const legend = useChartLegend({
|
|
1886
|
+
names: data?.series?.map((s) => s.name) ?? [],
|
|
1887
|
+
colors: data?.series?.map((s) => s.color) ?? [],
|
|
1888
|
+
palette: getChartColors7(currentTheme).series,
|
|
1889
|
+
config: legendConfig,
|
|
1890
|
+
title,
|
|
1891
|
+
onLegendChange
|
|
1892
|
+
});
|
|
1893
|
+
const customLegend = renderLegend !== void 0;
|
|
1894
|
+
const option = React12.useMemo(() => {
|
|
1267
1895
|
if (isEmpty) return {};
|
|
1268
|
-
return
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1896
|
+
return mergeChartOption7(
|
|
1897
|
+
{
|
|
1898
|
+
tooltip: buildTooltip7(
|
|
1899
|
+
{
|
|
1900
|
+
trigger: "item"
|
|
1901
|
+
},
|
|
1902
|
+
{
|
|
1903
|
+
show: showTooltip,
|
|
1904
|
+
formatter: tooltipFormatter,
|
|
1905
|
+
valueFormatter: tooltipValueFormatter
|
|
1906
|
+
}
|
|
1907
|
+
),
|
|
1908
|
+
legend: buildLegend7(
|
|
1909
|
+
data.series.map((s) => s.name),
|
|
1910
|
+
legendConfig,
|
|
1911
|
+
{ show: showLegend, custom: customLegend }
|
|
1912
|
+
),
|
|
1913
|
+
radar: {
|
|
1914
|
+
indicator: indicators.map((ind) => ({
|
|
1915
|
+
name: ind.name,
|
|
1916
|
+
max: ind.max,
|
|
1917
|
+
min: ind.min
|
|
1918
|
+
})),
|
|
1919
|
+
shape,
|
|
1920
|
+
center: legendCenter3(legendConfig, showLegend && !customLegend, ["50%", "50%"])
|
|
1921
|
+
},
|
|
1922
|
+
series: [
|
|
1923
|
+
{
|
|
1924
|
+
type: "radar",
|
|
1925
|
+
label: buildDataLabel7({ show: true }, void 0, {
|
|
1926
|
+
show: showLabels,
|
|
1927
|
+
formatter: labelFormatter
|
|
1928
|
+
}),
|
|
1929
|
+
data: data.series.map((series) => ({
|
|
1930
|
+
name: series.name,
|
|
1931
|
+
value: series.data,
|
|
1932
|
+
itemStyle: series.color ? { color: series.color } : void 0,
|
|
1933
|
+
areaStyle: {
|
|
1934
|
+
opacity: 0.2
|
|
1935
|
+
}
|
|
1936
|
+
}))
|
|
1937
|
+
}
|
|
1938
|
+
]
|
|
1283
1939
|
},
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1940
|
+
optionOverride
|
|
1941
|
+
);
|
|
1942
|
+
}, [
|
|
1943
|
+
data,
|
|
1944
|
+
indicators,
|
|
1945
|
+
isEmpty,
|
|
1946
|
+
showTooltip,
|
|
1947
|
+
showLegend,
|
|
1948
|
+
shape,
|
|
1949
|
+
showLabels,
|
|
1950
|
+
labelFormatter,
|
|
1951
|
+
tooltipFormatter,
|
|
1952
|
+
tooltipValueFormatter,
|
|
1953
|
+
legendConfig,
|
|
1954
|
+
customLegend,
|
|
1955
|
+
optionOverride
|
|
1956
|
+
]);
|
|
1299
1957
|
const { containerRef } = useChart({
|
|
1300
1958
|
option,
|
|
1301
1959
|
theme,
|
|
1302
|
-
animation
|
|
1960
|
+
animation,
|
|
1961
|
+
onReady: (chart) => {
|
|
1962
|
+
legend.attach(chart);
|
|
1963
|
+
}
|
|
1303
1964
|
});
|
|
1304
1965
|
const accessibilityDescription = description || (!isEmpty ? `${title}. Radar chart with ${indicators.length} dimensions comparing ${data.series.length} series.` : void 0);
|
|
1305
|
-
return /* @__PURE__ */
|
|
1966
|
+
return /* @__PURE__ */ jsx12(
|
|
1306
1967
|
ChartContainer,
|
|
1307
1968
|
{
|
|
1308
1969
|
ref,
|
|
@@ -1314,8 +1975,10 @@ var RadarChart = React11.forwardRef(
|
|
|
1314
1975
|
empty: isEmpty,
|
|
1315
1976
|
emptyMessage,
|
|
1316
1977
|
className: cn(className),
|
|
1978
|
+
legend: !isEmpty && renderLegend ? renderLegend(legend.renderProps) : void 0,
|
|
1979
|
+
legendPosition: legendConfig?.position,
|
|
1317
1980
|
...props,
|
|
1318
|
-
children: /* @__PURE__ */
|
|
1981
|
+
children: /* @__PURE__ */ jsx12("div", { ref: containerRef, className: "h-full w-full" })
|
|
1319
1982
|
}
|
|
1320
1983
|
);
|
|
1321
1984
|
}
|
|
@@ -1323,12 +1986,23 @@ var RadarChart = React11.forwardRef(
|
|
|
1323
1986
|
RadarChart.displayName = "RadarChart";
|
|
1324
1987
|
|
|
1325
1988
|
// src/components/extended/FunnelChart.tsx
|
|
1326
|
-
import * as
|
|
1989
|
+
import * as React13 from "react";
|
|
1327
1990
|
import * as echarts10 from "echarts/core";
|
|
1328
1991
|
import { FunnelChart as EChartsFunnelChart } from "echarts/charts";
|
|
1329
1992
|
import { TooltipComponent as TooltipComponent8, LegendComponent as LegendComponent8, TitleComponent as TitleComponent8 } from "echarts/components";
|
|
1330
1993
|
import { CanvasRenderer as CanvasRenderer8 } from "echarts/renderers";
|
|
1331
|
-
import {
|
|
1994
|
+
import {
|
|
1995
|
+
buildDataLabel as buildDataLabel8,
|
|
1996
|
+
buildLegend as buildLegend8,
|
|
1997
|
+
buildTooltip as buildTooltip8,
|
|
1998
|
+
escapeHtml as escapeHtml4,
|
|
1999
|
+
formatTooltipValue as formatTooltipValue4,
|
|
2000
|
+
getChartColors as getChartColors8,
|
|
2001
|
+
itemLabelLookup as itemLabelLookup3,
|
|
2002
|
+
mergeChartOption as mergeChartOption8,
|
|
2003
|
+
pointLabel as pointLabel3
|
|
2004
|
+
} from "@classic-homes/charts-core";
|
|
2005
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
1332
2006
|
echarts10.use([
|
|
1333
2007
|
EChartsFunnelChart,
|
|
1334
2008
|
TooltipComponent8,
|
|
@@ -1336,7 +2010,7 @@ echarts10.use([
|
|
|
1336
2010
|
TitleComponent8,
|
|
1337
2011
|
CanvasRenderer8
|
|
1338
2012
|
]);
|
|
1339
|
-
var FunnelChart =
|
|
2013
|
+
var FunnelChart = React13.forwardRef(
|
|
1340
2014
|
({
|
|
1341
2015
|
title,
|
|
1342
2016
|
description,
|
|
@@ -1352,81 +2026,134 @@ var FunnelChart = React12.forwardRef(
|
|
|
1352
2026
|
sort = "descending",
|
|
1353
2027
|
orientation = "vertical",
|
|
1354
2028
|
showLabels = true,
|
|
2029
|
+
labelFormatter,
|
|
2030
|
+
tooltipFormatter,
|
|
2031
|
+
tooltipValueFormatter,
|
|
2032
|
+
legend: legendConfig,
|
|
2033
|
+
renderLegend,
|
|
2034
|
+
onLegendChange,
|
|
2035
|
+
option: optionOverride,
|
|
1355
2036
|
onClick,
|
|
1356
2037
|
class: className,
|
|
1357
2038
|
...props
|
|
1358
2039
|
}, ref) => {
|
|
1359
2040
|
const isEmpty = !data?.length;
|
|
1360
|
-
const
|
|
2041
|
+
const currentTheme = useChartTheme(theme);
|
|
2042
|
+
const legend = useChartLegend({
|
|
2043
|
+
names: data?.map((d) => d.name) ?? [],
|
|
2044
|
+
colors: data?.map((d) => d.color) ?? [],
|
|
2045
|
+
palette: getChartColors8(currentTheme).series,
|
|
2046
|
+
config: legendConfig,
|
|
2047
|
+
title,
|
|
2048
|
+
onLegendChange
|
|
2049
|
+
});
|
|
2050
|
+
const customLegend = renderLegend !== void 0;
|
|
2051
|
+
const option = React13.useMemo(() => {
|
|
1361
2052
|
if (isEmpty) return {};
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
} : void 0,
|
|
1371
|
-
series: [
|
|
1372
|
-
{
|
|
1373
|
-
name: title,
|
|
1374
|
-
type: "funnel",
|
|
1375
|
-
left: "10%",
|
|
1376
|
-
top: 60,
|
|
1377
|
-
bottom: 60,
|
|
1378
|
-
width: "80%",
|
|
1379
|
-
min: 0,
|
|
1380
|
-
max: Math.max(...data.map((d) => d.value)),
|
|
1381
|
-
minSize: "0%",
|
|
1382
|
-
maxSize: "100%",
|
|
1383
|
-
sort,
|
|
1384
|
-
orient: orientation,
|
|
1385
|
-
gap: 2,
|
|
1386
|
-
label: showLabels ? {
|
|
1387
|
-
show: true,
|
|
1388
|
-
position: "inside",
|
|
1389
|
-
formatter: "{b}: {c}"
|
|
1390
|
-
} : {
|
|
1391
|
-
show: false
|
|
1392
|
-
},
|
|
1393
|
-
labelLine: {
|
|
1394
|
-
show: false
|
|
1395
|
-
},
|
|
1396
|
-
emphasis: {
|
|
1397
|
-
label: {
|
|
1398
|
-
fontSize: 16
|
|
1399
|
-
}
|
|
1400
|
-
},
|
|
1401
|
-
data: data.map((item) => ({
|
|
1402
|
-
name: item.name,
|
|
1403
|
-
value: item.value,
|
|
1404
|
-
itemStyle: item.color ? { color: item.color } : void 0
|
|
1405
|
-
}))
|
|
1406
|
-
}
|
|
1407
|
-
]
|
|
2053
|
+
const getLabel = itemLabelLookup3(data);
|
|
2054
|
+
const valueFormatter = tooltipFormatter === void 0 ? tooltipValueFormatter : void 0;
|
|
2055
|
+
const tooltipBase = {
|
|
2056
|
+
trigger: "item",
|
|
2057
|
+
formatter: valueFormatter ? (params) => {
|
|
2058
|
+
const p = params;
|
|
2059
|
+
return `${escapeHtml4(p.seriesName)} <br/>${escapeHtml4(p.name)}: ${escapeHtml4(formatTooltipValue4(p.value, valueFormatter))}`;
|
|
2060
|
+
} : "{a} <br/>{b}: {c}"
|
|
1408
2061
|
};
|
|
1409
|
-
|
|
2062
|
+
return mergeChartOption8(
|
|
2063
|
+
{
|
|
2064
|
+
tooltip: buildTooltip8(tooltipBase, {
|
|
2065
|
+
show: showTooltip,
|
|
2066
|
+
formatter: tooltipFormatter,
|
|
2067
|
+
valueFormatter: tooltipValueFormatter,
|
|
2068
|
+
getLabel
|
|
2069
|
+
}),
|
|
2070
|
+
legend: buildLegend8(
|
|
2071
|
+
data.map((d) => d.name),
|
|
2072
|
+
legendConfig,
|
|
2073
|
+
{ show: showLegend, custom: customLegend }
|
|
2074
|
+
),
|
|
2075
|
+
series: [
|
|
2076
|
+
{
|
|
2077
|
+
name: title,
|
|
2078
|
+
type: "funnel",
|
|
2079
|
+
left: "10%",
|
|
2080
|
+
top: 60,
|
|
2081
|
+
bottom: 60,
|
|
2082
|
+
width: "80%",
|
|
2083
|
+
min: 0,
|
|
2084
|
+
// reduce, not Math.max(...): spreading large arrays overflows the stack
|
|
2085
|
+
max: data.reduce((m, d) => d.value > m ? d.value : m, -Infinity),
|
|
2086
|
+
minSize: "0%",
|
|
2087
|
+
maxSize: "100%",
|
|
2088
|
+
sort,
|
|
2089
|
+
orient: orientation,
|
|
2090
|
+
gap: 2,
|
|
2091
|
+
label: buildDataLabel8(
|
|
2092
|
+
{
|
|
2093
|
+
show: true,
|
|
2094
|
+
position: "inside",
|
|
2095
|
+
formatter: "{b}: {c}"
|
|
2096
|
+
},
|
|
2097
|
+
{ show: false },
|
|
2098
|
+
{ show: showLabels, formatter: labelFormatter, getLabel }
|
|
2099
|
+
),
|
|
2100
|
+
labelLine: {
|
|
2101
|
+
show: false
|
|
2102
|
+
},
|
|
2103
|
+
emphasis: {
|
|
2104
|
+
label: {
|
|
2105
|
+
fontSize: 16
|
|
2106
|
+
}
|
|
2107
|
+
},
|
|
2108
|
+
data: data.map((item) => ({
|
|
2109
|
+
name: item.name,
|
|
2110
|
+
value: item.value,
|
|
2111
|
+
itemStyle: item.color ? { color: item.color } : void 0,
|
|
2112
|
+
label: pointLabel3(item.label, labelFormatter, { position: "inside" })
|
|
2113
|
+
}))
|
|
2114
|
+
}
|
|
2115
|
+
]
|
|
2116
|
+
},
|
|
2117
|
+
optionOverride
|
|
2118
|
+
);
|
|
2119
|
+
}, [
|
|
2120
|
+
data,
|
|
2121
|
+
isEmpty,
|
|
2122
|
+
showTooltip,
|
|
2123
|
+
showLegend,
|
|
2124
|
+
sort,
|
|
2125
|
+
orientation,
|
|
2126
|
+
showLabels,
|
|
2127
|
+
title,
|
|
2128
|
+
labelFormatter,
|
|
2129
|
+
tooltipFormatter,
|
|
2130
|
+
tooltipValueFormatter,
|
|
2131
|
+
legendConfig,
|
|
2132
|
+
customLegend,
|
|
2133
|
+
optionOverride
|
|
2134
|
+
]);
|
|
2135
|
+
const latest = useLatestRef({ onClick });
|
|
1410
2136
|
const { containerRef } = useChart({
|
|
1411
2137
|
option,
|
|
1412
2138
|
theme,
|
|
1413
2139
|
animation,
|
|
1414
2140
|
onReady: (chart) => {
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
2141
|
+
legend.attach(chart);
|
|
2142
|
+
chart.on("click", (params) => {
|
|
2143
|
+
const { onClick: onClick2 } = latest.current;
|
|
2144
|
+
if (!onClick2) return;
|
|
2145
|
+
onClick2({
|
|
2146
|
+
type: params.type || "click",
|
|
2147
|
+
componentType: params.componentType || "series",
|
|
2148
|
+
name: params.name || "",
|
|
2149
|
+
value: params.value,
|
|
2150
|
+
color: params.color
|
|
1424
2151
|
});
|
|
1425
|
-
}
|
|
2152
|
+
});
|
|
1426
2153
|
}
|
|
1427
2154
|
});
|
|
1428
2155
|
const accessibilityDescription = description || (!isEmpty ? `${title}. Funnel chart with ${data.length} stages.` : void 0);
|
|
1429
|
-
return /* @__PURE__ */
|
|
2156
|
+
return /* @__PURE__ */ jsx13(
|
|
1430
2157
|
ChartContainer,
|
|
1431
2158
|
{
|
|
1432
2159
|
ref,
|
|
@@ -1438,8 +2165,10 @@ var FunnelChart = React12.forwardRef(
|
|
|
1438
2165
|
empty: isEmpty,
|
|
1439
2166
|
emptyMessage,
|
|
1440
2167
|
className: cn(className),
|
|
2168
|
+
legend: !isEmpty && renderLegend ? renderLegend(legend.renderProps) : void 0,
|
|
2169
|
+
legendPosition: legendConfig?.position,
|
|
1441
2170
|
...props,
|
|
1442
|
-
children: /* @__PURE__ */
|
|
2171
|
+
children: /* @__PURE__ */ jsx13("div", { ref: containerRef, className: "h-full w-full" })
|
|
1443
2172
|
}
|
|
1444
2173
|
);
|
|
1445
2174
|
}
|
|
@@ -1447,14 +2176,20 @@ var FunnelChart = React12.forwardRef(
|
|
|
1447
2176
|
FunnelChart.displayName = "FunnelChart";
|
|
1448
2177
|
|
|
1449
2178
|
// src/components/extended/GaugeChart.tsx
|
|
1450
|
-
import * as
|
|
2179
|
+
import * as React14 from "react";
|
|
1451
2180
|
import * as echarts11 from "echarts/core";
|
|
1452
2181
|
import { GaugeChart as EChartsGaugeChart } from "echarts/charts";
|
|
1453
|
-
import { TitleComponent as TitleComponent9 } from "echarts/components";
|
|
2182
|
+
import { TitleComponent as TitleComponent9, TooltipComponent as TooltipComponent9 } from "echarts/components";
|
|
1454
2183
|
import { CanvasRenderer as CanvasRenderer9 } from "echarts/renderers";
|
|
1455
|
-
import {
|
|
1456
|
-
|
|
1457
|
-
|
|
2184
|
+
import {
|
|
2185
|
+
buildTooltip as buildTooltip9,
|
|
2186
|
+
getChartColors as getChartColors9,
|
|
2187
|
+
mergeChartOption as mergeChartOption9,
|
|
2188
|
+
THEME_DARK as THEME_DARK5
|
|
2189
|
+
} from "@classic-homes/charts-core";
|
|
2190
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
2191
|
+
echarts11.use([EChartsGaugeChart, TitleComponent9, TooltipComponent9, CanvasRenderer9]);
|
|
2192
|
+
var GaugeChart = React14.forwardRef(
|
|
1458
2193
|
({
|
|
1459
2194
|
title,
|
|
1460
2195
|
description,
|
|
@@ -1470,89 +2205,123 @@ var GaugeChart = React13.forwardRef(
|
|
|
1470
2205
|
splitNumber = 10,
|
|
1471
2206
|
showProgress = true,
|
|
1472
2207
|
formatValue,
|
|
2208
|
+
showTooltip = true,
|
|
2209
|
+
tooltipFormatter,
|
|
2210
|
+
tooltipValueFormatter,
|
|
2211
|
+
option: optionOverride,
|
|
1473
2212
|
class: className,
|
|
1474
2213
|
...props
|
|
1475
2214
|
}, ref) => {
|
|
1476
|
-
const
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
}
|
|
1490
|
-
|
|
1491
|
-
|
|
2215
|
+
const currentTheme = useChartTheme(theme);
|
|
2216
|
+
const chartColors = getChartColors9(currentTheme);
|
|
2217
|
+
const reducedMotion = useReducedMotion();
|
|
2218
|
+
const option = React14.useMemo(() => {
|
|
2219
|
+
return mergeChartOption9(
|
|
2220
|
+
{
|
|
2221
|
+
// No tooltip by default; one appears once its content is customised
|
|
2222
|
+
tooltip: tooltipFormatter || tooltipValueFormatter ? buildTooltip9(
|
|
2223
|
+
{ trigger: "item" },
|
|
2224
|
+
{
|
|
2225
|
+
show: showTooltip,
|
|
2226
|
+
formatter: tooltipFormatter,
|
|
2227
|
+
valueFormatter: tooltipValueFormatter
|
|
2228
|
+
}
|
|
2229
|
+
) : void 0,
|
|
2230
|
+
series: [
|
|
2231
|
+
{
|
|
2232
|
+
type: "gauge",
|
|
2233
|
+
center: ["50%", "60%"],
|
|
2234
|
+
radius: "80%",
|
|
2235
|
+
min,
|
|
2236
|
+
max,
|
|
2237
|
+
splitNumber,
|
|
2238
|
+
progress: showProgress ? {
|
|
2239
|
+
show: true,
|
|
1492
2240
|
width: 18
|
|
1493
|
-
}
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
value
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
2241
|
+
} : void 0,
|
|
2242
|
+
axisLine: {
|
|
2243
|
+
lineStyle: {
|
|
2244
|
+
width: 18
|
|
2245
|
+
}
|
|
2246
|
+
},
|
|
2247
|
+
axisTick: {
|
|
2248
|
+
distance: -30,
|
|
2249
|
+
splitNumber: 5,
|
|
2250
|
+
lineStyle: {
|
|
2251
|
+
width: 2,
|
|
2252
|
+
color: chartColors.mutedForeground
|
|
2253
|
+
}
|
|
2254
|
+
},
|
|
2255
|
+
splitLine: {
|
|
2256
|
+
distance: -32,
|
|
2257
|
+
length: 10,
|
|
2258
|
+
lineStyle: {
|
|
2259
|
+
width: 3,
|
|
2260
|
+
color: chartColors.mutedForeground
|
|
2261
|
+
}
|
|
2262
|
+
},
|
|
2263
|
+
axisLabel: {
|
|
2264
|
+
distance: -20,
|
|
2265
|
+
color: chartColors.mutedForeground,
|
|
2266
|
+
fontSize: 12
|
|
2267
|
+
},
|
|
2268
|
+
anchor: {
|
|
2269
|
+
show: true,
|
|
2270
|
+
size: 20,
|
|
2271
|
+
itemStyle: {
|
|
2272
|
+
borderWidth: 2
|
|
2273
|
+
}
|
|
2274
|
+
},
|
|
2275
|
+
pointer: {
|
|
2276
|
+
width: 6,
|
|
2277
|
+
length: "60%"
|
|
2278
|
+
},
|
|
2279
|
+
title: {
|
|
2280
|
+
show: true,
|
|
2281
|
+
offsetCenter: [0, "70%"],
|
|
2282
|
+
fontSize: 14
|
|
2283
|
+
},
|
|
2284
|
+
detail: {
|
|
2285
|
+
valueAnimation: animation && !reducedMotion,
|
|
2286
|
+
fontSize: 28,
|
|
2287
|
+
fontWeight: "bold",
|
|
2288
|
+
offsetCenter: [0, "40%"],
|
|
2289
|
+
formatter: formatValue || "{value}"
|
|
2290
|
+
},
|
|
2291
|
+
data: [
|
|
2292
|
+
{
|
|
2293
|
+
value,
|
|
2294
|
+
name: title
|
|
2295
|
+
}
|
|
2296
|
+
]
|
|
2297
|
+
}
|
|
2298
|
+
]
|
|
2299
|
+
},
|
|
2300
|
+
optionOverride
|
|
2301
|
+
);
|
|
2302
|
+
}, [
|
|
2303
|
+
value,
|
|
2304
|
+
min,
|
|
2305
|
+
max,
|
|
2306
|
+
splitNumber,
|
|
2307
|
+
showProgress,
|
|
2308
|
+
formatValue,
|
|
2309
|
+
title,
|
|
2310
|
+
animation,
|
|
2311
|
+
reducedMotion,
|
|
2312
|
+
chartColors,
|
|
2313
|
+
showTooltip,
|
|
2314
|
+
tooltipFormatter,
|
|
2315
|
+
tooltipValueFormatter,
|
|
2316
|
+
optionOverride
|
|
2317
|
+
]);
|
|
1549
2318
|
const { containerRef } = useChart({
|
|
1550
2319
|
option,
|
|
1551
|
-
theme,
|
|
2320
|
+
theme: currentTheme === THEME_DARK5 ? "dark" : "light",
|
|
1552
2321
|
animation
|
|
1553
2322
|
});
|
|
1554
2323
|
const accessibilityDescription = description || `${title}. Gauge showing value ${value} on scale from ${min} to ${max}.`;
|
|
1555
|
-
return /* @__PURE__ */
|
|
2324
|
+
return /* @__PURE__ */ jsx14(
|
|
1556
2325
|
ChartContainer,
|
|
1557
2326
|
{
|
|
1558
2327
|
ref,
|
|
@@ -1564,7 +2333,7 @@ var GaugeChart = React13.forwardRef(
|
|
|
1564
2333
|
emptyMessage,
|
|
1565
2334
|
className: cn(className),
|
|
1566
2335
|
...props,
|
|
1567
|
-
children: /* @__PURE__ */
|
|
2336
|
+
children: /* @__PURE__ */ jsx14("div", { ref: containerRef, className: "h-full w-full" })
|
|
1568
2337
|
}
|
|
1569
2338
|
);
|
|
1570
2339
|
}
|
|
@@ -1572,26 +2341,34 @@ var GaugeChart = React13.forwardRef(
|
|
|
1572
2341
|
GaugeChart.displayName = "GaugeChart";
|
|
1573
2342
|
|
|
1574
2343
|
// src/components/extended/HeatmapChart.tsx
|
|
1575
|
-
import * as
|
|
2344
|
+
import * as React15 from "react";
|
|
1576
2345
|
import * as echarts12 from "echarts/core";
|
|
1577
2346
|
import { HeatmapChart as EChartsHeatmapChart } from "echarts/charts";
|
|
1578
2347
|
import {
|
|
1579
2348
|
GridComponent as GridComponent5,
|
|
1580
|
-
TooltipComponent as
|
|
2349
|
+
TooltipComponent as TooltipComponent10,
|
|
1581
2350
|
TitleComponent as TitleComponent10,
|
|
1582
2351
|
VisualMapComponent
|
|
1583
2352
|
} from "echarts/components";
|
|
1584
2353
|
import { CanvasRenderer as CanvasRenderer10 } from "echarts/renderers";
|
|
1585
|
-
import {
|
|
2354
|
+
import {
|
|
2355
|
+
buildAxis as buildAxis5,
|
|
2356
|
+
buildDataLabel as buildDataLabel9,
|
|
2357
|
+
buildTooltip as buildTooltip10,
|
|
2358
|
+
escapeHtml as escapeHtml5,
|
|
2359
|
+
formatTooltipValue as formatTooltipValue5,
|
|
2360
|
+
mergeChartOption as mergeChartOption10
|
|
2361
|
+
} from "@classic-homes/charts-core";
|
|
2362
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
1586
2363
|
echarts12.use([
|
|
1587
2364
|
EChartsHeatmapChart,
|
|
1588
2365
|
GridComponent5,
|
|
1589
|
-
|
|
2366
|
+
TooltipComponent10,
|
|
1590
2367
|
TitleComponent10,
|
|
1591
2368
|
VisualMapComponent,
|
|
1592
2369
|
CanvasRenderer10
|
|
1593
2370
|
]);
|
|
1594
|
-
var HeatmapChart =
|
|
2371
|
+
var HeatmapChart = React15.forwardRef(
|
|
1595
2372
|
({
|
|
1596
2373
|
title,
|
|
1597
2374
|
description,
|
|
@@ -1606,95 +2383,140 @@ var HeatmapChart = React14.forwardRef(
|
|
|
1606
2383
|
animation = true,
|
|
1607
2384
|
showTooltip = true,
|
|
1608
2385
|
showValues = false,
|
|
2386
|
+
labelFormatter,
|
|
2387
|
+
xAxisConfig,
|
|
2388
|
+
yAxisConfig,
|
|
2389
|
+
tooltipFormatter,
|
|
2390
|
+
tooltipValueFormatter,
|
|
2391
|
+
option: optionOverride,
|
|
1609
2392
|
onClick,
|
|
1610
2393
|
class: className,
|
|
1611
2394
|
...props
|
|
1612
2395
|
}, ref) => {
|
|
1613
2396
|
const isEmpty = !data?.data?.length || !xAxis?.length || !yAxis?.length;
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
const
|
|
1617
|
-
|
|
2397
|
+
let dataMin = Infinity;
|
|
2398
|
+
let dataMax = -Infinity;
|
|
2399
|
+
for (const [, , value] of data?.data ?? []) {
|
|
2400
|
+
if (value < dataMin) dataMin = value;
|
|
2401
|
+
if (value > dataMax) dataMax = value;
|
|
2402
|
+
}
|
|
2403
|
+
const minValue = data?.min ?? dataMin;
|
|
2404
|
+
const maxValue = data?.max ?? dataMax;
|
|
2405
|
+
const option = React15.useMemo(() => {
|
|
1618
2406
|
if (isEmpty) return {};
|
|
1619
|
-
return
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
grid: {
|
|
1630
|
-
left: "3%",
|
|
1631
|
-
right: "10%",
|
|
1632
|
-
bottom: "3%",
|
|
1633
|
-
containLabel: true
|
|
1634
|
-
},
|
|
1635
|
-
xAxis: {
|
|
1636
|
-
type: "category",
|
|
1637
|
-
data: xAxis,
|
|
1638
|
-
splitArea: {
|
|
1639
|
-
show: true
|
|
1640
|
-
}
|
|
1641
|
-
},
|
|
1642
|
-
yAxis: {
|
|
1643
|
-
type: "category",
|
|
1644
|
-
data: yAxis,
|
|
1645
|
-
splitArea: {
|
|
1646
|
-
show: true
|
|
1647
|
-
}
|
|
1648
|
-
},
|
|
1649
|
-
visualMap: {
|
|
1650
|
-
min: minValue,
|
|
1651
|
-
max: maxValue,
|
|
1652
|
-
calculable: true,
|
|
1653
|
-
orient: "vertical",
|
|
1654
|
-
right: "0%",
|
|
1655
|
-
top: "center"
|
|
1656
|
-
},
|
|
1657
|
-
series: [
|
|
1658
|
-
{
|
|
1659
|
-
name: title,
|
|
1660
|
-
type: "heatmap",
|
|
1661
|
-
data: data.data,
|
|
1662
|
-
label: showValues ? {
|
|
1663
|
-
show: true
|
|
1664
|
-
} : void 0,
|
|
1665
|
-
emphasis: {
|
|
1666
|
-
itemStyle: {
|
|
1667
|
-
shadowBlur: 10,
|
|
1668
|
-
shadowColor: "rgba(0, 0, 0, 0.5)"
|
|
2407
|
+
return mergeChartOption10(
|
|
2408
|
+
{
|
|
2409
|
+
tooltip: buildTooltip10(
|
|
2410
|
+
{
|
|
2411
|
+
position: "top",
|
|
2412
|
+
formatter: (params) => {
|
|
2413
|
+
const p = params;
|
|
2414
|
+
if (!p.value) return "";
|
|
2415
|
+
const [xIdx, yIdx, value] = p.value;
|
|
2416
|
+
return `${escapeHtml5(xAxis[xIdx])} / ${escapeHtml5(yAxis[yIdx])}: ${escapeHtml5(formatTooltipValue5(value, tooltipValueFormatter))}`;
|
|
1669
2417
|
}
|
|
2418
|
+
},
|
|
2419
|
+
{
|
|
2420
|
+
show: showTooltip,
|
|
2421
|
+
formatter: tooltipFormatter,
|
|
2422
|
+
valueFormatter: tooltipValueFormatter
|
|
1670
2423
|
}
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
2424
|
+
),
|
|
2425
|
+
grid: {
|
|
2426
|
+
left: "3%",
|
|
2427
|
+
right: "10%",
|
|
2428
|
+
bottom: "3%",
|
|
2429
|
+
containLabel: true
|
|
2430
|
+
},
|
|
2431
|
+
xAxis: buildAxis5(
|
|
2432
|
+
{
|
|
2433
|
+
type: "category",
|
|
2434
|
+
data: xAxis,
|
|
2435
|
+
splitArea: {
|
|
2436
|
+
show: true
|
|
2437
|
+
}
|
|
2438
|
+
},
|
|
2439
|
+
xAxisConfig
|
|
2440
|
+
),
|
|
2441
|
+
yAxis: buildAxis5(
|
|
2442
|
+
{
|
|
2443
|
+
type: "category",
|
|
2444
|
+
data: yAxis,
|
|
2445
|
+
splitArea: {
|
|
2446
|
+
show: true
|
|
2447
|
+
}
|
|
2448
|
+
},
|
|
2449
|
+
yAxisConfig
|
|
2450
|
+
),
|
|
2451
|
+
visualMap: {
|
|
2452
|
+
min: minValue,
|
|
2453
|
+
max: maxValue,
|
|
2454
|
+
calculable: true,
|
|
2455
|
+
orient: "vertical",
|
|
2456
|
+
right: "0%",
|
|
2457
|
+
top: "center"
|
|
2458
|
+
},
|
|
2459
|
+
series: [
|
|
2460
|
+
{
|
|
2461
|
+
name: title,
|
|
2462
|
+
type: "heatmap",
|
|
2463
|
+
data: data.data,
|
|
2464
|
+
label: buildDataLabel9({ show: true }, void 0, {
|
|
2465
|
+
show: showValues,
|
|
2466
|
+
formatter: labelFormatter
|
|
2467
|
+
}),
|
|
2468
|
+
emphasis: {
|
|
2469
|
+
itemStyle: {
|
|
2470
|
+
shadowBlur: 10,
|
|
2471
|
+
shadowColor: "rgba(0, 0, 0, 0.5)"
|
|
2472
|
+
}
|
|
2473
|
+
}
|
|
2474
|
+
}
|
|
2475
|
+
]
|
|
2476
|
+
},
|
|
2477
|
+
optionOverride
|
|
2478
|
+
);
|
|
2479
|
+
}, [
|
|
2480
|
+
data,
|
|
2481
|
+
xAxis,
|
|
2482
|
+
yAxis,
|
|
2483
|
+
isEmpty,
|
|
2484
|
+
showTooltip,
|
|
2485
|
+
showValues,
|
|
2486
|
+
minValue,
|
|
2487
|
+
maxValue,
|
|
2488
|
+
title,
|
|
2489
|
+
labelFormatter,
|
|
2490
|
+
xAxisConfig,
|
|
2491
|
+
yAxisConfig,
|
|
2492
|
+
tooltipFormatter,
|
|
2493
|
+
tooltipValueFormatter,
|
|
2494
|
+
optionOverride
|
|
2495
|
+
]);
|
|
2496
|
+
const latest = useLatestRef({ onClick, xAxis, yAxis });
|
|
1675
2497
|
const { containerRef } = useChart({
|
|
1676
2498
|
option,
|
|
1677
2499
|
theme,
|
|
1678
2500
|
animation,
|
|
1679
2501
|
onReady: (chart) => {
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
2502
|
+
chart.on("click", (params) => {
|
|
2503
|
+
const { onClick: onClick2, xAxis: xAxis2, yAxis: yAxis2 } = latest.current;
|
|
2504
|
+
if (!onClick2) return;
|
|
2505
|
+
const [xIdx, yIdx, value] = params.value || [0, 0, 0];
|
|
2506
|
+
onClick2({
|
|
2507
|
+
type: params.type || "click",
|
|
2508
|
+
componentType: params.componentType || "series",
|
|
2509
|
+
xIndex: xIdx,
|
|
2510
|
+
yIndex: yIdx,
|
|
2511
|
+
xLabel: xAxis2[xIdx],
|
|
2512
|
+
yLabel: yAxis2[yIdx],
|
|
2513
|
+
value
|
|
1692
2514
|
});
|
|
1693
|
-
}
|
|
2515
|
+
});
|
|
1694
2516
|
}
|
|
1695
2517
|
});
|
|
1696
2518
|
const accessibilityDescription = description || (!isEmpty ? `${title}. Heatmap with ${xAxis.length} columns and ${yAxis.length} rows.` : void 0);
|
|
1697
|
-
return /* @__PURE__ */
|
|
2519
|
+
return /* @__PURE__ */ jsx15(
|
|
1698
2520
|
ChartContainer,
|
|
1699
2521
|
{
|
|
1700
2522
|
ref,
|
|
@@ -1707,7 +2529,7 @@ var HeatmapChart = React14.forwardRef(
|
|
|
1707
2529
|
emptyMessage,
|
|
1708
2530
|
className: cn(className),
|
|
1709
2531
|
...props,
|
|
1710
|
-
children: /* @__PURE__ */
|
|
2532
|
+
children: /* @__PURE__ */ jsx15("div", { ref: containerRef, className: "h-full w-full" })
|
|
1711
2533
|
}
|
|
1712
2534
|
);
|
|
1713
2535
|
}
|
|
@@ -1715,14 +2537,25 @@ var HeatmapChart = React14.forwardRef(
|
|
|
1715
2537
|
HeatmapChart.displayName = "HeatmapChart";
|
|
1716
2538
|
|
|
1717
2539
|
// src/components/extended/TreemapChart.tsx
|
|
1718
|
-
import * as
|
|
2540
|
+
import * as React16 from "react";
|
|
1719
2541
|
import * as echarts13 from "echarts/core";
|
|
1720
2542
|
import { TreemapChart as EChartsTreemapChart } from "echarts/charts";
|
|
1721
|
-
import { TooltipComponent as
|
|
2543
|
+
import { TooltipComponent as TooltipComponent11, TitleComponent as TitleComponent11 } from "echarts/components";
|
|
1722
2544
|
import { CanvasRenderer as CanvasRenderer11 } from "echarts/renderers";
|
|
1723
|
-
import {
|
|
1724
|
-
|
|
1725
|
-
|
|
2545
|
+
import {
|
|
2546
|
+
buildDataLabel as buildDataLabel10,
|
|
2547
|
+
buildTooltip as buildTooltip11,
|
|
2548
|
+
escapeHtml as escapeHtml6,
|
|
2549
|
+
formatTooltipValue as formatTooltipValue6,
|
|
2550
|
+
getChartColors as getChartColors10,
|
|
2551
|
+
mergeChartOption as mergeChartOption11,
|
|
2552
|
+
nameLabelLookup,
|
|
2553
|
+
pointLabel as pointLabel4,
|
|
2554
|
+
THEME_DARK as THEME_DARK6
|
|
2555
|
+
} from "@classic-homes/charts-core";
|
|
2556
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
2557
|
+
echarts13.use([EChartsTreemapChart, TooltipComponent11, TitleComponent11, CanvasRenderer11]);
|
|
2558
|
+
var TreemapChart = React16.forwardRef(
|
|
1726
2559
|
({
|
|
1727
2560
|
title,
|
|
1728
2561
|
description,
|
|
@@ -1735,89 +2568,122 @@ var TreemapChart = React15.forwardRef(
|
|
|
1735
2568
|
theme = "auto",
|
|
1736
2569
|
animation = true,
|
|
1737
2570
|
showTooltip = true,
|
|
2571
|
+
labelFormatter,
|
|
2572
|
+
tooltipFormatter,
|
|
2573
|
+
tooltipValueFormatter,
|
|
2574
|
+
option: optionOverride,
|
|
1738
2575
|
onClick,
|
|
1739
2576
|
class: className,
|
|
1740
2577
|
...props
|
|
1741
2578
|
}, ref) => {
|
|
1742
2579
|
const isEmpty = !data?.length;
|
|
1743
|
-
const
|
|
2580
|
+
const currentTheme = useChartTheme(theme);
|
|
2581
|
+
const chartColors = getChartColors10(currentTheme);
|
|
2582
|
+
const option = React16.useMemo(() => {
|
|
1744
2583
|
if (isEmpty) return {};
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
2584
|
+
const toNode = (node) => ({
|
|
2585
|
+
...node,
|
|
2586
|
+
children: node.children?.map(toNode),
|
|
2587
|
+
label: pointLabel4(node.label, labelFormatter)
|
|
2588
|
+
});
|
|
2589
|
+
return mergeChartOption11(
|
|
2590
|
+
{
|
|
2591
|
+
tooltip: buildTooltip11(
|
|
2592
|
+
{
|
|
2593
|
+
formatter: (params) => {
|
|
2594
|
+
const p = params;
|
|
2595
|
+
return `${escapeHtml6(p.name)}: ${escapeHtml6(formatTooltipValue6(p.value, tooltipValueFormatter))}`;
|
|
2596
|
+
}
|
|
2597
|
+
},
|
|
2598
|
+
{
|
|
2599
|
+
show: showTooltip,
|
|
2600
|
+
formatter: tooltipFormatter,
|
|
2601
|
+
valueFormatter: tooltipValueFormatter
|
|
2602
|
+
}
|
|
2603
|
+
),
|
|
2604
|
+
series: [
|
|
2605
|
+
{
|
|
2606
|
+
type: "treemap",
|
|
2607
|
+
data: data.map(toNode),
|
|
2608
|
+
roam: false,
|
|
2609
|
+
levels: levels || [
|
|
2610
|
+
{
|
|
2611
|
+
itemStyle: {
|
|
2612
|
+
borderColor: chartColors.divider,
|
|
2613
|
+
borderWidth: 4,
|
|
2614
|
+
gapWidth: 4
|
|
2615
|
+
}
|
|
2616
|
+
},
|
|
2617
|
+
{
|
|
2618
|
+
colorSaturation: [0.3, 0.6],
|
|
2619
|
+
itemStyle: {
|
|
2620
|
+
borderColorSaturation: 0.7,
|
|
2621
|
+
gapWidth: 2,
|
|
2622
|
+
borderWidth: 2
|
|
2623
|
+
}
|
|
2624
|
+
},
|
|
2625
|
+
{
|
|
2626
|
+
colorSaturation: [0.3, 0.5],
|
|
2627
|
+
itemStyle: {
|
|
2628
|
+
borderColorSaturation: 0.6,
|
|
2629
|
+
gapWidth: 1
|
|
2630
|
+
}
|
|
2631
|
+
},
|
|
2632
|
+
{
|
|
2633
|
+
colorSaturation: [0.3, 0.5]
|
|
1778
2634
|
}
|
|
2635
|
+
],
|
|
2636
|
+
label: buildDataLabel10({ show: true, formatter: "{b}" }, void 0, {
|
|
2637
|
+
show: true,
|
|
2638
|
+
formatter: labelFormatter,
|
|
2639
|
+
getLabel: nameLabelLookup(data)
|
|
2640
|
+
}),
|
|
2641
|
+
upperLabel: {
|
|
2642
|
+
show: true,
|
|
2643
|
+
height: 30
|
|
1779
2644
|
},
|
|
1780
|
-
{
|
|
1781
|
-
|
|
2645
|
+
breadcrumb: {
|
|
2646
|
+
show: true
|
|
1782
2647
|
}
|
|
1783
|
-
],
|
|
1784
|
-
label: {
|
|
1785
|
-
show: true,
|
|
1786
|
-
formatter: "{b}"
|
|
1787
|
-
},
|
|
1788
|
-
upperLabel: {
|
|
1789
|
-
show: true,
|
|
1790
|
-
height: 30
|
|
1791
|
-
},
|
|
1792
|
-
breadcrumb: {
|
|
1793
|
-
show: true
|
|
1794
2648
|
}
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
2649
|
+
]
|
|
2650
|
+
},
|
|
2651
|
+
optionOverride
|
|
2652
|
+
);
|
|
2653
|
+
}, [
|
|
2654
|
+
data,
|
|
2655
|
+
levels,
|
|
2656
|
+
isEmpty,
|
|
2657
|
+
showTooltip,
|
|
2658
|
+
chartColors,
|
|
2659
|
+
labelFormatter,
|
|
2660
|
+
tooltipFormatter,
|
|
2661
|
+
tooltipValueFormatter,
|
|
2662
|
+
optionOverride
|
|
2663
|
+
]);
|
|
2664
|
+
const latest = useLatestRef({ onClick });
|
|
1799
2665
|
const { containerRef } = useChart({
|
|
1800
2666
|
option,
|
|
1801
|
-
theme,
|
|
2667
|
+
theme: currentTheme === THEME_DARK6 ? "dark" : "light",
|
|
1802
2668
|
animation,
|
|
1803
2669
|
onReady: (chart) => {
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
2670
|
+
chart.on("click", (params) => {
|
|
2671
|
+
const { onClick: onClick2 } = latest.current;
|
|
2672
|
+
if (!onClick2) return;
|
|
2673
|
+
const treePathInfo = params.treePathInfo || [];
|
|
2674
|
+
onClick2({
|
|
2675
|
+
type: params.type || "click",
|
|
2676
|
+
componentType: params.componentType || "series",
|
|
2677
|
+
name: params.name || "",
|
|
2678
|
+
value: params.value,
|
|
2679
|
+
path: treePathInfo.map((item) => item.name || ""),
|
|
2680
|
+
depth: treePathInfo.length - 1
|
|
1815
2681
|
});
|
|
1816
|
-
}
|
|
2682
|
+
});
|
|
1817
2683
|
}
|
|
1818
2684
|
});
|
|
1819
2685
|
const accessibilityDescription = description || (!isEmpty ? `${title}. Treemap chart showing hierarchical data.` : void 0);
|
|
1820
|
-
return /* @__PURE__ */
|
|
2686
|
+
return /* @__PURE__ */ jsx16(
|
|
1821
2687
|
ChartContainer,
|
|
1822
2688
|
{
|
|
1823
2689
|
ref,
|
|
@@ -1830,7 +2696,7 @@ var TreemapChart = React15.forwardRef(
|
|
|
1830
2696
|
emptyMessage,
|
|
1831
2697
|
className: cn(className),
|
|
1832
2698
|
...props,
|
|
1833
|
-
children: /* @__PURE__ */
|
|
2699
|
+
children: /* @__PURE__ */ jsx16("div", { ref: containerRef, className: "h-full w-full" })
|
|
1834
2700
|
}
|
|
1835
2701
|
);
|
|
1836
2702
|
}
|
|
@@ -1838,7 +2704,7 @@ var TreemapChart = React15.forwardRef(
|
|
|
1838
2704
|
TreemapChart.displayName = "TreemapChart";
|
|
1839
2705
|
|
|
1840
2706
|
// src/components/extended/CandlestickChart.tsx
|
|
1841
|
-
import * as
|
|
2707
|
+
import * as React17 from "react";
|
|
1842
2708
|
import * as echarts14 from "echarts/core";
|
|
1843
2709
|
import {
|
|
1844
2710
|
CandlestickChart as EChartsCandlestickChart,
|
|
@@ -1846,22 +2712,29 @@ import {
|
|
|
1846
2712
|
} from "echarts/charts";
|
|
1847
2713
|
import {
|
|
1848
2714
|
GridComponent as GridComponent6,
|
|
1849
|
-
TooltipComponent as
|
|
2715
|
+
TooltipComponent as TooltipComponent12,
|
|
1850
2716
|
TitleComponent as TitleComponent12,
|
|
1851
2717
|
DataZoomComponent
|
|
1852
2718
|
} from "echarts/components";
|
|
1853
2719
|
import { CanvasRenderer as CanvasRenderer12 } from "echarts/renderers";
|
|
1854
|
-
import {
|
|
2720
|
+
import {
|
|
2721
|
+
buildAxis as buildAxis6,
|
|
2722
|
+
buildTooltip as buildTooltip12,
|
|
2723
|
+
getChartColors as getChartColors11,
|
|
2724
|
+
mergeChartOption as mergeChartOption12,
|
|
2725
|
+
THEME_DARK as THEME_DARK7
|
|
2726
|
+
} from "@classic-homes/charts-core";
|
|
2727
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
1855
2728
|
echarts14.use([
|
|
1856
2729
|
EChartsCandlestickChart,
|
|
1857
2730
|
EChartsBarChart2,
|
|
1858
2731
|
GridComponent6,
|
|
1859
|
-
|
|
2732
|
+
TooltipComponent12,
|
|
1860
2733
|
TitleComponent12,
|
|
1861
2734
|
DataZoomComponent,
|
|
1862
2735
|
CanvasRenderer12
|
|
1863
2736
|
]);
|
|
1864
|
-
var CandlestickChart =
|
|
2737
|
+
var CandlestickChart = React17.forwardRef(
|
|
1865
2738
|
({
|
|
1866
2739
|
title,
|
|
1867
2740
|
description,
|
|
@@ -1874,12 +2747,19 @@ var CandlestickChart = React16.forwardRef(
|
|
|
1874
2747
|
animation = true,
|
|
1875
2748
|
showTooltip = true,
|
|
1876
2749
|
showVolume = false,
|
|
2750
|
+
xAxisConfig,
|
|
2751
|
+
yAxisConfig,
|
|
2752
|
+
tooltipFormatter,
|
|
2753
|
+
tooltipValueFormatter,
|
|
2754
|
+
option: optionOverride,
|
|
1877
2755
|
onClick,
|
|
1878
2756
|
class: className,
|
|
1879
2757
|
...props
|
|
1880
2758
|
}, ref) => {
|
|
1881
2759
|
const isEmpty = !data?.dates?.length || !data?.data?.length;
|
|
1882
|
-
const
|
|
2760
|
+
const currentTheme = useChartTheme(theme);
|
|
2761
|
+
const chartColors = getChartColors11(currentTheme);
|
|
2762
|
+
const option = React17.useMemo(() => {
|
|
1883
2763
|
if (isEmpty) return {};
|
|
1884
2764
|
const candlestickData = data.data.map((item) => [item.open, item.close, item.low, item.high]);
|
|
1885
2765
|
const seriesArr = [
|
|
@@ -1888,12 +2768,12 @@ var CandlestickChart = React16.forwardRef(
|
|
|
1888
2768
|
type: "candlestick",
|
|
1889
2769
|
data: candlestickData,
|
|
1890
2770
|
itemStyle: {
|
|
1891
|
-
color:
|
|
2771
|
+
color: chartColors.destructive,
|
|
1892
2772
|
// Up color (red for bearish in some markets)
|
|
1893
|
-
color0:
|
|
2773
|
+
color0: chartColors.success,
|
|
1894
2774
|
// Down color (green for bullish)
|
|
1895
|
-
borderColor:
|
|
1896
|
-
borderColor0:
|
|
2775
|
+
borderColor: chartColors.destructive,
|
|
2776
|
+
borderColor0: chartColors.success
|
|
1897
2777
|
}
|
|
1898
2778
|
}
|
|
1899
2779
|
];
|
|
@@ -1906,23 +2786,29 @@ var CandlestickChart = React16.forwardRef(
|
|
|
1906
2786
|
}
|
|
1907
2787
|
];
|
|
1908
2788
|
const xAxisArr = [
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
2789
|
+
buildAxis6(
|
|
2790
|
+
{
|
|
2791
|
+
type: "category",
|
|
2792
|
+
data: data.dates,
|
|
2793
|
+
boundaryGap: false,
|
|
2794
|
+
axisLine: { onZero: false },
|
|
2795
|
+
splitLine: { show: false },
|
|
2796
|
+
min: "dataMin",
|
|
2797
|
+
max: "dataMax"
|
|
2798
|
+
},
|
|
2799
|
+
xAxisConfig
|
|
2800
|
+
)
|
|
1918
2801
|
];
|
|
1919
2802
|
const yAxisArr = [
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
2803
|
+
buildAxis6(
|
|
2804
|
+
{
|
|
2805
|
+
scale: true,
|
|
2806
|
+
splitArea: {
|
|
2807
|
+
show: true
|
|
2808
|
+
}
|
|
2809
|
+
},
|
|
2810
|
+
yAxisConfig
|
|
2811
|
+
)
|
|
1926
2812
|
];
|
|
1927
2813
|
if (showVolume && data.volume) {
|
|
1928
2814
|
gridArr.push({
|
|
@@ -1959,62 +2845,86 @@ var CandlestickChart = React16.forwardRef(
|
|
|
1959
2845
|
yAxisIndex: 1,
|
|
1960
2846
|
data: data.volume,
|
|
1961
2847
|
itemStyle: {
|
|
1962
|
-
color:
|
|
2848
|
+
color: chartColors.mutedForeground
|
|
1963
2849
|
}
|
|
1964
2850
|
});
|
|
1965
2851
|
}
|
|
1966
|
-
return
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
2852
|
+
return mergeChartOption12(
|
|
2853
|
+
{
|
|
2854
|
+
tooltip: buildTooltip12(
|
|
2855
|
+
{
|
|
2856
|
+
trigger: "axis",
|
|
2857
|
+
axisPointer: {
|
|
2858
|
+
type: "cross"
|
|
2859
|
+
}
|
|
2860
|
+
},
|
|
2861
|
+
{
|
|
2862
|
+
show: showTooltip,
|
|
2863
|
+
formatter: tooltipFormatter,
|
|
2864
|
+
valueFormatter: tooltipValueFormatter
|
|
2865
|
+
}
|
|
2866
|
+
),
|
|
2867
|
+
grid: gridArr,
|
|
2868
|
+
xAxis: xAxisArr,
|
|
2869
|
+
yAxis: yAxisArr,
|
|
2870
|
+
dataZoom: [
|
|
2871
|
+
{
|
|
2872
|
+
type: "inside",
|
|
2873
|
+
start: 80,
|
|
2874
|
+
end: 100
|
|
2875
|
+
},
|
|
2876
|
+
{
|
|
2877
|
+
show: true,
|
|
2878
|
+
type: "slider",
|
|
2879
|
+
top: "90%",
|
|
2880
|
+
start: 80,
|
|
2881
|
+
end: 100
|
|
2882
|
+
}
|
|
2883
|
+
],
|
|
2884
|
+
series: seriesArr
|
|
2885
|
+
},
|
|
2886
|
+
optionOverride
|
|
2887
|
+
);
|
|
2888
|
+
}, [
|
|
2889
|
+
data,
|
|
2890
|
+
isEmpty,
|
|
2891
|
+
showTooltip,
|
|
2892
|
+
showVolume,
|
|
2893
|
+
title,
|
|
2894
|
+
chartColors,
|
|
2895
|
+
xAxisConfig,
|
|
2896
|
+
yAxisConfig,
|
|
2897
|
+
tooltipFormatter,
|
|
2898
|
+
tooltipValueFormatter,
|
|
2899
|
+
optionOverride
|
|
2900
|
+
]);
|
|
2901
|
+
const latest = useLatestRef({ onClick, data });
|
|
1993
2902
|
const { containerRef } = useChart({
|
|
1994
2903
|
option,
|
|
1995
|
-
theme,
|
|
2904
|
+
theme: currentTheme === THEME_DARK7 ? "dark" : "light",
|
|
1996
2905
|
animation,
|
|
1997
2906
|
onReady: (chart) => {
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2907
|
+
chart.on("click", (params) => {
|
|
2908
|
+
const { onClick: onClick2, data: data2 } = latest.current;
|
|
2909
|
+
if (!onClick2) return;
|
|
2910
|
+
const dataIndex = params.dataIndex || 0;
|
|
2911
|
+
const item = data2.data[dataIndex];
|
|
2912
|
+
if (!item) return;
|
|
2913
|
+
onClick2({
|
|
2914
|
+
type: params.type || "click",
|
|
2915
|
+
componentType: params.componentType || "series",
|
|
2916
|
+
date: data2.dates[dataIndex],
|
|
2917
|
+
open: item.open,
|
|
2918
|
+
close: item.close,
|
|
2919
|
+
high: item.high,
|
|
2920
|
+
low: item.low,
|
|
2921
|
+
volume: data2.volume?.[dataIndex]
|
|
2012
2922
|
});
|
|
2013
|
-
}
|
|
2923
|
+
});
|
|
2014
2924
|
}
|
|
2015
2925
|
});
|
|
2016
2926
|
const accessibilityDescription = description || (!isEmpty ? `${title}. Candlestick chart with ${data.dates.length} data points.` : void 0);
|
|
2017
|
-
return /* @__PURE__ */
|
|
2927
|
+
return /* @__PURE__ */ jsx17(
|
|
2018
2928
|
ChartContainer,
|
|
2019
2929
|
{
|
|
2020
2930
|
ref,
|
|
@@ -2027,7 +2937,7 @@ var CandlestickChart = React16.forwardRef(
|
|
|
2027
2937
|
emptyMessage,
|
|
2028
2938
|
className: cn(className),
|
|
2029
2939
|
...props,
|
|
2030
|
-
children: /* @__PURE__ */
|
|
2940
|
+
children: /* @__PURE__ */ jsx17("div", { ref: containerRef, className: "h-full w-full" })
|
|
2031
2941
|
}
|
|
2032
2942
|
);
|
|
2033
2943
|
}
|
|
@@ -2035,14 +2945,21 @@ var CandlestickChart = React16.forwardRef(
|
|
|
2035
2945
|
CandlestickChart.displayName = "CandlestickChart";
|
|
2036
2946
|
|
|
2037
2947
|
// src/components/extended/SankeyChart.tsx
|
|
2038
|
-
import * as
|
|
2948
|
+
import * as React18 from "react";
|
|
2039
2949
|
import * as echarts15 from "echarts/core";
|
|
2040
2950
|
import { SankeyChart as EChartsSankeyChart } from "echarts/charts";
|
|
2041
|
-
import { TooltipComponent as
|
|
2951
|
+
import { TooltipComponent as TooltipComponent13, TitleComponent as TitleComponent13 } from "echarts/components";
|
|
2042
2952
|
import { CanvasRenderer as CanvasRenderer13 } from "echarts/renderers";
|
|
2043
|
-
import {
|
|
2044
|
-
|
|
2045
|
-
|
|
2953
|
+
import {
|
|
2954
|
+
buildDataLabel as buildDataLabel11,
|
|
2955
|
+
buildTooltip as buildTooltip13,
|
|
2956
|
+
mergeChartOption as mergeChartOption13,
|
|
2957
|
+
nameLabelLookup as nameLabelLookup2,
|
|
2958
|
+
pointLabel as pointLabel5
|
|
2959
|
+
} from "@classic-homes/charts-core";
|
|
2960
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
2961
|
+
echarts15.use([EChartsSankeyChart, TooltipComponent13, TitleComponent13, CanvasRenderer13]);
|
|
2962
|
+
var SankeyChart = React18.forwardRef(
|
|
2046
2963
|
({
|
|
2047
2964
|
title,
|
|
2048
2965
|
description,
|
|
@@ -2055,68 +2972,97 @@ var SankeyChart = React17.forwardRef(
|
|
|
2055
2972
|
animation = true,
|
|
2056
2973
|
showTooltip = true,
|
|
2057
2974
|
orient = "horizontal",
|
|
2975
|
+
labelFormatter,
|
|
2976
|
+
tooltipFormatter,
|
|
2977
|
+
tooltipValueFormatter,
|
|
2978
|
+
option: optionOverride,
|
|
2058
2979
|
onClick,
|
|
2059
2980
|
class: className,
|
|
2060
2981
|
...props
|
|
2061
2982
|
}, ref) => {
|
|
2062
2983
|
const isEmpty = !data?.nodes?.length || !data?.links?.length;
|
|
2063
|
-
const option =
|
|
2984
|
+
const option = React18.useMemo(() => {
|
|
2064
2985
|
if (isEmpty) return {};
|
|
2065
|
-
return
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
{
|
|
2072
|
-
type: "sankey",
|
|
2073
|
-
orient,
|
|
2074
|
-
emphasis: {
|
|
2075
|
-
focus: "adjacency"
|
|
2076
|
-
},
|
|
2077
|
-
data: data.nodes.map((node) => ({
|
|
2078
|
-
name: node.name,
|
|
2079
|
-
itemStyle: node.color ? { color: node.color } : void 0
|
|
2080
|
-
})),
|
|
2081
|
-
links: data.links.map((link) => ({
|
|
2082
|
-
source: link.source,
|
|
2083
|
-
target: link.target,
|
|
2084
|
-
value: link.value
|
|
2085
|
-
})),
|
|
2086
|
-
lineStyle: {
|
|
2087
|
-
color: "gradient",
|
|
2088
|
-
curveness: 0.5
|
|
2986
|
+
return mergeChartOption13(
|
|
2987
|
+
{
|
|
2988
|
+
tooltip: buildTooltip13(
|
|
2989
|
+
{
|
|
2990
|
+
trigger: "item",
|
|
2991
|
+
triggerOn: "mousemove"
|
|
2089
2992
|
},
|
|
2090
|
-
|
|
2091
|
-
|
|
2993
|
+
{
|
|
2994
|
+
show: showTooltip,
|
|
2995
|
+
formatter: tooltipFormatter,
|
|
2996
|
+
valueFormatter: tooltipValueFormatter
|
|
2092
2997
|
}
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2998
|
+
),
|
|
2999
|
+
series: [
|
|
3000
|
+
{
|
|
3001
|
+
type: "sankey",
|
|
3002
|
+
orient,
|
|
3003
|
+
emphasis: {
|
|
3004
|
+
focus: "adjacency"
|
|
3005
|
+
},
|
|
3006
|
+
data: data.nodes.map((node) => ({
|
|
3007
|
+
name: node.name,
|
|
3008
|
+
itemStyle: node.color ? { color: node.color } : void 0,
|
|
3009
|
+
label: pointLabel5(node.label, labelFormatter)
|
|
3010
|
+
})),
|
|
3011
|
+
links: data.links.map((link) => ({
|
|
3012
|
+
source: link.source,
|
|
3013
|
+
target: link.target,
|
|
3014
|
+
value: link.value
|
|
3015
|
+
})),
|
|
3016
|
+
lineStyle: {
|
|
3017
|
+
color: "gradient",
|
|
3018
|
+
curveness: 0.5
|
|
3019
|
+
},
|
|
3020
|
+
label: buildDataLabel11(
|
|
3021
|
+
{
|
|
3022
|
+
position: orient === "horizontal" ? "right" : "bottom"
|
|
3023
|
+
},
|
|
3024
|
+
void 0,
|
|
3025
|
+
{ show: true, formatter: labelFormatter, getLabel: nameLabelLookup2(data.nodes) }
|
|
3026
|
+
)
|
|
3027
|
+
}
|
|
3028
|
+
]
|
|
3029
|
+
},
|
|
3030
|
+
optionOverride
|
|
3031
|
+
);
|
|
3032
|
+
}, [
|
|
3033
|
+
data,
|
|
3034
|
+
isEmpty,
|
|
3035
|
+
showTooltip,
|
|
3036
|
+
orient,
|
|
3037
|
+
labelFormatter,
|
|
3038
|
+
tooltipFormatter,
|
|
3039
|
+
tooltipValueFormatter,
|
|
3040
|
+
optionOverride
|
|
3041
|
+
]);
|
|
3042
|
+
const latest = useLatestRef({ onClick });
|
|
2097
3043
|
const { containerRef } = useChart({
|
|
2098
3044
|
option,
|
|
2099
3045
|
theme,
|
|
2100
3046
|
animation,
|
|
2101
3047
|
onReady: (chart) => {
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
3048
|
+
chart.on("click", (params) => {
|
|
3049
|
+
const { onClick: onClick2 } = latest.current;
|
|
3050
|
+
if (!onClick2) return;
|
|
3051
|
+
const isEdge = params.dataType === "edge";
|
|
3052
|
+
onClick2({
|
|
3053
|
+
type: params.type || "click",
|
|
3054
|
+
componentType: params.componentType || "series",
|
|
3055
|
+
dataType: isEdge ? "edge" : "node",
|
|
3056
|
+
name: params.name || "",
|
|
3057
|
+
value: isEdge ? params.value : void 0,
|
|
3058
|
+
source: isEdge ? params.data?.source : void 0,
|
|
3059
|
+
target: isEdge ? params.data?.target : void 0
|
|
2114
3060
|
});
|
|
2115
|
-
}
|
|
3061
|
+
});
|
|
2116
3062
|
}
|
|
2117
3063
|
});
|
|
2118
3064
|
const accessibilityDescription = description || (!isEmpty ? `${title}. Sankey diagram with ${data.nodes.length} nodes and ${data.links.length} links.` : void 0);
|
|
2119
|
-
return /* @__PURE__ */
|
|
3065
|
+
return /* @__PURE__ */ jsx18(
|
|
2120
3066
|
ChartContainer,
|
|
2121
3067
|
{
|
|
2122
3068
|
ref,
|
|
@@ -2129,7 +3075,7 @@ var SankeyChart = React17.forwardRef(
|
|
|
2129
3075
|
emptyMessage,
|
|
2130
3076
|
className: cn(className),
|
|
2131
3077
|
...props,
|
|
2132
|
-
children: /* @__PURE__ */
|
|
3078
|
+
children: /* @__PURE__ */ jsx18("div", { ref: containerRef, className: "h-full w-full" })
|
|
2133
3079
|
}
|
|
2134
3080
|
);
|
|
2135
3081
|
}
|
|
@@ -2142,6 +3088,7 @@ export {
|
|
|
2142
3088
|
ChartContainer,
|
|
2143
3089
|
ChartEmpty,
|
|
2144
3090
|
ChartError,
|
|
3091
|
+
ChartLegend,
|
|
2145
3092
|
ChartSkeleton,
|
|
2146
3093
|
DonutChart,
|
|
2147
3094
|
FunnelChart,
|
|
@@ -2156,6 +3103,7 @@ export {
|
|
|
2156
3103
|
cn,
|
|
2157
3104
|
registerClassicThemes,
|
|
2158
3105
|
useChart,
|
|
3106
|
+
useChartLegend,
|
|
2159
3107
|
useChartResize,
|
|
2160
3108
|
useChartTheme,
|
|
2161
3109
|
useReducedMotion
|