@spatika/react 1.3.1 → 1.5.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/AGENTS.md +6 -3
- package/README.md +1 -1
- package/dist/composites/EventCalendar.d.ts +13 -2
- package/dist/composites/EventCalendar.d.ts.map +1 -1
- package/dist/composites/EventCalendar.js +13 -27
- package/dist/composites/GlassCard.d.ts +1 -1
- package/dist/composites/RichTextEditor.d.ts +1 -4
- package/dist/composites/RichTextEditor.d.ts.map +1 -1
- package/dist/composites/RichTextEditor.js +12 -19
- package/dist/composites/SurfaceCard.d.ts +1 -1
- package/dist/composites/Tag.d.ts +2 -2
- package/dist/composites/cartesian-charts.d.ts +12 -2
- package/dist/composites/cartesian-charts.d.ts.map +1 -1
- package/dist/composites/cartesian-charts.js +27 -13
- package/dist/composites/chart-composition.d.ts +19 -1
- package/dist/composites/chart-composition.d.ts.map +1 -1
- package/dist/composites/chart-composition.js +124 -62
- package/dist/composites/chart-interaction.d.ts +81 -0
- package/dist/composites/chart-interaction.d.ts.map +1 -0
- package/dist/composites/chart-interaction.js +56 -0
- package/dist/composites/chart-ui.d.ts +8 -13
- package/dist/composites/chart-ui.d.ts.map +1 -1
- package/dist/composites/chart-ui.js +9 -6
- package/dist/composites/flow-charts.d.ts +6 -1
- package/dist/composites/flow-charts.d.ts.map +1 -1
- package/dist/composites/flow-charts.js +28 -14
- package/dist/composites/radial-charts.d.ts +11 -1
- package/dist/composites/radial-charts.d.ts.map +1 -1
- package/dist/composites/radial-charts.js +33 -14
- package/dist/composites/scheduler-ui.d.ts +14 -1
- package/dist/composites/scheduler-ui.d.ts.map +1 -1
- package/dist/composites/scheduler-ui.js +23 -2
- package/dist/index.d.ts +14 -26
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -14
- package/dist/lib/breakpoints.d.ts +17 -0
- package/dist/lib/breakpoints.d.ts.map +1 -0
- package/dist/lib/breakpoints.js +23 -0
- package/dist/lib/chips.d.ts +3 -0
- package/dist/lib/chips.d.ts.map +1 -1
- package/dist/lib/chips.js +10 -0
- package/dist/lib/create-theme.d.ts +162 -0
- package/dist/lib/create-theme.d.ts.map +1 -0
- package/dist/lib/create-theme.js +138 -0
- package/dist/lib/scheduler.d.ts +12 -0
- package/dist/lib/scheduler.d.ts.map +1 -1
- package/dist/lib/scheduler.js +24 -2
- package/dist/lib/themes.d.ts +17 -7
- package/dist/lib/themes.d.ts.map +1 -1
- package/dist/lib/themes.js +22 -8
- package/dist/lib/use-media-query.d.ts +9 -0
- package/dist/lib/use-media-query.d.ts.map +1 -1
- package/dist/lib/use-media-query.js +28 -1
- package/dist/primitives/Alert.d.ts +1 -1
- package/dist/primitives/Badge.d.ts +2 -2
- package/dist/primitives/Button.d.ts +2 -2
- package/dist/primitives/Container.d.ts +2 -2
- package/dist/primitives/Fab.d.ts +4 -4
- package/dist/primitives/Grid.d.ts +2 -1
- package/dist/primitives/Grid.d.ts.map +1 -1
- package/dist/primitives/Grid.js +10 -2
- package/dist/primitives/IconButton.d.ts +2 -2
- package/dist/primitives/NativeSelect.d.ts +10 -1
- package/dist/primitives/NativeSelect.d.ts.map +1 -1
- package/dist/primitives/NativeSelect.js +2 -2
- package/dist/primitives/ToggleButton.d.ts +1 -1
- package/dist/theme/SpatikaThemeProvider.d.ts +4 -5
- package/dist/theme/SpatikaThemeProvider.d.ts.map +1 -1
- package/dist/theme/SpatikaThemeProvider.js +28 -13
- package/package.json +4 -2
- package/skills/spatika-ui/SKILL.md +28 -5
- package/src/composites/EventCalendar.test.tsx +293 -0
- package/src/composites/EventCalendar.tsx +38 -27
- package/src/composites/RichTextEditor.test.tsx +51 -0
- package/src/composites/RichTextEditor.tsx +20 -84
- package/src/composites/chart-ui.test.tsx +21 -0
- package/src/composites/scheduler-ui.tsx +128 -26
- package/src/composites/scheduler.test.tsx +0 -219
- package/src/index.test.ts +10 -0
- package/src/index.ts +148 -65
- package/src/lib/breakpoints.test.ts +29 -0
- package/src/lib/breakpoints.ts +28 -0
- package/src/lib/chips.ts +16 -0
- package/src/lib/create-theme.test.ts +79 -0
- package/src/lib/create-theme.ts +249 -0
- package/src/lib/scheduler.test.ts +26 -0
- package/src/lib/scheduler.ts +36 -2
- package/src/lib/themes.test.ts +17 -0
- package/src/lib/themes.ts +43 -12
- package/src/lib/use-media-query.test.tsx +80 -0
- package/src/lib/use-media-query.ts +35 -1
- package/src/primitives/Grid.test.tsx +55 -0
- package/src/primitives/Grid.tsx +13 -3
- package/src/primitives/NativeSelect.test.tsx +28 -0
- package/src/primitives/NativeSelect.tsx +14 -4
- package/src/primitives/mui-more.test.tsx +17 -0
- package/src/theme/SpatikaThemeProvider.test.tsx +38 -0
- package/src/theme/SpatikaThemeProvider.tsx +43 -15
- package/src/composites/ChartDataGrid.test.tsx +0 -57
- package/src/composites/ChartDataGrid.tsx +0 -196
- package/src/composites/MapChart.test.tsx +0 -39
- package/src/composites/MapChart.tsx +0 -130
- package/src/composites/ScatterWebGL.test.tsx +0 -25
- package/src/composites/ScatterWebGL.tsx +0 -79
- package/src/composites/cartesian-charts.test.tsx +0 -52
- package/src/composites/cartesian-charts.tsx +0 -1287
- package/src/composites/chart-composition.test.tsx +0 -53
- package/src/composites/chart-composition.tsx +0 -898
- package/src/composites/chart-ui.tsx +0 -328
- package/src/composites/charts-3d.test.tsx +0 -25
- package/src/composites/charts-3d.tsx +0 -318
- package/src/composites/charts.test.tsx +0 -254
- package/src/composites/flow-charts.test.tsx +0 -79
- package/src/composites/flow-charts.tsx +0 -607
- package/src/composites/radial-charts.test.tsx +0 -74
- package/src/composites/radial-charts.tsx +0 -617
- package/src/lib/chart-export.test.ts +0 -20
- package/src/lib/chart-export.ts +0 -99
- package/src/lib/charts-platform.test.ts +0 -93
- package/src/lib/charts.test.ts +0 -132
- package/src/lib/charts.ts +0 -1021
- package/src/lib/geo.test.ts +0 -42
- package/src/lib/geo.ts +0 -138
- package/src/lib/iso.test.ts +0 -22
- package/src/lib/iso.ts +0 -102
- package/src/lib/webgl-scatter.test.ts +0 -36
- package/src/lib/webgl-scatter.ts +0 -230
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { createContext, useCallback, useContext, useEffect, useId, useMemo, useRef, useState, } from "react";
|
|
3
3
|
import { Download, Maximize2, Move, SquareDashedMousePointer, ZoomIn, ZoomOut } from "lucide-react";
|
|
4
4
|
import { cn } from "../lib/cn";
|
|
@@ -6,6 +6,7 @@ import { exportChart } from "../lib/chart-export";
|
|
|
6
6
|
import { DEFAULT_CHART_MARGIN, DEFAULT_ZOOM, applyZoom, areaPath, axisDataFromDataset, bandScale, chartColor, clampZoom, extent, formatAxisValue, formatChartNumber, inferScaleType, linePath, linearScale, markOpacity, niceTicks, panZoom, plotBox, pointScale, rangeAreaPath, roundedRectPath, seriesDataFromDataset, stackSeries, wheelZoom, zoomFromBrush, } from "../lib/charts";
|
|
7
7
|
import { IconButton } from "../primitives/IconButton";
|
|
8
8
|
import { CartesianGrid, CategoryAxis, ChartLegend, ChartTooltip, ValueAxis, categoryLabels, formatSeriesValue, resolveMargin, seriesMeta, } from "./chart-ui";
|
|
9
|
+
import { bindChartMark, seriesItemColor, } from "./chart-interaction";
|
|
9
10
|
const ChartContext = createContext(null);
|
|
10
11
|
export function useChartContext() {
|
|
11
12
|
const value = useContext(ChartContext);
|
|
@@ -45,6 +46,7 @@ function resolveSeries(series, dataset, colors) {
|
|
|
45
46
|
type,
|
|
46
47
|
label: item.label ?? item.dataKey ?? item.id ?? `Series ${index + 1}`,
|
|
47
48
|
color: item.color ?? chartColor(index, colors),
|
|
49
|
+
itemColors: item.itemColors,
|
|
48
50
|
data,
|
|
49
51
|
stack: item.stack,
|
|
50
52
|
yAxisId: item.yAxisId,
|
|
@@ -104,12 +106,13 @@ function numericDomain(series, stacked, axis) {
|
|
|
104
106
|
function leftId(axis) {
|
|
105
107
|
return axis?.id ?? "left";
|
|
106
108
|
}
|
|
107
|
-
export function ChartContainer({ slot = "chart-container", className, width, height = 280, margin, dataset, xAxis, yAxis, series, colors, hideLegend, hideGrid, stacked = false, barGapRatio = 0.15, borderRadius = 6, zoom, defaultZoom, onZoomChange, showToolbar, highlightScope = "item", selected, animated = true, locale, children, "aria-label": ariaLabel, }) {
|
|
109
|
+
export function ChartContainer({ slot = "chart-container", className, width, height = 280, margin, dataset, xAxis, yAxis, series, colors, hideLegend, hideGrid, stacked = false, barGapRatio = 0.15, borderRadius = 6, zoom, defaultZoom, onZoomChange, showToolbar, highlightScope = "item", selected, animated = true, locale, children, "aria-label": ariaLabel, fillHeight = false, onItemClick, renderTooltip, renderMark, referenceLines, showLabels = false, }) {
|
|
108
110
|
const surfaceRef = useRef(null);
|
|
109
111
|
const svgRef = useRef(null);
|
|
110
112
|
const clipPathId = `spk-chart-clip-${useId().replace(/:/g, "")}`;
|
|
111
113
|
const measured = useElementSize(surfaceRef, width ?? 320, height);
|
|
112
114
|
const plotWidth = width ?? measured.width;
|
|
115
|
+
const plotHeight = fillHeight ? measured.height : height;
|
|
113
116
|
const hasRight = yAxis?.some((axis) => axis.position === "right");
|
|
114
117
|
const m = resolveMargin(margin ?? (hasRight ? { ...DEFAULT_CHART_MARGIN, right: 48 } : undefined));
|
|
115
118
|
const resolved = useMemo(() => resolveSeries(series, dataset, colors), [series, dataset, colors]);
|
|
@@ -148,7 +151,7 @@ export function ChartContainer({ slot = "chart-container", className, width, hei
|
|
|
148
151
|
const [hover, setHover] = useState(null);
|
|
149
152
|
const [brush, setBrush] = useState(null);
|
|
150
153
|
const activeHighlight = selected ?? highlighted;
|
|
151
|
-
const plot = plotBox(plotWidth,
|
|
154
|
+
const plot = plotBox(plotWidth, plotHeight, m);
|
|
152
155
|
const visible = resolved.filter((item) => !hidden.has(item.id));
|
|
153
156
|
const leftSeries = visible.filter((item) => !item.yAxisId || item.yAxisId === (leftAxis?.id ?? item.yAxisId));
|
|
154
157
|
const rightSeries = visible.filter((item) => rightAxis && item.yAxisId === rightAxis.id);
|
|
@@ -192,7 +195,7 @@ export function ChartContainer({ slot = "chart-container", className, width, hei
|
|
|
192
195
|
const ctx = {
|
|
193
196
|
slot,
|
|
194
197
|
width: plotWidth,
|
|
195
|
-
height,
|
|
198
|
+
height: plotHeight,
|
|
196
199
|
margin: m,
|
|
197
200
|
plot,
|
|
198
201
|
categories,
|
|
@@ -229,15 +232,19 @@ export function ChartContainer({ slot = "chart-container", className, width, hei
|
|
|
229
232
|
brush,
|
|
230
233
|
setBrush,
|
|
231
234
|
exportChart: doExport,
|
|
235
|
+
onItemClick,
|
|
236
|
+
renderMark,
|
|
237
|
+
referenceLines,
|
|
238
|
+
showLabels,
|
|
232
239
|
};
|
|
233
240
|
const legend = seriesMeta(resolved, colors);
|
|
234
241
|
const label = ariaLabel ??
|
|
235
242
|
`Chart of ${resolved.map((item) => item.label).join(", ")}`;
|
|
236
|
-
return (_jsx(ChartContext.Provider, { value: ctx, children: _jsxs("div", { "data-slot": slot, className: cn("spk-chart", animated && "spk-chart--animated", className), role: "img", "aria-label": label, children: [showToolbar ? _jsx(ChartsToolbar, {}) : null, hideLegend ? null : (_jsx(ChartLegend, { items: legend, hiddenIds: hidden, onToggle: toggleSeries })), _jsxs("div", { ref: surfaceRef, className: "spk-chart-surface", style: { height }, children: [plotWidth > 0 ? children ?? _jsx(DefaultChartSurface, {}) : null, _jsx(ChartTooltip, { hover: hover, boundsWidth: plotWidth })] }), _jsx(ChartA11yTable, {})] }) }));
|
|
243
|
+
return (_jsx(ChartContext.Provider, { value: ctx, children: _jsxs("div", { "data-slot": slot, className: cn("spk-chart", animated && "spk-chart--animated", fillHeight && "spk-chart--fill", className), role: "img", "aria-label": label, children: [showToolbar ? _jsx(ChartsToolbar, {}) : null, hideLegend ? null : (_jsx(ChartLegend, { items: legend, hiddenIds: hidden, onToggle: toggleSeries })), _jsxs("div", { ref: surfaceRef, className: "spk-chart-surface", style: fillHeight ? undefined : { height: plotHeight }, children: [plotWidth > 0 && plotHeight > 0 ? children ?? _jsx(DefaultChartSurface, {}) : null, _jsx(ChartTooltip, { hover: hover, boundsWidth: plotWidth, render: renderTooltip })] }), _jsx(ChartA11yTable, {})] }) }));
|
|
237
244
|
}
|
|
238
245
|
function DefaultChartSurface() {
|
|
239
246
|
const { rightAxis } = useChartContext();
|
|
240
|
-
return (_jsxs(ChartSurface, { children: [_jsx(ChartsGrid, {}), _jsx(BarPlot, {}), _jsx(AreaPlot, {}), _jsx(LinePlot, {}), _jsx(ScatterPlot, {}), _jsx(ChartsXAxis, {}), _jsx(ChartsYAxis, {}), rightAxis ? _jsx(ChartsYAxis, { position: "right" }) : null, _jsx(ChartsBrush, {})] }));
|
|
247
|
+
return (_jsxs(ChartSurface, { children: [_jsx(ChartsGrid, {}), _jsx(BarPlot, {}), _jsx(AreaPlot, {}), _jsx(LinePlot, {}), _jsx(ScatterPlot, {}), _jsx(ChartsXAxis, {}), _jsx(ChartsYAxis, {}), rightAxis ? _jsx(ChartsYAxis, { position: "right" }) : null, _jsx(ChartsReferenceLine, {}), _jsx(ChartsBrush, {})] }));
|
|
241
248
|
}
|
|
242
249
|
export function ChartSurface({ children, className }) {
|
|
243
250
|
const ctx = useChartContext();
|
|
@@ -342,38 +349,53 @@ export function BarPlot() {
|
|
|
342
349
|
const gap = n > 1 ? ctx.bandwidth * ctx.barGapRatio : 0;
|
|
343
350
|
const barW = (ctx.bandwidth - gap * (n - 1)) / n;
|
|
344
351
|
const zero = ctx.yAt(0);
|
|
345
|
-
return (_jsx(PlotClip, { slot: "bar-plot", children: bars.map((item, s) => item.data.map((value, i) => {
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
ctx.
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
352
|
+
return (_jsxs(_Fragment, { children: [_jsx(PlotClip, { slot: "bar-plot", children: bars.map((item, s) => item.data.map((value, i) => {
|
|
353
|
+
if (value == null)
|
|
354
|
+
return null;
|
|
355
|
+
let x = ctx.xAt(i);
|
|
356
|
+
let y1;
|
|
357
|
+
let y2;
|
|
358
|
+
if (stacks) {
|
|
359
|
+
const seg = stacks[s][i];
|
|
360
|
+
y1 = ctx.yAt(seg.end, item.yAxisId);
|
|
361
|
+
y2 = ctx.yAt(seg.start, item.yAxisId);
|
|
362
|
+
}
|
|
363
|
+
else {
|
|
364
|
+
x = ctx.xAt(i) + s * (barW + gap);
|
|
365
|
+
y1 = ctx.yAt(value, item.yAxisId);
|
|
366
|
+
y2 = zero;
|
|
367
|
+
}
|
|
368
|
+
const y = Math.min(y1, y2);
|
|
369
|
+
const h = Math.max(1, Math.abs(y2 - y1));
|
|
370
|
+
const opacity = markOpacity(ctx.highlightScope, ctx.highlighted, item.id, i);
|
|
371
|
+
const color = seriesItemColor(item.color, item.itemColors, i);
|
|
372
|
+
const event = {
|
|
373
|
+
seriesId: item.id,
|
|
374
|
+
seriesLabel: item.label,
|
|
375
|
+
dataIndex: i,
|
|
376
|
+
category: ctx.categories[i] ?? i,
|
|
377
|
+
value,
|
|
378
|
+
color,
|
|
379
|
+
};
|
|
380
|
+
return (_jsx("path", { d: roundedRectPath(x, y, ctx.stacked ? ctx.bandwidth : barW, h, ctx.borderRadius), fill: color, opacity: opacity, ...bindChartMark({
|
|
381
|
+
event,
|
|
382
|
+
hover: {
|
|
383
|
+
title: String(ctx.categories[i]),
|
|
384
|
+
items: [{ color, label: item.label, value: formatSeriesValue(value) }],
|
|
385
|
+
},
|
|
386
|
+
onItemClick: ctx.onItemClick,
|
|
387
|
+
setHover: ctx.setHover,
|
|
388
|
+
clearHover: () => ctx.setHover(null),
|
|
389
|
+
onHighlight: ctx.setHighlighted,
|
|
390
|
+
}) }, `${item.id}-${i}`));
|
|
391
|
+
})) }), ctx.showLabels ? (_jsx("g", { "data-slot": "bar-labels", pointerEvents: "none", children: bars.map((item, s) => item.data.map((value, i) => {
|
|
392
|
+
if (value == null)
|
|
393
|
+
return null;
|
|
394
|
+
const x = ctx.stacked ? ctx.xAt(i) : ctx.xAt(i) + s * (barW + gap);
|
|
395
|
+
const y = ctx.yAt(value, item.yAxisId);
|
|
396
|
+
const width = ctx.stacked ? ctx.bandwidth : barW;
|
|
397
|
+
return (_jsx("text", { className: "spk-chart-label", x: x + width / 2, y: y - 4, textAnchor: "middle", children: formatSeriesValue(value) }, `${item.id}-${i}-label`));
|
|
398
|
+
})) })) : null] }));
|
|
377
399
|
}
|
|
378
400
|
function LineLikePlot({ types, slot }) {
|
|
379
401
|
const ctx = useChartContext();
|
|
@@ -403,18 +425,31 @@ function LineLikePlot({ types, slot }) {
|
|
|
403
425
|
return (_jsxs("g", { opacity: opacity, children: [fill ? (_jsx("path", { d: baseline
|
|
404
426
|
? rangeAreaPath(pts, baseline, item.curve)
|
|
405
427
|
: areaPath(pts, ctx.plot.bottom, item.curve), fill: item.color, opacity: baseline ? 0.88 : 0.18, className: "spk-chart-mark" })) : null, _jsx("path", { d: linePath(pts, item.curve), fill: "none", stroke: item.color, strokeWidth: 2.25, strokeLinejoin: "round", strokeLinecap: "round", className: "spk-chart-mark" }), item.showMark
|
|
406
|
-
? pts.map((pt) =>
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
428
|
+
? pts.map((pt) => {
|
|
429
|
+
const color = seriesItemColor(item.color, item.itemColors, pt.i);
|
|
430
|
+
const event = {
|
|
431
|
+
seriesId: item.id,
|
|
432
|
+
seriesLabel: item.label,
|
|
433
|
+
dataIndex: pt.i,
|
|
434
|
+
category: ctx.categories[pt.i] ?? pt.i,
|
|
435
|
+
value: pt.value,
|
|
436
|
+
color,
|
|
437
|
+
};
|
|
438
|
+
const mark = ctx.renderMark?.({ ...event, x: pt.x, y: pt.y }) ?? (_jsx("circle", { cx: pt.x, cy: pt.y, r: 3.4, fill: color }));
|
|
439
|
+
return (_jsx("g", { ...bindChartMark({
|
|
440
|
+
event,
|
|
441
|
+
hover: {
|
|
442
|
+
x: pt.x,
|
|
443
|
+
y: pt.y,
|
|
444
|
+
title: String(ctx.categories[pt.i]),
|
|
445
|
+
items: [{ color, label: item.label, value: formatSeriesValue(pt.value) }],
|
|
446
|
+
},
|
|
447
|
+
onItemClick: ctx.onItemClick,
|
|
448
|
+
setHover: ctx.setHover,
|
|
449
|
+
clearHover: () => ctx.setHover(null),
|
|
450
|
+
onHighlight: ctx.setHighlighted,
|
|
451
|
+
}), children: mark }, pt.i));
|
|
452
|
+
})
|
|
418
453
|
: null] }, item.id));
|
|
419
454
|
}) }));
|
|
420
455
|
}
|
|
@@ -441,21 +476,29 @@ export function ScatterPlot() {
|
|
|
441
476
|
const cx = applyZoom(xScale(point.x), ctx.plot.left, ctx.plot.iw, ctx.zoom.x);
|
|
442
477
|
const cy = ctx.yAt(point.y, item.yAxisId);
|
|
443
478
|
const opacity = markOpacity(ctx.highlightScope, ctx.highlighted, item.id, i);
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
479
|
+
const color = seriesItemColor(item.color, item.itemColors, i);
|
|
480
|
+
const event = {
|
|
481
|
+
seriesId: item.id,
|
|
482
|
+
seriesLabel: item.label,
|
|
483
|
+
dataIndex: i,
|
|
484
|
+
category: point.id ?? i,
|
|
485
|
+
value: point.y,
|
|
486
|
+
color,
|
|
487
|
+
};
|
|
488
|
+
return (_jsx("circle", { cx: cx, cy: cy, r: 4.5, fill: color, opacity: opacity, ...bindChartMark({
|
|
489
|
+
event,
|
|
490
|
+
hover: {
|
|
449
491
|
title: item.label,
|
|
450
492
|
items: [
|
|
451
|
-
{ color
|
|
452
|
-
{ color
|
|
493
|
+
{ color, label: "x", value: formatChartNumber(point.x, ctx.locale) },
|
|
494
|
+
{ color, label: "y", value: formatChartNumber(point.y, ctx.locale) },
|
|
453
495
|
],
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
ctx.
|
|
457
|
-
ctx.setHover(null)
|
|
458
|
-
|
|
496
|
+
},
|
|
497
|
+
onItemClick: ctx.onItemClick,
|
|
498
|
+
setHover: ctx.setHover,
|
|
499
|
+
clearHover: () => ctx.setHover(null),
|
|
500
|
+
onHighlight: ctx.setHighlighted,
|
|
501
|
+
}) }, `${item.id}-${point.id ?? i}`));
|
|
459
502
|
});
|
|
460
503
|
}) }));
|
|
461
504
|
}
|
|
@@ -467,6 +510,25 @@ export function ChartsBrush() {
|
|
|
467
510
|
const width = Math.abs(brush.x1 - brush.x0);
|
|
468
511
|
return (_jsx("rect", { "data-slot": "chart-brush", className: "spk-chart-brush", x: x, y: plot.top, width: width, height: plot.ih }));
|
|
469
512
|
}
|
|
513
|
+
/** Horizontal (value) or vertical (category index) guide overlay. */
|
|
514
|
+
export function ChartsReferenceLine() {
|
|
515
|
+
const { referenceLines, yAt, xAt, plot, bandwidth } = useChartContext();
|
|
516
|
+
if (!referenceLines?.length)
|
|
517
|
+
return null;
|
|
518
|
+
return (_jsx("g", { "data-slot": "chart-reference-lines", children: referenceLines.map((line, index) => {
|
|
519
|
+
const color = line.color ?? "var(--primary)";
|
|
520
|
+
const dash = line.strokeDasharray ?? "4 4";
|
|
521
|
+
if (line.y != null) {
|
|
522
|
+
const y = yAt(line.y, line.yAxisId);
|
|
523
|
+
return (_jsxs("g", { children: [_jsx("line", { className: "spk-chart-ref-line", x1: plot.left, x2: plot.right, y1: y, y2: y, stroke: color, strokeDasharray: dash }), line.label ? (_jsx("text", { className: "spk-chart-ref-label", x: plot.right - 4, y: y - 4, textAnchor: "end", children: line.label })) : null] }, `y-${index}`));
|
|
524
|
+
}
|
|
525
|
+
if (line.xIndex != null) {
|
|
526
|
+
const x = xAt(line.xIndex) + bandwidth / 2;
|
|
527
|
+
return (_jsxs("g", { children: [_jsx("line", { className: "spk-chart-ref-line", x1: x, x2: x, y1: plot.top, y2: plot.bottom, stroke: color, strokeDasharray: dash }), line.label ? (_jsx("text", { className: "spk-chart-ref-label", x: x + 4, y: plot.top + 12, children: line.label })) : null] }, `x-${index}`));
|
|
528
|
+
}
|
|
529
|
+
return null;
|
|
530
|
+
}) }));
|
|
531
|
+
}
|
|
470
532
|
export function ChartsLegend() {
|
|
471
533
|
const { series, hidden, toggleSeries } = useChartContext();
|
|
472
534
|
return (_jsx(ChartLegend, { items: series.map((item) => ({ id: item.id, label: item.label, color: item.color })), hiddenIds: hidden, onToggle: toggleSeries }));
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
export type ChartTooltipItem = {
|
|
3
|
+
color: string;
|
|
4
|
+
label: string;
|
|
5
|
+
value: string;
|
|
6
|
+
};
|
|
7
|
+
export type ChartHover = {
|
|
8
|
+
x: number;
|
|
9
|
+
y: number;
|
|
10
|
+
title?: string;
|
|
11
|
+
items: ChartTooltipItem[];
|
|
12
|
+
dataIndex?: number;
|
|
13
|
+
seriesId?: string;
|
|
14
|
+
category?: string | number | Date;
|
|
15
|
+
} | null;
|
|
16
|
+
/** Payload fired when a chart mark (bar, slice, point, cell) is activated. */
|
|
17
|
+
export type ChartItemEvent = {
|
|
18
|
+
seriesId: string;
|
|
19
|
+
seriesLabel: string;
|
|
20
|
+
dataIndex: number;
|
|
21
|
+
category: string | number | Date;
|
|
22
|
+
value: number | null;
|
|
23
|
+
color: string;
|
|
24
|
+
};
|
|
25
|
+
/** Geometry plus item identity, used by `renderMark` on line and area series. */
|
|
26
|
+
export type ChartMarkRenderContext = ChartItemEvent & {
|
|
27
|
+
x: number;
|
|
28
|
+
y: number;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Overlay guide on a cartesian plot.
|
|
32
|
+
* Set `y` for a horizontal value line, or `xIndex` for a vertical category line.
|
|
33
|
+
*/
|
|
34
|
+
export type ChartReferenceLine = {
|
|
35
|
+
y?: number;
|
|
36
|
+
xIndex?: number;
|
|
37
|
+
yAxisId?: string;
|
|
38
|
+
color?: string;
|
|
39
|
+
label?: string;
|
|
40
|
+
strokeDasharray?: string;
|
|
41
|
+
};
|
|
42
|
+
export type ChartTooltipRenderer = (hover: NonNullable<ChartHover>) => ReactNode;
|
|
43
|
+
export type ChartMarkBind = {
|
|
44
|
+
className: string;
|
|
45
|
+
role?: "button";
|
|
46
|
+
tabIndex?: number;
|
|
47
|
+
"aria-label"?: string;
|
|
48
|
+
onClick?: (event: {
|
|
49
|
+
stopPropagation(): void;
|
|
50
|
+
}) => void;
|
|
51
|
+
onKeyDown?: (event: {
|
|
52
|
+
key: string;
|
|
53
|
+
preventDefault(): void;
|
|
54
|
+
}) => void;
|
|
55
|
+
onMouseEnter?: (event: {
|
|
56
|
+
nativeEvent: {
|
|
57
|
+
offsetX: number;
|
|
58
|
+
offsetY: number;
|
|
59
|
+
};
|
|
60
|
+
}) => void;
|
|
61
|
+
onMouseLeave?: () => void;
|
|
62
|
+
};
|
|
63
|
+
/** Per-category color, falling back to the series token. */
|
|
64
|
+
export declare function seriesItemColor(color: string, itemColors: Array<string | null | undefined> | undefined, index: number): string;
|
|
65
|
+
export declare function chartItemAriaLabel(event: ChartItemEvent): string;
|
|
66
|
+
/**
|
|
67
|
+
* Pointer, keyboard, and hover bindings for an SVG mark.
|
|
68
|
+
* Adds a button role only when `onItemClick` is set so legends stay the sole named buttons.
|
|
69
|
+
*/
|
|
70
|
+
export declare function bindChartMark({ event, hover, onItemClick, setHover, clearHover, onHighlight, }: {
|
|
71
|
+
event: ChartItemEvent;
|
|
72
|
+
hover: Pick<NonNullable<ChartHover>, "title" | "items"> & Partial<NonNullable<ChartHover>>;
|
|
73
|
+
onItemClick?: (event: ChartItemEvent) => void;
|
|
74
|
+
setHover: (hover: ChartHover) => void;
|
|
75
|
+
clearHover: () => void;
|
|
76
|
+
onHighlight?: (item: {
|
|
77
|
+
seriesId: string;
|
|
78
|
+
dataIndex: number;
|
|
79
|
+
} | null) => void;
|
|
80
|
+
}): ChartMarkBind;
|
|
81
|
+
//# sourceMappingURL=chart-interaction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chart-interaction.d.ts","sourceRoot":"","sources":["../../src/composites/chart-interaction.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;CACnC,GAAG,IAAI,CAAC;AAET,8EAA8E;AAC9E,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACjC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,iFAAiF;AACjF,MAAM,MAAM,sBAAsB,GAAG,cAAc,GAAG;IACpD,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE,WAAW,CAAC,UAAU,CAAC,KAAK,SAAS,CAAC;AAEjF,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,eAAe,IAAI,IAAI,CAAA;KAAE,KAAK,IAAI,CAAC;IACvD,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,cAAc,IAAI,IAAI,CAAA;KAAE,KAAK,IAAI,CAAC;IACrE,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,WAAW,EAAE;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,KAAK,IAAI,CAAC;IACtF,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B,CAAC;AAEF,4DAA4D;AAC5D,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,SAAS,EACxD,KAAK,EAAE,MAAM,GACZ,MAAM,CAER;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAMhE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,KAAK,EACL,WAAW,EACX,QAAQ,EACR,UAAU,EACV,WAAW,GACZ,EAAE;IACD,KAAK,EAAE,cAAc,CAAC;IACtB,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC;IAC3F,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAC9C,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,KAAK,IAAI,CAAC;CAC9E,GAAG,aAAa,CAuChB"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { cn } from "../lib/cn";
|
|
2
|
+
/** Per-category color, falling back to the series token. */
|
|
3
|
+
export function seriesItemColor(color, itemColors, index) {
|
|
4
|
+
return itemColors?.[index] || color;
|
|
5
|
+
}
|
|
6
|
+
export function chartItemAriaLabel(event) {
|
|
7
|
+
const category = String(event.category);
|
|
8
|
+
if (event.seriesLabel && event.seriesLabel !== category) {
|
|
9
|
+
return `${event.seriesLabel} ${category}`;
|
|
10
|
+
}
|
|
11
|
+
return category;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Pointer, keyboard, and hover bindings for an SVG mark.
|
|
15
|
+
* Adds a button role only when `onItemClick` is set so legends stay the sole named buttons.
|
|
16
|
+
*/
|
|
17
|
+
export function bindChartMark({ event, hover, onItemClick, setHover, clearHover, onHighlight, }) {
|
|
18
|
+
const clickable = Boolean(onItemClick);
|
|
19
|
+
const applyHover = (x, y) => {
|
|
20
|
+
onHighlight?.({ seriesId: event.seriesId, dataIndex: event.dataIndex });
|
|
21
|
+
setHover({
|
|
22
|
+
x: hover.x ?? x,
|
|
23
|
+
y: hover.y ?? y,
|
|
24
|
+
title: hover.title,
|
|
25
|
+
items: hover.items,
|
|
26
|
+
dataIndex: event.dataIndex,
|
|
27
|
+
seriesId: event.seriesId,
|
|
28
|
+
category: event.category,
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
return {
|
|
32
|
+
className: cn("spk-chart-mark", clickable && "spk-chart-mark--interactive"),
|
|
33
|
+
role: clickable ? "button" : undefined,
|
|
34
|
+
tabIndex: clickable ? 0 : undefined,
|
|
35
|
+
"aria-label": clickable ? chartItemAriaLabel(event) : undefined,
|
|
36
|
+
onClick: clickable
|
|
37
|
+
? (native) => {
|
|
38
|
+
native.stopPropagation();
|
|
39
|
+
onItemClick?.(event);
|
|
40
|
+
}
|
|
41
|
+
: undefined,
|
|
42
|
+
onKeyDown: clickable
|
|
43
|
+
? (native) => {
|
|
44
|
+
if (native.key === "Enter" || native.key === " ") {
|
|
45
|
+
native.preventDefault();
|
|
46
|
+
onItemClick?.(event);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
: undefined,
|
|
50
|
+
onMouseEnter: (native) => applyHover(native.nativeEvent.offsetX, native.nativeEvent.offsetY),
|
|
51
|
+
onMouseLeave: () => {
|
|
52
|
+
onHighlight?.(null);
|
|
53
|
+
clearHover();
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
@@ -1,31 +1,25 @@
|
|
|
1
1
|
import { type ReactNode } from "react";
|
|
2
2
|
import { type ChartAxisConfig, type ChartMargin } from "../lib/charts";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
label: string;
|
|
6
|
-
value: string;
|
|
7
|
-
};
|
|
3
|
+
import { type ChartHover, type ChartTooltipRenderer } from "./chart-interaction";
|
|
4
|
+
export type { ChartHover, ChartTooltipItem } from "./chart-interaction";
|
|
8
5
|
export type ChartLegendItem = {
|
|
9
6
|
id: string;
|
|
10
7
|
label: string;
|
|
11
8
|
color: string;
|
|
12
9
|
};
|
|
13
|
-
export type ChartHover = {
|
|
14
|
-
x: number;
|
|
15
|
-
y: number;
|
|
16
|
-
title?: string;
|
|
17
|
-
items: ChartTooltipItem[];
|
|
18
|
-
} | null;
|
|
19
10
|
export type ChartFrameProps = {
|
|
20
11
|
slot: string;
|
|
21
12
|
className?: string;
|
|
22
13
|
width?: number;
|
|
23
14
|
height?: number;
|
|
15
|
+
/** When true, plot height follows the parent instead of the numeric `height`. */
|
|
16
|
+
fillHeight?: boolean;
|
|
24
17
|
margin?: ChartMargin;
|
|
25
18
|
legend?: ChartLegendItem[];
|
|
26
19
|
hiddenIds?: Set<string>;
|
|
27
20
|
onToggleSeries?: (id: string) => void;
|
|
28
21
|
hover?: ChartHover;
|
|
22
|
+
renderTooltip?: ChartTooltipRenderer;
|
|
29
23
|
"aria-label"?: string;
|
|
30
24
|
children: (plot: {
|
|
31
25
|
width: number;
|
|
@@ -34,15 +28,16 @@ export type ChartFrameProps = {
|
|
|
34
28
|
}) => ReactNode;
|
|
35
29
|
};
|
|
36
30
|
export declare function resolveMargin(margin?: ChartMargin): Required<ChartMargin>;
|
|
37
|
-
export declare function ChartFrame({ slot, className, width, height, margin, legend, hiddenIds, onToggleSeries, hover, "aria-label": ariaLabel, children, }: ChartFrameProps): import("react").JSX.Element;
|
|
31
|
+
export declare function ChartFrame({ slot, className, width, height, fillHeight, margin, legend, hiddenIds, onToggleSeries, hover, renderTooltip, "aria-label": ariaLabel, children, }: ChartFrameProps): import("react").JSX.Element;
|
|
38
32
|
export declare function ChartLegend({ items, hiddenIds, onToggle, }: {
|
|
39
33
|
items: ChartLegendItem[];
|
|
40
34
|
hiddenIds?: Set<string>;
|
|
41
35
|
onToggle?: (id: string) => void;
|
|
42
36
|
}): import("react").JSX.Element;
|
|
43
|
-
export declare function ChartTooltip({ hover, boundsWidth, }: {
|
|
37
|
+
export declare function ChartTooltip({ hover, boundsWidth, render, }: {
|
|
44
38
|
hover: ChartHover;
|
|
45
39
|
boundsWidth: number;
|
|
40
|
+
render?: ChartTooltipRenderer;
|
|
46
41
|
}): import("react").JSX.Element | null;
|
|
47
42
|
export declare function CartesianGrid({ ticks, scale, left, right, top, bottom, }: {
|
|
48
43
|
ticks: number[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chart-ui.d.ts","sourceRoot":"","sources":["../../src/composites/chart-ui.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,SAAS,EAEf,MAAM,OAAO,CAAC;AAEf,OAAO,EAKL,KAAK,eAAe,EACpB,KAAK,WAAW,EACjB,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"chart-ui.d.ts","sourceRoot":"","sources":["../../src/composites/chart-ui.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useRef, useState, } from "react";
|
|
3
3
|
import { cn } from "../lib/cn";
|
|
4
4
|
import { DEFAULT_CHART_MARGIN, chartColor, formatAxisValue, formatChartNumber, } from "../lib/charts";
|
|
@@ -31,22 +31,25 @@ function useElementSize(ref, fallbackWidth, fallbackHeight) {
|
|
|
31
31
|
}, [fallbackWidth, fallbackHeight, ref]);
|
|
32
32
|
return size;
|
|
33
33
|
}
|
|
34
|
-
export function ChartFrame({ slot, className, width, height = 280, margin, legend, hiddenIds, onToggleSeries, hover, "aria-label": ariaLabel, children, }) {
|
|
34
|
+
export function ChartFrame({ slot, className, width, height = 280, fillHeight = false, margin, legend, hiddenIds, onToggleSeries, hover, renderTooltip, "aria-label": ariaLabel, children, }) {
|
|
35
35
|
const surfaceRef = useRef(null);
|
|
36
36
|
const measured = useElementSize(surfaceRef, width ?? 320, height);
|
|
37
37
|
const plotWidth = width ?? measured.width;
|
|
38
|
-
const plotHeight = height;
|
|
38
|
+
const plotHeight = fillHeight ? measured.height : height;
|
|
39
39
|
const m = resolveMargin(margin);
|
|
40
|
-
return (_jsxs("div", { "data-slot": slot, className: cn("spk-chart", className), role: "img", "aria-label": ariaLabel, children: [legend?.length ? (_jsx(ChartLegend, { items: legend, hiddenIds: hiddenIds, onToggle: onToggleSeries })) : null, _jsxs("div", { ref: surfaceRef, className: "spk-chart-surface", style: { height: plotHeight }, children: [plotWidth > 0 ? children({ width: plotWidth, height: plotHeight, m }) : null, _jsx(ChartTooltip, { hover: hover ?? null, boundsWidth: plotWidth })] })] }));
|
|
40
|
+
return (_jsxs("div", { "data-slot": slot, className: cn("spk-chart", fillHeight && "spk-chart--fill", className), role: "img", "aria-label": ariaLabel, children: [legend?.length ? (_jsx(ChartLegend, { items: legend, hiddenIds: hiddenIds, onToggle: onToggleSeries })) : null, _jsxs("div", { ref: surfaceRef, className: "spk-chart-surface", style: fillHeight ? undefined : { height: plotHeight }, children: [plotWidth > 0 && plotHeight > 0 ? children({ width: plotWidth, height: plotHeight, m }) : null, _jsx(ChartTooltip, { hover: hover ?? null, boundsWidth: plotWidth, render: renderTooltip })] })] }));
|
|
41
41
|
}
|
|
42
42
|
export function ChartLegend({ items, hiddenIds, onToggle, }) {
|
|
43
43
|
return (_jsx("div", { className: "spk-chart-legend", children: items.map((item) => (_jsxs("button", { type: "button", className: "spk-chart-legend-item", "data-hidden": hiddenIds?.has(item.id) ? "true" : undefined, onClick: () => onToggle?.(item.id), children: [_jsx("span", { className: "spk-chart-swatch", style: { background: item.color } }), item.label] }, item.id))) }));
|
|
44
44
|
}
|
|
45
|
-
export function ChartTooltip({ hover, boundsWidth, }) {
|
|
45
|
+
export function ChartTooltip({ hover, boundsWidth, render, }) {
|
|
46
46
|
if (!hover || !hover.items.length)
|
|
47
47
|
return null;
|
|
48
|
+
const custom = render?.(hover);
|
|
49
|
+
if (render && custom == null)
|
|
50
|
+
return null;
|
|
48
51
|
const left = clampTooltip(hover.x, boundsWidth);
|
|
49
|
-
return (
|
|
52
|
+
return (_jsx("div", { className: "spk-chart-tooltip", style: { left, top: hover.y }, role: "tooltip", children: render ? (custom) : (_jsxs(_Fragment, { children: [hover.title ? _jsx("p", { className: "spk-chart-tooltip-title", children: hover.title }) : null, _jsx("ul", { children: hover.items.map((item) => (_jsxs("li", { children: [_jsx("span", { className: "spk-chart-swatch", style: { background: item.color } }), _jsx("span", { children: item.label }), _jsx("strong", { children: item.value })] }, item.label))) })] })) }));
|
|
50
53
|
}
|
|
51
54
|
function clampTooltip(x, width) {
|
|
52
55
|
return clampNum(x, 72, Math.max(72, width - 72));
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type ChartAxisConfig, type ChartMargin, type SankeyLink, type SankeyNode, type TreeNode } from "../lib/charts";
|
|
2
|
+
import { type ChartItemEvent, type ChartTooltipRenderer } from "./chart-interaction";
|
|
2
3
|
export type HeatDatum = {
|
|
3
4
|
x: number;
|
|
4
5
|
y: number;
|
|
@@ -16,8 +17,12 @@ export type HeatmapProps = {
|
|
|
16
17
|
showColorScale?: boolean;
|
|
17
18
|
margin?: ChartMargin;
|
|
18
19
|
className?: string;
|
|
20
|
+
fillHeight?: boolean;
|
|
21
|
+
onItemClick?: (event: ChartItemEvent) => void;
|
|
22
|
+
renderTooltip?: ChartTooltipRenderer;
|
|
23
|
+
showCellLabels?: boolean | ((cell: HeatDatum) => string);
|
|
19
24
|
};
|
|
20
|
-
export declare function Heatmap({ xAxis, yAxis, series, height, width, hideLegend, showColorScale, margin, className, }: HeatmapProps): import("react").JSX.Element;
|
|
25
|
+
export declare function Heatmap({ xAxis, yAxis, series, height, width, hideLegend, showColorScale, margin, className, fillHeight, onItemClick, renderTooltip, showCellLabels, }: HeatmapProps): import("react").JSX.Element;
|
|
21
26
|
export type FunnelDatum = {
|
|
22
27
|
id?: string;
|
|
23
28
|
label: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flow-charts.d.ts","sourceRoot":"","sources":["../../src/composites/flow-charts.tsx"],"names":[],"mappings":"AACA,OAAO,EAUL,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,QAAQ,EACd,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"flow-charts.d.ts","sourceRoot":"","sources":["../../src/composites/flow-charts.tsx"],"names":[],"mappings":"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"}
|