semiotic 3.2.3 → 3.3.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/CLAUDE.md +118 -264
- package/README.md +37 -17
- package/ai/schema.json +1 -1
- package/ai/system-prompt.md +3 -3
- package/dist/components/charts/ordinal/SwimlaneChart.d.ts +4 -0
- package/dist/components/charts/realtime/RealtimeHeatmap.d.ts +2 -0
- package/dist/components/charts/realtime/RealtimeHistogram.d.ts +2 -0
- package/dist/components/charts/realtime/RealtimeLineChart.d.ts +2 -0
- package/dist/components/charts/realtime/RealtimeSwarmChart.d.ts +2 -0
- package/dist/components/charts/realtime/RealtimeWaterfallChart.d.ts +2 -0
- package/dist/components/charts/shared/hooks.d.ts +2 -1
- package/dist/components/charts/shared/types.d.ts +6 -2
- package/dist/components/charts/shared/useChartSetup.d.ts +1 -1
- package/dist/components/realtime/RingBuffer.d.ts +11 -0
- package/dist/components/realtime/types.d.ts +4 -0
- package/dist/components/semiotic-server.d.ts +6 -1
- package/dist/components/server/animatedGif.d.ts +78 -0
- package/dist/components/server/renderToStaticSVG.d.ts +85 -5
- package/dist/components/server/staticAnnotations.d.ts +40 -0
- package/dist/components/server/staticLegend.d.ts +39 -0
- package/dist/components/server/svgHatchPattern.d.ts +26 -0
- package/dist/components/server/themeResolver.d.ts +35 -0
- package/dist/components/stream/GeoPipelineStore.d.ts +6 -1
- package/dist/components/stream/NetworkPipelineStore.d.ts +20 -0
- package/dist/components/stream/OrdinalPipelineStore.d.ts +11 -0
- package/dist/components/stream/OrdinalSVGOverlay.d.ts +5 -0
- package/dist/components/stream/PipelineStore.d.ts +11 -0
- package/dist/components/stream/accessorUtils.d.ts +3 -3
- package/dist/components/stream/geoTypes.d.ts +2 -0
- package/dist/components/stream/networkTypes.d.ts +33 -0
- package/dist/components/stream/ordinalTypes.d.ts +30 -3
- package/dist/components/stream/renderers/resolveCSSColor.d.ts +17 -0
- package/dist/components/stream/types.d.ts +4 -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.min.js +1 -1
- package/dist/semiotic-ai.module.min.js +1 -1
- package/dist/semiotic-server.d.ts +6 -1
- package/dist/semiotic-utils.min.js +1 -1
- package/dist/semiotic-utils.module.min.js +1 -1
- 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.min.js +1 -1
- package/dist/xy.module.min.js +1 -1
- package/package.json +14 -3
package/ai/system-prompt.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Semiotic — React Data Visualization
|
|
2
2
|
|
|
3
|
-
Use `
|
|
3
|
+
Use sub-path imports: `semiotic/xy` (143KB gz), `semiotic/ordinal` (109KB), `semiotic/network` (98KB), `semiotic/geo` (93KB), `semiotic/realtime` (145KB). Or `semiotic/ai` for all 38 HOCs in one import (269KB).
|
|
4
4
|
|
|
5
5
|
## Flat Array Data (`data: object[]`)
|
|
6
6
|
- **LineChart** — `xAccessor`, `yAccessor`, `lineBy` (multi-line), `curve`
|
|
@@ -58,7 +58,7 @@ const chartRef = useRef()
|
|
|
58
58
|
chartRef.current.push({ x: 1, y: 2 })
|
|
59
59
|
<Scatterplot ref={chartRef} xAccessor="x" yAccessor="y" />
|
|
60
60
|
```
|
|
61
|
-
Methods: `push(datum)`, `pushMany(data)`, `clear()`, `getData()`. Streaming-specific props (`windowSize`, `decay`, `pulse`) go in `frameProps`. Supported: XY charts, ordinal charts, network charts (ForceDirectedGraph, SankeyDiagram, ChordDiagram), ProportionalSymbolMap, DistanceCartogram. Not supported: hierarchy charts (TreeDiagram, Treemap, CirclePack, OrbitDiagram), ChoroplethMap, FlowMap, ScatterplotMatrix.
|
|
61
|
+
Methods: `push(datum)`, `pushMany(data)`, `remove(id)` (requires `pointIdAccessor`/`dataIdAccessor`), `update(id, updater)`, `clear()`, `getData()`. Network HOC refs use `remove()`/`update()` for node operations. Edge-level methods (`removeNode`, `removeEdge`, `updateNode`, `updateEdge`) are on `StreamNetworkFrameHandle`. Geo charts: `update()` is implemented as remove+push internally. Streaming-specific props (`windowSize`, `decay`, `pulse`) go in `frameProps`. Supported: XY charts, ordinal charts, network charts (ForceDirectedGraph, SankeyDiagram, ChordDiagram), ProportionalSymbolMap, DistanceCartogram. Not supported: hierarchy charts (TreeDiagram, Treemap, CirclePack, OrbitDiagram), ChoroplethMap, FlowMap, ScatterplotMatrix.
|
|
62
62
|
|
|
63
63
|
For advanced streaming control, use Stream Frames (`StreamXYFrame`, `StreamOrdinalFrame`, `StreamNetworkFrame`) with `runtimeMode="streaming"` and ref-based push.
|
|
64
64
|
|
|
@@ -113,5 +113,5 @@ Or use ThemeProvider with 15 named presets: `<ThemeProvider theme="tufte">`, `"t
|
|
|
113
113
|
|
|
114
114
|
## Key Patterns
|
|
115
115
|
- **Percentile band + main line**: Layer `<AreaChart yAccessor="p95" y0Accessor="p5" showLine={false} />` + `<LineChart yAccessor="p50" />`. AreaChart's `showLine` only draws the top edge, NOT a separate main line.
|
|
116
|
-
- **SSR**: `
|
|
116
|
+
- **SSR**: `renderChart("BarChart", props)` from `semiotic/server` — uses HOC names. Also `"Sparkline"` (no axes, 2px margins). `renderToImage()` (PNG), `renderToAnimatedGif()` (GIF), `renderDashboard()` (multi-chart). All accept `theme`. Required props: StackedBarChart needs `stackBy`, GroupedBarChart needs `groupBy`, StackedAreaChart needs `areaBy`, BubbleChart needs `sizeBy`, FunnelChart uses `stepAccessor`, GaugeChart needs `thresholds`.
|
|
117
117
|
- **exportChart**: Pass the wrapper div, not the SVG element: `exportChart(wrapperDiv, { format: "png" })`. It finds canvas+SVG internally.
|
|
@@ -56,6 +56,10 @@ export interface SwimlaneChartProps<TDatum extends Record<string, any> = Record<
|
|
|
56
56
|
};
|
|
57
57
|
/** Custom formatter for category tick labels */
|
|
58
58
|
categoryFormat?: CategoryFormatFn;
|
|
59
|
+
/** Custom tick values for the value axis. Forces specific values instead of d3 auto-ticks. */
|
|
60
|
+
rTickValues?: number[];
|
|
61
|
+
/** Align first value tick label to start, last to end. Prevents clipping at chart edges. */
|
|
62
|
+
tickLabelEdgeAlign?: boolean;
|
|
59
63
|
/** Pass-through props to StreamOrdinalFrame */
|
|
60
64
|
frameProps?: Partial<Omit<StreamOrdinalFrameProps, "data" | "size">>;
|
|
61
65
|
}
|
|
@@ -96,6 +96,8 @@ export interface RealtimeHeatmapProps<TDatum extends Record<string, any> = Recor
|
|
|
96
96
|
legendPosition?: LegendPosition;
|
|
97
97
|
/** Legend interaction mode */
|
|
98
98
|
legendInteraction?: LegendInteractionMode;
|
|
99
|
+
/** ID accessor for remove()/update() on the push API */
|
|
100
|
+
pointIdAccessor?: string | ((d: any) => string);
|
|
99
101
|
}
|
|
100
102
|
/**
|
|
101
103
|
* RealtimeHeatmap - Streaming heatmap with 2D grid binning.
|
|
@@ -130,6 +130,8 @@ export interface RealtimeTemporalHistogramProps<TDatum extends Record<string, an
|
|
|
130
130
|
legendPosition?: LegendPosition;
|
|
131
131
|
/** Legend interaction mode */
|
|
132
132
|
legendInteraction?: LegendInteractionMode;
|
|
133
|
+
/** ID accessor for remove()/update() on the push API */
|
|
134
|
+
pointIdAccessor?: string | ((d: any) => string);
|
|
133
135
|
}
|
|
134
136
|
/**
|
|
135
137
|
* RealtimeTemporalHistogram - Streaming temporal histogram.
|
|
@@ -96,6 +96,8 @@ export interface RealtimeLineChartProps<TDatum extends Record<string, any> = Rec
|
|
|
96
96
|
legendPosition?: LegendPosition;
|
|
97
97
|
/** Legend interaction mode */
|
|
98
98
|
legendInteraction?: LegendInteractionMode;
|
|
99
|
+
/** ID accessor for remove()/update() on the push API */
|
|
100
|
+
pointIdAccessor?: string | ((d: any) => string);
|
|
99
101
|
}
|
|
100
102
|
/**
|
|
101
103
|
* RealtimeLineChart - Simplified wrapper for streaming line charts.
|
|
@@ -96,6 +96,8 @@ export interface RealtimeSwarmChartProps<TDatum extends Record<string, any> = Re
|
|
|
96
96
|
legendPosition?: LegendPosition;
|
|
97
97
|
/** Legend interaction mode */
|
|
98
98
|
legendInteraction?: LegendInteractionMode;
|
|
99
|
+
/** ID accessor for remove()/update() on the push API */
|
|
100
|
+
pointIdAccessor?: string | ((d: any) => string);
|
|
99
101
|
}
|
|
100
102
|
/**
|
|
101
103
|
* RealtimeSwarmChart - Simplified wrapper for streaming dot/swarm charts.
|
|
@@ -96,6 +96,8 @@ export interface RealtimeWaterfallChartProps<TDatum extends Record<string, any>
|
|
|
96
96
|
legendPosition?: LegendPosition;
|
|
97
97
|
/** Legend interaction mode */
|
|
98
98
|
legendInteraction?: LegendInteractionMode;
|
|
99
|
+
/** ID accessor for remove()/update() on the push API */
|
|
100
|
+
pointIdAccessor?: string | ((d: any) => string);
|
|
99
101
|
}
|
|
100
102
|
/**
|
|
101
103
|
* RealtimeWaterfallChart - Simplified wrapper for streaming waterfall charts.
|
|
@@ -55,7 +55,7 @@ export declare function useChartSelection({ selection, linkedHover, fallbackFiel
|
|
|
55
55
|
x: number;
|
|
56
56
|
y: number;
|
|
57
57
|
}) => void;
|
|
58
|
-
hoverHighlight?: boolean
|
|
58
|
+
hoverHighlight?: boolean;
|
|
59
59
|
colorByField?: string;
|
|
60
60
|
}): {
|
|
61
61
|
activeSelectionHook: SelectionHookResult | null;
|
|
@@ -128,6 +128,7 @@ export declare function useLegendInteraction(mode: LegendInteractionMode | undef
|
|
|
128
128
|
interface ChartModeInput {
|
|
129
129
|
width?: number;
|
|
130
130
|
height?: number;
|
|
131
|
+
showAxes?: boolean;
|
|
131
132
|
showGrid?: boolean;
|
|
132
133
|
enableHover?: boolean;
|
|
133
134
|
showLegend?: boolean;
|
|
@@ -93,10 +93,14 @@ export interface BaseChartProps {
|
|
|
93
93
|
x: number;
|
|
94
94
|
y: number;
|
|
95
95
|
}) => void;
|
|
96
|
-
/** Dim non-hovered series when hovering a data mark.
|
|
97
|
-
hoverHighlight?: boolean
|
|
96
|
+
/** Dim non-hovered series when hovering a data mark. Requires `colorBy`. */
|
|
97
|
+
hoverHighlight?: boolean;
|
|
98
98
|
/** Max pixel distance for hover/click hit testing. Default 30. Increase for sparse charts, decrease for dense ones. */
|
|
99
99
|
hoverRadius?: number;
|
|
100
|
+
/** ID accessor for remove()/update() on XY charts. Extracts a unique identifier from each datum. */
|
|
101
|
+
pointIdAccessor?: string | ((d: any) => string);
|
|
102
|
+
/** ID accessor for remove()/update() on ordinal charts. Extracts a unique identifier from each datum. */
|
|
103
|
+
dataIdAccessor?: string | ((d: any) => string);
|
|
100
104
|
/** Visual emphasis level for dashboard hierarchy. "primary" spans two columns in ChartGrid. */
|
|
101
105
|
emphasis?: "primary" | "secondary";
|
|
102
106
|
/** Enable declarative bounded animation (enter/exit/update transitions).
|
|
@@ -56,7 +56,7 @@ export interface ChartSetupInput {
|
|
|
56
56
|
y: number;
|
|
57
57
|
}) => void;
|
|
58
58
|
/** Dim non-hovered series on data mark hover */
|
|
59
|
-
hoverHighlight?: boolean
|
|
59
|
+
hoverHighlight?: boolean;
|
|
60
60
|
/** Loading state */
|
|
61
61
|
loading: boolean | undefined;
|
|
62
62
|
/** Empty content override */
|
|
@@ -13,6 +13,17 @@ export declare class RingBuffer<T> {
|
|
|
13
13
|
forEach(callback: (value: T, index: number) => void): void;
|
|
14
14
|
toArray(): T[];
|
|
15
15
|
resize(newCapacity: number): T[];
|
|
16
|
+
/**
|
|
17
|
+
* Update items in place. The updater receives each matching item and returns
|
|
18
|
+
* the replacement. Returns the previous values of updated items.
|
|
19
|
+
* O(n) scan, no compaction needed — buffer positions stay stable.
|
|
20
|
+
*/
|
|
21
|
+
update(predicate: (item: T) => boolean, updater: (item: T) => T): T[];
|
|
22
|
+
/**
|
|
23
|
+
* Remove items matching a predicate. Returns removed items.
|
|
24
|
+
* O(n) scan + compaction. Size decreases; capacity stays the same.
|
|
25
|
+
*/
|
|
26
|
+
remove(predicate: (item: T) => boolean): T[];
|
|
16
27
|
clear(): void;
|
|
17
28
|
get size(): number;
|
|
18
29
|
get capacity(): number;
|
|
@@ -131,6 +131,10 @@ export interface RealtimeFrameProps {
|
|
|
131
131
|
export interface RealtimeFrameHandle {
|
|
132
132
|
push(point: Record<string, any>): void;
|
|
133
133
|
pushMany(points: Record<string, any>[]): void;
|
|
134
|
+
/** Remove data by ID. Requires an ID accessor (pointIdAccessor or dataIdAccessor). */
|
|
135
|
+
remove(id: string | string[]): Record<string, any>[];
|
|
136
|
+
/** Update data by ID in place. Requires an ID accessor. Returns previous values. */
|
|
137
|
+
update(id: string | string[], updater: (d: Record<string, any>) => Record<string, any>): Record<string, any>[];
|
|
134
138
|
clear(): void;
|
|
135
139
|
getData(): Record<string, any>[];
|
|
136
140
|
}
|
|
@@ -1 +1,6 @@
|
|
|
1
|
-
export { renderToStaticSVG, renderXYToStaticSVG, renderOrdinalToStaticSVG, renderNetworkToStaticSVG, renderGeoToStaticSVG } from "./server/renderToStaticSVG";
|
|
1
|
+
export { renderToStaticSVG, renderXYToStaticSVG, renderOrdinalToStaticSVG, renderNetworkToStaticSVG, renderGeoToStaticSVG, renderChart, renderToImage, renderDashboard, } from "./server/renderToStaticSVG";
|
|
2
|
+
export type { RenderToImageOptions, DashboardChart, DashboardLayout, RenderDashboardOptions, } from "./server/renderToStaticSVG";
|
|
3
|
+
export { renderToAnimatedGif, generateFrameSVGs, generateFrameSequence } from "./server/animatedGif";
|
|
4
|
+
export type { AnimatedGifOptions } from "./server/animatedGif";
|
|
5
|
+
export { resolveTheme, themeStyles } from "./server/themeResolver";
|
|
6
|
+
export type { ThemeInput } from "./server/themeResolver";
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Animated GIF generation from semiotic chart data.
|
|
3
|
+
*
|
|
4
|
+
* Renders a sequence of chart frames by progressively feeding data into
|
|
5
|
+
* PipelineStore, optionally applying transition easing and decay effects,
|
|
6
|
+
* then encoding all frames as an animated GIF.
|
|
7
|
+
*
|
|
8
|
+
* Phases:
|
|
9
|
+
* 1. Sliding window — slice data into progressive windows, render each
|
|
10
|
+
* 2. Transition easing — interpolate enter/update between data windows
|
|
11
|
+
* 3. Decay/pulse — apply age-based opacity fading per frame
|
|
12
|
+
*
|
|
13
|
+
* Requires: sharp (SVG→PNG rasterization), gifenc (GIF encoding)
|
|
14
|
+
* Both are optional dependencies of semiotic.
|
|
15
|
+
*/
|
|
16
|
+
import type { SemioticTheme } from "../store/ThemeStore";
|
|
17
|
+
export interface AnimatedGifOptions {
|
|
18
|
+
/** Frames per second (default 12) */
|
|
19
|
+
fps?: number;
|
|
20
|
+
/** Number of data points to advance per frame (default: auto-calculated) */
|
|
21
|
+
stepSize?: number;
|
|
22
|
+
/** Data points visible per frame (default: all data up to current step) */
|
|
23
|
+
windowSize?: number;
|
|
24
|
+
/** Total number of frames (default: auto from data length / stepSize) */
|
|
25
|
+
frameCount?: number;
|
|
26
|
+
/** Lock X axis domain to prevent shifting (default: auto from full data) */
|
|
27
|
+
xExtent?: [number, number];
|
|
28
|
+
/** Lock Y axis domain (default: auto from full data) */
|
|
29
|
+
yExtent?: [number, number];
|
|
30
|
+
/** Transition frames between data steps (0 = no easing, default 4). XY charts only — ordinal charts use instant transitions. */
|
|
31
|
+
transitionFrames?: number;
|
|
32
|
+
/** Easing for transitions (default "ease-out") */
|
|
33
|
+
easing?: "linear" | "ease-out";
|
|
34
|
+
/** Apply decay (age-based fade) to older data points */
|
|
35
|
+
decay?: {
|
|
36
|
+
type: "linear" | "exponential" | "step";
|
|
37
|
+
minOpacity?: number;
|
|
38
|
+
halfLife?: number;
|
|
39
|
+
};
|
|
40
|
+
/** Loop the GIF (default true) */
|
|
41
|
+
loop?: boolean;
|
|
42
|
+
/** Scale factor for resolution (default 1) */
|
|
43
|
+
scale?: number;
|
|
44
|
+
/** Background color */
|
|
45
|
+
background?: string;
|
|
46
|
+
}
|
|
47
|
+
export interface AnimatedGifFrameConfig {
|
|
48
|
+
/** Chart width */
|
|
49
|
+
width: number;
|
|
50
|
+
/** Chart height */
|
|
51
|
+
height: number;
|
|
52
|
+
/** Theme for styling */
|
|
53
|
+
theme: SemioticTheme;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Generate SVG strings for each animation frame.
|
|
57
|
+
* This is the core logic shared between GIF export and client-side preview.
|
|
58
|
+
*/
|
|
59
|
+
export declare function generateFrameSVGs(chartType: string, data: Record<string, any>[], props: Record<string, any>, options?: AnimatedGifOptions): string[];
|
|
60
|
+
/**
|
|
61
|
+
* Generate SVG strings from an array of data snapshots.
|
|
62
|
+
*
|
|
63
|
+
* Unlike `generateFrameSVGs` which slices a single array progressively,
|
|
64
|
+
* this accepts pre-built snapshots — each entry is the complete props
|
|
65
|
+
* for one frame. Use for scenarios where data changes non-monotonically
|
|
66
|
+
* (edge deletion, network splits, failover paths).
|
|
67
|
+
*
|
|
68
|
+
* Each snapshot is passed directly to `renderChart()`.
|
|
69
|
+
*/
|
|
70
|
+
export declare function generateFrameSequence(component: string, snapshots: Record<string, any>[], baseProps?: Record<string, any>): string[];
|
|
71
|
+
/**
|
|
72
|
+
* Render a chart as an animated GIF.
|
|
73
|
+
*
|
|
74
|
+
* Requires `sharp` (SVG→PNG) and `gifenc` (GIF encoding) as optional dependencies.
|
|
75
|
+
*
|
|
76
|
+
* @returns Buffer containing the animated GIF
|
|
77
|
+
*/
|
|
78
|
+
export declare function renderToAnimatedGif(chartType: string, data: Record<string, any>[], props: Record<string, any>, options?: AnimatedGifOptions): Promise<Buffer>;
|
|
@@ -4,15 +4,95 @@
|
|
|
4
4
|
* Uses the shared SceneToSVG converters (same code used by Stream Frames
|
|
5
5
|
* for SSR) plus PipelineStore / OrdinalPipelineStore / NetworkPipelineStore
|
|
6
6
|
* for scene graph computation.
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - Theme inlining (resolve presets to concrete SVG styles)
|
|
10
|
+
* - Legend rendering (categorical color swatches)
|
|
11
|
+
* - Accessibility (title, desc, role="img")
|
|
12
|
+
* - Grid lines
|
|
13
|
+
* - Annotations (y-threshold, x-threshold, band, label, text, category-highlight)
|
|
14
|
+
* - renderChart HOC-level API
|
|
7
15
|
*/
|
|
16
|
+
import * as React from "react";
|
|
8
17
|
import type { StreamXYFrameProps } from "../stream/types";
|
|
9
18
|
import type { StreamNetworkFrameProps } from "../stream/networkTypes";
|
|
10
19
|
import type { StreamOrdinalFrameProps } from "../stream/ordinalTypes";
|
|
11
20
|
import type { StreamGeoFrameProps } from "../stream/geoTypes";
|
|
21
|
+
import { type ThemeInput } from "./themeResolver";
|
|
12
22
|
type FrameType = "xy" | "ordinal" | "network" | "geo";
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
23
|
+
interface ThemeAwareProps {
|
|
24
|
+
theme?: ThemeInput;
|
|
25
|
+
showLegend?: boolean;
|
|
26
|
+
showGrid?: boolean;
|
|
27
|
+
annotations?: Record<string, any>[];
|
|
28
|
+
title?: string | React.ReactNode;
|
|
29
|
+
description?: string;
|
|
30
|
+
background?: string;
|
|
31
|
+
className?: string;
|
|
32
|
+
/** Prefix for SVG element IDs — used by renderDashboard to avoid collisions */
|
|
33
|
+
_idPrefix?: string;
|
|
34
|
+
}
|
|
35
|
+
export declare function renderToStaticSVG(frameType: FrameType, props: (StreamXYFrameProps | StreamNetworkFrameProps | StreamOrdinalFrameProps | StreamGeoFrameProps) & ThemeAwareProps): string;
|
|
36
|
+
export declare function renderXYToStaticSVG(props: StreamXYFrameProps & ThemeAwareProps): string;
|
|
37
|
+
export declare function renderOrdinalToStaticSVG(props: StreamOrdinalFrameProps & ThemeAwareProps): string;
|
|
38
|
+
export declare function renderNetworkToStaticSVG(props: StreamNetworkFrameProps & ThemeAwareProps): string;
|
|
39
|
+
export declare function renderGeoToStaticSVG(props: StreamGeoFrameProps & ThemeAwareProps): string;
|
|
40
|
+
/** Chart component name to frame type + props mapping */
|
|
41
|
+
type ChartName = "LineChart" | "AreaChart" | "StackedAreaChart" | "Scatterplot" | "BubbleChart" | "ConnectedScatterplot" | "Heatmap" | "Sparkline" | "BarChart" | "StackedBarChart" | "GroupedBarChart" | "PieChart" | "DonutChart" | "SwimlaneChart" | "Histogram" | "BoxPlot" | "ViolinPlot" | "SwarmPlot" | "DotPlot" | "RidgelinePlot" | "FunnelChart" | "GaugeChart" | "ForceDirectedGraph" | "SankeyDiagram" | "ChordDiagram" | "TreeDiagram" | "Treemap" | "CirclePack" | "ChoroplethMap" | "ProportionalSymbolMap";
|
|
42
|
+
interface RenderChartOptions {
|
|
43
|
+
/** Output format — currently only "svg" is synchronous */
|
|
44
|
+
format?: "svg";
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Render a chart using HOC-level props (categoryAccessor, valueAccessor, etc.)
|
|
48
|
+
* instead of frame-level props (oAccessor, rAccessor, etc.).
|
|
49
|
+
*
|
|
50
|
+
* This is the primary API for AI/MCP workflows.
|
|
51
|
+
*/
|
|
52
|
+
export declare function renderChart(component: ChartName, props: Record<string, any>, _options?: RenderChartOptions): string;
|
|
53
|
+
export interface RenderToImageOptions {
|
|
54
|
+
/** Output format */
|
|
55
|
+
format?: "png" | "jpeg";
|
|
56
|
+
/** Scale factor (e.g., 2 for retina) */
|
|
57
|
+
scale?: number;
|
|
58
|
+
/** Background color (overrides theme) */
|
|
59
|
+
background?: string;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Render a chart to a PNG or JPEG Buffer.
|
|
63
|
+
*
|
|
64
|
+
* Requires `sharp` as an optional peer dependency.
|
|
65
|
+
* Falls back to a descriptive error if sharp is not installed.
|
|
66
|
+
*/
|
|
67
|
+
export declare function renderToImage(frameTypeOrComponent: FrameType | ChartName, props: Record<string, any>, options?: RenderToImageOptions): Promise<Buffer>;
|
|
68
|
+
export interface DashboardChart {
|
|
69
|
+
/** Frame type or HOC component name */
|
|
70
|
+
component?: ChartName;
|
|
71
|
+
frameType?: FrameType;
|
|
72
|
+
/** Chart props (data, accessors, etc.) */
|
|
73
|
+
props: Record<string, any>;
|
|
74
|
+
/** Span multiple columns (for emphasis="primary") */
|
|
75
|
+
colSpan?: number;
|
|
76
|
+
}
|
|
77
|
+
export interface DashboardLayout {
|
|
78
|
+
/** Number of columns */
|
|
79
|
+
columns?: number;
|
|
80
|
+
/** Gap between charts in pixels */
|
|
81
|
+
gap?: number;
|
|
82
|
+
}
|
|
83
|
+
export interface RenderDashboardOptions {
|
|
84
|
+
title?: string;
|
|
85
|
+
subtitle?: string;
|
|
86
|
+
theme?: ThemeInput;
|
|
87
|
+
width?: number;
|
|
88
|
+
height?: number;
|
|
89
|
+
layout?: DashboardLayout;
|
|
90
|
+
background?: string;
|
|
91
|
+
/** Output format */
|
|
92
|
+
format?: "svg";
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Compose multiple charts into a single SVG.
|
|
96
|
+
*/
|
|
97
|
+
export declare function renderDashboard(charts: DashboardChart[], options?: RenderDashboardOptions): string;
|
|
18
98
|
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static annotation rendering for server-side SVG.
|
|
3
|
+
*
|
|
4
|
+
* Supports common annotation types without DOM or React hooks.
|
|
5
|
+
* Converts data coordinates to pixels using provided scales.
|
|
6
|
+
*/
|
|
7
|
+
import * as React from "react";
|
|
8
|
+
import type { SemioticTheme } from "../store/ThemeStore";
|
|
9
|
+
interface AnnotationScales {
|
|
10
|
+
x?: (v: any) => number;
|
|
11
|
+
y?: (v: any) => number;
|
|
12
|
+
/** For ordinal charts: band scale */
|
|
13
|
+
o?: {
|
|
14
|
+
(v: string): number | undefined;
|
|
15
|
+
bandwidth?: () => number;
|
|
16
|
+
};
|
|
17
|
+
/** For ordinal charts: value scale */
|
|
18
|
+
r?: (v: number) => number;
|
|
19
|
+
}
|
|
20
|
+
interface AnnotationLayout {
|
|
21
|
+
width: number;
|
|
22
|
+
height: number;
|
|
23
|
+
}
|
|
24
|
+
export interface StaticAnnotationConfig {
|
|
25
|
+
annotations: Record<string, any>[];
|
|
26
|
+
scales: AnnotationScales;
|
|
27
|
+
layout: AnnotationLayout;
|
|
28
|
+
theme: SemioticTheme;
|
|
29
|
+
/** ID prefix for multi-chart documents */
|
|
30
|
+
idPrefix?: string;
|
|
31
|
+
xAccessor?: string;
|
|
32
|
+
yAccessor?: string;
|
|
33
|
+
/** Ordinal projection — determines whether r maps to x or y */
|
|
34
|
+
projection?: "vertical" | "horizontal" | "radial";
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Render annotations as static SVG elements.
|
|
38
|
+
*/
|
|
39
|
+
export declare function renderStaticAnnotations(config: StaticAnnotationConfig): React.ReactNode;
|
|
40
|
+
export {};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static legend rendering for server-side SVG.
|
|
3
|
+
*
|
|
4
|
+
* Builds legend SVG elements from data + colorScheme without React hooks.
|
|
5
|
+
* Used by renderToStaticSVG when showLegend is true.
|
|
6
|
+
*/
|
|
7
|
+
import * as React from "react";
|
|
8
|
+
import type { SemioticTheme } from "../store/ThemeStore";
|
|
9
|
+
export interface StaticLegendConfig {
|
|
10
|
+
/** Category labels to show in legend */
|
|
11
|
+
categories: string[];
|
|
12
|
+
/** Color scheme — array of colors or d3-scale-chromatic name */
|
|
13
|
+
colorScheme?: string | string[];
|
|
14
|
+
/** Theme for text/font colors */
|
|
15
|
+
theme: SemioticTheme;
|
|
16
|
+
/** Legend position */
|
|
17
|
+
position?: "right" | "left" | "top" | "bottom";
|
|
18
|
+
/** Chart dimensions for positioning */
|
|
19
|
+
totalWidth: number;
|
|
20
|
+
totalHeight: number;
|
|
21
|
+
/** Chart margins */
|
|
22
|
+
margin: {
|
|
23
|
+
top: number;
|
|
24
|
+
right: number;
|
|
25
|
+
bottom: number;
|
|
26
|
+
left: number;
|
|
27
|
+
};
|
|
28
|
+
/** Title presence (affects top-position offset) */
|
|
29
|
+
hasTitle?: boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Render a static legend as SVG elements.
|
|
33
|
+
* Returns null if no categories to show.
|
|
34
|
+
*/
|
|
35
|
+
export declare function renderStaticLegend(config: StaticLegendConfig): React.ReactNode;
|
|
36
|
+
/**
|
|
37
|
+
* Extract unique categories from data using an accessor.
|
|
38
|
+
*/
|
|
39
|
+
export declare function extractCategories(data: any[], accessor: string | ((d: any) => string) | undefined): string[];
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SVG hatch pattern for server-side rendering.
|
|
3
|
+
*
|
|
4
|
+
* Creates a <pattern> element that can be referenced via url(#id) fill.
|
|
5
|
+
* The SVG equivalent of createHatchPattern() which produces CanvasPatterns.
|
|
6
|
+
*/
|
|
7
|
+
import * as React from "react";
|
|
8
|
+
export interface SVGHatchOptions {
|
|
9
|
+
/** Pattern ID — must be unique within the SVG */
|
|
10
|
+
id: string;
|
|
11
|
+
/** Background color */
|
|
12
|
+
background?: string;
|
|
13
|
+
/** Line color */
|
|
14
|
+
stroke?: string;
|
|
15
|
+
/** Line width @default 1.5 */
|
|
16
|
+
lineWidth?: number;
|
|
17
|
+
/** Spacing between lines @default 6 */
|
|
18
|
+
spacing?: number;
|
|
19
|
+
/** Angle in degrees @default 45 */
|
|
20
|
+
angle?: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Create an SVG <pattern> element for diagonal hatch fills.
|
|
24
|
+
* Place inside <defs> and reference with fill="url(#id)".
|
|
25
|
+
*/
|
|
26
|
+
export declare function createSVGHatchPattern(options: SVGHatchOptions): React.ReactElement;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme resolution for server-side rendering.
|
|
3
|
+
*
|
|
4
|
+
* Resolves theme presets and partial theme objects to concrete
|
|
5
|
+
* SemioticTheme instances with all color/font values resolved.
|
|
6
|
+
* No CSS custom properties — everything is concrete for inline SVG.
|
|
7
|
+
*/
|
|
8
|
+
import type { SemioticTheme } from "../store/ThemeStore";
|
|
9
|
+
export type ThemeInput = string | Partial<SemioticTheme> | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* Resolve a theme input to a full SemioticTheme object.
|
|
12
|
+
*
|
|
13
|
+
* - undefined → LIGHT_THEME
|
|
14
|
+
* - string → named preset ("dark", "tufte", "carbon-dark", etc.)
|
|
15
|
+
* - object with mode → merge onto matching base theme
|
|
16
|
+
* - object without mode → merge onto LIGHT_THEME
|
|
17
|
+
*/
|
|
18
|
+
export declare function resolveTheme(theme: ThemeInput): SemioticTheme;
|
|
19
|
+
/**
|
|
20
|
+
* Extract concrete style values from a resolved theme for use in SVG attributes.
|
|
21
|
+
* Returns a flat object of commonly-needed values.
|
|
22
|
+
*/
|
|
23
|
+
export declare function themeStyles(theme: SemioticTheme): {
|
|
24
|
+
background: string;
|
|
25
|
+
text: string;
|
|
26
|
+
textSecondary: string;
|
|
27
|
+
grid: string;
|
|
28
|
+
border: string;
|
|
29
|
+
primary: string;
|
|
30
|
+
fontFamily: string;
|
|
31
|
+
titleSize: number;
|
|
32
|
+
labelSize: number;
|
|
33
|
+
tickSize: number;
|
|
34
|
+
categorical: string[];
|
|
35
|
+
};
|
|
@@ -39,6 +39,11 @@ export declare class GeoPipelineStore {
|
|
|
39
39
|
pushPoint(datum: Record<string, any>): void;
|
|
40
40
|
/** Push multiple streaming points */
|
|
41
41
|
pushMany(data: Record<string, any>[]): void;
|
|
42
|
+
/**
|
|
43
|
+
* Remove points by ID. Requires pointIdAccessor to be configured.
|
|
44
|
+
* Returns the removed items.
|
|
45
|
+
*/
|
|
46
|
+
removePoint(id: string | string[]): Record<string, any>[];
|
|
42
47
|
clear(): void;
|
|
43
48
|
computeScene(layout: StreamLayout): void;
|
|
44
49
|
private fitProjection;
|
|
@@ -70,7 +75,7 @@ export declare class GeoPipelineStore {
|
|
|
70
75
|
scale: number;
|
|
71
76
|
translate: [number, number];
|
|
72
77
|
};
|
|
73
|
-
|
|
78
|
+
getPoints(): Record<string, any>[];
|
|
74
79
|
private buildSceneNodes;
|
|
75
80
|
private applyCartogramTransform;
|
|
76
81
|
private applyDecay;
|
|
@@ -126,5 +126,25 @@ export declare class NetworkPipelineStore {
|
|
|
126
126
|
nodes: RealtimeNode[];
|
|
127
127
|
edges: RealtimeEdge[];
|
|
128
128
|
};
|
|
129
|
+
/**
|
|
130
|
+
* Update a node's data by ID. Returns the previous data, or null if not found.
|
|
131
|
+
*/
|
|
132
|
+
updateNode(id: string, updater: (data: Record<string, any>) => Record<string, any>): Record<string, any> | null;
|
|
133
|
+
/**
|
|
134
|
+
* Update all edges between source and target. Handles parallel edges.
|
|
135
|
+
* Returns array of previous data values (one per updated edge), or empty array.
|
|
136
|
+
*/
|
|
137
|
+
updateEdge(sourceId: string, targetId: string, updater: (data: Record<string, any>) => Record<string, any>): Record<string, any>[];
|
|
138
|
+
/**
|
|
139
|
+
* Remove a node by ID. Also removes all edges connected to this node.
|
|
140
|
+
* Returns true if the node was found and removed.
|
|
141
|
+
*/
|
|
142
|
+
removeNode(id: string): boolean;
|
|
143
|
+
/**
|
|
144
|
+
* Remove all edges between source and target node IDs.
|
|
145
|
+
* Handles parallel edges (multiple edges between the same pair).
|
|
146
|
+
* Returns true if at least one edge was removed.
|
|
147
|
+
*/
|
|
148
|
+
removeEdge(sourceId: string, targetId: string): boolean;
|
|
129
149
|
clear(): void;
|
|
130
150
|
}
|
|
@@ -32,6 +32,7 @@ export declare class OrdinalPipelineStore {
|
|
|
32
32
|
private getGroup;
|
|
33
33
|
private getColor;
|
|
34
34
|
private getConnector;
|
|
35
|
+
private getDataId;
|
|
35
36
|
/** Discovered categories in insertion order */
|
|
36
37
|
private categories;
|
|
37
38
|
/** True once a non-bounded (push) changeset has been ingested */
|
|
@@ -77,6 +78,16 @@ export declare class OrdinalPipelineStore {
|
|
|
77
78
|
private startTransition;
|
|
78
79
|
advanceTransition(now: number): boolean;
|
|
79
80
|
getData(): Record<string, any>[];
|
|
81
|
+
/**
|
|
82
|
+
* Remove data items by ID. Requires dataIdAccessor to be configured.
|
|
83
|
+
* Returns the removed items. Marks the store dirty for scene rebuild.
|
|
84
|
+
*/
|
|
85
|
+
remove(id: string | string[]): Record<string, any>[];
|
|
86
|
+
/**
|
|
87
|
+
* Update data items by ID. Requires dataIdAccessor.
|
|
88
|
+
* Returns the previous values. Categories and extents are rebuilt.
|
|
89
|
+
*/
|
|
90
|
+
update(id: string | string[], updater: (d: Record<string, any>) => Record<string, any>): Record<string, any>[];
|
|
80
91
|
clear(): void;
|
|
81
92
|
get size(): number;
|
|
82
93
|
getOAccessor(): (d: any) => string;
|
|
@@ -21,6 +21,10 @@ interface OrdinalSVGOverlayProps {
|
|
|
21
21
|
rLabel?: string;
|
|
22
22
|
oFormat?: (d: string, index?: number) => string | React.ReactNode;
|
|
23
23
|
rFormat?: (d: number) => string;
|
|
24
|
+
/** Custom tick values for the value (r) axis */
|
|
25
|
+
rTickValues?: number[];
|
|
26
|
+
/** Align first tick label to start, last to end */
|
|
27
|
+
tickLabelEdgeAlign?: boolean;
|
|
24
28
|
showGrid?: boolean;
|
|
25
29
|
title?: string | ReactNode;
|
|
26
30
|
legend?: ReactNode | {
|
|
@@ -63,6 +67,7 @@ interface OrdinalSVGUnderlayProps {
|
|
|
63
67
|
showAxes?: boolean;
|
|
64
68
|
showGrid?: boolean;
|
|
65
69
|
rFormat?: (d: number) => string;
|
|
70
|
+
rTickValues?: number[];
|
|
66
71
|
}
|
|
67
72
|
export declare function OrdinalSVGUnderlay(props: OrdinalSVGUnderlayProps): React.JSX.Element | null;
|
|
68
73
|
export declare function OrdinalSVGOverlay(props: OrdinalSVGOverlayProps): React.JSX.Element | null;
|
|
@@ -197,6 +197,17 @@ export declare class PipelineStore {
|
|
|
197
197
|
*/
|
|
198
198
|
private getBufferArray;
|
|
199
199
|
getData(): Record<string, any>[];
|
|
200
|
+
/**
|
|
201
|
+
* Remove data points by ID. Requires pointIdAccessor to be configured.
|
|
202
|
+
* Returns the removed items. Marks the store dirty for scene rebuild.
|
|
203
|
+
*/
|
|
204
|
+
remove(id: string | string[]): Record<string, any>[];
|
|
205
|
+
/**
|
|
206
|
+
* Update data points by ID. Requires pointIdAccessor.
|
|
207
|
+
* The updater receives the current datum and returns the replacement.
|
|
208
|
+
* Returns the previous values. Extents and scene are marked dirty.
|
|
209
|
+
*/
|
|
210
|
+
update(id: string | string[], updater: (d: Record<string, any>) => Record<string, any>): Record<string, any>[];
|
|
200
211
|
/** Returns sorted bin boundary values from the last bar scene build. Persists until clear() or the next bar scene build. */
|
|
201
212
|
getBinBoundaries(): number[];
|
|
202
213
|
getExtents(): {
|
|
@@ -12,6 +12,6 @@
|
|
|
12
12
|
* the variable in the dependency array so the reference changes when behavior changes.
|
|
13
13
|
*/
|
|
14
14
|
export declare function accessorsEquivalent(a: string | ((...args: any[]) => any) | undefined, b: string | ((...args: any[]) => any) | undefined): boolean;
|
|
15
|
-
export declare function resolveAccessor<T
|
|
16
|
-
export declare function resolveRawAccessor<T
|
|
17
|
-
export declare function resolveStringAccessor<T
|
|
15
|
+
export declare function resolveAccessor<T extends Record<string, unknown>>(accessor: string | ((d: T) => number) | undefined, fallback: string): (d: T) => number;
|
|
16
|
+
export declare function resolveRawAccessor<T extends Record<string, unknown>>(accessor: string | ((d: T) => unknown) | undefined, fallback: string): (d: T) => unknown;
|
|
17
|
+
export declare function resolveStringAccessor<T extends Record<string, unknown>>(accessor: string | ((d: T) => string) | undefined, fallback?: string): ((d: T) => string) | undefined;
|
|
@@ -171,6 +171,8 @@ export interface StreamGeoFrameProps<T = Record<string, any>> {
|
|
|
171
171
|
export interface StreamGeoFrameHandle {
|
|
172
172
|
push(datum: Record<string, any>): void;
|
|
173
173
|
pushMany(data: Record<string, any>[]): void;
|
|
174
|
+
/** Remove points by ID. Requires pointIdAccessor. */
|
|
175
|
+
removePoint(id: string | string[]): Record<string, any>[];
|
|
174
176
|
clear(): void;
|
|
175
177
|
getProjection(): GeoProjection | null;
|
|
176
178
|
getGeoPath(): GeoPath<any, GeoPermissibleObjects> | null;
|