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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apexcharts",
3
- "version": "8.2.0",
3
+ "version": "8.3.1",
4
4
  "description": "A JavaScript Chart Library",
5
5
  "repository": {
6
6
  "type": "git",
package/src/apexcharts.js CHANGED
@@ -862,6 +862,9 @@ export default class ApexCharts {
862
862
  ) {
863
863
  me.keyboardNavigation?.init()
864
864
  }
865
+ // The focus note is for this render only: one that nav was off for
866
+ // must not pull focus back when a later update turns nav on
867
+ w.interact.keyNav = null
865
868
 
866
869
  if (
867
870
  Environment.isBrowser() &&
@@ -1055,50 +1058,30 @@ export default class ApexCharts {
1055
1058
  // fixes apexcharts.js#1488
1056
1059
  w.interact.selection = undefined
1057
1060
 
1058
- // try shallow comparison first before expensive JSON.stringify
1059
- if (this.lastUpdateOptions) {
1060
- // quick shallow check on top-level keys
1061
- if (Utils.shallowEqual(this.lastUpdateOptions, options)) {
1062
- return Promise.resolve(this)
1063
- }
1064
-
1065
- // If shallow check fails, do deep comparison only for critical paths
1066
- // check series separately (skipped for data-heavy series, where the
1067
- // stringify costs more than the render it might save)
1068
- if (
1069
- options.series &&
1070
- this.lastUpdateOptions.series &&
1071
- !ApexCharts._optionsTooBigToCompare(options)
1072
- ) {
1073
- if (
1074
- Utils.stringifyForCompare(this.lastUpdateOptions.series) ===
1075
- Utils.stringifyForCompare(options.series)
1076
- ) {
1077
- // series unchanged, check other options
1078
- const optionsWithoutSeries = { ...options }
1079
- const lastWithoutSeries = { ...this.lastUpdateOptions }
1080
- delete optionsWithoutSeries.series
1081
- delete lastWithoutSeries.series
1082
-
1083
- if (Utils.shallowEqual(optionsWithoutSeries, lastWithoutSeries)) {
1084
- return Promise.resolve(this)
1085
- }
1086
- }
1087
- }
1088
- }
1061
+ // An identical update is skipped in update(), against the options it
1062
+ // last rendered. The checks that used to run here compared this raw
1063
+ // payload with those processed options, so they could only match a
1064
+ // payload of bare values, and a series payload never.
1089
1065
 
1090
1066
  if (options.series) {
1091
1067
  this.data.resetParsingFlags()
1068
+ this.series.clearSeriesCache()
1092
1069
 
1093
- this.series.resetSeries(false, true, false)
1094
1070
  if (options.series.length && options.series[0].data) {
1071
+ // A partial row inherits from the baseline resetSeries() restores,
1072
+ // collapsed rows emptied. Shallow rows: restoring it in place deep
1073
+ // cloned every old point twice, and the merge then replaced it.
1074
+ const peek = w.globals._initialSeriesPeek
1075
+ const base = this.series.emptyCollapsedSeries(
1076
+ Utils.copySeriesShallow(Array.isArray(peek) ? peek : w.config.series),
1077
+ )
1095
1078
  /**
1096
1079
  * @param {Record<string, any>} s
1097
1080
  * @param {number} i
1098
1081
  */
1099
1082
  options.series = options.series.map(
1100
1083
  (/** @type {any} */ s, /** @type {any} */ i) => {
1101
- return this.updateHelpers._extendSeries(s, i)
1084
+ return this.updateHelpers._extendSeries(s, i, base[i])
1102
1085
  },
1103
1086
  )
1104
1087
  }
@@ -1232,11 +1215,7 @@ export default class ApexCharts {
1232
1215
  // zoom, a brush moving its target, updateSeries(data, false)) silently
1233
1216
  // switched off the animation of every append after it.
1234
1217
  me.w.globals.shouldAnimate = true
1235
- // previous paths feed the update morph; with animations off nothing
1236
- // consumes them, and the capture is O(n) (stream-frame + DOM walk)
1237
- if (me.w.config.chart.animations.enabled) {
1238
- me.series.getPreviousPaths()
1239
- }
1218
+ me.updateHelpers.capture(true)
1240
1219
 
1241
1220
  // Histogram, waterfall and dumbbell: `config.series` holds rows this
1242
1221
  // library derived (binned counts, accumulated [start, end] pairs, merged
@@ -1347,24 +1326,22 @@ export default class ApexCharts {
1347
1326
  // and cloning megabytes of series data costs more per update than the
1348
1327
  // render it might save. Data-heavy paths (updateSeries/appendData) call
1349
1328
  // update() with no options at all and skip straight through.
1350
- if (
1351
- options &&
1352
- this.lastUpdateOptions &&
1353
- !ApexCharts._optionsTooBigToCompare(options) &&
1354
- Utils.stringifyForCompare(this.lastUpdateOptions) ===
1355
- Utils.stringifyForCompare(options)
1356
- ) {
1329
+ //
1330
+ // The comparison string is taken now and kept: a deep clone kept to be
1331
+ // stringified on the next call cost a clone per update. The options
1332
+ // themselves are kept by reference (the payload copied at the boundary
1333
+ // is the chart's own) for the highlight filter's radial pass.
1334
+ const key =
1335
+ options && !ApexCharts._optionsTooBigToCompare(options)
1336
+ ? Utils.stringifyForCompare(options)
1337
+ : null
1338
+ // (Every reset nulls lastUpdateOptions, which disarms the key too.)
1339
+ if (this.lastUpdateOptions && key === this._lastUpdateKey) {
1357
1340
  // Options are identical, skip the update
1358
1341
  return resolve(this)
1359
1342
  }
1360
-
1361
- // Series data changed (or is too big to compare cheaply): any previously
1362
- // stored options no longer describe the chart, so clear rather than
1363
- // deep-clone a potentially huge object.
1364
- this.lastUpdateOptions =
1365
- options && !ApexCharts._optionsTooBigToCompare(options)
1366
- ? Utils.clone(options)
1367
- : null
1343
+ this._lastUpdateKey = key
1344
+ this.lastUpdateOptions = key && options
1368
1345
 
1369
1346
  // A type-change morph that has already been shown is over for this
1370
1347
  // render: it starts from the screen, not from the old chart's shapes.
@@ -2609,22 +2586,26 @@ export default class ApexCharts {
2609
2586
  * Returns the highest y value in the specified series.
2610
2587
  *
2611
2588
  * @param {number} [seriesIndex=0]
2612
- * @returns {number}
2589
+ * @returns {number | undefined}
2613
2590
  */
2614
2591
  getHighestValueInSeries(seriesIndex = 0) {
2615
- const range = new Range(this.w)
2616
- return range.getMinYMaxY(seriesIndex).highestY
2592
+ return (
2593
+ this.w.seriesData.series[seriesIndex] &&
2594
+ new Range(this.w).getMinYMaxY(seriesIndex).highestY
2595
+ )
2617
2596
  }
2618
2597
 
2619
2598
  /**
2620
2599
  * Returns the lowest y value in the specified series.
2621
2600
  *
2622
2601
  * @param {number} [seriesIndex=0]
2623
- * @returns {number}
2602
+ * @returns {number | undefined}
2624
2603
  */
2625
2604
  getLowestValueInSeries(seriesIndex = 0) {
2626
- const range = new Range(this.w)
2627
- return range.getMinYMaxY(seriesIndex).lowestY
2605
+ return (
2606
+ this.w.seriesData.series[seriesIndex] &&
2607
+ new Range(this.w).getMinYMaxY(seriesIndex).lowestY
2608
+ )
2628
2609
  }
2629
2610
 
2630
2611
  /**
@@ -1040,6 +1040,41 @@ rect.legend-mouseover-inactive,
1040
1040
  cursor: move
1041
1041
  }
1042
1042
 
1043
+ .apexcharts-wheel-hint {
1044
+ position: absolute;
1045
+ inset: 0;
1046
+ z-index: 12;
1047
+ display: flex;
1048
+ align-items: center;
1049
+ justify-content: center;
1050
+ pointer-events: none;
1051
+ opacity: 0;
1052
+ transition: opacity 0.2s ease;
1053
+ }
1054
+
1055
+ .apexcharts-wheel-hint-visible {
1056
+ opacity: 1;
1057
+ }
1058
+
1059
+ .apexcharts-wheel-hint span {
1060
+ padding: 6px 12px;
1061
+ border-radius: 8px;
1062
+ font-size: 13px;
1063
+ color: #fff;
1064
+ background: rgba(28, 28, 31, 0.82);
1065
+ }
1066
+
1067
+ .apexcharts-theme-dark .apexcharts-wheel-hint span {
1068
+ color: #1c1c1f;
1069
+ background: rgba(255, 255, 255, 0.9);
1070
+ }
1071
+
1072
+ @media (prefers-reduced-motion: reduce) {
1073
+ .apexcharts-wheel-hint {
1074
+ transition: none;
1075
+ }
1076
+ }
1077
+
1043
1078
  .apexcharts-menu-icon,
1044
1079
  .apexcharts-measure-icon,
1045
1080
  .apexcharts-pan-icon,
@@ -1262,21 +1297,16 @@ rect.legend-mouseover-inactive,
1262
1297
  fill: none
1263
1298
  }
1264
1299
 
1265
- .apexcharts-pie-label-delay,
1300
+ /* A slow fade, on purpose: these come in while the dots are still easing
1301
+ into place, so a longer fade reads as arriving WITH the crowd. */
1266
1302
  .apexcharts-unit-label-delay {
1267
1303
  opacity: 0;
1268
1304
  animation-name: opaque;
1269
- animation-duration: .3s;
1305
+ animation-duration: .5s;
1270
1306
  animation-fill-mode: forwards;
1271
1307
  animation-timing-function: ease
1272
1308
  }
1273
1309
 
1274
- /* Slower than the pie's, on purpose: these come in while the dots are still
1275
- easing into place, so a longer fade reads as arriving WITH the crowd. */
1276
- .apexcharts-unit-label-delay {
1277
- animation-duration: .5s
1278
- }
1279
-
1280
1310
  .apexcharts-radialbar-label {
1281
1311
  cursor: pointer;
1282
1312
  }
package/src/charts/Bar.js CHANGED
@@ -7,10 +7,10 @@ import Filters from '../modules/Filters'
7
7
  import Graphics from '../modules/Graphics'
8
8
  import Animations, { computeStagger } from '../modules/Animations'
9
9
  import {
10
- datumKey,
11
10
  lengthTransitionEnabled,
12
11
  renderBarExitGhosts,
13
12
  seriesJoin,
13
+ seriesKeys,
14
14
  } from '../modules/animations/LengthTransition'
15
15
  import Series from '../modules/Series'
16
16
  import AxisMapping from '../modules/AxisMapping'
@@ -136,7 +136,7 @@ class Bar {
136
136
  /**
137
137
  * Point the per-series axis state at this series' y axis. Every bar-family
138
138
  * renderer calls it before initialPositions, which reads the baseline by
139
- * this.translationsIndex.
139
+ * this.translationsIndex and flips it for a reversed axis.
140
140
  * @param {number} realIndex
141
141
  * @return {number} translationsIndex
142
142
  */
@@ -145,6 +145,7 @@ class Bar {
145
145
  this.yaxisIndex = this.w.globals.seriesYAxisReverseMap[realIndex]
146
146
  this.translationsIndex = realIndex
147
147
  }
148
+ this.isReversed = this.w.config.yaxis[this.yaxisIndex]?.reversed
148
149
  return this.translationsIndex
149
150
  }
150
151
 
@@ -163,7 +164,7 @@ class Bar {
163
164
  this.series = series
164
165
  this.yRatio = coreUtils.getLogYRatios(this.yRatio)
165
166
 
166
- this.barHelpers.initVariables(series)
167
+ this.barHelpers.initVariables(series, seriesIndex)
167
168
 
168
169
  const ret = graphics.group({
169
170
  class: 'apexcharts-bar-series apexcharts-plot-series',
@@ -210,10 +211,6 @@ class Bar {
210
211
 
211
212
  const translationsIndex = this.setSeriesAxis(realIndex)
212
213
 
213
- this.isReversed =
214
- w.config.yaxis[this.yaxisIndex] &&
215
- w.config.yaxis[this.yaxisIndex].reversed
216
-
217
214
  if (this.isPyramid) {
218
215
  // Recompute the per-segment trapezoid layout once per series, before
219
216
  // drawing any of its segments. Each entry yields the segment's top
@@ -322,6 +319,9 @@ class Bar {
322
319
  if (this.isHorizontal) {
323
320
  paths = this.drawBarPaths({
324
321
  ...pathsParams,
322
+ ...(this.barHelpers.rows && {
323
+ y: initY + this.barHelpers.barRow(realIndex, j) * yDivision,
324
+ }),
325
325
  barHeight,
326
326
  zeroW,
327
327
  yDivision,
@@ -426,6 +426,7 @@ class Bar {
426
426
  series,
427
427
  barHeight: Math.abs(paths.barHeight ? paths.barHeight : barHeight),
428
428
  barWidth: Math.abs(paths.barWidth ? paths.barWidth : barWidth),
429
+ barXPosition: paths.barXPosition,
429
430
  elDataLabelsWrap,
430
431
  elGoalsMarkers,
431
432
  elBarShadows,
@@ -441,15 +442,11 @@ class Bar {
441
442
  // Exit ghosts: previous datums whose keys are gone shrink to their
442
443
  // baseline edge and fade under the reflowing survivors.
443
444
  if (w.globals.previousPaths.length > 0) {
444
- const newKeys = []
445
- for (let j = 0; j < series[i].length; j++) {
446
- newKeys.push(datumKey(w, realIndex, j))
447
- }
448
445
  renderBarExitGhosts({
449
446
  w,
450
447
  elSeries,
451
448
  record: this._prevRecord(realIndex),
452
- newKeys,
449
+ newKeys: this._keys(realIndex),
453
450
  isHorizontal: this.isHorizontal,
454
451
  speed: w.config.chart.animations.dynamicAnimation.speed,
455
452
  })
@@ -461,7 +458,7 @@ class Bar {
461
458
  return ret
462
459
  }
463
460
 
464
- /** @param {{ hl?: any, realIndex?: any, pathFill?: any, lineFill?: any, j?: any, i?: any, columnGroupIndex?: any, pathFrom?: any, pathTo?: any, strokeWidth?: any, elSeries?: any, x?: any, y?: any, y1?: any, y2?: any, series?: any, barHeight?: any, barWidth?: any, barXPosition?: any, barYPosition?: any, elDataLabelsWrap?: any, elGoalsMarkers?: any, elBarShadows?: any, visibleSeries?: any, type?: any, classes?: any, fadeReveal?: boolean }} opts */
461
+ /** @param {{ hl?: any, realIndex?: any, pathFill?: any, lineFill?: any, j?: any, i?: any, columnGroupIndex?: any, pathFrom?: any, pathTo?: any, strokeWidth?: any, elSeries?: any, x?: any, y?: any, y1?: any, y2?: any, series?: any, barHeight?: any, barWidth?: any, barXPosition?: any, barYPosition?: any, elDataLabelsWrap?: any, elGoalsMarkers?: any, elBarShadows?: any, visibleSeries?: any, type?: any, classes?: any, fadeReveal?: boolean, noLabel?: boolean }} opts */
465
462
  renderSeries({
466
463
  hl,
467
464
  realIndex,
@@ -490,6 +487,7 @@ class Bar {
490
487
  type,
491
488
  classes,
492
489
  fadeReveal = false,
490
+ noLabel, // a datum's extra paths (box halves, box lane) label nothing
493
491
  }) {
494
492
  const w = this.w
495
493
  const graphics = new Graphics(this.w, this.ctx)
@@ -619,6 +617,7 @@ class Bar {
619
617
  barYPosition,
620
618
  visibleSeries,
621
619
  hl: hl?.label,
620
+ noLabel,
622
621
  })
623
622
  )
624
623
 
@@ -640,28 +639,23 @@ class Bar {
640
639
 
641
640
  // Drawn only to slide out of view (see _wasOnScreen): removed once the
642
641
  // update has landed, so nothing is left lying off-screen.
642
+ // Culled on the bar's own centre: the label x carries dataLabels.offsetX,
643
+ // which dropped the first or last columns even with labels off.
643
644
  let leaving = false
644
645
  if (!w.globals.isBarHorizontal) {
645
- if (
646
- dataLabelsObj.dataLabelsPos.dataLabelsX +
647
- Math.max(barWidth, w.globals.barPadForNumericAxis) <
648
- 0 ||
649
- dataLabelsObj.dataLabelsPos.dataLabelsX -
650
- Math.max(barWidth, w.globals.barPadForNumericAxis) >
651
- w.layout.gridWidth
652
- ) {
646
+ const cx =
647
+ barXPosition === undefined
648
+ ? dataLabelsObj.dataLabelsPos.dataLabelsX
649
+ : barXPosition + barWidth / 2
650
+ const pad = Math.max(barWidth, w.globals.barPadForNumericAxis)
651
+ if (cx + pad < 0 || cx - pad > w.layout.gridWidth) {
653
652
  if (this._wasOnScreen(realIndex, j)) leaving = true
654
653
  else skipDrawing = true
655
654
  }
656
655
  }
657
656
 
658
- if (
659
- /** @type {Record<string,any>} */ (w.config.series[i]).data[j] &&
660
- /** @type {Record<string,any>} */ (w.config.series[i]).data[j].strokeColor
661
- ) {
662
- lineFill = /** @type {Record<string,any>} */ (w.config.series[i]).data[j]
663
- .strokeColor
664
- }
657
+ const datum = /** @type {any} */ (w.config.series[realIndex]).data[j]
658
+ if (datum && datum.strokeColor) lineFill = datum.strokeColor
665
659
 
666
660
  const fill = pathFill
667
661
 
@@ -711,7 +705,7 @@ class Bar {
711
705
  pathTo,
712
706
  stroke: lineFill,
713
707
  strokeWidth,
714
- strokeLineCap: w.config.stroke.lineCap,
708
+ strokeLinecap: w.config.stroke.lineCap,
715
709
  fill: pathFill,
716
710
  pathToInterp,
717
711
  animationDelay: delay,
@@ -777,12 +771,12 @@ class Bar {
777
771
  cy: dataLabelsObj.dataLabelsPos.bcy,
778
772
  cx: dataLabelsObj.dataLabelsPos.bcx,
779
773
  j,
780
- val: w.seriesData.series[i][j],
774
+ val: w.seriesData.series[realIndex][j],
781
775
  barHeight,
782
776
  barWidth,
783
777
  // Datum identity for the next update's keyed join (see
784
778
  // LengthTransition): survivors match by key, not array position.
785
- 'data:pathKey': datumKey(w, realIndex, j),
779
+ 'data:pathKey': this._keys(realIndex)[j],
786
780
  })
787
781
 
788
782
  // Highlight filter: fade this whole and draw its part above it (below
@@ -886,7 +880,10 @@ class Bar {
886
880
  // band.
887
881
  if (w.config.plotOptions.bar.hideZeroBarsWhenGrouped) {
888
882
  const { nonZeroColumns, zeroEncounters } =
889
- this.barHelpers.getZeroValueEncounters({ i, j })
883
+ this.barHelpers.getZeroValueEncounters({
884
+ i: indexes.realIndex,
885
+ j,
886
+ })
890
887
 
891
888
  if (nonZeroColumns > 0) {
892
889
  barHeight = (this.seriesLen * barHeight) / nonZeroColumns
@@ -1054,7 +1051,7 @@ class Bar {
1054
1051
  } else {
1055
1052
  if (w.config.plotOptions.bar.hideZeroBarsWhenGrouped) {
1056
1053
  const { nonZeroColumns, zeroEncounters } =
1057
- this.barHelpers.getZeroValueEncounters({ i, j })
1054
+ this.barHelpers.getZeroValueEncounters({ i: realIndex, j })
1058
1055
 
1059
1056
  if (nonZeroColumns > 0) {
1060
1057
  barWidth = (this.seriesLen * barWidth) / nonZeroColumns
@@ -1122,6 +1119,7 @@ class Bar {
1122
1119
  /** @param {{x: any, barWidth: any, realIndex: any, j: any}} opts */
1123
1120
  getBarXForNumericXAxis({ x, barWidth, realIndex, j }) {
1124
1121
  const w = this.w
1122
+ const overlay = isHistogramOverlay(w)
1125
1123
  let sxI = realIndex
1126
1124
  if (!w.seriesData.seriesX[realIndex].length) {
1127
1125
  sxI = w.globals.maxValsInArrayIndex
@@ -1133,15 +1131,15 @@ class Bar {
1133
1131
  // ranges cannot drift apart.
1134
1132
  x =
1135
1133
  AxisMapping.dataXToPx(w, w.seriesData.seriesX[sxI][j]) -
1136
- (barWidth * this.seriesLen) / 2
1134
+ (barWidth * (overlay ? 1 : this.seriesLen)) / 2
1137
1135
  }
1138
1136
 
1139
1137
  // Overlaid histogram series all sit on the bin, rather than stepping across
1140
- // it one series-width at a time. `seriesLen` is already forced to 1 above,
1141
- // so `barWidth` is the whole bin and stepping would march each series clear
1142
- // of the last.
1138
+ // it one series-width at a time. `barWidth` is already the whole bin, so
1139
+ // centring on seriesLen bars or stepping would march each series clear of
1140
+ // the last.
1143
1141
  return {
1144
- barXPosition: x + (isHistogramOverlay(w) ? 0 : barWidth * this.visibleI),
1142
+ barXPosition: x + (overlay ? 0 : barWidth * this.visibleI),
1145
1143
  x,
1146
1144
  }
1147
1145
  }
@@ -1163,7 +1161,18 @@ class Bar {
1163
1161
  _wasOnScreen(realIndex, j) {
1164
1162
  if (!lengthTransitionEnabled(this.w)) return false
1165
1163
  const keyed = this._prevKeyedPaths(realIndex)
1166
- return !!keyed && keyed.has(datumKey(this.w, realIndex, j))
1164
+ return !!keyed && keyed.has(this._keys(realIndex)[j])
1165
+ }
1166
+
1167
+ /**
1168
+ * This render's datum keys for a series (see seriesKeys), as stamped on
1169
+ * each bar and looked up in the previous render's.
1170
+ * @param {number} realIndex
1171
+ * @returns {string[]}
1172
+ */
1173
+ _keys(realIndex) {
1174
+ const c = (/** @type {any} */ (this)._keyCache ||= {})
1175
+ return (c[realIndex] ||= seriesKeys(this.w, realIndex))
1167
1176
  }
1168
1177
 
1169
1178
  /**
@@ -1235,20 +1244,21 @@ class Bar {
1235
1244
  if (lengthTransitionEnabled(w) && w.globals.previousPaths.length > 0) {
1236
1245
  const record = this._prevRecord(realIndex)
1237
1246
  const dataLen = w.seriesData.series[realIndex]?.length ?? 0
1247
+ const keyed = record && this._prevKeyedPaths(realIndex)
1238
1248
  if (!record) {
1239
1249
  result = dataLen > 0 // a brand-new series entering
1240
- } else if (record.paths.length !== dataLen) {
1241
- result = true
1250
+ } else if (keyed) {
1251
+ // Off-screen bars are not drawn, so a zoomed series has fewer paths
1252
+ // than points and comparing counts called every value update a
1253
+ // layout change. The datum count comes from the previous frame; a
1254
+ // drawn datum whose key is gone has left.
1255
+ const now = new Set(this._keys(realIndex))
1256
+ result =
1257
+ (w.globals.prevStreamFrame?.seriesY?.[realIndex]?.length ??
1258
+ dataLen) !== dataLen ||
1259
+ [...keyed.keys()].some((k) => !now.has(k))
1242
1260
  } else {
1243
- const keyed = this._prevKeyedPaths(realIndex)
1244
- if (keyed) {
1245
- for (let j = 0; j < dataLen; j++) {
1246
- if (!keyed.has(datumKey(w, realIndex, j))) {
1247
- result = true
1248
- break
1249
- }
1250
- }
1251
- }
1261
+ result = record.paths.length !== dataLen
1252
1262
  }
1253
1263
  }
1254
1264
  this._ltCache[realIndex] = result
@@ -1317,7 +1327,7 @@ class Bar {
1317
1327
  let isNewDatum = false
1318
1328
  const keyed = this._prevKeyedPaths(realIndex)
1319
1329
  if (keyed) {
1320
- const prev = keyed.get(datumKey(w, realIndex, j))
1330
+ const prev = keyed.get(this._keys(realIndex)[j])
1321
1331
  if (prev) {
1322
1332
  oldD = prev.d
1323
1333
  } else {
@@ -1535,14 +1545,11 @@ class Bar {
1535
1545
  * @returns {boolean | null} null when there is no previous record to consult
1536
1546
  */
1537
1547
  getPreviousFlip(realIndex, j) {
1538
- const w = this.w
1539
1548
  const record = this._prevRecord(realIndex)
1540
1549
  if (!record) return null
1541
1550
 
1542
1551
  const keyed = this._prevKeyedPaths(realIndex)
1543
- const prev = keyed
1544
- ? keyed.get(datumKey(w, realIndex, j))
1545
- : record.paths[j]
1552
+ const prev = keyed ? keyed.get(this._keys(realIndex)[j]) : record.paths[j]
1546
1553
  return prev ? !!prev.flip : null
1547
1554
  }
1548
1555