semiotic 3.1.2 → 3.2.1
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/CLAUDE.md +173 -213
- package/LICENSE +197 -10
- package/README.md +12 -11
- package/ai/dist/componentRegistry.js +6 -0
- package/ai/dist/mcp-server.js +115 -5
- package/ai/examples.md +184 -0
- package/ai/schema.json +4140 -888
- package/ai/system-prompt.md +36 -1
- package/dist/components/ChartContainer.d.ts +2 -0
- package/dist/components/DataSummaryContext.d.ts +12 -0
- package/dist/components/ThemeProvider.d.ts +5 -3
- package/dist/components/Tooltip/FlippingTooltip.d.ts +34 -0
- package/dist/components/charts/geo/ChoroplethMap.d.ts +1 -1
- package/dist/components/charts/index.d.ts +12 -1
- package/dist/components/charts/ordinal/BarChart.d.ts +4 -1
- package/dist/components/charts/ordinal/BoxPlot.d.ts +4 -1
- package/dist/components/charts/ordinal/DonutChart.d.ts +1 -1
- package/dist/components/charts/ordinal/DotPlot.d.ts +4 -1
- package/dist/components/charts/ordinal/FunnelChart.d.ts +57 -0
- package/dist/components/charts/ordinal/GroupedBarChart.d.ts +4 -1
- package/dist/components/charts/ordinal/Histogram.d.ts +17 -2
- package/dist/components/charts/ordinal/LikertChart.d.ts +94 -0
- package/dist/components/charts/ordinal/PieChart.d.ts +1 -1
- package/dist/components/charts/ordinal/RidgelinePlot.d.ts +12 -7
- package/dist/components/charts/ordinal/StackedBarChart.d.ts +4 -1
- package/dist/components/charts/ordinal/SwarmPlot.d.ts +15 -1
- package/dist/components/charts/ordinal/SwimlaneChart.d.ts +65 -0
- package/dist/components/charts/ordinal/ViolinPlot.d.ts +17 -2
- package/dist/components/charts/realtime/RealtimeHistogram.d.ts +20 -0
- package/dist/components/charts/shared/annotationResolvers.d.ts +28 -0
- package/dist/components/charts/shared/colorManipulation.d.ts +15 -0
- package/dist/components/charts/shared/formatUtils.d.ts +28 -0
- package/dist/components/charts/shared/hatchPattern.d.ts +35 -0
- package/dist/components/charts/shared/hooks.d.ts +39 -3
- package/dist/components/charts/shared/legendUtils.d.ts +2 -1
- package/dist/components/charts/shared/selectionUtils.d.ts +16 -1
- package/dist/components/charts/shared/statisticalOverlays.d.ts +49 -5
- package/dist/components/charts/shared/statsTooltip.d.ts +11 -0
- package/dist/components/charts/shared/types.d.ts +26 -2
- package/dist/components/charts/shared/useChartSetup.d.ts +12 -2
- package/dist/components/charts/shared/useLikertAggregation.d.ts +51 -0
- package/dist/components/charts/shared/useOrdinalBrush.d.ts +28 -0
- package/dist/components/charts/shared/useOrdinalStreaming.d.ts +54 -0
- package/dist/components/charts/shared/useStreamingLegend.d.ts +2 -2
- package/dist/components/charts/shared/validateProps.d.ts +2 -2
- package/dist/components/charts/shared/validationMap.d.ts +12 -0
- package/dist/components/charts/xy/AreaChart.d.ts +11 -0
- package/dist/components/charts/xy/Heatmap.d.ts +1 -1
- package/dist/components/charts/xy/MinimapChart.d.ts +1 -1
- package/dist/components/charts/xy/MultiAxisLineChart.d.ts +71 -0
- package/dist/components/charts/xy/StackedAreaChart.d.ts +11 -0
- package/dist/components/realtime/types.d.ts +6 -0
- package/dist/components/semiotic-ai.d.ts +4 -0
- package/dist/components/semiotic-ordinal.d.ts +5 -0
- package/dist/components/semiotic-themes.d.ts +80 -0
- package/dist/components/semiotic-utils.d.ts +30 -0
- package/dist/components/semiotic-xy.d.ts +1 -0
- package/dist/components/semiotic.d.ts +11 -5
- package/dist/components/store/LinkedCrosshairStore.d.ts +11 -0
- package/dist/components/store/ThemeStore.d.ts +22 -2
- package/dist/components/store/useSelection.d.ts +1 -0
- package/dist/components/stream/AccessibleDataTable.d.ts +28 -6
- package/dist/components/stream/FocusRing.d.ts +33 -0
- package/dist/components/stream/OrdinalBrushOverlay.d.ts +43 -0
- package/dist/components/stream/OrdinalPipelineStore.d.ts +16 -0
- package/dist/components/stream/OrdinalSVGOverlay.d.ts +2 -1
- package/dist/components/stream/PipelineStore.d.ts +7 -47
- package/dist/components/stream/SVGOverlay.d.ts +9 -3
- package/dist/components/stream/SceneGraph.d.ts +6 -1
- package/dist/components/stream/XYBrushOverlay.d.ts +47 -0
- package/dist/components/stream/accessorUtils.d.ts +14 -0
- package/dist/components/stream/geoTypes.d.ts +5 -1
- package/dist/components/stream/keyboardNav.d.ts +85 -9
- package/dist/components/stream/layouts/hierarchySceneBuilders.d.ts +35 -0
- package/dist/components/stream/layouts/hierarchyUtils.d.ts +25 -0
- package/dist/components/stream/networkTypes.d.ts +7 -1
- package/dist/components/stream/ordinalSceneBuilders/barFunnelScene.d.ts +27 -0
- package/dist/components/stream/ordinalSceneBuilders/funnelScene.d.ts +26 -0
- package/dist/components/stream/ordinalSceneBuilders/swimlaneScene.d.ts +12 -0
- package/dist/components/stream/ordinalTypes.d.ts +30 -4
- package/dist/components/stream/pipelineDecay.d.ts +20 -0
- package/dist/components/stream/pipelinePulse.d.ts +24 -0
- package/dist/components/stream/pipelineTransitions.d.ts +59 -0
- package/dist/components/stream/renderers/barFunnelCanvasRenderer.d.ts +12 -0
- package/dist/components/stream/renderers/pointCanvasRenderer.d.ts +2 -1
- package/dist/components/stream/renderers/trapezoidCanvasRenderer.d.ts +15 -0
- package/dist/components/stream/sceneUtils.d.ts +10 -0
- package/dist/components/stream/types.d.ts +29 -4
- package/dist/components/stream/useMediaPreferences.d.ts +11 -0
- package/dist/components/stream/xySceneBuilders/areaScene.d.ts +13 -0
- package/dist/components/stream/xySceneBuilders/barScene.d.ts +18 -0
- package/dist/components/stream/xySceneBuilders/boundsScene.d.ts +8 -0
- package/dist/components/stream/xySceneBuilders/candlestickScene.d.ts +10 -0
- package/dist/components/stream/xySceneBuilders/emitPointNodes.d.ts +13 -0
- package/dist/components/stream/xySceneBuilders/heatmapScene.d.ts +3 -0
- package/dist/components/stream/xySceneBuilders/lineScene.d.ts +12 -0
- package/dist/components/stream/xySceneBuilders/pointScene.d.ts +12 -0
- package/dist/components/stream/xySceneBuilders/swarmScene.d.ts +10 -0
- package/dist/components/stream/xySceneBuilders/types.d.ts +93 -0
- package/dist/components/stream/xySceneBuilders/waterfallScene.d.ts +12 -0
- package/dist/geo.min.js +1 -1
- package/dist/geo.module.min.js +1 -1
- package/dist/network.min.js +1 -1
- package/dist/network.module.min.js +1 -1
- package/dist/ordinal.min.js +1 -1
- package/dist/ordinal.module.min.js +1 -1
- package/dist/realtime.min.js +1 -1
- package/dist/realtime.module.min.js +1 -1
- package/dist/semiotic-ai-statisticalOverlays-C2PPlmXv.js +1 -0
- package/dist/semiotic-ai.d.ts +4 -0
- package/dist/semiotic-ai.min.js +1 -1
- package/dist/semiotic-ai.module.min.js +1 -1
- package/dist/semiotic-ordinal.d.ts +5 -0
- package/dist/semiotic-statisticalOverlays-DGX_WWc5.js +1 -0
- package/dist/semiotic-themes.d.ts +80 -0
- package/dist/semiotic-themes.min.js +1 -0
- package/dist/semiotic-themes.module.min.js +1 -0
- package/dist/semiotic-utils.d.ts +30 -0
- package/dist/semiotic-utils.min.js +1 -0
- package/dist/semiotic-utils.module.min.js +1 -0
- package/dist/semiotic-xy.d.ts +1 -0
- package/dist/semiotic.d.ts +11 -5
- package/dist/semiotic.min.js +1 -1
- package/dist/semiotic.module.min.js +1 -1
- package/dist/server.min.js +1 -1
- package/dist/server.module.min.js +1 -1
- package/dist/xy-statisticalOverlays-C2PPlmXv.js +1 -0
- package/dist/xy.min.js +1 -1
- package/dist/xy.module.min.js +1 -1
- package/package.json +38 -12
- package/dist/semiotic-ai-statisticalOverlays-C1f7TYyD.js +0 -1
- package/dist/semiotic-statisticalOverlays-C1f7TYyD.js +0 -1
- package/dist/xy-statisticalOverlays-C1f7TYyD.js +0 -1
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OrdinalBrushOverlay — d3-brush SVG overlay for ordinal frames.
|
|
3
|
+
*
|
|
4
|
+
* Renders a transparent SVG positioned above the canvas. Brushes along the
|
|
5
|
+
* r-axis (value axis) only: horizontal projection → brushX, vertical → brushY.
|
|
6
|
+
*
|
|
7
|
+
* Key design decisions:
|
|
8
|
+
* - Outer SVG has pointerEvents:"none", inner brush-g has "all", so
|
|
9
|
+
* axes/legends rendered underneath remain clickable.
|
|
10
|
+
* - d3-brush lifecycle (useEffect) depends on [width, height, isHorizontal]
|
|
11
|
+
* only — NOT scales. Scales are read from a ref to avoid brush teardown
|
|
12
|
+
* mid-drag (scales change every render due to new object identity).
|
|
13
|
+
* - A separate useEffect repositions the brush when scales change (streaming).
|
|
14
|
+
*
|
|
15
|
+
* Consumed by: StreamOrdinalFrame (rendered when brush prop is set).
|
|
16
|
+
* Wired by: useOrdinalBrush hook in HOC charts.
|
|
17
|
+
*/
|
|
18
|
+
import * as React from "react";
|
|
19
|
+
import type { OrdinalScales } from "./ordinalTypes";
|
|
20
|
+
interface OrdinalBrushOverlayProps {
|
|
21
|
+
width: number;
|
|
22
|
+
height: number;
|
|
23
|
+
totalWidth: number;
|
|
24
|
+
totalHeight: number;
|
|
25
|
+
margin: {
|
|
26
|
+
top: number;
|
|
27
|
+
right: number;
|
|
28
|
+
bottom: number;
|
|
29
|
+
left: number;
|
|
30
|
+
};
|
|
31
|
+
scales: OrdinalScales | null;
|
|
32
|
+
onBrush: (extent: {
|
|
33
|
+
r: [number, number];
|
|
34
|
+
} | null) => void;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* SVG brush overlay for ordinal frames.
|
|
38
|
+
* Brushes along the r-axis (value axis) only.
|
|
39
|
+
* In horizontal projection, r maps to x-pixels → uses brushX.
|
|
40
|
+
* In vertical projection, r maps to y-pixels → uses brushY.
|
|
41
|
+
*/
|
|
42
|
+
export declare function OrdinalBrushOverlay({ width, height, totalWidth, totalHeight, margin, scales, onBrush }: OrdinalBrushOverlayProps): React.JSX.Element;
|
|
43
|
+
export {};
|
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OrdinalPipelineStore — stateful pipeline for ordinal chart data.
|
|
3
|
+
*
|
|
4
|
+
* Owns: data ingestion (RingBuffer), scale computation (o-band + r-linear),
|
|
5
|
+
* value domain logic (per-lane sums for swimlane, zero-inclusion for bars),
|
|
6
|
+
* and scene layout delegation to ordinalSceneBuilders/*.
|
|
7
|
+
*
|
|
8
|
+
* Key design decisions:
|
|
9
|
+
* - Swimlane domain uses per-lane sums, not individual values, because
|
|
10
|
+
* stacked bars within a lane must fit within the lane's total range.
|
|
11
|
+
* - Zero-inclusion for bar/swimlane is skipped when explicit rExtent is
|
|
12
|
+
* set (either end non-null), enabling zoom/brush without domain override.
|
|
13
|
+
* - Scene builders are pure functions; this store coordinates them.
|
|
14
|
+
*
|
|
15
|
+
* Consumed by: StreamOrdinalFrame (sole consumer).
|
|
16
|
+
*/
|
|
1
17
|
import { type ScaleLinear } from "d3-scale";
|
|
2
18
|
import type { OrdinalPipelineConfig, OrdinalScales, OrdinalSceneNode, OrdinalColumn, OrdinalLayout } from "./ordinalTypes";
|
|
3
19
|
import type { Changeset } from "./types";
|
|
@@ -16,9 +16,10 @@ interface OrdinalSVGOverlayProps {
|
|
|
16
16
|
};
|
|
17
17
|
scales: OrdinalScales | null;
|
|
18
18
|
showAxes?: boolean;
|
|
19
|
+
showCategoryTicks?: boolean;
|
|
19
20
|
oLabel?: string;
|
|
20
21
|
rLabel?: string;
|
|
21
|
-
oFormat?: (d: string) => string;
|
|
22
|
+
oFormat?: (d: string, index?: number) => string;
|
|
22
23
|
rFormat?: (d: number) => string;
|
|
23
24
|
showGrid?: boolean;
|
|
24
25
|
title?: string | ReactNode;
|
|
@@ -106,6 +106,8 @@ export declare class PipelineStore {
|
|
|
106
106
|
/** Separate group→color map for resolveGroupColor (insertion-order based, never invalidates _colorMapCache) */
|
|
107
107
|
private _groupColorMap;
|
|
108
108
|
private _barCategoryCache;
|
|
109
|
+
/** Sorted bin boundary values from the last bar scene build (for data-driven brush snapping) */
|
|
110
|
+
private _binBoundaries;
|
|
109
111
|
/** Cache stacked area cumulative sums to skip recalculation when buffer hasn't changed */
|
|
110
112
|
private _stackExtentCache;
|
|
111
113
|
/** Monotonic counter incremented on each ingest — used as part of cache keys */
|
|
@@ -119,6 +121,8 @@ export declare class PipelineStore {
|
|
|
119
121
|
scales: StreamScales | null;
|
|
120
122
|
scene: SceneNode[];
|
|
121
123
|
version: number;
|
|
124
|
+
/** True when the x accessor returns Date objects (auto-detected on first data ingestion) */
|
|
125
|
+
xIsDate: boolean;
|
|
122
126
|
private _quadtree;
|
|
123
127
|
private static readonly QUADTREE_THRESHOLD;
|
|
124
128
|
constructor(config: PipelineConfig);
|
|
@@ -147,60 +151,14 @@ export declare class PipelineStore {
|
|
|
147
151
|
*/
|
|
148
152
|
private remapScene;
|
|
149
153
|
private buildSceneNodes;
|
|
150
|
-
private buildLineScene;
|
|
151
|
-
private buildAreaScene;
|
|
152
|
-
private buildStackedAreaScene;
|
|
153
|
-
private buildPointScene;
|
|
154
|
-
private buildHeatmapScene;
|
|
155
|
-
/**
|
|
156
|
-
* Streaming heatmap: discretize continuous x/y into a grid and aggregate.
|
|
157
|
-
*/
|
|
158
|
-
private buildStreamingHeatmapScene;
|
|
159
|
-
private buildBarScene;
|
|
160
|
-
private buildSwarmScene;
|
|
161
|
-
private buildWaterfallScene;
|
|
162
|
-
private buildCandlestickScene;
|
|
163
|
-
private buildBoundsForGroup;
|
|
164
154
|
private resolveBoundsStyle;
|
|
165
|
-
/**
|
|
166
|
-
* Compute decay opacity for a datum at `bufferIndex` out of `bufferSize` items.
|
|
167
|
-
* Index 0 = oldest, bufferSize-1 = newest. Returns 0–1.
|
|
168
|
-
*/
|
|
169
155
|
computeDecayOpacity(bufferIndex: number, bufferSize: number): number;
|
|
170
|
-
/**
|
|
171
|
-
* Apply decay opacity to a list of discrete scene nodes.
|
|
172
|
-
* Uses the datum's index in the buffer data array.
|
|
173
|
-
*/
|
|
174
156
|
private applyDecay;
|
|
175
|
-
/**
|
|
176
|
-
* Compute pulse intensity for a datum inserted at `insertTime`.
|
|
177
|
-
* Returns 0–1 (1 = just inserted, 0 = pulse expired).
|
|
178
|
-
*/
|
|
179
|
-
private computePulseIntensity;
|
|
180
|
-
/**
|
|
181
|
-
* Apply pulse glow to discrete scene nodes.
|
|
182
|
-
*/
|
|
183
157
|
private applyPulse;
|
|
184
|
-
/**
|
|
185
|
-
* Returns true if there are active pulse animations that need continuous rendering.
|
|
186
|
-
*/
|
|
187
158
|
get hasActivePulses(): boolean;
|
|
188
|
-
|
|
189
|
-
* Snapshot current scene node positions before rebuild.
|
|
190
|
-
*/
|
|
159
|
+
private get transitionContext();
|
|
191
160
|
private snapshotPositions;
|
|
192
|
-
/**
|
|
193
|
-
* Get a stable identity key for a scene node.
|
|
194
|
-
*/
|
|
195
|
-
private getNodeIdentity;
|
|
196
|
-
/**
|
|
197
|
-
* After scene rebuild, set up transition from old to new positions.
|
|
198
|
-
* Detects entering nodes (new, no prev match) and exiting nodes (prev, no new match).
|
|
199
|
-
*/
|
|
200
161
|
private startTransition;
|
|
201
|
-
/**
|
|
202
|
-
* Advance the transition animation. Returns true if still animating.
|
|
203
|
-
*/
|
|
204
162
|
advanceTransition(now: number): boolean;
|
|
205
163
|
private groupData;
|
|
206
164
|
/**
|
|
@@ -223,6 +181,8 @@ export declare class PipelineStore {
|
|
|
223
181
|
*/
|
|
224
182
|
private getBufferArray;
|
|
225
183
|
getData(): Record<string, any>[];
|
|
184
|
+
/** Returns sorted bin boundary values from the last bar scene build. Persists until clear() or the next bar scene build. */
|
|
185
|
+
getBinBoundaries(): number[];
|
|
226
186
|
getExtents(): {
|
|
227
187
|
x: [number, number];
|
|
228
188
|
y: [number, number];
|
|
@@ -7,7 +7,7 @@ export interface AxisConfig {
|
|
|
7
7
|
orient: "left" | "right" | "top" | "bottom";
|
|
8
8
|
label?: string;
|
|
9
9
|
ticks?: number;
|
|
10
|
-
tickFormat?: (d: any) => string;
|
|
10
|
+
tickFormat?: (d: any, index?: number, allTicks?: number[]) => string;
|
|
11
11
|
baseline?: boolean | "under";
|
|
12
12
|
jaggedBase?: boolean;
|
|
13
13
|
/** Highlight ticks at time boundaries (new month, year, etc.) with semibold text.
|
|
@@ -30,7 +30,9 @@ interface SVGOverlayProps {
|
|
|
30
30
|
axes?: AxisConfig[];
|
|
31
31
|
xLabel?: string;
|
|
32
32
|
yLabel?: string;
|
|
33
|
-
|
|
33
|
+
/** Label for the right Y axis (dual-axis charts) */
|
|
34
|
+
yLabelRight?: string;
|
|
35
|
+
xFormat?: (d: any, index?: number, allTicks?: number[]) => string;
|
|
34
36
|
yFormat?: (d: any) => string;
|
|
35
37
|
showGrid?: boolean;
|
|
36
38
|
title?: string | ReactNode;
|
|
@@ -73,6 +75,10 @@ interface SVGOverlayProps {
|
|
|
73
75
|
curve?: string;
|
|
74
76
|
/** When true, grid lines and axis baselines are skipped (rendered by SVGUnderlay instead) */
|
|
75
77
|
underlayRendered?: boolean;
|
|
78
|
+
/** Name of the linked crosshair store entry to read */
|
|
79
|
+
linkedCrosshairName?: string;
|
|
80
|
+
/** Source chart ID — crosshair line is suppressed on the source to avoid double rendering */
|
|
81
|
+
linkedCrosshairSourceId?: string;
|
|
76
82
|
children?: ReactNode;
|
|
77
83
|
}
|
|
78
84
|
interface SVGUnderlayProps {
|
|
@@ -90,7 +96,7 @@ interface SVGUnderlayProps {
|
|
|
90
96
|
showAxes?: boolean;
|
|
91
97
|
axes?: AxisConfig[];
|
|
92
98
|
showGrid?: boolean;
|
|
93
|
-
xFormat?: (d: any) => string;
|
|
99
|
+
xFormat?: (d: any, index?: number, allTicks?: number[]) => string;
|
|
94
100
|
yFormat?: (d: any) => string;
|
|
95
101
|
}
|
|
96
102
|
export declare function SVGUnderlay(props: SVGUnderlayProps): React.JSX.Element | null;
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import type { SceneNode, LineSceneNode, AreaSceneNode, PointSceneNode, RectSceneNode, HeatcellSceneNode, Style, StreamScales, CurveType } from "./types";
|
|
2
2
|
export declare function buildLineNode(data: Record<string, any>[], scales: StreamScales, xGet: (d: Record<string, any>) => number, yGet: (d: Record<string, any>) => number, style: Style, group?: string): LineSceneNode;
|
|
3
3
|
export declare function buildAreaNode(data: Record<string, any>[], scales: StreamScales, xGet: (d: Record<string, any>) => number, yGet: (d: Record<string, any>) => number, baselineY: number, style: Style, group?: string, y0Get?: (d: Record<string, any>) => number): AreaSceneNode;
|
|
4
|
+
/** Per-group-per-x stacked top values, keyed by group then x */
|
|
5
|
+
export type StackedTops = Map<string, Map<number, number>>;
|
|
4
6
|
export declare function buildStackedAreaNodes(groups: {
|
|
5
7
|
key: string;
|
|
6
8
|
data: Record<string, any>[];
|
|
7
|
-
}[], scales: StreamScales, xGet: (d: Record<string, any>) => number, yGet: (d: Record<string, any>) => number, styleFn: (group: string, sampleDatum?: Record<string, any>) => Style, normalize?: boolean, curve?: CurveType):
|
|
9
|
+
}[], scales: StreamScales, xGet: (d: Record<string, any>) => number, yGet: (d: Record<string, any>) => number, styleFn: (group: string, sampleDatum?: Record<string, any>) => Style, normalize?: boolean, curve?: CurveType): {
|
|
10
|
+
nodes: AreaSceneNode[];
|
|
11
|
+
stackedTops: StackedTops;
|
|
12
|
+
};
|
|
8
13
|
export declare function buildPointNode(datum: Record<string, any>, scales: StreamScales, xGet: (d: Record<string, any>) => number, yGet: (d: Record<string, any>) => number, r: number, style: Style, pointId?: string): PointSceneNode | null;
|
|
9
14
|
export declare function buildRectNode(x: number, y: number, w: number, h: number, style: Style, datum: any, group?: string): RectSceneNode;
|
|
10
15
|
export declare function buildHeatcellNode(x: number, y: number, w: number, h: number, fill: string, datum: any, options?: {
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* XYBrushOverlay — d3-brush SVG overlay for XY frames.
|
|
3
|
+
*
|
|
4
|
+
* Renders a transparent SVG positioned above the canvas. Supports x, y, and
|
|
5
|
+
* xy brush dimensions, bin snapping, and streaming brush tracking (shrinks/
|
|
6
|
+
* clears the brush as data scrolls past the selected range).
|
|
7
|
+
*
|
|
8
|
+
* Key design decisions:
|
|
9
|
+
* - d3-brush lifecycle depends on [width, height, dimension, snap, binSize, snapDuring]
|
|
10
|
+
* only — scales and binBoundaries are read from refs to avoid teardown mid-drag.
|
|
11
|
+
* - Data-driven snapping (binBoundaries) uses binary search to snap to actual bin
|
|
12
|
+
* edges. Falls back to uniform grid math (binSize) when no boundaries are provided.
|
|
13
|
+
* - Bin snapping applies on "end" events by default. Set snapDuring=true to also
|
|
14
|
+
* snap during drag (the "brush" event).
|
|
15
|
+
* - Streaming tracking guards against y-only dimension (no x-domain to track).
|
|
16
|
+
* - isProgrammaticMoveRef prevents re-entrant brush events from .move() calls.
|
|
17
|
+
*
|
|
18
|
+
* Consumed by: StreamXYFrame (rendered when brush prop is set).
|
|
19
|
+
*/
|
|
20
|
+
import * as React from "react";
|
|
21
|
+
import type { StreamScales } from "./types";
|
|
22
|
+
export interface XYBrushOverlayProps {
|
|
23
|
+
width: number;
|
|
24
|
+
height: number;
|
|
25
|
+
totalWidth: number;
|
|
26
|
+
totalHeight: number;
|
|
27
|
+
margin: {
|
|
28
|
+
top: number;
|
|
29
|
+
right: number;
|
|
30
|
+
bottom: number;
|
|
31
|
+
left: number;
|
|
32
|
+
};
|
|
33
|
+
dimension: "x" | "y" | "xy";
|
|
34
|
+
scales: StreamScales | null;
|
|
35
|
+
onBrush: (extent: {
|
|
36
|
+
x: [number, number];
|
|
37
|
+
y: [number, number];
|
|
38
|
+
} | null) => void;
|
|
39
|
+
binSize?: number;
|
|
40
|
+
snap?: "continuous" | "bin";
|
|
41
|
+
/** Sorted bin boundary values for data-driven snapping (overrides uniform grid math when snap="bin"). Defensively sorted internally. */
|
|
42
|
+
binBoundaries?: number[];
|
|
43
|
+
/** When true, snap during drag (not just on release). Default false. */
|
|
44
|
+
snapDuring?: boolean;
|
|
45
|
+
streaming?: boolean;
|
|
46
|
+
}
|
|
47
|
+
export declare function XYBrushOverlay({ width, height, totalWidth, totalHeight, margin, dimension, scales, onBrush, binSize, snap, binBoundaries, snapDuring, streaming }: XYBrushOverlayProps): React.JSX.Element;
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compare two accessor specs for equivalence.
|
|
3
|
+
* - Same reference: always equivalent (`===`)
|
|
4
|
+
* - String accessors: exact string match
|
|
5
|
+
* - Function accessors: `.toString()` comparison (catches inline arrow functions
|
|
6
|
+
* like `d => d.value` that are recreated on every render but have identical source)
|
|
7
|
+
* - Mismatched types or undefined vs defined: not equivalent
|
|
8
|
+
*
|
|
9
|
+
* **Known limitation**: `.toString()` compares source text, not closure bindings.
|
|
10
|
+
* Two functions with identical source but different captured variables will appear
|
|
11
|
+
* equivalent. For closures that depend on changing values, use `useCallback` with
|
|
12
|
+
* the variable in the dependency array so the reference changes when behavior changes.
|
|
13
|
+
*/
|
|
14
|
+
export declare function accessorsEquivalent(a: string | ((...args: any[]) => any) | undefined, b: string | ((...args: any[]) => any) | undefined): boolean;
|
|
1
15
|
export declare function resolveAccessor<T>(accessor: string | ((d: T) => number) | undefined, fallback: string): (d: T) => number;
|
|
2
16
|
export declare function resolveRawAccessor<T>(accessor: string | ((d: T) => any) | undefined, fallback: string): (d: T) => any;
|
|
3
17
|
export declare function resolveStringAccessor<T>(accessor: string | ((d: T) => string) | undefined, fallback?: string): ((d: T) => string) | undefined;
|
|
@@ -161,8 +161,12 @@ export interface StreamGeoFrameProps<T = Record<string, any>> {
|
|
|
161
161
|
legendHighlightedCategory?: string | null;
|
|
162
162
|
legendIsolatedCategories?: Set<string>;
|
|
163
163
|
showAxes?: boolean;
|
|
164
|
-
/** Render a visually-hidden data table from the scene graph for screen readers
|
|
164
|
+
/** Render a visually-hidden data table from the scene graph for screen readers */
|
|
165
165
|
accessibleTable?: boolean;
|
|
166
|
+
/** Accessible description overriding the auto-generated aria-label on the chart container */
|
|
167
|
+
description?: string;
|
|
168
|
+
/** Accessible summary rendered as a screen-reader-only note */
|
|
169
|
+
summary?: string;
|
|
166
170
|
}
|
|
167
171
|
export interface StreamGeoFrameHandle {
|
|
168
172
|
push(datum: Record<string, any>): void;
|
|
@@ -1,36 +1,112 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Keyboard navigation utilities for Stream Frames.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* Supports two navigation modes:
|
|
5
|
+
* - **Flat**: ArrowRight/Left and ArrowUp/Down both advance linearly (geo, simple charts)
|
|
6
|
+
* - **Graph**: ArrowRight/Left navigates within a series/group, ArrowUp/Down switches
|
|
7
|
+
* between series/groups at a similar position (XY lines, stacked bars, networks)
|
|
8
|
+
*
|
|
9
|
+
* Reuses the existing hover/tooltip system — keyboard focus sets the same
|
|
10
|
+
* HoverData state that mouse hover does.
|
|
8
11
|
*/
|
|
9
12
|
import type { HoverData } from "../realtime/types";
|
|
10
13
|
export interface NavPoint {
|
|
11
14
|
x: number;
|
|
12
15
|
y: number;
|
|
13
16
|
datum: any;
|
|
17
|
+
/** Shape hint for focus ring rendering */
|
|
18
|
+
shape?: "circle" | "rect" | "wedge";
|
|
19
|
+
/** Width of rect-shaped elements (bars, sankey nodes) */
|
|
20
|
+
w?: number;
|
|
21
|
+
/** Height of rect-shaped elements */
|
|
22
|
+
h?: number;
|
|
23
|
+
/** Group identifier for graph navigation (series name, category, node id) */
|
|
24
|
+
group?: string;
|
|
25
|
+
/** Index in NavGraph.flat — set by buildNavGraph for O(1) lookup */
|
|
26
|
+
_flatIndex?: number;
|
|
27
|
+
/** Index within its group — set by buildNavGraph for O(1) resolvePosition */
|
|
28
|
+
_groupIndex?: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* A navigation graph that organizes NavPoints into groups (series/categories)
|
|
32
|
+
* and positions within each group, enabling 2D keyboard navigation.
|
|
33
|
+
*
|
|
34
|
+
* ArrowRight/Left = next/prev within the current group (e.g. along a line series)
|
|
35
|
+
* ArrowUp/Down = switch to the nearest point in an adjacent group (e.g. switch series)
|
|
36
|
+
*/
|
|
37
|
+
export interface NavGraph {
|
|
38
|
+
/** All points in flat order (for PageUp/Down, Home/End) */
|
|
39
|
+
flat: NavPoint[];
|
|
40
|
+
/** Group names in stable order */
|
|
41
|
+
groups: string[];
|
|
42
|
+
/** Points per group, in position order */
|
|
43
|
+
byGroup: Map<string, NavPoint[]>;
|
|
44
|
+
/** Precomputed node id → flat index lookup (for network navigation) */
|
|
45
|
+
idToIdx: Map<string, number>;
|
|
14
46
|
}
|
|
47
|
+
export interface NavPosition {
|
|
48
|
+
/** Index into NavGraph.flat */
|
|
49
|
+
flatIndex: number;
|
|
50
|
+
/** Current group name */
|
|
51
|
+
group: string;
|
|
52
|
+
/** Index within the current group */
|
|
53
|
+
indexInGroup: number;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Build a navigation graph from grouped NavPoints.
|
|
57
|
+
* Points within each group are sorted by x then y.
|
|
58
|
+
* Groups are sorted by their first-point y position (top to bottom).
|
|
59
|
+
*/
|
|
60
|
+
export declare function buildNavGraph(points: NavPoint[]): NavGraph;
|
|
61
|
+
/**
|
|
62
|
+
* Resolve the current NavPosition from a flat index.
|
|
63
|
+
* Clamps to valid range if the index is stale (e.g. scene changed between key presses).
|
|
64
|
+
*/
|
|
65
|
+
export declare function resolvePosition(graph: NavGraph, flatIndex: number): NavPosition;
|
|
66
|
+
/**
|
|
67
|
+
* Compute the next navigation position given a key press and current position.
|
|
68
|
+
* Returns the flat index into graph.flat, -1 to clear, or null for unhandled keys.
|
|
69
|
+
*/
|
|
70
|
+
export declare function nextGraphIndex(key: string, pos: NavPosition, graph: NavGraph): number | null;
|
|
15
71
|
/**
|
|
16
72
|
* Extract navigable data points from XY scene nodes.
|
|
17
|
-
*
|
|
18
|
-
*
|
|
73
|
+
* Lines/areas carry a `group` field identifying the series.
|
|
74
|
+
* ArrowRight/Left = within series, ArrowUp/Down = switch series.
|
|
19
75
|
*/
|
|
20
76
|
export declare function extractXYNavPoints(scene: any[]): NavPoint[];
|
|
21
77
|
/**
|
|
22
78
|
* Extract navigable points from ordinal scene nodes.
|
|
23
|
-
*
|
|
79
|
+
* Bars use `node.group` (stack/group key) falling back to `datum.category`.
|
|
80
|
+
* ArrowRight/Left = across categories, ArrowUp/Down = within stacked segments.
|
|
24
81
|
*/
|
|
25
82
|
export declare function extractOrdinalNavPoints(scene: any[]): NavPoint[];
|
|
26
83
|
/**
|
|
27
84
|
* Extract navigable points from network scene nodes.
|
|
28
|
-
*
|
|
85
|
+
* Each node's group is its own id, enabling neighbor traversal via edges.
|
|
29
86
|
*/
|
|
30
87
|
export declare function extractNetworkNavPoints(scene: any[]): NavPoint[];
|
|
88
|
+
/**
|
|
89
|
+
* Network-specific navigation: spatial arrow keys + edge following.
|
|
90
|
+
*
|
|
91
|
+
* ArrowRight/Left/Up/Down: move to the nearest node in that direction.
|
|
92
|
+
* Enter: follow an edge to a connected neighbor of the current node.
|
|
93
|
+
* PageUp/Down, Home/End, Escape: flat navigation.
|
|
94
|
+
*
|
|
95
|
+
* Returns the flat index of the target node, -1 to clear, or null for unhandled keys.
|
|
96
|
+
*/
|
|
97
|
+
export declare function nextNetworkIndex(key: string, pos: NavPosition, graph: NavGraph, edges: any[], neighborIndexRef: {
|
|
98
|
+
current: number;
|
|
99
|
+
}): number | null;
|
|
100
|
+
/**
|
|
101
|
+
* Extract navigable points from geo scene nodes.
|
|
102
|
+
* Flat navigation only (no meaningful grouping for geo).
|
|
103
|
+
*/
|
|
104
|
+
export declare function extractGeoNavPoints(scene: any[]): NavPoint[];
|
|
31
105
|
/**
|
|
32
106
|
* Compute the next focus index given a key and current index.
|
|
33
|
-
* Returns -1 to clear focus.
|
|
107
|
+
* Returns -1 to clear focus. Returns null for unhandled keys.
|
|
108
|
+
*
|
|
109
|
+
* Used by Geo frame (flat navigation) and as fallback.
|
|
34
110
|
*/
|
|
35
111
|
export declare function nextIndex(key: string, current: number, total: number): number | null;
|
|
36
112
|
/**
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scene builders for hierarchy layouts (tree, treemap, circlepack).
|
|
3
|
+
*
|
|
4
|
+
* Converts RealtimeNode/Edge arrays (positioned by d3-hierarchy) into
|
|
5
|
+
* NetworkSceneNode/Edge arrays for canvas rendering.
|
|
6
|
+
*
|
|
7
|
+
* Three builder functions, one per visual form:
|
|
8
|
+
* buildTreeScene — circle nodes + curved edges (tree/cluster)
|
|
9
|
+
* buildRectScene — rect nodes, no edges (treemap/partition)
|
|
10
|
+
* buildCircleScene — circle nodes, no edges (circlepack)
|
|
11
|
+
*
|
|
12
|
+
* Dependencies: hierarchyUtils (palette, contrast, label resolution)
|
|
13
|
+
* Consumed by: hierarchyLayoutPlugin.ts (buildScene dispatcher)
|
|
14
|
+
*/
|
|
15
|
+
import type { NetworkPipelineConfig, NetworkSceneNode, NetworkSceneEdge, NetworkLabel, RealtimeNode, RealtimeEdge } from "../networkTypes";
|
|
16
|
+
export declare function buildTreeScene(nodes: RealtimeNode[], edges: RealtimeEdge[], config: NetworkPipelineConfig, size: [number, number], nodeStyleFn: (d: any) => Record<string, any>, edgeStyleFn: (d: any) => Record<string, any>): {
|
|
17
|
+
sceneNodes: NetworkSceneNode[];
|
|
18
|
+
sceneEdges: NetworkSceneEdge[];
|
|
19
|
+
labels: NetworkLabel[];
|
|
20
|
+
};
|
|
21
|
+
export declare function buildRectScene(nodes: RealtimeNode[], config: NetworkPipelineConfig, size: [number, number], nodeStyleFn: (d: any) => Record<string, any>): {
|
|
22
|
+
sceneNodes: NetworkSceneNode[];
|
|
23
|
+
sceneEdges: NetworkSceneEdge[];
|
|
24
|
+
labels: NetworkLabel[];
|
|
25
|
+
};
|
|
26
|
+
export declare function buildCircleScene(nodes: RealtimeNode[], config: NetworkPipelineConfig, size: [number, number], nodeStyleFn: (d: any) => Record<string, any>): {
|
|
27
|
+
sceneNodes: NetworkSceneNode[];
|
|
28
|
+
sceneEdges: NetworkSceneEdge[];
|
|
29
|
+
labels: NetworkLabel[];
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Generate a cubic bezier path string for a tree/cluster edge.
|
|
33
|
+
* Uses different curve strategies based on tree orientation.
|
|
34
|
+
*/
|
|
35
|
+
export declare function generateTreeEdgePath(sx: number, sy: number, tx: number, ty: number, orientation: string): string;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utilities for hierarchy layout plugins.
|
|
3
|
+
*
|
|
4
|
+
* CSS color parsing, contrast text, depth palette, and accessor resolution
|
|
5
|
+
* used across tree, treemap, and circlepack scene builders.
|
|
6
|
+
*
|
|
7
|
+
* Consumed by: hierarchyLayoutPlugin.ts, hierarchySceneBuilders.ts
|
|
8
|
+
*/
|
|
9
|
+
import type { NetworkPipelineConfig } from "../networkTypes";
|
|
10
|
+
/** Depth-based color palette shared across all hierarchy scene builders */
|
|
11
|
+
export declare const DEPTH_PALETTE: string[];
|
|
12
|
+
/**
|
|
13
|
+
* Parse a CSS color string (hex or rgb/rgba) into [r, g, b].
|
|
14
|
+
* Falls back to mid-gray if the format is unrecognized.
|
|
15
|
+
*/
|
|
16
|
+
export declare function parseColor(color: string): [number, number, number];
|
|
17
|
+
/**
|
|
18
|
+
* Return a high-contrast text color (white or near-black) for the given background.
|
|
19
|
+
* Uses perceived luminance (ITU-R BT.601).
|
|
20
|
+
*/
|
|
21
|
+
export declare function contrastTextColor(bgColor: string): string;
|
|
22
|
+
export declare function resolveChildrenAccessor(accessor: string | ((d: any) => any[]) | undefined): ((d: any) => any[]) | undefined;
|
|
23
|
+
export declare function resolveNodeId(d: any, config: NetworkPipelineConfig, index: number): string;
|
|
24
|
+
export declare function resolveLabelFn(nodeLabel: string | ((d: any) => string) | undefined): ((d: any) => string) | null;
|
|
25
|
+
export declare function resolveDefaultNodeSize(nodeSize: number | string | ((d: any) => number) | undefined): number;
|
|
@@ -54,6 +54,8 @@ export interface RealtimeEdge {
|
|
|
54
54
|
circularPathData?: any;
|
|
55
55
|
bezier?: BezierCache;
|
|
56
56
|
data?: Record<string, any>;
|
|
57
|
+
/** Unique key for this edge (supports parallel edges between same node pair) */
|
|
58
|
+
_edgeKey?: string;
|
|
57
59
|
}
|
|
58
60
|
export interface BezierPoint {
|
|
59
61
|
x: number;
|
|
@@ -438,8 +440,12 @@ export interface StreamNetworkFrameProps<T = Record<string, any>> {
|
|
|
438
440
|
orbitEccentricity?: number | ((node: any) => number);
|
|
439
441
|
orbitShowRings?: boolean;
|
|
440
442
|
orbitAnimated?: boolean;
|
|
441
|
-
/** Render a visually-hidden data table from the scene graph for screen readers
|
|
443
|
+
/** Render a visually-hidden data table from the scene graph for screen readers */
|
|
442
444
|
accessibleTable?: boolean;
|
|
445
|
+
/** Accessible description overriding the auto-generated aria-label on the chart container */
|
|
446
|
+
description?: string;
|
|
447
|
+
/** Accessible summary rendered as a screen-reader-only note */
|
|
448
|
+
summary?: string;
|
|
443
449
|
}
|
|
444
450
|
export interface StreamNetworkFrameHandle {
|
|
445
451
|
push(edge: EdgePush): void;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { OrdinalSceneNode, OrdinalLayout } from "../ordinalTypes";
|
|
2
|
+
import type { OrdinalSceneContext } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Bar-funnel scene builder (vertical orientation).
|
|
5
|
+
*
|
|
6
|
+
* Renders funnel data as vertical bars — one per step on the x-axis.
|
|
7
|
+
* Each bar is stacked: solid bottom = retained value, hatched top = dropoff
|
|
8
|
+
* from the previous step. The first step has no dropoff (100% solid).
|
|
9
|
+
*
|
|
10
|
+
* Multi-category: bars are grouped side-by-side within each step,
|
|
11
|
+
* each with its own retained + dropoff stack.
|
|
12
|
+
*
|
|
13
|
+
* The rScale (y-axis) is set by the pipeline based on the data's max value.
|
|
14
|
+
* Bars are sized proportionally via scales.r so the first step fills the
|
|
15
|
+
* available height and subsequent steps shrink relative to it.
|
|
16
|
+
*
|
|
17
|
+
* Metadata on each rect datum (used by barFunnelLabelRenderer):
|
|
18
|
+
* - __barFunnelValue: numeric value for this bar
|
|
19
|
+
* - __barFunnelPercent: percent of this category's first-step value
|
|
20
|
+
* - __barFunnelIsFirstStep: true for step index 0
|
|
21
|
+
* - __barFunnelIsDropoff: true for the dropoff portion (hatched)
|
|
22
|
+
* - __barFunnelStep: step name
|
|
23
|
+
* - __barFunnelDropoffValue: the dropoff amount
|
|
24
|
+
* - __barFunnelCategory: category key (for multi-category)
|
|
25
|
+
* - __barFunnelLabelX/Y: position for the floating label
|
|
26
|
+
*/
|
|
27
|
+
export declare function buildBarFunnelScene(ctx: OrdinalSceneContext, layout: OrdinalLayout): OrdinalSceneNode[];
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { OrdinalSceneNode, OrdinalLayout } from "../ordinalTypes";
|
|
2
|
+
import type { OrdinalSceneContext } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Funnel scene builder.
|
|
5
|
+
*
|
|
6
|
+
* Steps run top-to-bottom. Each step is a horizontal row whose bar width is
|
|
7
|
+
* proportional to its value. Multiple categories mirror around the center axis:
|
|
8
|
+
* with 2 categories, one extends right and the other extends left.
|
|
9
|
+
*
|
|
10
|
+
* Produces:
|
|
11
|
+
* - RectSceneNode for each bar (step × category)
|
|
12
|
+
* - TrapezoidSceneNode for each connector between consecutive steps
|
|
13
|
+
*
|
|
14
|
+
* Label metadata on each rect datum (used by funnelLabelRenderer):
|
|
15
|
+
* - __funnelStepLabel: step name (only on first category rect per row)
|
|
16
|
+
* - __funnelValue: numeric value for this bar
|
|
17
|
+
* - __funnelPercent: percent of this category's first-step value
|
|
18
|
+
* - __funnelIsFirstStep: true for step index 0 (suppresses "100%")
|
|
19
|
+
* - __funnelStepLabelX/Y: center position for step name
|
|
20
|
+
* - __funnelValueLabelX/Y: center position for value label
|
|
21
|
+
* - __funnelBarW: pixel width of this bar (for min-size suppression)
|
|
22
|
+
*
|
|
23
|
+
* NOTE: FunnelChart HOC uses projection="horizontal" so the ordinal band
|
|
24
|
+
* scale maps to layout.height (y-axis). col.x = y-position, col.width = band height.
|
|
25
|
+
*/
|
|
26
|
+
export declare function buildFunnelScene(ctx: OrdinalSceneContext, layout: OrdinalLayout): OrdinalSceneNode[];
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { OrdinalSceneNode, OrdinalLayout } from "../ordinalTypes";
|
|
2
|
+
import type { OrdinalSceneContext } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Swimlane scene builder.
|
|
5
|
+
*
|
|
6
|
+
* Each category (oAccessor) defines a horizontal lane.
|
|
7
|
+
* Items within a lane are stacked left-to-right (or bottom-to-top in vertical),
|
|
8
|
+
* colored by subcategory (stackBy/colorBy). Unlike a standard stacked bar,
|
|
9
|
+
* multiple items with the same subcategory can appear in the same lane —
|
|
10
|
+
* they simply stack sequentially.
|
|
11
|
+
*/
|
|
12
|
+
export declare function buildSwimlaneScene(ctx: OrdinalSceneContext, layout: OrdinalLayout): OrdinalSceneNode[];
|