apexcharts 8.2.0 → 8.3.1

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 (256) hide show
  1. package/README.md +7 -7
  2. package/dist/apexcharts.common.js +2 -2
  3. package/dist/apexcharts.core.js +19793 -19713
  4. package/dist/apexcharts.core.min.js +2 -2
  5. package/dist/apexcharts.css +38 -8
  6. package/dist/apexcharts.esm.js +1882 -1625
  7. package/dist/apexcharts.full.js +22044 -21634
  8. package/dist/apexcharts.full.min.js +2 -2
  9. package/dist/apexcharts.js +21414 -21124
  10. package/dist/apexcharts.min.js +2 -2
  11. package/dist/apexcharts.ssr.common.js +2 -2
  12. package/dist/apexcharts.ssr.esm.js +21413 -21123
  13. package/dist/area.common.js +2 -2
  14. package/dist/area.esm.js +91 -40
  15. package/dist/bar.common.js +2 -2
  16. package/dist/bar.esm.js +478 -406
  17. package/dist/bar.js +2 -2
  18. package/dist/boxPlot.common.js +2 -2
  19. package/dist/boxPlot.esm.js +409 -334
  20. package/dist/bubble.common.js +2 -2
  21. package/dist/bubble.esm.js +91 -40
  22. package/dist/candlestick.common.js +2 -2
  23. package/dist/candlestick.esm.js +409 -334
  24. package/dist/candlestick.js +2 -2
  25. package/dist/column.common.js +2 -2
  26. package/dist/column.esm.js +478 -406
  27. package/dist/core.common.js +2 -2
  28. package/dist/core.esm.js +19793 -19713
  29. package/dist/donut.common.js +2 -2
  30. package/dist/donut.esm.js +3 -9
  31. package/dist/dumbbell.common.js +2 -2
  32. package/dist/dumbbell.esm.js +478 -406
  33. package/dist/features/all.common.js +2 -2
  34. package/dist/features/all.esm.js +442 -324
  35. package/dist/features/annotations.common.js +2 -2
  36. package/dist/features/annotations.esm.js +65 -48
  37. package/dist/features/annotations.js +2 -2
  38. package/dist/features/context-menu.common.js +1 -1
  39. package/dist/features/context-menu.esm.js +1 -1
  40. package/dist/features/context-menu.js +1 -1
  41. package/dist/features/drilldown.common.js +2 -2
  42. package/dist/features/drilldown.esm.js +4 -2
  43. package/dist/features/drilldown.js +2 -2
  44. package/dist/features/dumbbell.common.js +1 -1
  45. package/dist/features/dumbbell.esm.js +1 -1
  46. package/dist/features/dumbbell.js +1 -1
  47. package/dist/features/exports.common.js +2 -2
  48. package/dist/features/exports.esm.js +10 -4
  49. package/dist/features/exports.js +2 -2
  50. package/dist/features/facet.common.js +1 -1
  51. package/dist/features/facet.esm.js +1 -1
  52. package/dist/features/facet.js +1 -1
  53. package/dist/features/highlight-filter.common.js +2 -2
  54. package/dist/features/highlight-filter.esm.js +14 -9
  55. package/dist/features/highlight-filter.js +2 -2
  56. package/dist/features/history.common.js +1 -1
  57. package/dist/features/history.esm.js +1 -1
  58. package/dist/features/history.js +1 -1
  59. package/dist/features/ink.common.js +1 -1
  60. package/dist/features/ink.esm.js +1 -1
  61. package/dist/features/ink.js +1 -1
  62. package/dist/features/keyboard.common.js +2 -2
  63. package/dist/features/keyboard.esm.js +97 -145
  64. package/dist/features/keyboard.js +2 -2
  65. package/dist/features/legend.common.js +2 -2
  66. package/dist/features/legend.esm.js +64 -44
  67. package/dist/features/legend.js +2 -2
  68. package/dist/features/link.common.js +1 -1
  69. package/dist/features/link.esm.js +1 -1
  70. package/dist/features/link.js +1 -1
  71. package/dist/features/marks.common.js +1 -1
  72. package/dist/features/marks.esm.js +1 -1
  73. package/dist/features/marks.js +1 -1
  74. package/dist/features/measure.common.js +1 -1
  75. package/dist/features/measure.esm.js +1 -1
  76. package/dist/features/measure.js +1 -1
  77. package/dist/features/morph.common.js +2 -2
  78. package/dist/features/morph.esm.js +9 -5
  79. package/dist/features/morph.js +2 -2
  80. package/dist/features/perspectives.common.js +2 -2
  81. package/dist/features/perspectives.esm.js +4 -1
  82. package/dist/features/perspectives.js +2 -2
  83. package/dist/features/raincloud.common.js +2 -2
  84. package/dist/features/raincloud.esm.js +26 -27
  85. package/dist/features/raincloud.js +2 -2
  86. package/dist/features/renderer-canvas.common.js +2 -2
  87. package/dist/features/renderer-canvas.esm.js +2 -1
  88. package/dist/features/renderer-canvas.js +2 -2
  89. package/dist/features/stats.common.js +2 -2
  90. package/dist/features/stats.esm.js +52 -59
  91. package/dist/features/stats.js +2 -2
  92. package/dist/features/storyboard.common.js +2 -2
  93. package/dist/features/storyboard.esm.js +4 -1
  94. package/dist/features/storyboard.js +2 -2
  95. package/dist/features/streamgraph.common.js +2 -2
  96. package/dist/features/streamgraph.esm.js +48 -14
  97. package/dist/features/streamgraph.js +2 -2
  98. package/dist/features/toolbar.common.js +2 -2
  99. package/dist/features/toolbar.esm.js +148 -18
  100. package/dist/features/toolbar.js +2 -2
  101. package/dist/features/trellis.common.js +2 -2
  102. package/dist/features/trellis.esm.js +150 -63
  103. package/dist/features/trellis.js +2 -2
  104. package/dist/features/waterfall.common.js +1 -1
  105. package/dist/features/waterfall.esm.js +1 -1
  106. package/dist/features/waterfall.js +1 -1
  107. package/dist/features/weave.common.js +2 -2
  108. package/dist/features/weave.esm.js +13 -12
  109. package/dist/features/weave.js +2 -2
  110. package/dist/full.common.js +2 -2
  111. package/dist/full.esm.js +1068 -842
  112. package/dist/heatmap.common.js +2 -2
  113. package/dist/heatmap.esm.js +3 -17
  114. package/dist/heatmap.js +2 -2
  115. package/dist/histogram.common.js +2 -2
  116. package/dist/histogram.esm.js +529 -464
  117. package/dist/icicle.common.js +2 -2
  118. package/dist/icicle.esm.js +80 -46
  119. package/dist/icicle.js +2 -2
  120. package/dist/line.common.js +2 -2
  121. package/dist/line.esm.js +91 -40
  122. package/dist/line.js +2 -2
  123. package/dist/locales/en.json +2 -1
  124. package/dist/locales/ro.json +3 -2
  125. package/dist/pictograms.common.js +1 -1
  126. package/dist/pictograms.esm.js +1 -1
  127. package/dist/pictograms.js +1 -1
  128. package/dist/pie.common.js +2 -2
  129. package/dist/pie.esm.js +3 -9
  130. package/dist/pie.js +2 -2
  131. package/dist/polarArea.common.js +2 -2
  132. package/dist/polarArea.esm.js +3 -9
  133. package/dist/radar.common.js +2 -2
  134. package/dist/radar.esm.js +5 -4
  135. package/dist/radar.js +2 -2
  136. package/dist/radialBar.common.js +2 -2
  137. package/dist/radialBar.esm.js +5 -12
  138. package/dist/radialBar.js +2 -2
  139. package/dist/raincloud.common.js +2 -2
  140. package/dist/raincloud.esm.js +97 -52
  141. package/dist/rangeArea.common.js +2 -2
  142. package/dist/rangeArea.esm.js +91 -40
  143. package/dist/rangeBar.common.js +2 -2
  144. package/dist/rangeBar.esm.js +478 -406
  145. package/dist/scatter.common.js +2 -2
  146. package/dist/scatter.esm.js +91 -40
  147. package/dist/streamgraph.common.js +2 -2
  148. package/dist/streamgraph.esm.js +138 -53
  149. package/dist/sunburst.common.js +2 -2
  150. package/dist/sunburst.esm.js +116 -94
  151. package/dist/sunburst.js +2 -2
  152. package/dist/treemap.common.js +2 -2
  153. package/dist/treemap.esm.js +138 -104
  154. package/dist/treemap.js +2 -2
  155. package/dist/unit-shapes.common.js +1 -1
  156. package/dist/unit-shapes.esm.js +1 -1
  157. package/dist/unit-shapes.js +1 -1
  158. package/dist/unit.common.js +2 -2
  159. package/dist/unit.esm.js +280 -202
  160. package/dist/unit.js +2 -2
  161. package/dist/violin.common.js +2 -2
  162. package/dist/violin.esm.js +72 -26
  163. package/dist/violin.js +2 -2
  164. package/dist/waterfall.common.js +2 -2
  165. package/dist/waterfall.esm.js +477 -405
  166. package/package.json +1 -1
  167. package/src/apexcharts.js +40 -59
  168. package/src/assets/apexcharts.css +38 -8
  169. package/src/charts/Bar.js +62 -55
  170. package/src/charts/BarStacked.js +80 -88
  171. package/src/charts/BoxCandleStick.js +28 -31
  172. package/src/charts/Icicle.js +68 -47
  173. package/src/charts/Line.js +118 -42
  174. package/src/charts/Pie.js +2 -8
  175. package/src/charts/Radar.js +5 -7
  176. package/src/charts/Radial.js +2 -6
  177. package/src/charts/RangeBar.js +47 -43
  178. package/src/charts/Sunburst.js +101 -98
  179. package/src/charts/Treemap.js +150 -88
  180. package/src/charts/Unit.js +368 -250
  181. package/src/charts/Violin.js +48 -30
  182. package/src/charts/common/Breadcrumb.js +2 -2
  183. package/src/charts/common/Hierarchy.js +32 -11
  184. package/src/charts/common/Jitter.js +32 -7
  185. package/src/charts/common/Stats.js +30 -23
  186. package/src/charts/common/bar/DataLabels.js +76 -81
  187. package/src/charts/common/bar/Helpers.js +43 -7
  188. package/src/charts/common/line/Helpers.js +12 -15
  189. package/src/charts/common/partition/NodeTooltip.js +29 -7
  190. package/src/charts/common/partition/Partition.js +33 -1
  191. package/src/charts/common/treemap/Helpers.js +3 -11
  192. package/src/charts/common/treemap/Nested.js +2 -3
  193. package/src/features/raincloud.js +16 -10
  194. package/src/features/stats.js +67 -62
  195. package/src/locales/en.json +2 -1
  196. package/src/locales/ro.json +3 -2
  197. package/src/modules/Animations.js +102 -95
  198. package/src/modules/AxisMapping.js +47 -12
  199. package/src/modules/Core.js +4 -0
  200. package/src/modules/CoreUtils.js +18 -42
  201. package/src/modules/Data.js +23 -24
  202. package/src/modules/DataLabels.js +6 -6
  203. package/src/modules/Exports.js +12 -5
  204. package/src/modules/Fill.js +17 -8
  205. package/src/modules/Filters.js +50 -50
  206. package/src/modules/Graphics.js +69 -51
  207. package/src/modules/Markers.js +3 -1
  208. package/src/modules/MorphTypeChange.js +13 -7
  209. package/src/modules/Range.js +44 -29
  210. package/src/modules/RendererController.js +17 -3
  211. package/src/modules/Scales.js +32 -9
  212. package/src/modules/Series.js +41 -19
  213. package/src/modules/Theme.js +1 -1
  214. package/src/modules/Toolbar.js +3 -2
  215. package/src/modules/UnitMarkRegistry.js +0 -5
  216. package/src/modules/ZoomPanSelection.js +123 -2
  217. package/src/modules/accessibility/KeyboardNavigation.js +114 -186
  218. package/src/modules/animations/Easing.js +2 -1
  219. package/src/modules/animations/LengthTransition.js +22 -2
  220. package/src/modules/annotations/Helpers.js +68 -52
  221. package/src/modules/axes/Grid.js +21 -7
  222. package/src/modules/axes/YAxis.js +8 -9
  223. package/src/modules/dimensions/Dimensions.js +9 -3
  224. package/src/modules/dimensions/Grid.js +2 -2
  225. package/src/modules/dimensions/XAxis.js +2 -5
  226. package/src/modules/drilldown/Breadcrumb.js +5 -2
  227. package/src/modules/helpers/Destroy.js +1 -1
  228. package/src/modules/helpers/UpdateHelpers.js +33 -15
  229. package/src/modules/highlightFilter/HighlightFilter.js +8 -9
  230. package/src/modules/highlightFilter/TreemapPart.js +2 -2
  231. package/src/modules/legend/HeatmapGradientLegend.js +76 -45
  232. package/src/modules/legend/Helpers.js +8 -1
  233. package/src/modules/legend/Legend.js +11 -12
  234. package/src/modules/license/LicenseEnforcer.js +5 -0
  235. package/src/modules/settings/Defaults.js +28 -56
  236. package/src/modules/settings/Globals.js +5 -0
  237. package/src/modules/settings/Options.js +7 -7
  238. package/src/modules/settings/TypeAliases.js +33 -16
  239. package/src/modules/streamgraph/StreamLabels.js +1 -0
  240. package/src/modules/tooltip/Labels.js +73 -76
  241. package/src/modules/tooltip/Marker.js +25 -21
  242. package/src/modules/tooltip/Position.js +88 -51
  243. package/src/modules/tooltip/Tooltip.js +242 -255
  244. package/src/modules/tooltip/Utils.js +71 -130
  245. package/src/modules/tooltip/constants.js +5 -5
  246. package/src/modules/trellis/Trellis.js +6 -0
  247. package/src/modules/trellis/TrellisChrome.js +18 -7
  248. package/src/modules/trellis/TrellisSync.js +2 -0
  249. package/src/modules/trellis/TrellisTooltip.js +2 -11
  250. package/src/modules/weave/WeaveHost.js +18 -12
  251. package/src/renderers/canvas/CanvasGraphics.js +1 -0
  252. package/src/ssr/DOMShim.js +10 -0
  253. package/src/svg/SVGFilter.js +26 -17
  254. package/src/types/internal.d.ts +9 -3
  255. package/src/utils/Utils.js +0 -14
  256. package/types/apexcharts.d.ts +33 -12
@@ -48,6 +48,8 @@ export default class HeatmapGradientLegend {
48
48
  this._max = 0
49
49
  /** @type {any} */
50
50
  this._geom = null
51
+ /** @type {any} */
52
+ this._grad = null
51
53
  /** @type {any[]} */
52
54
  this._bandHitEls = []
53
55
  /** @type {number} Currently highlighted band index (-1 = none). */
@@ -58,6 +60,8 @@ export default class HeatmapGradientLegend {
58
60
  * @type {HTMLElement|null}
59
61
  */
60
62
  this._targetEl = null
63
+ /** @type {(() => any[])|null} detached mode: every panel's w */
64
+ this.panelsW = null
61
65
  this._onCellEnter = this._onCellEnter.bind(this)
62
66
  this._onCellLeave = this._onCellLeave.bind(this)
63
67
  this._onBandEnter = this._onBandEnter.bind(this)
@@ -217,15 +221,8 @@ export default class HeatmapGradientLegend {
217
221
  linearGrad.setAttribute('y2', '0')
218
222
  }
219
223
 
220
- const { min, max, stops, bands } = this._computeStops()
221
- this._min = min
222
- this._max = max
223
- stops.forEach((s) => {
224
- const stopEl = BrowserAPIs.createElementNS(SVG_NS, 'stop')
225
- stopEl.setAttribute('offset', `${(s.percent * 100).toFixed(2)}%`)
226
- stopEl.setAttribute('stop-color', s.color)
227
- linearGrad.appendChild(stopEl)
228
- })
224
+ this._grad = linearGrad
225
+ const { min, max, bands } = this._paintStops()
229
226
  defs.appendChild(linearGrad)
230
227
  svg.appendChild(defs)
231
228
 
@@ -498,6 +495,9 @@ export default class HeatmapGradientLegend {
498
495
  * Honors `legend.offsetX/offsetY` for user nudging. Safe to call repeatedly.
499
496
  */
500
497
  repositionToPlot() {
498
+ // The cells' y extent and hasNegs exist only now (draw runs before
499
+ // coreCalculations), so shade the strip again against them.
500
+ if (this._grad) this._paintStops()
501
501
  if (!Environment.isBrowser()) return
502
502
  // Detached mode (trellis): the host slot owns layout entirely.
503
503
  if (this._targetEl) return
@@ -672,7 +672,7 @@ export default class HeatmapGradientLegend {
672
672
  if (idx < 0 || idx === this._activeBandIndex) return
673
673
  this._activeBandIndex = idx
674
674
  this.ctx?.events?.fireEvent?.('legendHover', [this.ctx, idx, w])
675
- new Series(w).highlightRangeInSeries(idx, 'highlight')
675
+ this._highlightRange(idx, 'highlight')
676
676
  }
677
677
 
678
678
  /** Leaving a band clears the highlight. */
@@ -680,7 +680,18 @@ export default class HeatmapGradientLegend {
680
680
  if (this._activeBandIndex < 0) return
681
681
  const idx = this._activeBandIndex
682
682
  this._activeBandIndex = -1
683
- new Series(this.w).highlightRangeInSeries(idx, 'reset')
683
+ this._highlightRange(idx, 'reset')
684
+ }
685
+
686
+ /**
687
+ * A shared trellis strip sets `panelsW` so a band reaches every panel.
688
+ * @param {number} idx
689
+ * @param {'highlight'|'reset'} action
690
+ */
691
+ _highlightRange(idx, action) {
692
+ ;(this.panelsW?.() || [this.w]).forEach((/** @type {any} */ w) =>
693
+ new Series(w).highlightRangeInSeries(idx, action),
694
+ )
684
695
  }
685
696
 
686
697
  _attachHoverListeners() {
@@ -702,11 +713,12 @@ export default class HeatmapGradientLegend {
702
713
  * @param {...any} args
703
714
  */
704
715
  _onCellEnter(...args) {
705
- const w = this.w
706
716
  if (!this.arrowEl) return
707
717
  // The opts object is the last argument.
708
718
  const opts = args[args.length - 1]
709
719
  if (!opts || typeof opts !== 'object') return
720
+ // the hovered chart: a shared trellis strip hears every panel
721
+ const w = opts.w || this.w
710
722
  const i = opts.seriesIndex
711
723
  const j = opts.dataPointIndex
712
724
  if (typeof i !== 'number' || typeof j !== 'number') return
@@ -845,6 +857,22 @@ export default class HeatmapGradientLegend {
845
857
  return polygon
846
858
  }
847
859
 
860
+ /** (Re)write the strip's stops; returns `_computeStops()`. */
861
+ _paintStops() {
862
+ const r = this._computeStops()
863
+ const grad = this._grad
864
+ this._min = r.min
865
+ this._max = r.max
866
+ grad.innerHTML = ''
867
+ r.stops.forEach((s) => {
868
+ const stopEl = BrowserAPIs.createElementNS(SVG_NS, 'stop')
869
+ stopEl.setAttribute('offset', `${(s.percent * 100).toFixed(2)}%`)
870
+ stopEl.setAttribute('stop-color', s.color)
871
+ grad.appendChild(stopEl)
872
+ })
873
+ return r
874
+ }
875
+
848
876
  /**
849
877
  * Build gradient stops + return effective min/max.
850
878
  * - If `colorScale.ranges` is set, stops are placed at each range boundary
@@ -898,7 +926,9 @@ export default class HeatmapGradientLegend {
898
926
  // one-sided = the historical expand-not-clamp semantics.
899
927
  let min = dataMin
900
928
  let max = dataMax
901
- if (typeof cs.min !== 'undefined' && typeof cs.max !== 'undefined' && cs.max > cs.min) {
929
+ const csWindow =
930
+ typeof cs.min !== 'undefined' && typeof cs.max !== 'undefined' && cs.max > cs.min
931
+ if (csWindow) {
902
932
  min = cs.min
903
933
  max = cs.max
904
934
  } else {
@@ -956,45 +986,46 @@ export default class HeatmapGradientLegend {
956
986
  // is the documented behavior).
957
987
  const baseColor = w.globals.colors[0] || '#008FFB'
958
988
  const utils = new Utils()
959
- const plot = w.config.plotOptions[w.config.chart.type] || {}
989
+ const type = w.config.chart.type
990
+ const plot = w.config.plotOptions[type] || {}
960
991
  const shadeIntensity = plot.shadeIntensity ?? 0.5
961
- const hasNegs = /** @type {any} */ (w.globals).hasNegs
992
+ const g = /** @type {any} */ (w.globals)
993
+ const hasNegs = g.hasNegs
994
+ // A non-distributed heatmap's cells shade against the niced y extent
995
+ // and clamp into it (determineColor); use it once coreCalculations ran.
996
+ // A one-sided colorScale.max past maxY is ignored there, so cap at maxY.
997
+ const yExt =
998
+ type === 'heatmap' && !plot.distributed && !csWindow && g.maxY >= g.minY
999
+ const hi = yExt ? g.maxY : max
1000
+ const total =
1001
+ Math.abs(hi) + Math.abs(yExt ? (cs.min < g.minY ? cs.min : g.minY) : min)
1002
+ const k = shadeIntensity * 1.25
962
1003
  const n = Math.max(2, cfg.stops || 16)
963
1004
  for (let s = 0; s < n; s++) {
964
1005
  const t = s / (n - 1) // 0..1
965
- // Map t to the shade percent the cell at that t would receive.
1006
+ // Map t to the shade fraction the cell at that t would receive.
966
1007
  // determineColor computes percent = 100*val/(|min|+|max|), so the cell
967
- // sitting at value v = min + t*(max-min) gets percent_v.
968
- const v = min + t * (max - min)
969
- const total = Math.abs(max) + Math.abs(min)
970
- const percent_v = total === 0 ? 0 : (100 * v) / total
971
- let colorShadePercent
972
- if (hasNegs) {
973
- if (plot.reverseNegativeShade) {
974
- colorShadePercent =
975
- percent_v < 0
976
- ? (percent_v / 100) * (shadeIntensity * 1.25)
977
- : (1 - percent_v / 100) * (shadeIntensity * 1.25)
978
- } else {
979
- colorShadePercent =
980
- percent_v <= 0
981
- ? 1 - (1 + percent_v / 100) * shadeIntensity
982
- : (1 - percent_v / 100) * shadeIntensity
983
- }
984
- } else {
985
- colorShadePercent = 1 - percent_v / 100
986
- }
987
- // Clamp to a reasonable range to avoid color blowout.
988
- if (colorShadePercent > 1) colorShadePercent = 1
989
- if (colorShadePercent < -1) colorShadePercent = -1
1008
+ // sitting at value v = min + t*(max-min) gets p = v / total.
1009
+ const p =
1010
+ total === 0 ? 0 : Math.min(min + t * (max - min), hi) / total
1011
+ // Clamp to a reasonable range to avoid color blowout. Treemap tiles
1012
+ // scale the plain shade too (getShadeColor).
1013
+ const c = Math.max(
1014
+ -1,
1015
+ Math.min(
1016
+ 1,
1017
+ hasNegs
1018
+ ? plot.reverseNegativeShade
1019
+ ? (p < 0 ? p : 1 - p) * k
1020
+ : p <= 0
1021
+ ? 1 - (1 + p) * shadeIntensity
1022
+ : (1 - p) * shadeIntensity
1023
+ : (1 - p) * (type === 'treemap' ? k : 1),
1024
+ ),
1025
+ )
990
1026
 
991
1027
  const shaded = plot.enableShades
992
- ? utils.shadeColor(
993
- w.config.theme.mode === 'dark'
994
- ? colorShadePercent * -1
995
- : colorShadePercent,
996
- baseColor,
997
- )
1028
+ ? utils.shadeColor(w.config.theme.mode === 'dark' ? -c : c, baseColor)
998
1029
  : baseColor
999
1030
  stops.push({ percent: t, color: shaded })
1000
1031
  }
@@ -55,6 +55,8 @@ export default class Helpers {
55
55
  */
56
56
  toggleDataSeries(seriesCnt, isHidden) {
57
57
  const w = this.w
58
+ // a legendClick handler may have destroyed the chart
59
+ if (!w.dom.baseEl) return
58
60
  if (w.globals.axisCharts || w.config.chart.type === 'radialBar') {
59
61
  w.globals.resized = true // we don't want initial animations again
60
62
 
@@ -276,7 +278,12 @@ export default class Helpers {
276
278
  const w = this.w
277
279
  const gl = w.globals
278
280
 
279
- const series = Utils.clone(w.config.series)
281
+ // An axis chart only replaces a row's `data` below, so a copy per row
282
+ // does; a deep clone cost every point, once per `hidden: true` series on
283
+ // each render. A non-axis collapse writes into the slice values.
284
+ const series = gl.axisCharts
285
+ ? Utils.copySeriesShallow(w.config.series)
286
+ : Utils.clone(w.config.series)
280
287
 
281
288
  if (gl.axisCharts) {
282
289
  const yaxis = w.config.yaxis[gl.seriesYAxisReverseMap[realIndex]]
@@ -74,6 +74,11 @@ class Legend {
74
74
  const gl = w.globals
75
75
  const cnf = w.config
76
76
 
77
+ // Tear down any previous gradient legend every render, so hiding the
78
+ // legend does not leave its listeners and repositioning behind.
79
+ this.heatmapGradientLegend?.destroy()
80
+ this.heatmapGradientLegend = null
81
+
77
82
  // Recompute each render: the Legend instance is reused across updates, so a
78
83
  // value cached in the constructor would go stale when updateOptions changes
79
84
  // the type / distributed flag / series count (e.g. a distributed single-series
@@ -106,12 +111,6 @@ class Legend {
106
111
  elLegendWrap.removeChild(elLegendWrap.firstChild)
107
112
  }
108
113
 
109
- // Tear down any previous gradient-legend listeners before re-rendering.
110
- if (this.heatmapGradientLegend) {
111
- this.heatmapGradientLegend.destroy()
112
- this.heatmapGradientLegend = null
113
- }
114
-
115
114
  if (HeatmapGradientLegend.isEnabled(w)) {
116
115
  this.heatmapGradientLegend = new HeatmapGradientLegend(w, this.ctx)
117
116
  this.heatmapGradientLegend.draw()
@@ -381,7 +380,8 @@ class Legend {
381
380
  // by index: groups may reuse series names, and an unnamed series has
382
381
  // none to match
383
382
  const lg = legendGroups[w.labelData.seriesGroupIndex[i]]
384
- if (lg) elLegendWrap.appendChild(lg)
383
+ // once: re-appending moves the group, reordering interleaved groups
384
+ if (lg && !lg.parentNode) elLegendWrap.appendChild(lg)
385
385
  ;(lg || elLegendWrap).appendChild(elLegend)
386
386
 
387
387
  elLegendWrap.classList.add(
@@ -537,10 +537,8 @@ class Legend {
537
537
  const hoverOverLegend = isLegendItem(target)
538
538
 
539
539
  if (w.config.chart.type !== 'heatmap' && !this.isBarsDistributed) {
540
- if (
541
- !target.classList.contains('apexcharts-inactive-legend') &&
542
- hoverOverLegend
543
- ) {
540
+ // closest: the text span of a hidden item carries no inactive class
541
+ if (hoverOverLegend && !target.closest('.apexcharts-inactive-legend')) {
544
542
  const series = new Series(this.ctx.w)
545
543
  series.toggleSeriesOnHover(e, target)
546
544
  }
@@ -585,7 +583,8 @@ class Legend {
585
583
  // can keep toggling without having to re-tab to the legend.
586
584
  if (rel !== null && w.config.legend.onItemClick.toggleDataSeries) {
587
585
  requestAnimationFrame(() => {
588
- const restored = w.dom.baseEl.querySelector(
586
+ // the chart may have been destroyed before this frame
587
+ const restored = w.dom.baseEl?.querySelector(
589
588
  `.apexcharts-legend-series[rel="${rel}"]`,
590
589
  )
591
590
  if (restored) /** @type {HTMLElement} */ (restored).focus()
@@ -235,6 +235,7 @@ function reinstateWatermark(ctx, elWrap) {
235
235
  // and resolves a per-chart `chart.license` key, so letting the package decide
236
236
  // would paint free charts and erase watermarks we deliberately applied.
237
237
  const node = Watermark.add(elWrap, { manage: false })
238
+ ctx._wmPainted = true
238
239
  if (!node || typeof MutationObserver === 'undefined') return
239
240
  if (ctx._wmNodeObserver && ctx._wmObservedNode === node) return
240
241
 
@@ -279,6 +280,10 @@ function addWatermark(ctx, elWrap) {
279
280
  * @param {any} ctx @param {HTMLElement | null | undefined} [elWrap]
280
281
  */
281
282
  export function teardownWatermark(ctx, elWrap) {
283
+ // Free and licensed charts run this on every render: with nothing painted
284
+ // there is nothing to undo, so skip the subtree query for the node.
285
+ if (!ctx._wmPainted) return
286
+ ctx._wmPainted = false
282
287
  if (ctx._wmWrapObserver) {
283
288
  ctx._wmWrapObserver.disconnect()
284
289
  ctx._wmWrapObserver = null
@@ -3,7 +3,7 @@ import Utils from '../../utils/Utils'
3
3
  import DateTime from '../../utils/DateTime'
4
4
  import Formatters from '../Formatters'
5
5
  import Options from './Options'
6
- import { TYPE_ALIASES, BUILTIN_TYPES } from './TypeAliases'
6
+ import { TYPE_ALIASES, BUILTIN_TYPES, SOLO_TYPES } from './TypeAliases'
7
7
 
8
8
  /**
9
9
  * ApexCharts Default Class for setting default options for all chart types.
@@ -110,6 +110,17 @@ const TYPE_OWNED_PATHS = [
110
110
  */
111
111
  const floorLabel = (val) => (Utils.isNumber(val) ? Math.floor(val) : val)
112
112
 
113
+ /**
114
+ * The pie, donut and polarArea label: the share of the whole, as a percentage.
115
+ * One function for all three, so a pie that becomes a donut hands it over as
116
+ * the same default. Guarded because a config survives a chart-type change: a
117
+ * pie that becomes a treemap hands this a category NAME, and a default of ours
118
+ * must not throw on a value it was never designed for.
119
+ * @param {any} val
120
+ */
121
+ const percentLabel = (val) =>
122
+ typeof val === 'number' ? val.toFixed(1) + '%' : val
123
+
113
124
  /**
114
125
  * The base options with a type's defaults laid over them: what a leaf is when
115
126
  * no mode preset has touched it.
@@ -380,20 +391,13 @@ export default class Defaults {
380
391
  const requestedType = opts.chart.requestedType
381
392
  let chartDefaults
382
393
 
383
- if (requestedType === 'funnel' || requestedType === 'pyramid') {
384
- chartDefaults = /** @type {any} */ (defaults)[requestedType]()
385
- } else if (requestedType === 'gauge') {
386
- chartDefaults = defaults.gauge()
387
- } else if (requestedType === 'histogram') {
388
- chartDefaults = defaults.histogram()
389
- } else if (requestedType === 'waterfall') {
390
- chartDefaults = defaults.waterfall()
391
- } else if (requestedType === 'dumbbell') {
392
- chartDefaults = defaults.dumbbell()
393
- } else if (requestedType === 'streamgraph') {
394
- chartDefaults = defaults.streamgraph()
395
- } else if (requestedType === 'raincloud') {
396
- chartDefaults = defaults.raincloud()
394
+ // Every alias but waffle (and column, a plain bar) has a method of its own.
395
+ const aliasDefaults =
396
+ /** @type {any} */ (TYPE_ALIASES)[requestedType] &&
397
+ /** @type {any} */ (defaults)[requestedType]
398
+
399
+ if (aliasDefaults) {
400
+ chartDefaults = aliasDefaults.call(defaults)
397
401
  } else if (requestedType === 'waffle') {
398
402
  chartDefaults = Utils.extend(defaults.unit(), {
399
403
  plotOptions: { unit: { layout: 'grid', shape: 'square' } },
@@ -1374,7 +1378,9 @@ export default class Defaults {
1374
1378
  return {
1375
1379
  chart: {
1376
1380
  animations: {
1377
- animateGradually: false,
1381
+ animateGradually: {
1382
+ enabled: false,
1383
+ },
1378
1384
  },
1379
1385
  },
1380
1386
  stroke: {
@@ -2064,16 +2070,9 @@ export default class Defaults {
2064
2070
  chartType === 'violin') &&
2065
2071
  opts.plotOptions?.bar?.horizontal
2066
2072
 
2067
- const unsupportedZoom =
2068
- chartType === 'pie' ||
2069
- chartType === 'polarArea' ||
2070
- chartType === 'donut' ||
2071
- chartType === 'radar' ||
2072
- chartType === 'radialBar' ||
2073
- chartType === 'heatmap' ||
2074
- chartType === 'unit' ||
2075
- chartType === 'sunburst' ||
2076
- chartType === 'icicle'
2073
+ // A type that owns its plot has no category axis to space: the registry
2074
+ // list, since a hand-kept copy of it once left treemap out.
2075
+ const unsupportedZoom = SOLO_TYPES.includes(chartType)
2077
2076
 
2078
2077
  // The type's own axis counts as much as the user's: a histogram asks for a
2079
2078
  // numeric axis through Defaults.histogram, not by writing it into opts.
@@ -2478,16 +2477,7 @@ export default class Defaults {
2478
2477
  },
2479
2478
  },
2480
2479
  dataLabels: {
2481
- /**
2482
- * The share of the whole, as a percentage. Guarded because a config
2483
- * survives a chart-type change: a pie that becomes a treemap hands
2484
- * this same default a category NAME, and a default of ours must not
2485
- * throw on a value it was never designed for.
2486
- * @param {any} val
2487
- */
2488
- formatter(val) {
2489
- return typeof val === 'number' ? val.toFixed(1) + '%' : val
2490
- },
2480
+ formatter: percentLabel,
2491
2481
  style: {
2492
2482
  colors: ['#fff'],
2493
2483
  },
@@ -2534,16 +2524,7 @@ export default class Defaults {
2534
2524
  },
2535
2525
  },
2536
2526
  dataLabels: {
2537
- /**
2538
- * The share of the whole, as a percentage. Guarded because a config
2539
- * survives a chart-type change: a pie that becomes a treemap hands
2540
- * this same default a category NAME, and a default of ours must not
2541
- * throw on a value it was never designed for.
2542
- * @param {any} val
2543
- */
2544
- formatter(val) {
2545
- return typeof val === 'number' ? val.toFixed(1) + '%' : val
2546
- },
2527
+ formatter: percentLabel,
2547
2528
  style: {
2548
2529
  colors: ['#fff'],
2549
2530
  },
@@ -2593,16 +2574,7 @@ export default class Defaults {
2593
2574
  },
2594
2575
  },
2595
2576
  dataLabels: {
2596
- /**
2597
- * The share of the whole, as a percentage. Guarded because a config
2598
- * survives a chart-type change: a pie that becomes a treemap hands
2599
- * this same default a category NAME, and a default of ours must not
2600
- * throw on a value it was never designed for.
2601
- * @param {any} val
2602
- */
2603
- formatter(val) {
2604
- return typeof val === 'number' ? val.toFixed(1) + '%' : val
2605
- },
2577
+ formatter: percentLabel,
2606
2578
  enabled: false,
2607
2579
  },
2608
2580
  stroke: {
@@ -49,6 +49,11 @@ export default class Globals {
49
49
  // that drops range data. See audit D1.
50
50
  gl.seriesRangeName = {}
51
51
 
52
+ // Fill colours resolved through a probe (CSS variables), keyed by the
53
+ // colour as configured. Reset each render, so a theme change is re-read.
54
+ // No prototype: a configured colour is user input.
55
+ gl.themeColors = Object.create(null)
56
+
52
57
  // ── Labels & categories (ephemeral — derived from parsed series/config) ──
53
58
  gl.labels = []
54
59
  gl.hasXaxisGroups = false
@@ -498,12 +498,6 @@ export default class Options {
498
498
  // canvas-capable in v1; chrome stays SVG.
499
499
  renderer: 'svg',
500
500
  rendererThreshold: 8000,
501
- layers: {
502
- series: 'auto',
503
- grid: 'svg',
504
- annotations: 'svg',
505
- dataLabels: 'svg',
506
- },
507
501
  dropShadow: {
508
502
  enabled: false,
509
503
  enabledOnSeries: undefined,
@@ -788,7 +782,14 @@ export default class Options {
788
782
  // asked for and nobody can undo is a trap. Set either to true to
789
783
  // force the gesture on regardless (for a page that supplies its own
790
784
  // reset control), or false to turn it off outright.
785
+ //
786
+ // The 'auto' wheel is also cooperative: a bare wheel scrolls the
787
+ // page, and Ctrl/Cmd + wheel (or a trackpad pinch) zooms, so a page
788
+ // of charts scrolls past them. `true` zooms on every wheel.
791
789
  allowMouseWheelZoom: 'auto',
790
+ // With the cooperative wheel, a bare scroll over the chart briefly
791
+ // shows how to zoom it ("Use Ctrl + scroll to zoom").
792
+ wheelHint: true,
792
793
  // Momentum: two-finger pinch-zoom on touch devices. Zooms the x-axis
793
794
  // around the pinch centroid (matching the x-only wheel/toolbar zoom),
794
795
  // frame-by-frame rather than the 400ms wheel throttle.
@@ -839,7 +840,6 @@ export default class Options {
839
840
  },
840
841
  dataReducer: {
841
842
  enabled: false,
842
- algorithm: 'lttb',
843
843
  targetPoints: 250,
844
844
  threshold: 500,
845
845
  },
@@ -32,23 +32,27 @@
32
32
  */
33
33
  export const RESERVED_TYPES = ['icicle', 'unit', 'sunburst', 'violin']
34
34
 
35
+ // No prototype, so a lookup never finds 'constructor' or 'toString'
35
36
  /** @type {Record<string, string>} */
36
- export const TYPE_ALIASES = {
37
- funnel: 'bar',
38
- pyramid: 'bar',
39
- gauge: 'radialBar',
40
- waffle: 'unit',
41
- histogram: 'bar',
42
- waterfall: 'rangeBar',
43
- dumbbell: 'rangeBar',
44
- streamgraph: 'rangeArea',
45
- raincloud: 'violin',
46
- // `column` is the name half the world uses for a vertical bar chart, and the
47
- // combo path has always accepted it on `series[].type`. On `chart.type` it
48
- // used to fall through every dispatch and die inside the renderer (#5325),
49
- // so it is spelled out here as what it has always meant.
50
- column: 'bar',
51
- }
37
+ export const TYPE_ALIASES = Object.setPrototypeOf(
38
+ {
39
+ funnel: 'bar',
40
+ pyramid: 'bar',
41
+ gauge: 'radialBar',
42
+ waffle: 'unit',
43
+ histogram: 'bar',
44
+ waterfall: 'rangeBar',
45
+ dumbbell: 'rangeBar',
46
+ streamgraph: 'rangeArea',
47
+ raincloud: 'violin',
48
+ // `column` is the name half the world uses for a vertical bar chart, and the
49
+ // combo path has always accepted it on `series[].type`. On `chart.type` it
50
+ // used to fall through every dispatch and die inside the renderer (#5325),
51
+ // so it is spelled out here as what it has always meant.
52
+ column: 'bar',
53
+ },
54
+ null,
55
+ )
52
56
 
53
57
  /**
54
58
  * Alias chart types that cannot draw anything true until the named feature
@@ -122,6 +126,19 @@ export const XY_TYPES = [
122
126
  'bubble',
123
127
  ]
124
128
 
129
+ /**
130
+ * The XY types drawn through the bar pathway: one slot per point, so the
131
+ * hover divisor counts slots, and on a numeric axis the edge marks hang half
132
+ * a slot outside the plot and need padding and a widened clip.
133
+ */
134
+ export const BAR_PATHWAY_TYPES = [
135
+ 'bar',
136
+ 'rangeBar',
137
+ 'candlestick',
138
+ 'boxPlot',
139
+ 'violin',
140
+ ]
141
+
125
142
  /**
126
143
  * Types that need the axis/grid/scale pipeline but own the whole plot: they
127
144
  * take part in no combo, and a chart is one of them or it is not.
@@ -276,6 +276,7 @@ export default class StreamLabels {
276
276
  maxWidth: span,
277
277
  fontSize: `${px}px`,
278
278
  fontFamily,
279
+ fontWeight,
279
280
  })
280
281
  if (!text || text === '...') continue
281
282
  const drawnWidth =