semiotic 3.1.2 → 3.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/CLAUDE.md +173 -213
  2. package/LICENSE +197 -10
  3. package/README.md +12 -11
  4. package/ai/dist/componentRegistry.js +6 -0
  5. package/ai/dist/mcp-server.js +115 -5
  6. package/ai/examples.md +184 -0
  7. package/ai/schema.json +4140 -888
  8. package/ai/system-prompt.md +36 -1
  9. package/dist/components/ChartContainer.d.ts +2 -0
  10. package/dist/components/DataSummaryContext.d.ts +12 -0
  11. package/dist/components/ThemeProvider.d.ts +5 -3
  12. package/dist/components/Tooltip/FlippingTooltip.d.ts +34 -0
  13. package/dist/components/charts/geo/ChoroplethMap.d.ts +1 -1
  14. package/dist/components/charts/index.d.ts +12 -1
  15. package/dist/components/charts/ordinal/BarChart.d.ts +4 -1
  16. package/dist/components/charts/ordinal/BoxPlot.d.ts +4 -1
  17. package/dist/components/charts/ordinal/DonutChart.d.ts +1 -1
  18. package/dist/components/charts/ordinal/DotPlot.d.ts +4 -1
  19. package/dist/components/charts/ordinal/FunnelChart.d.ts +57 -0
  20. package/dist/components/charts/ordinal/GroupedBarChart.d.ts +4 -1
  21. package/dist/components/charts/ordinal/Histogram.d.ts +17 -2
  22. package/dist/components/charts/ordinal/LikertChart.d.ts +94 -0
  23. package/dist/components/charts/ordinal/PieChart.d.ts +1 -1
  24. package/dist/components/charts/ordinal/RidgelinePlot.d.ts +12 -7
  25. package/dist/components/charts/ordinal/StackedBarChart.d.ts +4 -1
  26. package/dist/components/charts/ordinal/SwarmPlot.d.ts +15 -1
  27. package/dist/components/charts/ordinal/SwimlaneChart.d.ts +65 -0
  28. package/dist/components/charts/ordinal/ViolinPlot.d.ts +17 -2
  29. package/dist/components/charts/realtime/RealtimeHistogram.d.ts +20 -0
  30. package/dist/components/charts/shared/annotationResolvers.d.ts +28 -0
  31. package/dist/components/charts/shared/colorManipulation.d.ts +15 -0
  32. package/dist/components/charts/shared/formatUtils.d.ts +28 -0
  33. package/dist/components/charts/shared/hatchPattern.d.ts +35 -0
  34. package/dist/components/charts/shared/hooks.d.ts +39 -3
  35. package/dist/components/charts/shared/legendUtils.d.ts +2 -1
  36. package/dist/components/charts/shared/selectionUtils.d.ts +16 -1
  37. package/dist/components/charts/shared/statisticalOverlays.d.ts +49 -5
  38. package/dist/components/charts/shared/statsTooltip.d.ts +11 -0
  39. package/dist/components/charts/shared/types.d.ts +26 -2
  40. package/dist/components/charts/shared/useChartSetup.d.ts +12 -2
  41. package/dist/components/charts/shared/useLikertAggregation.d.ts +51 -0
  42. package/dist/components/charts/shared/useOrdinalBrush.d.ts +28 -0
  43. package/dist/components/charts/shared/useOrdinalStreaming.d.ts +54 -0
  44. package/dist/components/charts/shared/useStreamingLegend.d.ts +2 -2
  45. package/dist/components/charts/shared/validateProps.d.ts +2 -2
  46. package/dist/components/charts/shared/validationMap.d.ts +12 -0
  47. package/dist/components/charts/xy/AreaChart.d.ts +11 -0
  48. package/dist/components/charts/xy/Heatmap.d.ts +1 -1
  49. package/dist/components/charts/xy/MinimapChart.d.ts +1 -1
  50. package/dist/components/charts/xy/MultiAxisLineChart.d.ts +71 -0
  51. package/dist/components/charts/xy/StackedAreaChart.d.ts +11 -0
  52. package/dist/components/realtime/types.d.ts +6 -0
  53. package/dist/components/semiotic-ai.d.ts +4 -0
  54. package/dist/components/semiotic-ordinal.d.ts +5 -0
  55. package/dist/components/semiotic-themes.d.ts +80 -0
  56. package/dist/components/semiotic-utils.d.ts +30 -0
  57. package/dist/components/semiotic-xy.d.ts +1 -0
  58. package/dist/components/semiotic.d.ts +11 -5
  59. package/dist/components/store/LinkedCrosshairStore.d.ts +11 -0
  60. package/dist/components/store/ThemeStore.d.ts +22 -2
  61. package/dist/components/store/useSelection.d.ts +1 -0
  62. package/dist/components/stream/AccessibleDataTable.d.ts +28 -6
  63. package/dist/components/stream/FocusRing.d.ts +33 -0
  64. package/dist/components/stream/OrdinalBrushOverlay.d.ts +43 -0
  65. package/dist/components/stream/OrdinalPipelineStore.d.ts +16 -0
  66. package/dist/components/stream/OrdinalSVGOverlay.d.ts +2 -1
  67. package/dist/components/stream/PipelineStore.d.ts +7 -47
  68. package/dist/components/stream/SVGOverlay.d.ts +9 -3
  69. package/dist/components/stream/SceneGraph.d.ts +6 -1
  70. package/dist/components/stream/XYBrushOverlay.d.ts +47 -0
  71. package/dist/components/stream/accessorUtils.d.ts +14 -0
  72. package/dist/components/stream/geoTypes.d.ts +5 -1
  73. package/dist/components/stream/keyboardNav.d.ts +85 -9
  74. package/dist/components/stream/layouts/hierarchySceneBuilders.d.ts +35 -0
  75. package/dist/components/stream/layouts/hierarchyUtils.d.ts +25 -0
  76. package/dist/components/stream/networkTypes.d.ts +7 -1
  77. package/dist/components/stream/ordinalSceneBuilders/barFunnelScene.d.ts +27 -0
  78. package/dist/components/stream/ordinalSceneBuilders/funnelScene.d.ts +26 -0
  79. package/dist/components/stream/ordinalSceneBuilders/swimlaneScene.d.ts +12 -0
  80. package/dist/components/stream/ordinalTypes.d.ts +30 -4
  81. package/dist/components/stream/pipelineDecay.d.ts +20 -0
  82. package/dist/components/stream/pipelinePulse.d.ts +24 -0
  83. package/dist/components/stream/pipelineTransitions.d.ts +59 -0
  84. package/dist/components/stream/renderers/barFunnelCanvasRenderer.d.ts +12 -0
  85. package/dist/components/stream/renderers/pointCanvasRenderer.d.ts +2 -1
  86. package/dist/components/stream/renderers/trapezoidCanvasRenderer.d.ts +15 -0
  87. package/dist/components/stream/sceneUtils.d.ts +10 -0
  88. package/dist/components/stream/types.d.ts +29 -4
  89. package/dist/components/stream/useMediaPreferences.d.ts +11 -0
  90. package/dist/components/stream/xySceneBuilders/areaScene.d.ts +13 -0
  91. package/dist/components/stream/xySceneBuilders/barScene.d.ts +18 -0
  92. package/dist/components/stream/xySceneBuilders/boundsScene.d.ts +8 -0
  93. package/dist/components/stream/xySceneBuilders/candlestickScene.d.ts +10 -0
  94. package/dist/components/stream/xySceneBuilders/emitPointNodes.d.ts +13 -0
  95. package/dist/components/stream/xySceneBuilders/heatmapScene.d.ts +3 -0
  96. package/dist/components/stream/xySceneBuilders/lineScene.d.ts +12 -0
  97. package/dist/components/stream/xySceneBuilders/pointScene.d.ts +12 -0
  98. package/dist/components/stream/xySceneBuilders/swarmScene.d.ts +10 -0
  99. package/dist/components/stream/xySceneBuilders/types.d.ts +93 -0
  100. package/dist/components/stream/xySceneBuilders/waterfallScene.d.ts +12 -0
  101. package/dist/geo.min.js +1 -1
  102. package/dist/geo.module.min.js +1 -1
  103. package/dist/network.min.js +1 -1
  104. package/dist/network.module.min.js +1 -1
  105. package/dist/ordinal.min.js +1 -1
  106. package/dist/ordinal.module.min.js +1 -1
  107. package/dist/realtime.min.js +1 -1
  108. package/dist/realtime.module.min.js +1 -1
  109. package/dist/semiotic-ai-statisticalOverlays-C2PPlmXv.js +1 -0
  110. package/dist/semiotic-ai.d.ts +4 -0
  111. package/dist/semiotic-ai.min.js +1 -1
  112. package/dist/semiotic-ai.module.min.js +1 -1
  113. package/dist/semiotic-ordinal.d.ts +5 -0
  114. package/dist/semiotic-statisticalOverlays-DGX_WWc5.js +1 -0
  115. package/dist/semiotic-themes.d.ts +80 -0
  116. package/dist/semiotic-themes.min.js +1 -0
  117. package/dist/semiotic-themes.module.min.js +1 -0
  118. package/dist/semiotic-utils.d.ts +30 -0
  119. package/dist/semiotic-utils.min.js +1 -0
  120. package/dist/semiotic-utils.module.min.js +1 -0
  121. package/dist/semiotic-xy.d.ts +1 -0
  122. package/dist/semiotic.d.ts +11 -5
  123. package/dist/semiotic.min.js +1 -1
  124. package/dist/semiotic.module.min.js +1 -1
  125. package/dist/server.min.js +1 -1
  126. package/dist/server.module.min.js +1 -1
  127. package/dist/xy-statisticalOverlays-C2PPlmXv.js +1 -0
  128. package/dist/xy.min.js +1 -1
  129. package/dist/xy.module.min.js +1 -1
  130. package/package.json +38 -12
  131. package/dist/semiotic-ai-statisticalOverlays-C1f7TYyD.js +0 -1
  132. package/dist/semiotic-statisticalOverlays-C1f7TYyD.js +0 -1
  133. package/dist/xy-statisticalOverlays-C1f7TYyD.js +0 -1
@@ -0,0 +1,65 @@
1
+ import * as React from "react";
2
+ import type { StreamOrdinalFrameProps } from "../../stream/ordinalTypes";
3
+ import type { LegendInteractionMode } from "../shared/hooks";
4
+ import type { BaseChartProps, ChartAccessor, CategoryFormatFn } from "../shared/types";
5
+ import { type TooltipProp } from "../../Tooltip/Tooltip";
6
+ import type { RealtimeFrameHandle } from "../../realtime/types";
7
+ export interface SwimlaneChartProps<TDatum extends Record<string, any> = Record<string, any>> extends BaseChartProps {
8
+ /** Data array. Omit for push API mode. */
9
+ data?: TDatum[];
10
+ /** Accessor for lane categories (swim lanes). Default "category". */
11
+ categoryAccessor?: ChartAccessor<TDatum, string>;
12
+ /** Accessor for item subcategory (color grouping within lanes). Required. */
13
+ subcategoryAccessor: ChartAccessor<TDatum, string>;
14
+ /** Accessor for item size/duration. Default "value". */
15
+ valueAccessor?: ChartAccessor<TDatum, number>;
16
+ /** Orientation: "horizontal" renders lanes as rows (default), "vertical" as columns. */
17
+ orientation?: "vertical" | "horizontal";
18
+ /** Label for the category axis */
19
+ categoryLabel?: string;
20
+ /** Label for the value axis */
21
+ valueLabel?: string;
22
+ /** Format function for value axis ticks */
23
+ valueFormat?: (d: number | string) => string;
24
+ /** Color accessor — defaults to subcategoryAccessor */
25
+ colorBy?: ChartAccessor<TDatum, string>;
26
+ /** Color scheme for subcategories */
27
+ colorScheme?: string | string[];
28
+ /** Padding between lanes in pixels */
29
+ barPadding?: number;
30
+ /** Enable hover annotations */
31
+ enableHover?: boolean;
32
+ /** Show grid lines */
33
+ showGrid?: boolean;
34
+ /** Show category axis tick labels */
35
+ showCategoryTicks?: boolean;
36
+ /** Show legend */
37
+ showLegend?: boolean;
38
+ /** Legend interaction mode */
39
+ legendInteraction?: LegendInteractionMode;
40
+ /** Legend position */
41
+ legendPosition?: "right" | "left" | "top" | "bottom";
42
+ /** Tooltip configuration */
43
+ tooltip?: TooltipProp;
44
+ /** Annotation objects */
45
+ annotations?: Record<string, any>[];
46
+ /** Enable brush on the value axis */
47
+ brush?: boolean;
48
+ /** Callback when brush selection changes */
49
+ onBrush?: (extent: {
50
+ r: [number, number];
51
+ } | null) => void;
52
+ /** LinkedCharts brush integration */
53
+ linkedBrush?: string | {
54
+ name: string;
55
+ rField?: string;
56
+ };
57
+ /** Custom formatter for category tick labels */
58
+ categoryFormat?: CategoryFormatFn;
59
+ /** Pass-through props to StreamOrdinalFrame */
60
+ frameProps?: Partial<Omit<StreamOrdinalFrameProps, "data" | "size">>;
61
+ }
62
+ export declare const SwimlaneChart: {
63
+ <TDatum extends Record<string, any> = Record<string, any>>(props: SwimlaneChartProps<TDatum> & React.RefAttributes<RealtimeFrameHandle>): React.ReactElement | null;
64
+ displayName?: string;
65
+ };
@@ -1,7 +1,7 @@
1
1
  import * as React from "react";
2
2
  import type { StreamOrdinalFrameProps } from "../../stream/ordinalTypes";
3
- import type { LegendPosition } from "../shared/hooks";
4
- import type { BaseChartProps, ChartAccessor } from "../shared/types";
3
+ import type { LegendInteractionMode, LegendPosition } from "../shared/hooks";
4
+ import type { BaseChartProps, ChartAccessor, CategoryFormatFn } from "../shared/types";
5
5
  import { type TooltipProp } from "../../Tooltip/Tooltip";
6
6
  import type { RealtimeFrameHandle } from "../../realtime/types";
7
7
  export interface ViolinPlotProps<TDatum extends Record<string, any> = Record<string, any>> extends BaseChartProps {
@@ -20,10 +20,25 @@ export interface ViolinPlotProps<TDatum extends Record<string, any> = Record<str
20
20
  categoryPadding?: number;
21
21
  enableHover?: boolean;
22
22
  showGrid?: boolean;
23
+ showCategoryTicks?: boolean;
23
24
  showLegend?: boolean;
25
+ legendInteraction?: LegendInteractionMode;
24
26
  legendPosition?: LegendPosition;
25
27
  tooltip?: TooltipProp;
26
28
  annotations?: Record<string, any>[];
29
+ /** Enable brush on the value axis */
30
+ brush?: boolean;
31
+ /** Callback when brush selection changes */
32
+ onBrush?: (extent: {
33
+ r: [number, number];
34
+ } | null) => void;
35
+ /** LinkedCharts brush integration */
36
+ linkedBrush?: string | {
37
+ name: string;
38
+ rField?: string;
39
+ };
40
+ /** Custom formatter for category tick labels */
41
+ categoryFormat?: CategoryFormatFn;
27
42
  frameProps?: Partial<Omit<StreamOrdinalFrameProps, "data" | "size">>;
28
43
  }
29
44
  export declare const ViolinPlot: {
@@ -102,6 +102,26 @@ export interface RealtimeTemporalHistogramProps<TDatum extends Record<string, an
102
102
  loading?: boolean;
103
103
  /** Custom content to render when data is empty. Set to `false` to disable empty state. */
104
104
  emptyContent?: ReactNode | false;
105
+ /** Brush configuration. `true` defaults to `{ dimension: "x", snap: "bin" }`. */
106
+ brush?: boolean | "x" | {
107
+ dimension?: "x" | "y" | "xy";
108
+ snap?: "continuous" | "bin";
109
+ /** Actual bin boundary values for data-driven snapping (auto-populated from histogram bins when omitted) */
110
+ binBoundaries?: number[];
111
+ /** When true, snap during drag (not just on release). Default false. */
112
+ snapDuring?: boolean;
113
+ };
114
+ /** Callback when brush selection changes. Called with data-space extent, or null when cleared. */
115
+ onBrush?: (extent: {
116
+ x: [number, number];
117
+ y: [number, number];
118
+ } | null) => void;
119
+ /** Linked brush for cross-chart coordination via LinkedCharts */
120
+ linkedBrush?: string | {
121
+ name: string;
122
+ xField?: string;
123
+ yField?: string;
124
+ };
105
125
  /** Visual emphasis level for dashboard hierarchy. "primary" spans two columns in ChartGrid. */
106
126
  emphasis?: "primary" | "secondary";
107
127
  /** Show a legend */
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Coordinate resolution helpers for annotations.
3
+ *
4
+ * Resolves data coordinates to pixel positions, respecting anchor modes
5
+ * (fixed, latest, sticky), pointId matching, and bounds checking for
6
+ * streaming charts where data scrolls off-screen.
7
+ *
8
+ * Dependencies: types (AnnotationContext)
9
+ * Consumed by: annotationRules.tsx (all annotation type renderers)
10
+ */
11
+ import type { AnnotationContext } from "../../realtime/types";
12
+ export declare function resolveX(ann: Record<string, any>, context: AnnotationContext): number | null;
13
+ export declare function resolveY(ann: Record<string, any>, context: AnnotationContext): number | null;
14
+ /**
15
+ * Resolve annotation position respecting anchor mode.
16
+ * - "fixed" (default): resolve from annotation's own fields
17
+ * - "latest": resolve from the most recent datum in the buffer
18
+ * - "sticky": resolve from annotation fields; if not found, use cached position
19
+ */
20
+ export declare function resolveAnchoredPosition(ann: Record<string, any>, index: number, context: AnnotationContext): {
21
+ x: number;
22
+ y: number;
23
+ } | null;
24
+ /**
25
+ * Returns true if a point annotation is within the visible chart area.
26
+ * Used to hide data-anchored annotations that have scrolled off-screen.
27
+ */
28
+ export declare function isInBounds(px: number, py: number, context: AnnotationContext, margin?: number): boolean;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Lightweight color manipulation helpers.
3
+ * Extracted from statisticalOverlays to avoid pulling the heavy module
4
+ * into the main barrel import graph.
5
+ */
6
+ /**
7
+ * Darken a CSS hex color by a factor (0–1). factor=0.5 darkens by 50%.
8
+ * Returns the original string unchanged if it's not a valid hex color.
9
+ */
10
+ export declare function darkenColor(hex: string, factor?: number): string;
11
+ /**
12
+ * Lighten a CSS hex color by a factor (0–1). factor=0.5 lightens by 50%.
13
+ * Returns the original string unchanged if it's not a valid hex color.
14
+ */
15
+ export declare function lightenColor(hex: string, factor?: number): string;
@@ -84,6 +84,33 @@ export declare function formatLargeNumber(value: number, decimals?: number): str
84
84
  * Used as the default axis tickFormat when no explicit format is provided.
85
85
  */
86
86
  export declare function smartTickFormat(value: any): string;
87
+ type TimeGranularity = "seconds" | "minutes" | "hours" | "days" | "months" | "years";
88
+ /**
89
+ * Creates a hierarchical time axis formatter.
90
+ *
91
+ * The first tick is fully qualified (e.g., "Mar 24, 2026 14:33:52").
92
+ * Subsequent ticks show only the significant unit change (e.g., ":53").
93
+ * When a time boundary is crossed (new minute, hour, day, etc.), the
94
+ * label re-qualifies up to that boundary (e.g., "14:34:00").
95
+ *
96
+ * Designed to be passed as `xFormat` on any Semiotic XY chart.
97
+ * Uses the extended `(value, index, allTicks)` signature.
98
+ *
99
+ * @param granularity - Optional explicit granularity. If omitted,
100
+ * auto-detected from the tick spacing on first call.
101
+ *
102
+ * @example
103
+ * ```tsx
104
+ * import { adaptiveTimeTicks } from "semiotic"
105
+ *
106
+ * // Auto-detect granularity from the data
107
+ * <LineChart data={ts} xFormat={adaptiveTimeTicks()} />
108
+ *
109
+ * // Explicit granularity
110
+ * <LineChart data={ts} xFormat={adaptiveTimeTicks("minutes")} />
111
+ * ```
112
+ */
113
+ export declare function adaptiveTimeTicks(granularity?: TimeGranularity): (value: any, index?: number, allTicks?: number[]) => string;
87
114
  /**
88
115
  * Truncates text to specified length with ellipsis
89
116
  *
@@ -92,3 +119,4 @@ export declare function smartTickFormat(value: any): string;
92
119
  * @returns Truncated text
93
120
  */
94
121
  export declare function truncateText(text: string, maxLength?: number): string;
122
+ export {};
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Create a diagonal-line hatch CanvasPattern for use as a fill style.
3
+ *
4
+ * Returns a CanvasPattern that can be passed as `fill` in any pieceStyle,
5
+ * nodeStyle, or edgeStyle function. Works with all canvas-rendered charts.
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * const hatch = createHatchPattern({ background: "#4e79a7", stroke: "#fff" })
10
+ * <BarChart
11
+ * pieceStyle={(d) => ({ fill: d.projected ? hatch : "#4e79a7" })}
12
+ * />
13
+ * ```
14
+ */
15
+ export interface HatchPatternOptions {
16
+ /** Background color of the pattern tile */
17
+ background?: string;
18
+ /** Color of the diagonal lines */
19
+ stroke?: string;
20
+ /** Width of the diagonal lines in pixels @default 1.5 */
21
+ lineWidth?: number;
22
+ /** Spacing between lines in pixels @default 6 */
23
+ spacing?: number;
24
+ /** Angle of the lines in degrees (0 = horizontal, 45 = diagonal) @default 45 */
25
+ angle?: number;
26
+ }
27
+ /**
28
+ * Create a repeating diagonal-line hatch pattern for canvas fills.
29
+ *
30
+ * Must be called in a browser environment (needs canvas). Returns null
31
+ * in server/test environments where canvas is unavailable.
32
+ */
33
+ export declare function createHatchPattern(options?: HatchPatternOptions,
34
+ /** Optional target canvas to create the pattern on (for correct DPR scaling) */
35
+ targetCtx?: CanvasRenderingContext2D): CanvasPattern | null;
@@ -8,6 +8,17 @@ import type { TransitionConfig } from "../../stream/types";
8
8
  * Default fill color used when no colorBy is specified
9
9
  */
10
10
  export declare const DEFAULT_COLOR = "#007bff";
11
+ /**
12
+ * Returns the theme's categorical palette, or undefined if no ThemeProvider or
13
+ * the palette is empty. Safe to call outside a ThemeProvider (returns undefined).
14
+ */
15
+ export declare function useThemeCategorical(): string[] | undefined;
16
+ /**
17
+ * Resolve the effective color for a data element when no colorBy is specified.
18
+ * Priority: color prop > theme categorical > colorScheme > DEFAULT_COLOR.
19
+ * When a palette is available, cycles through colors by category name.
20
+ */
21
+ export declare function resolveDefaultFill(color: string | undefined, themeCategorical: string[] | undefined, colorScheme: string | string[] | undefined, category: string | undefined, categoryIndexMap: Map<string, number>): string;
11
22
  /**
12
23
  * Resolve an accessor (string key or function) into a function.
13
24
  * Used across chart components to normalize `valueAccessor`, `categoryAccessor`, etc.
@@ -15,7 +26,8 @@ export declare const DEFAULT_COLOR = "#007bff";
15
26
  export declare function resolveAccessor<T = any>(accessor: string | ((d: Record<string, any>, i?: number) => T)): (d: Record<string, any>) => T;
16
27
  /**
17
28
  * Hook to create a color scale from data and colorBy configuration.
18
- * Returns undefined when colorBy is absent or is a function accessor.
29
+ * Returns undefined when colorBy is absent or data is empty (push API mode).
30
+ * Supports both string and function accessors for colorBy.
19
31
  */
20
32
  export declare function useColorScale(data: Array<Record<string, any>>, colorBy: string | ((d: any, i?: number) => any) | undefined, colorScheme?: string | string[]): ((v: string) => string) | undefined;
21
33
  /**
@@ -31,7 +43,7 @@ export declare function useSortedData(data: Array<Record<string, any>>, sort: bo
31
43
  * @param unwrapData - Deprecated / no-op. Hover data is always unwrapped
32
44
  * (stream frames wrap the raw datum in { data, time, value, x, y }).
33
45
  */
34
- export declare function useChartSelection({ selection, linkedHover, fallbackFields, unwrapData, onObservation, chartType, chartId, }: {
46
+ export declare function useChartSelection({ selection, linkedHover, fallbackFields, unwrapData, onObservation, chartType, chartId, onClick, }: {
35
47
  selection?: SelectionConfig;
36
48
  linkedHover?: LinkedHoverProp;
37
49
  fallbackFields?: string[];
@@ -39,18 +51,32 @@ export declare function useChartSelection({ selection, linkedHover, fallbackFiel
39
51
  onObservation?: OnObservationCallback;
40
52
  chartType?: string;
41
53
  chartId?: string;
54
+ onClick?: (datum: any, event: {
55
+ x: number;
56
+ y: number;
57
+ }) => void;
42
58
  }): {
43
59
  activeSelectionHook: SelectionHookResult | null;
44
60
  customHoverBehavior: (d: Record<string, any> | null) => void;
45
61
  customClickBehavior: (d: Record<string, any> | null) => void;
62
+ /** Stable ID for this chart instance, used to suppress linked crosshair on source chart */
63
+ crosshairSourceId: string;
46
64
  };
65
+ /**
66
+ * Compute crosshair props for StreamXYFrame from linkedHover config.
67
+ * Returns undefined when linkedHover is not in x-position mode.
68
+ */
69
+ export declare function getCrosshairProps(linkedHover: unknown, crosshairSourceId: string): {
70
+ linkedCrosshairName: string;
71
+ linkedCrosshairSourceId: string;
72
+ } | undefined;
47
73
  /**
48
74
  * Hook to create a legend and compute margins with legend-aware adjustment.
49
75
  * Consolidates the shouldShowLegend / createLegend / margin merge / right-margin
50
76
  * expansion pattern that every chart with color encoding repeats.
51
77
  */
52
78
  export type LegendPosition = "right" | "left" | "top" | "bottom";
53
- export declare function useChartLegendAndMargin({ data, colorBy, colorScale, showLegend, legendPosition, userMargin, defaults, }: {
79
+ export declare function useChartLegendAndMargin({ data, colorBy, colorScale, showLegend, legendPosition, userMargin, defaults, categories, }: {
54
80
  data: Array<Record<string, any>>;
55
81
  colorBy: Accessor<string> | undefined;
56
82
  colorScale: ((v: string) => string) | undefined;
@@ -63,6 +89,7 @@ export declare function useChartLegendAndMargin({ data, colorBy, colorScale, sho
63
89
  left: number;
64
90
  right: number;
65
91
  };
92
+ categories?: string[];
66
93
  }): {
67
94
  legend: ReturnType<typeof createLegend> | undefined;
68
95
  margin: {
@@ -102,7 +129,13 @@ interface ChartModeInput {
102
129
  enableHover?: boolean;
103
130
  showLegend?: boolean;
104
131
  showLabels?: boolean;
132
+ showCategoryTicks?: boolean;
133
+ /** "vertical" | "horizontal" — used to shrink the category-axis margin when showCategoryTicks is false */
134
+ orientation?: string;
105
135
  title?: string;
136
+ description?: string;
137
+ summary?: string;
138
+ accessibleTable?: boolean;
106
139
  xLabel?: string;
107
140
  yLabel?: string;
108
141
  categoryLabel?: string;
@@ -119,6 +152,9 @@ interface ChartModeResult {
119
152
  showLegend: boolean | undefined;
120
153
  showLabels: boolean | undefined;
121
154
  title: string | undefined;
155
+ description: string | undefined;
156
+ summary: string | undefined;
157
+ accessibleTable: boolean | undefined;
122
158
  xLabel: string | undefined;
123
159
  yLabel: string | undefined;
124
160
  categoryLabel: string | undefined;
@@ -11,13 +11,14 @@ import type { LegendItem } from "../../types/legendTypes";
11
11
  * @param strokeWidth - Optional stroke width for legend items
12
12
  * @returns Legend configuration object for Semiotic frames
13
13
  */
14
- export declare function createLegend({ data, colorBy, colorScale, getColor, strokeColor, strokeWidth }: {
14
+ export declare function createLegend({ data, colorBy, colorScale, getColor, strokeColor, strokeWidth, categories }: {
15
15
  data: Array<Record<string, any>>;
16
16
  colorBy: Accessor<string>;
17
17
  colorScale?: ((v: string) => string);
18
18
  getColor: (d: Record<string, any>, accessor: Accessor<string>, scale?: ((v: string) => string)) => string;
19
19
  strokeColor?: string;
20
20
  strokeWidth?: number;
21
+ categories?: string[];
21
22
  }): {
22
23
  legendGroups: {
23
24
  styleFn: (d: LegendItem) => Record<string, string | number>;
@@ -7,6 +7,8 @@
7
7
  export interface NormalizedLinkedHover {
8
8
  name: string;
9
9
  fields: string[];
10
+ mode?: "field" | "x-position";
11
+ xField?: string;
10
12
  }
11
13
  export interface NormalizedLinkedBrush {
12
14
  name: string;
@@ -22,7 +24,9 @@ export interface NormalizedLinkedBrush {
22
24
  */
23
25
  export declare function normalizeLinkedHover(prop: boolean | string | {
24
26
  name?: string;
25
- fields: string[];
27
+ fields?: string[];
28
+ mode?: "field" | "x-position";
29
+ xField?: string;
26
30
  } | undefined, fallbackFields?: string[]): NormalizedLinkedHover | null;
27
31
  /**
28
32
  * Normalize the linkedBrush prop into a consistent config object.
@@ -44,8 +48,19 @@ export interface SelectionStyleConfig {
44
48
  unselectedStyle?: Record<string, any>;
45
49
  selectedStyle?: Record<string, any>;
46
50
  }
51
+ /** Default opacity for unselected (dimmed) elements */
52
+ export declare const DEFAULT_SELECTION_OPACITY = 0.2;
53
+ /**
54
+ * Read the --semiotic-selection-opacity CSS variable from a container element.
55
+ * Returns the numeric value or the default if not set or not parseable.
56
+ */
57
+ export declare function readSelectionOpacityFromCSS(container: Element | null): number;
47
58
  /**
48
59
  * Wrap a base style function with selection awareness.
49
60
  * When a selection is active, non-matching datums get dimmed.
61
+ *
62
+ * Dimming opacity is resolved in this order:
63
+ * 1. `config.unselectedOpacity` (explicit prop)
64
+ * 2. `DEFAULT_SELECTION_OPACITY` (0.2)
50
65
  */
51
66
  export declare function wrapStyleWithSelection(baseStyleFn: (d: Record<string, any>) => Record<string, any>, selectionHook: SelectionHookResult | null, config?: SelectionStyleConfig): (d: Record<string, any>) => Record<string, any>;
@@ -56,20 +56,64 @@ export interface ForecastConfig {
56
56
  trainDasharray?: string;
57
57
  /** Dash pattern for forecast line segment. Default: "4,4" */
58
58
  forecastDasharray?: string;
59
- /** Outlier dot color (pre-computed mode). Default: "#ef4444" */
60
- anomalyColor?: string;
61
- /** Outlier dot radius (pre-computed mode). Default: 6 */
62
- anomalyRadius?: number;
59
+ /** Stroke opacity for the training line segment (0–1). Default: 1 */
60
+ trainOpacity?: number;
61
+ /** Stroke opacity for the forecast line segment (0–1). Default: 1 */
62
+ forecastOpacity?: number;
63
+ /**
64
+ * Training line stroke color.
65
+ * - `"darken"`: auto-darken the line's own color by 50% (hex colors only —
66
+ * non-hex values like `rgb()` or CSS variables pass through unchanged).
67
+ * - Any CSS color string: use that color explicitly.
68
+ * - Omit to inherit the line's color unchanged.
69
+ */
70
+ trainStroke?: string;
71
+ /** Training line linecap (e.g. "round"). Default: inherits from base style */
72
+ trainLinecap?: string;
73
+ /**
74
+ * Render a solid underline beneath the dashed training line.
75
+ * - `true`: solid line in the base (or lightened) color beneath the dashed training line
76
+ * - `"lighten"`: solid line in a 40% lightened version of the line's color
77
+ * - Omit or `false`: no underline (default)
78
+ */
79
+ trainUnderline?: boolean | "lighten";
80
+ /**
81
+ * Outlier dot color.
82
+ * - `string`: fixed color (default: "#ef4444")
83
+ * - `(datum) => string`: per-datum color function
84
+ */
85
+ anomalyColor?: string | ((datum: Record<string, any>) => string);
86
+ /**
87
+ * Outlier dot radius.
88
+ * - `number`: fixed radius (default: 6)
89
+ * - `(datum) => number`: per-datum radius function (e.g. for count-based sizing)
90
+ */
91
+ anomalyRadius?: number | ((datum: Record<string, any>) => number);
92
+ /**
93
+ * Full style override for anomaly dots.
94
+ * When provided as a function, receives the datum and should return a CSS style object.
95
+ * Overrides `anomalyColor` when provided.
96
+ */
97
+ anomalyStyle?: Record<string, any> | ((datum: Record<string, any>) => Record<string, any>);
98
+ /**
99
+ * Internal: field name used to group data into separate lines (e.g. "metricLabel").
100
+ * When set, boundary point duplication only bridges within the same group,
101
+ * preventing cross-metric stray lines. Set automatically by LineChart when
102
+ * both lineBy and forecast are active.
103
+ * @internal
104
+ */
105
+ _groupBy?: string;
63
106
  /** Label for the forecast/envelope region */
64
107
  label?: string;
65
108
  }
66
109
  /** Internal segment marker added to each datum */
67
110
  export declare const SEGMENT_FIELD: "__forecastSegment";
68
- export type SegmentType = "training" | "observed" | "forecast";
111
+ export type SegmentType = "training" | "training-base" | "observed" | "forecast";
69
112
  export declare function buildAnomalyAnnotations(config: AnomalyConfig): Record<string, any>[];
70
113
  export interface ForecastResult {
71
114
  processedData: Record<string, any>[];
72
115
  annotations: Record<string, any>[];
73
116
  }
74
117
  export declare function buildForecast(data: Record<string, any>[], xAccessor: string, yAccessor: string, forecastConfig: ForecastConfig, anomalyConfig?: AnomalyConfig): ForecastResult;
118
+ export { darkenColor, lightenColor } from "./colorManipulation";
75
119
  export declare function createSegmentLineStyle(baseStyle: (d: Record<string, any>) => Record<string, any>, forecastConfig: ForecastConfig): (d: Record<string, any>) => Record<string, any>;
@@ -0,0 +1,11 @@
1
+ import * as React from "react";
2
+ /**
3
+ * Shared tooltip for distribution charts (BoxPlot, ViolinPlot, RidgelinePlot).
4
+ *
5
+ * Renders category name + summary statistics (n, min, Q1, median, Q3, max, mean).
6
+ * Falls back to category-only display when stats are unavailable.
7
+ */
8
+ export declare function buildStatsTooltip(options?: {
9
+ /** If provided, computes fallback stats from raw data when d.stats is missing */
10
+ valueAccessor?: string | ((d: any) => number);
11
+ }): (d: Record<string, any>) => React.ReactElement;
@@ -21,7 +21,9 @@ export interface SelectionConfig {
21
21
  */
22
22
  export type LinkedHoverProp = boolean | string | {
23
23
  name?: string;
24
- fields: string[];
24
+ fields?: string[];
25
+ mode?: "field" | "x-position";
26
+ xField?: string;
25
27
  };
26
28
  /**
27
29
  * Linked brush config
@@ -73,6 +75,23 @@ export interface BaseChartProps {
73
75
  loading?: boolean;
74
76
  /** Custom content to render when data is empty. Set to `false` to disable empty state. */
75
77
  emptyContent?: React.ReactNode | false;
78
+ /** Uniform fill color for all data marks. Overrides colorScheme and theme categorical.
79
+ * For per-category coloring, use `colorBy` + `colorScheme` instead. */
80
+ color?: string;
81
+ /** Accessible description overriding the auto-generated aria-label on the chart container.
82
+ * Should describe the chart's purpose or content for screen reader users. */
83
+ description?: string;
84
+ /** Accessible summary rendered as a screen-reader-only note.
85
+ * Use for trend descriptions or key takeaways that supplement the visual. */
86
+ summary?: string;
87
+ /** Enable accessible data table below the chart canvas. Default: true (via frame). */
88
+ accessibleTable?: boolean;
89
+ /** Callback when a data element is clicked. Receives the original datum and pixel coordinates.
90
+ * For lines, receives the line data; for bars, the bar datum; for pie slices, the slice datum. */
91
+ onClick?: (datum: any, event: {
92
+ x: number;
93
+ y: number;
94
+ }) => void;
76
95
  /** Visual emphasis level for dashboard hierarchy. "primary" spans two columns in ChartGrid. */
77
96
  emphasis?: "primary" | "secondary";
78
97
  /** Enable declarative bounded animation (enter/exit/update transitions).
@@ -91,10 +110,15 @@ export interface AxisConfig {
91
110
  /** Label for the y-axis */
92
111
  yLabel?: string;
93
112
  /** Format function for x-axis tick labels */
94
- xFormat?: (d: any) => string;
113
+ xFormat?: (d: any, index?: number, allTicks?: number[]) => string;
95
114
  /** Format function for y-axis tick labels */
96
115
  yFormat?: (d: any) => string;
97
116
  }
117
+ /**
118
+ * Category formatting for ordinal chart tick labels.
119
+ * Receives the category value and its index, returns a formatted string.
120
+ */
121
+ export type CategoryFormatFn = (label: string, index?: number) => string;
98
122
  /**
99
123
  * Accessor type - can be a property name or a function
100
124
  * @deprecated Use DataAccessor from generalTypes for generic type safety
@@ -19,8 +19,8 @@ export interface ChartSetupInput {
19
19
  rawData: unknown[] | undefined;
20
20
  /** The color-by accessor (may be an "actual" colorBy derived from stackBy/groupBy/categoryAccessor) */
21
21
  colorBy: Accessor<string> | undefined;
22
- /** Color scheme name or custom array */
23
- colorScheme: string | string[];
22
+ /** Color scheme name or custom array — undefined lets useColorScale consult the theme */
23
+ colorScheme: string | string[] | undefined;
24
24
  /** Legend interaction mode */
25
25
  legendInteraction: LegendInteractionMode | undefined;
26
26
  /** Legend position override */
@@ -50,6 +50,11 @@ export interface ChartSetupInput {
50
50
  left: number;
51
51
  right: number;
52
52
  };
53
+ /** onClick callback */
54
+ onClick?: (datum: any, event: {
55
+ x: number;
56
+ y: number;
57
+ }) => void;
53
58
  /** Loading state */
54
59
  loading: boolean | undefined;
55
60
  /** Empty content override */
@@ -92,6 +97,11 @@ export interface ChartSetupResult {
92
97
  earlyReturn: ReactElement | null;
93
98
  /** Props to spread into the stream frame for legend behavior */
94
99
  legendBehaviorProps: Record<string, any>;
100
+ /** Crosshair props to spread into StreamXYFrame when linkedHover mode is "x-position" */
101
+ crosshairProps: {
102
+ linkedCrosshairName: string;
103
+ linkedCrosshairSourceId: string;
104
+ } | undefined;
95
105
  }
96
106
  /**
97
107
  * Hook that consolidates the shared boilerplate across all HOC charts:
@@ -0,0 +1,51 @@
1
+ import type { RefObject, MutableRefObject } from "react";
2
+ import type { StreamOrdinalFrameHandle } from "../../stream/ordinalTypes";
3
+ export interface AggregatedRow {
4
+ __likertCategory: string;
5
+ /** Stacking key — may be sentinel value for neutral halves */
6
+ __likertLevel: string;
7
+ /** Human-readable level label — always the original level name (for legend/selection) */
8
+ __likertLevelLabel: string;
9
+ __likertCount: number;
10
+ __likertPct: number;
11
+ __likertLevelIndex: number;
12
+ }
13
+ /** Sentinel level names for the neutral split halves */
14
+ export declare const NEUTRAL_NEG = "__likert_neutral_neg";
15
+ export declare const NEUTRAL_POS = "__likert_neutral_pos";
16
+ export declare function resolveAccessorFn<T>(accessor: string | ((d: any) => T) | undefined, fallback: string): (d: any) => T;
17
+ /**
18
+ * Generate a diverging color scheme for N levels.
19
+ * Interpolates from red → gray → blue for odd, red → blue for even.
20
+ */
21
+ export declare function defaultDivergingScheme(n: number): string[];
22
+ export declare function aggregateData(data: any[], levels: string[], getCat: (d: any) => string, getScore: ((d: any) => number) | null, getLevel: ((d: any) => string) | null, getCount: ((d: any) => number) | null): AggregatedRow[];
23
+ export declare function toDivergingValues(rows: AggregatedRow[], levels: string[]): AggregatedRow[];
24
+ export declare function orderForDiverging(rows: AggregatedRow[], levels: string[]): AggregatedRow[];
25
+ interface UseLikertAggregationConfig {
26
+ data: any[] | undefined;
27
+ levels: string[];
28
+ categoryAccessor?: string | ((d: any) => string);
29
+ valueAccessor?: string | ((d: any) => number);
30
+ levelAccessor?: string | ((d: any) => string);
31
+ countAccessor?: string | ((d: any) => number);
32
+ isDiverging: boolean;
33
+ frameRef: RefObject<StreamOrdinalFrameHandle | null>;
34
+ }
35
+ interface UseLikertAggregationResult {
36
+ /** Pre-processed data for static mode */
37
+ processedData: AggregatedRow[];
38
+ /** Re-aggregate all accumulated data (call from push handlers) */
39
+ reAggregate: (rawData: any[]) => void;
40
+ /** Ref holding accumulated raw data for push mode */
41
+ accumulatorRef: MutableRefObject<any[]>;
42
+ }
43
+ /**
44
+ * Encapsulates Likert-specific data aggregation:
45
+ * - Resolves accessor functions
46
+ * - Aggregates raw/pre-aggregated data to percentages
47
+ * - Applies diverging transforms (sign flip, neutral split, stacking order)
48
+ * - Provides re-aggregation callback for push API streaming
49
+ */
50
+ export declare function useLikertAggregation({ data, levels, categoryAccessor, valueAccessor, levelAccessor, countAccessor, isDiverging, frameRef, }: UseLikertAggregationConfig): UseLikertAggregationResult;
51
+ export {};
@@ -0,0 +1,28 @@
1
+ import type { ChartAccessor } from "./types";
2
+ export interface OrdinalBrushInput {
3
+ brushProp: boolean | undefined;
4
+ onBrushProp: ((extent: {
5
+ r: [number, number];
6
+ } | null) => void) | undefined;
7
+ linkedBrush: string | {
8
+ name: string;
9
+ rField?: string;
10
+ } | undefined;
11
+ valueAccessor: ChartAccessor<any, number>;
12
+ }
13
+ export interface OrdinalBrushResult {
14
+ hasBrush: boolean;
15
+ handleBrush: (extent: {
16
+ r: [number, number];
17
+ } | null) => void;
18
+ /** Spread into streamProps: `...brushStreamProps` */
19
+ brushStreamProps: {
20
+ brush: {
21
+ dimension: "r";
22
+ };
23
+ onBrush: (extent: {
24
+ r: [number, number];
25
+ } | null) => void;
26
+ } | Record<string, never>;
27
+ }
28
+ export declare function useOrdinalBrush({ brushProp, onBrushProp, linkedBrush, valueAccessor, }: OrdinalBrushInput): OrdinalBrushResult;