@opendata-ai/openchart-engine 7.2.4 → 7.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/index.d.ts +88 -39
  2. package/dist/index.js +4134 -2930
  3. package/dist/index.js.map +1 -1
  4. package/package.json +2 -2
  5. package/src/__tests__/__snapshots__/compile-snapshot.test.ts.snap +143 -78
  6. package/src/__tests__/axes.test.ts +129 -1
  7. package/src/__tests__/compile-chart.test.ts +6 -0
  8. package/src/__tests__/compile-layer.test.ts +49 -0
  9. package/src/__tests__/dimensions.test.ts +70 -2
  10. package/src/__tests__/helpers/invariants.ts +265 -0
  11. package/src/__tests__/known-bugs.test.ts +113 -0
  12. package/src/__tests__/layout-fuzz.test.ts +358 -0
  13. package/src/__tests__/layout-invariants.test.ts +535 -0
  14. package/src/__tests__/legend.test.ts +37 -0
  15. package/src/annotations/__tests__/compute.test.ts +8 -15
  16. package/src/annotations/__tests__/placement-fuzz.test.ts +256 -0
  17. package/src/annotations/__tests__/placement-invariants.test.ts +345 -0
  18. package/src/annotations/__tests__/placement.test.ts +316 -0
  19. package/src/annotations/collisions.ts +19 -7
  20. package/src/annotations/compute.ts +257 -16
  21. package/src/annotations/geometry.ts +73 -15
  22. package/src/annotations/placement.ts +588 -0
  23. package/src/annotations/resolve-text.ts +58 -10
  24. package/src/charts/__tests__/post-process.test.ts +3 -3
  25. package/src/charts/bar/__tests__/compute.test.ts +131 -45
  26. package/src/charts/bar/compute.ts +44 -4
  27. package/src/charts/bar/index.ts +9 -2
  28. package/src/charts/bar/labels.ts +77 -26
  29. package/src/charts/column/labels.ts +29 -16
  30. package/src/charts/post-process.ts +21 -7
  31. package/src/charts/registry.ts +4 -2
  32. package/src/compile/layer.ts +31 -9
  33. package/src/compile.ts +88 -149
  34. package/src/index.ts +9 -0
  35. package/src/layout/axes/rotation.ts +36 -0
  36. package/src/layout/axes.ts +130 -8
  37. package/src/layout/dimensions.ts +80 -98
  38. package/src/layout/plan.ts +550 -0
  39. package/src/layout/scales.ts +22 -0
  40. package/src/layout/shared.ts +44 -0
  41. package/src/legend/compute.ts +315 -78
  42. package/src/legend/wrap.ts +11 -7
  43. package/src/sankey/__tests__/node-label-wrap.test.ts +2 -2
  44. package/src/tables/__tests__/heatmap.test.ts +24 -20
  45. package/src/tables/heatmap.ts +25 -9
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _opendata_ai_openchart_core from '@opendata-ai/openchart-core';
2
- import { LegendLayout, ResolvedChrome, TooltipContent, A11yMetadata, ResolvedTheme, CompileOptions, ChartLayout, LayerSpec, CompileTableOptions, TableLayout, AnimationSpec, ResolvedAnimation, DataRow, BarListEncoding, ThemeConfig, DarkMode, TileMapEncoding, TileMapPalette, LegendConfig, MarkType, MarkDef, Encoding, ChromeText, Annotation, LabelConfig, Display, ColumnConfig, GraphSpec, GraphEncoding, GraphLayoutConfig, NodeOverride, SankeyEncoding, SankeyNodeAlign, SankeyLinkColor, VizSpec, ScaleType, EncodingChannel, Rect, LayoutStrategy, Mark, BinTransform, CalculateTransform, ConditionalValueDef, FilterPredicate, TimeUnitTransform, Transform } from '@opendata-ai/openchart-core';
2
+ import { LegendLayout, ResolvedChrome, TooltipContent, A11yMetadata, ResolvedTheme, CompileOptions, ChartLayout, LayerSpec, CompileTableOptions, TableLayout, AnimationSpec, ResolvedAnimation, DataRow, BarListEncoding, ThemeConfig, DarkMode, TileMapEncoding, TileMapPalette, LegendConfig, MarkType, MarkDef, Encoding, ChromeText, Annotation, LabelConfig, Display, ColumnConfig, GraphSpec, GraphEncoding, GraphLayoutConfig, NodeOverride, SankeyEncoding, SankeyNodeAlign, SankeyLinkColor, ScaleType, EncodingChannel, Rect, LayoutStrategy, VizSpec, Mark, BinTransform, CalculateTransform, ConditionalValueDef, FilterPredicate, TimeUnitTransform, Transform } from '@opendata-ai/openchart-core';
3
3
  export { BarListLayout, BarListSpec, ChartLayout, ChartSpec, CompileOptions, CompileTableOptions, GraphLayout, GraphSpec, LayerSpec, SankeyLayout, SankeySpec, TableLayout, TableSpec, TileMapLayout, TileMapSpec, VizSpec } from '@opendata-ai/openchart-core';
4
4
  import { ScaleLinear, ScaleTime, ScaleLogarithmic, ScalePower, ScaleSymLog, ScaleBand, ScalePoint, ScaleOrdinal, ScaleQuantile, ScaleQuantize, ScaleThreshold } from 'd3-scale';
5
5
 
@@ -416,6 +416,88 @@ interface NormalizedSankeySpec {
416
416
  linkOpacity?: number;
417
417
  }
418
418
 
419
+ /** Continuous D3 scales (linear, time, log, pow, sqrt, symlog) that support .ticks() and .nice(). */
420
+ type D3ContinuousScale = ScaleLinear<number, number> | ScaleTime<number, number> | ScaleLogarithmic<number, number> | ScalePower<number, number> | ScaleSymLog<number, number>;
421
+ /** Discretizing D3 scales (quantile, quantize, threshold). */
422
+ type D3DiscretizingScale = ScaleQuantile<number> | ScaleQuantize<number> | ScaleThreshold<number, number>;
423
+ /** Categorical D3 scales (band, point, ordinal) that support .domain() as string[]. */
424
+ type D3CategoricalScale = ScaleBand<string> | ScalePoint<string> | ScaleOrdinal<string, string>;
425
+ /** Union of all D3 scale types used by the engine. */
426
+ type D3Scale = D3ContinuousScale | D3CategoricalScale | D3DiscretizingScale;
427
+ /** All resolved scale type identifiers. */
428
+ type ResolvedScaleType = ScaleType | 'sequential';
429
+ /**
430
+ * A resolved scale wrapping a d3 scale with type metadata.
431
+ * We need to carry the scale type around so axes and marks know
432
+ * how to interpret the domain/range. Consumers use the `type` discriminant
433
+ * to determine which D3 methods are available on the scale.
434
+ */
435
+ interface ResolvedScale {
436
+ /** The d3 scale function. Maps domain value -> pixel position or color. */
437
+ scale: D3Scale;
438
+ /** The scale type for downstream use. */
439
+ type: ResolvedScaleType;
440
+ /** The encoding channel this scale was derived from. */
441
+ channel: EncodingChannel;
442
+ }
443
+ /** All resolved scales for a chart. */
444
+ interface ResolvedScales {
445
+ x?: ResolvedScale;
446
+ y?: ResolvedScale;
447
+ color?: ResolvedScale;
448
+ size?: ResolvedScale;
449
+ /** Default color for single-series charts (first categorical palette color or markDef.fill gradient). */
450
+ defaultColor?: string | _opendata_ai_openchart_core.GradientDef;
451
+ }
452
+
453
+ /**
454
+ * Geometry utilities for annotation text bounds, connector origins, and offsets.
455
+ */
456
+
457
+ type AnnotationMeasureTextFn = (text: string, font: {
458
+ fontSize: number;
459
+ fontWeight: number;
460
+ fontFamily?: string;
461
+ }) => number;
462
+ declare const heuristicMeasure: AnnotationMeasureTextFn;
463
+
464
+ /**
465
+ * Annotation placement engine: typed obstacles, candidate generation,
466
+ * scored search, and two-pass deterministic placement.
467
+ */
468
+
469
+ type ObstacleKind = 'mark' | 'line' | 'area-fill' | 'legend' | 'data-label' | 'endpoint-label' | 'watermark' | 'axis-band' | 'annotation';
470
+ interface PlacementObstacle extends Rect {
471
+ kind: ObstacleKind;
472
+ }
473
+
474
+ /**
475
+ * Annotation computation: converts spec-level annotations to pixel-positioned
476
+ * ResolvedAnnotation objects using the resolved scales.
477
+ *
478
+ * Handles three annotation types:
479
+ * - text: positioned at a data coordinate with an optional callout
480
+ * - range: a highlighted rectangle between two data values
481
+ * - refline: a horizontal or vertical reference line at a data value
482
+ *
483
+ * Supports fine-grained positioning via offset, anchor, connector, and zIndex.
484
+ * At compact breakpoints, annotations are simplified or hidden.
485
+ */
486
+
487
+ interface AnnotationContext {
488
+ scales: ResolvedScales;
489
+ chartArea: Rect;
490
+ strategy: LayoutStrategy;
491
+ isDark: boolean;
492
+ obstacles: PlacementObstacle[];
493
+ svg: {
494
+ width: number;
495
+ height: number;
496
+ };
497
+ measure: AnnotationMeasureTextFn;
498
+ debugPlacement?: boolean;
499
+ }
500
+
419
501
  /**
420
502
  * Normalize a validated VizSpec, filling in all defaults.
421
503
  *
@@ -462,40 +544,6 @@ declare function validateSpec(spec: unknown): ValidationResult;
462
544
  */
463
545
  declare function compile(spec: unknown): CompileResult;
464
546
 
465
- /** Continuous D3 scales (linear, time, log, pow, sqrt, symlog) that support .ticks() and .nice(). */
466
- type D3ContinuousScale = ScaleLinear<number, number> | ScaleTime<number, number> | ScaleLogarithmic<number, number> | ScalePower<number, number> | ScaleSymLog<number, number>;
467
- /** Discretizing D3 scales (quantile, quantize, threshold). */
468
- type D3DiscretizingScale = ScaleQuantile<number> | ScaleQuantize<number> | ScaleThreshold<number, number>;
469
- /** Categorical D3 scales (band, point, ordinal) that support .domain() as string[]. */
470
- type D3CategoricalScale = ScaleBand<string> | ScalePoint<string> | ScaleOrdinal<string, string>;
471
- /** Union of all D3 scale types used by the engine. */
472
- type D3Scale = D3ContinuousScale | D3CategoricalScale | D3DiscretizingScale;
473
- /** All resolved scale type identifiers. */
474
- type ResolvedScaleType = ScaleType | 'sequential';
475
- /**
476
- * A resolved scale wrapping a d3 scale with type metadata.
477
- * We need to carry the scale type around so axes and marks know
478
- * how to interpret the domain/range. Consumers use the `type` discriminant
479
- * to determine which D3 methods are available on the scale.
480
- */
481
- interface ResolvedScale {
482
- /** The d3 scale function. Maps domain value -> pixel position or color. */
483
- scale: D3Scale;
484
- /** The scale type for downstream use. */
485
- type: ResolvedScaleType;
486
- /** The encoding channel this scale was derived from. */
487
- channel: EncodingChannel;
488
- }
489
- /** All resolved scales for a chart. */
490
- interface ResolvedScales {
491
- x?: ResolvedScale;
492
- y?: ResolvedScale;
493
- color?: ResolvedScale;
494
- size?: ResolvedScale;
495
- /** Default color for single-series charts (first categorical palette color or markDef.fill gradient). */
496
- defaultColor?: string | _opendata_ai_openchart_core.GradientDef;
497
- }
498
-
499
547
  /**
500
548
  * Chart renderer registry.
501
549
  *
@@ -508,10 +556,11 @@ interface ResolvedScales {
508
556
  * A chart renderer function.
509
557
  *
510
558
  * Takes a normalized spec, resolved scales, chart area, layout strategy,
511
- * and the resolved theme for theme-aware styling (e.g. label colors).
512
- * Returns an array of marks to render.
559
+ * the resolved theme for theme-aware styling (e.g. label colors), and the
560
+ * full container width (used by geometry gates that must key off the
561
+ * container, not the derived plot width). Returns an array of marks to render.
513
562
  */
514
- type ChartRenderer = (spec: NormalizedChartSpec, scales: ResolvedScales, chartArea: Rect, strategy: LayoutStrategy, theme: ResolvedTheme) => Mark[];
563
+ type ChartRenderer = (spec: NormalizedChartSpec, scales: ResolvedScales, chartArea: Rect, strategy: LayoutStrategy, theme: ResolvedTheme, containerWidth: number) => Mark[];
515
564
  /**
516
565
  * Register a chart renderer for a specific chart type.
517
566
  *
@@ -671,4 +720,4 @@ declare function runTimeUnit(data: DataRow[], transform: TimeUnitTransform): Dat
671
720
  */
672
721
  declare function runTransforms(data: DataRow[], transforms: Transform[]): DataRow[];
673
722
 
674
- export { type ChartRenderer, type CompileResult, type CompiledGraphEdge, type CompiledGraphNode, type GraphCompilation, type NormalizedBarListSpec, type NormalizedChartSpec, type NormalizedChrome, type NormalizedGraphSpec, type NormalizedSankeySpec, type NormalizedSpec, type NormalizedTableSpec, type NormalizedTileMapSpec, type SimulationConfig, type ValidationError, type ValidationErrorCode, type ValidationResult, clampStaggerDelay, clearRenderers, compile, compileBarList, compileChart, compileGraph, compileLayer, compileSankey, compileTable, compileTileMap, evaluatePredicate, getChartRenderer, isConditionalValueDef, normalizeSpec, registerChartRenderer, resolveAnimation, resolveConditionalValue, runBin, runCalculate, runFilter, runTimeUnit, runTransforms, validateSpec };
723
+ export { type AnnotationContext, type AnnotationMeasureTextFn, type ChartRenderer, type CompileResult, type CompiledGraphEdge, type CompiledGraphNode, type GraphCompilation, type NormalizedBarListSpec, type NormalizedChartSpec, type NormalizedChrome, type NormalizedGraphSpec, type NormalizedSankeySpec, type NormalizedSpec, type NormalizedTableSpec, type NormalizedTileMapSpec, type ObstacleKind, type PlacementObstacle, type SimulationConfig, type ValidationError, type ValidationErrorCode, type ValidationResult, clampStaggerDelay, clearRenderers, compile, compileBarList, compileChart, compileGraph, compileLayer, compileSankey, compileTable, compileTileMap, evaluatePredicate, getChartRenderer, heuristicMeasure, isConditionalValueDef, normalizeSpec, registerChartRenderer, resolveAnimation, resolveConditionalValue, runBin, runCalculate, runFilter, runTimeUnit, runTransforms, validateSpec };