@opendata-ai/openchart-engine 6.0.0 → 6.1.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 (65) hide show
  1. package/dist/index.d.ts +155 -19
  2. package/dist/index.js +1513 -164
  3. package/dist/index.js.map +1 -1
  4. package/package.json +2 -2
  5. package/src/__test-fixtures__/specs.ts +6 -3
  6. package/src/__tests__/axes.test.ts +168 -4
  7. package/src/__tests__/compile-chart.test.ts +23 -12
  8. package/src/__tests__/compile-layer.test.ts +386 -0
  9. package/src/__tests__/dimensions.test.ts +6 -3
  10. package/src/__tests__/legend.test.ts +6 -3
  11. package/src/__tests__/scales.test.ts +176 -2
  12. package/src/annotations/__tests__/compute.test.ts +8 -4
  13. package/src/charts/bar/__tests__/compute.test.ts +12 -6
  14. package/src/charts/bar/compute.ts +21 -5
  15. package/src/charts/column/__tests__/compute.test.ts +14 -7
  16. package/src/charts/column/compute.ts +21 -6
  17. package/src/charts/dot/__tests__/compute.test.ts +10 -5
  18. package/src/charts/dot/compute.ts +10 -4
  19. package/src/charts/line/__tests__/compute.test.ts +102 -11
  20. package/src/charts/line/__tests__/curves.test.ts +51 -0
  21. package/src/charts/line/__tests__/labels.test.ts +2 -1
  22. package/src/charts/line/__tests__/mark-options.test.ts +175 -0
  23. package/src/charts/line/area.ts +19 -8
  24. package/src/charts/line/compute.ts +64 -25
  25. package/src/charts/line/curves.ts +40 -0
  26. package/src/charts/pie/__tests__/compute.test.ts +10 -5
  27. package/src/charts/pie/compute.ts +2 -1
  28. package/src/charts/rule/index.ts +127 -0
  29. package/src/charts/scatter/__tests__/compute.test.ts +10 -5
  30. package/src/charts/scatter/compute.ts +15 -5
  31. package/src/charts/text/index.ts +92 -0
  32. package/src/charts/tick/index.ts +84 -0
  33. package/src/charts/utils.ts +1 -1
  34. package/src/compile.ts +175 -23
  35. package/src/compiler/__tests__/compile.test.ts +4 -4
  36. package/src/compiler/__tests__/normalize.test.ts +4 -4
  37. package/src/compiler/__tests__/validate.test.ts +25 -26
  38. package/src/compiler/index.ts +1 -1
  39. package/src/compiler/normalize.ts +77 -4
  40. package/src/compiler/types.ts +6 -2
  41. package/src/compiler/validate.ts +167 -35
  42. package/src/graphs/__tests__/compile-graph.test.ts +2 -2
  43. package/src/graphs/compile-graph.ts +2 -2
  44. package/src/index.ts +17 -1
  45. package/src/layout/axes.ts +122 -20
  46. package/src/layout/dimensions.ts +15 -9
  47. package/src/layout/scales.ts +320 -31
  48. package/src/legend/compute.ts +9 -6
  49. package/src/tables/__tests__/compile-table.test.ts +1 -1
  50. package/src/tooltips/__tests__/compute.test.ts +10 -5
  51. package/src/tooltips/compute.ts +32 -14
  52. package/src/transforms/__tests__/bin.test.ts +88 -0
  53. package/src/transforms/__tests__/calculate.test.ts +146 -0
  54. package/src/transforms/__tests__/conditional.test.ts +109 -0
  55. package/src/transforms/__tests__/filter.test.ts +59 -0
  56. package/src/transforms/__tests__/index.test.ts +93 -0
  57. package/src/transforms/__tests__/predicates.test.ts +176 -0
  58. package/src/transforms/__tests__/timeunit.test.ts +129 -0
  59. package/src/transforms/bin.ts +87 -0
  60. package/src/transforms/calculate.ts +60 -0
  61. package/src/transforms/conditional.ts +46 -0
  62. package/src/transforms/filter.ts +17 -0
  63. package/src/transforms/index.ts +48 -0
  64. package/src/transforms/predicates.ts +90 -0
  65. package/src/transforms/timeunit.ts +88 -0
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as _opendata_ai_openchart_core from '@opendata-ai/openchart-core';
2
- import { LegendLayout, ResolvedChrome, TooltipContent, A11yMetadata, ResolvedTheme, CompileOptions, ChartLayout, CompileTableOptions, TableLayout, ChartType, DataRow, Encoding, ChromeText, Annotation, LabelConfig, LegendConfig, ThemeConfig, DarkMode, ColumnConfig, GraphSpec, GraphEncoding, GraphLayoutConfig, NodeOverride, VizSpec, EncodingChannel, Rect, LayoutStrategy, Mark } from '@opendata-ai/openchart-core';
3
- export { ChartLayout, ChartSpec, CompileOptions, CompileTableOptions, GraphLayout, GraphSpec, TableLayout, TableSpec, VizSpec } from '@opendata-ai/openchart-core';
4
- import { ScaleLinear, ScaleTime, ScaleLogarithmic, ScaleBand, ScalePoint, ScaleOrdinal } from 'd3-scale';
2
+ import { LegendLayout, ResolvedChrome, TooltipContent, A11yMetadata, ResolvedTheme, CompileOptions, ChartLayout, LayerSpec, CompileTableOptions, TableLayout, MarkType, MarkDef, DataRow, Encoding, ChromeText, Annotation, LabelConfig, LegendConfig, ThemeConfig, DarkMode, ColumnConfig, GraphSpec, GraphEncoding, GraphLayoutConfig, NodeOverride, VizSpec, ScaleType, EncodingChannel, Rect, LayoutStrategy, Mark, BinTransform, CalculateTransform, ConditionalValueDef, FilterPredicate, TimeUnitTransform, Transform } from '@opendata-ai/openchart-core';
3
+ export { ChartLayout, ChartSpec, CompileOptions, CompileTableOptions, GraphLayout, GraphSpec, LayerSpec, TableLayout, TableSpec, VizSpec } from '@opendata-ai/openchart-core';
4
+ import { ScaleLinear, ScaleTime, ScaleLogarithmic, ScalePower, ScaleSymLog, ScaleBand, ScalePoint, ScaleOrdinal, ScaleQuantile, ScaleQuantize, ScaleThreshold } from 'd3-scale';
5
5
 
6
6
  /**
7
7
  * Graph compilation types.
@@ -129,6 +129,18 @@ interface GraphCompilation {
129
129
  * @throws Error if spec is invalid or not a chart type.
130
130
  */
131
131
  declare function compileChart(spec: unknown, options: CompileOptions): ChartLayout;
132
+ /**
133
+ * Compile a LayerSpec into a single ChartLayout.
134
+ *
135
+ * Flattens nested layers, merges inherited data/encoding/transforms,
136
+ * compiles each leaf layer independently, unions scale domains (shared
137
+ * by default), and concatenates marks in layer order.
138
+ *
139
+ * @param spec - A LayerSpec with child layers.
140
+ * @param options - Compile options (width, height, theme, darkMode).
141
+ * @returns A single ChartLayout with combined marks from all layers.
142
+ */
143
+ declare function compileLayer(spec: LayerSpec, options: CompileOptions): ChartLayout;
132
144
  /**
133
145
  * Compile a table spec into a TableLayout.
134
146
  *
@@ -166,7 +178,10 @@ interface NormalizedChrome {
166
178
  }
167
179
  /** A ChartSpec with all optional fields filled with sensible defaults. */
168
180
  interface NormalizedChartSpec {
169
- type: ChartType;
181
+ /** Resolved mark type string (extracted from spec.mark). */
182
+ markType: MarkType;
183
+ /** Resolved mark definition with defaults filled in. */
184
+ markDef: MarkDef;
170
185
  data: DataRow[];
171
186
  encoding: Encoding;
172
187
  chrome: NormalizedChrome;
@@ -245,16 +260,6 @@ interface CompileResult {
245
260
  warnings: string[];
246
261
  }
247
262
 
248
- /**
249
- * Spec normalization: fill in defaults and infer types.
250
- *
251
- * Takes a validated VizSpec and produces a NormalizedSpec where:
252
- * - All optional fields have sensible defaults
253
- * - Chrome strings are converted to ChromeText objects
254
- * - Encoding types are inferred from data if not specified
255
- * - Annotations have default styles
256
- */
257
-
258
263
  /**
259
264
  * Normalize a validated VizSpec, filling in all defaults.
260
265
  *
@@ -309,12 +314,16 @@ declare function compile(spec: unknown): CompileResult;
309
314
  * nominal/ordinal -> scaleBand() or scaleOrdinal(), depending on context.
310
315
  */
311
316
 
312
- /** Continuous D3 scales (linear, time, log) that support .ticks() and .nice(). */
313
- type D3ContinuousScale = ScaleLinear<number, number> | ScaleTime<number, number> | ScaleLogarithmic<number, number>;
317
+ /** Continuous D3 scales (linear, time, log, pow, sqrt, symlog) that support .ticks() and .nice(). */
318
+ type D3ContinuousScale = ScaleLinear<number, number> | ScaleTime<number, number> | ScaleLogarithmic<number, number> | ScalePower<number, number> | ScaleSymLog<number, number>;
319
+ /** Discretizing D3 scales (quantile, quantize, threshold). */
320
+ type D3DiscretizingScale = ScaleQuantile<number> | ScaleQuantize<number> | ScaleThreshold<number, number>;
314
321
  /** Categorical D3 scales (band, point, ordinal) that support .domain() as string[]. */
315
322
  type D3CategoricalScale = ScaleBand<string> | ScalePoint<string> | ScaleOrdinal<string, string>;
316
323
  /** Union of all D3 scale types used by the engine. */
317
- type D3Scale = D3ContinuousScale | D3CategoricalScale;
324
+ type D3Scale = D3ContinuousScale | D3CategoricalScale | D3DiscretizingScale;
325
+ /** All resolved scale type identifiers. */
326
+ type ResolvedScaleType = ScaleType | 'sequential';
318
327
  /**
319
328
  * A resolved scale wrapping a d3 scale with type metadata.
320
329
  * We need to carry the scale type around so axes and marks know
@@ -325,7 +334,7 @@ interface ResolvedScale {
325
334
  /** The d3 scale function. Maps domain value -> pixel position or color. */
326
335
  scale: D3Scale;
327
336
  /** The scale type for downstream use. */
328
- type: 'linear' | 'time' | 'band' | 'ordinal' | 'point' | 'log' | 'sequential';
337
+ type: ResolvedScaleType;
329
338
  /** The encoding channel this scale was derived from. */
330
339
  channel: EncodingChannel;
331
340
  }
@@ -374,4 +383,131 @@ declare function getChartRenderer(type: string): ChartRenderer | undefined;
374
383
  */
375
384
  declare function clearRenderers(): void;
376
385
 
377
- export { type ChartRenderer, type CompileResult, type CompiledGraphEdge, type CompiledGraphNode, type GraphCompilation, type NormalizedChartSpec, type NormalizedChrome, type NormalizedGraphSpec, type NormalizedSpec, type NormalizedTableSpec, type SimulationConfig, type ValidationError, type ValidationErrorCode, type ValidationResult, clearRenderers, compile, compileChart, compileGraph, compileTable, getChartRenderer, normalizeSpec, registerChartRenderer, validateSpec };
386
+ /**
387
+ * Bin transform: discretizes a continuous field into bins.
388
+ *
389
+ * Adds bin start (and optionally bin end) fields to each row.
390
+ */
391
+
392
+ /**
393
+ * Apply a bin transform to data rows.
394
+ *
395
+ * Adds one or two fields to each row:
396
+ * - If `as` is a string: adds `as` with the bin start value.
397
+ * - If `as` is [start, end]: adds both bin start and bin end fields.
398
+ *
399
+ * @param data - Input rows.
400
+ * @param transform - Bin transform definition.
401
+ * @returns New rows with binned field(s) added.
402
+ */
403
+ declare function runBin(data: DataRow[], transform: BinTransform): DataRow[];
404
+
405
+ /**
406
+ * Calculate transform: adds a computed field to each row.
407
+ *
408
+ * Supports arithmetic operations on fields and constant values.
409
+ */
410
+
411
+ /**
412
+ * Apply a calculate transform to data rows.
413
+ *
414
+ * Adds a new field with the computed value to each row.
415
+ *
416
+ * @param data - Input rows.
417
+ * @param transform - Calculate transform definition.
418
+ * @returns New rows with the calculated field added.
419
+ */
420
+ declare function runCalculate(data: DataRow[], transform: CalculateTransform): DataRow[];
421
+
422
+ /**
423
+ * Conditional encoding evaluation.
424
+ *
425
+ * Resolves conditional value definitions per-datum by evaluating
426
+ * predicates and returning the first matching condition's value.
427
+ */
428
+
429
+ /**
430
+ * Resolve a conditional value definition for a datum.
431
+ *
432
+ * Evaluates conditions in order, returning the value from the first
433
+ * condition whose test passes. Falls back to the default value if
434
+ * no condition matches.
435
+ *
436
+ * @param datum - The data row to evaluate against.
437
+ * @param channelDef - The conditional value definition.
438
+ * @returns The resolved value, or undefined if no condition matches and no default.
439
+ */
440
+ declare function resolveConditionalValue(datum: DataRow, channelDef: ConditionalValueDef): unknown;
441
+ /**
442
+ * Check if a channel definition is a ConditionalValueDef.
443
+ */
444
+ declare function isConditionalValueDef(def: unknown): def is ConditionalValueDef;
445
+
446
+ /**
447
+ * Filter transform: removes rows that don't match a predicate.
448
+ */
449
+
450
+ /**
451
+ * Filter data rows by a predicate.
452
+ *
453
+ * @param data - Input rows.
454
+ * @param predicate - Filter predicate to evaluate per row.
455
+ * @returns Rows that pass the predicate.
456
+ */
457
+ declare function runFilter(data: DataRow[], predicate: FilterPredicate): DataRow[];
458
+
459
+ /**
460
+ * Predicate evaluation for filter transforms and conditional encoding.
461
+ *
462
+ * Supports field predicates (equal, lt, gt, range, oneOf, valid)
463
+ * and logical combinators (and, or, not).
464
+ */
465
+
466
+ /**
467
+ * Evaluate a filter predicate (field predicate or logical combinator) against a datum.
468
+ *
469
+ * @param datum - The data row to test.
470
+ * @param predicate - The filter predicate to evaluate.
471
+ * @returns Whether the datum passes the predicate.
472
+ */
473
+ declare function evaluatePredicate(datum: DataRow, predicate: FilterPredicate): boolean;
474
+
475
+ /**
476
+ * Time unit transform: extracts temporal components from date fields.
477
+ *
478
+ * Follows Vega-Lite time unit conventions.
479
+ */
480
+
481
+ /**
482
+ * Apply a time unit transform to data rows.
483
+ *
484
+ * Parses the field as a date and extracts the specified time unit,
485
+ * storing the result in a new field.
486
+ *
487
+ * @param data - Input rows.
488
+ * @param transform - Time unit transform definition.
489
+ * @returns New rows with the time unit field added.
490
+ */
491
+ declare function runTimeUnit(data: DataRow[], transform: TimeUnitTransform): DataRow[];
492
+
493
+ /**
494
+ * Data transform pipeline.
495
+ *
496
+ * Runs an ordered sequence of transforms (filter, bin, calculate, timeUnit)
497
+ * against a data array. Each transform produces a new array, feeding into
498
+ * the next transform in sequence.
499
+ */
500
+
501
+ /**
502
+ * Run a sequence of transforms against a data array.
503
+ *
504
+ * Each transform is applied in order, producing a new data array
505
+ * that feeds into the next transform. The original data is not mutated.
506
+ *
507
+ * @param data - Input data rows.
508
+ * @param transforms - Ordered array of transform definitions.
509
+ * @returns Transformed data rows.
510
+ */
511
+ declare function runTransforms(data: DataRow[], transforms: Transform[]): DataRow[];
512
+
513
+ export { type ChartRenderer, type CompileResult, type CompiledGraphEdge, type CompiledGraphNode, type GraphCompilation, type NormalizedChartSpec, type NormalizedChrome, type NormalizedGraphSpec, type NormalizedSpec, type NormalizedTableSpec, type SimulationConfig, type ValidationError, type ValidationErrorCode, type ValidationResult, clearRenderers, compile, compileChart, compileGraph, compileLayer, compileTable, evaluatePredicate, getChartRenderer, isConditionalValueDef, normalizeSpec, registerChartRenderer, resolveConditionalValue, runBin, runCalculate, runFilter, runTimeUnit, runTransforms, validateSpec };