semiotic 3.8.5 → 3.8.6

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 (176) hide show
  1. package/CLAUDE.md +5 -4
  2. package/README.md +42 -42
  3. package/ai/behaviorContracts.cjs +2 -2
  4. package/ai/componentMetadata.cjs +1 -1
  5. package/ai/dist/mcp-server.js +2 -0
  6. package/ai/examples.md +44 -2
  7. package/ai/schema.json +385 -14
  8. package/ai/surface-manifest.json +6 -4
  9. package/ai/system-prompt.md +1 -1
  10. package/dist/{chunk-chartContainerDataAudit-74TLKIP6.module.min.js → chunk-chartContainerDataAudit-FEOD5GTQ.module.min.js} +1 -1
  11. package/dist/chunk-chunk-2CHN2TA3.module.min.js +1 -0
  12. package/dist/chunk-chunk-2JGJ5GUG.module.min.js +1 -0
  13. package/dist/chunk-chunk-3NGIKFD6.module.min.js +1 -0
  14. package/dist/chunk-chunk-3SHB24AG.module.min.js +1 -0
  15. package/dist/chunk-chunk-4MMOOYTX.module.min.js +2 -0
  16. package/dist/{chunk-chunk-KT2VAZMZ.module.min.js → chunk-chunk-75OTQSXS.module.min.js} +1 -1
  17. package/dist/chunk-chunk-A5GRQUOF.module.min.js +1 -0
  18. package/dist/chunk-chunk-AAF5LZAU.module.min.js +2 -0
  19. package/dist/{chunk-chunk-4AANPFOX.module.min.js → chunk-chunk-ARZGA4LJ.module.min.js} +1 -1
  20. package/dist/chunk-chunk-CAFLML4L.module.min.js +2 -0
  21. package/dist/chunk-chunk-FHBN7OEB.module.min.js +2 -0
  22. package/dist/{chunk-chunk-TMWIZL3K.module.min.js → chunk-chunk-GFTVACTO.module.min.js} +1 -1
  23. package/dist/chunk-chunk-IP2UE74X.module.min.js +1 -0
  24. package/dist/chunk-chunk-ITDWLZXV.module.min.js +2 -0
  25. package/dist/chunk-chunk-LPSPATPC.module.min.js +1 -0
  26. package/dist/chunk-chunk-OM6NWS4H.module.min.js +2 -0
  27. package/dist/chunk-chunk-PX5YQGDP.module.min.js +2 -0
  28. package/dist/chunk-chunk-Q2BS46W2.module.min.js +2 -0
  29. package/dist/{chunk-chunk-LJLS6DY7.module.min.js → chunk-chunk-RA7JCG7D.module.min.js} +1 -1
  30. package/dist/chunk-chunk-RNUHEXZA.module.min.js +2 -0
  31. package/dist/chunk-chunk-ROZWKEUG.module.min.js +1 -0
  32. package/dist/chunk-chunk-SMVD3EQJ.module.min.js +2 -0
  33. package/dist/chunk-chunk-T2FKJD4O.module.min.js +2 -0
  34. package/dist/{chunk-chunk-K3DMEW22.module.min.js → chunk-chunk-UDREYOLV.module.min.js} +1 -1
  35. package/dist/chunk-chunk-VOWE3SAP.module.min.js +2 -0
  36. package/dist/chunk-chunk-VQPNBUSW.module.min.js +2 -0
  37. package/dist/{chunk-chunk-N5DDKCCF.module.min.js → chunk-chunk-WAWCIHFJ.module.min.js} +1 -1
  38. package/dist/{chunk-chunk-XXWSHGPL.module.min.js → chunk-chunk-WYARAXHR.module.min.js} +1 -1
  39. package/dist/{chunk-chunk-I36PJ4OC.module.min.js → chunk-chunk-XP3OHHFX.module.min.js} +1 -1
  40. package/dist/chunk-chunk-XV3KGYTR.module.min.js +2 -0
  41. package/dist/chunk-chunk-YC2IVEPX.module.min.js +1 -0
  42. package/dist/components/ai/chartCapabilities.d.ts +2 -1
  43. package/dist/components/charts/custom/XYCustomChart.d.ts +3 -0
  44. package/dist/components/charts/geo/DistanceCartogram.d.ts +1 -1
  45. package/dist/components/charts/index.d.ts +3 -0
  46. package/dist/components/charts/ordinal/BarChart.d.ts +7 -14
  47. package/dist/components/charts/ordinal/GaugeChart.d.ts +3 -0
  48. package/dist/components/charts/ordinal/GroupedBarChart.d.ts +3 -0
  49. package/dist/components/charts/ordinal/StackedBarChart.d.ts +3 -0
  50. package/dist/components/charts/ordinal/SwimlaneChart.d.ts +4 -14
  51. package/dist/components/charts/shared/chartSpecCore.d.ts +2 -4
  52. package/dist/components/charts/shared/gaugeGradient.d.ts +4 -8
  53. package/dist/components/charts/shared/gradient.d.ts +35 -0
  54. package/dist/components/charts/shared/hatchFill.d.ts +3 -10
  55. package/dist/components/charts/shared/hooks.d.ts +2 -50
  56. package/dist/components/charts/shared/knownChartComponents.d.ts +1 -1
  57. package/dist/components/charts/shared/streamPropsHelpers.d.ts +1 -2
  58. package/dist/components/charts/shared/useChartLegend.d.ts +58 -0
  59. package/dist/components/charts/shared/useChartSetup.d.ts +5 -0
  60. package/dist/components/charts/shared/useCustomChartSetup.d.ts +6 -1
  61. package/dist/components/charts/shared/useNetworkChartSetup.d.ts +1 -0
  62. package/dist/components/charts/shared/useStreamingLegend.d.ts +1 -1
  63. package/dist/components/charts/xy/AreaChart.d.ts +25 -42
  64. package/dist/components/charts/xy/BumpChart.capability.d.ts +11 -0
  65. package/dist/components/charts/xy/BumpChart.d.ts +161 -0
  66. package/dist/components/charts/xy/DifferenceChart.d.ts +3 -10
  67. package/dist/components/charts/xy/Heatmap.d.ts +3 -0
  68. package/dist/components/charts/xy/LineChart.d.ts +6 -8
  69. package/dist/components/geometry/bumpRibbonGeometry.d.ts +36 -0
  70. package/dist/components/legendLayout.d.ts +19 -1
  71. package/dist/components/semiotic-ai.d.ts +2 -1
  72. package/dist/components/semiotic-geo.d.ts +1 -0
  73. package/dist/components/semiotic-network.d.ts +1 -0
  74. package/dist/components/semiotic-ordinal.d.ts +2 -0
  75. package/dist/components/semiotic-physics.d.ts +1 -0
  76. package/dist/components/semiotic-realtime-core.d.ts +1 -0
  77. package/dist/components/semiotic-server-edge.d.ts +1 -1
  78. package/dist/components/semiotic-server.d.ts +1 -1
  79. package/dist/components/semiotic-xy.d.ts +4 -0
  80. package/dist/components/semiotic.d.ts +4 -4
  81. package/dist/components/server/serverChartConfigs.d.ts +1 -0
  82. package/dist/components/server/serverChartConfigsXY.d.ts +1 -0
  83. package/dist/components/server/staticLegend.d.ts +4 -2
  84. package/dist/components/server/staticSVGChrome.d.ts +4 -4
  85. package/dist/components/stream/GeoSVGOverlay.d.ts +4 -10
  86. package/dist/components/stream/NetworkSVGOverlay.d.ts +2 -6
  87. package/dist/components/stream/OrdinalSVGOverlay.d.ts +2 -6
  88. package/dist/components/stream/SVGOverlay.d.ts +2 -6
  89. package/dist/components/stream/StalenessBadge.d.ts +2 -6
  90. package/dist/components/stream/geoTypes.d.ts +3 -6
  91. package/dist/components/stream/legendRenderer.d.ts +2 -6
  92. package/dist/components/stream/ordinalTypes.d.ts +7 -31
  93. package/dist/components/stream/physics/PhysicsKernel.d.ts +1 -0
  94. package/dist/components/stream/physics/PhysicsSVGOverlay.d.ts +2 -6
  95. package/dist/components/stream/physics/StreamPhysicsTypes.d.ts +2 -6
  96. package/dist/components/stream/pipelineConfig.d.ts +7 -15
  97. package/dist/components/stream/renderers/canvasRenderHelpers.d.ts +9 -69
  98. package/dist/components/stream/renderers/cornerRadii.d.ts +2 -9
  99. package/dist/components/stream/renderers/thresholdLineSegments.d.ts +12 -0
  100. package/dist/components/stream/sceneToSVGShared.d.ts +3 -5
  101. package/dist/components/stream/types.d.ts +32 -56
  102. package/dist/components/stream/xySceneBuilders/areaGradient.d.ts +4 -20
  103. package/dist/components/stream/xySceneBuilders/types.d.ts +6 -6
  104. package/dist/components/types/legendTypes.d.ts +15 -6
  105. package/dist/geo.min.js +1 -1
  106. package/dist/geo.module.min.js +1 -1
  107. package/dist/network.min.js +1 -1
  108. package/dist/network.module.min.js +1 -1
  109. package/dist/ordinal.min.js +1 -1
  110. package/dist/ordinal.module.min.js +1 -1
  111. package/dist/physics.min.js +1 -1
  112. package/dist/physics.module.min.js +1 -1
  113. package/dist/physicsWorker.js +1 -1
  114. package/dist/realtime.min.js +1 -1
  115. package/dist/realtime.module.min.js +1 -1
  116. package/dist/semiotic-ai-core.min.js +1 -1
  117. package/dist/semiotic-ai-core.module.min.js +1 -1
  118. package/dist/semiotic-ai.d.ts +2 -1
  119. package/dist/semiotic-ai.min.js +1 -1
  120. package/dist/semiotic-ai.module.min.js +1 -1
  121. package/dist/semiotic-experimental.min.js +1 -1
  122. package/dist/semiotic-experimental.module.min.js +1 -1
  123. package/dist/semiotic-geo.d.ts +1 -0
  124. package/dist/semiotic-network.d.ts +1 -0
  125. package/dist/semiotic-ordinal.d.ts +2 -0
  126. package/dist/semiotic-physics.d.ts +1 -0
  127. package/dist/semiotic-realtime-core.d.ts +1 -0
  128. package/dist/semiotic-realtime-core.min.js +1 -1
  129. package/dist/semiotic-realtime-core.module.min.js +1 -1
  130. package/dist/semiotic-recipes-core.module.min.js +1 -1
  131. package/dist/semiotic-recipes.module.min.js +1 -1
  132. package/dist/semiotic-server-edge.d.ts +1 -1
  133. package/dist/semiotic-server-edge.min.js +1 -1
  134. package/dist/semiotic-server-edge.module.min.js +1 -1
  135. package/dist/semiotic-server-node.min.js +1 -1
  136. package/dist/semiotic-server-node.module.min.js +1 -1
  137. package/dist/semiotic-server.d.ts +1 -1
  138. package/dist/semiotic-utils-core.min.js +1 -1
  139. package/dist/semiotic-utils-core.module.min.js +1 -1
  140. package/dist/semiotic-utils.min.js +1 -1
  141. package/dist/semiotic-utils.module.min.js +1 -1
  142. package/dist/semiotic-xy.d.ts +4 -0
  143. package/dist/semiotic.d.ts +4 -4
  144. package/dist/semiotic.min.js +1 -1
  145. package/dist/semiotic.module.min.js +1 -1
  146. package/dist/server.min.js +1 -1
  147. package/dist/server.module.min.js +1 -1
  148. package/dist/xy.min.js +1 -1
  149. package/dist/xy.module.min.js +1 -1
  150. package/package.json +1 -1
  151. package/dist/chunk-chunk-5I3UZV4Q.module.min.js +0 -2
  152. package/dist/chunk-chunk-74CCPVXB.module.min.js +0 -1
  153. package/dist/chunk-chunk-ANYDWOZF.module.min.js +0 -1
  154. package/dist/chunk-chunk-AVBI6GDT.module.min.js +0 -1
  155. package/dist/chunk-chunk-BANTPINB.module.min.js +0 -2
  156. package/dist/chunk-chunk-C57LR3YG.module.min.js +0 -1
  157. package/dist/chunk-chunk-CKMD5NV3.module.min.js +0 -2
  158. package/dist/chunk-chunk-CWQ5YIHX.module.min.js +0 -2
  159. package/dist/chunk-chunk-E6TXX6MI.module.min.js +0 -1
  160. package/dist/chunk-chunk-L6EA5V3G.module.min.js +0 -2
  161. package/dist/chunk-chunk-LJPCLYSC.module.min.js +0 -2
  162. package/dist/chunk-chunk-LRIFN2HK.module.min.js +0 -1
  163. package/dist/chunk-chunk-NEVE562N.module.min.js +0 -1
  164. package/dist/chunk-chunk-NLO44TOS.module.min.js +0 -2
  165. package/dist/chunk-chunk-PZJ2SBLL.module.min.js +0 -2
  166. package/dist/chunk-chunk-QUJ6TTLY.module.min.js +0 -1
  167. package/dist/chunk-chunk-RBIDBUT4.module.min.js +0 -2
  168. package/dist/chunk-chunk-RFLAG356.module.min.js +0 -1
  169. package/dist/chunk-chunk-RPU4IZAV.module.min.js +0 -2
  170. package/dist/chunk-chunk-SKMBCFIL.module.min.js +0 -2
  171. package/dist/chunk-chunk-TAE7W424.module.min.js +0 -2
  172. package/dist/chunk-chunk-TUBMTZMU.module.min.js +0 -2
  173. package/dist/chunk-chunk-UFFEXJQY.module.min.js +0 -1
  174. package/dist/chunk-chunk-XSCHTS4D.module.min.js +0 -2
  175. package/dist/chunk-statisticalOverlays-QGDLRUHX.module.min.js +0 -1
  176. package/dist/chunk-statisticalOverlays-T77OKLDY.module.min.js +0 -1
@@ -8,12 +8,8 @@ interface StalenessBadgeProps {
8
8
  * `staleness.showBadge` is set.
9
9
  *
10
10
  * Shared by all four Stream Frames (XY / ordinal / network / geo) so the badge
11
- * is pixel-identical across families. Previously each frame inlined its own
12
- * copy and they had drifted — the network frame used a smaller, heavier variant
13
- * (10px/700, tighter padding, letterSpacing). This is the canonical style: the
14
- * more legible 11px/600 the other three shared, plus `zIndex`/`pointerEvents`
15
- * hardening so the badge always sits above the canvas and never intercepts
16
- * pointer events.
11
+ * is pixel-identical across families. The badge sits above the canvas and does
12
+ * not intercept pointer events.
17
13
  */
18
14
  export declare function StalenessBadge({ isStale, position }: StalenessBadgeProps): import("react").JSX.Element;
19
15
  export {};
@@ -1,6 +1,6 @@
1
1
  import type { ReactNode } from "react";
2
2
  import type { GeoProjection, GeoPath, GeoPermissibleObjects } from "d3-geo";
3
- import type { GradientLegendConfig, LegendGroup, LegendLayout } from "../types/legendTypes";
3
+ import type { LegendLayout, LegendValue } from "../types/legendTypes";
4
4
  import type { Style, DecayConfig, PulseConfig, TransitionConfig, StalenessConfig, SceneDatum, PointSceneNode, GlyphSceneNode, ThemeSemanticColors, SceneAccessibilityMetadata, SceneRenderMode } from "./types";
5
5
  import type { AnimateProp } from "./pipelineTransitionUtils";
6
6
  import type { AnnotationContext, HoverAnnotationConfig, HoverData } from "../realtime/types";
@@ -33,6 +33,7 @@ export interface DistanceCartogramConfig {
33
33
  center: string;
34
34
  centerAccessor?: string | ((d: Datum) => string);
35
35
  costAccessor: string | ((d: Datum) => number);
36
+ /** Interpolation from fitted geography (0) to the cost layout (1). Values are clamped to [0, 1]. */
36
37
  strength?: number;
37
38
  lineMode?: "straight" | "fractional";
38
39
  /**
@@ -276,11 +277,7 @@ export interface StreamGeoFrameProps<T = Datum> {
276
277
  backgroundGraphics?: ReactNode;
277
278
  foregroundGraphics?: ReactNode;
278
279
  title?: string | ReactNode;
279
- legend?: ReactNode | {
280
- legendGroups: LegendGroup[];
281
- } | {
282
- gradient: GradientLegendConfig;
283
- };
280
+ legend?: LegendValue;
284
281
  legendPosition?: "right" | "left" | "top" | "bottom";
285
282
  legendLayout?: LegendLayout;
286
283
  legendHoverBehavior?: (item: {
@@ -1,11 +1,7 @@
1
1
  import type { ReactNode } from "react";
2
- import type { LegendGroup, GradientLegendConfig, LegendLayout } from "../types/legendTypes";
2
+ import type { LegendLayout, LegendValue } from "../types/legendTypes";
3
3
  export interface LegendRenderConfig {
4
- legend: ReactNode | {
5
- legendGroups: LegendGroup[];
6
- } | {
7
- gradient: GradientLegendConfig;
8
- };
4
+ legend: LegendValue;
9
5
  totalWidth: number;
10
6
  totalHeight: number;
11
7
  margin: {
@@ -5,11 +5,12 @@ import type { AutoPlaceAnnotations } from "../recipes/annotationLayout";
5
5
  import type { SymbolName } from "./symbolPath";
6
6
  import type { Style, SceneDatum, DecayConfig, PulseConfig, TransitionConfig, StalenessConfig, ThemeSemanticColors, FrameGraphicsProp, SceneAccessibilityMetadata, SceneRenderMode } from "./types";
7
7
  import type { AnimateProp } from "./pipelineTransitionUtils";
8
- import type { GradientLegendConfig, LegendGroup, LegendLayout } from "../types/legendTypes";
8
+ import type { LegendLayout, LegendValue } from "../types/legendTypes";
9
9
  import type { Datum } from "../charts/shared/datumTypes";
10
10
  import type { OnObservationCallback } from "../store/ObservationStore";
11
11
  import type { SemanticClickBehavior, SemanticHoverBehavior } from "../charts/shared/semanticInteractions";
12
12
  import type { OnAnnotationActivateCallback } from "../charts/shared/annotationActivation";
13
+ import type { GradientConfig, GradientInput } from "../charts/shared/gradient";
13
14
  export type OrdinalChartType = "bar" | "clusterbar" | "point" | "swarm" | "pie" | "donut" | "boxplot" | "violin" | "histogram" | "ridgeline" | "timeline" | "funnel" | "bar-funnel" | "swimlane" | "custom";
14
15
  export interface OrdinalScales {
15
16
  o: ScaleBand<string>;
@@ -223,20 +224,8 @@ export interface OrdinalPipelineConfig {
223
224
  barPadding?: number;
224
225
  /** Rounded top corner radius for bar charts. Only the end away from the baseline is rounded. For stacked bars, only the topmost segment gets rounded. */
225
226
  roundedTop?: number;
226
- /** Gradient fill for bar rects. `{ topOpacity, bottomOpacity }` fades the
227
- * resolved fill color from tip (opposite the baseline) to base; `{ colorStops }`
228
- * renders a multi-color gradient along the same axis. Direction follows the
229
- * bar's orientation (tip → base). Same shape as AreaChart.gradientFill
230
- * sans the `boolean` case — the HOC resolves `true` to default opacities. */
231
- gradientFill?: {
232
- topOpacity: number;
233
- bottomOpacity: number;
234
- } | {
235
- colorStops: Array<{
236
- offset: number;
237
- color: string;
238
- }>;
239
- };
227
+ /** Gradient fill for bar rects. Offset 0 is the tip; offset 1 is the base. */
228
+ gradientFill?: GradientConfig;
240
229
  /** Swimlane "track" fill — a rect drawn behind each lane spanning the
241
230
  * full value-axis range, sized to the lane's bandwidth. Used to make
242
231
  * budget/progress lanes read as filled vs. empty. Pass a color (CSS
@@ -339,17 +328,8 @@ export interface StreamOrdinalFrameProps<T = Datum> {
339
328
  };
340
329
  barPadding?: number;
341
330
  roundedTop?: number;
342
- /** Gradient fill for bar rects. Same shape as AreaChart.gradientFill sans
343
- * the boolean case — resolve booleans at the HOC layer. */
344
- gradientFill?: {
345
- topOpacity: number;
346
- bottomOpacity: number;
347
- } | {
348
- colorStops: Array<{
349
- offset: number;
350
- color: string;
351
- }>;
352
- };
331
+ /** Gradient fill for bar rects. Offset 0 is the tip; offset 1 is the base. */
332
+ gradientFill?: GradientInput;
353
333
  /** Swimlane "track" fill — see OrdinalPipelineConfig.trackFill */
354
334
  trackFill?: string | {
355
335
  color: string;
@@ -430,11 +410,7 @@ export interface StreamOrdinalFrameProps<T = Datum> {
430
410
  autoPlaceAnnotations?: AutoPlaceAnnotations;
431
411
  svgAnnotationRules?: (annotation: Datum, index: number, context: AnnotationContext) => ReactNode;
432
412
  showGrid?: boolean;
433
- legend?: ReactNode | {
434
- legendGroups: LegendGroup[];
435
- } | {
436
- gradient: GradientLegendConfig;
437
- };
413
+ legend?: LegendValue;
438
414
  legendHoverBehavior?: (item: {
439
415
  label: string;
440
416
  } | null) => void;
@@ -201,6 +201,7 @@ export declare class PhysicsKernelWorld {
201
201
  private resolveStaticCollision;
202
202
  private updateSensors;
203
203
  private updateSleeping;
204
+ private contactOpposesGravity;
204
205
  private wake;
205
206
  /** Uses the deterministic PRNG for future jittered spawn helpers. */
206
207
  nextRandom(): number;
@@ -6,7 +6,7 @@
6
6
  import type { Datum } from "../../charts/shared/datumTypes";
7
7
  import * as React from "react";
8
8
  import type { ReactNode } from "react";
9
- import type { LegendGroup, GradientLegendConfig, LegendLayout } from "../../types/legendTypes";
9
+ import type { LegendLayout, LegendValue } from "../../types/legendTypes";
10
10
  import { type AutoPlaceAnnotations } from "../../recipes/annotationLayout";
11
11
  import type { AnnotationContext } from "../../realtime/types";
12
12
  import type { PhysicsBodyState } from "./PhysicsKernel";
@@ -31,11 +31,7 @@ export interface PhysicsSVGOverlayProps {
31
31
  left: number;
32
32
  };
33
33
  title?: string | ReactNode;
34
- legend?: ReactNode | {
35
- legendGroups: LegendGroup[];
36
- } | {
37
- gradient: GradientLegendConfig;
38
- };
34
+ legend?: LegendValue;
39
35
  legendHoverBehavior?: (item: {
40
36
  label: string;
41
37
  } | null) => void;
@@ -10,7 +10,7 @@ import type { Datum } from "../../charts/shared/datumTypes";
10
10
  import type { OnObservationCallback } from "../../store/ObservationStore";
11
11
  import type { AutoPlaceAnnotations } from "../../recipes/annotationLayout";
12
12
  import type { AnnotationContext } from "../../realtime/types";
13
- import type { GradientLegendConfig, LegendGroup, LegendLayout } from "../../types/legendTypes";
13
+ import type { LegendLayout, LegendValue } from "../../types/legendTypes";
14
14
  import type { FocusRingProps } from "../FocusRing";
15
15
  import type { PhysicsBodyState, PhysicsColliderBodyFilter, PhysicsColliderShape } from "./PhysicsKernel";
16
16
  import type { PhysicsPipelineConfig, PhysicsPipelineControlSurface, PhysicsPipelineStore, PhysicsPipelineTickResult, PhysicsQueuedSpawn, PhysicsSpawnPacingOptions, PhysicsSimulationState, PhysicsObservationEvent } from "./PhysicsPipelineStore";
@@ -245,11 +245,7 @@ export interface StreamPhysicsFrameProps {
245
245
  onAnnotationActivate?: import("../../charts/shared/annotationActivation").OnAnnotationActivateCallback;
246
246
  autoPlaceAnnotations?: AutoPlaceAnnotations;
247
247
  svgAnnotationRules?: (annotation: Datum, index: number, context: AnnotationContext) => React.ReactNode;
248
- legend?: React.ReactNode | {
249
- legendGroups: LegendGroup[];
250
- } | {
251
- gradient: GradientLegendConfig;
252
- };
248
+ legend?: LegendValue;
253
249
  legendHoverBehavior?: (item: {
254
250
  label: string;
255
251
  } | null) => void;
@@ -8,6 +8,7 @@ import type { CoercibleNumber } from "./accessorUtils";
8
8
  import type { CustomLayout } from "./customLayout";
9
9
  import type { CustomLayoutSelection } from "./customLayoutSelection";
10
10
  import type { MarginType } from "../types/marginType";
11
+ import type { GradientConfig } from "../charts/shared/gradient";
11
12
  export interface PipelineConfig {
12
13
  chartType: StreamChartType;
13
14
  runtimeMode?: "streaming" | "bounded";
@@ -76,22 +77,13 @@ export interface PipelineConfig {
76
77
  boundsStyle?: Style | ((d: Datum, group?: string) => Style);
77
78
  y0Accessor?: string | ((d: Datum) => CoercibleNumber);
78
79
  band?: BandConfig | BandConfig[];
79
- gradientFill?: {
80
- topOpacity: number;
81
- bottomOpacity: number;
82
- } | {
83
- colorStops: Array<{
84
- offset: number;
85
- color: string;
86
- }>;
87
- };
80
+ gradientFill?: GradientConfig;
88
81
  areaGroups?: Set<string>;
89
- lineGradient?: {
90
- colorStops: Array<{
91
- offset: number;
92
- color: string;
93
- }>;
94
- };
82
+ lineGradient?: GradientConfig;
83
+ semanticLineStops?: Array<{
84
+ offset: number;
85
+ color: string;
86
+ }>;
95
87
  lineStyle?: Style | ((d: Datum, group?: string) => Style);
96
88
  pointStyle?: (d: Datum) => Style & {
97
89
  r?: number;
@@ -1,50 +1,12 @@
1
- /**
2
- * Shared canvas-rendering primitives used by `bar`/`area`/`line`/`point`
3
- * renderers (and any future mark renderer that paints a fill, a stroke,
4
- * or a linear gradient).
5
- *
6
- * These are extractions, not abstractions: every function in this module
7
- * was inline-duplicated across two or more renderers in byte-identical
8
- * (or near-identical) form. Centralizing them eliminates drift at the
9
- * "what does the canvas seam look like for a stream renderer" boundary
10
- * and keeps each renderer focused on its mark-specific path tracing.
11
- *
12
- * Anything genuinely chart-shape-specific — `buildBarGradient`'s
13
- * tip-vs-base coordinate computation from `node.roundedEdge`, the
14
- * area's strip-decay path, the line's threshold-color crossing logic —
15
- * stays in the renderer that owns the mark. The helpers here are the
16
- * mechanical bits that recur regardless of the shape being painted.
17
- */
1
+ /** Shared canvas primitives for fills, strokes, curves, and gradients. */
18
2
  import type { CurveType } from "../types";
3
+ import type { GradientConfig } from "../../charts/shared/gradient";
19
4
  import { type HatchFill } from "../../charts/shared/hatchFill";
20
5
  import type { CurveFactory } from "d3-shape";
21
- /**
22
- * Structural shapes for the gradient configs the helpers accept. Kept
23
- * local rather than exported from `types.ts` because today's scene-node
24
- * interfaces (`AreaSceneNode`, `RectSceneNode`, `LineSceneNode`) declare
25
- * the same shapes inline. TS structural typing means a caller passing
26
- * `node.fillGradient` satisfies these types without an explicit cast.
27
- */
28
- type ColorStop = {
29
- offset: number;
30
- color: string;
31
- };
32
- export type ColorStopGradient = {
33
- colorStops: ColorStop[];
34
- };
35
- export type OpacityGradient = {
36
- topOpacity: number;
37
- bottomOpacity: number;
38
- };
39
- export type FillGradient = ColorStopGradient | OpacityGradient;
40
6
  /**
41
7
  * Map a `CurveType` string to a d3-shape curve factory. Returns `null`
42
8
  * for `"linear"` and `undefined` so callers can branch on a single
43
9
  * "use linear fallback" sentinel instead of a separate has-curve check.
44
- *
45
- * Identical implementations previously lived in `areaCanvasRenderer.ts`
46
- * and `lineCanvasRenderer.ts` — every new curve token had to be added
47
- * to both switches in lockstep.
48
10
  */
49
11
  export declare function resolveCurveFactory(curve: CurveType | undefined): CurveFactory | null;
50
12
  /**
@@ -52,15 +14,10 @@ export declare function resolveCurveFactory(curve: CurveType | undefined): Curve
52
14
  * canvas can accept as `fillStyle` / `strokeStyle`:
53
15
  *
54
16
  * - Strings go through `resolveCSSColor` so `var(...)` references
55
- * resolve via the canvas DOM ancestor's computed style. Without
56
- * this, canvas silently rejects CSS-variable strings and falls
57
- * back to `#000000`.
17
+ * resolve via the canvas DOM ancestor's computed style.
58
18
  * - `CanvasPattern` values pass through untouched.
59
19
  * - `null` / `undefined` returns the caller-provided fallback.
60
20
  *
61
- * The previous inline form was
62
- * `(typeof X === "string" ? resolveCSSColor(ctx, X) : X) || fallback`,
63
- * repeated once per renderer per fill/stroke site.
64
21
  */
65
22
  export declare function resolveCanvasFill(ctx: CanvasRenderingContext2D, fill: string | HatchFill | CanvasPattern | null | undefined, fallback: string): string | CanvasPattern;
66
23
  /**
@@ -77,30 +34,13 @@ export declare function resolveCanvasFill(ctx: CanvasRenderingContext2D, fill: s
77
34
  */
78
35
  export declare function coerceCanvasFill(ctx: CanvasRenderingContext2D, fill: string | HatchFill | CanvasPattern | null | undefined): string | CanvasPattern | undefined;
79
36
  /**
80
- * Build a linear gradient from a `FillGradient` config. Returns `null`
81
- * when the gradient cannot be constructed (fewer than two valid color
82
- * stops in the `colorStops` form, or a non-finite opacity in the
83
- * `topOpacity` form).
37
+ * Build a linear gradient from a normalized gradient config. Stops without a
38
+ * color inherit the resolved mark color.
84
39
  *
85
40
  * The renderer is responsible for choosing the gradient axis (a bar
86
41
  * runs tip→base along its value axis; an area runs minTop→maxBottom
87
- * vertically). The opacity-form path color-normalizes through the
88
- * canvas via `parseCanvasColor` so named colors (`steelblue`), hsl(),
89
- * etc. all produce gradients that match the mark's actual fill.
90
- *
91
- * Replaces `buildBarGradient` (bar) and the inline gradient block in
92
- * `areaCanvasRenderer` — both implemented the same two-shape switch
93
- * with the same offset-clamping and the same parseCanvasColor flow.
94
- */
95
- export declare function buildLinearFillGradient(ctx: CanvasRenderingContext2D, fillGradient: FillGradient, baseFill: string, x0: number, y0: number, x1: number, y1: number): CanvasGradient | null;
96
- /**
97
- * Build a linear gradient from a `ColorStopGradient` (the stroke-side
98
- * shape — only the `colorStops` form, no opacity variant). Returns
99
- * `null` when there aren't enough valid stops to render a gradient.
100
- *
101
- * Caller picks the axis. Identical patterns previously lived inline in
102
- * `areaCanvasRenderer`'s top-stroke branch and `lineCanvasRenderer`'s
103
- * stroke branch.
42
+ * vertically).
104
43
  */
105
- export declare function buildColorStopGradient(ctx: CanvasRenderingContext2D, strokeGradient: ColorStopGradient, x0: number, y0: number, x1: number, y1: number): CanvasGradient | null;
106
- export {};
44
+ export declare function buildLinearFillGradient(ctx: CanvasRenderingContext2D, fillGradient: GradientConfig, baseFill: string, x0: number, y0: number, x1: number, y1: number): CanvasGradient | null;
45
+ /** Build a linear stroke gradient along the caller-provided axis. */
46
+ export declare function buildColorStopGradient(ctx: CanvasRenderingContext2D, strokeGradient: GradientConfig, baseStroke: string, x0: number, y0: number, x1: number, y1: number): CanvasGradient | null;
@@ -1,13 +1,6 @@
1
1
  /**
2
- * Per-corner radius utilities shared between the canvas (`barCanvasRenderer`)
3
- * and SVG (`SceneToSVG`) paint paths.
4
- *
5
- * Both paths previously carried the same `hasAnyCornerRadius` predicate
6
- * and the same `min(radius, w/2, h/2)` clamp inline. Splitting them by
7
- * renderer left two near-identical implementations that drifted in
8
- * comments more than once; centralizing here keeps the swimlane rounding
9
- * contract — and any future per-corner shape (cards, tab corners,
10
- * partial-stack rounding) — in one place.
2
+ * Per-corner radius geometry shared between the canvas
3
+ * (`barCanvasRenderer`) and SVG (`SceneToSVG`) paint paths.
11
4
  *
12
5
  * The actual path-tracing primitives (canvas `arcTo` vs SVG `A`) stay in
13
6
  * each renderer because their output formats differ — this module owns
@@ -0,0 +1,12 @@
1
+ import type { LineColorThreshold } from "../types";
2
+ export interface ThresholdLineSegment {
3
+ color: string;
4
+ path: [number, number][];
5
+ }
6
+ export declare function resolveThresholdColor(value: number, thresholds: LineColorThreshold[], baseColor: string): string;
7
+ /**
8
+ * Split a value-bearing polyline wherever it crosses a color threshold.
9
+ * Adjacent intervals with the same resolved color are merged so canvas and
10
+ * SVG can paint identical hard-edged bands with a minimal number of paths.
11
+ */
12
+ export declare function buildThresholdLineSegments(path: [number, number][], rawValues: number[], thresholds: LineColorThreshold[], baseColor: string): ThresholdLineSegment[];
@@ -9,6 +9,7 @@ import type { DefaultArcObject } from "d3-shape";
9
9
  import { type HatchFill } from "../charts/shared/hatchFill";
10
10
  import type { GlyphDef } from "./glyphDef";
11
11
  import type { RectSceneNode, Style, SymbolSceneNode } from "./types";
12
+ import type { GradientStop } from "../charts/shared/gradient";
12
13
  /**
13
14
  * Sentinel arg for d3-shape arc generators that have all four
14
15
  * accessors set to constants. The generator's call signature requires
@@ -49,14 +50,11 @@ export declare function glyphNodeToSVG(g: {
49
50
  pointId?: string;
50
51
  _decayOpacity?: number;
51
52
  }, x: number, y: number, key: string): React.ReactNode;
52
- export declare function colorStopElements(colorStops: Array<{
53
- offset: number;
54
- color: string;
55
- }>): React.ReactElement[] | null;
53
+ export declare function colorStopElements(stops: GradientStop[], baseColor: string): React.ReactElement[] | null;
56
54
  /**
57
55
  * Build `<defs><linearGradient>` for a bar's fillGradient, mirroring the
58
56
  * tip→base direction the canvas renderer uses (inferred from roundedEdge).
59
- * Returns null when the config can't resolve (e.g. colorStops < 2), so the
57
+ * Returns null when the config has fewer than two usable stops, so the
60
58
  * caller falls back to a solid fill — same parity with the canvas path.
61
59
  *
62
60
  * Using `gradientUnits="userSpaceOnUse"` with absolute coords keeps each bar's
@@ -1,10 +1,11 @@
1
1
  import type { ReactNode } from "react";
2
2
  import type { ScaleLinear } from "d3-scale";
3
3
  import type { AnimateProp } from "./pipelineTransitionUtils";
4
- import type { LegendGroup, GradientLegendConfig, LegendLayout } from "../types/legendTypes";
4
+ import type { LegendLayout, LegendValue } from "../types/legendTypes";
5
5
  import type { ArrowOfTime, WindowMode, LineStyle, BarStyle, WaterfallStyle, SwarmStyle, HoverAnnotationConfig, HoverData, AnnotationContext, AnnotationAnchorMode } from "../realtime/types";
6
6
  import type { Datum } from "../charts/shared/datumTypes";
7
7
  import type { HatchFill } from "../charts/shared/hatchFill";
8
+ import type { ColorGradientInput, GradientConfig, GradientInput } from "../charts/shared/gradient";
8
9
  import type { CoercibleNumber } from "./accessorUtils";
9
10
  import type { AutoPlaceAnnotations } from "../recipes/annotationLayout";
10
11
  import type { SymbolName } from "./symbolPath";
@@ -147,12 +148,7 @@ export interface LineSceneNode {
147
148
  accessibility?: SceneAccessibilityMetadata["accessibility"];
148
149
  group?: string;
149
150
  /** Horizontal gradient for the line stroke */
150
- strokeGradient?: {
151
- colorStops: Array<{
152
- offset: number;
153
- color: string;
154
- }>;
155
- };
151
+ strokeGradient?: GradientConfig;
156
152
  /** Curve interpolation type (default: linear / straight segments) */
157
153
  curve?: CurveType;
158
154
  /** Per-vertex decay opacities (oldest→newest = minOpacity→1.0). Set by PipelineStore.applyDecay. */
@@ -174,6 +170,20 @@ export interface AreaSceneNode {
174
170
  type: "area";
175
171
  topPath: [number, number][];
176
172
  bottomPath: [number, number][];
173
+ /** Raw y-values corresponding to each top-path point (for threshold coloring) */
174
+ rawValues?: number[];
175
+ /** Threshold-based colors for the area's top-edge stroke */
176
+ colorThresholds?: LineColorThreshold[];
177
+ /**
178
+ * Plot-relative horizontal clips for value-colored top strokes. Each band
179
+ * redraws the complete top path, preserving its configured curve exactly.
180
+ * An omitted color means the area's normal stroke color.
181
+ */
182
+ strokeColorBands?: Array<{
183
+ y: number;
184
+ height: number;
185
+ color?: string;
186
+ }>;
177
187
  style: Style;
178
188
  datum: SeriesDatum;
179
189
  accessibleDatum?: SceneAccessibilityMetadata["accessibleDatum"];
@@ -187,23 +197,10 @@ export interface AreaSceneNode {
187
197
  width: number;
188
198
  height: number;
189
199
  };
190
- /** Gradient fill: opacity-based (topOpacity/bottomOpacity) or multi-color (colorStops) */
191
- fillGradient?: {
192
- topOpacity: number;
193
- bottomOpacity: number;
194
- } | {
195
- colorStops: Array<{
196
- offset: number;
197
- color: string;
198
- }>;
199
- };
200
+ /** Gradient fill from top edge to baseline. */
201
+ fillGradient?: GradientConfig;
200
202
  /** Horizontal gradient for the line stroke */
201
- strokeGradient?: {
202
- colorStops: Array<{
203
- offset: number;
204
- color: string;
205
- }>;
206
- };
203
+ strokeGradient?: GradientConfig;
207
204
  /** When false, skip hit testing (used for decorative bounds areas) */
208
205
  interactive?: boolean;
209
206
  /** Pulse intensity 0–1 (set when aggregated group value changes) */
@@ -384,15 +381,7 @@ export interface RectSceneNode {
384
381
  };
385
382
  /** Gradient fill — same shape as the area-scene version. Runs tip → base
386
383
  * along the bar axis (inferred from `roundedEdge`). */
387
- fillGradient?: {
388
- topOpacity: number;
389
- bottomOpacity: number;
390
- } | {
391
- colorStops: Array<{
392
- offset: number;
393
- color: string;
394
- }>;
395
- };
384
+ fillGradient?: GradientConfig;
396
385
  style: Style;
397
386
  datum: SceneDatum;
398
387
  accessibleDatum?: SceneAccessibilityMetadata["accessibleDatum"];
@@ -641,27 +630,18 @@ export interface StreamXYFrameProps<T = Datum> extends StreamSemanticInteraction
641
630
  * Use for percentile bands, confidence ribbons, or any band/ribbon chart.
642
631
  */
643
632
  y0Accessor?: string | ((d: T) => number);
633
+ /** Gradient fill for area charts. Offset 0 is the top edge; offset 1 is the baseline. */
634
+ gradientFill?: GradientInput;
635
+ /** Horizontal gradient for line strokes. Offset 0 is left; offset 1 is right. */
636
+ lineGradient?: ColorGradientInput;
644
637
  /**
645
- * Gradient fill for area charts. The fill fades from topOpacity at the line
646
- * to bottomOpacity at the baseline. Set to `true` for default (0.8 → 0.05)
647
- * or `{ topOpacity, bottomOpacity }` for custom values.
638
+ * Internal value-anchored color stops for an area's top-edge stroke.
639
+ * Offsets are resolved against the final y-domain by the scene builder.
648
640
  */
649
- gradientFill?: boolean | {
650
- topOpacity: number;
651
- bottomOpacity: number;
652
- } | {
653
- colorStops: Array<{
654
- offset: number;
655
- color: string;
656
- }>;
657
- };
658
- /** Horizontal gradient for line strokes. Applied to all lines/area top-strokes. */
659
- lineGradient?: {
660
- colorStops: Array<{
661
- offset: number;
662
- color: string;
663
- }>;
664
- };
641
+ semanticLineStops?: Array<{
642
+ offset: number;
643
+ color: string;
644
+ }>;
665
645
  /** Series names (matching lineBy/colorBy group keys) that render as filled areas in "mixed" chartType */
666
646
  areaGroups?: string[];
667
647
  /**
@@ -777,11 +757,7 @@ export interface StreamXYFrameProps<T = Datum> extends StreamSemanticInteraction
777
757
  autoPlaceAnnotations?: AutoPlaceAnnotations;
778
758
  svgAnnotationRules?: (annotation: Datum, index: number, context: AnnotationContext) => ReactNode;
779
759
  showGrid?: boolean;
780
- legend?: ReactNode | {
781
- legendGroups: LegendGroup[];
782
- } | {
783
- gradient: GradientLegendConfig;
784
- };
760
+ legend?: LegendValue;
785
761
  legendHoverBehavior?: (item: {
786
762
  label: string;
787
763
  } | null) => void;
@@ -1,20 +1,4 @@
1
- import type { AreaSceneNode } from "../types";
2
- type ResolvedAreaGradient = NonNullable<AreaSceneNode["fillGradient"]>;
3
- type OpacityGradient = {
4
- topOpacity: number;
5
- bottomOpacity: number;
6
- };
7
- type ColorStopGradient = {
8
- colorStops: Array<{
9
- offset: number;
10
- color: string;
11
- }>;
12
- };
13
- type OpacityGradientConfig = {
14
- topOpacity?: number;
15
- bottomOpacity?: number;
16
- };
17
- export type AreaGradientConfig = boolean | OpacityGradientConfig | ColorStopGradient;
18
- export declare const DEFAULT_AREA_GRADIENT: OpacityGradient;
19
- export declare function resolveAreaGradient(gradient: AreaGradientConfig | undefined): ResolvedAreaGradient | undefined;
20
- export {};
1
+ import { type GradientConfig, type GradientInput } from "../../charts/shared/gradient";
2
+ export type AreaGradientConfig = GradientInput;
3
+ export declare const DEFAULT_AREA_GRADIENT: GradientConfig;
4
+ export declare function resolveAreaGradient(gradient: AreaGradientConfig | undefined): GradientConfig | undefined;
@@ -11,6 +11,7 @@ import type { AreaGradientConfig } from "./areaGradient";
11
11
  import type { StreamScales, Style, CurveType, BarStyle, ThemeSemanticColors } from "../types";
12
12
  import type { SymbolName } from "../symbolPath";
13
13
  import type { ResolvedRibbon } from "./ribbonScene";
14
+ import type { GradientConfig } from "../../charts/shared/gradient";
14
15
  export interface XYSceneContext {
15
16
  scales: StreamScales;
16
17
  config: XYSceneConfig;
@@ -61,12 +62,11 @@ export interface XYSceneConfig {
61
62
  stackOrder?: "key" | "input" | "insideOut" | "asc" | "desc";
62
63
  gradientFill?: AreaGradientConfig;
63
64
  areaGroups?: Set<string>;
64
- lineGradient?: {
65
- colorStops: Array<{
66
- offset: number;
67
- color: string;
68
- }>;
69
- };
65
+ lineGradient?: GradientConfig;
66
+ semanticLineStops?: Array<{
67
+ offset: number;
68
+ color: string;
69
+ }>;
70
70
  annotations?: Datum[];
71
71
  pointStyle?: (d: Datum) => Style & {
72
72
  r?: number;
@@ -25,11 +25,16 @@ export interface GradientLegendConfig {
25
25
  }
26
26
  export interface CategoricalLegendConfig {
27
27
  legendGroups: LegendGroup[];
28
+ /** Gap in pixels between the legend and the plot/side gutter. Default: 10. */
29
+ legendDistance?: number;
28
30
  }
29
- /** Public legend slot accepted by stream frames and legend-aware chart HOCs. */
30
- export type LegendValue = ReactNode | CategoricalLegendConfig | {
31
+ export interface GradientLegendValue {
31
32
  gradient: GradientLegendConfig;
32
- };
33
+ /** Gap in pixels between the legend and the plot/side gutter. Default: 10. */
34
+ legendDistance?: number;
35
+ }
36
+ /** Public legend slot accepted by stream frames and legend-aware chart HOCs. */
37
+ export type LegendValue = ReactNode | CategoricalLegendConfig | GradientLegendValue;
33
38
  /**
34
39
  * Compose inferred and caller-supplied legends without discarding either
35
40
  * categorical domain. Configured groups are appended in argument order, so
@@ -41,9 +46,7 @@ export declare function composeLegendConfigs(...values: Array<LegendValue | null
41
46
  /** Type guard: categorical legend config */
42
47
  export declare function isLegendConfig(value: unknown): value is CategoricalLegendConfig;
43
48
  /** Type guard: gradient legend config */
44
- export declare function isGradientLegendConfig(value: unknown): value is {
45
- gradient: GradientLegendConfig;
46
- };
49
+ export declare function isGradientLegendConfig(value: unknown): value is GradientLegendValue;
47
50
  export interface LegendLayout {
48
51
  /** Horizontal alignment for top/bottom legends within the plot width */
49
52
  align?: "start" | "center" | "end" | "left" | "right";
@@ -57,6 +60,12 @@ export interface LegendLayout {
57
60
  rowHeight?: number;
58
61
  /** Override the alignment width used for top/bottom legends */
59
62
  maxWidth?: number;
63
+ /**
64
+ * Space between the plot and a left/right legend reserved for adjacent
65
+ * chart chrome such as axis ticks and an axis title. Ignored for top/bottom
66
+ * legends. The legend is placed outside this gutter.
67
+ */
68
+ sideGutter?: number;
60
69
  }
61
70
  export interface LegendProps {
62
71
  legendGroups?: LegendGroup[];