apexcharts 8.2.0 → 8.3.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.
Files changed (222) hide show
  1. package/README.md +7 -7
  2. package/dist/apexcharts.common.js +2 -2
  3. package/dist/apexcharts.core.js +271 -173
  4. package/dist/apexcharts.core.min.js +2 -2
  5. package/dist/apexcharts.css +35 -0
  6. package/dist/apexcharts.esm.js +1722 -1527
  7. package/dist/apexcharts.full.js +1459 -1075
  8. package/dist/apexcharts.full.min.js +2 -2
  9. package/dist/apexcharts.js +994 -715
  10. package/dist/apexcharts.min.js +2 -2
  11. package/dist/apexcharts.ssr.common.js +2 -2
  12. package/dist/apexcharts.ssr.esm.js +994 -715
  13. package/dist/area.common.js +2 -2
  14. package/dist/area.esm.js +91 -40
  15. package/dist/bar.common.js +2 -2
  16. package/dist/bar.esm.js +433 -394
  17. package/dist/bar.js +2 -2
  18. package/dist/boxPlot.common.js +2 -2
  19. package/dist/boxPlot.esm.js +364 -322
  20. package/dist/bubble.common.js +2 -2
  21. package/dist/bubble.esm.js +91 -40
  22. package/dist/candlestick.common.js +2 -2
  23. package/dist/candlestick.esm.js +364 -322
  24. package/dist/candlestick.js +2 -2
  25. package/dist/column.common.js +2 -2
  26. package/dist/column.esm.js +433 -394
  27. package/dist/core.common.js +2 -2
  28. package/dist/core.esm.js +271 -173
  29. package/dist/donut.common.js +1 -1
  30. package/dist/donut.esm.js +1 -1
  31. package/dist/dumbbell.common.js +2 -2
  32. package/dist/dumbbell.esm.js +433 -394
  33. package/dist/features/all.common.js +2 -2
  34. package/dist/features/all.esm.js +250 -187
  35. package/dist/features/annotations.common.js +1 -1
  36. package/dist/features/annotations.esm.js +1 -1
  37. package/dist/features/annotations.js +1 -1
  38. package/dist/features/context-menu.common.js +1 -1
  39. package/dist/features/context-menu.esm.js +1 -1
  40. package/dist/features/context-menu.js +1 -1
  41. package/dist/features/drilldown.common.js +2 -2
  42. package/dist/features/drilldown.esm.js +4 -2
  43. package/dist/features/drilldown.js +2 -2
  44. package/dist/features/dumbbell.common.js +1 -1
  45. package/dist/features/dumbbell.esm.js +1 -1
  46. package/dist/features/dumbbell.js +1 -1
  47. package/dist/features/exports.common.js +1 -1
  48. package/dist/features/exports.esm.js +1 -1
  49. package/dist/features/exports.js +1 -1
  50. package/dist/features/facet.common.js +1 -1
  51. package/dist/features/facet.esm.js +1 -1
  52. package/dist/features/facet.js +1 -1
  53. package/dist/features/highlight-filter.common.js +2 -2
  54. package/dist/features/highlight-filter.esm.js +14 -9
  55. package/dist/features/highlight-filter.js +2 -2
  56. package/dist/features/history.common.js +1 -1
  57. package/dist/features/history.esm.js +1 -1
  58. package/dist/features/history.js +1 -1
  59. package/dist/features/ink.common.js +1 -1
  60. package/dist/features/ink.esm.js +1 -1
  61. package/dist/features/ink.js +1 -1
  62. package/dist/features/keyboard.common.js +2 -2
  63. package/dist/features/keyboard.esm.js +97 -145
  64. package/dist/features/keyboard.js +2 -2
  65. package/dist/features/legend.common.js +2 -2
  66. package/dist/features/legend.esm.js +63 -43
  67. package/dist/features/legend.js +2 -2
  68. package/dist/features/link.common.js +1 -1
  69. package/dist/features/link.esm.js +1 -1
  70. package/dist/features/link.js +1 -1
  71. package/dist/features/marks.common.js +1 -1
  72. package/dist/features/marks.esm.js +1 -1
  73. package/dist/features/marks.js +1 -1
  74. package/dist/features/measure.common.js +1 -1
  75. package/dist/features/measure.esm.js +1 -1
  76. package/dist/features/measure.js +1 -1
  77. package/dist/features/morph.common.js +1 -1
  78. package/dist/features/morph.esm.js +1 -1
  79. package/dist/features/morph.js +1 -1
  80. package/dist/features/perspectives.common.js +1 -1
  81. package/dist/features/perspectives.esm.js +1 -1
  82. package/dist/features/perspectives.js +1 -1
  83. package/dist/features/raincloud.common.js +1 -1
  84. package/dist/features/raincloud.esm.js +1 -1
  85. package/dist/features/raincloud.js +1 -1
  86. package/dist/features/renderer-canvas.common.js +2 -2
  87. package/dist/features/renderer-canvas.esm.js +2 -1
  88. package/dist/features/renderer-canvas.js +2 -2
  89. package/dist/features/stats.common.js +1 -1
  90. package/dist/features/stats.esm.js +1 -1
  91. package/dist/features/stats.js +1 -1
  92. package/dist/features/storyboard.common.js +1 -1
  93. package/dist/features/storyboard.esm.js +1 -1
  94. package/dist/features/storyboard.js +1 -1
  95. package/dist/features/streamgraph.common.js +2 -2
  96. package/dist/features/streamgraph.esm.js +3 -2
  97. package/dist/features/streamgraph.js +2 -2
  98. package/dist/features/toolbar.common.js +2 -2
  99. package/dist/features/toolbar.esm.js +92 -2
  100. package/dist/features/toolbar.js +2 -2
  101. package/dist/features/trellis.common.js +2 -2
  102. package/dist/features/trellis.esm.js +83 -47
  103. package/dist/features/trellis.js +2 -2
  104. package/dist/features/waterfall.common.js +1 -1
  105. package/dist/features/waterfall.esm.js +1 -1
  106. package/dist/features/waterfall.js +1 -1
  107. package/dist/features/weave.common.js +1 -1
  108. package/dist/features/weave.esm.js +1 -1
  109. package/dist/features/weave.js +1 -1
  110. package/dist/full.common.js +2 -2
  111. package/dist/full.esm.js +950 -795
  112. package/dist/heatmap.common.js +2 -2
  113. package/dist/heatmap.esm.js +3 -17
  114. package/dist/heatmap.js +2 -2
  115. package/dist/histogram.common.js +2 -2
  116. package/dist/histogram.esm.js +433 -394
  117. package/dist/icicle.common.js +2 -2
  118. package/dist/icicle.esm.js +54 -38
  119. package/dist/icicle.js +2 -2
  120. package/dist/line.common.js +2 -2
  121. package/dist/line.esm.js +91 -40
  122. package/dist/line.js +2 -2
  123. package/dist/locales/en.json +2 -1
  124. package/dist/locales/ro.json +3 -2
  125. package/dist/pictograms.common.js +1 -1
  126. package/dist/pictograms.esm.js +1 -1
  127. package/dist/pictograms.js +1 -1
  128. package/dist/pie.common.js +1 -1
  129. package/dist/pie.esm.js +1 -1
  130. package/dist/pie.js +1 -1
  131. package/dist/polarArea.common.js +1 -1
  132. package/dist/polarArea.esm.js +1 -1
  133. package/dist/radar.common.js +2 -2
  134. package/dist/radar.esm.js +5 -4
  135. package/dist/radar.js +2 -2
  136. package/dist/radialBar.common.js +1 -1
  137. package/dist/radialBar.esm.js +1 -1
  138. package/dist/radialBar.js +1 -1
  139. package/dist/raincloud.common.js +2 -2
  140. package/dist/raincloud.esm.js +72 -26
  141. package/dist/rangeArea.common.js +2 -2
  142. package/dist/rangeArea.esm.js +91 -40
  143. package/dist/rangeBar.common.js +2 -2
  144. package/dist/rangeBar.esm.js +433 -394
  145. package/dist/scatter.common.js +2 -2
  146. package/dist/scatter.esm.js +91 -40
  147. package/dist/streamgraph.common.js +2 -2
  148. package/dist/streamgraph.esm.js +93 -41
  149. package/dist/sunburst.common.js +2 -2
  150. package/dist/sunburst.esm.js +103 -93
  151. package/dist/sunburst.js +2 -2
  152. package/dist/treemap.common.js +2 -2
  153. package/dist/treemap.esm.js +105 -86
  154. package/dist/treemap.js +2 -2
  155. package/dist/unit-shapes.common.js +1 -1
  156. package/dist/unit-shapes.esm.js +1 -1
  157. package/dist/unit-shapes.js +1 -1
  158. package/dist/unit.common.js +2 -2
  159. package/dist/unit.esm.js +280 -202
  160. package/dist/unit.js +2 -2
  161. package/dist/violin.common.js +2 -2
  162. package/dist/violin.esm.js +72 -26
  163. package/dist/violin.js +2 -2
  164. package/dist/waterfall.common.js +2 -2
  165. package/dist/waterfall.esm.js +432 -393
  166. package/package.json +1 -1
  167. package/src/apexcharts.js +13 -6
  168. package/src/assets/apexcharts.css +35 -0
  169. package/src/charts/Bar.js +62 -55
  170. package/src/charts/BarStacked.js +80 -88
  171. package/src/charts/BoxCandleStick.js +28 -31
  172. package/src/charts/Icicle.js +37 -37
  173. package/src/charts/Line.js +118 -42
  174. package/src/charts/Radar.js +5 -7
  175. package/src/charts/RangeBar.js +47 -43
  176. package/src/charts/Sunburst.js +101 -98
  177. package/src/charts/Treemap.js +108 -66
  178. package/src/charts/Unit.js +368 -250
  179. package/src/charts/Violin.js +48 -30
  180. package/src/charts/common/Breadcrumb.js +2 -2
  181. package/src/charts/common/Hierarchy.js +32 -11
  182. package/src/charts/common/Jitter.js +32 -7
  183. package/src/charts/common/bar/DataLabels.js +76 -81
  184. package/src/charts/common/bar/Helpers.js +43 -7
  185. package/src/charts/common/line/Helpers.js +12 -15
  186. package/src/charts/common/partition/NodeTooltip.js +8 -1
  187. package/src/charts/common/partition/Partition.js +33 -1
  188. package/src/charts/common/treemap/Helpers.js +3 -11
  189. package/src/locales/en.json +2 -1
  190. package/src/locales/ro.json +3 -2
  191. package/src/modules/Core.js +4 -0
  192. package/src/modules/CoreUtils.js +18 -42
  193. package/src/modules/Data.js +23 -24
  194. package/src/modules/DataLabels.js +6 -6
  195. package/src/modules/Graphics.js +62 -49
  196. package/src/modules/Markers.js +3 -1
  197. package/src/modules/Range.js +44 -29
  198. package/src/modules/RendererController.js +17 -3
  199. package/src/modules/Scales.js +32 -9
  200. package/src/modules/Series.js +39 -18
  201. package/src/modules/Theme.js +1 -1
  202. package/src/modules/ZoomPanSelection.js +119 -2
  203. package/src/modules/accessibility/KeyboardNavigation.js +114 -186
  204. package/src/modules/animations/LengthTransition.js +22 -2
  205. package/src/modules/drilldown/Breadcrumb.js +5 -2
  206. package/src/modules/helpers/Destroy.js +1 -1
  207. package/src/modules/highlightFilter/HighlightFilter.js +8 -9
  208. package/src/modules/highlightFilter/TreemapPart.js +2 -2
  209. package/src/modules/legend/HeatmapGradientLegend.js +76 -45
  210. package/src/modules/legend/Helpers.js +2 -0
  211. package/src/modules/legend/Legend.js +11 -12
  212. package/src/modules/settings/Options.js +7 -0
  213. package/src/modules/streamgraph/StreamLabels.js +1 -0
  214. package/src/modules/tooltip/Tooltip.js +20 -4
  215. package/src/modules/tooltip/Utils.js +8 -0
  216. package/src/modules/trellis/Trellis.js +6 -0
  217. package/src/modules/trellis/TrellisChrome.js +18 -7
  218. package/src/modules/trellis/TrellisSync.js +2 -0
  219. package/src/renderers/canvas/CanvasGraphics.js +1 -0
  220. package/src/ssr/DOMShim.js +10 -0
  221. package/src/types/internal.d.ts +9 -3
  222. package/types/apexcharts.d.ts +31 -12
@@ -31,7 +31,7 @@ var __objRest = (source, exclude) => {
31
31
  };
32
32
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
33
33
  /*!
34
- * ApexCharts v8.2.0
34
+ * ApexCharts v8.3.0
35
35
  * (c) 2018-2026 ApexCharts
36
36
  */
37
37
  import * as _core from "apexcharts/core";
@@ -960,6 +960,7 @@ let Helpers$1 = class Helpers {
960
960
  toggleDataSeries(seriesCnt, isHidden) {
961
961
  var _a, _b, _c;
962
962
  const w = this.w;
963
+ if (!w.dom.baseEl) return;
963
964
  if (w.globals.axisCharts || w.config.chart.type === "radialBar") {
964
965
  w.globals.resized = true;
965
966
  let seriesEl = null;
@@ -1426,9 +1427,11 @@ class HeatmapGradientLegend {
1426
1427
  this._min = 0;
1427
1428
  this._max = 0;
1428
1429
  this._geom = null;
1430
+ this._grad = null;
1429
1431
  this._bandHitEls = [];
1430
1432
  this._activeBandIndex = -1;
1431
1433
  this._targetEl = null;
1434
+ this.panelsW = null;
1432
1435
  this._onCellEnter = this._onCellEnter.bind(this);
1433
1436
  this._onCellLeave = this._onCellLeave.bind(this);
1434
1437
  this._onBandEnter = this._onBandEnter.bind(this);
@@ -1543,15 +1546,8 @@ class HeatmapGradientLegend {
1543
1546
  linearGrad.setAttribute("x2", "1");
1544
1547
  linearGrad.setAttribute("y2", "0");
1545
1548
  }
1546
- const { min, max, stops, bands } = this._computeStops();
1547
- this._min = min;
1548
- this._max = max;
1549
- stops.forEach((s) => {
1550
- const stopEl = BrowserAPIs.createElementNS(SVG_NS, "stop");
1551
- stopEl.setAttribute("offset", `${(s.percent * 100).toFixed(2)}%`);
1552
- stopEl.setAttribute("stop-color", s.color);
1553
- linearGrad.appendChild(stopEl);
1554
- });
1549
+ this._grad = linearGrad;
1550
+ const { min, max, bands } = this._paintStops();
1555
1551
  defs.appendChild(linearGrad);
1556
1552
  svg.appendChild(defs);
1557
1553
  const rect = BrowserAPIs.createElementNS(SVG_NS, "rect");
@@ -1760,6 +1756,7 @@ class HeatmapGradientLegend {
1760
1756
  */
1761
1757
  repositionToPlot() {
1762
1758
  var _a, _b;
1759
+ if (this._grad) this._paintStops();
1763
1760
  if (!Environment.isBrowser()) return;
1764
1761
  if (this._targetEl) return;
1765
1762
  const w = this.w;
@@ -1894,14 +1891,25 @@ class HeatmapGradientLegend {
1894
1891
  if (idx < 0 || idx === this._activeBandIndex) return;
1895
1892
  this._activeBandIndex = idx;
1896
1893
  (_d = (_c = (_b = this.ctx) == null ? void 0 : _b.events) == null ? void 0 : _c.fireEvent) == null ? void 0 : _d.call(_c, "legendHover", [this.ctx, idx, w]);
1897
- new Series(w).highlightRangeInSeries(idx, "highlight");
1894
+ this._highlightRange(idx, "highlight");
1898
1895
  }
1899
1896
  /** Leaving a band clears the highlight. */
1900
1897
  _onBandLeave() {
1901
1898
  if (this._activeBandIndex < 0) return;
1902
1899
  const idx = this._activeBandIndex;
1903
1900
  this._activeBandIndex = -1;
1904
- new Series(this.w).highlightRangeInSeries(idx, "reset");
1901
+ this._highlightRange(idx, "reset");
1902
+ }
1903
+ /**
1904
+ * A shared trellis strip sets `panelsW` so a band reaches every panel.
1905
+ * @param {number} idx
1906
+ * @param {'highlight'|'reset'} action
1907
+ */
1908
+ _highlightRange(idx, action) {
1909
+ var _a;
1910
+ (((_a = this.panelsW) == null ? void 0 : _a.call(this)) || [this.w]).forEach(
1911
+ (w) => new Series(w).highlightRangeInSeries(idx, action)
1912
+ );
1905
1913
  }
1906
1914
  _attachHoverListeners() {
1907
1915
  var _a, _b;
@@ -1923,10 +1931,10 @@ class HeatmapGradientLegend {
1923
1931
  */
1924
1932
  _onCellEnter(...args) {
1925
1933
  var _a, _b, _c;
1926
- const w = this.w;
1927
1934
  if (!this.arrowEl) return;
1928
1935
  const opts = args[args.length - 1];
1929
1936
  if (!opts || typeof opts !== "object") return;
1937
+ const w = opts.w || this.w;
1930
1938
  const i = opts.seriesIndex;
1931
1939
  const j = opts.dataPointIndex;
1932
1940
  if (typeof i !== "number" || typeof j !== "number") return;
@@ -2038,6 +2046,21 @@ class HeatmapGradientLegend {
2038
2046
  polygon.setAttribute("pointer-events", "none");
2039
2047
  return polygon;
2040
2048
  }
2049
+ /** (Re)write the strip's stops; returns `_computeStops()`. */
2050
+ _paintStops() {
2051
+ const r = this._computeStops();
2052
+ const grad = this._grad;
2053
+ this._min = r.min;
2054
+ this._max = r.max;
2055
+ grad.innerHTML = "";
2056
+ r.stops.forEach((s) => {
2057
+ const stopEl = BrowserAPIs.createElementNS(SVG_NS, "stop");
2058
+ stopEl.setAttribute("offset", `${(s.percent * 100).toFixed(2)}%`);
2059
+ stopEl.setAttribute("stop-color", s.color);
2060
+ grad.appendChild(stopEl);
2061
+ });
2062
+ return r;
2063
+ }
2041
2064
  /**
2042
2065
  * Build gradient stops + return effective min/max.
2043
2066
  * - If `colorScale.ranges` is set, stops are placed at each range boundary
@@ -2079,7 +2102,8 @@ class HeatmapGradientLegend {
2079
2102
  if (!Number.isFinite(dataMax)) dataMax = 0;
2080
2103
  let min = dataMin;
2081
2104
  let max = dataMax;
2082
- if (typeof cs.min !== "undefined" && typeof cs.max !== "undefined" && cs.max > cs.min) {
2105
+ const csWindow = typeof cs.min !== "undefined" && typeof cs.max !== "undefined" && cs.max > cs.min;
2106
+ if (csWindow) {
2083
2107
  min = cs.min;
2084
2108
  max = cs.max;
2085
2109
  } else {
@@ -2110,34 +2134,30 @@ class HeatmapGradientLegend {
2110
2134
  } else {
2111
2135
  const baseColor = w.globals.colors[0] || "#008FFB";
2112
2136
  const utils = new Utils();
2113
- const plot = w.config.plotOptions[w.config.chart.type] || {};
2137
+ const type = w.config.chart.type;
2138
+ const plot = w.config.plotOptions[type] || {};
2114
2139
  const shadeIntensity = (_b = plot.shadeIntensity) != null ? _b : 0.5;
2115
- const hasNegs = (
2140
+ const g = (
2116
2141
  /** @type {any} */
2117
- w.globals.hasNegs
2142
+ w.globals
2118
2143
  );
2144
+ const hasNegs = g.hasNegs;
2145
+ const yExt = type === "heatmap" && !plot.distributed && !csWindow && g.maxY >= g.minY;
2146
+ const hi = yExt ? g.maxY : max;
2147
+ const total = Math.abs(hi) + Math.abs(yExt ? cs.min < g.minY ? cs.min : g.minY : min);
2148
+ const k2 = shadeIntensity * 1.25;
2119
2149
  const n = Math.max(2, cfg.stops || 16);
2120
2150
  for (let s = 0; s < n; s++) {
2121
2151
  const t = s / (n - 1);
2122
- const v = min + t * (max - min);
2123
- const total = Math.abs(max) + Math.abs(min);
2124
- const percent_v = total === 0 ? 0 : 100 * v / total;
2125
- let colorShadePercent;
2126
- if (hasNegs) {
2127
- if (plot.reverseNegativeShade) {
2128
- colorShadePercent = percent_v < 0 ? percent_v / 100 * (shadeIntensity * 1.25) : (1 - percent_v / 100) * (shadeIntensity * 1.25);
2129
- } else {
2130
- colorShadePercent = percent_v <= 0 ? 1 - (1 + percent_v / 100) * shadeIntensity : (1 - percent_v / 100) * shadeIntensity;
2131
- }
2132
- } else {
2133
- colorShadePercent = 1 - percent_v / 100;
2134
- }
2135
- if (colorShadePercent > 1) colorShadePercent = 1;
2136
- if (colorShadePercent < -1) colorShadePercent = -1;
2137
- const shaded = plot.enableShades ? utils.shadeColor(
2138
- w.config.theme.mode === "dark" ? colorShadePercent * -1 : colorShadePercent,
2139
- baseColor
2140
- ) : baseColor;
2152
+ const p = total === 0 ? 0 : Math.min(min + t * (max - min), hi) / total;
2153
+ const c = Math.max(
2154
+ -1,
2155
+ Math.min(
2156
+ 1,
2157
+ hasNegs ? plot.reverseNegativeShade ? (p < 0 ? p : 1 - p) * k2 : p <= 0 ? 1 - (1 + p) * shadeIntensity : (1 - p) * shadeIntensity : (1 - p) * (type === "treemap" ? k2 : 1)
2158
+ )
2159
+ );
2160
+ const shaded = plot.enableShades ? utils.shadeColor(w.config.theme.mode === "dark" ? -c : c, baseColor) : baseColor;
2141
2161
  stops.push({ percent: t, color: shaded });
2142
2162
  }
2143
2163
  }
@@ -2168,9 +2188,12 @@ class Legend {
2168
2188
  this.legendHelpers = new Helpers$1(this);
2169
2189
  }
2170
2190
  init() {
2191
+ var _a;
2171
2192
  const w = this.w;
2172
2193
  const gl = w.globals;
2173
2194
  const cnf = w.config;
2195
+ (_a = this.heatmapGradientLegend) == null ? void 0 : _a.destroy();
2196
+ this.heatmapGradientLegend = null;
2174
2197
  this.isBarsDistributed = cnf.chart.type === "bar" && cnf.plotOptions.bar.distributed && cnf.series.length === 1;
2175
2198
  const showLegendAlways = cnf.legend.showForSingleSeries && this.w.seriesData.series.length === 1 || this.isBarsDistributed || // Heatmap legends are colorScale-driven (discrete ranges or the
2176
2199
  // gradient strip), not series-driven, so they must render even for a
@@ -2188,10 +2211,6 @@ class Legend {
2188
2211
  while (elLegendWrap.firstChild) {
2189
2212
  elLegendWrap.removeChild(elLegendWrap.firstChild);
2190
2213
  }
2191
- if (this.heatmapGradientLegend) {
2192
- this.heatmapGradientLegend.destroy();
2193
- this.heatmapGradientLegend = null;
2194
- }
2195
2214
  if (HeatmapGradientLegend.isEnabled(w)) {
2196
2215
  this.heatmapGradientLegend = new HeatmapGradientLegend(w, this.ctx);
2197
2216
  this.heatmapGradientLegend.draw();
@@ -2369,7 +2388,7 @@ class Legend {
2369
2388
  }
2370
2389
  }
2371
2390
  const lg = legendGroups[w.labelData.seriesGroupIndex[i]];
2372
- if (lg) elLegendWrap.appendChild(lg);
2391
+ if (lg && !lg.parentNode) elLegendWrap.appendChild(lg);
2373
2392
  (lg || elLegendWrap).appendChild(elLegend);
2374
2393
  elLegendWrap.classList.add(
2375
2394
  `apexcharts-align-${w.config.legend.horizontalAlign}`
@@ -2480,7 +2499,7 @@ class Legend {
2480
2499
  );
2481
2500
  const hoverOverLegend = isLegendItem(target);
2482
2501
  if (w.config.chart.type !== "heatmap" && !this.isBarsDistributed) {
2483
- if (!target.classList.contains("apexcharts-inactive-legend") && hoverOverLegend) {
2502
+ if (hoverOverLegend && !target.closest(".apexcharts-inactive-legend")) {
2484
2503
  const series = new Series(this.ctx.w);
2485
2504
  series.toggleSeriesOnHover(e, target);
2486
2505
  }
@@ -2514,7 +2533,8 @@ class Legend {
2514
2533
  me.onLegendClick(e);
2515
2534
  if (rel !== null && w.config.legend.onItemClick.toggleDataSeries) {
2516
2535
  requestAnimationFrame(() => {
2517
- const restored = w.dom.baseEl.querySelector(
2536
+ var _a;
2537
+ const restored = (_a = w.dom.baseEl) == null ? void 0 : _a.querySelector(
2518
2538
  `.apexcharts-legend-series[rel="${rel}"]`
2519
2539
  );
2520
2540
  if (restored) restored.focus();
@@ -3600,6 +3620,63 @@ class ZoomPanSelection extends Toolbar {
3600
3620
  const { zoom } = this.w.config.chart;
3601
3621
  return this._incidentalZoomEnabled(zoom && zoom.allowMouseWheelZoom);
3602
3622
  }
3623
+ /** An explicit `true` zooms on every wheel; 'auto' needs Ctrl/Cmd. */
3624
+ _wheelZoomGreedy() {
3625
+ return this.w.config.chart.zoom.allowMouseWheelZoom === true;
3626
+ }
3627
+ /**
3628
+ * Tell a viewer whose bare wheel just scrolled past the chart how to zoom it.
3629
+ * Shown over the chart while the scroll goes on and faded out shortly after
3630
+ * it stops. Only for a mostly vertical wheel: a sideways trackpad swipe is
3631
+ * not someone reaching for zoom.
3632
+ *
3633
+ * The node lives in elWrap and the timer on w.interact, since a re-render can
3634
+ * replace both this instance and the wrapper's contents while it is up.
3635
+ *
3636
+ * @param {any} e
3637
+ */
3638
+ _showWheelHint(e) {
3639
+ const w = this.w;
3640
+ if (w.config.chart.zoom.wheelHint === false) return;
3641
+ if (Math.abs(e.deltaY) <= Math.abs(e.deltaX)) return;
3642
+ const wrap = w.dom.elWrap;
3643
+ if (!wrap) return;
3644
+ let el = wrap.querySelector(".apexcharts-wheel-hint");
3645
+ if (!el) {
3646
+ const win = BrowserAPIs.getWindow();
3647
+ const nav = win && win.navigator;
3648
+ const mac = !!nav && /Mac|iPhone|iPad/.test(nav.platform || nav.userAgent);
3649
+ const text = (w.globals.locale.toolbar.wheelZoomHint || "").replace(
3650
+ "{key}",
3651
+ mac ? "⌘" : "Ctrl"
3652
+ );
3653
+ el = BrowserAPIs.createElement("div");
3654
+ el.className = "apexcharts-wheel-hint";
3655
+ el.setAttribute("aria-hidden", "true");
3656
+ const label = BrowserAPIs.createElement("span");
3657
+ label.textContent = text;
3658
+ label.style.fontFamily = w.config.chart.fontFamily;
3659
+ el.appendChild(label);
3660
+ wrap.appendChild(el);
3661
+ void /** @type {HTMLElement} */
3662
+ el.offsetWidth;
3663
+ }
3664
+ el.classList.add("apexcharts-wheel-hint-visible");
3665
+ const it = w.interact;
3666
+ if (it.wheelHintTimer) clearTimeout(it.wheelHintTimer);
3667
+ it.wheelHintTimer = setTimeout(() => this._hideWheelHint(), 1200);
3668
+ }
3669
+ _hideWheelHint() {
3670
+ var _a;
3671
+ const w = this.w;
3672
+ const it = w.interact;
3673
+ if (it.wheelHintTimer) {
3674
+ clearTimeout(it.wheelHintTimer);
3675
+ it.wheelHintTimer = null;
3676
+ }
3677
+ const el = (_a = w.dom.elWrap) == null ? void 0 : _a.querySelector(".apexcharts-wheel-hint");
3678
+ if (el) el.classList.remove("apexcharts-wheel-hint-visible");
3679
+ }
3603
3680
  /**
3604
3681
  * Put keyboard focus on the chart, where the chart is focusable at all.
3605
3682
  *
@@ -3671,8 +3748,13 @@ class ZoomPanSelection extends Toolbar {
3671
3748
  * @param {any} e
3672
3749
  */
3673
3750
  mouseWheelEvent(e) {
3674
- e.preventDefault();
3675
3751
  const st = this._wheel();
3752
+ if (!this._wheelZoomGreedy() && !e.ctrlKey && !e.metaKey && st.endTimer == null) {
3753
+ this._showWheelHint(e);
3754
+ return;
3755
+ }
3756
+ e.preventDefault();
3757
+ this._hideWheelHint();
3676
3758
  let dy = e.deltaY;
3677
3759
  if (e.deltaMode === 1) dy *= 33;
3678
3760
  else if (e.deltaMode === 2) dy *= 330;
@@ -4436,6 +4518,34 @@ class ZoomPanSelection extends Toolbar {
4436
4518
  w.config.chart.events.scrolled(this.ctx, args);
4437
4519
  this.ctx.events.fireEvent("scrolled", args);
4438
4520
  }
4521
+ /**
4522
+ * Pan a zoomed x-window by `fraction` of its width (keyboard Shift+Arrow),
4523
+ * clamped to the data as a drag pan is, and reported as one (`scrolled`).
4524
+ * @param {number} fraction
4525
+ */
4526
+ panBy(fraction) {
4527
+ const w = this.w;
4528
+ if (!w.interact.zoomed) return;
4529
+ const { min, max } = this._currentXWindow();
4530
+ let d = (max - min) * fraction;
4531
+ if (w.config.xaxis.convertedCatToNumeric) {
4532
+ d = d > 0 ? Math.ceil(d) : Math.floor(d);
4533
+ }
4534
+ if (w.axisFlags.isRangeBar) {
4535
+ const r = w.rangeData;
4536
+ let lo = Infinity;
4537
+ let hi = -Infinity;
4538
+ r.seriesRangeStart.concat(r.seriesRangeEnd).flat().forEach((y) => {
4539
+ if (y != null) {
4540
+ lo = Math.min(lo, y);
4541
+ hi = Math.max(hi, y);
4542
+ }
4543
+ });
4544
+ d = d > 0 ? Math.min(d, Math.max(0, hi - max)) : Math.max(d, Math.min(0, lo - min));
4545
+ if (!d) return;
4546
+ }
4547
+ if (this._applyXRange(min + d, max + d, false)) this._fireScrolled();
4548
+ }
4439
4549
  /** @param {number} x @param {number} t */
4440
4550
  _pushSample(x2, t) {
4441
4551
  const s = this._m().samples;
@@ -5903,16 +6013,35 @@ class KeyboardNavigation {
5903
6013
  });
5904
6014
  svgEl.addEventListener("keydown", this._onKeyDown, { passive: false });
5905
6015
  this.ctx.events.addEventListener("legendClick", this._onLegendClick);
6016
+ const kept = w.interact.keyNav;
6017
+ const doc = svgEl.ownerDocument;
6018
+ w.interact.keyNav = null;
6019
+ if (kept && (!doc.activeElement || doc.activeElement === doc.body)) {
6020
+ [this.seriesIndex, this.dataPointIndex, , this._tooltipDismissed] = kept;
6021
+ if (!kept[2]) this.notePointerFocus();
6022
+ svgEl.focus({ preventScroll: true });
6023
+ }
5906
6024
  }
5907
6025
  /**
5908
- * Removes all event listeners. Called from chart.destroy().
6026
+ * Removes all event listeners. Called from chart.destroy(), and with
6027
+ * `updating` when an update is about to replace the SVG.
6028
+ * @param {boolean} [updating]
5909
6029
  */
5910
- destroy() {
6030
+ destroy(updating) {
6031
+ var _a;
5911
6032
  const w = this.w;
5912
6033
  const svgEl = w.dom.Paper && w.dom.Paper.node;
5913
6034
  this.ctx.events.removeEventListener("legendClick", this._onLegendClick);
5914
6035
  clearTimeout(this._announceTimer);
5915
6036
  if (!svgEl) return;
6037
+ if (updating && ((_a = svgEl.getRootNode) == null ? void 0 : _a.call(svgEl).activeElement) === svgEl) {
6038
+ w.interact.keyNav = [
6039
+ this.seriesIndex,
6040
+ this.dataPointIndex,
6041
+ this.active,
6042
+ this._tooltipDismissed
6043
+ ];
6044
+ }
5916
6045
  svgEl.removeEventListener("focus", this._onFocus);
5917
6046
  svgEl.removeEventListener("blur", this._onBlur);
5918
6047
  svgEl.removeEventListener("keydown", this._onKeyDown);
@@ -5964,7 +6093,7 @@ class KeyboardNavigation {
5964
6093
  this.active = true;
5965
6094
  this._clampCursor();
5966
6095
  this._snapToVisibleRange();
5967
- this._showCurrentPoint();
6096
+ if (!this._tooltipDismissed) this._showCurrentPoint();
5968
6097
  }
5969
6098
  _onBlur() {
5970
6099
  this.active = false;
@@ -6010,20 +6139,18 @@ class KeyboardNavigation {
6010
6139
  break;
6011
6140
  case "Home":
6012
6141
  e.preventDefault();
6013
- this.dataPointIndex = 0;
6014
- this._skipNullForward();
6142
+ this._seek(0, 1);
6015
6143
  this._showCurrentPoint();
6016
6144
  break;
6017
6145
  case "End":
6018
6146
  e.preventDefault();
6019
- this.dataPointIndex = this._getDataPointCount(this.seriesIndex) - 1;
6020
- this._skipNullBackward();
6147
+ this._seek(this._getDataPointCount(this.seriesIndex) - 1, -1);
6021
6148
  this._showCurrentPoint();
6022
6149
  break;
6023
6150
  case "Enter":
6024
6151
  case " ":
6025
6152
  e.preventDefault();
6026
- this._fireClick();
6153
+ this._fireClick(e);
6027
6154
  break;
6028
6155
  case "+":
6029
6156
  case "=":
@@ -6071,22 +6198,15 @@ class KeyboardNavigation {
6071
6198
  );
6072
6199
  }
6073
6200
  _canPan() {
6074
- return this._canZoom();
6201
+ return this._canZoom() && this.w.interact.zoomed;
6075
6202
  }
6076
6203
  /**
6077
- * Shift the visible x-range by ~10% in the given direction.
6204
+ * Shift the visible x-range by ~10% in the given direction, as a drag pan.
6078
6205
  * @param {number} direction +1 = right, -1 = left
6079
6206
  */
6080
6207
  _panBy(direction) {
6081
- const toolbar = this.ctx.toolbar;
6082
- if (!toolbar) return;
6083
- const r = toolbar._currentXRange();
6084
- const minX = Number(r.minX);
6085
- const maxX = Number(r.maxX);
6086
- if (!isFinite(minX) || !isFinite(maxX) || minX === maxX) return;
6087
- const span = maxX - minX;
6088
- const step = span * 0.1 * direction;
6089
- toolbar.zoomUpdateOptions(minX + step, maxX + step);
6208
+ var _a;
6209
+ (_a = this.ctx.zoomPanSelection) == null ? void 0 : _a.panBy(direction / 10);
6090
6210
  this._announce(direction > 0 ? "Panned right" : "Panned left");
6091
6211
  }
6092
6212
  // ─── Navigation ───────────────────────────────────────────────────────────
@@ -6101,8 +6221,8 @@ class KeyboardNavigation {
6101
6221
  if (dSeries !== 0) {
6102
6222
  const ttCtx = this.w.globals.tooltip;
6103
6223
  const type = w.config.chart.type;
6104
- const perCell = type === "heatmap" || type === "treemap";
6105
- if (!perCell && ttCtx && ttCtx.tConfig && ttCtx.tConfig.shared) {
6224
+ const perCell = type === "heatmap" || type === "treemap" || type === "radialBar";
6225
+ if (!perCell && (ttCtx == null ? void 0 : ttCtx.ttItems) && ttCtx.tConfig.shared) {
6106
6226
  const j = this.dataPointIndex;
6107
6227
  const isActuallyShared = ttCtx.tooltipUtil && ttCtx.tooltipUtil.isXoverlap(j) && ttCtx.tooltipUtil.isInitialSeriesSameLen();
6108
6228
  if (isActuallyShared) return;
@@ -6128,59 +6248,43 @@ class KeyboardNavigation {
6128
6248
  }
6129
6249
  }
6130
6250
  if (dPoint !== 0) {
6131
- const dpCount = this._getDataPointCount(this.seriesIndex);
6132
- let di = this.dataPointIndex + dPoint;
6133
- if (di < 0) di = wrapAround ? dpCount - 1 : 0;
6134
- if (di >= dpCount) di = wrapAround ? 0 : dpCount - 1;
6135
- this.dataPointIndex = di;
6136
- if (dPoint > 0) {
6137
- this._skipNullForward();
6138
- } else {
6139
- this._skipNullBackward();
6140
- }
6251
+ this._seek(this.dataPointIndex + dPoint, dPoint);
6141
6252
  if (!this._isDataPointVisible(this.seriesIndex, this.dataPointIndex)) {
6142
6253
  this._snapToVisibleRangeInDirection(dPoint);
6143
6254
  }
6144
6255
  }
6145
6256
  this._showCurrentPoint();
6146
6257
  }
6147
- /** Advance dataPointIndex forward past any nulls */
6148
- _skipNullForward() {
6149
- const w = this.w;
6150
- const si = this.seriesIndex;
6151
- const dpCount = this._getDataPointCount(si);
6152
- let di = this.dataPointIndex;
6153
- let attempts = 0;
6154
- if (!Array.isArray(w.seriesData.series[si])) return;
6155
- while (attempts < dpCount && w.seriesData.series[si][di] === null) {
6156
- di = (di + 1) % dpCount;
6157
- attempts++;
6158
- }
6159
- this.dataPointIndex = di;
6160
- }
6161
- /** Retreat dataPointIndex backward past any nulls */
6162
- _skipNullBackward() {
6258
+ /**
6259
+ * Land on the first non-null point from `di` going `dir`. Past an edge it
6260
+ * wraps only with wrapAround; when no point lies ahead the cursor stays.
6261
+ * @param {number} di
6262
+ * @param {number} dir
6263
+ */
6264
+ _seek(di, dir) {
6163
6265
  const w = this.w;
6164
- const si = this.seriesIndex;
6165
- const dpCount = this._getDataPointCount(si);
6166
- let di = this.dataPointIndex;
6167
- let attempts = 0;
6168
- if (!Array.isArray(w.seriesData.series[si])) return;
6169
- while (attempts < dpCount && w.seriesData.series[si][di] === null) {
6170
- di = (di - 1 + dpCount) % dpCount;
6171
- attempts++;
6266
+ const row = w.seriesData.series[this.seriesIndex];
6267
+ const n = this._getDataPointCount(this.seriesIndex);
6268
+ for (let k2 = 0; k2 < n; k2++, di += dir) {
6269
+ if (w.config.chart.accessibility.keyboard.navigation.wrapAround) {
6270
+ di = (di + n) % n;
6271
+ } else if (di < 0 || di >= n) return;
6272
+ if (!Array.isArray(row) || row[di] !== null) {
6273
+ this.dataPointIndex = di;
6274
+ return;
6275
+ }
6172
6276
  }
6173
- this.dataPointIndex = di;
6174
6277
  }
6175
6278
  // ─── Display ──────────────────────────────────────────────────────────────
6176
6279
  _showCurrentPoint() {
6177
6280
  const { seriesIndex: i, dataPointIndex: j } = this;
6178
6281
  const w = this.w;
6179
6282
  const ttCtx = w.globals.tooltip;
6180
- if (!ttCtx || !ttCtx.ttItems) return;
6283
+ this._tooltipDismissed = false;
6181
6284
  w.interact.capturedSeriesIndex = i;
6182
6285
  w.interact.capturedDataPointIndex = j;
6183
6286
  this._applyFocusClass(i, j);
6287
+ if (!(ttCtx == null ? void 0 : ttCtx.ttItems)) return this._announce(this._buildPointLabel(i, j));
6184
6288
  this._showTooltip(
6185
6289
  i,
6186
6290
  j,
@@ -6238,10 +6342,8 @@ class KeyboardNavigation {
6238
6342
  if (w.config.chart.accessibility.enabled && w.config.chart.accessibility.announcements.enabled) {
6239
6343
  tooltipEl.removeAttribute("aria-hidden");
6240
6344
  }
6241
- if (type === "pie" || type === "donut" || type === "polarArea") {
6345
+ if (type === "pie" || type === "donut" || type === "polarArea" || type === "radialBar") {
6242
6346
  this._showTooltipNonAxis(i, j, ttCtx, tooltipEl);
6243
- } else if (type === "radialBar") {
6244
- this._showTooltipRadialBar(i, j, ttCtx, tooltipEl);
6245
6347
  } else if (type === "heatmap" || type === "treemap") {
6246
6348
  this._showTooltipHeatTree(i, j, ttCtx, tooltipEl, type);
6247
6349
  } else if (this._isBarLikeSeries(i)) {
@@ -6596,24 +6698,23 @@ class KeyboardNavigation {
6596
6698
  return true;
6597
6699
  }
6598
6700
  /**
6599
- * pie / donut / polarArea
6701
+ * pie / donut / polarArea (a slice per point, i is 0) and radialBar (a ring
6702
+ * per series, j is 0)
6600
6703
  * @param {number} i
6601
6704
  * @param {number} j
6602
6705
  * @param {import('../tooltip/Tooltip').default} ttCtx
6603
6706
  * @param {HTMLElement} tooltipEl
6604
6707
  */
6605
6708
  _showTooltipNonAxis(i, j, ttCtx, tooltipEl) {
6606
- const w = this.w;
6607
6709
  ttCtx.tooltipLabels.drawSeriesTexts({
6608
6710
  ttItems: ttCtx.ttItems,
6609
- i: j,
6711
+ i: i + j,
6610
6712
  shared: false
6611
6713
  });
6612
6714
  const tooltipBound = tooltipEl.getBoundingClientRect();
6613
6715
  const ttWidth = tooltipBound.width || ttCtx.tooltipRect.ttWidth || 0;
6614
6716
  const ttHeight = tooltipBound.height || ttCtx.tooltipRect.ttHeight || 0;
6615
- const sliceEl = w.dom.baseEl.querySelector(`.apexcharts-pie-area[j='${j}']`);
6616
- const anchor = ttCtx.getSliceAnchor(sliceEl);
6717
+ const anchor = ttCtx.getSliceAnchor(this._getFocusableElement(i, j));
6617
6718
  if (anchor) {
6618
6719
  const pos = ttCtx.tooltipPosition.placeOverAnchor(
6619
6720
  anchor.x,
@@ -6626,56 +6727,6 @@ class KeyboardNavigation {
6626
6727
  tooltipEl.style.top = pos.y + "px";
6627
6728
  }
6628
6729
  }
6629
- /**
6630
- * radialBar — one ring per series, single value each
6631
- * @param {number} i
6632
- * @param {any} _j
6633
- * @param {import('../tooltip/Tooltip').default} ttCtx
6634
- * @param {HTMLElement} tooltipEl
6635
- */
6636
- _showTooltipRadialBar(i, _j, ttCtx, tooltipEl) {
6637
- var _a;
6638
- const w = this.w;
6639
- ttCtx.tooltipLabels.drawSeriesTexts({
6640
- ttItems: ttCtx.ttItems,
6641
- i,
6642
- shared: false
6643
- });
6644
- const { ttWidth = 0, ttHeight = 0 } = ttCtx.getCachedDimensions();
6645
- const arcEl = w.dom.baseEl.querySelector(
6646
- `.apexcharts-radialbar-series[data\\:realIndex='${i}'] path`
6647
- );
6648
- if (arcEl) {
6649
- const angle = parseFloat((_a = arcEl.getAttribute("data:angle")) != null ? _a : "") || 0;
6650
- const initialAngle = w.config.plotOptions.radialBar.startAngle || 0;
6651
- const midAngle = initialAngle + angle / 2;
6652
- const centerX = w.layout.gridWidth / 2;
6653
- const centerY = w.layout.gridHeight / 2;
6654
- const radialSize = w.globals.radialSize || Math.min(w.layout.gridWidth, w.layout.gridHeight) / 2;
6655
- const seriesCount = w.seriesData.series.length;
6656
- const trackSize = radialSize / Math.max(seriesCount, 1);
6657
- const outerRadius = radialSize - i * trackSize;
6658
- const innerRadius = outerRadius - trackSize;
6659
- const ringRadius = (outerRadius + innerRadius) / 2;
6660
- const centroid = Utils.polarToCartesian(
6661
- centerX,
6662
- centerY,
6663
- ringRadius,
6664
- midAngle
6665
- );
6666
- const x2 = centroid.x + (w.layout.translateX || 0);
6667
- const y = centroid.y + (w.layout.translateY || 0);
6668
- const pos = ttCtx.tooltipPosition.placeOverAnchor(
6669
- x2,
6670
- y,
6671
- ttWidth,
6672
- ttHeight,
6673
- 10
6674
- );
6675
- tooltipEl.style.left = pos.x + "px";
6676
- tooltipEl.style.top = pos.y + "px";
6677
- }
6678
- }
6679
6730
  /**
6680
6731
  * heatmap / treemap — position tooltip using element bounding rect
6681
6732
  * @param {number} i
@@ -6935,9 +6986,7 @@ class KeyboardNavigation {
6935
6986
  const mark = this._canvasMark(i, j);
6936
6987
  if (!mark) return this._drawCanvasMarkerFocusRing(i, j);
6937
6988
  const w = this.w;
6938
- const host = Array.from(
6939
- w.dom.baseEl.querySelectorAll(".apexcharts-series")
6940
- ).find((g) => g.getAttribute("data:realIndex") === String(i));
6989
+ const host = this._seriesGroup(i);
6941
6990
  if (!host) return null;
6942
6991
  const ring = new Graphics(w, this.ctx).drawPath({
6943
6992
  d: mark.d,
@@ -6961,9 +7010,7 @@ class KeyboardNavigation {
6961
7010
  const marker = this._canvasMarker(i, j);
6962
7011
  if (!marker) return null;
6963
7012
  const w = this.w;
6964
- const host = Array.from(
6965
- w.dom.baseEl.querySelectorAll(".apexcharts-series")
6966
- ).find((g) => g.getAttribute("data:realIndex") === String(i));
7013
+ const host = this._seriesGroup(i);
6967
7014
  if (!host) return null;
6968
7015
  const ring = new Graphics(w, this.ctx).drawPath({
6969
7016
  d: marker.d,
@@ -7057,6 +7104,7 @@ class KeyboardNavigation {
7057
7104
  * @param {number} j
7058
7105
  */
7059
7106
  _getFocusableElement(i, j) {
7107
+ var _a, _b;
7060
7108
  const w = this.w;
7061
7109
  const type = w.config.chart.type;
7062
7110
  const baseEl = w.dom.baseEl;
@@ -7074,32 +7122,47 @@ class KeyboardNavigation {
7074
7122
  );
7075
7123
  }
7076
7124
  if (type === "radialBar") {
7077
- return baseEl.querySelector(
7078
- `.apexcharts-radialbar-series[data\\:realIndex='${i}'] path`
7079
- );
7125
+ return baseEl.querySelector(`.apexcharts-radialbar-slice-${i}`);
7080
7126
  }
7081
7127
  if (this._isBarLikeSeries(i)) {
7082
7128
  if (this._canvasMark(i, j)) return null;
7083
- return baseEl.querySelector(
7084
- `.apexcharts-series[data\\:realIndex='${i}'] path[j='${j}']`
7085
- );
7129
+ return (_a = this._seriesGroup(i)) == null ? void 0 : _a.querySelector(`path[j='${j}']`);
7086
7130
  }
7087
- const marker = baseEl.querySelector(
7088
- `.apexcharts-series[data\\:realIndex='${i}'] .apexcharts-marker[rel='${j}']`
7089
- );
7090
- return marker || null;
7131
+ return (_b = this._seriesGroup(i)) == null ? void 0 : _b.querySelector(`.apexcharts-marker[rel='${j}']`);
7132
+ }
7133
+ /**
7134
+ * The series' own group, by realIndex (`rel` counts within a type's groups,
7135
+ * which a combo has several of). Matched in script: not every selector
7136
+ * engine takes the escaped `data\:realIndex` attribute.
7137
+ * @param {number} i
7138
+ * @returns {Element | undefined}
7139
+ */
7140
+ _seriesGroup(i) {
7141
+ return Array.from(
7142
+ this.w.dom.baseEl.querySelectorAll(".apexcharts-series")
7143
+ ).find((g) => g.getAttribute("data:realIndex") === String(i));
7091
7144
  }
7092
7145
  // ─── Click / Enter ────────────────────────────────────────────────────────
7093
- _fireClick() {
7094
- const w = this.w;
7095
- const ttCtx = w.globals.tooltip;
7096
- if (!ttCtx) return;
7097
- const syntheticEvent = {
7098
- type: "mouseup",
7099
- clientX: 0,
7100
- clientY: 0
7101
- };
7102
- ttCtx.markerClick(syntheticEvent, this.seriesIndex, this.dataPointIndex);
7146
+ /**
7147
+ * What a click on the focused mark does: its mousedown selects it
7148
+ * (dataPointSelection), its mouseup slides a pie slice out and fires
7149
+ * markerClick.
7150
+ * @param {KeyboardEvent} e
7151
+ */
7152
+ _fireClick(e) {
7153
+ var _a, _b;
7154
+ const el = (
7155
+ /** @type {any} */
7156
+ (_a = this._focusedEl) == null ? void 0 : _a.instance
7157
+ );
7158
+ const pie = this.ctx.pie;
7159
+ if (el) new Graphics(this.w, this.ctx).pathMouseDown(el, e);
7160
+ if (pie && pie.getExpandOffset() > 0) pie.pieClicked(this.dataPointIndex);
7161
+ (_b = this.w.globals.tooltip) == null ? void 0 : _b.markerClick(
7162
+ e,
7163
+ this.seriesIndex,
7164
+ this.dataPointIndex
7165
+ );
7103
7166
  }
7104
7167
  // ─── Helpers ──────────────────────────────────────────────────────────────
7105
7168
  _isNavEnabled() {
@@ -7123,8 +7186,8 @@ class KeyboardNavigation {
7123
7186
  if (type === "pie" || type === "donut" || type === "polarArea") {
7124
7187
  return w.seriesData.series.length;
7125
7188
  }
7126
- const series = w.seriesData.series;
7127
- return series[si] && Array.isArray(series[si]) ? series[si].length : 0;
7189
+ const s = w.seriesData.series[si];
7190
+ return Array.isArray(s) ? s.length : 1;
7128
7191
  }
7129
7192
  _clampCursor() {
7130
7193
  const seriesCount = this._getSeriesCount();