apexcharts 6.2.0 → 6.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/dist/apexcharts.common.js +2 -2
  2. package/dist/apexcharts.esm.js +611 -96
  3. package/dist/apexcharts.js +611 -96
  4. package/dist/apexcharts.min.js +2 -2
  5. package/dist/apexcharts.ssr.common.js +2 -2
  6. package/dist/apexcharts.ssr.esm.js +611 -96
  7. package/dist/area.common.js +2 -2
  8. package/dist/area.esm.js +2 -2
  9. package/dist/bar.common.js +1 -1
  10. package/dist/bar.esm.js +1 -1
  11. package/dist/boxPlot.common.js +1 -1
  12. package/dist/boxPlot.esm.js +1 -1
  13. package/dist/bubble.common.js +2 -2
  14. package/dist/bubble.esm.js +2 -2
  15. package/dist/candlestick.common.js +1 -1
  16. package/dist/candlestick.esm.js +1 -1
  17. package/dist/column.common.js +1 -1
  18. package/dist/column.esm.js +1 -1
  19. package/dist/core.common.js +2 -2
  20. package/dist/core.esm.js +578 -76
  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 +33 -20
  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 +15 -1
  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 +1 -1
  62. package/dist/heatmap.esm.js +1 -1
  63. package/dist/line.common.js +2 -2
  64. package/dist/line.esm.js +2 -2
  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 +2 -2
  75. package/dist/rangeBar.common.js +1 -1
  76. package/dist/rangeBar.esm.js +1 -1
  77. package/dist/scatter.common.js +2 -2
  78. package/dist/scatter.esm.js +2 -2
  79. package/dist/treemap.common.js +1 -1
  80. package/dist/treemap.esm.js +1 -1
  81. package/dist/violin.common.js +1 -1
  82. package/dist/violin.esm.js +1 -1
  83. package/package.json +1 -1
  84. package/src/apexcharts.js +300 -33
  85. package/src/charts/Line.js +7 -5
  86. package/src/modules/Core.js +19 -0
  87. package/src/modules/Crosshairs.js +24 -5
  88. package/src/modules/Data.js +198 -14
  89. package/src/modules/Range.js +160 -32
  90. package/src/modules/Series.js +19 -0
  91. package/src/modules/ZoomPanSelection.js +16 -11
  92. package/src/modules/helpers/UpdateHelpers.js +16 -5
  93. package/src/modules/settings/Globals.js +50 -1
  94. package/src/modules/tooltip/AxesTooltip.js +7 -1
  95. package/src/modules/tooltip/Utils.js +5 -1
  96. package/src/renderers/canvas/CanvasRenderer.js +16 -0
  97. package/src/types/internal.d.ts +23 -0
@@ -54,7 +54,7 @@ var __async = (__this, __arguments, generator) => {
54
54
  });
55
55
  };
56
56
  /*!
57
- * ApexCharts v6.2.0
57
+ * ApexCharts v6.3.0
58
58
  * (c) 2018-2026 ApexCharts
59
59
  */
60
60
 
@@ -5765,14 +5765,54 @@ var __async = (__this, __arguments, generator) => {
5765
5765
  globals
5766
5766
  );
5767
5767
  }
5768
+ /**
5769
+ * Lazy initial-series snapshot. Capturing `initialSeries` used to deep-clone
5770
+ * the entire series on every parse and every update: the single largest CPU
5771
+ * bucket at 50k+ points (profiled at ~23ms per 50k update). The setter now
5772
+ * stores a cheap per-series shallow copy (series OBJECTS copied, data arrays
5773
+ * shared) and the deep snapshot materializes only when something actually
5774
+ * reads it (resetSeries, toolbar reset-home, tooltip same-length check).
5775
+ *
5776
+ * Why sharing the data arrays is safe: internal "mutations" of a series'
5777
+ * data are property REPLACEMENTS (`series[i].data = []` on legend collapse),
5778
+ * which cannot reach the captured copies because each series object was
5779
+ * copied at capture time. The one in-place mutator (appendData's push loop)
5780
+ * re-captures immediately after mutating, so the pending snapshot never
5781
+ * spans the mutation.
5782
+ *
5783
+ * @param {Record<string, any>} globals
5784
+ */
5785
+ defineLazyInitialSeries(globals) {
5786
+ let src = [];
5787
+ let snap = null;
5788
+ Object.defineProperty(globals, "initialSeries", {
5789
+ configurable: true,
5790
+ enumerable: true,
5791
+ get() {
5792
+ if (snap === null) {
5793
+ snap = Utils$1.clone(src);
5794
+ }
5795
+ return snap;
5796
+ },
5797
+ set(value) {
5798
+ src = Array.isArray(value) ? value.map(
5799
+ (s) => s && typeof s === "object" && !Array.isArray(s) ? __spreadValues({}, s) : s
5800
+ ) : value;
5801
+ snap = null;
5802
+ globals._initialSeriesPeek = src;
5803
+ }
5804
+ });
5805
+ globals._initialSeriesPeek = src;
5806
+ }
5768
5807
  /**
5769
5808
  * @param {Record<string, any>} config
5770
5809
  */
5771
5810
  init(config) {
5772
5811
  const globals = this.globalVars(config);
5773
5812
  this.initGlobalVars(globals);
5813
+ this.defineLazyInitialSeries(globals);
5774
5814
  globals.initialConfig = Utils$1.extend({}, config);
5775
- globals.initialSeries = Utils$1.clone(config.series);
5815
+ globals.initialSeries = config.series;
5776
5816
  globals.lastXAxis = Utils$1.clone(
5777
5817
  /** @type {NonNullable<typeof globals.initialConfig>} */
5778
5818
  globals.initialConfig.xaxis
@@ -12728,7 +12768,7 @@ var __async = (__this, __arguments, generator) => {
12728
12768
  * @param {number | null} [endingSeriesIndex]
12729
12769
  */
12730
12770
  getMinYMaxY(startingSeriesIndex, lowestY = Number.MAX_VALUE, highestY = -Number.MAX_VALUE, endingSeriesIndex = null) {
12731
- var _a, _b, _c, _d, _e, _f, _g, _h;
12771
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
12732
12772
  const cnf = this.w.config;
12733
12773
  const gl = this.w.globals;
12734
12774
  let maxY = -Number.MAX_VALUE;
@@ -12792,14 +12832,68 @@ var __async = (__this, __arguments, generator) => {
12792
12832
  }
12793
12833
  }
12794
12834
  }
12835
+ 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);
12836
+ if (plainNumeric) {
12837
+ const arr = series[i];
12838
+ const jEnd = Math.min(lastXIndex, arr.length - 1);
12839
+ const pe = (_b = this.w.seriesData._parsedExtrema) == null ? void 0 : _b[i];
12840
+ if (pe && pe.ref === arr && pe.len === arr.length && firstXIndex === 0 && jEnd === arr.length - 1) {
12841
+ if (pe.maxY > maxY) maxY = pe.maxY;
12842
+ if (pe.lowestY < lowestY) lowestY = pe.lowestY;
12843
+ if (pe.negMinY < 0 && pe.negMinY < minY) minY = pe.negMinY;
12844
+ if (pe.yDec > gl.yValueDecimal) gl.yValueDecimal = pe.yDec;
12845
+ if (pe.hasNulls) gl.hasNullValues = true;
12846
+ } else {
12847
+ let yDec = gl.yValueDecimal;
12848
+ let hasNulls = false;
12849
+ for (let j = firstXIndex; j <= jEnd; j++) {
12850
+ const val = arr[j];
12851
+ if (val !== null && typeof val === "number" && val === val && val !== Infinity && val !== -Infinity) {
12852
+ if (val > maxY) maxY = val;
12853
+ if (val < lowestY) lowestY = val;
12854
+ if (minY > val && val < 0) minY = val;
12855
+ if (!Number.isInteger(val)) {
12856
+ const av = val < 0 ? -val : val;
12857
+ if (av >= 1e-6 && av < 1e21) {
12858
+ const str = "" + val;
12859
+ const dot = str.indexOf(".");
12860
+ const dec = dot === -1 ? 0 : str.length - dot - 1;
12861
+ if (dec > yDec) yDec = dec;
12862
+ } else {
12863
+ const nv = Utils$1.noExponents(val);
12864
+ if (Utils$1.isFloat(nv)) {
12865
+ yDec = Math.max(yDec, nv.toString().split(".")[1].length);
12866
+ }
12867
+ }
12868
+ }
12869
+ } else {
12870
+ hasNulls = true;
12871
+ }
12872
+ }
12873
+ gl.yValueDecimal = yDec;
12874
+ if (hasNulls) gl.hasNullValues = true;
12875
+ }
12876
+ highestY = maxY;
12877
+ if (seriesType === "bar" || seriesType === "column") {
12878
+ if (minY < 0 && maxY < 0) {
12879
+ maxY = 0;
12880
+ highestY = Math.max(highestY, 0);
12881
+ }
12882
+ if (minY === Number.MIN_VALUE) {
12883
+ minY = 0;
12884
+ lowestY = Math.min(lowestY, 0);
12885
+ }
12886
+ }
12887
+ continue;
12888
+ }
12795
12889
  for (let j = firstXIndex; j <= lastXIndex && j < this.w.seriesData.series[i].length; j++) {
12796
12890
  let val = series[i][j];
12797
12891
  if (val !== null && Utils$1.isNumber(val)) {
12798
- if (typeof ((_b = seriesMax[i]) == null ? void 0 : _b[j]) !== "undefined") {
12892
+ if (typeof ((_c = seriesMax[i]) == null ? void 0 : _c[j]) !== "undefined") {
12799
12893
  maxY = Math.max(maxY, seriesMax[i][j]);
12800
12894
  lowestY = Math.min(lowestY, seriesMax[i][j]);
12801
12895
  }
12802
- if (typeof ((_c = seriesMin[i]) == null ? void 0 : _c[j]) !== "undefined") {
12896
+ if (typeof ((_d = seriesMin[i]) == null ? void 0 : _d[j]) !== "undefined") {
12803
12897
  lowestY = Math.min(lowestY, seriesMin[i][j]);
12804
12898
  highestY = Math.max(highestY, seriesMin[i][j]);
12805
12899
  }
@@ -12828,7 +12922,7 @@ var __async = (__this, __arguments, generator) => {
12828
12922
  break;
12829
12923
  case "violin":
12830
12924
  {
12831
- if (typeof ((_d = this.w.violinData.seriesViolinMax[i]) == null ? void 0 : _d[j]) !== "undefined") {
12925
+ if (typeof ((_e = this.w.violinData.seriesViolinMax[i]) == null ? void 0 : _e[j]) !== "undefined") {
12832
12926
  maxY = Math.max(maxY, this.w.violinData.seriesViolinMax[i][j]);
12833
12927
  lowestY = Math.min(
12834
12928
  lowestY,
@@ -12851,7 +12945,7 @@ var __async = (__this, __arguments, generator) => {
12851
12945
  );
12852
12946
  }
12853
12947
  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];
12948
+ const boxPts = (_g = (_f = this.w.candleData.seriesBoxPoints) == null ? void 0 : _f[i]) == null ? void 0 : _g[j];
12855
12949
  if (boxPts) {
12856
12950
  for (let p = 0; p < boxPts.length; p++) {
12857
12951
  const pv = boxPts[p];
@@ -12870,7 +12964,7 @@ var __async = (__this, __arguments, generator) => {
12870
12964
  val.toString().split(".")[1].length
12871
12965
  );
12872
12966
  }
12873
- if (minY > ((_g = seriesMin[i]) == null ? void 0 : _g[j]) && ((_h = seriesMin[i]) == null ? void 0 : _h[j]) < 0) {
12967
+ if (minY > ((_h = seriesMin[i]) == null ? void 0 : _h[j]) && ((_i = seriesMin[i]) == null ? void 0 : _i[j]) < 0) {
12874
12968
  minY = seriesMin[i][j];
12875
12969
  }
12876
12970
  } else {
@@ -13024,38 +13118,33 @@ var __async = (__this, __arguments, generator) => {
13024
13118
  const cnf = this.w.config;
13025
13119
  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
13120
  const getInitialMinXMaxX = () => {
13121
+ var _a;
13122
+ let minX = gl.minX;
13123
+ let maxX = gl.maxX;
13027
13124
  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
- }
13125
+ const lbls = (
13126
+ /** @type {any} */
13127
+ this.w.labelData.labels[i]
13128
+ );
13129
+ if (!lbls) continue;
13130
+ const pe = (_a = this.w.seriesData._parsedExtrema) == null ? void 0 : _a[i];
13131
+ if (pe && pe.xNumeric && pe.xref === lbls && pe.len === lbls.length) {
13132
+ if (pe.maxX > maxX) maxX = pe.maxX;
13133
+ if (pe.minX < minX) minX = pe.minX;
13134
+ continue;
13135
+ }
13136
+ for (let j = 0; j < lbls.length; j++) {
13137
+ const v = lbls[j];
13138
+ if (v !== null && typeof v === "number" && v === v) {
13139
+ if (v > maxX) maxX = v;
13140
+ if (v < minX) minX = v;
13056
13141
  }
13057
13142
  }
13058
13143
  }
13144
+ gl.maxX = maxX;
13145
+ gl.initialMaxX = maxX;
13146
+ gl.minX = minX;
13147
+ gl.initialMinX = minX;
13059
13148
  };
13060
13149
  if (this.w.axisFlags.isXNumeric) {
13061
13150
  getInitialMinXMaxX();
@@ -13197,13 +13286,40 @@ var __async = (__this, __arguments, generator) => {
13197
13286
  _getMinXDiff() {
13198
13287
  const gl = this.w.globals;
13199
13288
  if (this.w.axisFlags.isXNumeric) {
13200
- this.w.seriesData.seriesX.forEach((sX) => {
13289
+ this.w.seriesData.seriesX.forEach((sX, si) => {
13290
+ var _a;
13201
13291
  if (sX.length) {
13202
13292
  if (sX.length === 1) {
13203
13293
  sX.push(
13204
13294
  this.w.seriesData.seriesX[gl.maxValsInArrayIndex][this.w.seriesData.seriesX[gl.maxValsInArrayIndex].length - 1]
13205
13295
  );
13206
13296
  }
13297
+ const pe = (_a = this.w.seriesData._parsedExtrema) == null ? void 0 : _a[si];
13298
+ if (pe && pe.xNumeric && pe.xSorted && pe.xref === sX && pe.len === sX.length) {
13299
+ if (pe.minXDiff < gl.minXDiff) gl.minXDiff = pe.minXDiff;
13300
+ if (gl.dataPoints === 1 || gl.minXDiff === Number.MAX_VALUE) {
13301
+ gl.minXDiff = 0.5;
13302
+ }
13303
+ return;
13304
+ }
13305
+ let presorted = true;
13306
+ let minDiff = gl.minXDiff;
13307
+ for (let j = 1; j < sX.length; j++) {
13308
+ const d = sX[j] - sX[j - 1];
13309
+ if (d > 0) {
13310
+ if (d < minDiff) minDiff = d;
13311
+ } else if (d < 0) {
13312
+ presorted = false;
13313
+ break;
13314
+ }
13315
+ }
13316
+ if (presorted) {
13317
+ gl.minXDiff = minDiff;
13318
+ if (gl.dataPoints === 1 || gl.minXDiff === Number.MAX_VALUE) {
13319
+ gl.minXDiff = 0.5;
13320
+ }
13321
+ return;
13322
+ }
13207
13323
  const seriesX = sX.slice();
13208
13324
  seriesX.sort((a, b) => a - b);
13209
13325
  seriesX.forEach((s, j) => {
@@ -13980,6 +14096,7 @@ var __async = (__this, __arguments, generator) => {
13980
14096
  }
13981
14097
  drawXCrosshairs() {
13982
14098
  const w = this.w;
14099
+ w.dom.elGraphical.node.querySelectorAll(":scope > .apexcharts-xcrosshairs").forEach((el) => el.remove());
13983
14100
  const graphics = new Graphics(this.w);
13984
14101
  const filters = new Filters(this.w);
13985
14102
  const crosshairGradient = w.config.xaxis.crosshairs.fill.gradient;
@@ -14011,10 +14128,7 @@ var __async = (__this, __arguments, generator) => {
14011
14128
  []
14012
14129
  );
14013
14130
  }
14014
- let xcrosshairs = graphics.drawRect();
14015
- if (w.config.xaxis.crosshairs.width === 1) {
14016
- xcrosshairs = graphics.drawLine(0, 0, 0, 0);
14017
- }
14131
+ let xcrosshairs = w.config.xaxis.crosshairs.width === 1 ? graphics.drawLine(0, 0, 0, 0) : graphics.drawRect();
14018
14132
  let gridHeight = w.layout.gridHeight;
14019
14133
  if (!Utils$1.isNumber(gridHeight) || gridHeight < 0) {
14020
14134
  gridHeight = 0;
@@ -14051,6 +14165,9 @@ var __async = (__this, __arguments, generator) => {
14051
14165
  }
14052
14166
  drawYCrosshairs() {
14053
14167
  const w = this.w;
14168
+ w.dom.elGraphical.node.querySelectorAll(
14169
+ ":scope > .apexcharts-ycrosshairs, :scope > .apexcharts-ycrosshairs-hidden"
14170
+ ).forEach((el) => el.remove());
14054
14171
  const graphics = new Graphics(this.w);
14055
14172
  const crosshair = (
14056
14173
  /** @type {any[]} */
@@ -15241,6 +15358,24 @@ var __async = (__this, __arguments, generator) => {
15241
15358
  (_a = this._toggleDataSeries) == null ? void 0 : _a.call(this, isSeriesHidden.realIndex, false);
15242
15359
  }
15243
15360
  }
15361
+ /**
15362
+ * Cheap pre-update reset for the data-replacement paths (updateSeries /
15363
+ * appendSeries). Clears the same bookkeeping resetSeries() clears (series
15364
+ * cache, previous paths, collapsed-series state) WITHOUT restoring
15365
+ * config.series from the initialSeries snapshot: the caller is about to
15366
+ * replace the series anyway (parseData assigns config.series = newSeries),
15367
+ * so materializing and cloning the snapshot per update is pure waste (two
15368
+ * O(n) deep clones per streaming tick at 50k points).
15369
+ */
15370
+ prepareDataUpdate() {
15371
+ const w = this.w;
15372
+ this.clearSeriesCache();
15373
+ w.globals.previousPaths = [];
15374
+ w.globals.collapsedSeries = [];
15375
+ w.globals.ancillaryCollapsedSeries = [];
15376
+ w.globals.collapsedSeriesIndices = [];
15377
+ w.globals.ancillaryCollapsedSeriesIndices = [];
15378
+ }
15244
15379
  resetSeries(shouldUpdateChart = true, shouldResetZoom = true, shouldResetCollapsed = true) {
15245
15380
  var _a, _b;
15246
15381
  const w = this.w;
@@ -17742,6 +17877,24 @@ var __async = (__this, __arguments, generator) => {
17742
17877
  }
17743
17878
  }
17744
17879
  if (canvasMode) {
17880
+ const rr = (
17881
+ /** @type {any} */
17882
+ ctx.renderer
17883
+ );
17884
+ if (rr && rr._repaintHostInPlace) {
17885
+ rr._repaintHostInPlace = false;
17886
+ const wrapNode = this.w.dom.elGraphical.node.querySelector(
17887
+ ".apexcharts-canvas-series-wrap"
17888
+ );
17889
+ if (wrapNode && rr.canRepaintInPlace && rr.canRepaintInPlace()) {
17890
+ rr.repaintInPlace();
17891
+ const groups = Array.isArray(elGraph) ? elGraph : [elGraph];
17892
+ groups.forEach((g) => {
17893
+ if (g && g.node) wrapNode.appendChild(g.node);
17894
+ });
17895
+ return [];
17896
+ }
17897
+ }
17745
17898
  const host = ctx.renderer.present();
17746
17899
  if (host) {
17747
17900
  const wrap = new Graphics(w).group({
@@ -18139,6 +18292,108 @@ var __async = (__this, __arguments, generator) => {
18139
18292
  const firstDataPoint = this.getFirstDataPoint();
18140
18293
  return firstDataPoint && Array.isArray(firstDataPoint);
18141
18294
  }
18295
+ /**
18296
+ * Typed single pass for the dominant [[x, y], ...] shape: scalar numeric or
18297
+ * null y, no z, no OHLC tuples. One monomorphic loop fills preallocated
18298
+ * x/y arrays and fuses the y-extrema scan that Range.getMinYMaxY would
18299
+ * otherwise repeat over every value (the extrema entry is ref+length
18300
+ * guarded, so any later reshaping of the series array simply falls back to
18301
+ * the scan). Returns false untouched on any non-conforming point so the
18302
+ * general loop below handles mixed/exotic data with unchanged output.
18303
+ * @param {any[]} data
18304
+ * @param {number} i
18305
+ * @returns {boolean}
18306
+ */
18307
+ _fast2DArrayParse(data, i) {
18308
+ var _a, _b;
18309
+ const n = data.length;
18310
+ if (n === 0) return false;
18311
+ const ys = new Array(n);
18312
+ const xs = new Array(n);
18313
+ let maxY = -Number.MAX_VALUE;
18314
+ let lowestY = Number.MAX_VALUE;
18315
+ let negMinY = Infinity;
18316
+ let hasNulls = false;
18317
+ let yDec = 0;
18318
+ let xNumeric = true;
18319
+ let minX = Infinity;
18320
+ let maxX = -Infinity;
18321
+ let xSorted = true;
18322
+ let minXDiff = Infinity;
18323
+ let prevX = NaN;
18324
+ for (let j = 0; j < n; j++) {
18325
+ const point = data[j];
18326
+ if (!Array.isArray(point) || point.length > 2) return false;
18327
+ const x = point[0];
18328
+ const y = point[1];
18329
+ if (xNumeric) {
18330
+ if (typeof x === "number") {
18331
+ if (x === x) {
18332
+ if (x < minX) minX = x;
18333
+ if (x > maxX) maxX = x;
18334
+ }
18335
+ const d = x - prevX;
18336
+ if (d > 0) {
18337
+ if (d < minXDiff) minXDiff = d;
18338
+ } else if (d < 0) {
18339
+ xSorted = false;
18340
+ }
18341
+ prevX = x;
18342
+ } else {
18343
+ xNumeric = false;
18344
+ }
18345
+ }
18346
+ if (typeof y === "number") {
18347
+ if (y === y && y !== Infinity && y !== -Infinity) {
18348
+ if (y > maxY) maxY = y;
18349
+ if (y < lowestY) lowestY = y;
18350
+ if (y < 0 && y < negMinY) negMinY = y;
18351
+ if (!Number.isInteger(y)) {
18352
+ const av = y < 0 ? -y : y;
18353
+ if (av >= 1e-6 && av < 1e21) {
18354
+ const str = "" + y;
18355
+ const dot = str.indexOf(".");
18356
+ const dec = dot === -1 ? 0 : str.length - dot - 1;
18357
+ if (dec > yDec) yDec = dec;
18358
+ } else {
18359
+ const nv = Utils$1.noExponents(y);
18360
+ if (Utils$1.isFloat(nv)) {
18361
+ yDec = Math.max(yDec, nv.toString().split(".")[1].length);
18362
+ }
18363
+ }
18364
+ }
18365
+ } else {
18366
+ hasNulls = true;
18367
+ }
18368
+ } else if (y === null) {
18369
+ hasNulls = true;
18370
+ } else {
18371
+ return false;
18372
+ }
18373
+ ys[j] = y;
18374
+ xs[j] = x;
18375
+ }
18376
+ this.twoDSeries = ys;
18377
+ this.twoDSeriesX = xs;
18378
+ this.w.axisFlags.dataFormatXNumeric = true;
18379
+ const extrema = (_b = (_a = this.w.seriesData)._parsedExtrema) != null ? _b : _a._parsedExtrema = [];
18380
+ extrema[i] = {
18381
+ ref: ys,
18382
+ len: n,
18383
+ maxY,
18384
+ lowestY,
18385
+ negMinY,
18386
+ hasNulls,
18387
+ yDec,
18388
+ xref: xs,
18389
+ xNumeric,
18390
+ minX,
18391
+ maxX,
18392
+ xSorted,
18393
+ minXDiff
18394
+ };
18395
+ return true;
18396
+ }
18142
18397
  /**
18143
18398
  * @param {any[]} ser
18144
18399
  * @param {number} i
@@ -18148,6 +18403,9 @@ var __async = (__this, __arguments, generator) => {
18148
18403
  const data = ser[i].data;
18149
18404
  const isBoxPlot = cnf.chart.type === "boxPlot" || /** @type {any} */
18150
18405
  cnf.series[i].type === "boxPlot";
18406
+ if (!isBoxPlot && cnf.xaxis.type !== "datetime" && this._fast2DArrayParse(data, i)) {
18407
+ return;
18408
+ }
18151
18409
  for (let j = 0; j < data.length; j++) {
18152
18410
  const point = data[j];
18153
18411
  const x = point[0];
@@ -18544,6 +18802,7 @@ var __async = (__this, __arguments, generator) => {
18544
18802
  const cnf = this.w.config;
18545
18803
  const gl = this.w.globals;
18546
18804
  const dt = new DateTime(this.w);
18805
+ this.w.seriesData._parsedExtrema = [];
18547
18806
  const xlabels = cnf.labels.length > 0 ? cnf.labels.slice() : cnf.xaxis.categories.slice();
18548
18807
  this.w.axisFlags.isRangeBar = cnf.chart.type === "rangeBar" && gl.isBarHorizontal;
18549
18808
  this.w.labelData.hasXaxisGroups = cnf.xaxis.type === "category" && cnf.xaxis.group.groups.length > 0;
@@ -18933,7 +19192,11 @@ var __async = (__this, __arguments, generator) => {
18933
19192
  if (this.w.axisFlags.dataWasParsed) {
18934
19193
  return series;
18935
19194
  }
18936
- if (!globalParsing && !series.some((s) => s.parsing)) {
19195
+ const hasGlobalParsing = !!(globalParsing && (globalParsing.x || globalParsing.y || globalParsing.z));
19196
+ const hasSeriesParsing = series.some(
19197
+ (s) => s.parsing && (s.parsing.x || s.parsing.y || s.parsing.z)
19198
+ );
19199
+ if (!hasGlobalParsing && !hasSeriesParsing) {
18937
19200
  return series;
18938
19201
  }
18939
19202
  const processedSeries = series.map((serie, index) => {
@@ -19236,7 +19499,7 @@ var __async = (__this, __arguments, generator) => {
19236
19499
  });
19237
19500
  });
19238
19501
  } else {
19239
- gl.initialSeries = Utils$1.clone(ser);
19502
+ gl.initialSeries = ser;
19240
19503
  }
19241
19504
  this.excludeCollapsedSeriesInYAxis();
19242
19505
  this.fallbackToCategory = false;
@@ -19256,10 +19519,23 @@ var __async = (__this, __arguments, generator) => {
19256
19519
  }
19257
19520
  this.coreUtils.getSeriesTotals();
19258
19521
  if (gl.axisCharts) {
19259
- this.w.seriesData.stackedSeriesTotals = this.coreUtils.getStackedSeriesTotals();
19260
- this.w.seriesData.stackedSeriesTotalsByGroups = this.coreUtils.getStackedSeriesTotalsByGroups();
19522
+ Data._defineLazyResult(
19523
+ this.w.seriesData,
19524
+ "stackedSeriesTotals",
19525
+ () => this.coreUtils.getStackedSeriesTotals()
19526
+ );
19527
+ Data._defineLazyResult(
19528
+ this.w.seriesData,
19529
+ "stackedSeriesTotalsByGroups",
19530
+ () => this.coreUtils.getStackedSeriesTotalsByGroups()
19531
+ );
19532
+ Data._defineLazyResult(gl, "seriesPercent", () => {
19533
+ this.coreUtils.getPercentSeries();
19534
+ return gl.seriesPercent;
19535
+ });
19536
+ } else {
19537
+ this.coreUtils.getPercentSeries();
19261
19538
  }
19262
- this.coreUtils.getPercentSeries();
19263
19539
  if (!this.w.axisFlags.dataFormatXNumeric && (!this.w.axisFlags.isXNumeric || cnf.xaxis.type === "numeric" && cnf.labels.length === 0 && cnf.xaxis.categories.length === 0)) {
19264
19540
  this.handleExternalLabelsData(ser);
19265
19541
  }
@@ -19272,6 +19548,12 @@ var __async = (__this, __arguments, generator) => {
19272
19548
  }
19273
19549
  return {
19274
19550
  // w.seriesData (future slice)
19551
+ // initialSeries/originalSeries and the stacked totals are deliberately
19552
+ // ABSENT: they already live as lazy accessors on gl / w.seriesData, so
19553
+ // a snapshot field would either force their materialization (a deep
19554
+ // clone plus three O(n) passes per parse that most charts never need)
19555
+ // or, as a delegating getter, recurse into itself when a writer copies
19556
+ // it back onto the object it delegates to.
19275
19557
  seriesData: {
19276
19558
  series: this.w.seriesData.series,
19277
19559
  seriesNames: this.w.seriesData.seriesNames,
@@ -19279,10 +19561,6 @@ var __async = (__this, __arguments, generator) => {
19279
19561
  seriesZ: this.w.seriesData.seriesZ,
19280
19562
  seriesColors: this.w.seriesData.seriesColors,
19281
19563
  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
19564
  noLabelsProvided: this.w.axisFlags.noLabelsProvided
19287
19565
  },
19288
19566
  // w.rangeData (future slice)
@@ -19331,6 +19609,40 @@ var __async = (__this, __arguments, generator) => {
19331
19609
  * @param {number|null|undefined} xmax
19332
19610
  * @returns {any[]} Sliced array (new array, never the input reference).
19333
19611
  */
19612
+ /**
19613
+ * Define `key` on `obj` as a lazily computed property: `compute` runs on
19614
+ * first read after this call and its result is cached; assigning to the
19615
+ * property stores the assigned value directly (so code that writes the
19616
+ * field, like getPercentSeries, keeps working). Re-calling resets the cache
19617
+ * (used once per parse).
19618
+ * @param {any} obj
19619
+ * @param {string} key
19620
+ * @param {() => any} compute
19621
+ */
19622
+ static _defineLazyResult(obj, key, compute) {
19623
+ let has = false;
19624
+ let value;
19625
+ Object.defineProperty(obj, key, {
19626
+ configurable: true,
19627
+ enumerable: true,
19628
+ get() {
19629
+ if (!has) {
19630
+ has = true;
19631
+ value = compute();
19632
+ }
19633
+ return value;
19634
+ },
19635
+ set(v) {
19636
+ has = true;
19637
+ value = v;
19638
+ }
19639
+ });
19640
+ }
19641
+ /**
19642
+ * @param {any[]} data
19643
+ * @param {any} xmin
19644
+ * @param {any} xmax
19645
+ */
19334
19646
  static sliceByXRange(data, xmin, xmax) {
19335
19647
  const len = data.length;
19336
19648
  if (len === 0) return data;
@@ -19554,7 +19866,7 @@ var __async = (__this, __arguments, generator) => {
19554
19866
  if (!redraw) {
19555
19867
  w.globals.resized = true;
19556
19868
  w.globals.dataChanged = true;
19557
- if (animate) {
19869
+ if (animate && w.config.chart.animations.enabled) {
19558
19870
  ch.series.getPreviousPaths();
19559
19871
  }
19560
19872
  }
@@ -19600,7 +19912,7 @@ var __async = (__this, __arguments, generator) => {
19600
19912
  w.globals.lastXAxis = options2.xaxis ? Utils$1.clone(options2.xaxis) : [];
19601
19913
  w.globals.lastYAxis = options2.yaxis ? Utils$1.clone(options2.yaxis) : [];
19602
19914
  w.globals.initialConfig = Utils$1.extend({}, w.config);
19603
- w.globals.initialSeries = Utils$1.clone(w.config.series);
19915
+ w.globals.initialSeries = w.config.series;
19604
19916
  if (options2.series) {
19605
19917
  for (let i = 0; i < w.globals.collapsedSeriesIndices.length; i++) {
19606
19918
  const series = w.config.series[w.globals.collapsedSeriesIndices[i]];
@@ -19645,7 +19957,7 @@ var __async = (__this, __arguments, generator) => {
19645
19957
  xMax: w.globals.maxX
19646
19958
  });
19647
19959
  PerformanceCache.invalidateSelectors(w);
19648
- if (animate) {
19960
+ if (animate && w.config.chart.animations.enabled) {
19649
19961
  this.ctx.series.getPreviousPaths();
19650
19962
  }
19651
19963
  const prevSeriesCount = w.config.series.length;
@@ -19665,15 +19977,16 @@ var __async = (__this, __arguments, generator) => {
19665
19977
  this.ctx._writeParsedAxisFlags(parsedState.axisFlags);
19666
19978
  if (overwriteInitialSeries) {
19667
19979
  if (w.globals.initialConfig) {
19668
- w.globals.initialConfig.series = Utils$1.clone(w.config.series);
19980
+ w.globals.initialConfig.series = w.config.series;
19669
19981
  }
19670
- w.globals.initialSeries = Utils$1.clone(w.config.series);
19982
+ w.globals.initialSeries = w.config.series;
19671
19983
  }
19672
19984
  if (this._canUseFastPath(newSeries, prevSeriesCount, prevDataLengths, w)) {
19673
19985
  return this.ctx.fastUpdate(animate, prevAxisScaleSig).then(() => {
19674
19986
  resolve(this.ctx);
19675
19987
  });
19676
19988
  }
19989
+ if (this.ctx._updateStats) this.ctx._updateStats.full++;
19677
19990
  return this.ctx.update().then(() => {
19678
19991
  resolve(this.ctx);
19679
19992
  });
@@ -20196,11 +20509,11 @@ var __async = (__this, __arguments, generator) => {
20196
20509
  return false;
20197
20510
  }
20198
20511
  isInitialSeriesSameLen() {
20199
- var _a, _b, _c;
20512
+ var _a, _b, _c, _d;
20200
20513
  let sameLen = true;
20201
20514
  const initialSeries = (
20202
20515
  /** @type {any[]} */
20203
- ((_a = this.w.globals.initialSeries) == null ? void 0 : _a.filter(
20516
+ ((_b = (_a = this.w.globals._initialSeriesPeek) != null ? _a : this.w.globals.initialSeries) == null ? void 0 : _b.filter(
20204
20517
  /**
20205
20518
  * @param {Record<string, any>} s
20206
20519
  * @param {number} i
@@ -20212,7 +20525,7 @@ var __async = (__this, __arguments, generator) => {
20212
20525
  )) || []
20213
20526
  );
20214
20527
  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;
20528
+ if (!((_c = initialSeries[i]) == null ? void 0 : _c.data) || !((_d = initialSeries[i + 1]) == null ? void 0 : _d.data)) return true;
20216
20529
  if (initialSeries[i].data.length !== initialSeries[i + 1].data.length) {
20217
20530
  sameLen = false;
20218
20531
  break;
@@ -22076,7 +22389,7 @@ var __async = (__this, __arguments, generator) => {
22076
22389
  const tooltipCssClass = isRight ? `apexcharts-yaxistooltip apexcharts-yaxistooltip-${i} apexcharts-yaxistooltip-right` : `apexcharts-yaxistooltip apexcharts-yaxistooltip-${i} apexcharts-yaxistooltip-left`;
22077
22390
  const renderTo = w.dom.elWrap;
22078
22391
  const yaxisTooltip = w.dom.baseEl.querySelector(
22079
- `.apexcharts-yaxistooltip apexcharts-yaxistooltip-${i}`
22392
+ `.apexcharts-yaxistooltip.apexcharts-yaxistooltip-${i}`
22080
22393
  );
22081
22394
  if (yaxisTooltip === null) {
22082
22395
  ttCtx.yaxisTooltip = BrowserAPIs.createElementNS(
@@ -24786,6 +25099,8 @@ var __async = (__this, __arguments, generator) => {
24786
25099
  /** @type {any} */
24787
25100
  __publicField(this, "_keyboardNavigation");
24788
25101
  /** @type {any} */
25102
+ __publicField(this, "_zoomPanSelection");
25103
+ /** @type {any} */
24789
25104
  __publicField(this, "windowResizeHandler");
24790
25105
  /** @type {any} */
24791
25106
  __publicField(this, "parentResizeHandler");
@@ -24827,6 +25142,7 @@ var __async = (__this, __arguments, generator) => {
24827
25142
  const initCtx = new InitCtxVariables(this);
24828
25143
  initCtx.initModules();
24829
25144
  this.lastUpdateOptions = null;
25145
+ this._updateStats = { fast: 0, fastWithAxes: 0, full: 0 };
24830
25146
  this.create = this.create.bind(this);
24831
25147
  if (Environment.isBrowser()) {
24832
25148
  this.windowResizeHandler = this._windowResizeHandler.bind(this);
@@ -25207,7 +25523,7 @@ var __async = (__this, __arguments, generator) => {
25207
25523
  if (Utils$1.shallowEqual(this.lastUpdateOptions, options2)) {
25208
25524
  return Promise.resolve(this);
25209
25525
  }
25210
- if (options2.series && this.lastUpdateOptions.series) {
25526
+ if (options2.series && this.lastUpdateOptions.series && !_ApexCharts._optionsTooBigToCompare(options2)) {
25211
25527
  if (JSON.stringify(this.lastUpdateOptions.series) === JSON.stringify(options2.series)) {
25212
25528
  const optionsWithoutSeries = __spreadValues({}, options2);
25213
25529
  const lastWithoutSeries = __spreadValues({}, this.lastUpdateOptions);
@@ -25261,7 +25577,7 @@ var __async = (__this, __arguments, generator) => {
25261
25577
  */
25262
25578
  updateSeries(newSeries = [], animate = true, overwriteInitialSeries = true) {
25263
25579
  this.data.resetParsingFlags();
25264
- this.series.resetSeries(false);
25580
+ this.series.prepareDataUpdate();
25265
25581
  this.updateHelpers.revertDefaultAxisMinMax();
25266
25582
  return this.updateHelpers._updateSeries(
25267
25583
  newSeries,
@@ -25284,7 +25600,7 @@ var __async = (__this, __arguments, generator) => {
25284
25600
  /** @type {any} */
25285
25601
  newSerie
25286
25602
  );
25287
- this.series.resetSeries(false);
25603
+ this.series.prepareDataUpdate();
25288
25604
  this.updateHelpers.revertDefaultAxisMinMax();
25289
25605
  return this.updateHelpers._updateSeries(
25290
25606
  newSeries,
@@ -25304,7 +25620,9 @@ var __async = (__this, __arguments, generator) => {
25304
25620
  const me = this;
25305
25621
  me.data.resetParsingFlags();
25306
25622
  me.w.globals.dataChanged = true;
25307
- me.series.getPreviousPaths();
25623
+ if (me.w.config.chart.animations.enabled) {
25624
+ me.series.getPreviousPaths();
25625
+ }
25308
25626
  const newSeries = me.w.config.series.slice();
25309
25627
  for (let i = 0; i < newSeries.length; i++) {
25310
25628
  if (newData[i] !== null && typeof newData[i] !== "undefined") {
@@ -25324,19 +25642,37 @@ var __async = (__this, __arguments, generator) => {
25324
25642
  trimStreamingSeries(newSeries, me.w);
25325
25643
  me.w.config.series = newSeries;
25326
25644
  if (overwriteInitialSeries) {
25327
- me.w.globals.initialSeries = Utils$1.clone(me.w.config.series);
25645
+ me.w.globals.initialSeries = me.w.config.series;
25328
25646
  }
25329
25647
  return this.update();
25330
25648
  }
25649
+ /**
25650
+ * True when an options object carries enough series data that a
25651
+ * JSON.stringify equality check (and the Utils.clone needed to store it for
25652
+ * later comparison) would cost more than the re-render it tries to avoid.
25653
+ * @param {any} options
25654
+ * @returns {boolean}
25655
+ */
25656
+ static _optionsTooBigToCompare(options2) {
25657
+ const series = options2 && options2.series;
25658
+ if (!Array.isArray(series)) return false;
25659
+ let points = 0;
25660
+ for (let i = 0; i < series.length; i++) {
25661
+ const d = series[i] && series[i].data;
25662
+ points += Array.isArray(d) ? d.length : 1;
25663
+ if (points > 1e3) return true;
25664
+ }
25665
+ return false;
25666
+ }
25331
25667
  /**
25332
25668
  * @param {object} [options]
25333
25669
  */
25334
25670
  update(options2) {
25335
25671
  return new Promise((resolve, reject) => {
25336
- if (this.lastUpdateOptions && JSON.stringify(this.lastUpdateOptions) === JSON.stringify(options2)) {
25672
+ if (options2 && this.lastUpdateOptions && !_ApexCharts._optionsTooBigToCompare(options2) && JSON.stringify(this.lastUpdateOptions) === JSON.stringify(options2)) {
25337
25673
  return resolve(this);
25338
25674
  }
25339
- this.lastUpdateOptions = Utils$1.clone(options2);
25675
+ this.lastUpdateOptions = options2 && !_ApexCharts._optionsTooBigToCompare(options2) ? Utils$1.clone(options2) : null;
25340
25676
  new Destroy(this.ctx).clear({ isUpdating: true });
25341
25677
  const graphData = this.create(this.w.config.series, options2 != null ? options2 : {});
25342
25678
  if (!graphData) return resolve(this);
@@ -25355,6 +25691,140 @@ var __async = (__this, __arguments, generator) => {
25355
25691
  });
25356
25692
  });
25357
25693
  }
25694
+ /**
25695
+ * Redraws the scale-dependent chrome (grid lines, x-axis, y-axes) IN PLACE
25696
+ * within the frozen layout after a data-only update changed the axis
25697
+ * domain. The rebuilt groups replace the old nodes positionally, so z-order
25698
+ * (grid back/front) is preserved without re-running mount. Legend,
25699
+ * annotations containers, toolbar, defs/masks, and the plot geometry are
25700
+ * untouched.
25701
+ *
25702
+ * Returns false when the refresh cannot faithfully reproduce the chart and
25703
+ * the caller must fall back to a full render:
25704
+ * - horizontal bar charts (inversed axes draw through a different path)
25705
+ * - charts with annotations or ink notes (their positions are scale-bound
25706
+ * and are laid out by the full render)
25707
+ * - the new y labels no longer fit the width reserved at layout time
25708
+ *
25709
+ * @param {any} _xyRatios
25710
+ * @returns {boolean} true when the chrome was refreshed in place
25711
+ */
25712
+ _fastAxisChromeRefresh(_xyRatios) {
25713
+ const w = this.w;
25714
+ const gl = w.globals;
25715
+ this._fastAxisBailReason = "";
25716
+ try {
25717
+ if (gl.isBarHorizontal) {
25718
+ this._fastAxisBailReason = "barHorizontal";
25719
+ return false;
25720
+ }
25721
+ if (w.config.chart.sparkline.enabled) return true;
25722
+ const a = w.config.annotations;
25723
+ 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)) {
25724
+ this._fastAxisBailReason = "annotations";
25725
+ return false;
25726
+ }
25727
+ if (w.config.chart.ink && w.config.chart.ink.enabled) {
25728
+ this._fastAxisBailReason = "ink";
25729
+ return false;
25730
+ }
25731
+ const dim = this.dimensions;
25732
+ if (!dim || !dim.dimYAxis) {
25733
+ this._fastAxisBailReason = "noDimensions";
25734
+ return false;
25735
+ }
25736
+ const prevYLabelsCoords = w.layout.yLabelsCoords;
25737
+ const prevYTitleCoords = w.layout.yTitleCoords;
25738
+ const yaxisLabelCoords = dim.dimYAxis.getyAxisLabelsCoords();
25739
+ const yTitleCoords = dim.dimYAxis.getyAxisTitleCoords();
25740
+ w.layout.yLabelsCoords = [];
25741
+ w.layout.yTitleCoords = [];
25742
+ w.config.yaxis.map((_yaxe, index) => {
25743
+ w.layout.yLabelsCoords.push({
25744
+ width: yaxisLabelCoords[index].width,
25745
+ index
25746
+ });
25747
+ w.layout.yTitleCoords.push(
25748
+ /** @type {any} */
25749
+ { width: yTitleCoords[index].width, index }
25750
+ );
25751
+ });
25752
+ const newYAxisWidth = dim.dimYAxis.getTotalYAxisWidth();
25753
+ if (newYAxisWidth > dim.yAxisWidth + 2) {
25754
+ w.layout.yLabelsCoords = prevYLabelsCoords;
25755
+ w.layout.yTitleCoords = prevYTitleCoords;
25756
+ this._fastAxisBailReason = `labelWidth ${newYAxisWidth} > ${dim.yAxisWidth}`;
25757
+ return false;
25758
+ }
25759
+ const innerEl = w.dom.elGraphical.node;
25760
+ const oldGrid = innerEl.querySelector(".apexcharts-grid");
25761
+ const oldGridBorders = innerEl.querySelector(".apexcharts-grid-borders");
25762
+ if (!oldGrid) {
25763
+ this._fastAxisBailReason = "missingGridNode";
25764
+ return false;
25765
+ }
25766
+ const gridParent = oldGrid.parentNode;
25767
+ const gridNext = oldGridBorders ? oldGridBorders.nextSibling : oldGrid.nextSibling;
25768
+ oldGrid.remove();
25769
+ if (oldGridBorders) oldGridBorders.remove();
25770
+ innerEl.querySelectorAll(".apexcharts-xaxis-tick").forEach((t) => t.remove());
25771
+ this.grid = new Grid(w, this);
25772
+ const elgrid = this.grid.drawGrid();
25773
+ if (elgrid && elgrid.el) {
25774
+ gridParent.insertBefore(elgrid.el.node, gridNext);
25775
+ if (elgrid.elGridBorders && elgrid.elGridBorders.node) {
25776
+ gridParent.insertBefore(elgrid.elGridBorders.node, gridNext);
25777
+ }
25778
+ }
25779
+ const xAxis = new XAxis(this.w, this.ctx, elgrid);
25780
+ const oldXaxis = innerEl.querySelector(".apexcharts-xaxis");
25781
+ if (oldXaxis) {
25782
+ const xParent = oldXaxis.parentNode;
25783
+ const xNext = oldXaxis.nextSibling;
25784
+ oldXaxis.remove();
25785
+ const elXaxis = xAxis.drawXaxis();
25786
+ xParent.insertBefore(elXaxis.node, xNext);
25787
+ }
25788
+ const yAxis = new YAxis(
25789
+ this.w,
25790
+ { theme: this.theme, timeScale: this.timeScale },
25791
+ elgrid
25792
+ );
25793
+ for (let index = 0; index < w.config.yaxis.length; index++) {
25794
+ if (gl.ignoreYAxisIndexes.indexOf(index) !== -1) continue;
25795
+ const oldY = w.dom.baseEl.querySelector(
25796
+ `.apexcharts-yaxis[rel='${index}']`
25797
+ );
25798
+ if (!oldY) {
25799
+ this._fastAxisBailReason = "missingYAxisNode";
25800
+ return false;
25801
+ }
25802
+ const yParent = oldY.parentNode;
25803
+ if (!yParent) {
25804
+ this._fastAxisBailReason = "missingYAxisParent";
25805
+ return false;
25806
+ }
25807
+ const yNext = oldY.nextSibling;
25808
+ oldY.remove();
25809
+ const elYaxis = yAxis.drawYaxis(index);
25810
+ yParent.insertBefore(elYaxis.node, yNext);
25811
+ }
25812
+ if (elgrid !== null) {
25813
+ xAxis.xAxisLabelCorrections();
25814
+ yAxis.setYAxisTextAlignments();
25815
+ w.config.yaxis.map((yaxe, index) => {
25816
+ if (gl.ignoreYAxisIndexes.indexOf(index) === -1) {
25817
+ yAxis.yAxisTitleRotate(index, yaxe.opposite);
25818
+ }
25819
+ });
25820
+ }
25821
+ return true;
25822
+ } catch (e) {
25823
+ this._fastAxisBailReason = "error: " + (e && /** @type {any} */
25824
+ e.message);
25825
+ return false;
25826
+ }
25827
+ }
25358
25828
  /**
25359
25829
  * Fast update path for data-only series changes.
25360
25830
  *
@@ -25412,18 +25882,32 @@ var __async = (__this, __arguments, generator) => {
25412
25882
  }
25413
25883
  }
25414
25884
  const xyRatios = this.core.xySettings();
25885
+ if (this._zoomPanSelection) this._zoomPanSelection.xyRatios = xyRatios;
25415
25886
  const newAxisScaleSig = JSON.stringify({
25416
25887
  y: (gl.yAxisScale || []).map((s) => s ? s.result : null),
25417
25888
  xMin: gl.minX,
25418
25889
  xMax: gl.maxX
25419
25890
  });
25420
- if (gl.axisCharts && prevAxisScaleSig != null && newAxisScaleSig !== prevAxisScaleSig) {
25891
+ const scaleChanged = gl.axisCharts && prevAxisScaleSig != null && newAxisScaleSig !== prevAxisScaleSig;
25892
+ if (scaleChanged && !this._fastAxisChromeRefresh(xyRatios)) {
25893
+ this._updateStats.full++;
25421
25894
  return this.update().then(() => resolve(this)).catch(reject);
25422
25895
  }
25896
+ if (scaleChanged) {
25897
+ this._updateStats.fastWithAxes++;
25898
+ } else {
25899
+ this._updateStats.fast++;
25900
+ }
25423
25901
  (_a = this.weave) == null ? void 0 : _a.dispatch("afterScales", { pass: "fast", xyRatios });
25902
+ const rr = (
25903
+ /** @type {any} */
25904
+ this.ctx.renderer
25905
+ );
25906
+ const reuseCanvasHost = !!(rr && rr.kind === "canvas" && rr.canRepaintInPlace && rr.canRepaintInPlace());
25907
+ if (reuseCanvasHost) rr._repaintHostInPlace = true;
25424
25908
  const innerEl = w.dom.elGraphical.node;
25425
25909
  const toRemove = innerEl.querySelectorAll(
25426
- ".apexcharts-canvas-series-wrap, .apexcharts-series, .apexcharts-datalabels, .apexcharts-datalabels-background"
25910
+ (reuseCanvasHost ? "" : ".apexcharts-canvas-series-wrap, ") + ".apexcharts-plot-series, .apexcharts-series, .apexcharts-datalabels, .apexcharts-datalabels-background"
25427
25911
  );
25428
25912
  toRemove.forEach(
25429
25913
  (el) => {
@@ -25433,11 +25917,13 @@ var __async = (__this, __arguments, generator) => {
25433
25917
  );
25434
25918
  const elGraph = this.core.plotChartType(w.config.series, xyRatios);
25435
25919
  const gridEl = innerEl.querySelector(".apexcharts-grid");
25920
+ const xaxisEl = innerEl.querySelector(".apexcharts-xaxis");
25436
25921
  const graphs = Array.isArray(elGraph) ? elGraph : [elGraph];
25437
- if (gridEl && w.config.grid.position === "front") {
25922
+ const anchor = gridEl && w.config.grid.position === "front" ? gridEl : xaxisEl;
25923
+ if (anchor) {
25438
25924
  graphs.forEach((g) => {
25439
25925
  const node = g && g.node ? g.node : g;
25440
- if (node) innerEl.insertBefore(node, gridEl);
25926
+ if (node) innerEl.insertBefore(node, anchor);
25441
25927
  });
25442
25928
  } else {
25443
25929
  graphs.forEach((g) => {
@@ -26197,41 +26683,57 @@ var __async = (__this, __arguments, generator) => {
26197
26683
  return this.ctx.drilldown.drillToRoot();
26198
26684
  }
26199
26685
  // ─── Slice write-back stubs ─────────────────────────────────────────────────
26686
+ /**
26687
+ * Copy own DATA properties of a parse-state slice onto a live w.* slice.
26688
+ * Never Object.assign here: several w.* fields (and, historically, snapshot
26689
+ * fields) are lazy accessors, and [[Get]]-ing an accessor while copying
26690
+ * forces its deferred computation (a deep initialSeries clone plus O(n)
26691
+ * stacked-totals passes on every render/update) and can replace the live
26692
+ * accessor with a materialized value for the life of the instance.
26693
+ * @param {any} target
26694
+ * @param {any} slice
26695
+ */
26696
+ static _writeDataProps(target, slice) {
26697
+ for (const key of Object.keys(slice)) {
26698
+ const d = Object.getOwnPropertyDescriptor(slice, key);
26699
+ if (d && "value" in d) target[key] = d.value;
26700
+ }
26701
+ }
26200
26702
  /**
26201
26703
  * @param {Partial<import('./types/internal').SeriesData>} slice
26202
26704
  */
26203
26705
  _writeParsedSeriesData(slice) {
26204
- Object.assign(this.w.seriesData, slice);
26706
+ _ApexCharts._writeDataProps(this.w.seriesData, slice);
26205
26707
  }
26206
26708
  /**
26207
26709
  * @param {Partial<import('./types/internal').RangeData>} slice
26208
26710
  */
26209
26711
  _writeParsedRangeData(slice) {
26210
- Object.assign(this.w.rangeData, slice);
26712
+ _ApexCharts._writeDataProps(this.w.rangeData, slice);
26211
26713
  }
26212
26714
  /**
26213
26715
  * @param {Partial<import('./types/internal').CandleData>} slice
26214
26716
  */
26215
26717
  _writeParsedCandleData(slice) {
26216
- Object.assign(this.w.candleData, slice);
26718
+ _ApexCharts._writeDataProps(this.w.candleData, slice);
26217
26719
  }
26218
26720
  /**
26219
26721
  * @param {Partial<import('./types/internal').LabelData>} slice
26220
26722
  */
26221
26723
  _writeParsedLabelData(slice) {
26222
- Object.assign(this.w.labelData, slice);
26724
+ _ApexCharts._writeDataProps(this.w.labelData, slice);
26223
26725
  }
26224
26726
  /**
26225
26727
  * @param {Partial<import('./types/internal').AxisFlags>} slice
26226
26728
  */
26227
26729
  _writeParsedAxisFlags(slice) {
26228
- Object.assign(this.w.axisFlags, slice);
26730
+ _ApexCharts._writeDataProps(this.w.axisFlags, slice);
26229
26731
  }
26230
26732
  /**
26231
26733
  * @param {Partial<import('./types/internal').LayoutCoords>} slice
26232
26734
  */
26233
26735
  _writeLayoutCoords(slice) {
26234
- Object.assign(this.w.layout, slice);
26736
+ _ApexCharts._writeDataProps(this.w.layout, slice);
26235
26737
  }
26236
26738
  _parentResizeCallback() {
26237
26739
  if (this.w.globals.animationEnded && this.w.config.chart.redrawOnParentResize) {
@@ -28769,7 +29271,6 @@ var __async = (__this, __arguments, generator) => {
28769
29271
  this.xyRatios = xyRatios;
28770
29272
  this.zoomRect = this.graphics.drawRect(0, 0, 0, 0);
28771
29273
  this.selectionRect = this.graphics.drawRect(0, 0, 0, 0);
28772
- this.gridRect = w.dom.baseEl.querySelector(".apexcharts-grid");
28773
29274
  this.constraints = new Box(0, 0, w.layout.gridWidth, w.layout.gridHeight);
28774
29275
  this.zoomRect.node.classList.add("apexcharts-zoom-rect");
28775
29276
  this.selectionRect.node.classList.add("apexcharts-selection-rect");
@@ -28833,14 +29334,12 @@ var __async = (__this, __arguments, generator) => {
28833
29334
  }
28834
29335
  this.selectionRect = null;
28835
29336
  this.zoomRect = null;
28836
- this.gridRect = null;
28837
29337
  }
28838
29338
  /**
28839
29339
  * @param {import('../types/internal').XYRatios} xyRatios
28840
29340
  * @param {any} e
28841
29341
  */
28842
29342
  svgMouseEvents(xyRatios, e) {
28843
- var _a;
28844
29343
  const w = this.w;
28845
29344
  const toolbar = this.ctx.toolbar;
28846
29345
  if (w.interact.momentum && w.interact.momentum.busy) return;
@@ -28871,7 +29370,7 @@ var __async = (__this, __arguments, generator) => {
28871
29370
  this.clientX = e.type === "touchmove" || e.type === "touchstart" ? e.touches[0].clientX : e.type === "touchend" ? e.changedTouches[0].clientX : e.clientX;
28872
29371
  this.clientY = e.type === "touchmove" || e.type === "touchstart" ? e.touches[0].clientY : e.type === "touchend" ? e.changedTouches[0].clientY : e.clientY;
28873
29372
  if (e.type === "mousedown" && e.which === 1 || e.type === "touchstart") {
28874
- const gridRectDim = (_a = this.gridRect) == null ? void 0 : _a.getBoundingClientRect();
29373
+ const gridRectDim = this._gridRect();
28875
29374
  if (!gridRectDim) return;
28876
29375
  this.startX = this.clientX - gridRectDim.left - w.globals.barPadForNumericAxis;
28877
29376
  this.startY = this.clientY - gridRectDim.top;
@@ -28886,7 +29385,7 @@ var __async = (__this, __arguments, generator) => {
28886
29385
  this.panDragging({
28887
29386
  context: this,
28888
29387
  zoomtype,
28889
- xyRatios
29388
+ xyRatios: this.xyRatios
28890
29389
  });
28891
29390
  }
28892
29391
  } else {
@@ -28905,9 +29404,8 @@ var __async = (__this, __arguments, generator) => {
28905
29404
  }
28906
29405
  /** @param {{ zoomtype?: any, isResized?: any }} opts */
28907
29406
  handleMouseUp({ zoomtype, isResized }) {
28908
- var _a;
28909
29407
  const w = this.w;
28910
- const gridRectDim = (_a = this.gridRect) == null ? void 0 : _a.getBoundingClientRect();
29408
+ const gridRectDim = this._gridRect();
28911
29409
  if (gridRectDim && (this.w.interact.mousedown || isResized)) {
28912
29410
  this.endX = this.clientX - gridRectDim.left - w.globals.barPadForNumericAxis;
28913
29411
  this.endY = this.clientY - gridRectDim.top;
@@ -28949,11 +29447,11 @@ var __async = (__this, __arguments, generator) => {
28949
29447
  * @param {any} e
28950
29448
  */
28951
29449
  executeMouseWheelZoom(e) {
28952
- var _a, _b, _c;
29450
+ var _a, _b;
28953
29451
  const w = this.w;
28954
29452
  this.minX = w.axisFlags.isRangeBar ? w.globals.minY : w.globals.minX;
28955
29453
  this.maxX = w.axisFlags.isRangeBar ? w.globals.maxY : w.globals.maxX;
28956
- const gridRectDim = (_a = this.gridRect) == null ? void 0 : _a.getBoundingClientRect();
29454
+ const gridRectDim = this._gridRect();
28957
29455
  if (!gridRectDim) return;
28958
29456
  const mouseX = (e.clientX - gridRectDim.left) / gridRectDim.width;
28959
29457
  const currentMinX = this.minX;
@@ -28974,8 +29472,8 @@ var __async = (__this, __arguments, generator) => {
28974
29472
  newMaxX = currentMaxX + zoomRange / 2;
28975
29473
  }
28976
29474
  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;
29475
+ const clampMin = (_a = w.globals.dataReducerRawMinX) != null ? _a : w.globals.initialMinX;
29476
+ const clampMax = (_b = w.globals.dataReducerRawMaxX) != null ? _b : w.globals.initialMaxX;
28979
29477
  newMinX = Math.max(newMinX, clampMin);
28980
29478
  newMaxX = Math.min(newMaxX, clampMax);
28981
29479
  const minXDiff = w.globals.minXDiff > 0 && isFinite(w.globals.minXDiff) ? w.globals.minXDiff : 0;
@@ -29112,10 +29610,9 @@ var __async = (__this, __arguments, generator) => {
29112
29610
  }
29113
29611
  }
29114
29612
  selectionDrawing({ context, zoomtype }) {
29115
- var _a;
29116
29613
  const w = this.w;
29117
29614
  const me = context;
29118
- const gridRectDim = (_a = this.gridRect) == null ? void 0 : _a.getBoundingClientRect();
29615
+ const gridRectDim = this._gridRect();
29119
29616
  if (!gridRectDim) return;
29120
29617
  const startX = me.startX - 1;
29121
29618
  const startY = me.startY;
@@ -29221,8 +29718,8 @@ var __async = (__this, __arguments, generator) => {
29221
29718
  if ((typeof w.config.chart.events.selection === "function" || linkActive) && w.interact.selectionEnabled) {
29222
29719
  clearTimeout((_a = this.w.globals.selectionResizeTimer) != null ? _a : void 0);
29223
29720
  this.w.globals.selectionResizeTimer = window.setTimeout(() => {
29224
- var _a2, _b;
29225
- const gridRectDim = (_a2 = this.gridRect) == null ? void 0 : _a2.getBoundingClientRect();
29721
+ var _a2;
29722
+ const gridRectDim = this._gridRect();
29226
29723
  if (!gridRectDim) return;
29227
29724
  const selectionRect = selRect.node.getBoundingClientRect();
29228
29725
  let minX, maxX, minY, maxY;
@@ -29256,7 +29753,7 @@ var __async = (__this, __arguments, generator) => {
29256
29753
  if (w.config.chart.brush.enabled && w.config.chart.events.brushScrolled !== void 0) {
29257
29754
  w.config.chart.events.brushScrolled(this.ctx, xyAxis);
29258
29755
  }
29259
- (_b = this.ctx.linkedViews) == null ? void 0 : _b.onSourceSelection(xyAxis.xaxis);
29756
+ (_a2 = this.ctx.linkedViews) == null ? void 0 : _a2.onSourceSelection(xyAxis.xaxis);
29260
29757
  }, timerInterval);
29261
29758
  }
29262
29759
  }
@@ -29268,7 +29765,8 @@ var __async = (__this, __arguments, generator) => {
29268
29765
  const xyRatios = this.xyRatios;
29269
29766
  const toolbar = this.ctx.toolbar;
29270
29767
  const selRect = w.interact.zoomEnabled ? me.zoomRect.node.getBoundingClientRect() : me.selectionRect.node.getBoundingClientRect();
29271
- const gridRectDim = me.gridRect.getBoundingClientRect();
29768
+ const gridRectDim = me._gridRect();
29769
+ if (!gridRectDim) return;
29272
29770
  const localStartX = selRect.left - gridRectDim.left - w.globals.barPadForNumericAxis;
29273
29771
  const localEndX = selRect.right - gridRectDim.left - w.globals.barPadForNumericAxis;
29274
29772
  const localStartY = selRect.top - gridRectDim.top;
@@ -29526,8 +30024,11 @@ var __async = (__this, __arguments, generator) => {
29526
30024
  const w = this.w;
29527
30025
  return w.axisFlags.isRangeBar ? { min: w.globals.minY, max: w.globals.maxY } : { min: w.globals.minX, max: w.globals.maxX };
29528
30026
  }
29529
- /** Live grid rect from the current DOM (this.gridRect goes stale/null after
29530
- * the re-render a gesture frame triggers). */
30027
+ /** Live grid rect from the current DOM. Never cache the grid node on the
30028
+ * instance: a full render replaces this whole instance, but the fast update
30029
+ * path (fastUpdate/_fastAxisChromeRefresh) keeps the instance while swapping
30030
+ * the grid node, and a cached node would go stale (detached nodes report an
30031
+ * all-zero bounding rect, silently corrupting selection geometry). */
29531
30032
  _gridRect() {
29532
30033
  const baseEl = this.w.dom.baseEl;
29533
30034
  const grid = baseEl && baseEl.querySelector(".apexcharts-grid");
@@ -35340,6 +35841,20 @@ var __async = (__this, __arguments, generator) => {
35340
35841
  clear() {
35341
35842
  this._compositor.clear();
35342
35843
  }
35844
+ /**
35845
+ * Whether the existing <canvas> host can be repainted in place (it exists
35846
+ * and is still mounted). Used by the data-only fast update path to skip
35847
+ * recreating the foreignObject + backing store on every tick.
35848
+ * @returns {boolean}
35849
+ */
35850
+ canRepaintInPlace() {
35851
+ const host = this._compositor.getHost();
35852
+ return !!(host && host.node && host.node.isConnected);
35853
+ }
35854
+ /** Repaint the freshly recorded display list into the EXISTING canvas. */
35855
+ repaintInPlace() {
35856
+ this._compositor.paint(this._g.displayList(), this._g);
35857
+ }
35343
35858
  // ── emit primitives (delegate to the display-list shim) ──
35344
35859
  /** @param {any} attrs */
35345
35860
  group(attrs) {
@@ -43953,7 +44468,7 @@ var __async = (__this, __arguments, generator) => {
43953
44468
  let { pathFromLine, pathFromArea } = pathsFrom;
43954
44469
  const r = this.ctx && this.ctx.renderer;
43955
44470
  const canvasMode = !!(r && r.kind && r.kind !== "svg");
43956
- const buildStrings = !canvasMode || w.globals.dataChanged;
44471
+ const buildStrings = !canvasMode || w.globals.dataChanged && !!w.globals.prevStreamFrame;
43957
44472
  const nxs = canvasMode ? new Float64Array(n) : null;
43958
44473
  const nys = canvasMode ? new Float64Array(n) : null;
43959
44474
  if (nxs && nys) {