@opendata-ai/openchart-engine 8.0.0-rc.23 → 8.0.0-rc.25

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.
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as _opendata_ai_openchart_core from '@opendata-ai/openchart-core';
2
- import { AnimationEase, LegendLayout, ResolvedChrome, TooltipContent, A11yMetadata, ResolvedTheme, LegendEntry, CompileOptions, ChartLayout, LayerSpec, CompileTableOptions, TableLayout, ResolvedAnimationPhase, AnimationSpec, ResolvedAnimation, Point, DataRow, BarListEncoding, ThemeConfig, DarkMode, MapGeo, MapEncoding, LegendConfig, MapPointsLayer, TileMapEncoding, TileMapPalette, MarkType, MarkDef, Encoding, ChromeText, Annotation, LabelConfig, Display, ColumnConfig, GraphSpec, GraphEncoding, GraphLayoutConfig, NodeOverride, GraphAnimationSpec, GraphInteractionConfig, SankeyEncoding, SankeyNodeAlign, SankeyLinkColor, ScaleType, EncodingChannel, FieldFormatContext, Rect, LayoutStrategy, VizSpec, Mark, BinTransform, CalculateTransform, ConditionalValueDef, FilterPredicate, TimeUnitTransform, Transform } from '@opendata-ai/openchart-core';
3
- export { BarListLayout, BarListSpec, ChartLayout, ChartSpec, CompileOptions, CompileTableOptions, GraphLayout, GraphSpec, LayerSpec, MapLayout, MapSpec, SankeyLayout, SankeySpec, TableLayout, TableSpec, TileMapLayout, TileMapSpec, VizSpec } from '@opendata-ai/openchart-core';
2
+ import { AnimationEase, LegendLayout, ResolvedChrome, TooltipContent, A11yMetadata, ResolvedTheme, LegendEntry, CompileOptions, ChartLayout, LayerSpec, CompileTableOptions, TableLayout, ResolvedAnimationPhase, AnimationSpec, ResolvedAnimation, Point, DataRow, BarListEncoding, ThemeConfig, DarkMode, GeoMapGeo, GeoMapEncoding, LegendConfig, GeoMapPointsLayer, TileMapEncoding, TileMapPalette, MarkType, MarkDef, Encoding, ChromeText, Annotation, LabelConfig, Display, ColumnConfig, GraphSpec, GraphEncoding, GraphLayoutConfig, NodeOverride, GraphAnimationSpec, GraphInteractionConfig, SankeyEncoding, SankeyNodeAlign, SankeyLinkColor, ScaleType, EncodingChannel, FieldFormatContext, Rect, LayoutStrategy, VizSpec, Mark, BinTransform, CalculateTransform, ConditionalValueDef, FilterPredicate, TimeUnitTransform, Transform } from '@opendata-ai/openchart-core';
3
+ export { BarListLayout, BarListSpec, ChartLayout, ChartSpec, CompileOptions, CompileTableOptions, GeoMapLayout, GeoMapSpec, 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
 
6
6
  /**
@@ -272,18 +272,18 @@ declare function compileSankey(spec: unknown, options: CompileOptions): _opendat
272
272
  */
273
273
  declare function compileTileMap(spec: unknown, options: CompileOptions): _opendata_ai_openchart_core.TileMapLayout;
274
274
  /**
275
- * Compile a map spec into a MapLayout.
275
+ * Compile a map spec into a GeoMapLayout.
276
276
  *
277
277
  * Takes a raw map spec, validates, normalizes, resolves theme and chrome,
278
278
  * projects geo features, joins data, builds feature marks with color fills,
279
- * and returns a MapLayout ready for rendering.
279
+ * and returns a GeoMapLayout ready for rendering.
280
280
  *
281
281
  * @param spec - Raw map spec (validated and normalized internally).
282
282
  * @param options - Compile options (width, height, theme, darkMode).
283
- * @returns MapLayout with computed positions and visual properties.
283
+ * @returns GeoMapLayout with computed positions and visual properties.
284
284
  * @throws Error if spec is invalid or not a map type.
285
285
  */
286
- declare function compileMap(spec: unknown, options: CompileOptions): _opendata_ai_openchart_core.MapLayout;
286
+ declare function compileGeoMap(spec: unknown, options: CompileOptions): _opendata_ai_openchart_core.GeoMapLayout;
287
287
  /**
288
288
  * Compile a barlist spec into a BarListLayout.
289
289
  *
@@ -413,11 +413,11 @@ interface NormalizedBarListSpec {
413
413
  valueFormat?: string;
414
414
  }
415
415
 
416
- interface NormalizedMapSpec {
416
+ interface NormalizedGeoMapSpec {
417
417
  type: 'map';
418
- geo: Required<MapGeo>;
418
+ geo: Required<GeoMapGeo>;
419
419
  data: Record<string, unknown>[];
420
- encoding: MapEncoding;
420
+ encoding: GeoMapEncoding;
421
421
  chrome: NormalizedChrome;
422
422
  legend?: LegendConfig;
423
423
  theme: ThemeConfig;
@@ -425,7 +425,7 @@ interface NormalizedMapSpec {
425
425
  watermark: boolean;
426
426
  animation?: AnimationSpec;
427
427
  valueFormat?: string;
428
- points?: MapPointsLayer;
428
+ points?: GeoMapPointsLayer;
429
429
  }
430
430
 
431
431
  /**
@@ -593,7 +593,7 @@ interface NormalizedGraphSpec {
593
593
  };
594
594
  }
595
595
  /** Discriminated union of all normalized spec types. */
596
- type NormalizedSpec = NormalizedChartSpec | NormalizedTableSpec | NormalizedGraphSpec | NormalizedSankeySpec | NormalizedTileMapSpec | NormalizedMapSpec | NormalizedBarListSpec;
596
+ type NormalizedSpec = NormalizedChartSpec | NormalizedTableSpec | NormalizedGraphSpec | NormalizedSankeySpec | NormalizedTileMapSpec | NormalizedGeoMapSpec | NormalizedBarListSpec;
597
597
  /** Machine-readable error code for programmatic handling. */
598
598
  type ValidationErrorCode = 'MISSING_FIELD' | 'INVALID_TYPE' | 'INVALID_VALUE' | 'ENCODING_MISMATCH' | 'DATA_FIELD_MISSING' | 'EMPTY_DATA';
599
599
  /** A single validation error with context. */
@@ -1058,4 +1058,4 @@ declare function runTimeUnit(data: DataRow[], transform: TimeUnitTransform): Dat
1058
1058
  */
1059
1059
  declare function runTransforms(data: DataRow[], transforms: Transform[]): DataRow[];
1060
1060
 
1061
- export { ARROWHEAD_LENGTH, type AnnotationContext, type AnnotationMeasureTextFn, type ArrowheadPoints, BOLD_SPAN_FONT_WEIGHT, type ChartRenderer, type CompileResult, type CompiledGraphEdge, type CompiledGraphNode, DEFAULT_ANNOTATION_FONT_SIZE, DEFAULT_LINE_HEIGHT, ENTER_DEFAULTS, EXIT_DEFAULTS, type GraphCompilation, type NormalizedBarListSpec, type NormalizedChartSpec, type NormalizedChrome, type NormalizedGraphSpec, type NormalizedMapSpec, type NormalizedSankeySpec, type NormalizedSpec, type NormalizedTableSpec, type NormalizedTileMapSpec, type ObstacleKind, type PlacementObstacle, type RichSpan, type SimulationConfig, UPDATE_DEFAULTS, type ValidationError, type ValidationErrorCode, type ValidationResult, buildAreaPath, buildEdgeTooltip, buildLinePath, clampStaggerDelay, clearRenderers, compile, compileBarList, compileChart, compileGraph, compileLayer, compileMap, compileSankey, compileTable, compileTileMap, computeArrowheadPoints, dedupeKeys, evaluatePredicate, facetMinHeight, getChartRenderer, heuristicMeasure, isConditionalValueDef, legendGap, normalizeSpec, parseAnnotationSpans, registerChartRenderer, resolveAnimation, resolveConditionalValue, runBin, runCalculate, runFilter, runTimeUnit, runTransforms, serializeKeyValue, validateSpec };
1061
+ export { ARROWHEAD_LENGTH, type AnnotationContext, type AnnotationMeasureTextFn, type ArrowheadPoints, BOLD_SPAN_FONT_WEIGHT, type ChartRenderer, type CompileResult, type CompiledGraphEdge, type CompiledGraphNode, DEFAULT_ANNOTATION_FONT_SIZE, DEFAULT_LINE_HEIGHT, ENTER_DEFAULTS, EXIT_DEFAULTS, type GraphCompilation, type NormalizedBarListSpec, type NormalizedChartSpec, type NormalizedChrome, type NormalizedGeoMapSpec, type NormalizedGraphSpec, type NormalizedSankeySpec, type NormalizedSpec, type NormalizedTableSpec, type NormalizedTileMapSpec, type ObstacleKind, type PlacementObstacle, type RichSpan, type SimulationConfig, UPDATE_DEFAULTS, type ValidationError, type ValidationErrorCode, type ValidationResult, buildAreaPath, buildEdgeTooltip, buildLinePath, clampStaggerDelay, clearRenderers, compile, compileBarList, compileChart, compileGeoMap, compileGraph, compileLayer, compileSankey, compileTable, compileTileMap, computeArrowheadPoints, dedupeKeys, evaluatePredicate, facetMinHeight, getChartRenderer, heuristicMeasure, isConditionalValueDef, legendGap, normalizeSpec, parseAnnotationSpans, registerChartRenderer, resolveAnimation, resolveConditionalValue, runBin, runCalculate, runFilter, runTimeUnit, runTransforms, serializeKeyValue, validateSpec };
package/dist/index.js CHANGED
@@ -9719,6 +9719,16 @@ function stripIgnoredKeys(spec, warnings) {
9719
9719
  const { $schema: _schema, ...rest } = spec;
9720
9720
  return rest;
9721
9721
  }
9722
+ function stripRemovedMarkRender(spec, warnings) {
9723
+ const mark = spec.mark;
9724
+ if (!mark || typeof mark !== "object" || Array.isArray(mark)) return spec;
9725
+ if (!("render" in mark)) return spec;
9726
+ warnings.push(
9727
+ "[openchart] mark.render was removed in v8. This field is stripped for backward compatibility. Pass { renderer } to createChart() or the compile options instead."
9728
+ );
9729
+ const { render: _render, ...restMark } = mark;
9730
+ return { ...spec, mark: restMark };
9731
+ }
9722
9732
  function applyFixedSizeDefault(spec) {
9723
9733
  if (typeof spec.width === "number" && typeof spec.height === "number" && spec.responsive === void 0) {
9724
9734
  return { ...spec, responsive: false };
@@ -9989,6 +9999,7 @@ function expandChartSugar(spec, warnings, inheritedData) {
9989
9999
  out = expandTopLevelTitle(out);
9990
10000
  out = expandDescriptionSugar(out);
9991
10001
  out = stripIgnoredKeys(out, warnings);
10002
+ out = stripRemovedMarkRender(out, warnings);
9992
10003
  out = applyFixedSizeDefault(out);
9993
10004
  out = expandAnnotationSugar(out, warnings);
9994
10005
  out = expandChannelSugar(out, warnings);
@@ -10152,9 +10163,9 @@ function resolveStagger(stagger, defaults) {
10152
10163
  import {
10153
10164
  isBarListSpec,
10154
10165
  isChartSpec,
10166
+ isGeoMapSpec,
10155
10167
  isGraphSpec,
10156
10168
  isLayerSpec,
10157
- isMapSpec,
10158
10169
  isSankeySpec,
10159
10170
  isTableSpec,
10160
10171
  isTileMapSpec,
@@ -10652,7 +10663,7 @@ function normalizeTileMapSpec(spec, warnings) {
10652
10663
  valueFormat: spec.valueFormat
10653
10664
  };
10654
10665
  }
10655
- function normalizeMapSpec(spec, _warnings) {
10666
+ function normalizeGeoMapSpec(spec, _warnings) {
10656
10667
  return {
10657
10668
  type: "map",
10658
10669
  geo: {
@@ -10712,8 +10723,8 @@ function normalizeSpec(spec, warnings = []) {
10712
10723
  if (isTileMapSpec(spec)) {
10713
10724
  return normalizeTileMapSpec(spec, warnings);
10714
10725
  }
10715
- if (isMapSpec(spec)) {
10716
- return normalizeMapSpec(spec, warnings);
10726
+ if (isGeoMapSpec(spec)) {
10727
+ return normalizeGeoMapSpec(spec, warnings);
10717
10728
  }
10718
10729
  if (isBarListSpec(spec)) {
10719
10730
  return normalizeBarListSpec(spec, warnings);
@@ -11029,19 +11040,38 @@ function validateCalendarSpec(spec, errors) {
11029
11040
  seenDays.set(dayKey, i);
11030
11041
  }
11031
11042
  }
11032
- var VALID_RENDER_MODES = /* @__PURE__ */ new Set(["auto", "svg", "canvas"]);
11033
- function validateMarkRenderMode(spec, errors) {
11034
- const mark = spec.mark;
11035
- if (!mark || typeof mark !== "object" || Array.isArray(mark)) return;
11036
- const render = mark.render;
11037
- if (render === void 0) return;
11038
- if (typeof render !== "string" || !VALID_RENDER_MODES.has(render)) {
11039
- errors.push({
11040
- message: `Spec error: mark.render ${JSON.stringify(render)} is not valid. Must be one of: auto, svg, canvas`,
11041
- path: "mark.render",
11042
- code: "INVALID_VALUE",
11043
- suggestion: 'Use mark: { type: "point", render: "auto" } (default), "canvas" to force the canvas mark layer, or "svg" to force one circle per point.'
11044
- });
11043
+ var MAX_PLAUSIBLE_POINT_RADIUS = 50;
11044
+ function pointSizeError(path2, value2) {
11045
+ const radius = Math.max(1, Math.round(Math.sqrt(value2 / Math.PI)));
11046
+ return {
11047
+ message: `Spec error: ${path2} is a radius in pixels, and ${value2} would draw a ${Math.round(value2 * 2)}px-wide circle. This usually means the value was written in Vega-Lite's units, where point size is an area in px^2.`,
11048
+ path: path2,
11049
+ code: "INVALID_VALUE",
11050
+ suggestion: `Point sizes are radii in px (default 5, typical 2-12). For the dot a Vega-Lite size of ${value2} draws, use ${radius} (r = sqrt(area / pi)).`
11051
+ };
11052
+ }
11053
+ function validatePointSize(spec, errors) {
11054
+ const markType = typeof spec.mark === "string" ? spec.mark : spec.mark?.type;
11055
+ if (markType !== "point") return;
11056
+ if (spec.mark && typeof spec.mark === "object") {
11057
+ const size = spec.mark.size;
11058
+ if (typeof size === "number" && size > MAX_PLAUSIBLE_POINT_RADIUS) {
11059
+ errors.push(pointSizeError("mark.size", size));
11060
+ }
11061
+ }
11062
+ const sizeEnc = spec.encoding && typeof spec.encoding === "object" ? spec.encoding.size : void 0;
11063
+ if (!sizeEnc || typeof sizeEnc !== "object") return;
11064
+ if (typeof sizeEnc.value === "number" && sizeEnc.value > MAX_PLAUSIBLE_POINT_RADIUS) {
11065
+ errors.push(pointSizeError("encoding.size.value", sizeEnc.value));
11066
+ }
11067
+ const range3 = sizeEnc.scale && typeof sizeEnc.scale === "object" ? sizeEnc.scale.range : void 0;
11068
+ if (Array.isArray(range3)) {
11069
+ const worst = range3.find(
11070
+ (entry) => typeof entry === "number" && entry > MAX_PLAUSIBLE_POINT_RADIUS
11071
+ );
11072
+ if (typeof worst === "number") {
11073
+ errors.push(pointSizeError("encoding.size.scale.range", worst));
11074
+ }
11045
11075
  }
11046
11076
  }
11047
11077
  function validateChartSpec(spec, errors) {
@@ -11149,7 +11179,7 @@ function validateChartSpec(spec, errors) {
11149
11179
  if (markType === "calendar") {
11150
11180
  validateCalendarSpec(spec, errors);
11151
11181
  }
11152
- validateMarkRenderMode(spec, errors);
11182
+ validatePointSize(spec, errors);
11153
11183
  if (Array.isArray(spec.transform)) {
11154
11184
  const transforms = spec.transform;
11155
11185
  for (let i = 0; i < transforms.length; i++) {
@@ -11887,7 +11917,7 @@ function validateTileMapSpec(spec, errors) {
11887
11917
  });
11888
11918
  }
11889
11919
  }
11890
- function validateMapSpec(spec, errors) {
11920
+ function validateGeoMapSpec(spec, errors) {
11891
11921
  if (!spec.geo || typeof spec.geo !== "object") {
11892
11922
  errors.push({
11893
11923
  message: 'Spec error: map spec requires a "geo" object with a TopoJSON "features" field',
@@ -12387,7 +12417,7 @@ function validateSpec(spec) {
12387
12417
  } else if (isTileMap) {
12388
12418
  validateTileMapSpec(obj, errors);
12389
12419
  } else if (isMap) {
12390
- validateMapSpec(obj, errors);
12420
+ validateGeoMapSpec(obj, errors);
12391
12421
  } else if (isBarList) {
12392
12422
  validateBarListSpec(obj, errors);
12393
12423
  }
@@ -15985,22 +16015,20 @@ function collectContrastWarnings(scales, markType, theme) {
15985
16015
 
15986
16016
  // src/compiler/mark-render-mode.ts
15987
16017
  var AUTO_CANVAS_THRESHOLD = 1e3;
15988
- var AUTO_ENABLED = true;
15989
16018
  function resolveMarkRenderMode(args, warnings = []) {
15990
- const { markDef, markType, pointCount, display, faceted, layered } = args;
15991
- const requested = markDef?.render ?? "auto";
16019
+ const { markType, pointCount, display, faceted, layered } = args;
16020
+ const requested = args.requested ?? "auto";
15992
16021
  if (requested === "svg") return "svg";
15993
16022
  const refusal = describeRefusal(markType, display, faceted, layered);
15994
16023
  if (refusal) {
15995
16024
  if (requested === "canvas") {
15996
16025
  warnings.push(
15997
- `Chart warning: mark.render "canvas" is not supported ${refusal}; rendering marks as SVG instead.`
16026
+ `Chart warning: renderer "canvas" is not supported ${refusal}; rendering marks as SVG instead.`
15998
16027
  );
15999
16028
  }
16000
16029
  return "svg";
16001
16030
  }
16002
16031
  if (requested === "canvas") return "canvas";
16003
- if (!AUTO_ENABLED) return "svg";
16004
16032
  return pointCount > AUTO_CANVAS_THRESHOLD ? "canvas" : "svg";
16005
16033
  }
16006
16034
  function describeRefusal(markType, display, faceted, layered) {
@@ -16077,7 +16105,7 @@ function buildSparklineAreaGradient(baseColor) {
16077
16105
  };
16078
16106
  }
16079
16107
 
16080
- // src/geo/compile-map.ts
16108
+ // src/geo/compile-geo-map.ts
16081
16109
  import {
16082
16110
  adaptTheme as adaptTheme2,
16083
16111
  buildD3Formatter as buildD3Formatter2,
@@ -17978,7 +18006,7 @@ function identity_default4() {
17978
18006
  return projection2;
17979
18007
  }
17980
18008
 
17981
- // src/geo/compile-map.ts
18009
+ // src/geo/compile-geo-map.ts
17982
18010
  import { feature as topoFeature, mesh as topoMesh } from "topojson-client";
17983
18011
 
17984
18012
  // src/geo/join.ts
@@ -18111,7 +18139,7 @@ function excludePolarFeatures(geojson) {
18111
18139
  return { type: "FeatureCollection", features: filtered };
18112
18140
  }
18113
18141
 
18114
- // src/geo/compile-map.ts
18142
+ // src/geo/compile-geo-map.ts
18115
18143
  var OVERLAY_LEGEND_INSET = 18;
18116
18144
  function validateGeoFeatures(geo) {
18117
18145
  if (!geo.features) {
@@ -18133,14 +18161,14 @@ function validateGeoFeatures(geo) {
18133
18161
  }
18134
18162
  return topo;
18135
18163
  }
18136
- function compileMap(spec, options) {
18164
+ function compileGeoMap(spec, options) {
18137
18165
  const sugarWarnings = [];
18138
18166
  const expandedSpec = spec && typeof spec === "object" && !Array.isArray(spec) ? expandSpecSugar(spec, sugarWarnings) : spec;
18139
18167
  const { spec: normalized, warnings } = compile(expandedSpec);
18140
18168
  emitSpecWarnings([...sugarWarnings, ...warnings], options.onWarn);
18141
18169
  if (!("type" in normalized) || normalized.type !== "map") {
18142
18170
  throw new Error(
18143
- "compileMap received a non-map spec. Use compileChart, compileTileMap, compileSankey, or compileBarList instead."
18171
+ "compileGeoMap received a non-map spec. Use compileChart, compileTileMap, compileSankey, or compileBarList instead."
18144
18172
  );
18145
18173
  }
18146
18174
  const mapSpec = normalized;
@@ -23410,7 +23438,7 @@ function compileChart(spec, optionsInput) {
23410
23438
  throw new Error("compileChart received a sankey spec. Use compileSankey instead.");
23411
23439
  }
23412
23440
  if ("type" in normalized && normalized.type === "map") {
23413
- throw new Error("compileChart received a map spec. Use compileMap instead.");
23441
+ throw new Error("compileChart received a map spec. Use compileGeoMap instead.");
23414
23442
  }
23415
23443
  let chartSpec = normalized;
23416
23444
  const rawWatermark = expandedSpec.watermark;
@@ -23708,7 +23736,7 @@ function compileChart(spec, optionsInput) {
23708
23736
  const markRenderModeWarnings = [];
23709
23737
  const markRenderMode = resolveMarkRenderMode(
23710
23738
  {
23711
- markDef: chartSpec.markDef,
23739
+ requested: options.renderer,
23712
23740
  markType: chartSpec.markType,
23713
23741
  pointCount: marks.reduce((n, m) => m.type === "point" ? n + 1 : n, 0),
23714
23742
  display: chartSpec.display,
@@ -24150,8 +24178,8 @@ function compileSankey2(spec, options) {
24150
24178
  function compileTileMap2(spec, options) {
24151
24179
  return compileTileMap(spec, options);
24152
24180
  }
24153
- function compileMap2(spec, options) {
24154
- return compileMap(spec, options);
24181
+ function compileGeoMap2(spec, options) {
24182
+ return compileGeoMap(spec, options);
24155
24183
  }
24156
24184
  function compileBarList2(spec, options) {
24157
24185
  return compileBarList(spec, options);
@@ -24172,9 +24200,9 @@ export {
24172
24200
  compile,
24173
24201
  compileBarList2 as compileBarList,
24174
24202
  compileChart,
24203
+ compileGeoMap2 as compileGeoMap,
24175
24204
  compileGraph2 as compileGraph,
24176
24205
  compileLayer2 as compileLayer,
24177
- compileMap2 as compileMap,
24178
24206
  compileSankey2 as compileSankey,
24179
24207
  compileTable,
24180
24208
  compileTileMap2 as compileTileMap,