semiotic 3.5.0 → 3.5.2

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 (105) hide show
  1. package/CLAUDE.md +21 -19
  2. package/README.md +22 -16
  3. package/ai/chartSuggestions.cjs +191 -3
  4. package/ai/componentMetadata.cjs +3 -3
  5. package/ai/dist/mcp-server.js +266 -48
  6. package/ai/examples.md +68 -0
  7. package/ai/schema.json +900 -1
  8. package/ai/system-prompt.md +4 -1
  9. package/dist/components/Tooltip/FlippingTooltip.d.ts +16 -1
  10. package/dist/components/charts/geo/FlowMap.d.ts +13 -4
  11. package/dist/components/charts/index.d.ts +6 -0
  12. package/dist/components/charts/network/OrbitDiagram.d.ts +5 -5
  13. package/dist/components/charts/network/ProcessSankey.d.ts +141 -0
  14. package/dist/components/charts/network/processSankey/algorithm.d.ts +136 -0
  15. package/dist/components/charts/network/processSankey/buildScenes.d.ts +45 -0
  16. package/dist/components/charts/network/processSankey/ribbonInputs.d.ts +32 -0
  17. package/dist/components/charts/network/processSankey/streamingLayout.d.ts +58 -0
  18. package/dist/components/charts/network/processSankey/tooltipUtils.d.ts +41 -0
  19. package/dist/components/charts/ordinal/BarChart.d.ts +14 -0
  20. package/dist/components/charts/ordinal/BoxPlot.d.ts +2 -0
  21. package/dist/components/charts/ordinal/DotPlot.d.ts +11 -0
  22. package/dist/components/charts/ordinal/GaugeChart.d.ts +20 -0
  23. package/dist/components/charts/ordinal/GroupedBarChart.d.ts +2 -0
  24. package/dist/components/charts/ordinal/Histogram.d.ts +2 -0
  25. package/dist/components/charts/ordinal/LikertChart.d.ts +2 -0
  26. package/dist/components/charts/ordinal/RidgelinePlot.d.ts +2 -0
  27. package/dist/components/charts/ordinal/StackedBarChart.d.ts +2 -0
  28. package/dist/components/charts/ordinal/SwarmPlot.d.ts +2 -0
  29. package/dist/components/charts/ordinal/SwimlaneChart.d.ts +7 -0
  30. package/dist/components/charts/ordinal/ViolinPlot.d.ts +2 -0
  31. package/dist/components/charts/realtime/RealtimeHistogram.d.ts +14 -11
  32. package/dist/components/charts/realtime/defaultRealtimeTooltip.d.ts +43 -0
  33. package/dist/components/charts/shared/axisExtent.d.ts +59 -0
  34. package/dist/components/charts/shared/chartSpecs.d.ts +75 -0
  35. package/dist/components/charts/shared/colorUtils.d.ts +8 -2
  36. package/dist/components/charts/shared/networkUtils.d.ts +3 -5
  37. package/dist/components/charts/shared/radialGeometry.d.ts +99 -0
  38. package/dist/components/charts/shared/regressionUtils.d.ts +59 -0
  39. package/dist/components/charts/shared/selectionUtils.d.ts +8 -1
  40. package/dist/components/charts/shared/streamPropsHelpers.d.ts +5 -0
  41. package/dist/components/charts/shared/types.d.ts +13 -0
  42. package/dist/components/charts/shared/useAreaSeriesSetup.d.ts +75 -0
  43. package/dist/components/charts/shared/useEncodingDomain.d.ts +48 -0
  44. package/dist/components/charts/shared/useFrameImperativeHandle.d.ts +1 -1
  45. package/dist/components/charts/shared/useNetworkChartSetup.d.ts +148 -0
  46. package/dist/components/charts/shared/useOrdinalPieceStyle.d.ts +87 -0
  47. package/dist/components/charts/shared/useSeriesFeatures.d.ts +57 -0
  48. package/dist/components/charts/shared/useStreamStatus.d.ts +33 -0
  49. package/dist/components/charts/shared/useXYLineStyle.d.ts +69 -0
  50. package/dist/components/charts/shared/useXYPointStyle.d.ts +87 -0
  51. package/dist/components/charts/xy/AreaChart.d.ts +38 -0
  52. package/dist/components/charts/xy/BubbleChart.d.ts +13 -0
  53. package/dist/components/charts/xy/CandlestickChart.d.ts +4 -0
  54. package/dist/components/charts/xy/ConnectedScatterplot.d.ts +20 -0
  55. package/dist/components/charts/xy/DifferenceChart.d.ts +172 -0
  56. package/dist/components/charts/xy/Heatmap.d.ts +4 -0
  57. package/dist/components/charts/xy/LineChart.d.ts +12 -0
  58. package/dist/components/charts/xy/MinimapChart.d.ts +7 -0
  59. package/dist/components/charts/xy/Scatterplot.d.ts +38 -0
  60. package/dist/components/charts/xy/StackedAreaChart.d.ts +12 -0
  61. package/dist/components/geometry/ribbonGeometry.d.ts +76 -0
  62. package/dist/components/semiotic-ai.d.ts +2 -0
  63. package/dist/components/semiotic-network.d.ts +4 -0
  64. package/dist/components/semiotic-realtime.d.ts +2 -0
  65. package/dist/components/semiotic-utils.d.ts +4 -0
  66. package/dist/components/semiotic-xy.d.ts +2 -0
  67. package/dist/components/semiotic.d.ts +3 -3
  68. package/dist/components/server/serverChartConfigs.d.ts +2 -0
  69. package/dist/components/stream/GeoPipelineStore.d.ts +21 -0
  70. package/dist/components/stream/OrdinalSVGOverlay.d.ts +8 -0
  71. package/dist/components/stream/PipelineStore.d.ts +5 -0
  72. package/dist/components/stream/SVGOverlay.d.ts +18 -0
  73. package/dist/components/stream/annotationAccessorResolver.d.ts +39 -0
  74. package/dist/components/stream/geoTypes.d.ts +12 -0
  75. package/dist/components/stream/ordinalTypes.d.ts +12 -0
  76. package/dist/components/stream/renderers/cornerRadii.d.ts +33 -0
  77. package/dist/components/stream/types.d.ts +23 -0
  78. package/dist/components/types/legendTypes.d.ts +1 -1
  79. package/dist/geo.min.js +1 -1
  80. package/dist/geo.module.min.js +1 -1
  81. package/dist/network.min.js +1 -1
  82. package/dist/network.module.min.js +1 -1
  83. package/dist/ordinal.min.js +1 -1
  84. package/dist/ordinal.module.min.js +1 -1
  85. package/dist/realtime.min.js +1 -1
  86. package/dist/realtime.module.min.js +1 -1
  87. package/dist/semiotic-ai.d.ts +2 -0
  88. package/dist/semiotic-ai.min.js +1 -1
  89. package/dist/semiotic-ai.module.min.js +1 -1
  90. package/dist/semiotic-network.d.ts +4 -0
  91. package/dist/semiotic-realtime.d.ts +2 -0
  92. package/dist/semiotic-recipes.min.js +1 -1
  93. package/dist/semiotic-recipes.module.min.js +1 -1
  94. package/dist/semiotic-utils.d.ts +4 -0
  95. package/dist/semiotic-utils.min.js +1 -1
  96. package/dist/semiotic-utils.module.min.js +1 -1
  97. package/dist/semiotic-xy.d.ts +2 -0
  98. package/dist/semiotic.d.ts +3 -3
  99. package/dist/semiotic.min.js +1 -1
  100. package/dist/semiotic.module.min.js +1 -1
  101. package/dist/server.min.js +1 -1
  102. package/dist/server.module.min.js +1 -1
  103. package/dist/xy.min.js +1 -1
  104. package/dist/xy.module.min.js +1 -1
  105. package/package.json +10 -5
@@ -0,0 +1,75 @@
1
+ import type { ReactNode } from "react";
2
+ import type { Datum } from "./datumTypes";
3
+ import type { Accessor, ChartAccessor } from "./types";
4
+ import type { SelectionHookResult } from "./selectionUtils";
5
+ import type { HoverData } from "../../stream/types";
6
+ export interface AreaSeriesSetupOptions<TDatum extends Datum = Datum> {
7
+ /** Sparse-filtered data array (the HOC's `safeData`). */
8
+ safeData: TDatum[];
9
+ /** Original `data` prop — used to short-circuit to push-mode flatten. */
10
+ data: TDatum[] | undefined;
11
+ /** Group accessor (`areaBy` on the HOC). When set, flat data is
12
+ * grouped into one series per distinct value. */
13
+ areaBy?: ChartAccessor<TDatum, string>;
14
+ /** Field on grouped objects that contains the coordinate array.
15
+ * Convention: `"coordinates"`. Pre-grouped input is detected by
16
+ * presence of this field on the first row. */
17
+ lineDataAccessor: string;
18
+ /** Effective color accessor (already resolved by HOC: AreaChart =
19
+ * `colorBy`; StackedAreaChart = `colorBy || areaBy`). */
20
+ colorBy?: Accessor<string> | ChartAccessor<TDatum, string>;
21
+ /** Resolved categorical color scale from `useChartSetup`. */
22
+ colorScale: ((v: string) => string) | undefined;
23
+ /** Top-level uniform `color` prop. */
24
+ color?: string;
25
+ /** Top-level primitive props — applied last so they win over
26
+ * HOC base + (future) user style. */
27
+ stroke?: string;
28
+ strokeWidth?: number;
29
+ opacity?: number;
30
+ /** Selection hook output (`setup.effectiveSelectionHook`). */
31
+ effectiveSelectionHook: SelectionHookResult | null | undefined;
32
+ /** Resolved selection config (`setup.resolvedSelection`). */
33
+ resolvedSelection: import("./types").SelectionConfig | undefined;
34
+ /** Area fillOpacity. @default 0.7 */
35
+ areaOpacity: number;
36
+ /** Render line on top of fill. @default true */
37
+ showLine: boolean;
38
+ /** Line stroke width. @default 2 */
39
+ lineWidth: number;
40
+ /** Render points along the line. @default false */
41
+ showPoints: boolean;
42
+ /** Point radius when `showPoints`. @default 3 */
43
+ pointRadius: number;
44
+ xAccessor: ChartAccessor<TDatum, number>;
45
+ yAccessor: ChartAccessor<TDatum, number>;
46
+ xLabel?: string;
47
+ yLabel?: string;
48
+ /** Tooltip-side x formatter — same signature as `AxisConfig.xFormat`
49
+ * so the HOC can forward the prop verbatim. ReactNode return is OK. */
50
+ xFormat?: (d: number | Date | string, index?: number, allTicks?: number[]) => string | ReactNode;
51
+ yFormat?: (d: number | Date | string) => string | ReactNode;
52
+ /** Field used to label the series row in the default tooltip.
53
+ * Typically `areaBy ?? colorBy`. */
54
+ groupField?: Accessor<string> | ChartAccessor<TDatum, string>;
55
+ }
56
+ export interface AreaSeriesSetupResult<TDatum extends Datum = Datum> {
57
+ /** Flat data array ready for `<StreamXYFrame data={…} />`. Empty
58
+ * when the HOC is in push mode (no `data` prop). */
59
+ flattenedData: TDatum[];
60
+ /** Selection-aware line/area style fn. */
61
+ lineStyle: (d: Datum) => Record<string, string | number>;
62
+ /** Selection-aware point style fn — `undefined` when `showPoints`
63
+ * is false so the HOC can spread it conditionally. */
64
+ pointStyle: ((d: Datum) => Record<string, string | number>) | undefined;
65
+ /** Default tooltip content fn for the chart. */
66
+ defaultTooltipContent: (hover: HoverData) => ReactNode;
67
+ }
68
+ /**
69
+ * Build the area-series pieces for an area-shaped XY HOC.
70
+ * The HOC still owns chart-specific frame props (chartType,
71
+ * gradientFill, normalize, baseline, stackOrder) and all the
72
+ * passthrough wiring; this hook covers the part both shared
73
+ * verbatim before extraction.
74
+ */
75
+ export declare function useAreaSeriesSetup<TDatum extends Datum = Datum>(options: AreaSeriesSetupOptions<TDatum>): AreaSeriesSetupResult<TDatum>;
@@ -0,0 +1,48 @@
1
+ import type { Datum } from "./datumTypes";
2
+ import type { Accessor } from "./types";
3
+ export interface EncodingDomainOptions<TDatum extends Datum = Datum> {
4
+ /** Encoding accessor (string field name or function). */
5
+ accessor: Accessor<number> | undefined;
6
+ /** Bounded chart data. Ignored when `isPushMode` is true. */
7
+ data: TDatum[];
8
+ /** When true, the hook tracks pushed values via the returned
9
+ * `trackPushed` helper instead of reading `data`. */
10
+ isPushMode: boolean;
11
+ }
12
+ export interface EncodingDomainResult<TDatum extends Datum = Datum> {
13
+ /** `[min, max]` tuple over seen values. Undefined when no data has
14
+ * been seen yet (push mode initial state, or bounded mode with
15
+ * empty data + no accessor). */
16
+ domain: [number, number] | undefined;
17
+ /** Walk `items` and update the running domain. Bumps the version
18
+ * counter when any min/max actually moves. No-op in bounded mode
19
+ * — the hook reads from `data` directly there. */
20
+ trackPushed: (items: TDatum[]) => void;
21
+ /** Reset the running domain to empty. Paired with the HOC's
22
+ * `clear()` override. No-op in bounded mode. */
23
+ reset: () => void;
24
+ }
25
+ /**
26
+ * Track a numeric encoding's `[min, max]` domain across bounded and
27
+ * push data sources.
28
+ *
29
+ * @example
30
+ * ```tsx
31
+ * // BubbleChart-style usage:
32
+ * const { domain: sizeDomain, trackPushed, reset } = useEncodingDomain({
33
+ * accessor: sizeBy,
34
+ * data: safeData,
35
+ * isPushMode: data === undefined,
36
+ * })
37
+ *
38
+ * useFrameImperativeHandle(ref, {
39
+ * variant: "xy", frameRef,
40
+ * overrides: {
41
+ * push: (d) => { trackPushed([d]); frameRef.current?.push(d) },
42
+ * pushMany: (ds) => { trackPushed(ds); frameRef.current?.pushMany(ds) },
43
+ * clear: () => { reset(); frameRef.current?.clear() },
44
+ * },
45
+ * })
46
+ * ```
47
+ */
48
+ export declare function useEncodingDomain<TDatum extends Datum = Datum>(options: EncodingDomainOptions<TDatum>): EncodingDomainResult<TDatum>;
@@ -1,6 +1,6 @@
1
1
  import type { Ref, RefObject, DependencyList } from "react";
2
2
  import type { RealtimeFrameHandle } from "../../realtime/types";
3
- type FrameVariant = "xy" | "network" | "geo-points";
3
+ type FrameVariant = "xy" | "network" | "geo-points" | "geo-lines";
4
4
  interface Options {
5
5
  /**
6
6
  * Variant decides which default method bodies are emitted. The
@@ -0,0 +1,148 @@
1
+ import type { ReactNode, ReactElement } from "react";
2
+ import type { Datum } from "./datumTypes";
3
+ import type { Accessor, ChartAccessor, SelectionConfig, LinkedHoverProp } from "./types";
4
+ import type { OnObservationCallback } from "../../store/ObservationStore";
5
+ import type { PartialMargin, MarginType } from "../../types/marginType";
6
+ import { useChartSelection, useChartLegendAndMargin } from "./hooks";
7
+ import type { LegendInteractionMode, LegendPosition, LegendInteractionState } from "./hooks";
8
+ export interface NetworkChartSetupInput<TNode extends Datum = Datum, TEdge extends Datum = Datum> {
9
+ /** Raw `nodes` prop (may be undefined). */
10
+ nodes: TNode[] | undefined;
11
+ /** Raw `edges` prop (may be undefined). */
12
+ edges: TEdge[] | undefined;
13
+ /**
14
+ * When `true`, missing nodes are inferred from edge endpoints via
15
+ * `inferNodesFromEdges`. Sankey/Chord set this; ForceDirected leaves
16
+ * it `false` and treats both as required. Default: `true`.
17
+ */
18
+ inferNodes?: boolean;
19
+ /** Node id accessor for inference + tooltip identity. */
20
+ nodeIdAccessor?: ChartAccessor<TNode, string>;
21
+ /** Edge source accessor (used by `inferNodesFromEdges`). */
22
+ sourceAccessor?: ChartAccessor<TEdge, string>;
23
+ /** Edge target accessor (used by `inferNodesFromEdges`). */
24
+ targetAccessor?: ChartAccessor<TEdge, string>;
25
+ colorBy?: Accessor<string>;
26
+ colorScheme?: string | string[];
27
+ /** `undefined` defaults to "auto" (on when colorBy is set). */
28
+ showLegend?: boolean;
29
+ legendPosition?: LegendPosition;
30
+ legendInteraction?: LegendInteractionMode;
31
+ selection?: SelectionConfig;
32
+ linkedHover?: LinkedHoverProp;
33
+ onObservation?: OnObservationCallback;
34
+ onClick?: (datum: Datum, event: {
35
+ x: number;
36
+ y: number;
37
+ }) => void;
38
+ /** Used by useChartSelection for chart-type-stamped observation events. */
39
+ chartType: string;
40
+ chartId?: string;
41
+ /** Mode-resolved margin defaults from useChartMode. */
42
+ marginDefaults: MarginType;
43
+ /** User-provided margin override. */
44
+ userMargin?: PartialMargin;
45
+ width: number;
46
+ height: number;
47
+ loading?: boolean;
48
+ emptyContent?: ReactNode | false;
49
+ /**
50
+ * Which array drives the empty-state check. `"edges"` (default)
51
+ * fits Sankey/Chord/ProcessSankey where edges are the primary
52
+ * data shape and nodes are optional/inferred. `"nodes"` fits
53
+ * ForceDirectedGraph where both nodes and edges are required and
54
+ * empty-state should fire when the user supplied a sparse-only
55
+ * node list. The undefined-vs-empty distinction is preserved
56
+ * either way: undefined = push mode (don't show empty UI);
57
+ * present-but-empty = user supplied empty data (show empty UI).
58
+ */
59
+ emptyDataKey?: "edges" | "nodes";
60
+ }
61
+ export interface NetworkChartSetupResult {
62
+ /**
63
+ * Sparse-filtered nodes. When `inferNodes` was `true` and the
64
+ * caller didn't supply nodes, this is the inferred `[{id}]` array
65
+ * derived from edge endpoints. Otherwise it's just the input
66
+ * `nodes` with sparse holes removed.
67
+ */
68
+ safeNodes: Datum[];
69
+ /** Sparse-filtered edges. Identity-equal to input when nothing was dropped. */
70
+ safeEdges: Datum[];
71
+ /**
72
+ * Color scale built from `(safeNodes, colorBy, colorScheme)`.
73
+ * `undefined` when colorBy is unset.
74
+ */
75
+ colorScale: ((v: string) => string) | undefined;
76
+ /**
77
+ * Effective palette array. Resolved as:
78
+ * 1. `colorScheme` if it's an array.
79
+ * 2. ThemeProvider categorical if non-empty.
80
+ * 3. Named scheme lookup in `COLOR_SCHEMES`.
81
+ * 4. `DEFAULT_COLORS` fallback.
82
+ *
83
+ * Pass this to the frame's `colorScheme` prop so its internal
84
+ * `getNodeColor` (used for particles, hover, interactions) matches
85
+ * what the HOC's nodeStyle resolves.
86
+ */
87
+ effectivePalette: string[];
88
+ themeCategorical: string[] | undefined;
89
+ /** Distinct category values from `(safeNodes, colorBy)`, for legend interaction. */
90
+ allCategories: string[];
91
+ legendState: LegendInteractionState;
92
+ legend: ReturnType<typeof useChartLegendAndMargin>["legend"];
93
+ margin: MarginType;
94
+ legendPosition: LegendPosition;
95
+ customHoverBehavior: ReturnType<typeof useChartSelection>["customHoverBehavior"];
96
+ customClickBehavior: ReturnType<typeof useChartSelection>["customClickBehavior"];
97
+ /**
98
+ * The full selection-hook output. Most network HOCs only need the
99
+ * resolved hover/click behaviors above, but hierarchy charts
100
+ * (Treemap, CirclePack, TreeDiagram, OrbitDiagram) wrap node styles
101
+ * with selection state via `activeSelectionHook.isActive` /
102
+ * `.predicate`. Passed through verbatim so those charts don't need
103
+ * a parallel `useChartSelection` call.
104
+ */
105
+ activeSelectionHook: ReturnType<typeof useChartSelection>["activeSelectionHook"];
106
+ hoverSelectionHook: ReturnType<typeof useChartSelection>["hoverSelectionHook"];
107
+ crosshairSourceId: ReturnType<typeof useChartSelection>["crosshairSourceId"];
108
+ /** When non-null, render this element instead of the chart. */
109
+ loadingEl: ReactElement | null;
110
+ /** When non-null, render this element instead of the chart. */
111
+ emptyEl: ReactElement | null;
112
+ }
113
+ /**
114
+ * Run the consolidated network-HOC setup pipeline. Call this once
115
+ * after `useChartMode` and before any chart-specific logic. The
116
+ * returned `loadingEl`/`emptyEl` are early-exit slots — when either
117
+ * is non-null, return it before the frame.
118
+ *
119
+ * @example
120
+ * ```tsx
121
+ * const setup = useNetworkChartSetup({
122
+ * nodes, edges,
123
+ * inferNodes: true,
124
+ * nodeIdAccessor, sourceAccessor, targetAccessor,
125
+ * colorBy, colorScheme, showLegend, legendPosition, legendInteraction,
126
+ * selection, linkedHover, onObservation, onClick,
127
+ * chartType: "SankeyDiagram", chartId,
128
+ * marginDefaults, userMargin, width, height,
129
+ * loading, emptyContent,
130
+ * })
131
+ * if (setup.loadingEl) return setup.loadingEl
132
+ * if (setup.emptyEl) return setup.emptyEl
133
+ * return (
134
+ * <StreamNetworkFrame
135
+ * nodes={setup.safeNodes}
136
+ * edges={setup.safeEdges}
137
+ * colorScheme={setup.effectivePalette}
138
+ * legend={setup.legend}
139
+ * legendPosition={setup.legendPosition}
140
+ * margin={setup.margin}
141
+ * customHoverBehavior={setup.customHoverBehavior}
142
+ * customClickBehavior={setup.customClickBehavior}
143
+ * ...
144
+ * />
145
+ * )
146
+ * ```
147
+ */
148
+ export declare function useNetworkChartSetup<TNode extends Datum = Datum, TEdge extends Datum = Datum>(input: NetworkChartSetupInput<TNode, TEdge>): NetworkChartSetupResult;
@@ -0,0 +1,87 @@
1
+ import type { Datum } from "./datumTypes";
2
+ import type { Accessor, ChartAccessor } from "./types";
3
+ import type { SelectionHookResult } from "./selectionUtils";
4
+ export interface OrdinalPieceStyleOptions {
5
+ /** colorBy accessor — string field name or function */
6
+ colorBy?: Accessor<string> | ChartAccessor<Datum, string>;
7
+ /** Resolved categorical color scale (typically from useChartSetup). */
8
+ colorScale: ((v: string) => string) | undefined;
9
+ /** Top-level uniform `color` prop (BaseChartProps). Applied as a
10
+ * default-fill primitive when `colorBy` is unset. */
11
+ color?: string;
12
+ /** Theme categorical palette (from useThemeCategorical). */
13
+ themeCategorical: string[] | undefined;
14
+ /** colorScheme prop — array or string scheme name. */
15
+ colorScheme?: string | string[];
16
+ /** Stable category-index map for default-fill cycling. */
17
+ categoryIndexMap: Map<string, number>;
18
+ /** User-supplied `frameProps.pieceStyle`. Accepts the looser
19
+ * Frame-side `Style` type (typed fields like `fill: string`) or a
20
+ * function returning the same shape; we don't pin a stricter
21
+ * contract here because every ordinal HOC re-types pieceStyle
22
+ * via its own props interface. */
23
+ userPieceStyle?: ((d: Datum, category?: string) => Record<string, unknown>) | Record<string, unknown> | unknown;
24
+ /** Top-level primitive props — applied last so they win over HOC base + user overlay. */
25
+ stroke?: string;
26
+ strokeWidth?: number;
27
+ opacity?: number;
28
+ /**
29
+ * Chart-shape defaults applied BEFORE the color resolution and
30
+ * user overlay. Use for properties that are intrinsic to the
31
+ * chart's mark shape (point radius `r`, fillOpacity for swarms /
32
+ * dots, etc.). User-supplied `frameProps.pieceStyle` and top-level
33
+ * primitive props can still override them.
34
+ *
35
+ * Static object form for shape-constant defaults
36
+ * (`{ r: dotRadius, fillOpacity: 0.8 }` — DotPlot). Function form
37
+ * for per-datum derivation (`(d) => ({ r: sizeBy ? getSize(d, ...) :
38
+ * pointRadius })` — SwarmPlot's size-encoded points). The function
39
+ * receives the same `(d, category)` args as user pieceStyle.
40
+ */
41
+ baseStyleExtras?: Record<string, string | number | undefined> | ((d: Datum, category?: string) => Record<string, string | number | undefined>);
42
+ /**
43
+ * After the base fill is resolved, also write it to `stroke`.
44
+ * Used by statistical-summary charts (BoxPlot / ViolinPlot /
45
+ * RidgelinePlot / Histogram) where the box outline should match
46
+ * the box fill rather than be a separate stroke. Top-level
47
+ * primitive `stroke` still wins via `mergeShapeStyle` if supplied.
48
+ */
49
+ linkStrokeToFill?: boolean;
50
+ /**
51
+ * When `colorBy` is unset, pass the per-piece `category` to
52
+ * `resolveDefaultFill` so each piece cycles through the
53
+ * colorScheme's palette (Pie / Donut / Funnel / radial charts —
54
+ * each slice/wedge wants its own color).
55
+ *
56
+ * When `false` (default), the category arg is omitted and
57
+ * `resolveDefaultFill` returns the first scheme color uniformly
58
+ * (BarChart / StackedBarChart / GroupedBarChart — bars without
59
+ * `colorBy` should be one color, since the user picked
60
+ * `categoryAccessor` but explicitly didn't ask for category-driven
61
+ * coloring). Locked by `bugRepros.test.tsx` BR-2.
62
+ */
63
+ cycleByCategory?: boolean;
64
+ /** Selection hook output (typically `setup.effectiveSelectionHook`). */
65
+ effectiveSelectionHook: SelectionHookResult | null | undefined;
66
+ /** Resolved selection config (typically `setup.resolvedSelection`). */
67
+ resolvedSelection: import("./types").SelectionConfig | undefined;
68
+ }
69
+ /**
70
+ * Build a memoized `pieceStyle` function that the chart can pass
71
+ * straight to `<StreamOrdinalFrame pieceStyle={…} />`. Composes the
72
+ * standard base-fill / user-overlay / primitive-prop / selection
73
+ * pipeline so each HOC doesn't re-derive it.
74
+ *
75
+ * @example
76
+ * ```tsx
77
+ * const pieceStyle = useOrdinalPieceStyle({
78
+ * colorBy, colorScale: setup.colorScale,
79
+ * color, themeCategorical, colorScheme, categoryIndexMap,
80
+ * userPieceStyle: frameProps?.pieceStyle,
81
+ * stroke, strokeWidth, opacity,
82
+ * effectiveSelectionHook: setup.effectiveSelectionHook,
83
+ * resolvedSelection: setup.resolvedSelection,
84
+ * })
85
+ * ```
86
+ */
87
+ export declare function useOrdinalPieceStyle(options: OrdinalPieceStyleOptions): (d: Datum, category?: string) => Record<string, string | number | undefined>;
@@ -0,0 +1,57 @@
1
+ import type { Datum } from "./datumTypes";
2
+ import type { Accessor } from "./types";
3
+ import type { ForecastConfig, AnomalyConfig } from "./statisticalOverlays";
4
+ export interface SeriesFeaturesOptions {
5
+ /** Sparse-filtered chart data (the HOC's `safeData`). */
6
+ data: Datum[];
7
+ /** x accessor — string or function. */
8
+ xAccessor: Accessor<number | Date | string>;
9
+ /** y accessor — string or function. */
10
+ yAccessor: Accessor<number>;
11
+ /** Optional forecast configuration. When set, the hook adds
12
+ * segment-tagged future points to `effectiveData` and appends
13
+ * envelope/forecast-line annotations. */
14
+ forecast?: ForecastConfig | undefined;
15
+ /** Optional anomaly configuration (band + dot overlay). */
16
+ anomaly?: AnomalyConfig | undefined;
17
+ /** When the consuming HOC supports grouped series (e.g. LineChart's
18
+ * `lineBy`), pass the grouping field name so the overlay pipeline
19
+ * can do group-aware boundary duplication. Required when the same
20
+ * data array carries multiple metric series interleaved by x. */
21
+ groupBy?: Accessor<string> | undefined;
22
+ }
23
+ export interface SeriesFeaturesResult {
24
+ /** Data to forward to the frame. When forecast adds future points,
25
+ * this is the augmented set; otherwise the original `data`. */
26
+ effectiveData: Datum[];
27
+ /** Annotations the chart should merge into its own annotations
28
+ * array (envelope, anomaly band, anomaly dots). Empty when
29
+ * forecast/anomaly are unset or still loading. */
30
+ statisticalAnnotations: Datum[];
31
+ /** True when forecast is active and processedData differs from
32
+ * the input data. Useful for HOC-side branches (e.g. LineChart's
33
+ * compound-group accessor). */
34
+ hasForecast: boolean;
35
+ /** Resolved string key for the x axis — either the user's string
36
+ * accessor or a synthetic key written by the bake step. The
37
+ * forecast/anomaly pipeline reads through this key. */
38
+ xAccessorKey: string;
39
+ /** Resolved string key for the y axis (mirror of xAccessorKey). */
40
+ yAccessorKey: string;
41
+ }
42
+ /**
43
+ * Build series feature overlays (forecast + anomaly) for a chart.
44
+ * Returns the effective data + annotations to merge into the
45
+ * chart's stream-frame props. Returns the input data unchanged when
46
+ * neither prop is set.
47
+ *
48
+ * @example
49
+ * ```tsx
50
+ * const { effectiveData, statisticalAnnotations } = useSeriesFeatures({
51
+ * data: safeData, xAccessor, yAccessor, forecast, anomaly,
52
+ * })
53
+ * const mergedAnnotations = [...(annotations || []), ...statisticalAnnotations]
54
+ * // forward effectiveData + mergedAnnotations to the frame
55
+ * ```
56
+ */
57
+ export declare function useSeriesFeatures(options: SeriesFeaturesOptions): SeriesFeaturesResult;
@@ -0,0 +1,33 @@
1
+ import type { RealtimeFrameHandle } from "../../realtime/types";
2
+ /**
3
+ * Status enum exposed by the hook.
4
+ *
5
+ * - `"idle"` — no pushes have happened yet since mount.
6
+ * - `"active"` — at least one push has happened within the
7
+ * threshold window.
8
+ * - `"stale"` — pushes have stopped or slowed; last push is older
9
+ * than `staleThresholdMs`.
10
+ */
11
+ export type StreamStatus = "idle" | "active" | "stale";
12
+ export interface StreamStatusOptions {
13
+ /** Time in ms since the last push before status flips to `"stale"`.
14
+ * @default 5000 */
15
+ staleThresholdMs?: number;
16
+ /** Polling interval for status transitions. Smaller = more
17
+ * responsive but higher cost. @default 1000 */
18
+ pollIntervalMs?: number;
19
+ }
20
+ export interface StreamStatusResult<THandle extends RealtimeFrameHandle = RealtimeFrameHandle> {
21
+ /** Ref to pass to the chart's `ref` prop. The hook intercepts
22
+ * push/pushMany calls on this ref so it can timestamp them. */
23
+ ref: React.MutableRefObject<THandle | null>;
24
+ /** Current status. Re-renders the consumer on transition. */
25
+ status: StreamStatus;
26
+ /** Timestamp (from `performance.now()`) of the most recent push,
27
+ * or null when no push has happened yet. */
28
+ lastPushTime: number | null;
29
+ }
30
+ /**
31
+ * Track ingest activity on a push-API chart and expose status.
32
+ */
33
+ export declare function useStreamStatus<THandle extends RealtimeFrameHandle = RealtimeFrameHandle>(options?: StreamStatusOptions): StreamStatusResult<THandle>;
@@ -0,0 +1,69 @@
1
+ import type { Datum } from "./datumTypes";
2
+ import type { Accessor, ChartAccessor } from "./types";
3
+ import type { SelectionHookResult, SelectionStyleConfig } from "./selectionUtils";
4
+ export interface XYLineStyleOptions {
5
+ /**
6
+ * Base stroke width. The top-level `strokeWidth` override below
7
+ * wins via `mergeShapeStyle` when both are supplied.
8
+ * @default 2
9
+ */
10
+ lineWidth?: number;
11
+ /** Color accessor (string field name or function). */
12
+ colorBy?: Accessor<string> | ChartAccessor<Datum, string>;
13
+ /** Resolved categorical color scale (typically from useChartSetup). */
14
+ colorScale?: ((v: string) => string);
15
+ /** Static color used as the fallback stroke when `colorBy` is unset. */
16
+ color?: string;
17
+ /** Custom stroke resolver. Wins over `colorBy`/`colorScale`/`color`.
18
+ * Receives the datum and the optional `group` key the frame
19
+ * passes through `resolveLineStyle`. */
20
+ resolveStroke?: (d: Datum, group?: string) => string;
21
+ /** When `true`, every line fills. When a `string[]`, only series
22
+ * whose `group` key appears in the array fill. When omitted/false,
23
+ * no fill is set on the style. */
24
+ fillArea?: boolean | string[];
25
+ /** Fill opacity used when `fillArea` triggers a fill. @default 0.3 */
26
+ areaOpacity?: number;
27
+ stroke?: string;
28
+ strokeWidth?: number;
29
+ opacity?: number;
30
+ /** Selection hook result from `useChartSelection`/`useChartSetup`.
31
+ * Pass `null`/`undefined` to skip dimming entirely (MinimapChart's
32
+ * overview line and main line both skip selection wrapping). */
33
+ effectiveSelectionHook?: SelectionHookResult | null;
34
+ /** Resolved selection style config (matched/unmatched style overrides). */
35
+ resolvedSelection?: SelectionStyleConfig;
36
+ }
37
+ /**
38
+ * Returns a memoized `lineStyle` callback that the XY frame's
39
+ * `resolveLineStyle` invokes with `(datum, group?)`.
40
+ *
41
+ * @example
42
+ * ```tsx
43
+ * // LineChart's recipe collapses to a single hook call:
44
+ * const lineStyle = useXYLineStyle({
45
+ * lineWidth, colorBy, colorScale, color, fillArea, areaOpacity,
46
+ * stroke, strokeWidth, opacity,
47
+ * effectiveSelectionHook, resolvedSelection,
48
+ * })
49
+ * ```
50
+ *
51
+ * @example
52
+ * ```tsx
53
+ * // MultiAxisLineChart hands in a series-aware resolver:
54
+ * const lineStyle = useXYLineStyle({
55
+ * lineWidth,
56
+ * resolveStroke: (d) => seriesColorMap.get(d[SERIES_FIELD]) || seriesColors[0],
57
+ * stroke, strokeWidth, opacity,
58
+ * effectiveSelectionHook: setup.effectiveSelectionHook,
59
+ * resolvedSelection: setup.resolvedSelection,
60
+ * })
61
+ * ```
62
+ *
63
+ * @example
64
+ * ```tsx
65
+ * // MinimapChart's overview line: thin stroke, no selection, no primitives.
66
+ * const overviewLineStyle = useXYLineStyle({ lineWidth: 1, colorBy, colorScale })
67
+ * ```
68
+ */
69
+ export declare function useXYLineStyle(options: XYLineStyleOptions): (d: Datum, group?: string) => Datum;
@@ -0,0 +1,87 @@
1
+ import type { Datum } from "./datumTypes";
2
+ import type { Accessor, ChartAccessor } from "./types";
3
+ import type { SelectionHookResult } from "./selectionUtils";
4
+ export interface XYPointStyleOptions {
5
+ /** colorBy accessor — string field name or function. */
6
+ colorBy?: Accessor<string> | ChartAccessor<Datum, string>;
7
+ /** Resolved categorical color scale (typically from useChartSetup). */
8
+ colorScale: ((v: string) => string) | undefined;
9
+ /** Top-level uniform `color` prop. Used as the fallback fill when
10
+ * `colorBy` is unset. */
11
+ color?: string;
12
+ /**
13
+ * Fixed point radius. When `radiusFn` is supplied, that wins
14
+ * (per-datum sizing for BubbleChart / Scatterplot's `sizeBy`).
15
+ * @default 5
16
+ */
17
+ pointRadius?: number;
18
+ /** Per-datum radius resolver (e.g. wraps `getSize(d, sizeBy, …)`).
19
+ * Ignored when undefined; HOCs with no `sizeBy` should pass it
20
+ * unset and rely on `pointRadius`. */
21
+ radiusFn?: (d: Datum) => number;
22
+ /** Default fillOpacity. Charts override this through their own
23
+ * prop name (`pointOpacity`, `bubbleOpacity`). @default 1 */
24
+ fillOpacity?: number;
25
+ /**
26
+ * Fallback fill resolver invoked when `colorBy` is unset. Used by
27
+ * QuadrantChart to pick a color from the quadrant the point lands
28
+ * in. When omitted, fallback is `color || DEFAULT_COLOR` (the
29
+ * standard Scatterplot/BubbleChart behavior).
30
+ */
31
+ fallbackFill?: (d: Datum) => string;
32
+ /**
33
+ * Static or per-datum extra style applied BEFORE color resolution
34
+ * and primitive overlay. Use for shape-constant defaults
35
+ * (BubbleChart's `{ stroke: bubbleStrokeColor, strokeWidth: 1 }`).
36
+ * If extras supply a `fill`, the standard color resolution is
37
+ * skipped — same bypass as `useOrdinalPieceStyle`. Lets
38
+ * ConnectedScatterplot drop in its viridis-by-order fill.
39
+ */
40
+ baseStyleExtras?: Record<string, string | number | undefined> | ((d: Datum) => Record<string, string | number | undefined>);
41
+ /** Top-level primitive props — applied last via `mergeShapeStyle`. */
42
+ stroke?: string;
43
+ strokeWidth?: number;
44
+ opacity?: number;
45
+ /** Selection hook output (typically `setup.effectiveSelectionHook`). */
46
+ effectiveSelectionHook: SelectionHookResult | null | undefined;
47
+ /** Resolved selection config (typically `setup.resolvedSelection`). */
48
+ resolvedSelection: import("./types").SelectionConfig | undefined;
49
+ /**
50
+ * For ConnectedScatterplot-style charts whose color depends on the
51
+ * point's position in an ordered sequence, the resolver may need
52
+ * the point's parent line. Defaults to identity (`d => d`).
53
+ * Same hook BarChart's `parentLine` cascade uses.
54
+ */
55
+ colorDatumAccessor?: (d: Datum) => Datum;
56
+ }
57
+ /**
58
+ * Build a memoized `pointStyle` function for an XY HOC.
59
+ *
60
+ * @example
61
+ * ```tsx
62
+ * // Scatterplot — sizeBy-driven radius, standard color fallback
63
+ * const pointStyle = useXYPointStyle({
64
+ * colorBy, colorScale: setup.colorScale,
65
+ * color, pointRadius, fillOpacity: pointOpacity,
66
+ * radiusFn: sizeBy ? (d) => getSize(d, sizeBy, sizeRange, sizeDomain) : undefined,
67
+ * stroke, strokeWidth, opacity,
68
+ * effectiveSelectionHook: setup.effectiveSelectionHook,
69
+ * resolvedSelection: setup.resolvedSelection,
70
+ * })
71
+ * ```
72
+ *
73
+ * @example
74
+ * ```tsx
75
+ * // QuadrantChart — bespoke fallback fill from quadrant lookup
76
+ * const pointStyle = useXYPointStyle({
77
+ * colorBy, colorScale: setup.colorScale, color,
78
+ * pointRadius, fillOpacity: pointOpacity,
79
+ * radiusFn: sizeBy ? (d) => getSize(d, sizeBy, sizeRange, sizeDomain) : undefined,
80
+ * fallbackFill: (d) => quadrantColor(d, getXValue, getYValue, xCenter, yCenter, quadrants),
81
+ * stroke, strokeWidth, opacity,
82
+ * effectiveSelectionHook: setup.effectiveSelectionHook,
83
+ * resolvedSelection: setup.resolvedSelection,
84
+ * })
85
+ * ```
86
+ */
87
+ export declare function useXYPointStyle(options: XYPointStyleOptions): (d: Datum) => Record<string, string | number | undefined>;
@@ -5,6 +5,7 @@ import type { RealtimeFrameHandle } from "../../realtime/types";
5
5
  import type { LegendInteractionMode, LegendPosition } from "../shared/hooks";
6
6
  import type { BaseChartProps, AxisConfig, ChartAccessor } from "../shared/types";
7
7
  import { type TooltipProp } from "../../Tooltip/Tooltip";
8
+ import type { ForecastConfig, AnomalyConfig } from "../shared/statisticalOverlays";
8
9
  /**
9
10
  * AreaChart component props
10
11
  */
@@ -159,6 +160,43 @@ export interface AreaChartProps<TDatum extends Datum = Datum> extends BaseChartP
159
160
  * Annotation objects to render on the chart
160
161
  */
161
162
  annotations?: Datum[];
163
+ /**
164
+ * Forecast overlay — extends the area with a tagged training /
165
+ * observed / forecast region and (optionally) a confidence
166
+ * envelope. Same shape as LineChart's `forecast` prop. Pair with
167
+ * `anomaly` for combined anomaly + forecast visualization.
168
+ *
169
+ * @example
170
+ * ```tsx
171
+ * <AreaChart data={obs} xAccessor="t" yAccessor="value"
172
+ * forecast={{ trainEnd: 80, steps: 10, color: "#6366f1" }} />
173
+ * ```
174
+ */
175
+ forecast?: ForecastConfig;
176
+ /**
177
+ * Anomaly overlay — adds a ±σ band and per-point anomaly dots.
178
+ * Standalone (without forecast) gives raw anomaly detection.
179
+ *
180
+ * @example
181
+ * ```tsx
182
+ * <AreaChart data={obs} anomaly={{ threshold: 2 }} />
183
+ * ```
184
+ */
185
+ anomaly?: AnomalyConfig;
186
+ /**
187
+ * Fixed x domain `[min, max]`. Either bound may be `undefined` to leave
188
+ * that side data-derived. Useful for pinning a time axis to a known
189
+ * window (e.g. last 24 hours) so streamed updates don't shift the
190
+ * left/right edges as data flows in.
191
+ */
192
+ xExtent?: [number | undefined, number | undefined] | [number];
193
+ /**
194
+ * Fixed y domain `[min, max]`. Either bound may be `undefined` to leave
195
+ * that side data-derived. The fill baseline is the y-domain minimum, so
196
+ * setting `yExtent={[0, 100]}` anchors both the axis AND the area's
197
+ * baseline at 0 — the typical "percentage / counter" shape.
198
+ */
199
+ yExtent?: [number | undefined, number | undefined] | [number];
162
200
  /**
163
201
  * Additional StreamXYFrame props for advanced customization
164
202
  * For full control, consider using StreamXYFrame directly