@opendata-ai/openchart-vanilla 8.1.0 → 8.2.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.
@@ -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;
@@ -8405,4 +8552,4 @@ export {
8405
8552
  scrubCamera,
8406
8553
  createGeoMap
8407
8554
  };
8408
- //# sourceMappingURL=chunk-RQNAZZJM.js.map
8555
+ //# sourceMappingURL=chunk-RC5PGDQX.js.map