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.
Files changed (53) hide show
  1. package/CLAUDE.md +118 -264
  2. package/README.md +37 -17
  3. package/ai/schema.json +1 -1
  4. package/ai/system-prompt.md +3 -3
  5. package/dist/components/charts/ordinal/SwimlaneChart.d.ts +4 -0
  6. package/dist/components/charts/realtime/RealtimeHeatmap.d.ts +2 -0
  7. package/dist/components/charts/realtime/RealtimeHistogram.d.ts +2 -0
  8. package/dist/components/charts/realtime/RealtimeLineChart.d.ts +2 -0
  9. package/dist/components/charts/realtime/RealtimeSwarmChart.d.ts +2 -0
  10. package/dist/components/charts/realtime/RealtimeWaterfallChart.d.ts +2 -0
  11. package/dist/components/charts/shared/hooks.d.ts +2 -1
  12. package/dist/components/charts/shared/types.d.ts +6 -2
  13. package/dist/components/charts/shared/useChartSetup.d.ts +1 -1
  14. package/dist/components/realtime/RingBuffer.d.ts +11 -0
  15. package/dist/components/realtime/types.d.ts +4 -0
  16. package/dist/components/semiotic-server.d.ts +6 -1
  17. package/dist/components/server/animatedGif.d.ts +78 -0
  18. package/dist/components/server/renderToStaticSVG.d.ts +85 -5
  19. package/dist/components/server/staticAnnotations.d.ts +40 -0
  20. package/dist/components/server/staticLegend.d.ts +39 -0
  21. package/dist/components/server/svgHatchPattern.d.ts +26 -0
  22. package/dist/components/server/themeResolver.d.ts +35 -0
  23. package/dist/components/stream/GeoPipelineStore.d.ts +6 -1
  24. package/dist/components/stream/NetworkPipelineStore.d.ts +20 -0
  25. package/dist/components/stream/OrdinalPipelineStore.d.ts +11 -0
  26. package/dist/components/stream/OrdinalSVGOverlay.d.ts +5 -0
  27. package/dist/components/stream/PipelineStore.d.ts +11 -0
  28. package/dist/components/stream/accessorUtils.d.ts +3 -3
  29. package/dist/components/stream/geoTypes.d.ts +2 -0
  30. package/dist/components/stream/networkTypes.d.ts +33 -0
  31. package/dist/components/stream/ordinalTypes.d.ts +30 -3
  32. package/dist/components/stream/renderers/resolveCSSColor.d.ts +17 -0
  33. package/dist/components/stream/types.d.ts +4 -0
  34. package/dist/geo.min.js +1 -1
  35. package/dist/geo.module.min.js +1 -1
  36. package/dist/network.min.js +1 -1
  37. package/dist/network.module.min.js +1 -1
  38. package/dist/ordinal.min.js +1 -1
  39. package/dist/ordinal.module.min.js +1 -1
  40. package/dist/realtime.min.js +1 -1
  41. package/dist/realtime.module.min.js +1 -1
  42. package/dist/semiotic-ai.min.js +1 -1
  43. package/dist/semiotic-ai.module.min.js +1 -1
  44. package/dist/semiotic-server.d.ts +6 -1
  45. package/dist/semiotic-utils.min.js +1 -1
  46. package/dist/semiotic-utils.module.min.js +1 -1
  47. package/dist/semiotic.min.js +1 -1
  48. package/dist/semiotic.module.min.js +1 -1
  49. package/dist/server.min.js +1 -1
  50. package/dist/server.module.min.js +1 -1
  51. package/dist/xy.min.js +1 -1
  52. package/dist/xy.module.min.js +1 -1
  53. package/package.json +14 -3
@@ -1,6 +1,6 @@
1
1
  # Semiotic — React Data Visualization
2
2
 
3
- Use `import { ComponentName } from "semiotic/ai"` for all components below.
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**: `renderToStaticSVG("ordinal", props)` or `renderOrdinalToStaticSVG(props)` from `semiotic/server`. Frame type is `"xy"` | `"ordinal"` | `"network"` (NOT component name).
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 | "series";
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. "series" dims by the colorBy group key. */
97
- hoverHighlight?: boolean | "series";
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 | "series";
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
- export declare function renderToStaticSVG(frameType: FrameType, props: StreamXYFrameProps | StreamNetworkFrameProps | StreamOrdinalFrameProps | StreamGeoFrameProps): string;
14
- export declare function renderXYToStaticSVG(props: StreamXYFrameProps): string;
15
- export declare function renderOrdinalToStaticSVG(props: StreamOrdinalFrameProps): string;
16
- export declare function renderNetworkToStaticSVG(props: StreamNetworkFrameProps): string;
17
- export declare function renderGeoToStaticSVG(props: StreamGeoFrameProps): string;
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
- private getPoints;
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>(accessor: string | ((d: T) => number) | undefined, fallback: string): (d: T) => number;
16
- export declare function resolveRawAccessor<T>(accessor: string | ((d: T) => any) | undefined, fallback: string): (d: T) => any;
17
- export declare function resolveStringAccessor<T>(accessor: string | ((d: T) => string) | undefined, fallback?: string): ((d: T) => string) | undefined;
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;