@opendata-ai/openchart-vanilla 8.1.1 → 8.2.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.
@@ -853,7 +853,7 @@ function keyAnnotations(annotations) {
853
853
  }
854
854
 
855
855
  // src/transition/gate.ts
856
- var TRANSITIONABLE_MARKS = /* @__PURE__ */ new Set(["bar", "line", "area", "point", "beeswarm"]);
856
+ var TRANSITIONABLE_MARKS = /* @__PURE__ */ new Set(["bar", "line", "area", "point", "beeswarm", "arc"]);
857
857
  var DEFAULT_UPDATE_MAX_MARKS = 500;
858
858
  var CANVAS_DEFAULT_UPDATE_MAX_MARKS = 2e4;
859
859
  function canTransitionSpecShape(prevSpec, nextSpec) {
@@ -867,14 +867,13 @@ function canTransitionSpecShape(prevSpec, nextSpec) {
867
867
  const prevEnc = prev.encoding;
868
868
  const nextEnc = next.encoding;
869
869
  if (!prevEnc || !nextEnc) return false;
870
- return !(prevEnc.x?.field !== nextEnc.x?.field || prevEnc.x?.type !== nextEnc.x?.type || prevEnc.y?.field !== nextEnc.y?.field || prevEnc.y?.type !== nextEnc.y?.type || prevEnc.color?.field !== nextEnc.color?.field || prevEnc.key?.field !== nextEnc.key?.field || prevEnc.facet?.field !== nextEnc.facet?.field || prevEnc.row?.field !== nextEnc.row?.field || prevEnc.column?.field !== nextEnc.column?.field);
870
+ return !(prevEnc.x?.field !== nextEnc.x?.field || prevEnc.x?.type !== nextEnc.x?.type || prevEnc.y?.field !== nextEnc.y?.field || prevEnc.y?.type !== nextEnc.y?.type || prevEnc.theta?.field !== nextEnc.theta?.field || prevEnc.theta?.type !== nextEnc.theta?.type || prevEnc.color?.field !== nextEnc.color?.field || prevEnc.key?.field !== nextEnc.key?.field || prevEnc.facet?.field !== nextEnc.facet?.field || prevEnc.row?.field !== nextEnc.row?.field || prevEnc.column?.field !== nextEnc.column?.field);
871
871
  }
872
872
  function canTransition(args) {
873
873
  const { prevLayout, nextLayout, prevSpec, nextSpec, isFirstRender, entranceInFlight } = args;
874
874
  if (!prevLayout || !prevSpec || isFirstRender) return false;
875
875
  if (!nextLayout.animation?.update) return false;
876
876
  if (!canTransitionSpecShape(prevSpec, nextSpec)) return false;
877
- if (nextLayout.display === "sparkline") return false;
878
877
  if (entranceInFlight) return false;
879
878
  if (prevLayout.dimensions.width !== nextLayout.dimensions.width || prevLayout.dimensions.height !== nextLayout.dimensions.height) {
880
879
  return false;
@@ -936,6 +935,10 @@ function hasGeometryChanged(prevLayout, nextLayout) {
936
935
  }
937
936
  } else if (p.type === "area" && n.type === "area") {
938
937
  if (p.path !== n.path) return true;
938
+ } else if (p.type === "arc" && n.type === "arc") {
939
+ if (p.startAngle !== n.startAngle || p.endAngle !== n.endAngle || p.innerRadius !== n.innerRadius || p.outerRadius !== n.outerRadius || p.center.x !== n.center.x || p.center.y !== n.center.y) {
940
+ return true;
941
+ }
939
942
  } else if (p.type === "point" && n.type === "point") {
940
943
  if (p.cx !== n.cx || p.cy !== n.cy || p.r !== n.r) return true;
941
944
  } else if (p.type === "rule" && n.type === "rule") {
@@ -953,6 +956,9 @@ function hasGeometryChanged(prevLayout, nextLayout) {
953
956
  import { isGradientDef } from "@opendata-ai/openchart-core";
954
957
  import { buildAreaPath as buildAreaPath2, buildLinePath as buildLinePath2, EXIT_DEFAULTS } from "@opendata-ai/openchart-engine";
955
958
 
959
+ // src/transition/apply.ts
960
+ import { buildArcPath } from "@opendata-ai/openchart-engine";
961
+
956
962
  // ../../node_modules/.bun/d3-color@3.1.0/node_modules/d3-color/src/define.js
957
963
  function define_default(constructor, factory, prototype) {
958
964
  constructor.prototype = factory.prototype = prototype;
@@ -2129,6 +2135,24 @@ function applyFinalAreaPaths(el, mark) {
2129
2135
  }
2130
2136
 
2131
2137
  // src/transition/apply.ts
2138
+ function lerpArcGeom(from, to, t) {
2139
+ return {
2140
+ startAngle: from.startAngle + (to.startAngle - from.startAngle) * t,
2141
+ endAngle: from.endAngle + (to.endAngle - from.endAngle) * t,
2142
+ innerRadius: from.innerRadius + (to.innerRadius - from.innerRadius) * t,
2143
+ outerRadius: from.outerRadius + (to.outerRadius - from.outerRadius) * t
2144
+ };
2145
+ }
2146
+ function applyArcState(tw, eased) {
2147
+ const geom = lerpArcGeom(tw.from, tw.to, eased);
2148
+ const pathEl = tw.el.tagName === "path" ? tw.el : tw.el.querySelector("path");
2149
+ pathEl?.setAttribute("d", buildArcPath(geom));
2150
+ if (tw.fromCenter.x !== tw.toCenter.x || tw.fromCenter.y !== tw.toCenter.y) {
2151
+ const cx = tw.fromCenter.x + (tw.toCenter.x - tw.fromCenter.x) * eased;
2152
+ const cy = tw.fromCenter.y + (tw.toCenter.y - tw.fromCenter.y) * eased;
2153
+ tw.el.setAttribute("transform", `translate(${cx},${cy})`);
2154
+ }
2155
+ }
2132
2156
  function getKeyForTween(tw) {
2133
2157
  if (tw.tweenType === "canvasPoints" || tw.tweenType === "canvasGridlines") return null;
2134
2158
  if ("ghost" in tw && tw.ghost) return null;
@@ -2176,6 +2200,10 @@ function applyTweenState(tw, elapsed, update, exit, enterDelay, enterDuration) {
2176
2200
  applyAreaPaths(tw.el, top, bottom, tw.interpolate, tw.hasStroke);
2177
2201
  break;
2178
2202
  }
2203
+ case "arc": {
2204
+ applyArcState(tw, eased);
2205
+ break;
2206
+ }
2179
2207
  case "point": {
2180
2208
  const cx = tw.fromCx + (tw.toCx - tw.fromCx) * eased;
2181
2209
  const cy = tw.fromCy + (tw.toCy - tw.fromCy) * eased;
@@ -2263,6 +2291,12 @@ function snapTweenToFinal(tw) {
2263
2291
  case "area":
2264
2292
  applyAreaPaths(tw.el, tw.toTop, tw.toBottom, tw.interpolate, tw.hasStroke);
2265
2293
  break;
2294
+ case "arc": {
2295
+ const pathEl = tw.el.tagName === "path" ? tw.el : tw.el.querySelector("path");
2296
+ pathEl?.setAttribute("d", tw.mark.path);
2297
+ tw.el.setAttribute("transform", `translate(${tw.toCenter.x},${tw.toCenter.y})`);
2298
+ break;
2299
+ }
2266
2300
  case "point":
2267
2301
  tw.el.setAttribute("cx", String(tw.toCx));
2268
2302
  tw.el.setAttribute("cy", String(tw.toCy));
@@ -2754,6 +2788,97 @@ function buildAreaTweens(prevLayout, nextLayout, marksContainer, dom, tweens, gh
2754
2788
  });
2755
2789
  }
2756
2790
  }
2791
+ function arcGeomFromMark(m) {
2792
+ return {
2793
+ startAngle: m.startAngle,
2794
+ endAngle: m.endAngle,
2795
+ innerRadius: m.innerRadius,
2796
+ outerRadius: m.outerRadius
2797
+ };
2798
+ }
2799
+ function buildArcTweens(prevLayout, nextLayout, marksContainer, dom, tweens, ghosts, ghostGradientMap, fromSnapshot) {
2800
+ const prevArcs = prevLayout.marks.filter((m) => m.type === "arc");
2801
+ const nextArcs = nextLayout.marks.filter((m) => m.type === "arc");
2802
+ const prevByKey = /* @__PURE__ */ new Map();
2803
+ for (const m of prevArcs) {
2804
+ if (m.key) prevByKey.set(m.key, m);
2805
+ }
2806
+ const nextByKey = /* @__PURE__ */ new Map();
2807
+ for (const m of nextArcs) {
2808
+ if (m.key) nextByKey.set(m.key, m);
2809
+ }
2810
+ for (const [key, next] of nextByKey) {
2811
+ const prev = prevByKey.get(key);
2812
+ if (!prev) continue;
2813
+ const el = dom.any(key);
2814
+ if (!el) continue;
2815
+ let fromGeom = arcGeomFromMark(prev);
2816
+ let fromCenter = prev.center;
2817
+ const snap = fromSnapshot?.get(key);
2818
+ if (snap && snap.type === "arc") {
2819
+ fromGeom = {
2820
+ startAngle: snap.startAngle,
2821
+ endAngle: snap.endAngle,
2822
+ innerRadius: snap.innerRadius,
2823
+ outerRadius: snap.outerRadius
2824
+ };
2825
+ fromCenter = { x: snap.cx, y: snap.cy };
2826
+ }
2827
+ tweens.push({
2828
+ tweenType: "arc",
2829
+ kind: "update",
2830
+ el,
2831
+ from: fromGeom,
2832
+ to: arcGeomFromMark(next),
2833
+ fromCenter,
2834
+ toCenter: next.center,
2835
+ mark: next
2836
+ });
2837
+ }
2838
+ for (const [key, next] of nextByKey) {
2839
+ if (prevByKey.has(key)) continue;
2840
+ const el = dom.any(key);
2841
+ if (!el) continue;
2842
+ tweens.push({
2843
+ tweenType: "arc",
2844
+ kind: "enter",
2845
+ el,
2846
+ from: { ...arcGeomFromMark(next), endAngle: next.startAngle },
2847
+ to: arcGeomFromMark(next),
2848
+ fromCenter: next.center,
2849
+ toCenter: next.center,
2850
+ mark: next,
2851
+ fromOpacity: 0,
2852
+ toOpacity: 1
2853
+ });
2854
+ }
2855
+ for (const [key, prev] of prevByKey) {
2856
+ if (nextByKey.has(key)) continue;
2857
+ const ghostMark = resolveGhostGradientFill(prev, ghostGradientMap);
2858
+ const ghost = renderSingleMark(ghostMark, 0);
2859
+ if (!ghost) continue;
2860
+ ghost.classList.add("oc-ghost");
2861
+ ghost.setAttribute("aria-hidden", "true");
2862
+ ghost.setAttribute("pointer-events", "none");
2863
+ ghost.removeAttribute("data-key");
2864
+ marksContainer.appendChild(ghost);
2865
+ ghosts.push(ghost);
2866
+ const mid = (prev.startAngle + prev.endAngle) / 2;
2867
+ tweens.push({
2868
+ tweenType: "arc",
2869
+ kind: "exit",
2870
+ el: ghost,
2871
+ from: arcGeomFromMark(prev),
2872
+ to: { ...arcGeomFromMark(prev), startAngle: mid, endAngle: mid },
2873
+ fromCenter: prev.center,
2874
+ toCenter: prev.center,
2875
+ mark: prev,
2876
+ ghost,
2877
+ fromOpacity: 1,
2878
+ toOpacity: 0
2879
+ });
2880
+ }
2881
+ }
2757
2882
  function buildPointTweens(prevLayout, nextLayout, marksContainer, dom, tweens, ghosts, ghostGradientMap, fromSnapshot) {
2758
2883
  const prevPoints = prevLayout.marks.filter((m) => m.type === "point");
2759
2884
  const nextPoints = nextLayout.marks.filter((m) => m.type === "point");
@@ -3143,6 +3268,7 @@ function runTransition(args) {
3143
3268
  const hasRects = prevLayout.marks.some((m) => m.type === "rect") || nextLayout.marks.some((m) => m.type === "rect");
3144
3269
  const hasLines = prevLayout.marks.some((m) => m.type === "line") || nextLayout.marks.some((m) => m.type === "line");
3145
3270
  const hasAreas = prevLayout.marks.some((m) => m.type === "area") || nextLayout.marks.some((m) => m.type === "area");
3271
+ const hasArcs = prevLayout.marks.some((m) => m.type === "arc") || nextLayout.marks.some((m) => m.type === "arc");
3146
3272
  const hasPoints = prevLayout.marks.some((m) => m.type === "point") || nextLayout.marks.some((m) => m.type === "point");
3147
3273
  const hasRules = prevLayout.marks.some((m) => m.type === "rule") || nextLayout.marks.some((m) => m.type === "rule");
3148
3274
  const hasTicks = prevLayout.marks.some((m) => m.type === "tick") || nextLayout.marks.some((m) => m.type === "tick");
@@ -3174,6 +3300,18 @@ function runTransition(args) {
3174
3300
  fromSnapshot
3175
3301
  );
3176
3302
  }
3303
+ if (hasArcs) {
3304
+ buildArcTweens(
3305
+ prevLayout,
3306
+ nextLayout,
3307
+ marksContainer,
3308
+ dom,
3309
+ tweens,
3310
+ ghosts,
3311
+ ghostGradientMap,
3312
+ fromSnapshot
3313
+ );
3314
+ }
3177
3315
  if (hasPoints) {
3178
3316
  if (canvas) {
3179
3317
  buildCanvasPointsTween(prevLayout, nextLayout, canvas, tweens, fromSnapshot);
@@ -3347,6 +3485,15 @@ function runTransition(args) {
3347
3485
  snap.set(key, { type: "area", d, topD });
3348
3486
  break;
3349
3487
  }
3488
+ case "arc": {
3489
+ snap.set(key, {
3490
+ type: "arc",
3491
+ ...lerpArcGeom(tw.from, tw.to, easedUpdate),
3492
+ cx: tw.fromCenter.x + (tw.toCenter.x - tw.fromCenter.x) * easedUpdate,
3493
+ cy: tw.fromCenter.y + (tw.toCenter.y - tw.fromCenter.y) * easedUpdate
3494
+ });
3495
+ break;
3496
+ }
3350
3497
  }
3351
3498
  }
3352
3499
  return snap;
@@ -4859,6 +5006,21 @@ function wireLegendInteraction(svg, _layout, toggleSeries, onLegendToggle, onEdi
4859
5006
 
4860
5007
  // src/interactions/selection.ts
4861
5008
  import { elementRef as elementRef2 } from "@opendata-ai/openchart-core";
5009
+
5010
+ // src/dom-helpers.ts
5011
+ function applySrOnlyStyles(el) {
5012
+ el.style.position = "absolute";
5013
+ el.style.width = "1px";
5014
+ el.style.height = "1px";
5015
+ el.style.padding = "0";
5016
+ el.style.margin = "-1px";
5017
+ el.style.overflow = "clip";
5018
+ el.style.clipPath = "inset(50%)";
5019
+ el.style.whiteSpace = "nowrap";
5020
+ el.style.borderWidth = "0";
5021
+ }
5022
+
5023
+ // src/interactions/selection.ts
4862
5024
  function findElementByRef(svg, ref) {
4863
5025
  switch (ref.type) {
4864
5026
  case "annotation": {
@@ -5017,17 +5179,10 @@ function renderSelectionOverlay(svg, ref, layout) {
5017
5179
  function createScreenReaderTable(layout, container) {
5018
5180
  const data = layout.a11y.dataTableFallback;
5019
5181
  if (!data || data.length === 0) return null;
5182
+ const wrapper = document.createElement("div");
5183
+ wrapper.className = "oc-sr-only";
5184
+ applySrOnlyStyles(wrapper);
5020
5185
  const table = document.createElement("table");
5021
- table.className = "oc-sr-only";
5022
- table.style.position = "absolute";
5023
- table.style.width = "1px";
5024
- table.style.height = "1px";
5025
- table.style.padding = "0";
5026
- table.style.margin = "-1px";
5027
- table.style.overflow = "hidden";
5028
- table.style.clipPath = "inset(50%)";
5029
- table.style.whiteSpace = "nowrap";
5030
- table.style.borderWidth = "0";
5031
5186
  table.setAttribute("role", "table");
5032
5187
  table.setAttribute("aria-label", `Data table: ${layout.a11y.altText}`);
5033
5188
  const totalRows = layout.a11y.totalRows;
@@ -5063,8 +5218,9 @@ function createScreenReaderTable(layout, container) {
5063
5218
  }
5064
5219
  table.appendChild(tbody);
5065
5220
  }
5066
- container.appendChild(table);
5067
- return table;
5221
+ wrapper.appendChild(table);
5222
+ container.appendChild(wrapper);
5223
+ return wrapper;
5068
5224
  }
5069
5225
 
5070
5226
  // src/interactions/tooltip-events.ts
@@ -6310,7 +6466,7 @@ function createChart(container, spec, options) {
6310
6466
  let cleanupEditDrags = null;
6311
6467
  let cleanupSelection = null;
6312
6468
  let cleanupKeyboardEdit = null;
6313
- let srTable = null;
6469
+ let srTableWrapper = null;
6314
6470
  let destroyed = false;
6315
6471
  let isDragging = false;
6316
6472
  let pendingRender = false;
@@ -6770,9 +6926,9 @@ function createChart(container, spec, options) {
6770
6926
  if (tooltipManager) {
6771
6927
  tooltipManager.destroy();
6772
6928
  }
6773
- if (srTable?.parentNode) {
6774
- srTable.parentNode.removeChild(srTable);
6775
- srTable = null;
6929
+ if (srTableWrapper?.parentNode) {
6930
+ srTableWrapper.parentNode.removeChild(srTableWrapper);
6931
+ srTableWrapper = null;
6776
6932
  }
6777
6933
  currentLayout = compile();
6778
6934
  lastRenderedWidth = currentLayout.dimensions.width;
@@ -6895,7 +7051,7 @@ function createChart(container, spec, options) {
6895
7051
  }
6896
7052
  }
6897
7053
  if (!currentLayout.a11y.hidden) {
6898
- srTable = createScreenReaderTable(currentLayout, container);
7054
+ srTableWrapper = createScreenReaderTable(currentLayout, container);
6899
7055
  }
6900
7056
  if (currentLayout.seriesSearch) {
6901
7057
  if (!seriesSearch) {
@@ -7175,9 +7331,9 @@ function createChart(container, spec, options) {
7175
7331
  svgElement.parentNode.removeChild(svgElement);
7176
7332
  svgElement = null;
7177
7333
  }
7178
- if (srTable?.parentNode) {
7179
- srTable.parentNode.removeChild(srTable);
7180
- srTable = null;
7334
+ if (srTableWrapper?.parentNode) {
7335
+ srTableWrapper.parentNode.removeChild(srTableWrapper);
7336
+ srTableWrapper = null;
7181
7337
  }
7182
7338
  container.classList.remove("oc-dark");
7183
7339
  container.classList.remove("oc-root");
@@ -8377,6 +8533,7 @@ export {
8377
8533
  createTooltipManager,
8378
8534
  VECTOR_EXPORT_MAX_POINTS,
8379
8535
  materializeCanvasModeSVG,
8536
+ applySrOnlyStyles,
8380
8537
  AnimationScheduler,
8381
8538
  quadtree,
8382
8539
  SpatialIndex,
@@ -8405,4 +8562,4 @@ export {
8405
8562
  scrubCamera,
8406
8563
  createGeoMap
8407
8564
  };
8408
- //# sourceMappingURL=chunk-RQNAZZJM.js.map
8565
+ //# sourceMappingURL=chunk-N5KDVZU7.js.map