@opendata-ai/openchart-engine 8.4.1 → 8.5.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.
package/dist/index.d.ts CHANGED
@@ -208,7 +208,23 @@ interface GraphCompilation {
208
208
  seedNodeIds: string[];
209
209
  /** Edge legend entries (nominal edgeColor with >1 category), or undefined. */
210
210
  edgeLegend?: LegendEntry[];
211
+ /**
212
+ * Resolved render dimensionality. `3` only when the spec asked for it AND the
213
+ * node count is within {@link MAX_3D_NODES}; otherwise `2`.
214
+ */
215
+ numDimensions: 2 | 3;
211
216
  }
217
+ /**
218
+ * Node ceiling for 3D rendering. The 3D simulation runs on the main thread, so
219
+ * a spec above this falls back to 2D with a warning rather than freezing the
220
+ * page.
221
+ *
222
+ * The number is measured, not guessed. On the RFC 27 gate rig (headed Chromium,
223
+ * ANGLE/Metal, 900x600, DPR 2) an idle 3,000-node / ~6,000-edge scene held
224
+ * 22-27fps against a 30fps floor, while 2,000 held 38-44fps. Every edge is a
225
+ * separate draw call, which is what the ceiling is really made of.
226
+ */
227
+ declare const MAX_3D_NODES = 2000;
212
228
 
213
229
  /**
214
230
  * Compile a chart spec into a ChartLayout.
@@ -645,6 +661,8 @@ interface NormalizedGraphSpec {
645
661
  interactive?: boolean;
646
662
  counts?: boolean;
647
663
  };
664
+ /** Requested render dimensionality. Validated (and gated) in compileGraph. */
665
+ dimensions?: 2 | 3;
648
666
  }
649
667
  /** Discriminated union of all normalized spec types. */
650
668
  type NormalizedSpec = NormalizedChartSpec | NormalizedTableSpec | NormalizedGraphSpec | NormalizedSankeySpec | NormalizedTileMapSpec | NormalizedGeoMapSpec | NormalizedBarListSpec;
@@ -1124,4 +1142,4 @@ declare function runTimeUnit(data: DataRow[], transform: TimeUnitTransform): Dat
1124
1142
  */
1125
1143
  declare function runTransforms(data: DataRow[], transforms: Transform[]): DataRow[];
1126
1144
 
1127
- export { ARROWHEAD_LENGTH, AUTO_CANVAS_THRESHOLD, 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, buildArcPath, 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 };
1145
+ export { ARROWHEAD_LENGTH, AUTO_CANVAS_THRESHOLD, 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, MAX_3D_NODES, 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, buildArcPath, 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
@@ -7430,7 +7430,8 @@ function normalizeGraphSpec(spec, warnings) {
7430
7430
  watermark: spec.watermark ?? true,
7431
7431
  animation: spec.animation,
7432
7432
  interaction: spec.interaction,
7433
- legend: spec.legend
7433
+ legend: spec.legend,
7434
+ dimensions: spec.dimensions
7434
7435
  };
7435
7436
  }
7436
7437
  function normalizeTileMapSpec(spec, warnings) {
@@ -15109,6 +15110,9 @@ function resolveGraphInteraction(cfg) {
15109
15110
  };
15110
15111
  }
15111
15112
 
15113
+ // src/graphs/types.ts
15114
+ var MAX_3D_NODES = 2e3;
15115
+
15112
15116
  // src/graphs/compile-graph.ts
15113
15117
  var graphNumberFormatter = defaultNumberFormatter8({ allIntegers: false, surface: "chart" });
15114
15118
  function mergeOverrides(...layers) {
@@ -15264,6 +15268,7 @@ function compileGraph(spec, options) {
15264
15268
  );
15265
15269
  }
15266
15270
  const graphSpec = normalized;
15271
+ const numDimensions = resolveNumDimensions(graphSpec, options.onWarn);
15267
15272
  for (const [name, ch] of [
15268
15273
  ["nodeColor", graphSpec.encoding.nodeColor],
15269
15274
  ["edgeColor", graphSpec.encoding.edgeColor]
@@ -15405,9 +15410,39 @@ function compileGraph(spec, options) {
15405
15410
  legendField,
15406
15411
  initialHighlight,
15407
15412
  seedNodeIds,
15408
- edgeLegend
15413
+ edgeLegend,
15414
+ numDimensions
15409
15415
  };
15410
15416
  }
15417
+ function resolveNumDimensions(spec, onWarn) {
15418
+ const requested = spec.dimensions;
15419
+ if (requested !== void 0 && requested !== 2 && requested !== 3) {
15420
+ throw new Error(
15421
+ `Spec error: graph "dimensions" must be 2 or 3, received ${JSON.stringify(requested)}.`
15422
+ );
15423
+ }
15424
+ if (requested !== 3) return 2;
15425
+ if (spec.nodes.length > MAX_3D_NODES) {
15426
+ onWarn?.(
15427
+ `dimensions: 3 is unavailable for ${spec.nodes.length} nodes (the limit is ${MAX_3D_NODES}); rendering in 2D.`
15428
+ );
15429
+ return 2;
15430
+ }
15431
+ if (spec.interaction?.cursorRepulsion) {
15432
+ onWarn?.("interaction.cursorRepulsion is not supported in 3D; it will be ignored.");
15433
+ }
15434
+ if (spec.interaction?.springyDrag) {
15435
+ onWarn?.("interaction.springyDrag is not supported in 3D; it will be ignored.");
15436
+ }
15437
+ const hasStroke = (o) => o?.stroke !== void 0 || o?.strokeWidth !== void 0;
15438
+ const strokeOverrides = Object.values(spec.nodeOverrides ?? {}).some(hasStroke) || hasStroke(spec.seedNode?.style);
15439
+ if (strokeOverrides) {
15440
+ onWarn?.(
15441
+ "nodeOverrides/seedNode.style stroke and strokeWidth are not supported in 3D; they will be ignored."
15442
+ );
15443
+ }
15444
+ return 3;
15445
+ }
15411
15446
  var DEFAULT_COLLISION_PADDING = 5;
15412
15447
 
15413
15448
  // src/layout/dimensions.ts
@@ -19970,6 +20005,7 @@ export {
19970
20005
  DEFAULT_LINE_HEIGHT,
19971
20006
  ENTER_DEFAULTS,
19972
20007
  EXIT_DEFAULTS,
20008
+ MAX_3D_NODES,
19973
20009
  UPDATE_DEFAULTS,
19974
20010
  buildArcPath,
19975
20011
  buildAreaPath,