@opendata-ai/openchart-vanilla 8.0.0-rc.3 → 8.0.0-rc.4

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.
@@ -552,6 +552,7 @@ function setupTableAnimationCleanup(wrapper) {
552
552
  }
553
553
 
554
554
  // src/map-camera.ts
555
+ var FOCUS_DIM_OPACITY = 0.25;
555
556
  function focusTargetForFeatures(layout, ids, padding = 16) {
556
557
  const idSet = new Set(ids.map(String));
557
558
  let minX = Infinity;
@@ -594,7 +595,6 @@ function applyMapCamera(svg, camera, layout) {
594
595
  const baseSW = Number(p.getAttribute("data-base-stroke-width") ?? 1);
595
596
  p.setAttribute("r", String(baseR / camera.k));
596
597
  p.setAttribute("stroke-width", String(baseSW / camera.k));
597
- p.setAttribute("vector-effect", "non-scaling-stroke");
598
598
  }
599
599
  } else {
600
600
  cameraGroup.removeAttribute("transform");
@@ -736,7 +736,7 @@ function renderBorders(parent, borders) {
736
736
  }
737
737
  parent.appendChild(g);
738
738
  }
739
- function renderFeatures(parent, features, animation, staggerBudget = 0) {
739
+ function renderFeatures(parent, features, animation, staggerBudget = 0, focusIds) {
740
740
  const g = createSVGElement2("g");
741
741
  g.setAttribute("class", "oc-map-features");
742
742
  g.setAttribute("role", "list");
@@ -779,12 +779,19 @@ function renderFeatures(parent, features, animation, staggerBudget = 0) {
779
779
  if (feature.aria?.label) {
780
780
  path.setAttribute("aria-label", feature.aria.label);
781
781
  }
782
+ const dimmed = focusIds ? !focusIds.has(String(feature.id)) : false;
783
+ const s = path.style;
784
+ if (dimmed) {
785
+ s.setProperty("opacity", String(FOCUS_DIM_OPACITY));
786
+ }
782
787
  if (!bulk && animation?.enter) {
783
788
  const idx = feature.animationIndex ?? i;
784
789
  path.setAttribute("data-animation-index", String(idx));
785
- const s = path.style;
786
790
  s.setProperty("--oc-mark-index", String(idx));
787
791
  s.setProperty("--oc-feature-fill", feature.fill);
792
+ if (dimmed) {
793
+ s.setProperty("--oc-feature-target-opacity", String(FOCUS_DIM_OPACITY));
794
+ }
788
795
  if (staggerBudget > 0 && maxIdx > 0) {
789
796
  s.setProperty("--oc-map-delay", `${shuffledDelays[i]}ms`);
790
797
  }
@@ -797,16 +804,15 @@ function renderPointMarks(parent, points, animation) {
797
804
  if (points.length === 0) return;
798
805
  const g = createSVGElement2("g");
799
806
  g.setAttribute("class", "oc-map-points");
800
- g.setAttribute("role", "list");
801
807
  for (const pt of points) {
802
808
  const circle = createSVGElement2("circle");
803
809
  circle.setAttribute("class", "oc-map-point");
804
- circle.setAttribute("role", "listitem");
805
810
  setAttrs2(circle, {
806
811
  cx: pt.cx,
807
812
  cy: pt.cy,
808
813
  r: pt.r,
809
814
  fill: pt.fill,
815
+ "fill-opacity": pt.fillOpacity,
810
816
  stroke: pt.stroke,
811
817
  "stroke-width": pt.strokeWidth
812
818
  });
@@ -817,10 +823,9 @@ function renderPointMarks(parent, points, animation) {
817
823
  circle.setAttribute("aria-label", pt.aria.label);
818
824
  }
819
825
  if (animation?.enter) {
820
- circle.style.setProperty(
821
- "--oc-mark-index",
822
- String(pt.animationIndex)
823
- );
826
+ const s = circle.style;
827
+ s.setProperty("--oc-mark-index", String(pt.animationIndex));
828
+ s.setProperty("transform-origin", `${pt.cx}px ${pt.cy}px`);
824
829
  }
825
830
  g.appendChild(circle);
826
831
  }
@@ -856,28 +861,64 @@ function renderMapSVG(layout, opts) {
856
861
  }
857
862
  const defs = createSVGElement2("defs");
858
863
  svg.appendChild(defs);
859
- renderChrome(svg, layout);
860
864
  const mapGroup = createSVGElement2("g");
861
865
  mapGroup.setAttribute("class", "oc-map-group");
862
866
  mapGroup.setAttribute("transform", `translate(${layout.area.x},${layout.area.y})`);
863
867
  const cameraGroup = createSVGElement2("g");
864
868
  cameraGroup.setAttribute("class", "oc-map-camera");
865
869
  cameraGroup.setAttribute("data-oc-map-camera", "");
866
- renderFeatures(cameraGroup, features, animate ? animation : void 0, mapStaggerBudget);
870
+ const focusIdSet = layout.focus ? new Set(layout.focus.ids.map(String)) : void 0;
871
+ renderFeatures(
872
+ cameraGroup,
873
+ features,
874
+ animate ? animation : void 0,
875
+ mapStaggerBudget,
876
+ focusIdSet
877
+ );
867
878
  renderBorders(cameraGroup, borders);
868
879
  renderPointMarks(cameraGroup, layout.pointMarks, animate ? animation : void 0);
869
880
  mapGroup.appendChild(cameraGroup);
870
881
  svg.appendChild(mapGroup);
882
+ renderChrome(svg, layout);
871
883
  if (layout.continuousLegend) {
872
884
  renderLegend(svg, layout.continuousLegend);
873
885
  } else if (layout.categoricalLegend) {
874
886
  renderLegend(svg, layout.categoricalLegend);
875
887
  }
876
- if (layout.pointCategoricalLegend) {
877
- renderLegend(svg, layout.pointCategoricalLegend);
878
- }
879
- if (layout.pointContinuousLegend) {
880
- renderLegend(svg, layout.pointContinuousLegend);
888
+ const ptLegend = layout.pointCategoricalLegend ?? layout.pointContinuousLegend;
889
+ if (ptLegend) {
890
+ const isDark = layout.theme.isDark;
891
+ const padX = 10;
892
+ const padY = 8;
893
+ const swatchSize = "swatchSize" in ptLegend ? ptLegend.swatchSize : 10;
894
+ const swatchGap = "swatchGap" in ptLegend ? ptLegend.swatchGap : 6;
895
+ const entryGap = "entryGap" in ptLegend ? ptLegend.entryGap : 16;
896
+ let contentWidth = ptLegend.bounds.width;
897
+ if ("entries" in ptLegend && ptLegend.entries) {
898
+ const cat = ptLegend;
899
+ if (cat && cat.entries.length > 0) {
900
+ const fontSize = ptLegend.labelStyle.fontSize;
901
+ let w = 0;
902
+ for (const entry of cat.entries) {
903
+ w += swatchSize + swatchGap + entry.label.length * fontSize * 0.6 + entryGap;
904
+ }
905
+ w -= entryGap;
906
+ contentWidth = Math.min(w, ptLegend.bounds.width);
907
+ }
908
+ }
909
+ const contentCenterY = ptLegend.bounds.y + swatchSize / 2;
910
+ const bgHeight = swatchSize + padY * 2;
911
+ const bg = createSVGElement2("rect");
912
+ setAttrs2(bg, {
913
+ x: ptLegend.bounds.x - padX,
914
+ y: contentCenterY - bgHeight / 2,
915
+ width: contentWidth + padX * 2,
916
+ height: bgHeight,
917
+ rx: 4,
918
+ fill: isDark ? "rgba(24,24,27,0.9)" : "rgba(255,255,255,0.9)"
919
+ });
920
+ svg.appendChild(bg);
921
+ renderLegend(svg, ptLegend);
881
922
  }
882
923
  if (watermark) {
883
924
  renderWatermark(svg, layout);
@@ -1540,6 +1581,7 @@ function createMap(container, spec, options) {
1540
1581
  }
1541
1582
  if (feature) {
1542
1583
  options?.onMarkHover?.({
1584
+ kind: "feature",
1543
1585
  id: feature.id,
1544
1586
  name: feature.name,
1545
1587
  data: feature.data
@@ -1564,6 +1606,7 @@ function createMap(container, spec, options) {
1564
1606
  const handleClick = () => {
1565
1607
  if (feature) {
1566
1608
  options?.onMarkClick?.({
1609
+ kind: "feature",
1567
1610
  id: feature.id,
1568
1611
  name: feature.name,
1569
1612
  data: feature.data
@@ -1600,8 +1643,8 @@ function createMap(container, spec, options) {
1600
1643
  }
1601
1644
  if (pointMark) {
1602
1645
  options?.onMarkHover?.({
1646
+ kind: "point",
1603
1647
  id: pointKey,
1604
- name: pointKey,
1605
1648
  data: pointMark.data
1606
1649
  });
1607
1650
  }
@@ -1624,8 +1667,8 @@ function createMap(container, spec, options) {
1624
1667
  const handlePointClick = () => {
1625
1668
  if (pointMark) {
1626
1669
  options?.onMarkClick?.({
1670
+ kind: "point",
1627
1671
  id: pointKey,
1628
- name: pointKey,
1629
1672
  data: pointMark.data
1630
1673
  });
1631
1674
  }
@@ -1708,7 +1751,7 @@ function createMap(container, spec, options) {
1708
1751
  const fid = el.getAttribute("data-feature-id");
1709
1752
  el.style.setProperty(
1710
1753
  "opacity",
1711
- fid && focusSet.has(fid) ? "1" : "0.25"
1754
+ fid && focusSet.has(fid) ? "1" : String(FOCUS_DIM_OPACITY)
1712
1755
  );
1713
1756
  }
1714
1757
  }
@@ -1721,15 +1764,17 @@ function createMap(container, spec, options) {
1721
1764
  fillTransitionHandle.cancel();
1722
1765
  fillTransitionHandle = null;
1723
1766
  }
1724
- if (svgElement) {
1767
+ const oldSvg = svgElement;
1768
+ const newSvg = renderMapSVG(currentLayout, { animate });
1769
+ if (oldSvg) {
1725
1770
  if (cleanupTooltipEvents) {
1726
1771
  cleanupTooltipEvents();
1727
1772
  cleanupTooltipEvents = null;
1728
1773
  }
1729
- svgElement.remove();
1774
+ container.replaceChild(newSvg, oldSvg);
1775
+ } else {
1776
+ container.appendChild(newSvg);
1730
1777
  }
1731
- const newSvg = renderMapSVG(currentLayout, { animate });
1732
- container.appendChild(newSvg);
1733
1778
  svgElement = newSvg;
1734
1779
  cleanupTooltipEvents = wireTooltipAndInteraction(newSvg, currentLayout);
1735
1780
  if (options?.tooltip !== false) {
@@ -6626,4 +6671,4 @@ export {
6626
6671
  createYouDrawIt,
6627
6672
  createChart
6628
6673
  };
6629
- //# sourceMappingURL=chunk-SBIGNRAH.js.map
6674
+ //# sourceMappingURL=chunk-43Y7EBT7.js.map