apexcharts 6.2.0 → 6.4.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 (115) hide show
  1. package/dist/apexcharts.common.js +2 -2
  2. package/dist/apexcharts.esm.js +1379 -212
  3. package/dist/apexcharts.js +1379 -212
  4. package/dist/apexcharts.min.js +2 -2
  5. package/dist/apexcharts.ssr.common.js +2 -2
  6. package/dist/apexcharts.ssr.esm.js +1379 -212
  7. package/dist/area.common.js +2 -2
  8. package/dist/area.esm.js +4 -4
  9. package/dist/bar.common.js +2 -2
  10. package/dist/bar.esm.js +208 -109
  11. package/dist/boxPlot.common.js +2 -2
  12. package/dist/boxPlot.esm.js +208 -109
  13. package/dist/bubble.common.js +2 -2
  14. package/dist/bubble.esm.js +4 -4
  15. package/dist/candlestick.common.js +2 -2
  16. package/dist/candlestick.esm.js +208 -109
  17. package/dist/column.common.js +2 -2
  18. package/dist/column.esm.js +208 -109
  19. package/dist/core.common.js +2 -2
  20. package/dist/core.esm.js +949 -137
  21. package/dist/donut.common.js +1 -1
  22. package/dist/donut.esm.js +1 -1
  23. package/dist/features/all.common.js +2 -2
  24. package/dist/features/all.esm.js +314 -28
  25. package/dist/features/annotations.common.js +1 -1
  26. package/dist/features/annotations.esm.js +1 -1
  27. package/dist/features/context-menu.common.js +1 -1
  28. package/dist/features/context-menu.esm.js +1 -1
  29. package/dist/features/drilldown.common.js +1 -1
  30. package/dist/features/drilldown.esm.js +1 -1
  31. package/dist/features/exports.common.js +1 -1
  32. package/dist/features/exports.esm.js +1 -1
  33. package/dist/features/facet.common.js +1 -1
  34. package/dist/features/facet.esm.js +1 -1
  35. package/dist/features/history.common.js +1 -1
  36. package/dist/features/history.esm.js +1 -1
  37. package/dist/features/ink.common.js +1 -1
  38. package/dist/features/ink.esm.js +1 -1
  39. package/dist/features/keyboard.common.js +1 -1
  40. package/dist/features/keyboard.esm.js +1 -1
  41. package/dist/features/legend.common.js +1 -1
  42. package/dist/features/legend.esm.js +1 -1
  43. package/dist/features/link.common.js +1 -1
  44. package/dist/features/link.esm.js +1 -1
  45. package/dist/features/marks.common.js +1 -1
  46. package/dist/features/marks.esm.js +1 -1
  47. package/dist/features/measure.common.js +1 -1
  48. package/dist/features/measure.esm.js +1 -1
  49. package/dist/features/morph.common.js +1 -1
  50. package/dist/features/morph.esm.js +1 -1
  51. package/dist/features/perspectives.common.js +1 -1
  52. package/dist/features/perspectives.esm.js +1 -1
  53. package/dist/features/renderer-canvas.common.js +2 -2
  54. package/dist/features/renderer-canvas.esm.js +294 -7
  55. package/dist/features/storyboard.common.js +1 -1
  56. package/dist/features/storyboard.esm.js +1 -1
  57. package/dist/features/toolbar.common.js +2 -2
  58. package/dist/features/toolbar.esm.js +19 -20
  59. package/dist/features/weave.common.js +1 -1
  60. package/dist/features/weave.esm.js +1 -1
  61. package/dist/heatmap.common.js +2 -2
  62. package/dist/heatmap.esm.js +79 -41
  63. package/dist/line.common.js +2 -2
  64. package/dist/line.esm.js +4 -4
  65. package/dist/pie.common.js +1 -1
  66. package/dist/pie.esm.js +1 -1
  67. package/dist/polarArea.common.js +1 -1
  68. package/dist/polarArea.esm.js +1 -1
  69. package/dist/radar.common.js +1 -1
  70. package/dist/radar.esm.js +1 -1
  71. package/dist/radialBar.common.js +1 -1
  72. package/dist/radialBar.esm.js +1 -1
  73. package/dist/rangeArea.common.js +2 -2
  74. package/dist/rangeArea.esm.js +4 -4
  75. package/dist/rangeBar.common.js +2 -2
  76. package/dist/rangeBar.esm.js +208 -109
  77. package/dist/scatter.common.js +2 -2
  78. package/dist/scatter.esm.js +4 -4
  79. package/dist/treemap.common.js +1 -1
  80. package/dist/treemap.esm.js +1 -1
  81. package/dist/violin.common.js +2 -2
  82. package/dist/violin.esm.js +208 -109
  83. package/package.json +1 -1
  84. package/src/apexcharts.js +307 -33
  85. package/src/charts/Bar.js +38 -6
  86. package/src/charts/HeatMap.js +126 -55
  87. package/src/charts/Line.js +7 -5
  88. package/src/charts/common/bar/DataLabels.js +16 -0
  89. package/src/modules/Core.js +19 -0
  90. package/src/modules/Crosshairs.js +24 -5
  91. package/src/modules/Data.js +212 -16
  92. package/src/modules/Filters.js +34 -6
  93. package/src/modules/Graphics.js +4 -4
  94. package/src/modules/Range.js +160 -32
  95. package/src/modules/Series.js +25 -0
  96. package/src/modules/ZoomPanSelection.js +16 -11
  97. package/src/modules/animations/AxisTransition.js +57 -15
  98. package/src/modules/animations/DataLabelTransition.js +235 -0
  99. package/src/modules/animations/LengthTransition.js +15 -2
  100. package/src/modules/axes/YAxis.js +21 -1
  101. package/src/modules/helpers/UpdateHelpers.js +16 -5
  102. package/src/modules/settings/Defaults.js +12 -1
  103. package/src/modules/settings/Globals.js +50 -1
  104. package/src/modules/settings/Options.js +16 -0
  105. package/src/modules/tooltip/AxesTooltip.js +7 -1
  106. package/src/modules/tooltip/Intersect.js +145 -32
  107. package/src/modules/tooltip/Labels.js +9 -0
  108. package/src/modules/tooltip/Tooltip.js +28 -7
  109. package/src/modules/tooltip/Utils.js +5 -1
  110. package/src/renderers/Renderer.js +8 -2
  111. package/src/renderers/canvas/CanvasCompositor.js +100 -1
  112. package/src/renderers/canvas/CanvasGraphics.js +184 -0
  113. package/src/renderers/canvas/CanvasRenderer.js +62 -6
  114. package/src/types/internal.d.ts +31 -0
  115. package/types/apexcharts.d.ts +30 -0
@@ -54,7 +54,7 @@ var __async = (__this, __arguments, generator) => {
54
54
  });
55
55
  };
56
56
  /*!
57
- * ApexCharts v6.2.0
57
+ * ApexCharts v6.4.0
58
58
  * (c) 2018-2026 ApexCharts
59
59
  */
60
60
 
@@ -2819,7 +2819,14 @@ var __async = (__this, __arguments, generator) => {
2819
2819
  heatmap() {
2820
2820
  return {
2821
2821
  chart: {
2822
- stacked: false
2822
+ stacked: false,
2823
+ // A heatmap is a fixed grid: zooming/panning only distorts the cells
2824
+ // and (on a datetime axis) collapses the month labels to repeats, so
2825
+ // it is off by default, mirroring treemap. Users can opt back in with
2826
+ // chart.zoom.enabled: true.
2827
+ zoom: {
2828
+ enabled: false
2829
+ }
2823
2830
  },
2824
2831
  fill: {
2825
2832
  opacity: 1
@@ -2833,7 +2840,11 @@ var __async = (__this, __arguments, generator) => {
2833
2840
  colors: ["#fff"]
2834
2841
  },
2835
2842
  tooltip: {
2836
- followCursor: true,
2843
+ // Anchor the tooltip above the hovered cell with a downward arrow
2844
+ // (flipping below near the top edge), the same treatment horizontal
2845
+ // bars get, rather than trailing the cursor. Opt back into the old
2846
+ // behavior with tooltip.followCursor: true.
2847
+ followCursor: false,
2837
2848
  marker: {
2838
2849
  show: false
2839
2850
  },
@@ -4514,6 +4525,20 @@ var __async = (__this, __arguments, generator) => {
4514
4525
  blur: 1,
4515
4526
  color: "#000",
4516
4527
  opacity: 0.8
4528
+ },
4529
+ // Ride data labels to their new position on a data-change update
4530
+ // (e.g. a bar chart race), instead of snapping. Off by default so
4531
+ // existing charts are unchanged. Speed/easing follow
4532
+ // chart.animations.dynamicAnimation. Bar/column only.
4533
+ animate: {
4534
+ enabled: false
4535
+ },
4536
+ // Count the numeric value up/down from its previous value on update,
4537
+ // like countUp.js. Off by default. The dataLabels.formatter runs each
4538
+ // frame, so number formatting (decimals, separators, prefixes) is
4539
+ // preserved. Bar/column only.
4540
+ countUp: {
4541
+ enabled: false
4517
4542
  }
4518
4543
  },
4519
4544
  fill: {
@@ -4705,13 +4730,15 @@ var __async = (__this, __arguments, generator) => {
4705
4730
  states: {
4706
4731
  hover: {
4707
4732
  filter: {
4708
- type: "lighten"
4733
+ type: "lighten",
4734
+ value: 0.15
4709
4735
  }
4710
4736
  },
4711
4737
  active: {
4712
4738
  allowMultipleDataPointsSelection: false,
4713
4739
  filter: {
4714
- type: "darken"
4740
+ type: "darken",
4741
+ value: 0.35
4715
4742
  }
4716
4743
  }
4717
4744
  },
@@ -5765,14 +5792,54 @@ var __async = (__this, __arguments, generator) => {
5765
5792
  globals
5766
5793
  );
5767
5794
  }
5795
+ /**
5796
+ * Lazy initial-series snapshot. Capturing `initialSeries` used to deep-clone
5797
+ * the entire series on every parse and every update: the single largest CPU
5798
+ * bucket at 50k+ points (profiled at ~23ms per 50k update). The setter now
5799
+ * stores a cheap per-series shallow copy (series OBJECTS copied, data arrays
5800
+ * shared) and the deep snapshot materializes only when something actually
5801
+ * reads it (resetSeries, toolbar reset-home, tooltip same-length check).
5802
+ *
5803
+ * Why sharing the data arrays is safe: internal "mutations" of a series'
5804
+ * data are property REPLACEMENTS (`series[i].data = []` on legend collapse),
5805
+ * which cannot reach the captured copies because each series object was
5806
+ * copied at capture time. The one in-place mutator (appendData's push loop)
5807
+ * re-captures immediately after mutating, so the pending snapshot never
5808
+ * spans the mutation.
5809
+ *
5810
+ * @param {Record<string, any>} globals
5811
+ */
5812
+ defineLazyInitialSeries(globals) {
5813
+ let src = [];
5814
+ let snap = null;
5815
+ Object.defineProperty(globals, "initialSeries", {
5816
+ configurable: true,
5817
+ enumerable: true,
5818
+ get() {
5819
+ if (snap === null) {
5820
+ snap = Utils$1.clone(src);
5821
+ }
5822
+ return snap;
5823
+ },
5824
+ set(value) {
5825
+ src = Array.isArray(value) ? value.map(
5826
+ (s) => s && typeof s === "object" && !Array.isArray(s) ? __spreadValues({}, s) : s
5827
+ ) : value;
5828
+ snap = null;
5829
+ globals._initialSeriesPeek = src;
5830
+ }
5831
+ });
5832
+ globals._initialSeriesPeek = src;
5833
+ }
5768
5834
  /**
5769
5835
  * @param {Record<string, any>} config
5770
5836
  */
5771
5837
  init(config) {
5772
5838
  const globals = this.globalVars(config);
5773
5839
  this.initGlobalVars(globals);
5840
+ this.defineLazyInitialSeries(globals);
5774
5841
  globals.initialConfig = Utils$1.extend({}, config);
5775
- globals.initialSeries = Utils$1.clone(config.series);
5842
+ globals.initialSeries = config.series;
5776
5843
  globals.lastXAxis = Utils$1.clone(
5777
5844
  /** @type {NonNullable<typeof globals.initialConfig>} */
5778
5845
  globals.initialConfig.xaxis
@@ -8151,6 +8218,7 @@ var __async = (__this, __arguments, generator) => {
8151
8218
  });
8152
8219
  }
8153
8220
  }
8221
+ const DEFAULT_INTENSITY = { lighten: 0.15, darken: 0.35 };
8154
8222
  class Filters {
8155
8223
  /**
8156
8224
  * @param {import('../types/internal').ChartStateW} w
@@ -8176,8 +8244,9 @@ var __async = (__this, __arguments, generator) => {
8176
8244
  * @param {any} el
8177
8245
  * @param {number} i
8178
8246
  * @param {string} filterType
8247
+ * @param {number} [intensity] Blend strength (0 to 1). Defaults per type.
8179
8248
  */
8180
- applyFilter(el, i, filterType) {
8249
+ applyFilter(el, i, filterType, intensity) {
8181
8250
  var _a, _b, _c;
8182
8251
  const w = this.w;
8183
8252
  if (el.unfilter) {
@@ -8188,15 +8257,21 @@ var __async = (__this, __arguments, generator) => {
8188
8257
  return;
8189
8258
  }
8190
8259
  const shadowAttr = w.config.chart.dropShadow;
8191
- const brightnessFactor = filterType === "lighten" ? 2 : 0.3;
8260
+ const fallback = filterType === "lighten" ? DEFAULT_INTENSITY.lighten : DEFAULT_INTENSITY.darken;
8261
+ const t = Math.max(
8262
+ 0,
8263
+ Math.min(1, typeof intensity === "number" ? intensity : fallback)
8264
+ );
8265
+ const diag = 1 - t;
8266
+ const offset = filterType === "lighten" ? t : 0;
8192
8267
  if (el.filterWith) {
8193
8268
  el.filterWith((add) => {
8194
8269
  add.colorMatrix({
8195
8270
  type: "matrix",
8196
8271
  values: `
8197
- ${brightnessFactor} 0 0 0 0
8198
- 0 ${brightnessFactor} 0 0 0
8199
- 0 0 ${brightnessFactor} 0 0
8272
+ ${diag} 0 0 0 ${offset}
8273
+ 0 ${diag} 0 0 ${offset}
8274
+ 0 0 ${diag} 0 ${offset}
8200
8275
  0 0 0 1 0
8201
8276
  `,
8202
8277
  in: "SourceGraphic",
@@ -8295,7 +8370,7 @@ var __async = (__this, __arguments, generator) => {
8295
8370
  el.node.setAttribute("selected", true);
8296
8371
  const activeFilter = w.config.states.active.filter;
8297
8372
  if (activeFilter !== "none") {
8298
- this.applyFilter(el, realIndex, activeFilter.type);
8373
+ this.applyFilter(el, realIndex, activeFilter.type, activeFilter.value);
8299
8374
  }
8300
8375
  }
8301
8376
  }
@@ -9134,7 +9209,7 @@ var __async = (__this, __arguments, generator) => {
9134
9209
  if (w.config.states.hover.filter.type !== "none") {
9135
9210
  if (!w.interact.isTouchDevice) {
9136
9211
  const hoverFilter = w.config.states.hover.filter;
9137
- filters.applyFilter(path, i, hoverFilter.type);
9212
+ filters.applyFilter(path, i, hoverFilter.type, hoverFilter.value);
9138
9213
  }
9139
9214
  }
9140
9215
  }
@@ -9219,12 +9294,12 @@ var __async = (__this, __arguments, generator) => {
9219
9294
  if (selected === "true") {
9220
9295
  const activeFilter = w.config.states.active.filter;
9221
9296
  if (activeFilter !== "none") {
9222
- filters.applyFilter(path, i, activeFilter.type);
9297
+ filters.applyFilter(path, i, activeFilter.type, activeFilter.value);
9223
9298
  } else {
9224
9299
  if (w.config.states.hover.filter !== "none") {
9225
9300
  if (!w.interact.isTouchDevice) {
9226
9301
  const hoverFilter = w.config.states.hover.filter;
9227
- filters.applyFilter(path, i, hoverFilter.type);
9302
+ filters.applyFilter(path, i, hoverFilter.type, hoverFilter.value);
9228
9303
  }
9229
9304
  }
9230
9305
  }
@@ -9232,7 +9307,7 @@ var __async = (__this, __arguments, generator) => {
9232
9307
  if (w.config.states.active.filter.type !== "none") {
9233
9308
  if (w.config.states.hover.filter.type !== "none" && !w.interact.isTouchDevice) {
9234
9309
  const hoverFilter = w.config.states.hover.filter;
9235
- filters.applyFilter(path, i, hoverFilter.type);
9310
+ filters.applyFilter(path, i, hoverFilter.type, hoverFilter.value);
9236
9311
  } else {
9237
9312
  filters.getDefaultFilter(path, i);
9238
9313
  }
@@ -9871,12 +9946,13 @@ var __async = (__this, __arguments, generator) => {
9871
9946
  const markerSize = w.config.markers && w.config.markers.size;
9872
9947
  const markersOn = Array.isArray(markerSize) ? markerSize.some((s) => s > 0) : (markerSize || 0) > 0;
9873
9948
  const labelsOn = !!(w.config.dataLabels && w.config.dataLabels.enabled);
9949
+ const isHeatmap = type === "heatmap";
9874
9950
  let total = 0;
9875
9951
  let maxLen = 0;
9876
9952
  series.forEach((s) => {
9877
9953
  const n = Array.isArray(s.data) ? s.data.length : 0;
9878
9954
  if (n > maxLen) maxLen = n;
9879
- if (scatterish || markersOn) total += n;
9955
+ if (scatterish || markersOn || isHeatmap) total += n;
9880
9956
  if (labelsOn) total += n;
9881
9957
  });
9882
9958
  const LARGE_D = 5e4;
@@ -12728,7 +12804,7 @@ var __async = (__this, __arguments, generator) => {
12728
12804
  * @param {number | null} [endingSeriesIndex]
12729
12805
  */
12730
12806
  getMinYMaxY(startingSeriesIndex, lowestY = Number.MAX_VALUE, highestY = -Number.MAX_VALUE, endingSeriesIndex = null) {
12731
- var _a, _b, _c, _d, _e, _f, _g, _h;
12807
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
12732
12808
  const cnf = this.w.config;
12733
12809
  const gl = this.w.globals;
12734
12810
  let maxY = -Number.MAX_VALUE;
@@ -12792,14 +12868,68 @@ var __async = (__this, __arguments, generator) => {
12792
12868
  }
12793
12869
  }
12794
12870
  }
12871
+ const plainNumeric = seriesMin === series && seriesMax === series && cnf.chart.type !== "boxPlot" && seriesType !== "candlestick" && seriesType !== "boxPlot" && seriesType !== "violin" && seriesType !== "rangeArea" && seriesType !== "rangeBar" && !(this.w.seriesData.seriesGoals[i] && this.w.seriesData.seriesGoals[i].length);
12872
+ if (plainNumeric) {
12873
+ const arr = series[i];
12874
+ const jEnd = Math.min(lastXIndex, arr.length - 1);
12875
+ const pe = (_b = this.w.seriesData._parsedExtrema) == null ? void 0 : _b[i];
12876
+ if (pe && pe.ref === arr && pe.len === arr.length && firstXIndex === 0 && jEnd === arr.length - 1) {
12877
+ if (pe.maxY > maxY) maxY = pe.maxY;
12878
+ if (pe.lowestY < lowestY) lowestY = pe.lowestY;
12879
+ if (pe.negMinY < 0 && pe.negMinY < minY) minY = pe.negMinY;
12880
+ if (pe.yDec > gl.yValueDecimal) gl.yValueDecimal = pe.yDec;
12881
+ if (pe.hasNulls) gl.hasNullValues = true;
12882
+ } else {
12883
+ let yDec = gl.yValueDecimal;
12884
+ let hasNulls = false;
12885
+ for (let j = firstXIndex; j <= jEnd; j++) {
12886
+ const val = arr[j];
12887
+ if (val !== null && typeof val === "number" && val === val && val !== Infinity && val !== -Infinity) {
12888
+ if (val > maxY) maxY = val;
12889
+ if (val < lowestY) lowestY = val;
12890
+ if (minY > val && val < 0) minY = val;
12891
+ if (!Number.isInteger(val)) {
12892
+ const av = val < 0 ? -val : val;
12893
+ if (av >= 1e-6 && av < 1e21) {
12894
+ const str = "" + val;
12895
+ const dot = str.indexOf(".");
12896
+ const dec = dot === -1 ? 0 : str.length - dot - 1;
12897
+ if (dec > yDec) yDec = dec;
12898
+ } else {
12899
+ const nv = Utils$1.noExponents(val);
12900
+ if (Utils$1.isFloat(nv)) {
12901
+ yDec = Math.max(yDec, nv.toString().split(".")[1].length);
12902
+ }
12903
+ }
12904
+ }
12905
+ } else {
12906
+ hasNulls = true;
12907
+ }
12908
+ }
12909
+ gl.yValueDecimal = yDec;
12910
+ if (hasNulls) gl.hasNullValues = true;
12911
+ }
12912
+ highestY = maxY;
12913
+ if (seriesType === "bar" || seriesType === "column") {
12914
+ if (minY < 0 && maxY < 0) {
12915
+ maxY = 0;
12916
+ highestY = Math.max(highestY, 0);
12917
+ }
12918
+ if (minY === Number.MIN_VALUE) {
12919
+ minY = 0;
12920
+ lowestY = Math.min(lowestY, 0);
12921
+ }
12922
+ }
12923
+ continue;
12924
+ }
12795
12925
  for (let j = firstXIndex; j <= lastXIndex && j < this.w.seriesData.series[i].length; j++) {
12796
12926
  let val = series[i][j];
12797
12927
  if (val !== null && Utils$1.isNumber(val)) {
12798
- if (typeof ((_b = seriesMax[i]) == null ? void 0 : _b[j]) !== "undefined") {
12928
+ if (typeof ((_c = seriesMax[i]) == null ? void 0 : _c[j]) !== "undefined") {
12799
12929
  maxY = Math.max(maxY, seriesMax[i][j]);
12800
12930
  lowestY = Math.min(lowestY, seriesMax[i][j]);
12801
12931
  }
12802
- if (typeof ((_c = seriesMin[i]) == null ? void 0 : _c[j]) !== "undefined") {
12932
+ if (typeof ((_d = seriesMin[i]) == null ? void 0 : _d[j]) !== "undefined") {
12803
12933
  lowestY = Math.min(lowestY, seriesMin[i][j]);
12804
12934
  highestY = Math.max(highestY, seriesMin[i][j]);
12805
12935
  }
@@ -12828,7 +12958,7 @@ var __async = (__this, __arguments, generator) => {
12828
12958
  break;
12829
12959
  case "violin":
12830
12960
  {
12831
- if (typeof ((_d = this.w.violinData.seriesViolinMax[i]) == null ? void 0 : _d[j]) !== "undefined") {
12961
+ if (typeof ((_e = this.w.violinData.seriesViolinMax[i]) == null ? void 0 : _e[j]) !== "undefined") {
12832
12962
  maxY = Math.max(maxY, this.w.violinData.seriesViolinMax[i][j]);
12833
12963
  lowestY = Math.min(
12834
12964
  lowestY,
@@ -12851,7 +12981,7 @@ var __async = (__this, __arguments, generator) => {
12851
12981
  );
12852
12982
  }
12853
12983
  if (this.w.config.chart.type === "boxPlot" || seriesType === "boxPlot") {
12854
- const boxPts = (_f = (_e = this.w.candleData.seriesBoxPoints) == null ? void 0 : _e[i]) == null ? void 0 : _f[j];
12984
+ const boxPts = (_g = (_f = this.w.candleData.seriesBoxPoints) == null ? void 0 : _f[i]) == null ? void 0 : _g[j];
12855
12985
  if (boxPts) {
12856
12986
  for (let p = 0; p < boxPts.length; p++) {
12857
12987
  const pv = boxPts[p];
@@ -12870,7 +13000,7 @@ var __async = (__this, __arguments, generator) => {
12870
13000
  val.toString().split(".")[1].length
12871
13001
  );
12872
13002
  }
12873
- if (minY > ((_g = seriesMin[i]) == null ? void 0 : _g[j]) && ((_h = seriesMin[i]) == null ? void 0 : _h[j]) < 0) {
13003
+ if (minY > ((_h = seriesMin[i]) == null ? void 0 : _h[j]) && ((_i = seriesMin[i]) == null ? void 0 : _i[j]) < 0) {
12874
13004
  minY = seriesMin[i][j];
12875
13005
  }
12876
13006
  } else {
@@ -13024,38 +13154,33 @@ var __async = (__this, __arguments, generator) => {
13024
13154
  const cnf = this.w.config;
13025
13155
  const isXNumeric = cnf.xaxis.type === "numeric" || cnf.xaxis.type === "datetime" || cnf.xaxis.type === "category" && !this.w.axisFlags.noLabelsProvided || this.w.axisFlags.noLabelsProvided || this.w.axisFlags.isXNumeric;
13026
13156
  const getInitialMinXMaxX = () => {
13157
+ var _a;
13158
+ let minX = gl.minX;
13159
+ let maxX = gl.maxX;
13027
13160
  for (let i = 0; i < this.w.seriesData.series.length; i++) {
13028
- if (this.w.labelData.labels[i]) {
13029
- for (let j = 0; j < this.w.labelData.labels[i].length; j++) {
13030
- if (this.w.labelData.labels[i][j] !== null && Utils$1.isNumber(this.w.labelData.labels[i][j])) {
13031
- gl.maxX = Math.max(
13032
- gl.maxX,
13033
- /** @type {number} */
13034
- /** @type {any} */
13035
- this.w.labelData.labels[i][j]
13036
- );
13037
- gl.initialMaxX = Math.max(
13038
- gl.maxX,
13039
- /** @type {number} */
13040
- /** @type {any} */
13041
- this.w.labelData.labels[i][j]
13042
- );
13043
- gl.minX = Math.min(
13044
- gl.minX,
13045
- /** @type {number} */
13046
- /** @type {any} */
13047
- this.w.labelData.labels[i][j]
13048
- );
13049
- gl.initialMinX = Math.min(
13050
- gl.minX,
13051
- /** @type {number} */
13052
- /** @type {any} */
13053
- this.w.labelData.labels[i][j]
13054
- );
13055
- }
13161
+ const lbls = (
13162
+ /** @type {any} */
13163
+ this.w.labelData.labels[i]
13164
+ );
13165
+ if (!lbls) continue;
13166
+ const pe = (_a = this.w.seriesData._parsedExtrema) == null ? void 0 : _a[i];
13167
+ if (pe && pe.xNumeric && pe.xref === lbls && pe.len === lbls.length) {
13168
+ if (pe.maxX > maxX) maxX = pe.maxX;
13169
+ if (pe.minX < minX) minX = pe.minX;
13170
+ continue;
13171
+ }
13172
+ for (let j = 0; j < lbls.length; j++) {
13173
+ const v = lbls[j];
13174
+ if (v !== null && typeof v === "number" && v === v) {
13175
+ if (v > maxX) maxX = v;
13176
+ if (v < minX) minX = v;
13056
13177
  }
13057
13178
  }
13058
13179
  }
13180
+ gl.maxX = maxX;
13181
+ gl.initialMaxX = maxX;
13182
+ gl.minX = minX;
13183
+ gl.initialMinX = minX;
13059
13184
  };
13060
13185
  if (this.w.axisFlags.isXNumeric) {
13061
13186
  getInitialMinXMaxX();
@@ -13197,13 +13322,40 @@ var __async = (__this, __arguments, generator) => {
13197
13322
  _getMinXDiff() {
13198
13323
  const gl = this.w.globals;
13199
13324
  if (this.w.axisFlags.isXNumeric) {
13200
- this.w.seriesData.seriesX.forEach((sX) => {
13325
+ this.w.seriesData.seriesX.forEach((sX, si) => {
13326
+ var _a;
13201
13327
  if (sX.length) {
13202
13328
  if (sX.length === 1) {
13203
13329
  sX.push(
13204
13330
  this.w.seriesData.seriesX[gl.maxValsInArrayIndex][this.w.seriesData.seriesX[gl.maxValsInArrayIndex].length - 1]
13205
13331
  );
13206
13332
  }
13333
+ const pe = (_a = this.w.seriesData._parsedExtrema) == null ? void 0 : _a[si];
13334
+ if (pe && pe.xNumeric && pe.xSorted && pe.xref === sX && pe.len === sX.length) {
13335
+ if (pe.minXDiff < gl.minXDiff) gl.minXDiff = pe.minXDiff;
13336
+ if (gl.dataPoints === 1 || gl.minXDiff === Number.MAX_VALUE) {
13337
+ gl.minXDiff = 0.5;
13338
+ }
13339
+ return;
13340
+ }
13341
+ let presorted = true;
13342
+ let minDiff = gl.minXDiff;
13343
+ for (let j = 1; j < sX.length; j++) {
13344
+ const d = sX[j] - sX[j - 1];
13345
+ if (d > 0) {
13346
+ if (d < minDiff) minDiff = d;
13347
+ } else if (d < 0) {
13348
+ presorted = false;
13349
+ break;
13350
+ }
13351
+ }
13352
+ if (presorted) {
13353
+ gl.minXDiff = minDiff;
13354
+ if (gl.dataPoints === 1 || gl.minXDiff === Number.MAX_VALUE) {
13355
+ gl.minXDiff = 0.5;
13356
+ }
13357
+ return;
13358
+ }
13207
13359
  const seriesX = sX.slice();
13208
13360
  seriesX.sort((a, b) => a - b);
13209
13361
  seriesX.forEach((s, j) => {
@@ -13362,6 +13514,13 @@ var __async = (__this, __arguments, generator) => {
13362
13514
  realIndex,
13363
13515
  w.globals.yAxisScale[realIndex].result.slice()
13364
13516
  );
13517
+ let labelStep = 1;
13518
+ if (w.config.chart.type === "heatmap" && !w.config.yaxis[realIndex].labels.formatter) {
13519
+ const fs = parseInt(yaxisFontSize, 10) || 11;
13520
+ const maxLabels = Math.max(1, Math.floor(w.layout.gridHeight / (fs * 1.4)));
13521
+ const count = tickAmount + 1;
13522
+ if (count > maxLabels) labelStep = Math.ceil(count / maxLabels);
13523
+ }
13365
13524
  if (w.config.yaxis[realIndex].labels.show) {
13366
13525
  let lY = w.layout.translateY + w.config.yaxis[realIndex].labels.offsetY;
13367
13526
  if (w.globals.isBarHorizontal) lY = 0;
@@ -13369,7 +13528,8 @@ var __async = (__this, __arguments, generator) => {
13369
13528
  lY += parseInt(yaxisFontSize, 10) / 3;
13370
13529
  let firstLabel = null;
13371
13530
  for (let i = tickAmount; i >= 0; i--) {
13372
- const val = lbFormatter(labels[i], i, w);
13531
+ const thinned = labelStep > 1 && i % labelStep !== 0;
13532
+ const val = thinned ? "" : lbFormatter(labels[i], i, w);
13373
13533
  let xPad = w.config.yaxis[realIndex].labels.padding;
13374
13534
  if (w.config.yaxis[realIndex].opposite && w.config.yaxis.length !== 0)
13375
13535
  xPad *= -1;
@@ -13980,6 +14140,7 @@ var __async = (__this, __arguments, generator) => {
13980
14140
  }
13981
14141
  drawXCrosshairs() {
13982
14142
  const w = this.w;
14143
+ w.dom.elGraphical.node.querySelectorAll(":scope > .apexcharts-xcrosshairs").forEach((el) => el.remove());
13983
14144
  const graphics = new Graphics(this.w);
13984
14145
  const filters = new Filters(this.w);
13985
14146
  const crosshairGradient = w.config.xaxis.crosshairs.fill.gradient;
@@ -14011,10 +14172,7 @@ var __async = (__this, __arguments, generator) => {
14011
14172
  []
14012
14173
  );
14013
14174
  }
14014
- let xcrosshairs = graphics.drawRect();
14015
- if (w.config.xaxis.crosshairs.width === 1) {
14016
- xcrosshairs = graphics.drawLine(0, 0, 0, 0);
14017
- }
14175
+ let xcrosshairs = w.config.xaxis.crosshairs.width === 1 ? graphics.drawLine(0, 0, 0, 0) : graphics.drawRect();
14018
14176
  let gridHeight = w.layout.gridHeight;
14019
14177
  if (!Utils$1.isNumber(gridHeight) || gridHeight < 0) {
14020
14178
  gridHeight = 0;
@@ -14051,6 +14209,9 @@ var __async = (__this, __arguments, generator) => {
14051
14209
  }
14052
14210
  drawYCrosshairs() {
14053
14211
  const w = this.w;
14212
+ w.dom.elGraphical.node.querySelectorAll(
14213
+ ":scope > .apexcharts-ycrosshairs, :scope > .apexcharts-ycrosshairs-hidden"
14214
+ ).forEach((el) => el.remove());
14054
14215
  const graphics = new Graphics(this.w);
14055
14216
  const crosshair = (
14056
14217
  /** @type {any[]} */
@@ -14603,7 +14764,7 @@ var __async = (__this, __arguments, generator) => {
14603
14764
  return count === 0 ? k : `${k}#${count}`;
14604
14765
  });
14605
14766
  }
14606
- function seriesJoin(w, realIndex, includeIdentity = false) {
14767
+ function seriesJoin(w, realIndex, includeIdentity = false, allowReorder = false) {
14607
14768
  var _a, _b;
14608
14769
  if (!lengthTransitionEnabled(w)) return null;
14609
14770
  const frame = w.globals.prevStreamFrame;
@@ -14617,7 +14778,7 @@ var __async = (__this, __arguments, generator) => {
14617
14778
  );
14618
14779
  const newKeys = uniquifyKeys(newY.map((_, j) => datumKey(w, realIndex, j)));
14619
14780
  const join = joinKeys(oldKeys, newKeys);
14620
- if (!join.ordered) return null;
14781
+ if (!join.ordered && !allowReorder) return null;
14621
14782
  if (!join.changed && !includeIdentity) return null;
14622
14783
  return { join, oldKeys, newKeys };
14623
14784
  }
@@ -14926,7 +15087,7 @@ var __async = (__this, __arguments, generator) => {
14926
15087
  gl.prevChromeFrame = null;
14927
15088
  }
14928
15089
  }
14929
- function fadeIn(w, node, duration, ease) {
15090
+ function fadeIn$1(w, node, duration, ease) {
14930
15091
  const style = (
14931
15092
  /** @type {any} */
14932
15093
  node.style
@@ -15023,34 +15184,59 @@ var __async = (__this, __arguments, generator) => {
15023
15184
  const spanHi = Math.max(...spanPs);
15024
15185
  const margin = Math.max(40, (spanHi - spanLo) * 0.25);
15025
15186
  const clamp = (p) => Math.max(spanLo - margin, Math.min(spanHi + margin, p));
15187
+ const tweenPairedLine = (line, old) => {
15188
+ if (!line) return;
15189
+ const lineTo = parseFloat(line.getAttribute(lineAttrs[0]) || "");
15190
+ const lineFrom = oldLines[old.i];
15191
+ if (isFinite(lineTo) && isFinite(lineFrom)) {
15192
+ tweenPos(w, line, lineAttrs, lineFrom, lineTo, duration, ease);
15193
+ }
15194
+ };
15026
15195
  newLabels.forEach((label, i) => {
15027
15196
  const to = parseFloat(label.getAttribute(posAttr) || "");
15028
15197
  const old = oldByText.get(label.textContent || "");
15029
15198
  const line = newLinesAligned ? newLines[i] : null;
15030
15199
  if (old) matchedOld.add(old.i);
15031
- if (!old || !isFinite(old.pos) || old.transform || label.getAttribute("transform")) {
15200
+ const labelTransform = label.getAttribute("transform");
15201
+ if (!old || !isFinite(old.pos)) {
15032
15202
  if (!old) {
15033
- if (project && isFinite(to) && !label.getAttribute("transform")) {
15203
+ if (project && isFinite(to) && !labelTransform) {
15034
15204
  const from = isFinite(project.toOld(to)) ? clamp(project.toOld(to)) : NaN;
15035
15205
  if (isFinite(from) && Math.abs(from - to) > 0.5) {
15036
15206
  tweenPos(w, label, [posAttr], from, to, duration, ease);
15037
15207
  if (line) tweenPos(w, line, lineAttrs, from, to, duration, ease);
15038
15208
  }
15039
15209
  }
15040
- fadeIn(w, label, duration, ease);
15041
- if (line) fadeIn(w, line, duration, ease);
15210
+ fadeIn$1(w, label, duration, ease);
15211
+ if (line) fadeIn$1(w, line, duration, ease);
15042
15212
  }
15043
15213
  return;
15044
15214
  }
15045
15215
  if (!isFinite(to) || Math.abs(old.pos - to) < 0.5) return;
15046
- tweenPos(w, label, [posAttr], old.pos, to, duration, ease);
15047
- if (line) {
15048
- const lineTo = parseFloat(line.getAttribute(lineAttrs[0]) || "");
15049
- const lineFrom = oldLines[old.i];
15050
- if (isFinite(lineTo) && isFinite(lineFrom)) {
15051
- tweenPos(w, line, lineAttrs, lineFrom, lineTo, duration, ease);
15216
+ if (labelTransform || old.transform) {
15217
+ const delta = old.pos - to;
15218
+ if (isFinite(delta)) {
15219
+ const base = labelTransform || "";
15220
+ rafTween(
15221
+ w,
15222
+ duration,
15223
+ ease,
15224
+ (eased) => {
15225
+ const v = delta * (1 - eased);
15226
+ const t = posAttr === "x" ? `translate(${v} 0)` : `translate(0 ${v})`;
15227
+ label.setAttribute("transform", `${t} ${base}`.trim());
15228
+ },
15229
+ () => {
15230
+ if (base) label.setAttribute("transform", base);
15231
+ else label.removeAttribute("transform");
15232
+ }
15233
+ );
15052
15234
  }
15235
+ tweenPairedLine(line, old);
15236
+ return;
15053
15237
  }
15238
+ tweenPos(w, label, [posAttr], old.pos, to, duration, ease);
15239
+ tweenPairedLine(line, old);
15054
15240
  });
15055
15241
  if (!project || !newLabels.length) return;
15056
15242
  let ghosts = 0;
@@ -15089,7 +15275,7 @@ var __async = (__this, __arguments, generator) => {
15089
15275
  if (!chrome || !gl.axisCharts || !Environment.isBrowser()) return;
15090
15276
  if (!lengthTransitionEnabled(w)) return;
15091
15277
  const anyMotion = (w.seriesData.series || []).some(
15092
- (_, i) => seriesJoin(w, i, true) !== null
15278
+ (_, i) => seriesJoin(w, i, true, true) !== null
15093
15279
  );
15094
15280
  if (!anyMotion) return;
15095
15281
  const root = w.dom.baseEl;
@@ -15133,6 +15319,158 @@ var __async = (__this, __arguments, generator) => {
15133
15319
  } catch (_) {
15134
15320
  }
15135
15321
  }
15322
+ const DL_GROUP_SEL = ".apexcharts-data-labels[data\\:dlKey]";
15323
+ const DL_TEXT_SEL = ".apexcharts-datalabel";
15324
+ function dataLabelMotionEnabled(w) {
15325
+ var _a, _b;
15326
+ const dl = w.config.dataLabels;
15327
+ return !!(((_a = dl == null ? void 0 : dl.animate) == null ? void 0 : _a.enabled) || ((_b = dl == null ? void 0 : dl.countUp) == null ? void 0 : _b.enabled));
15328
+ }
15329
+ function decimalsOf(n) {
15330
+ if (!isFinite(n)) return 0;
15331
+ const s = String(n);
15332
+ const dot = s.indexOf(".");
15333
+ return dot === -1 ? 0 : Math.min(6, s.length - dot - 1);
15334
+ }
15335
+ function writeLabel(textEl, s) {
15336
+ const tspan = textEl.querySelector("tspan");
15337
+ if (tspan) tspan.textContent = s;
15338
+ else textEl.textContent = s;
15339
+ }
15340
+ function captureDataLabels(w) {
15341
+ const gl = w.globals;
15342
+ gl.prevDataLabels = null;
15343
+ if (!gl.axisCharts || !Environment.isBrowser()) return;
15344
+ if (!dataLabelMotionEnabled(w)) return;
15345
+ const root = w.dom.baseEl;
15346
+ if (!Utils$1.elementExists(root)) return;
15347
+ try {
15348
+ const map = /* @__PURE__ */ new Map();
15349
+ root.querySelectorAll(DL_GROUP_SEL).forEach((group) => {
15350
+ const key = group.getAttribute("data:dlKey");
15351
+ if (!key) return;
15352
+ const textEl = group.querySelector(DL_TEXT_SEL);
15353
+ if (!textEl) return;
15354
+ map.set(key, {
15355
+ cx: parseFloat(textEl.getAttribute("cx") || ""),
15356
+ cy: parseFloat(textEl.getAttribute("cy") || ""),
15357
+ val: parseFloat(group.getAttribute("data:dlVal") || "")
15358
+ });
15359
+ });
15360
+ gl.prevDataLabels = map.size ? map : null;
15361
+ } catch (_) {
15362
+ gl.prevDataLabels = null;
15363
+ }
15364
+ }
15365
+ function fadeIn(w, node, duration, ease) {
15366
+ const style = (
15367
+ /** @type {any} */
15368
+ node.style
15369
+ );
15370
+ style.opacity = "0";
15371
+ rafTween(
15372
+ w,
15373
+ duration,
15374
+ ease,
15375
+ (eased) => {
15376
+ style.opacity = String(eased);
15377
+ },
15378
+ () => {
15379
+ style.opacity = "";
15380
+ }
15381
+ );
15382
+ }
15383
+ function applyDataLabelTransition(w) {
15384
+ var _a, _b;
15385
+ const gl = w.globals;
15386
+ const prev = gl.prevDataLabels;
15387
+ gl.prevDataLabels = null;
15388
+ if (!prev || !gl.axisCharts || !Environment.isBrowser()) return;
15389
+ if (!dataLabelMotionEnabled(w)) return;
15390
+ if (!lengthTransitionEnabled(w)) return;
15391
+ const root = w.dom.baseEl;
15392
+ if (!Utils$1.elementExists(root)) return;
15393
+ const dl = w.config.dataLabels;
15394
+ const ride = !!((_a = dl.animate) == null ? void 0 : _a.enabled);
15395
+ const countUp = !!((_b = dl.countUp) == null ? void 0 : _b.enabled);
15396
+ const formatter = dl.formatter;
15397
+ const duration = Math.max(1, w.config.chart.animations.dynamicAnimation.speed || 1);
15398
+ const ease = morphEasing(w);
15399
+ try {
15400
+ root.querySelectorAll(DL_GROUP_SEL).forEach((group) => {
15401
+ const key = group.getAttribute("data:dlKey");
15402
+ if (!key) return;
15403
+ const textEl = group.querySelector(DL_TEXT_SEL);
15404
+ if (!textEl) return;
15405
+ const old = prev.get(key);
15406
+ if (ride) {
15407
+ if (old && isFinite(old.cx) && isFinite(old.cy)) {
15408
+ const newCx = parseFloat(textEl.getAttribute("cx") || "");
15409
+ const newCy = parseFloat(textEl.getAttribute("cy") || "");
15410
+ const dx = old.cx - newCx;
15411
+ const dy = old.cy - newCy;
15412
+ if (isFinite(dx) && isFinite(dy) && Math.abs(dx) + Math.abs(dy) > 0.5) {
15413
+ const base = group.getAttribute("transform") || "";
15414
+ rafTween(
15415
+ w,
15416
+ duration,
15417
+ ease,
15418
+ (eased) => {
15419
+ const t = 1 - eased;
15420
+ group.setAttribute(
15421
+ "transform",
15422
+ `translate(${dx * t} ${dy * t}) ${base}`.trim()
15423
+ );
15424
+ },
15425
+ () => {
15426
+ group.setAttribute("transform", base);
15427
+ }
15428
+ );
15429
+ }
15430
+ } else if (!old) {
15431
+ fadeIn(w, group, duration, ease);
15432
+ }
15433
+ }
15434
+ if (countUp && old && isFinite(old.val)) {
15435
+ const newVal = parseFloat(group.getAttribute("data:dlVal") || "");
15436
+ if (isFinite(newVal) && Math.abs(newVal - old.val) > 1e-9) {
15437
+ const from = old.val;
15438
+ const dec = Math.max(decimalsOf(from), decimalsOf(newVal));
15439
+ const realIndex = parseInt(key, 10);
15440
+ const j = parseInt(group.getAttribute("data:dlJ") || "", 10);
15441
+ const format = (v) => {
15442
+ const rounded = Number(v.toFixed(dec));
15443
+ let out = rounded;
15444
+ if (typeof formatter === "function") {
15445
+ try {
15446
+ out = formatter(rounded, __spreadProps(__spreadValues({}, w), {
15447
+ seriesIndex: realIndex,
15448
+ dataPointIndex: isFinite(j) ? j : 0,
15449
+ w
15450
+ }));
15451
+ } catch (_) {
15452
+ out = rounded;
15453
+ }
15454
+ }
15455
+ return String(out);
15456
+ };
15457
+ rafTween(
15458
+ w,
15459
+ duration,
15460
+ ease,
15461
+ (eased) => {
15462
+ writeLabel(textEl, format(from + (newVal - from) * eased));
15463
+ },
15464
+ () => {
15465
+ writeLabel(textEl, format(newVal));
15466
+ }
15467
+ );
15468
+ }
15469
+ }
15470
+ });
15471
+ } catch (_) {
15472
+ }
15473
+ }
15136
15474
  class Series {
15137
15475
  /**
15138
15476
  * @param {import('../types/internal').ChartStateW} w
@@ -15241,6 +15579,24 @@ var __async = (__this, __arguments, generator) => {
15241
15579
  (_a = this._toggleDataSeries) == null ? void 0 : _a.call(this, isSeriesHidden.realIndex, false);
15242
15580
  }
15243
15581
  }
15582
+ /**
15583
+ * Cheap pre-update reset for the data-replacement paths (updateSeries /
15584
+ * appendSeries). Clears the same bookkeeping resetSeries() clears (series
15585
+ * cache, previous paths, collapsed-series state) WITHOUT restoring
15586
+ * config.series from the initialSeries snapshot: the caller is about to
15587
+ * replace the series anyway (parseData assigns config.series = newSeries),
15588
+ * so materializing and cloning the snapshot per update is pure waste (two
15589
+ * O(n) deep clones per streaming tick at 50k points).
15590
+ */
15591
+ prepareDataUpdate() {
15592
+ const w = this.w;
15593
+ this.clearSeriesCache();
15594
+ w.globals.previousPaths = [];
15595
+ w.globals.collapsedSeries = [];
15596
+ w.globals.ancillaryCollapsedSeries = [];
15597
+ w.globals.collapsedSeriesIndices = [];
15598
+ w.globals.ancillaryCollapsedSeriesIndices = [];
15599
+ }
15244
15600
  resetSeries(shouldUpdateChart = true, shouldResetZoom = true, shouldResetCollapsed = true) {
15245
15601
  var _a, _b;
15246
15602
  const w = this.w;
@@ -15488,6 +15844,7 @@ var __async = (__this, __arguments, generator) => {
15488
15844
  const w = this.w;
15489
15845
  captureStreamFrame(w);
15490
15846
  captureAxisChrome(w);
15847
+ captureDataLabels(w);
15491
15848
  if (!w.globals.axisCharts) {
15492
15849
  w.globals.previousPaths = w.seriesData.series;
15493
15850
  return;
@@ -17742,6 +18099,24 @@ var __async = (__this, __arguments, generator) => {
17742
18099
  }
17743
18100
  }
17744
18101
  if (canvasMode) {
18102
+ const rr = (
18103
+ /** @type {any} */
18104
+ ctx.renderer
18105
+ );
18106
+ if (rr && rr._repaintHostInPlace) {
18107
+ rr._repaintHostInPlace = false;
18108
+ const wrapNode = this.w.dom.elGraphical.node.querySelector(
18109
+ ".apexcharts-canvas-series-wrap"
18110
+ );
18111
+ if (wrapNode && rr.canRepaintInPlace && rr.canRepaintInPlace()) {
18112
+ rr.repaintInPlace();
18113
+ const groups = Array.isArray(elGraph) ? elGraph : [elGraph];
18114
+ groups.forEach((g) => {
18115
+ if (g && g.node) wrapNode.appendChild(g.node);
18116
+ });
18117
+ return [];
18118
+ }
18119
+ }
17745
18120
  const host = ctx.renderer.present();
17746
18121
  if (host) {
17747
18122
  const wrap = new Graphics(w).group({
@@ -18139,6 +18514,108 @@ var __async = (__this, __arguments, generator) => {
18139
18514
  const firstDataPoint = this.getFirstDataPoint();
18140
18515
  return firstDataPoint && Array.isArray(firstDataPoint);
18141
18516
  }
18517
+ /**
18518
+ * Typed single pass for the dominant [[x, y], ...] shape: scalar numeric or
18519
+ * null y, no z, no OHLC tuples. One monomorphic loop fills preallocated
18520
+ * x/y arrays and fuses the y-extrema scan that Range.getMinYMaxY would
18521
+ * otherwise repeat over every value (the extrema entry is ref+length
18522
+ * guarded, so any later reshaping of the series array simply falls back to
18523
+ * the scan). Returns false untouched on any non-conforming point so the
18524
+ * general loop below handles mixed/exotic data with unchanged output.
18525
+ * @param {any[]} data
18526
+ * @param {number} i
18527
+ * @returns {boolean}
18528
+ */
18529
+ _fast2DArrayParse(data, i) {
18530
+ var _a, _b;
18531
+ const n = data.length;
18532
+ if (n === 0) return false;
18533
+ const ys = new Array(n);
18534
+ const xs = new Array(n);
18535
+ let maxY = -Number.MAX_VALUE;
18536
+ let lowestY = Number.MAX_VALUE;
18537
+ let negMinY = Infinity;
18538
+ let hasNulls = false;
18539
+ let yDec = 0;
18540
+ let xNumeric = true;
18541
+ let minX = Infinity;
18542
+ let maxX = -Infinity;
18543
+ let xSorted = true;
18544
+ let minXDiff = Infinity;
18545
+ let prevX = NaN;
18546
+ for (let j = 0; j < n; j++) {
18547
+ const point = data[j];
18548
+ if (!Array.isArray(point) || point.length > 2) return false;
18549
+ const x = point[0];
18550
+ const y = point[1];
18551
+ if (xNumeric) {
18552
+ if (typeof x === "number") {
18553
+ if (x === x) {
18554
+ if (x < minX) minX = x;
18555
+ if (x > maxX) maxX = x;
18556
+ }
18557
+ const d = x - prevX;
18558
+ if (d > 0) {
18559
+ if (d < minXDiff) minXDiff = d;
18560
+ } else if (d < 0) {
18561
+ xSorted = false;
18562
+ }
18563
+ prevX = x;
18564
+ } else {
18565
+ xNumeric = false;
18566
+ }
18567
+ }
18568
+ if (typeof y === "number") {
18569
+ if (y === y && y !== Infinity && y !== -Infinity) {
18570
+ if (y > maxY) maxY = y;
18571
+ if (y < lowestY) lowestY = y;
18572
+ if (y < 0 && y < negMinY) negMinY = y;
18573
+ if (!Number.isInteger(y)) {
18574
+ const av = y < 0 ? -y : y;
18575
+ if (av >= 1e-6 && av < 1e21) {
18576
+ const str = "" + y;
18577
+ const dot = str.indexOf(".");
18578
+ const dec = dot === -1 ? 0 : str.length - dot - 1;
18579
+ if (dec > yDec) yDec = dec;
18580
+ } else {
18581
+ const nv = Utils$1.noExponents(y);
18582
+ if (Utils$1.isFloat(nv)) {
18583
+ yDec = Math.max(yDec, nv.toString().split(".")[1].length);
18584
+ }
18585
+ }
18586
+ }
18587
+ } else {
18588
+ hasNulls = true;
18589
+ }
18590
+ } else if (y === null) {
18591
+ hasNulls = true;
18592
+ } else {
18593
+ return false;
18594
+ }
18595
+ ys[j] = y;
18596
+ xs[j] = x;
18597
+ }
18598
+ this.twoDSeries = ys;
18599
+ this.twoDSeriesX = xs;
18600
+ this.w.axisFlags.dataFormatXNumeric = true;
18601
+ const extrema = (_b = (_a = this.w.seriesData)._parsedExtrema) != null ? _b : _a._parsedExtrema = [];
18602
+ extrema[i] = {
18603
+ ref: ys,
18604
+ len: n,
18605
+ maxY,
18606
+ lowestY,
18607
+ negMinY,
18608
+ hasNulls,
18609
+ yDec,
18610
+ xref: xs,
18611
+ xNumeric,
18612
+ minX,
18613
+ maxX,
18614
+ xSorted,
18615
+ minXDiff
18616
+ };
18617
+ return true;
18618
+ }
18142
18619
  /**
18143
18620
  * @param {any[]} ser
18144
18621
  * @param {number} i
@@ -18148,6 +18625,9 @@ var __async = (__this, __arguments, generator) => {
18148
18625
  const data = ser[i].data;
18149
18626
  const isBoxPlot = cnf.chart.type === "boxPlot" || /** @type {any} */
18150
18627
  cnf.series[i].type === "boxPlot";
18628
+ if (!isBoxPlot && cnf.xaxis.type !== "datetime" && this._fast2DArrayParse(data, i)) {
18629
+ return;
18630
+ }
18151
18631
  for (let j = 0; j < data.length; j++) {
18152
18632
  const point = data[j];
18153
18633
  const x = point[0];
@@ -18544,6 +19024,7 @@ var __async = (__this, __arguments, generator) => {
18544
19024
  const cnf = this.w.config;
18545
19025
  const gl = this.w.globals;
18546
19026
  const dt = new DateTime(this.w);
19027
+ this.w.seriesData._parsedExtrema = [];
18547
19028
  const xlabels = cnf.labels.length > 0 ? cnf.labels.slice() : cnf.xaxis.categories.slice();
18548
19029
  this.w.axisFlags.isRangeBar = cnf.chart.type === "rangeBar" && gl.isBarHorizontal;
18549
19030
  this.w.labelData.hasXaxisGroups = cnf.xaxis.type === "category" && cnf.xaxis.group.groups.length > 0;
@@ -18933,7 +19414,11 @@ var __async = (__this, __arguments, generator) => {
18933
19414
  if (this.w.axisFlags.dataWasParsed) {
18934
19415
  return series;
18935
19416
  }
18936
- if (!globalParsing && !series.some((s) => s.parsing)) {
19417
+ const hasGlobalParsing = !!(globalParsing && (globalParsing.x || globalParsing.y || globalParsing.z));
19418
+ const hasSeriesParsing = series.some(
19419
+ (s) => s.parsing && (s.parsing.x || s.parsing.y || s.parsing.z)
19420
+ );
19421
+ if (!hasGlobalParsing && !hasSeriesParsing) {
18937
19422
  return series;
18938
19423
  }
18939
19424
  const processedSeries = series.map((serie, index) => {
@@ -19200,7 +19685,7 @@ var __async = (__this, __arguments, generator) => {
19200
19685
  * @param {any[]} ser
19201
19686
  */
19202
19687
  parseData(ser) {
19203
- var _a, _b, _c, _d, _e, _f;
19688
+ var _a, _b, _c, _d, _e, _f, _g;
19204
19689
  const w = this.w;
19205
19690
  const cnf = w.config;
19206
19691
  const gl = w.globals;
@@ -19226,8 +19711,11 @@ var __async = (__this, __arguments, generator) => {
19226
19711
  gl.dataReducerRawMaxX = rawMaxX;
19227
19712
  }
19228
19713
  }
19229
- cnf.series = ser;
19230
19714
  if (gl.dataReducerRawSeries && ((_f = cnf.chart.dataReducer) == null ? void 0 : _f.enabled)) {
19715
+ ser = ser.map((s) => __spreadValues({}, s));
19716
+ }
19717
+ cnf.series = ser;
19718
+ if (gl.dataReducerRawSeries && ((_g = cnf.chart.dataReducer) == null ? void 0 : _g.enabled)) {
19231
19719
  const stash = gl.dataReducerRawSeries;
19232
19720
  gl.initialSeries = ser.map((s, i) => {
19233
19721
  var _a2, _b2, _c2;
@@ -19236,7 +19724,7 @@ var __async = (__this, __arguments, generator) => {
19236
19724
  });
19237
19725
  });
19238
19726
  } else {
19239
- gl.initialSeries = Utils$1.clone(ser);
19727
+ gl.initialSeries = ser;
19240
19728
  }
19241
19729
  this.excludeCollapsedSeriesInYAxis();
19242
19730
  this.fallbackToCategory = false;
@@ -19256,10 +19744,23 @@ var __async = (__this, __arguments, generator) => {
19256
19744
  }
19257
19745
  this.coreUtils.getSeriesTotals();
19258
19746
  if (gl.axisCharts) {
19259
- this.w.seriesData.stackedSeriesTotals = this.coreUtils.getStackedSeriesTotals();
19260
- this.w.seriesData.stackedSeriesTotalsByGroups = this.coreUtils.getStackedSeriesTotalsByGroups();
19747
+ Data._defineLazyResult(
19748
+ this.w.seriesData,
19749
+ "stackedSeriesTotals",
19750
+ () => this.coreUtils.getStackedSeriesTotals()
19751
+ );
19752
+ Data._defineLazyResult(
19753
+ this.w.seriesData,
19754
+ "stackedSeriesTotalsByGroups",
19755
+ () => this.coreUtils.getStackedSeriesTotalsByGroups()
19756
+ );
19757
+ Data._defineLazyResult(gl, "seriesPercent", () => {
19758
+ this.coreUtils.getPercentSeries();
19759
+ return gl.seriesPercent;
19760
+ });
19761
+ } else {
19762
+ this.coreUtils.getPercentSeries();
19261
19763
  }
19262
- this.coreUtils.getPercentSeries();
19263
19764
  if (!this.w.axisFlags.dataFormatXNumeric && (!this.w.axisFlags.isXNumeric || cnf.xaxis.type === "numeric" && cnf.labels.length === 0 && cnf.xaxis.categories.length === 0)) {
19264
19765
  this.handleExternalLabelsData(ser);
19265
19766
  }
@@ -19272,6 +19773,12 @@ var __async = (__this, __arguments, generator) => {
19272
19773
  }
19273
19774
  return {
19274
19775
  // w.seriesData (future slice)
19776
+ // initialSeries/originalSeries and the stacked totals are deliberately
19777
+ // ABSENT: they already live as lazy accessors on gl / w.seriesData, so
19778
+ // a snapshot field would either force their materialization (a deep
19779
+ // clone plus three O(n) passes per parse that most charts never need)
19780
+ // or, as a delegating getter, recurse into itself when a writer copies
19781
+ // it back onto the object it delegates to.
19275
19782
  seriesData: {
19276
19783
  series: this.w.seriesData.series,
19277
19784
  seriesNames: this.w.seriesData.seriesNames,
@@ -19279,10 +19786,6 @@ var __async = (__this, __arguments, generator) => {
19279
19786
  seriesZ: this.w.seriesData.seriesZ,
19280
19787
  seriesColors: this.w.seriesData.seriesColors,
19281
19788
  seriesGoals: this.w.seriesData.seriesGoals,
19282
- initialSeries: gl.initialSeries,
19283
- originalSeries: gl.originalSeries,
19284
- stackedSeriesTotals: this.w.seriesData.stackedSeriesTotals,
19285
- stackedSeriesTotalsByGroups: this.w.seriesData.stackedSeriesTotalsByGroups,
19286
19789
  noLabelsProvided: this.w.axisFlags.noLabelsProvided
19287
19790
  },
19288
19791
  // w.rangeData (future slice)
@@ -19331,6 +19834,40 @@ var __async = (__this, __arguments, generator) => {
19331
19834
  * @param {number|null|undefined} xmax
19332
19835
  * @returns {any[]} Sliced array (new array, never the input reference).
19333
19836
  */
19837
+ /**
19838
+ * Define `key` on `obj` as a lazily computed property: `compute` runs on
19839
+ * first read after this call and its result is cached; assigning to the
19840
+ * property stores the assigned value directly (so code that writes the
19841
+ * field, like getPercentSeries, keeps working). Re-calling resets the cache
19842
+ * (used once per parse).
19843
+ * @param {any} obj
19844
+ * @param {string} key
19845
+ * @param {() => any} compute
19846
+ */
19847
+ static _defineLazyResult(obj, key, compute) {
19848
+ let has = false;
19849
+ let value;
19850
+ Object.defineProperty(obj, key, {
19851
+ configurable: true,
19852
+ enumerable: true,
19853
+ get() {
19854
+ if (!has) {
19855
+ has = true;
19856
+ value = compute();
19857
+ }
19858
+ return value;
19859
+ },
19860
+ set(v) {
19861
+ has = true;
19862
+ value = v;
19863
+ }
19864
+ });
19865
+ }
19866
+ /**
19867
+ * @param {any[]} data
19868
+ * @param {any} xmin
19869
+ * @param {any} xmax
19870
+ */
19334
19871
  static sliceByXRange(data, xmin, xmax) {
19335
19872
  const len = data.length;
19336
19873
  if (len === 0) return data;
@@ -19554,7 +20091,7 @@ var __async = (__this, __arguments, generator) => {
19554
20091
  if (!redraw) {
19555
20092
  w.globals.resized = true;
19556
20093
  w.globals.dataChanged = true;
19557
- if (animate) {
20094
+ if (animate && w.config.chart.animations.enabled) {
19558
20095
  ch.series.getPreviousPaths();
19559
20096
  }
19560
20097
  }
@@ -19600,7 +20137,7 @@ var __async = (__this, __arguments, generator) => {
19600
20137
  w.globals.lastXAxis = options2.xaxis ? Utils$1.clone(options2.xaxis) : [];
19601
20138
  w.globals.lastYAxis = options2.yaxis ? Utils$1.clone(options2.yaxis) : [];
19602
20139
  w.globals.initialConfig = Utils$1.extend({}, w.config);
19603
- w.globals.initialSeries = Utils$1.clone(w.config.series);
20140
+ w.globals.initialSeries = w.config.series;
19604
20141
  if (options2.series) {
19605
20142
  for (let i = 0; i < w.globals.collapsedSeriesIndices.length; i++) {
19606
20143
  const series = w.config.series[w.globals.collapsedSeriesIndices[i]];
@@ -19645,7 +20182,7 @@ var __async = (__this, __arguments, generator) => {
19645
20182
  xMax: w.globals.maxX
19646
20183
  });
19647
20184
  PerformanceCache.invalidateSelectors(w);
19648
- if (animate) {
20185
+ if (animate && w.config.chart.animations.enabled) {
19649
20186
  this.ctx.series.getPreviousPaths();
19650
20187
  }
19651
20188
  const prevSeriesCount = w.config.series.length;
@@ -19665,15 +20202,16 @@ var __async = (__this, __arguments, generator) => {
19665
20202
  this.ctx._writeParsedAxisFlags(parsedState.axisFlags);
19666
20203
  if (overwriteInitialSeries) {
19667
20204
  if (w.globals.initialConfig) {
19668
- w.globals.initialConfig.series = Utils$1.clone(w.config.series);
20205
+ w.globals.initialConfig.series = w.config.series;
19669
20206
  }
19670
- w.globals.initialSeries = Utils$1.clone(w.config.series);
20207
+ w.globals.initialSeries = w.config.series;
19671
20208
  }
19672
20209
  if (this._canUseFastPath(newSeries, prevSeriesCount, prevDataLengths, w)) {
19673
20210
  return this.ctx.fastUpdate(animate, prevAxisScaleSig).then(() => {
19674
20211
  resolve(this.ctx);
19675
20212
  });
19676
20213
  }
20214
+ if (this.ctx._updateStats) this.ctx._updateStats.full++;
19677
20215
  return this.ctx.update().then(() => {
19678
20216
  resolve(this.ctx);
19679
20217
  });
@@ -20196,11 +20734,11 @@ var __async = (__this, __arguments, generator) => {
20196
20734
  return false;
20197
20735
  }
20198
20736
  isInitialSeriesSameLen() {
20199
- var _a, _b, _c;
20737
+ var _a, _b, _c, _d;
20200
20738
  let sameLen = true;
20201
20739
  const initialSeries = (
20202
20740
  /** @type {any[]} */
20203
- ((_a = this.w.globals.initialSeries) == null ? void 0 : _a.filter(
20741
+ ((_b = (_a = this.w.globals._initialSeriesPeek) != null ? _a : this.w.globals.initialSeries) == null ? void 0 : _b.filter(
20204
20742
  /**
20205
20743
  * @param {Record<string, any>} s
20206
20744
  * @param {number} i
@@ -20212,7 +20750,7 @@ var __async = (__this, __arguments, generator) => {
20212
20750
  )) || []
20213
20751
  );
20214
20752
  for (let i = 0; i < initialSeries.length - 1; i++) {
20215
- if (!((_b = initialSeries[i]) == null ? void 0 : _b.data) || !((_c = initialSeries[i + 1]) == null ? void 0 : _c.data)) return true;
20753
+ if (!((_c = initialSeries[i]) == null ? void 0 : _c.data) || !((_d = initialSeries[i + 1]) == null ? void 0 : _d.data)) return true;
20216
20754
  if (initialSeries[i].data.length !== initialSeries[i + 1].data.length) {
20217
20755
  sameLen = false;
20218
20756
  break;
@@ -20818,12 +21356,14 @@ var __async = (__this, __arguments, generator) => {
20818
21356
  w
20819
21357
  });
20820
21358
  if (tooltipEl) {
21359
+ const arrowEl = tooltipEl.querySelector(".apexcharts-tooltip-arrow");
20821
21360
  if (typeof customTooltip === "string" || typeof customTooltip === "number") {
20822
21361
  tooltipEl.innerHTML = String(customTooltip);
20823
21362
  } else if (customTooltip instanceof Element || typeof customTooltip.nodeName === "string") {
20824
21363
  tooltipEl.innerHTML = "";
20825
21364
  tooltipEl.appendChild(customTooltip.cloneNode(true));
20826
21365
  }
21366
+ if (arrowEl) tooltipEl.appendChild(arrowEl);
20827
21367
  }
20828
21368
  }
20829
21369
  }
@@ -21676,33 +22216,107 @@ var __async = (__this, __arguments, generator) => {
21676
22216
  var _a, _b;
21677
22217
  const ttCtx = this.ttCtx;
21678
22218
  const w = this.w;
21679
- if (e.target.classList.contains(`apexcharts-${type}-rect`)) {
21680
- const i = this.getAttr(e, "i");
21681
- const j = this.getAttr(e, "j");
21682
- const cx = this.getAttr(e, "cx");
21683
- const cy = this.getAttr(e, "cy");
21684
- const width = this.getAttr(e, "width");
21685
- const height = this.getAttr(e, "height");
21686
- ttCtx.tooltipLabels.drawSeriesTexts({
21687
- ttItems: opt.ttItems,
21688
- i,
21689
- j,
21690
- shared: false,
21691
- e
21692
- });
21693
- w.interact.capturedSeriesIndex = i;
21694
- w.interact.capturedDataPointIndex = j;
21695
- x = cx + ttCtx.tooltipRect.ttWidth / 2 + width;
21696
- y = cy + ttCtx.tooltipRect.ttHeight / 2 - height / 2;
21697
- ttCtx.tooltipPosition.moveXCrosshairs(cx + width / 2);
21698
- if (x > w.layout.gridWidth / 2) {
21699
- x = cx - ttCtx.tooltipRect.ttWidth / 2 + width;
21700
- }
21701
- if (ttCtx.w.config.tooltip.followCursor) {
21702
- const seriesBound = w.dom.elWrap.getBoundingClientRect();
21703
- x = ((_a = w.interact.clientX) != null ? _a : 0) - seriesBound.left - (x > w.layout.gridWidth / 2 ? ttCtx.tooltipRect.ttWidth : 0);
21704
- y = ((_b = w.interact.clientY) != null ? _b : 0) - seriesBound.top - (y > w.layout.gridHeight / 2 ? ttCtx.tooltipRect.ttHeight : 0);
22219
+ const renderer = w.globals.activeRenderer;
22220
+ const canvasCells = type === "heatmap" && renderer && renderer.kind === "canvas" && typeof renderer.hitTest === "function";
22221
+ let i, j, cx, cy, width, height;
22222
+ if (canvasCells) {
22223
+ const seriesBound = opt.elGrid.getBoundingClientRect();
22224
+ const clientX = e.type === "touchmove" ? e.touches[0].clientX : e.clientX;
22225
+ const clientY = e.type === "touchmove" ? e.touches[0].clientY : e.clientY;
22226
+ const hit = renderer.hitTest(
22227
+ clientX - seriesBound.left,
22228
+ clientY - seriesBound.top
22229
+ );
22230
+ if (!hit) {
22231
+ return { x, y, noHit: true };
22232
+ }
22233
+ i = hit.seriesIndex;
22234
+ j = hit.dataPointIndex;
22235
+ cx = hit.x;
22236
+ cy = hit.y;
22237
+ width = hit.width;
22238
+ height = hit.height;
22239
+ } else if (e.target.classList.contains(`apexcharts-${type}-rect`)) {
22240
+ i = this.getAttr(e, "i");
22241
+ j = this.getAttr(e, "j");
22242
+ cx = this.getAttr(e, "cx");
22243
+ cy = this.getAttr(e, "cy");
22244
+ width = this.getAttr(e, "width");
22245
+ height = this.getAttr(e, "height");
22246
+ } else {
22247
+ return { x, y };
22248
+ }
22249
+ ttCtx.tooltipLabels.drawSeriesTexts({
22250
+ ttItems: opt.ttItems,
22251
+ i,
22252
+ j,
22253
+ shared: false,
22254
+ e
22255
+ });
22256
+ w.interact.capturedSeriesIndex = i;
22257
+ w.interact.capturedDataPointIndex = j;
22258
+ ttCtx.tooltipPosition.moveXCrosshairs(cx + width / 2);
22259
+ const tooltipEl = ttCtx.getElTooltip();
22260
+ if (type === "heatmap" && w.config.tooltip.arrow && !w.config.tooltip.followCursor && tooltipEl) {
22261
+ const elGridRect = opt.elGrid.getBoundingClientRect();
22262
+ const elWrapRect = w.dom.elWrap.getBoundingClientRect();
22263
+ const gridOffsetXInElWrap = elGridRect.left - elWrapRect.left;
22264
+ let clLeft, clTop, clRight, clBottom;
22265
+ if (canvasCells) {
22266
+ clLeft = cx;
22267
+ clTop = cy;
22268
+ clRight = cx + width;
22269
+ clBottom = cy + height;
22270
+ } else {
22271
+ const r = e.target.getBoundingClientRect();
22272
+ clLeft = r.left - elGridRect.left;
22273
+ clTop = r.top - elGridRect.top;
22274
+ clRight = r.right - elGridRect.left;
22275
+ clBottom = r.bottom - elGridRect.top;
22276
+ }
22277
+ const ttW = ttCtx.tooltipRect.ttWidth || 0;
22278
+ const ttH = ttCtx.tooltipRect.ttHeight || 0;
22279
+ const ARROW_TIP_OVERHANG = 7;
22280
+ const cellCenterXInElWrap = (clLeft + clRight) / 2 + gridOffsetXInElWrap;
22281
+ const cellTopInElWrap = clTop + w.layout.translateY;
22282
+ const cellBottomInElWrap = clBottom + w.layout.translateY;
22283
+ const gridTop = w.layout.translateY;
22284
+ const gridBottom = w.layout.translateY + w.layout.gridHeight;
22285
+ const gridLeft = gridOffsetXInElWrap;
22286
+ const gridRight = gridOffsetXInElWrap + w.layout.gridWidth;
22287
+ let placement = "top";
22288
+ let finalY = cellTopInElWrap - ttH - ARROW_TIP_OVERHANG;
22289
+ if (finalY < gridTop) {
22290
+ const belowTop = cellBottomInElWrap + ARROW_TIP_OVERHANG;
22291
+ if (belowTop + ttH <= gridBottom) {
22292
+ placement = "bottom";
22293
+ finalY = belowTop;
22294
+ } else {
22295
+ finalY = gridTop;
22296
+ }
21705
22297
  }
22298
+ let finalX = cellCenterXInElWrap - ttW / 2;
22299
+ if (finalX < gridLeft) finalX = gridLeft;
22300
+ if (finalX + ttW > gridRight) finalX = gridRight - ttW;
22301
+ const arrowX = Math.max(10, Math.min(ttW - 10, cellCenterXInElWrap - finalX));
22302
+ ttCtx.tooltipPosition.applyTooltipPosition(tooltipEl, {
22303
+ x: finalX,
22304
+ y: finalY,
22305
+ placement,
22306
+ arrowY: null,
22307
+ arrowX
22308
+ });
22309
+ return { x: finalX, y: finalY, positioned: true };
22310
+ }
22311
+ x = cx + ttCtx.tooltipRect.ttWidth / 2 + width;
22312
+ y = cy + ttCtx.tooltipRect.ttHeight / 2 - height / 2;
22313
+ if (x > w.layout.gridWidth / 2) {
22314
+ x = cx - ttCtx.tooltipRect.ttWidth / 2 + width;
22315
+ }
22316
+ if (ttCtx.w.config.tooltip.followCursor) {
22317
+ const seriesBound = w.dom.elWrap.getBoundingClientRect();
22318
+ x = ((_a = w.interact.clientX) != null ? _a : 0) - seriesBound.left - (x > w.layout.gridWidth / 2 ? ttCtx.tooltipRect.ttWidth : 0);
22319
+ y = ((_b = w.interact.clientY) != null ? _b : 0) - seriesBound.top - (y > w.layout.gridHeight / 2 ? ttCtx.tooltipRect.ttHeight : 0);
21706
22320
  }
21707
22321
  return {
21708
22322
  x,
@@ -22076,7 +22690,7 @@ var __async = (__this, __arguments, generator) => {
22076
22690
  const tooltipCssClass = isRight ? `apexcharts-yaxistooltip apexcharts-yaxistooltip-${i} apexcharts-yaxistooltip-right` : `apexcharts-yaxistooltip apexcharts-yaxistooltip-${i} apexcharts-yaxistooltip-left`;
22077
22691
  const renderTo = w.dom.elWrap;
22078
22692
  const yaxisTooltip = w.dom.baseEl.querySelector(
22079
- `.apexcharts-yaxistooltip apexcharts-yaxistooltip-${i}`
22693
+ `.apexcharts-yaxistooltip.apexcharts-yaxistooltip-${i}`
22080
22694
  );
22081
22695
  if (yaxisTooltip === null) {
22082
22696
  ttCtx.yaxisTooltip = BrowserAPIs.createElementNS(
@@ -22341,7 +22955,7 @@ var __async = (__this, __arguments, generator) => {
22341
22955
  this.tConfig.style.background
22342
22956
  );
22343
22957
  }
22344
- const isSharedMulti = this.tConfig.shared && w.config.series.length > 1 && !w.globals.isBarHorizontal;
22958
+ const isSharedMulti = this.tConfig.shared && w.config.series.length > 1 && !w.globals.isBarHorizontal && w.config.chart.type !== "heatmap";
22345
22959
  const shouldDrawArrow = this.tConfig.arrow && !this.tConfig.followCursor && !this.tConfig.fixed.enabled && !isSharedMulti && !this.tConfig.fillSeriesColor && w.globals.axisCharts;
22346
22960
  if (shouldDrawArrow) {
22347
22961
  const arrowEl = BrowserAPIs.createElementNS(
@@ -22518,6 +23132,8 @@ var __async = (__this, __arguments, generator) => {
22518
23132
  this.addPathsEventListeners([hoverArea], seriesHoverParams);
22519
23133
  } else if (commonBar && !w.globals.comboCharts || chartWithmarkers && this.showOnIntersect) {
22520
23134
  this.addDatapointEventsListeners(seriesHoverParams);
23135
+ } else if (type === "heatmap" && w.globals.activeRenderer && w.globals.activeRenderer.kind === "canvas") {
23136
+ this.addPathsEventListeners([hoverArea], seriesHoverParams);
22521
23137
  } else if (!w.globals.axisCharts || type === "heatmap" || type === "treemap") {
22522
23138
  const seriesAll = w.dom.baseEl.querySelectorAll(".apexcharts-series");
22523
23139
  this.addPathsEventListeners(seriesAll, seriesHoverParams);
@@ -22767,10 +23383,16 @@ var __async = (__this, __arguments, generator) => {
22767
23383
  y,
22768
23384
  type: w.config.chart.type
22769
23385
  });
23386
+ if (markerXY.noHit) {
23387
+ this.handleMouseOut(opt);
23388
+ return;
23389
+ }
22770
23390
  x = markerXY.x;
22771
23391
  y = markerXY.y;
22772
- tooltipEl.style.left = x + "px";
22773
- tooltipEl.style.top = y + "px";
23392
+ if (!markerXY.positioned) {
23393
+ tooltipEl.style.left = x + "px";
23394
+ tooltipEl.style.top = y + "px";
23395
+ }
22774
23396
  } else {
22775
23397
  if (this.tooltipUtil.hasBars()) {
22776
23398
  this.intersect.handleBarTooltip({
@@ -24786,6 +25408,8 @@ var __async = (__this, __arguments, generator) => {
24786
25408
  /** @type {any} */
24787
25409
  __publicField(this, "_keyboardNavigation");
24788
25410
  /** @type {any} */
25411
+ __publicField(this, "_zoomPanSelection");
25412
+ /** @type {any} */
24789
25413
  __publicField(this, "windowResizeHandler");
24790
25414
  /** @type {any} */
24791
25415
  __publicField(this, "parentResizeHandler");
@@ -24827,6 +25451,7 @@ var __async = (__this, __arguments, generator) => {
24827
25451
  const initCtx = new InitCtxVariables(this);
24828
25452
  initCtx.initModules();
24829
25453
  this.lastUpdateOptions = null;
25454
+ this._updateStats = { fast: 0, fastWithAxes: 0, full: 0 };
24830
25455
  this.create = this.create.bind(this);
24831
25456
  if (Environment.isBrowser()) {
24832
25457
  this.windowResizeHandler = this._windowResizeHandler.bind(this);
@@ -25207,7 +25832,7 @@ var __async = (__this, __arguments, generator) => {
25207
25832
  if (Utils$1.shallowEqual(this.lastUpdateOptions, options2)) {
25208
25833
  return Promise.resolve(this);
25209
25834
  }
25210
- if (options2.series && this.lastUpdateOptions.series) {
25835
+ if (options2.series && this.lastUpdateOptions.series && !_ApexCharts._optionsTooBigToCompare(options2)) {
25211
25836
  if (JSON.stringify(this.lastUpdateOptions.series) === JSON.stringify(options2.series)) {
25212
25837
  const optionsWithoutSeries = __spreadValues({}, options2);
25213
25838
  const lastWithoutSeries = __spreadValues({}, this.lastUpdateOptions);
@@ -25261,7 +25886,7 @@ var __async = (__this, __arguments, generator) => {
25261
25886
  */
25262
25887
  updateSeries(newSeries = [], animate = true, overwriteInitialSeries = true) {
25263
25888
  this.data.resetParsingFlags();
25264
- this.series.resetSeries(false);
25889
+ this.series.prepareDataUpdate();
25265
25890
  this.updateHelpers.revertDefaultAxisMinMax();
25266
25891
  return this.updateHelpers._updateSeries(
25267
25892
  newSeries,
@@ -25284,7 +25909,7 @@ var __async = (__this, __arguments, generator) => {
25284
25909
  /** @type {any} */
25285
25910
  newSerie
25286
25911
  );
25287
- this.series.resetSeries(false);
25912
+ this.series.prepareDataUpdate();
25288
25913
  this.updateHelpers.revertDefaultAxisMinMax();
25289
25914
  return this.updateHelpers._updateSeries(
25290
25915
  newSeries,
@@ -25304,7 +25929,9 @@ var __async = (__this, __arguments, generator) => {
25304
25929
  const me = this;
25305
25930
  me.data.resetParsingFlags();
25306
25931
  me.w.globals.dataChanged = true;
25307
- me.series.getPreviousPaths();
25932
+ if (me.w.config.chart.animations.enabled) {
25933
+ me.series.getPreviousPaths();
25934
+ }
25308
25935
  const newSeries = me.w.config.series.slice();
25309
25936
  for (let i = 0; i < newSeries.length; i++) {
25310
25937
  if (newData[i] !== null && typeof newData[i] !== "undefined") {
@@ -25324,19 +25951,37 @@ var __async = (__this, __arguments, generator) => {
25324
25951
  trimStreamingSeries(newSeries, me.w);
25325
25952
  me.w.config.series = newSeries;
25326
25953
  if (overwriteInitialSeries) {
25327
- me.w.globals.initialSeries = Utils$1.clone(me.w.config.series);
25954
+ me.w.globals.initialSeries = me.w.config.series;
25328
25955
  }
25329
25956
  return this.update();
25330
25957
  }
25958
+ /**
25959
+ * True when an options object carries enough series data that a
25960
+ * JSON.stringify equality check (and the Utils.clone needed to store it for
25961
+ * later comparison) would cost more than the re-render it tries to avoid.
25962
+ * @param {any} options
25963
+ * @returns {boolean}
25964
+ */
25965
+ static _optionsTooBigToCompare(options2) {
25966
+ const series = options2 && options2.series;
25967
+ if (!Array.isArray(series)) return false;
25968
+ let points = 0;
25969
+ for (let i = 0; i < series.length; i++) {
25970
+ const d = series[i] && series[i].data;
25971
+ points += Array.isArray(d) ? d.length : 1;
25972
+ if (points > 1e3) return true;
25973
+ }
25974
+ return false;
25975
+ }
25331
25976
  /**
25332
25977
  * @param {object} [options]
25333
25978
  */
25334
25979
  update(options2) {
25335
25980
  return new Promise((resolve, reject) => {
25336
- if (this.lastUpdateOptions && JSON.stringify(this.lastUpdateOptions) === JSON.stringify(options2)) {
25981
+ if (options2 && this.lastUpdateOptions && !_ApexCharts._optionsTooBigToCompare(options2) && JSON.stringify(this.lastUpdateOptions) === JSON.stringify(options2)) {
25337
25982
  return resolve(this);
25338
25983
  }
25339
- this.lastUpdateOptions = Utils$1.clone(options2);
25984
+ this.lastUpdateOptions = options2 && !_ApexCharts._optionsTooBigToCompare(options2) ? Utils$1.clone(options2) : null;
25340
25985
  new Destroy(this.ctx).clear({ isUpdating: true });
25341
25986
  const graphData = this.create(this.w.config.series, options2 != null ? options2 : {});
25342
25987
  if (!graphData) return resolve(this);
@@ -25344,6 +25989,7 @@ var __async = (__this, __arguments, generator) => {
25344
25989
  var _a;
25345
25990
  (_a = this.morphTypeChange) == null ? void 0 : _a.applyChromeFade();
25346
25991
  applyAxisTransition(this.w);
25992
+ applyDataLabelTransition(this.w);
25347
25993
  if (typeof this.w.config.chart.events.updated === "function") {
25348
25994
  this.w.config.chart.events.updated(this, this.w);
25349
25995
  }
@@ -25355,6 +26001,140 @@ var __async = (__this, __arguments, generator) => {
25355
26001
  });
25356
26002
  });
25357
26003
  }
26004
+ /**
26005
+ * Redraws the scale-dependent chrome (grid lines, x-axis, y-axes) IN PLACE
26006
+ * within the frozen layout after a data-only update changed the axis
26007
+ * domain. The rebuilt groups replace the old nodes positionally, so z-order
26008
+ * (grid back/front) is preserved without re-running mount. Legend,
26009
+ * annotations containers, toolbar, defs/masks, and the plot geometry are
26010
+ * untouched.
26011
+ *
26012
+ * Returns false when the refresh cannot faithfully reproduce the chart and
26013
+ * the caller must fall back to a full render:
26014
+ * - horizontal bar charts (inversed axes draw through a different path)
26015
+ * - charts with annotations or ink notes (their positions are scale-bound
26016
+ * and are laid out by the full render)
26017
+ * - the new y labels no longer fit the width reserved at layout time
26018
+ *
26019
+ * @param {any} _xyRatios
26020
+ * @returns {boolean} true when the chrome was refreshed in place
26021
+ */
26022
+ _fastAxisChromeRefresh(_xyRatios) {
26023
+ const w = this.w;
26024
+ const gl = w.globals;
26025
+ this._fastAxisBailReason = "";
26026
+ try {
26027
+ if (gl.isBarHorizontal) {
26028
+ this._fastAxisBailReason = "barHorizontal";
26029
+ return false;
26030
+ }
26031
+ if (w.config.chart.sparkline.enabled) return true;
26032
+ const a = w.config.annotations;
26033
+ if (a && (a.yaxis && a.yaxis.length || a.xaxis && a.xaxis.length || a.points && a.points.length || a.texts && a.texts.length || a.images && a.images.length)) {
26034
+ this._fastAxisBailReason = "annotations";
26035
+ return false;
26036
+ }
26037
+ if (w.config.chart.ink && w.config.chart.ink.enabled) {
26038
+ this._fastAxisBailReason = "ink";
26039
+ return false;
26040
+ }
26041
+ const dim = this.dimensions;
26042
+ if (!dim || !dim.dimYAxis) {
26043
+ this._fastAxisBailReason = "noDimensions";
26044
+ return false;
26045
+ }
26046
+ const prevYLabelsCoords = w.layout.yLabelsCoords;
26047
+ const prevYTitleCoords = w.layout.yTitleCoords;
26048
+ const yaxisLabelCoords = dim.dimYAxis.getyAxisLabelsCoords();
26049
+ const yTitleCoords = dim.dimYAxis.getyAxisTitleCoords();
26050
+ w.layout.yLabelsCoords = [];
26051
+ w.layout.yTitleCoords = [];
26052
+ w.config.yaxis.map((_yaxe, index) => {
26053
+ w.layout.yLabelsCoords.push({
26054
+ width: yaxisLabelCoords[index].width,
26055
+ index
26056
+ });
26057
+ w.layout.yTitleCoords.push(
26058
+ /** @type {any} */
26059
+ { width: yTitleCoords[index].width, index }
26060
+ );
26061
+ });
26062
+ const newYAxisWidth = dim.dimYAxis.getTotalYAxisWidth();
26063
+ if (newYAxisWidth > dim.yAxisWidth + 2) {
26064
+ w.layout.yLabelsCoords = prevYLabelsCoords;
26065
+ w.layout.yTitleCoords = prevYTitleCoords;
26066
+ this._fastAxisBailReason = `labelWidth ${newYAxisWidth} > ${dim.yAxisWidth}`;
26067
+ return false;
26068
+ }
26069
+ const innerEl = w.dom.elGraphical.node;
26070
+ const oldGrid = innerEl.querySelector(".apexcharts-grid");
26071
+ const oldGridBorders = innerEl.querySelector(".apexcharts-grid-borders");
26072
+ if (!oldGrid) {
26073
+ this._fastAxisBailReason = "missingGridNode";
26074
+ return false;
26075
+ }
26076
+ const gridParent = oldGrid.parentNode;
26077
+ const gridNext = oldGridBorders ? oldGridBorders.nextSibling : oldGrid.nextSibling;
26078
+ oldGrid.remove();
26079
+ if (oldGridBorders) oldGridBorders.remove();
26080
+ innerEl.querySelectorAll(".apexcharts-xaxis-tick").forEach((t) => t.remove());
26081
+ this.grid = new Grid(w, this);
26082
+ const elgrid = this.grid.drawGrid();
26083
+ if (elgrid && elgrid.el) {
26084
+ gridParent.insertBefore(elgrid.el.node, gridNext);
26085
+ if (elgrid.elGridBorders && elgrid.elGridBorders.node) {
26086
+ gridParent.insertBefore(elgrid.elGridBorders.node, gridNext);
26087
+ }
26088
+ }
26089
+ const xAxis = new XAxis(this.w, this.ctx, elgrid);
26090
+ const oldXaxis = innerEl.querySelector(".apexcharts-xaxis");
26091
+ if (oldXaxis) {
26092
+ const xParent = oldXaxis.parentNode;
26093
+ const xNext = oldXaxis.nextSibling;
26094
+ oldXaxis.remove();
26095
+ const elXaxis = xAxis.drawXaxis();
26096
+ xParent.insertBefore(elXaxis.node, xNext);
26097
+ }
26098
+ const yAxis = new YAxis(
26099
+ this.w,
26100
+ { theme: this.theme, timeScale: this.timeScale },
26101
+ elgrid
26102
+ );
26103
+ for (let index = 0; index < w.config.yaxis.length; index++) {
26104
+ if (gl.ignoreYAxisIndexes.indexOf(index) !== -1) continue;
26105
+ const oldY = w.dom.baseEl.querySelector(
26106
+ `.apexcharts-yaxis[rel='${index}']`
26107
+ );
26108
+ if (!oldY) {
26109
+ this._fastAxisBailReason = "missingYAxisNode";
26110
+ return false;
26111
+ }
26112
+ const yParent = oldY.parentNode;
26113
+ if (!yParent) {
26114
+ this._fastAxisBailReason = "missingYAxisParent";
26115
+ return false;
26116
+ }
26117
+ const yNext = oldY.nextSibling;
26118
+ oldY.remove();
26119
+ const elYaxis = yAxis.drawYaxis(index);
26120
+ yParent.insertBefore(elYaxis.node, yNext);
26121
+ }
26122
+ if (elgrid !== null) {
26123
+ xAxis.xAxisLabelCorrections();
26124
+ yAxis.setYAxisTextAlignments();
26125
+ w.config.yaxis.map((yaxe, index) => {
26126
+ if (gl.ignoreYAxisIndexes.indexOf(index) === -1) {
26127
+ yAxis.yAxisTitleRotate(index, yaxe.opposite);
26128
+ }
26129
+ });
26130
+ }
26131
+ return true;
26132
+ } catch (e) {
26133
+ this._fastAxisBailReason = "error: " + (e && /** @type {any} */
26134
+ e.message);
26135
+ return false;
26136
+ }
26137
+ }
25358
26138
  /**
25359
26139
  * Fast update path for data-only series changes.
25360
26140
  *
@@ -25412,18 +26192,32 @@ var __async = (__this, __arguments, generator) => {
25412
26192
  }
25413
26193
  }
25414
26194
  const xyRatios = this.core.xySettings();
26195
+ if (this._zoomPanSelection) this._zoomPanSelection.xyRatios = xyRatios;
25415
26196
  const newAxisScaleSig = JSON.stringify({
25416
26197
  y: (gl.yAxisScale || []).map((s) => s ? s.result : null),
25417
26198
  xMin: gl.minX,
25418
26199
  xMax: gl.maxX
25419
26200
  });
25420
- if (gl.axisCharts && prevAxisScaleSig != null && newAxisScaleSig !== prevAxisScaleSig) {
26201
+ const scaleChanged = gl.axisCharts && prevAxisScaleSig != null && newAxisScaleSig !== prevAxisScaleSig;
26202
+ if (scaleChanged && !this._fastAxisChromeRefresh(xyRatios)) {
26203
+ this._updateStats.full++;
25421
26204
  return this.update().then(() => resolve(this)).catch(reject);
25422
26205
  }
26206
+ if (scaleChanged) {
26207
+ this._updateStats.fastWithAxes++;
26208
+ } else {
26209
+ this._updateStats.fast++;
26210
+ }
25423
26211
  (_a = this.weave) == null ? void 0 : _a.dispatch("afterScales", { pass: "fast", xyRatios });
26212
+ const rr = (
26213
+ /** @type {any} */
26214
+ this.ctx.renderer
26215
+ );
26216
+ const reuseCanvasHost = !!(rr && rr.kind === "canvas" && rr.canRepaintInPlace && rr.canRepaintInPlace());
26217
+ if (reuseCanvasHost) rr._repaintHostInPlace = true;
25424
26218
  const innerEl = w.dom.elGraphical.node;
25425
26219
  const toRemove = innerEl.querySelectorAll(
25426
- ".apexcharts-canvas-series-wrap, .apexcharts-series, .apexcharts-datalabels, .apexcharts-datalabels-background"
26220
+ (reuseCanvasHost ? "" : ".apexcharts-canvas-series-wrap, ") + ".apexcharts-plot-series, .apexcharts-series, .apexcharts-datalabels, .apexcharts-datalabels-background"
25427
26221
  );
25428
26222
  toRemove.forEach(
25429
26223
  (el) => {
@@ -25433,11 +26227,13 @@ var __async = (__this, __arguments, generator) => {
25433
26227
  );
25434
26228
  const elGraph = this.core.plotChartType(w.config.series, xyRatios);
25435
26229
  const gridEl = innerEl.querySelector(".apexcharts-grid");
26230
+ const xaxisEl = innerEl.querySelector(".apexcharts-xaxis");
25436
26231
  const graphs = Array.isArray(elGraph) ? elGraph : [elGraph];
25437
- if (gridEl && w.config.grid.position === "front") {
26232
+ const anchor = gridEl && w.config.grid.position === "front" ? gridEl : xaxisEl;
26233
+ if (anchor) {
25438
26234
  graphs.forEach((g) => {
25439
26235
  const node = g && g.node ? g.node : g;
25440
- if (node) innerEl.insertBefore(node, gridEl);
26236
+ if (node) innerEl.insertBefore(node, anchor);
25441
26237
  });
25442
26238
  } else {
25443
26239
  graphs.forEach((g) => {
@@ -26197,41 +26993,57 @@ var __async = (__this, __arguments, generator) => {
26197
26993
  return this.ctx.drilldown.drillToRoot();
26198
26994
  }
26199
26995
  // ─── Slice write-back stubs ─────────────────────────────────────────────────
26996
+ /**
26997
+ * Copy own DATA properties of a parse-state slice onto a live w.* slice.
26998
+ * Never Object.assign here: several w.* fields (and, historically, snapshot
26999
+ * fields) are lazy accessors, and [[Get]]-ing an accessor while copying
27000
+ * forces its deferred computation (a deep initialSeries clone plus O(n)
27001
+ * stacked-totals passes on every render/update) and can replace the live
27002
+ * accessor with a materialized value for the life of the instance.
27003
+ * @param {any} target
27004
+ * @param {any} slice
27005
+ */
27006
+ static _writeDataProps(target, slice) {
27007
+ for (const key of Object.keys(slice)) {
27008
+ const d = Object.getOwnPropertyDescriptor(slice, key);
27009
+ if (d && "value" in d) target[key] = d.value;
27010
+ }
27011
+ }
26200
27012
  /**
26201
27013
  * @param {Partial<import('./types/internal').SeriesData>} slice
26202
27014
  */
26203
27015
  _writeParsedSeriesData(slice) {
26204
- Object.assign(this.w.seriesData, slice);
27016
+ _ApexCharts._writeDataProps(this.w.seriesData, slice);
26205
27017
  }
26206
27018
  /**
26207
27019
  * @param {Partial<import('./types/internal').RangeData>} slice
26208
27020
  */
26209
27021
  _writeParsedRangeData(slice) {
26210
- Object.assign(this.w.rangeData, slice);
27022
+ _ApexCharts._writeDataProps(this.w.rangeData, slice);
26211
27023
  }
26212
27024
  /**
26213
27025
  * @param {Partial<import('./types/internal').CandleData>} slice
26214
27026
  */
26215
27027
  _writeParsedCandleData(slice) {
26216
- Object.assign(this.w.candleData, slice);
27028
+ _ApexCharts._writeDataProps(this.w.candleData, slice);
26217
27029
  }
26218
27030
  /**
26219
27031
  * @param {Partial<import('./types/internal').LabelData>} slice
26220
27032
  */
26221
27033
  _writeParsedLabelData(slice) {
26222
- Object.assign(this.w.labelData, slice);
27034
+ _ApexCharts._writeDataProps(this.w.labelData, slice);
26223
27035
  }
26224
27036
  /**
26225
27037
  * @param {Partial<import('./types/internal').AxisFlags>} slice
26226
27038
  */
26227
27039
  _writeParsedAxisFlags(slice) {
26228
- Object.assign(this.w.axisFlags, slice);
27040
+ _ApexCharts._writeDataProps(this.w.axisFlags, slice);
26229
27041
  }
26230
27042
  /**
26231
27043
  * @param {Partial<import('./types/internal').LayoutCoords>} slice
26232
27044
  */
26233
27045
  _writeLayoutCoords(slice) {
26234
- Object.assign(this.w.layout, slice);
27046
+ _ApexCharts._writeDataProps(this.w.layout, slice);
26235
27047
  }
26236
27048
  _parentResizeCallback() {
26237
27049
  if (this.w.globals.animationEnded && this.w.config.chart.redrawOnParentResize) {
@@ -28769,7 +29581,6 @@ var __async = (__this, __arguments, generator) => {
28769
29581
  this.xyRatios = xyRatios;
28770
29582
  this.zoomRect = this.graphics.drawRect(0, 0, 0, 0);
28771
29583
  this.selectionRect = this.graphics.drawRect(0, 0, 0, 0);
28772
- this.gridRect = w.dom.baseEl.querySelector(".apexcharts-grid");
28773
29584
  this.constraints = new Box(0, 0, w.layout.gridWidth, w.layout.gridHeight);
28774
29585
  this.zoomRect.node.classList.add("apexcharts-zoom-rect");
28775
29586
  this.selectionRect.node.classList.add("apexcharts-selection-rect");
@@ -28833,14 +29644,12 @@ var __async = (__this, __arguments, generator) => {
28833
29644
  }
28834
29645
  this.selectionRect = null;
28835
29646
  this.zoomRect = null;
28836
- this.gridRect = null;
28837
29647
  }
28838
29648
  /**
28839
29649
  * @param {import('../types/internal').XYRatios} xyRatios
28840
29650
  * @param {any} e
28841
29651
  */
28842
29652
  svgMouseEvents(xyRatios, e) {
28843
- var _a;
28844
29653
  const w = this.w;
28845
29654
  const toolbar = this.ctx.toolbar;
28846
29655
  if (w.interact.momentum && w.interact.momentum.busy) return;
@@ -28871,7 +29680,7 @@ var __async = (__this, __arguments, generator) => {
28871
29680
  this.clientX = e.type === "touchmove" || e.type === "touchstart" ? e.touches[0].clientX : e.type === "touchend" ? e.changedTouches[0].clientX : e.clientX;
28872
29681
  this.clientY = e.type === "touchmove" || e.type === "touchstart" ? e.touches[0].clientY : e.type === "touchend" ? e.changedTouches[0].clientY : e.clientY;
28873
29682
  if (e.type === "mousedown" && e.which === 1 || e.type === "touchstart") {
28874
- const gridRectDim = (_a = this.gridRect) == null ? void 0 : _a.getBoundingClientRect();
29683
+ const gridRectDim = this._gridRect();
28875
29684
  if (!gridRectDim) return;
28876
29685
  this.startX = this.clientX - gridRectDim.left - w.globals.barPadForNumericAxis;
28877
29686
  this.startY = this.clientY - gridRectDim.top;
@@ -28886,7 +29695,7 @@ var __async = (__this, __arguments, generator) => {
28886
29695
  this.panDragging({
28887
29696
  context: this,
28888
29697
  zoomtype,
28889
- xyRatios
29698
+ xyRatios: this.xyRatios
28890
29699
  });
28891
29700
  }
28892
29701
  } else {
@@ -28905,9 +29714,8 @@ var __async = (__this, __arguments, generator) => {
28905
29714
  }
28906
29715
  /** @param {{ zoomtype?: any, isResized?: any }} opts */
28907
29716
  handleMouseUp({ zoomtype, isResized }) {
28908
- var _a;
28909
29717
  const w = this.w;
28910
- const gridRectDim = (_a = this.gridRect) == null ? void 0 : _a.getBoundingClientRect();
29718
+ const gridRectDim = this._gridRect();
28911
29719
  if (gridRectDim && (this.w.interact.mousedown || isResized)) {
28912
29720
  this.endX = this.clientX - gridRectDim.left - w.globals.barPadForNumericAxis;
28913
29721
  this.endY = this.clientY - gridRectDim.top;
@@ -28949,11 +29757,11 @@ var __async = (__this, __arguments, generator) => {
28949
29757
  * @param {any} e
28950
29758
  */
28951
29759
  executeMouseWheelZoom(e) {
28952
- var _a, _b, _c;
29760
+ var _a, _b;
28953
29761
  const w = this.w;
28954
29762
  this.minX = w.axisFlags.isRangeBar ? w.globals.minY : w.globals.minX;
28955
29763
  this.maxX = w.axisFlags.isRangeBar ? w.globals.maxY : w.globals.maxX;
28956
- const gridRectDim = (_a = this.gridRect) == null ? void 0 : _a.getBoundingClientRect();
29764
+ const gridRectDim = this._gridRect();
28957
29765
  if (!gridRectDim) return;
28958
29766
  const mouseX = (e.clientX - gridRectDim.left) / gridRectDim.width;
28959
29767
  const currentMinX = this.minX;
@@ -28974,8 +29782,8 @@ var __async = (__this, __arguments, generator) => {
28974
29782
  newMaxX = currentMaxX + zoomRange / 2;
28975
29783
  }
28976
29784
  if (!w.axisFlags.isRangeBar) {
28977
- const clampMin = (_b = w.globals.dataReducerRawMinX) != null ? _b : w.globals.initialMinX;
28978
- const clampMax = (_c = w.globals.dataReducerRawMaxX) != null ? _c : w.globals.initialMaxX;
29785
+ const clampMin = (_a = w.globals.dataReducerRawMinX) != null ? _a : w.globals.initialMinX;
29786
+ const clampMax = (_b = w.globals.dataReducerRawMaxX) != null ? _b : w.globals.initialMaxX;
28979
29787
  newMinX = Math.max(newMinX, clampMin);
28980
29788
  newMaxX = Math.min(newMaxX, clampMax);
28981
29789
  const minXDiff = w.globals.minXDiff > 0 && isFinite(w.globals.minXDiff) ? w.globals.minXDiff : 0;
@@ -29112,10 +29920,9 @@ var __async = (__this, __arguments, generator) => {
29112
29920
  }
29113
29921
  }
29114
29922
  selectionDrawing({ context, zoomtype }) {
29115
- var _a;
29116
29923
  const w = this.w;
29117
29924
  const me = context;
29118
- const gridRectDim = (_a = this.gridRect) == null ? void 0 : _a.getBoundingClientRect();
29925
+ const gridRectDim = this._gridRect();
29119
29926
  if (!gridRectDim) return;
29120
29927
  const startX = me.startX - 1;
29121
29928
  const startY = me.startY;
@@ -29221,8 +30028,8 @@ var __async = (__this, __arguments, generator) => {
29221
30028
  if ((typeof w.config.chart.events.selection === "function" || linkActive) && w.interact.selectionEnabled) {
29222
30029
  clearTimeout((_a = this.w.globals.selectionResizeTimer) != null ? _a : void 0);
29223
30030
  this.w.globals.selectionResizeTimer = window.setTimeout(() => {
29224
- var _a2, _b;
29225
- const gridRectDim = (_a2 = this.gridRect) == null ? void 0 : _a2.getBoundingClientRect();
30031
+ var _a2;
30032
+ const gridRectDim = this._gridRect();
29226
30033
  if (!gridRectDim) return;
29227
30034
  const selectionRect = selRect.node.getBoundingClientRect();
29228
30035
  let minX, maxX, minY, maxY;
@@ -29256,7 +30063,7 @@ var __async = (__this, __arguments, generator) => {
29256
30063
  if (w.config.chart.brush.enabled && w.config.chart.events.brushScrolled !== void 0) {
29257
30064
  w.config.chart.events.brushScrolled(this.ctx, xyAxis);
29258
30065
  }
29259
- (_b = this.ctx.linkedViews) == null ? void 0 : _b.onSourceSelection(xyAxis.xaxis);
30066
+ (_a2 = this.ctx.linkedViews) == null ? void 0 : _a2.onSourceSelection(xyAxis.xaxis);
29260
30067
  }, timerInterval);
29261
30068
  }
29262
30069
  }
@@ -29268,7 +30075,8 @@ var __async = (__this, __arguments, generator) => {
29268
30075
  const xyRatios = this.xyRatios;
29269
30076
  const toolbar = this.ctx.toolbar;
29270
30077
  const selRect = w.interact.zoomEnabled ? me.zoomRect.node.getBoundingClientRect() : me.selectionRect.node.getBoundingClientRect();
29271
- const gridRectDim = me.gridRect.getBoundingClientRect();
30078
+ const gridRectDim = me._gridRect();
30079
+ if (!gridRectDim) return;
29272
30080
  const localStartX = selRect.left - gridRectDim.left - w.globals.barPadForNumericAxis;
29273
30081
  const localEndX = selRect.right - gridRectDim.left - w.globals.barPadForNumericAxis;
29274
30082
  const localStartY = selRect.top - gridRectDim.top;
@@ -29526,8 +30334,11 @@ var __async = (__this, __arguments, generator) => {
29526
30334
  const w = this.w;
29527
30335
  return w.axisFlags.isRangeBar ? { min: w.globals.minY, max: w.globals.maxY } : { min: w.globals.minX, max: w.globals.maxX };
29528
30336
  }
29529
- /** Live grid rect from the current DOM (this.gridRect goes stale/null after
29530
- * the re-render a gesture frame triggers). */
30337
+ /** Live grid rect from the current DOM. Never cache the grid node on the
30338
+ * instance: a full render replaces this whole instance, but the fast update
30339
+ * path (fastUpdate/_fastAxisChromeRefresh) keeps the instance while swapping
30340
+ * the grid node, and a cached node would go stale (detached nodes report an
30341
+ * all-zero bounding rect, silently corrupting selection geometry). */
29531
30342
  _gridRect() {
29532
30343
  const baseEl = this.w.dom.baseEl;
29533
30344
  const grid = baseEl && baseEl.querySelector(".apexcharts-grid");
@@ -34433,6 +35244,30 @@ var __async = (__this, __arguments, generator) => {
34433
35244
  return NOOP_RUNNER;
34434
35245
  }
34435
35246
  }
35247
+ const SHARED_RECT_REF = {
35248
+ __isCanvasMark: true,
35249
+ node: SHARED_MARKER_NODE,
35250
+ /** @returns {any} */
35251
+ attr() {
35252
+ return SHARED_RECT_REF;
35253
+ },
35254
+ add() {
35255
+ return SHARED_RECT_REF;
35256
+ },
35257
+ addTo() {
35258
+ return SHARED_RECT_REF;
35259
+ },
35260
+ remove() {
35261
+ return SHARED_RECT_REF;
35262
+ },
35263
+ /** @returns {any} */
35264
+ css() {
35265
+ return SHARED_RECT_REF;
35266
+ },
35267
+ animate() {
35268
+ return NOOP_RUNNER;
35269
+ }
35270
+ };
34436
35271
  class CanvasMark {
34437
35272
  /** @param {any} cmd */
34438
35273
  constructor(cmd) {
@@ -34560,6 +35395,16 @@ var __async = (__this, __arguments, generator) => {
34560
35395
  this._msi = new Int32Array(16);
34561
35396
  this._mn = 0;
34562
35397
  this._mcap = 16;
35398
+ this._crx = new Float64Array(16);
35399
+ this._cry = new Float64Array(16);
35400
+ this._crw = new Float64Array(16);
35401
+ this._crh = new Float64Array(16);
35402
+ this._crstyle = new Int32Array(16);
35403
+ this._crsi = new Int32Array(16);
35404
+ this._crdi = new Int32Array(16);
35405
+ this._crn = 0;
35406
+ this._crcap = 16;
35407
+ this._cellRadius = 0;
34563
35408
  this._styles = [];
34564
35409
  this._styleMap = /* @__PURE__ */ new Map();
34565
35410
  this._lf = NEVER;
@@ -34572,6 +35417,12 @@ var __async = (__this, __arguments, generator) => {
34572
35417
  this._lofFill = NEVER;
34573
35418
  this._lofBase = -1;
34574
35419
  this._lofId = -1;
35420
+ this._rlf = NEVER;
35421
+ this._rls = NEVER;
35422
+ this._rlsw = NEVER;
35423
+ this._rlfo = NEVER;
35424
+ this._rlso = NEVER;
35425
+ this._rlid = -1;
34575
35426
  }
34576
35427
  _resetStyleCache() {
34577
35428
  this._lf = NEVER;
@@ -34584,6 +35435,12 @@ var __async = (__this, __arguments, generator) => {
34584
35435
  this._lofFill = NEVER;
34585
35436
  this._lofBase = -1;
34586
35437
  this._lofId = -1;
35438
+ this._rlf = NEVER;
35439
+ this._rls = NEVER;
35440
+ this._rlsw = NEVER;
35441
+ this._rlfo = NEVER;
35442
+ this._rlso = NEVER;
35443
+ this._rlid = -1;
34587
35444
  }
34588
35445
  /** Start a fresh scene (columnar marker store + object-command list). */
34589
35446
  reset() {
@@ -34600,6 +35457,46 @@ var __async = (__this, __arguments, generator) => {
34600
35457
  }
34601
35458
  cap = Math.ceil(cap * 1.15) + 16;
34602
35459
  if (cap > this._mcap) this._allocMarkers(cap);
35460
+ this._crn = 0;
35461
+ this._cellRadius = 0;
35462
+ if (cap > this._crcap) this._allocRects(cap);
35463
+ }
35464
+ /** @param {number} cap */
35465
+ _allocRects(cap) {
35466
+ this._crcap = cap;
35467
+ this._crx = new Float64Array(cap);
35468
+ this._cry = new Float64Array(cap);
35469
+ this._crw = new Float64Array(cap);
35470
+ this._crh = new Float64Array(cap);
35471
+ this._crstyle = new Int32Array(cap);
35472
+ this._crsi = new Int32Array(cap);
35473
+ this._crdi = new Int32Array(cap);
35474
+ }
35475
+ /** Grow the rect columns (rare: capacity estimate was low). */
35476
+ _growRects() {
35477
+ const cap = this._crcap * 2;
35478
+ const nx = new Float64Array(cap);
35479
+ nx.set(this._crx);
35480
+ this._crx = nx;
35481
+ const ny = new Float64Array(cap);
35482
+ ny.set(this._cry);
35483
+ this._cry = ny;
35484
+ const nw = new Float64Array(cap);
35485
+ nw.set(this._crw);
35486
+ this._crw = nw;
35487
+ const nh = new Float64Array(cap);
35488
+ nh.set(this._crh);
35489
+ this._crh = nh;
35490
+ const nst = new Int32Array(cap);
35491
+ nst.set(this._crstyle);
35492
+ this._crstyle = nst;
35493
+ const nsi = new Int32Array(cap);
35494
+ nsi.set(this._crsi);
35495
+ this._crsi = nsi;
35496
+ const ndi = new Int32Array(cap);
35497
+ ndi.set(this._crdi);
35498
+ this._crdi = ndi;
35499
+ this._crcap = cap;
34603
35500
  }
34604
35501
  /** @param {number} cap */
34605
35502
  _allocMarkers(cap) {
@@ -34709,6 +35606,65 @@ var __async = (__this, __arguments, generator) => {
34709
35606
  shapeName(id) {
34710
35607
  return SHAPE_NAME[id] || "circle";
34711
35608
  }
35609
+ // ── columnar rect cell (heatmap): parallel unboxed arrays, no per-cell object ──
35610
+ /**
35611
+ * Record a heatmap-style cell (a filled, optionally stroked rect). Geometry
35612
+ * and style are captured up front into the columns; the returned handle is a
35613
+ * shared no-op (the emit site sets nothing back on it in canvas mode).
35614
+ * @param {number} x @param {number} y @param {number} w @param {number} h
35615
+ * @param {any} opts {fill, fillOpacity, stroke, strokeWidth, radius, seriesIndex, dataPointIndex}
35616
+ * @returns {any}
35617
+ */
35618
+ drawRectCell(x, y, w, h, opts = {}) {
35619
+ const styleId = this._rectStyleId(opts);
35620
+ if (this._crn >= this._crcap) this._growRects();
35621
+ const i = this._crn++;
35622
+ this._crx[i] = x || 0;
35623
+ this._cry[i] = y || 0;
35624
+ this._crw[i] = w > 0 ? w : 0;
35625
+ this._crh[i] = h > 0 ? h : 0;
35626
+ this._crstyle[i] = styleId;
35627
+ this._crsi[i] = opts.seriesIndex == null ? -1 : opts.seriesIndex;
35628
+ this._crdi[i] = opts.dataPointIndex == null ? -1 : opts.dataPointIndex;
35629
+ if (opts.radius) this._cellRadius = opts.radius;
35630
+ return SHARED_RECT_REF;
35631
+ }
35632
+ /**
35633
+ * Resolve (and dedupe) a rect-cell style → shared-palette id. A last-style
35634
+ * cache keeps the Map/string work off the path for runs of same-style cells.
35635
+ * @param {any} opts
35636
+ * @returns {number}
35637
+ */
35638
+ _rectStyleId(opts) {
35639
+ const fill = opts.fill;
35640
+ const stroke = opts.stroke;
35641
+ const sw = opts.strokeWidth;
35642
+ const fo = opts.fillOpacity;
35643
+ const so = opts.strokeOpacity;
35644
+ if (fill === this._rlf && stroke === this._rls && sw === this._rlsw && fo === this._rlfo && so === this._rlso) {
35645
+ return this._rlid;
35646
+ }
35647
+ const id = this._internStyle(fill, stroke, sw, 0, fo, so);
35648
+ this._rlf = fill;
35649
+ this._rls = stroke;
35650
+ this._rlsw = sw;
35651
+ this._rlfo = fo;
35652
+ this._rlso = so;
35653
+ this._rlid = id;
35654
+ return id;
35655
+ }
35656
+ /** @returns {number} number of recorded rect cells */
35657
+ rectCount() {
35658
+ return this._crn;
35659
+ }
35660
+ /** @param {number} i @returns {any} the style object for a rect cell */
35661
+ rectStyle(i) {
35662
+ return this._styles[this._crstyle[i]];
35663
+ }
35664
+ /** @param {number} i @returns {number} series (realIndex) of a cell, -1 if none */
35665
+ rectSeries(i) {
35666
+ return this._crsi[i];
35667
+ }
34712
35668
  /**
34713
35669
  * @param {string} tag
34714
35670
  * @param {number} z
@@ -35024,9 +35980,97 @@ var __async = (__this, __arguments, generator) => {
35024
35980
  this._paintOne(ctx, c);
35025
35981
  }
35026
35982
  }
35983
+ this._paintRects(ctx, shim2);
35027
35984
  this._paintMarkers(ctx, shim2);
35028
35985
  this._alpha = 1;
35029
35986
  }
35987
+ /**
35988
+ * Paint the columnar rect cells (heatmap) as STYLE BATCHES: one fill/stroke
35989
+ * state application per run of consecutive same-style cells, then a fast
35990
+ * fillRect (or a roundRect path when the shared corner radius is non-zero)
35991
+ * per cell. Clipped to the plot rect so cells never bleed into the canvas
35992
+ * margin (mirrors the SVG gridRectMask). Per-cell globalAlpha carries the
35993
+ * hover/legend dim multiplier when a dim spec is active.
35994
+ * @param {any} ctx
35995
+ * @param {any} shim
35996
+ */
35997
+ _paintRects(ctx, shim2) {
35998
+ const n = shim2.rectCount ? shim2.rectCount() : 0;
35999
+ if (!n) return;
36000
+ const rx = shim2._crx;
36001
+ const ry = shim2._cry;
36002
+ const rw = shim2._crw;
36003
+ const rh = shim2._crh;
36004
+ const rstyle = shim2._crstyle;
36005
+ const radius = shim2._cellRadius || 0;
36006
+ const cx = (
36007
+ /** @type {any} */
36008
+ ctx
36009
+ );
36010
+ const useRound = radius > 0 && typeof cx.roundRect === "function";
36011
+ const dimming = !!this._dim;
36012
+ const gw = Math.max(0, this.w.layout.gridWidth || 0);
36013
+ const gh = Math.max(0, this.w.layout.gridHeight || 0);
36014
+ ctx.save();
36015
+ ctx.beginPath();
36016
+ ctx.rect(0, 0, gw, gh);
36017
+ ctx.clip();
36018
+ let i = 0;
36019
+ while (i < n) {
36020
+ const styleId = rstyle[i];
36021
+ const style = shim2.rectStyle(i);
36022
+ if (!style) {
36023
+ i++;
36024
+ continue;
36025
+ }
36026
+ const fill = style.fill;
36027
+ const doFill = fill && fill !== "none" && !(typeof fill === "string" && fill.indexOf("url(") === 0);
36028
+ const stroke = style.stroke;
36029
+ const sw = style.strokeWidth == null ? 0 : Number(style.strokeWidth);
36030
+ const doStroke = stroke && stroke !== "none" && sw > 0 && !(typeof stroke === "string" && stroke.indexOf("url(") === 0);
36031
+ if (doFill) ctx.fillStyle = fill;
36032
+ if (doStroke) {
36033
+ ctx.strokeStyle = stroke;
36034
+ ctx.lineWidth = sw;
36035
+ ctx.setLineDash([]);
36036
+ }
36037
+ const baseFillA = style.fillOpacity == null ? 1 : Number(style.fillOpacity);
36038
+ const baseStrokeA = style.strokeOpacity == null ? 1 : Number(style.strokeOpacity);
36039
+ let j = i;
36040
+ while (j < n && rstyle[j] === styleId) {
36041
+ const w = rw[j];
36042
+ const h = rh[j];
36043
+ if (w > 0 && h > 0) {
36044
+ const f = dimming ? this._seriesAlpha(shim2.rectSeries(j)) : 1;
36045
+ if (useRound) {
36046
+ ctx.beginPath();
36047
+ cx.roundRect(rx[j], ry[j], w, h, radius);
36048
+ if (doFill) {
36049
+ ctx.globalAlpha = baseFillA * f;
36050
+ ctx.fill();
36051
+ }
36052
+ if (doStroke) {
36053
+ ctx.globalAlpha = baseStrokeA * f;
36054
+ ctx.stroke();
36055
+ }
36056
+ } else {
36057
+ if (doFill) {
36058
+ ctx.globalAlpha = baseFillA * f;
36059
+ ctx.fillRect(rx[j], ry[j], w, h);
36060
+ }
36061
+ if (doStroke) {
36062
+ ctx.globalAlpha = baseStrokeA * f;
36063
+ ctx.strokeRect(rx[j], ry[j], w, h);
36064
+ }
36065
+ }
36066
+ }
36067
+ j++;
36068
+ }
36069
+ i = j;
36070
+ }
36071
+ ctx.globalAlpha = 1;
36072
+ ctx.restore();
36073
+ }
35030
36074
  /**
35031
36075
  * Reusable unit Path2D for a (shape, size): the shape's geometry built at the
35032
36076
  * origin once, then translated per marker via setTransform. Returns null when
@@ -35340,6 +36384,20 @@ var __async = (__this, __arguments, generator) => {
35340
36384
  clear() {
35341
36385
  this._compositor.clear();
35342
36386
  }
36387
+ /**
36388
+ * Whether the existing <canvas> host can be repainted in place (it exists
36389
+ * and is still mounted). Used by the data-only fast update path to skip
36390
+ * recreating the foreignObject + backing store on every tick.
36391
+ * @returns {boolean}
36392
+ */
36393
+ canRepaintInPlace() {
36394
+ const host = this._compositor.getHost();
36395
+ return !!(host && host.node && host.node.isConnected);
36396
+ }
36397
+ /** Repaint the freshly recorded display list into the EXISTING canvas. */
36398
+ repaintInPlace() {
36399
+ this._compositor.paint(this._g.displayList(), this._g);
36400
+ }
35343
36401
  // ── emit primitives (delegate to the display-list shim) ──
35344
36402
  /** @param {any} attrs */
35345
36403
  group(attrs) {
@@ -35363,6 +36421,16 @@ var __async = (__this, __arguments, generator) => {
35363
36421
  this._g.drawRect(...args)
35364
36422
  );
35365
36423
  }
36424
+ /**
36425
+ * Columnar heatmap-cell rect (dense same-shape rects): recorded into typed
36426
+ * arrays, painted as style batches. Distinct from drawRect (object command)
36427
+ * so 100k cells don't allocate 100k retained commands.
36428
+ * @param {number} x @param {number} y @param {number} w @param {number} h
36429
+ * @param {any} opts
36430
+ */
36431
+ drawRectCell(x, y, w, h, opts) {
36432
+ return this._g.drawRectCell(x, y, w, h, opts);
36433
+ }
35366
36434
  /**
35367
36435
  * @param {number} r
35368
36436
  * @param {any} attrs
@@ -35392,14 +36460,44 @@ var __async = (__this, __arguments, generator) => {
35392
36460
  return feature === "solidFill" || feature === "dashArray";
35393
36461
  }
35394
36462
  // ── interaction ──
35395
- // Shared tooltip/zoom/click resolve via coordinate lookup (pointsArray), so
35396
- // there is no per-mark hit surface to query; hitTest stays a no-op unless a
35397
- // future per-point feature needs it.
35398
- /**
35399
- * @param {number} _px
35400
- * @param {number} _py
35401
- */
35402
- hitTest(_px, _py) {
36463
+ // Line/area/bar/scatter tooltips resolve via coordinate lookup (pointsArray),
36464
+ // so those need no per-mark query. Heatmap cells, however, are hovered by
36465
+ // point (the SVG path hit-tests the <rect> under the cursor); with cells on
36466
+ // canvas there is no node, so hitTest resolves the columnar rect store.
36467
+ /**
36468
+ * Find the cell under a plot-local point (0,0 = plot origin, the same space
36469
+ * as the recorded cell geometry). Reverse scan so a later-painted cell wins
36470
+ * when cells overlap (continuous-x edges). A linear scan stays well under a
36471
+ * frame even at 100k cells (~100k integer compares). Returns the cell's
36472
+ * series/dataPoint index plus its geometry for tooltip positioning, or null
36473
+ * when the point is off every cell.
36474
+ * @param {number} px
36475
+ * @param {number} py
36476
+ * @returns {({seriesIndex:number,dataPointIndex:number,x:number,y:number,width:number,height:number})|null}
36477
+ */
36478
+ hitTest(px, py) {
36479
+ const g = this._g;
36480
+ const n = g.rectCount ? g.rectCount() : 0;
36481
+ if (!n) return null;
36482
+ const rx = g._crx;
36483
+ const ry = g._cry;
36484
+ const rw = g._crw;
36485
+ const rh = g._crh;
36486
+ for (let k = n - 1; k >= 0; k--) {
36487
+ const w = rw[k];
36488
+ const h = rh[k];
36489
+ if (w <= 0 || h <= 0) continue;
36490
+ if (px >= rx[k] && px < rx[k] + w && py >= ry[k] && py < ry[k] + h) {
36491
+ return {
36492
+ seriesIndex: g._crsi[k],
36493
+ dataPointIndex: g._crdi[k],
36494
+ x: rx[k],
36495
+ y: ry[k],
36496
+ width: w,
36497
+ height: h
36498
+ };
36499
+ }
36500
+ }
35403
36501
  return null;
35404
36502
  }
35405
36503
  /**
@@ -39260,6 +40358,7 @@ var __async = (__this, __arguments, generator) => {
39260
40358
  barWidth,
39261
40359
  dataLabelsConfig
39262
40360
  }) {
40361
+ var _a, _b;
39263
40362
  const w = this.w;
39264
40363
  let rotate = "rotate(0)";
39265
40364
  if (w.config.plotOptions.bar.dataLabels.orientation === "vertical")
@@ -39274,6 +40373,17 @@ var __async = (__this, __arguments, generator) => {
39274
40373
  class: "apexcharts-data-labels",
39275
40374
  transform: rotate
39276
40375
  });
40376
+ const dlCfg = w.config.dataLabels;
40377
+ if (((_a = dlCfg.animate) == null ? void 0 : _a.enabled) || ((_b = dlCfg.countUp) == null ? void 0 : _b.enabled)) {
40378
+ elDataLabelsWrap.node.setAttribute(
40379
+ "data:dlKey",
40380
+ `${i}::${datumKey(w, i, j)}`
40381
+ );
40382
+ elDataLabelsWrap.node.setAttribute("data:dlJ", String(j));
40383
+ if (typeof val === "number" && isFinite(val)) {
40384
+ elDataLabelsWrap.node.setAttribute("data:dlVal", String(val));
40385
+ }
40386
+ }
39277
40387
  let text = "";
39278
40388
  if (typeof val !== "undefined") {
39279
40389
  text = formatter(val, __spreadProps(__spreadValues({}, w), {
@@ -40231,6 +41341,7 @@ var __async = (__this, __arguments, generator) => {
40231
41341
  this.pathArr = [];
40232
41342
  this._prevKeyed = null;
40233
41343
  this._ltCache = null;
41344
+ this._layoutShiftCache = null;
40234
41345
  this.series = [];
40235
41346
  this.elSeries = null;
40236
41347
  this.visibleI = 0;
@@ -40259,7 +41370,7 @@ var __async = (__this, __arguments, generator) => {
40259
41370
  * @return {Element} element which is supplied to parent chart draw method for appending
40260
41371
  **/
40261
41372
  draw(series, seriesIndex) {
40262
- var _a, _b;
41373
+ var _a, _b, _c;
40263
41374
  const w = this.w;
40264
41375
  const graphics = new Graphics(this.w);
40265
41376
  const coreUtils = new CoreUtils(this.w);
@@ -40333,8 +41444,10 @@ var __async = (__this, __arguments, generator) => {
40333
41444
  el: elDataLabelsWrap.node,
40334
41445
  // On a layout-changing update the labels must stay hidden through the
40335
41446
  // reflow morph (the updateOptions flow otherwise reveals them at
40336
- // frame 0, where they float over sliding bars).
40337
- holdUntilComplete: this.isLengthTransition(realIndex)
41447
+ // frame 0, where they float over sliding bars). When dataLabels.animate
41448
+ // is on the labels instead RIDE the morph (see DataLabelTransition), so
41449
+ // keep them visible: holding would hide the very motion we want to show.
41450
+ holdUntilComplete: !((_a = w.config.dataLabels.animate) == null ? void 0 : _a.enabled) && this.isLengthTransition(realIndex)
40338
41451
  });
40339
41452
  elDataLabelsWrap.node.classList.add("apexcharts-element-hidden");
40340
41453
  const elGoalsMarkers = graphics.group({
@@ -40387,9 +41500,9 @@ var __async = (__this, __arguments, generator) => {
40387
41500
  j,
40388
41501
  realIndex
40389
41502
  );
40390
- if (this.isFunnel && !this.isPyramid && this.barOptions.isFunnel3d && ((_a = w.config.plotOptions.funnel) == null ? void 0 : _a.shape) !== "trapezoid" && this.pathArr.length && j > 0) {
41503
+ if (this.isFunnel && !this.isPyramid && this.barOptions.isFunnel3d && ((_b = w.config.plotOptions.funnel) == null ? void 0 : _b.shape) !== "trapezoid" && this.pathArr.length && j > 0) {
40391
41504
  const barShadow = this.barHelpers.drawBarShadow({
40392
- color: typeof pathFill.color === "string" && ((_b = pathFill.color) == null ? void 0 : _b.indexOf("url")) === -1 ? pathFill.color : Utils$1.hexToRgba(w.globals.colors[i]),
41505
+ color: typeof pathFill.color === "string" && ((_c = pathFill.color) == null ? void 0 : _c.indexOf("url")) === -1 ? pathFill.color : Utils$1.hexToRgba(w.globals.colors[i]),
40393
41506
  prevPaths: this.pathArr[this.pathArr.length - 1],
40394
41507
  currPaths: paths,
40395
41508
  realIndex,
@@ -40561,7 +41674,7 @@ var __async = (__this, __arguments, generator) => {
40561
41674
  }
40562
41675
  const animCfg = w.config.chart.animations;
40563
41676
  const gradCfg = animCfg.animateGradually;
40564
- const staggerEnabled = gradCfg && gradCfg.enabled !== false && !(w.globals.dataChanged && this.isLengthTransition(realIndex));
41677
+ const staggerEnabled = gradCfg && gradCfg.enabled !== false && !(w.globals.dataChanged && this.isLayoutShift(realIndex));
40565
41678
  let delay = 0;
40566
41679
  if (staggerEnabled) {
40567
41680
  const totalBars = w.globals.dataPoints || 1;
@@ -40975,6 +42088,26 @@ var __async = (__this, __arguments, generator) => {
40975
42088
  this._ltCache[realIndex] = result;
40976
42089
  return result;
40977
42090
  }
42091
+ /**
42092
+ * Whether this update moves survivors to new slots: a length change
42093
+ * (enter/exit, via isLengthTransition) OR a pure reorder (a "bar chart race"
42094
+ * swap, same datum set in a new order). Used to drop the per-bar stagger so
42095
+ * all bars slide on one shared clock, staying locked to the axis/data labels.
42096
+ * Broader than isLengthTransition, which is deliberately enter/exit-only
42097
+ * (exit ghosts / baseline enters must not fire on a plain reorder).
42098
+ * @param {number} realIndex
42099
+ */
42100
+ isLayoutShift(realIndex) {
42101
+ if (this.isLengthTransition(realIndex)) return true;
42102
+ if (!this._layoutShiftCache) this._layoutShiftCache = {};
42103
+ if (this._layoutShiftCache[realIndex] !== void 0) {
42104
+ return this._layoutShiftCache[realIndex];
42105
+ }
42106
+ const sj = seriesJoin(this.w, realIndex, true, true);
42107
+ const result = !!(sj && sj.join.changed);
42108
+ this._layoutShiftCache[realIndex] = result;
42109
+ return result;
42110
+ }
40978
42111
  /**
40979
42112
  * Resolve `pathFrom` for a bar on data update, joining old and new datums
40980
42113
  * by KEY (category label / x value) so survivors keep their identity across
@@ -42836,14 +43969,24 @@ var __async = (__this, __arguments, generator) => {
42836
43969
  * @param {any[]} series
42837
43970
  */
42838
43971
  draw(series) {
43972
+ var _a, _b;
42839
43973
  const w = this.w;
42840
43974
  const graphics = new Graphics(this.w, this.ctx);
43975
+ const emit = seriesEmitter(this.ctx, graphics);
43976
+ const useCanvas = emit !== graphics && typeof emit.drawRectCell === "function";
42841
43977
  const ret = graphics.group({
42842
43978
  class: "apexcharts-heatmap"
42843
43979
  });
42844
43980
  ret.attr("clip-path", `url(#gridRectMask${w.globals.cuid})`);
42845
43981
  const xDivision = w.layout.gridWidth / w.globals.dataPoints;
42846
43982
  const yDivision = w.layout.gridHeight / w.seriesData.series.length;
43983
+ const isContinuousX = (w.config.xaxis.type === "numeric" || w.config.xaxis.type === "datetime") && w.axisFlags.isXNumeric && this.xRatio > 0;
43984
+ let binPx = xDivision;
43985
+ if (isContinuousX) {
43986
+ const diff = w.globals.minXDiff;
43987
+ binPx = Number.isFinite(diff) && diff > 0 ? diff / this.xRatio : xDivision;
43988
+ }
43989
+ const cellFillOpacity = Array.isArray(w.config.fill.opacity) ? (_a = w.config.fill.opacity[0]) != null ? _a : 1 : (_b = w.config.fill.opacity) != null ? _b : 1;
42847
43990
  let y1 = 0;
42848
43991
  let rev = false;
42849
43992
  this.negRange = this.helpers.checkColorRange();
@@ -42860,7 +44003,9 @@ var __async = (__this, __arguments, generator) => {
42860
44003
  "data:realIndex": i
42861
44004
  });
42862
44005
  Series.addCollapsedClassToSeries(this.w, elSeries, i);
42863
- graphics.setupEventDelegation(elSeries, ".apexcharts-heatmap-rect");
44006
+ if (!useCanvas) {
44007
+ graphics.setupEventDelegation(elSeries, ".apexcharts-heatmap-rect");
44008
+ }
42864
44009
  if (w.config.chart.dropShadow.enabled) {
42865
44010
  const shadow = w.config.chart.dropShadow;
42866
44011
  const filters = new Filters(this.w);
@@ -42870,13 +44015,22 @@ var __async = (__this, __arguments, generator) => {
42870
44015
  const shadeIntensity = w.config.plotOptions.heatmap.shadeIntensity;
42871
44016
  let j = 0;
42872
44017
  for (let dIndex = 0; dIndex < w.globals.dataPoints; dIndex++) {
42873
- if (w.seriesData.seriesX.length && !w.globals.allSeriesHasEqualX) {
44018
+ if (!isContinuousX && w.seriesData.seriesX.length && !w.globals.allSeriesHasEqualX) {
42874
44019
  if (w.globals.minX + w.globals.minXDiff * dIndex < w.seriesData.seriesX[i][j]) {
42875
44020
  x1 = x1 + xDivision;
42876
44021
  continue;
42877
44022
  }
42878
44023
  }
42879
44024
  if (j >= heatSeries[i].length) break;
44025
+ const cellW = isContinuousX ? binPx : xDivision;
44026
+ if (isContinuousX) {
44027
+ const xVal = w.seriesData.seriesX[i] ? w.seriesData.seriesX[i][j] : null;
44028
+ if (xVal == null || xVal !== xVal) {
44029
+ j++;
44030
+ continue;
44031
+ }
44032
+ x1 = (xVal - w.globals.minX) / this.xRatio - binPx / 2;
44033
+ }
42880
44034
  const heatColor = this.helpers.getShadeColor(
42881
44035
  w.config.chart.type,
42882
44036
  i,
@@ -42895,47 +44049,60 @@ var __async = (__this, __arguments, generator) => {
42895
44049
  w.globals.hasNegs ? heatColorProps.percent < 0 ? 1 - (1 + heatColorProps.percent / 100) : shadeIntensity + heatColorProps.percent / 100 : heatColorProps.percent / 100
42896
44050
  ),
42897
44051
  patternID: Utils$1.randomId(),
42898
- width: w.config.fill.image.width ? w.config.fill.image.width : xDivision,
44052
+ width: w.config.fill.image.width ? w.config.fill.image.width : cellW,
42899
44053
  height: w.config.fill.image.height ? w.config.fill.image.height : yDivision
42900
44054
  });
42901
44055
  }
42902
44056
  const radius = this.rectRadius;
42903
- const rect = graphics.drawRect(x1, y1, xDivision, yDivision, radius);
42904
- rect.attr({
42905
- cx: x1,
42906
- cy: y1
42907
- });
42908
- rect.node.classList.add("apexcharts-heatmap-rect");
42909
- elSeries.add(rect);
42910
- rect.attr({
42911
- fill: color,
42912
- i,
42913
- index: i,
42914
- j,
42915
- val: series[i][j],
42916
- "stroke-width": this.strokeWidth,
42917
- stroke: w.config.plotOptions.heatmap.useFillColorAsStroke ? color : w.globals.stroke.colors[0],
42918
- color
42919
- });
42920
- if (w.config.chart.animations.enabled && !w.globals.dataChanged) {
42921
- let speed = 1;
42922
- if (!w.globals.resized) {
42923
- speed = w.config.chart.animations.speed;
42924
- }
42925
- this.animateHeatMap(rect, x1, y1, xDivision, yDivision, speed, i, j);
42926
- }
42927
- if (w.globals.dataChanged) {
42928
- let speed = 1;
42929
- if (this.dynamicAnim.enabled && w.globals.shouldAnimate) {
42930
- speed = this.dynamicAnim.speed;
42931
- let colorFrom = w.globals.previousPaths[i] && w.globals.previousPaths[i][j] && w.globals.previousPaths[i][j].color;
42932
- if (!colorFrom) colorFrom = "rgba(255, 255, 255, 0)";
42933
- this.animateHeatColor(
42934
- rect,
42935
- Utils$1.isColorHex(colorFrom) ? colorFrom : Utils$1.rgb2hex(colorFrom),
42936
- Utils$1.isColorHex(color) ? color : Utils$1.rgb2hex(color),
42937
- speed
42938
- );
44057
+ const stroke = w.config.plotOptions.heatmap.useFillColorAsStroke ? color : w.globals.stroke.colors[0];
44058
+ if (useCanvas) {
44059
+ emit.drawRectCell(x1, y1, cellW, yDivision, {
44060
+ fill: color,
44061
+ fillOpacity: cellFillOpacity,
44062
+ stroke,
44063
+ strokeWidth: this.strokeWidth,
44064
+ radius,
44065
+ seriesIndex: i,
44066
+ dataPointIndex: j
44067
+ });
44068
+ } else {
44069
+ const rect = graphics.drawRect(x1, y1, cellW, yDivision, radius);
44070
+ rect.attr({
44071
+ cx: x1,
44072
+ cy: y1
44073
+ });
44074
+ rect.node.classList.add("apexcharts-heatmap-rect");
44075
+ elSeries.add(rect);
44076
+ rect.attr({
44077
+ fill: color,
44078
+ i,
44079
+ index: i,
44080
+ j,
44081
+ val: series[i][j],
44082
+ "stroke-width": this.strokeWidth,
44083
+ stroke,
44084
+ color
44085
+ });
44086
+ if (w.config.chart.animations.enabled && !w.globals.dataChanged) {
44087
+ let speed = 1;
44088
+ if (!w.globals.resized) {
44089
+ speed = w.config.chart.animations.speed;
44090
+ }
44091
+ this.animateHeatMap(rect, x1, y1, cellW, yDivision, speed, i, j);
44092
+ }
44093
+ if (w.globals.dataChanged) {
44094
+ let speed = 1;
44095
+ if (this.dynamicAnim.enabled && w.globals.shouldAnimate) {
44096
+ speed = this.dynamicAnim.speed;
44097
+ let colorFrom = w.globals.previousPaths[i] && w.globals.previousPaths[i][j] && w.globals.previousPaths[i][j].color;
44098
+ if (!colorFrom) colorFrom = "rgba(255, 255, 255, 0)";
44099
+ this.animateHeatColor(
44100
+ rect,
44101
+ Utils$1.isColorHex(colorFrom) ? colorFrom : Utils$1.rgb2hex(colorFrom),
44102
+ Utils$1.isColorHex(color) ? color : Utils$1.rgb2hex(color),
44103
+ speed
44104
+ );
44105
+ }
42939
44106
  }
42940
44107
  }
42941
44108
  const formatter = w.config.dataLabels.formatter;
@@ -42947,7 +44114,7 @@ var __async = (__this, __arguments, generator) => {
42947
44114
  });
42948
44115
  const dataLabels = this.helpers.calculateDataLabels({
42949
44116
  text: formattedText,
42950
- x: x1 + xDivision / 2,
44117
+ x: x1 + cellW / 2,
42951
44118
  y: y1 + yDivision / 2,
42952
44119
  i,
42953
44120
  j,
@@ -42957,7 +44124,7 @@ var __async = (__this, __arguments, generator) => {
42957
44124
  if (dataLabels !== null) {
42958
44125
  elSeries.add(dataLabels);
42959
44126
  }
42960
- x1 = x1 + xDivision;
44127
+ if (!isContinuousX) x1 = x1 + xDivision;
42961
44128
  j++;
42962
44129
  }
42963
44130
  y1 = y1 + yDivision;
@@ -43953,7 +45120,7 @@ var __async = (__this, __arguments, generator) => {
43953
45120
  let { pathFromLine, pathFromArea } = pathsFrom;
43954
45121
  const r = this.ctx && this.ctx.renderer;
43955
45122
  const canvasMode = !!(r && r.kind && r.kind !== "svg");
43956
- const buildStrings = !canvasMode || w.globals.dataChanged;
45123
+ const buildStrings = !canvasMode || w.globals.dataChanged && !!w.globals.prevStreamFrame;
43957
45124
  const nxs = canvasMode ? new Float64Array(n) : null;
43958
45125
  const nys = canvasMode ? new Float64Array(n) : null;
43959
45126
  if (nxs && nys) {