apexcharts 8.2.0 → 8.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (222) hide show
  1. package/README.md +7 -7
  2. package/dist/apexcharts.common.js +2 -2
  3. package/dist/apexcharts.core.js +271 -173
  4. package/dist/apexcharts.core.min.js +2 -2
  5. package/dist/apexcharts.css +35 -0
  6. package/dist/apexcharts.esm.js +1722 -1527
  7. package/dist/apexcharts.full.js +1459 -1075
  8. package/dist/apexcharts.full.min.js +2 -2
  9. package/dist/apexcharts.js +994 -715
  10. package/dist/apexcharts.min.js +2 -2
  11. package/dist/apexcharts.ssr.common.js +2 -2
  12. package/dist/apexcharts.ssr.esm.js +994 -715
  13. package/dist/area.common.js +2 -2
  14. package/dist/area.esm.js +91 -40
  15. package/dist/bar.common.js +2 -2
  16. package/dist/bar.esm.js +433 -394
  17. package/dist/bar.js +2 -2
  18. package/dist/boxPlot.common.js +2 -2
  19. package/dist/boxPlot.esm.js +364 -322
  20. package/dist/bubble.common.js +2 -2
  21. package/dist/bubble.esm.js +91 -40
  22. package/dist/candlestick.common.js +2 -2
  23. package/dist/candlestick.esm.js +364 -322
  24. package/dist/candlestick.js +2 -2
  25. package/dist/column.common.js +2 -2
  26. package/dist/column.esm.js +433 -394
  27. package/dist/core.common.js +2 -2
  28. package/dist/core.esm.js +271 -173
  29. package/dist/donut.common.js +1 -1
  30. package/dist/donut.esm.js +1 -1
  31. package/dist/dumbbell.common.js +2 -2
  32. package/dist/dumbbell.esm.js +433 -394
  33. package/dist/features/all.common.js +2 -2
  34. package/dist/features/all.esm.js +250 -187
  35. package/dist/features/annotations.common.js +1 -1
  36. package/dist/features/annotations.esm.js +1 -1
  37. package/dist/features/annotations.js +1 -1
  38. package/dist/features/context-menu.common.js +1 -1
  39. package/dist/features/context-menu.esm.js +1 -1
  40. package/dist/features/context-menu.js +1 -1
  41. package/dist/features/drilldown.common.js +2 -2
  42. package/dist/features/drilldown.esm.js +4 -2
  43. package/dist/features/drilldown.js +2 -2
  44. package/dist/features/dumbbell.common.js +1 -1
  45. package/dist/features/dumbbell.esm.js +1 -1
  46. package/dist/features/dumbbell.js +1 -1
  47. package/dist/features/exports.common.js +1 -1
  48. package/dist/features/exports.esm.js +1 -1
  49. package/dist/features/exports.js +1 -1
  50. package/dist/features/facet.common.js +1 -1
  51. package/dist/features/facet.esm.js +1 -1
  52. package/dist/features/facet.js +1 -1
  53. package/dist/features/highlight-filter.common.js +2 -2
  54. package/dist/features/highlight-filter.esm.js +14 -9
  55. package/dist/features/highlight-filter.js +2 -2
  56. package/dist/features/history.common.js +1 -1
  57. package/dist/features/history.esm.js +1 -1
  58. package/dist/features/history.js +1 -1
  59. package/dist/features/ink.common.js +1 -1
  60. package/dist/features/ink.esm.js +1 -1
  61. package/dist/features/ink.js +1 -1
  62. package/dist/features/keyboard.common.js +2 -2
  63. package/dist/features/keyboard.esm.js +97 -145
  64. package/dist/features/keyboard.js +2 -2
  65. package/dist/features/legend.common.js +2 -2
  66. package/dist/features/legend.esm.js +63 -43
  67. package/dist/features/legend.js +2 -2
  68. package/dist/features/link.common.js +1 -1
  69. package/dist/features/link.esm.js +1 -1
  70. package/dist/features/link.js +1 -1
  71. package/dist/features/marks.common.js +1 -1
  72. package/dist/features/marks.esm.js +1 -1
  73. package/dist/features/marks.js +1 -1
  74. package/dist/features/measure.common.js +1 -1
  75. package/dist/features/measure.esm.js +1 -1
  76. package/dist/features/measure.js +1 -1
  77. package/dist/features/morph.common.js +1 -1
  78. package/dist/features/morph.esm.js +1 -1
  79. package/dist/features/morph.js +1 -1
  80. package/dist/features/perspectives.common.js +1 -1
  81. package/dist/features/perspectives.esm.js +1 -1
  82. package/dist/features/perspectives.js +1 -1
  83. package/dist/features/raincloud.common.js +1 -1
  84. package/dist/features/raincloud.esm.js +1 -1
  85. package/dist/features/raincloud.js +1 -1
  86. package/dist/features/renderer-canvas.common.js +2 -2
  87. package/dist/features/renderer-canvas.esm.js +2 -1
  88. package/dist/features/renderer-canvas.js +2 -2
  89. package/dist/features/stats.common.js +1 -1
  90. package/dist/features/stats.esm.js +1 -1
  91. package/dist/features/stats.js +1 -1
  92. package/dist/features/storyboard.common.js +1 -1
  93. package/dist/features/storyboard.esm.js +1 -1
  94. package/dist/features/storyboard.js +1 -1
  95. package/dist/features/streamgraph.common.js +2 -2
  96. package/dist/features/streamgraph.esm.js +3 -2
  97. package/dist/features/streamgraph.js +2 -2
  98. package/dist/features/toolbar.common.js +2 -2
  99. package/dist/features/toolbar.esm.js +92 -2
  100. package/dist/features/toolbar.js +2 -2
  101. package/dist/features/trellis.common.js +2 -2
  102. package/dist/features/trellis.esm.js +83 -47
  103. package/dist/features/trellis.js +2 -2
  104. package/dist/features/waterfall.common.js +1 -1
  105. package/dist/features/waterfall.esm.js +1 -1
  106. package/dist/features/waterfall.js +1 -1
  107. package/dist/features/weave.common.js +1 -1
  108. package/dist/features/weave.esm.js +1 -1
  109. package/dist/features/weave.js +1 -1
  110. package/dist/full.common.js +2 -2
  111. package/dist/full.esm.js +950 -795
  112. package/dist/heatmap.common.js +2 -2
  113. package/dist/heatmap.esm.js +3 -17
  114. package/dist/heatmap.js +2 -2
  115. package/dist/histogram.common.js +2 -2
  116. package/dist/histogram.esm.js +433 -394
  117. package/dist/icicle.common.js +2 -2
  118. package/dist/icicle.esm.js +54 -38
  119. package/dist/icicle.js +2 -2
  120. package/dist/line.common.js +2 -2
  121. package/dist/line.esm.js +91 -40
  122. package/dist/line.js +2 -2
  123. package/dist/locales/en.json +2 -1
  124. package/dist/locales/ro.json +3 -2
  125. package/dist/pictograms.common.js +1 -1
  126. package/dist/pictograms.esm.js +1 -1
  127. package/dist/pictograms.js +1 -1
  128. package/dist/pie.common.js +1 -1
  129. package/dist/pie.esm.js +1 -1
  130. package/dist/pie.js +1 -1
  131. package/dist/polarArea.common.js +1 -1
  132. package/dist/polarArea.esm.js +1 -1
  133. package/dist/radar.common.js +2 -2
  134. package/dist/radar.esm.js +5 -4
  135. package/dist/radar.js +2 -2
  136. package/dist/radialBar.common.js +1 -1
  137. package/dist/radialBar.esm.js +1 -1
  138. package/dist/radialBar.js +1 -1
  139. package/dist/raincloud.common.js +2 -2
  140. package/dist/raincloud.esm.js +72 -26
  141. package/dist/rangeArea.common.js +2 -2
  142. package/dist/rangeArea.esm.js +91 -40
  143. package/dist/rangeBar.common.js +2 -2
  144. package/dist/rangeBar.esm.js +433 -394
  145. package/dist/scatter.common.js +2 -2
  146. package/dist/scatter.esm.js +91 -40
  147. package/dist/streamgraph.common.js +2 -2
  148. package/dist/streamgraph.esm.js +93 -41
  149. package/dist/sunburst.common.js +2 -2
  150. package/dist/sunburst.esm.js +103 -93
  151. package/dist/sunburst.js +2 -2
  152. package/dist/treemap.common.js +2 -2
  153. package/dist/treemap.esm.js +105 -86
  154. package/dist/treemap.js +2 -2
  155. package/dist/unit-shapes.common.js +1 -1
  156. package/dist/unit-shapes.esm.js +1 -1
  157. package/dist/unit-shapes.js +1 -1
  158. package/dist/unit.common.js +2 -2
  159. package/dist/unit.esm.js +280 -202
  160. package/dist/unit.js +2 -2
  161. package/dist/violin.common.js +2 -2
  162. package/dist/violin.esm.js +72 -26
  163. package/dist/violin.js +2 -2
  164. package/dist/waterfall.common.js +2 -2
  165. package/dist/waterfall.esm.js +432 -393
  166. package/package.json +1 -1
  167. package/src/apexcharts.js +13 -6
  168. package/src/assets/apexcharts.css +35 -0
  169. package/src/charts/Bar.js +62 -55
  170. package/src/charts/BarStacked.js +80 -88
  171. package/src/charts/BoxCandleStick.js +28 -31
  172. package/src/charts/Icicle.js +37 -37
  173. package/src/charts/Line.js +118 -42
  174. package/src/charts/Radar.js +5 -7
  175. package/src/charts/RangeBar.js +47 -43
  176. package/src/charts/Sunburst.js +101 -98
  177. package/src/charts/Treemap.js +108 -66
  178. package/src/charts/Unit.js +368 -250
  179. package/src/charts/Violin.js +48 -30
  180. package/src/charts/common/Breadcrumb.js +2 -2
  181. package/src/charts/common/Hierarchy.js +32 -11
  182. package/src/charts/common/Jitter.js +32 -7
  183. package/src/charts/common/bar/DataLabels.js +76 -81
  184. package/src/charts/common/bar/Helpers.js +43 -7
  185. package/src/charts/common/line/Helpers.js +12 -15
  186. package/src/charts/common/partition/NodeTooltip.js +8 -1
  187. package/src/charts/common/partition/Partition.js +33 -1
  188. package/src/charts/common/treemap/Helpers.js +3 -11
  189. package/src/locales/en.json +2 -1
  190. package/src/locales/ro.json +3 -2
  191. package/src/modules/Core.js +4 -0
  192. package/src/modules/CoreUtils.js +18 -42
  193. package/src/modules/Data.js +23 -24
  194. package/src/modules/DataLabels.js +6 -6
  195. package/src/modules/Graphics.js +62 -49
  196. package/src/modules/Markers.js +3 -1
  197. package/src/modules/Range.js +44 -29
  198. package/src/modules/RendererController.js +17 -3
  199. package/src/modules/Scales.js +32 -9
  200. package/src/modules/Series.js +39 -18
  201. package/src/modules/Theme.js +1 -1
  202. package/src/modules/ZoomPanSelection.js +119 -2
  203. package/src/modules/accessibility/KeyboardNavigation.js +114 -186
  204. package/src/modules/animations/LengthTransition.js +22 -2
  205. package/src/modules/drilldown/Breadcrumb.js +5 -2
  206. package/src/modules/helpers/Destroy.js +1 -1
  207. package/src/modules/highlightFilter/HighlightFilter.js +8 -9
  208. package/src/modules/highlightFilter/TreemapPart.js +2 -2
  209. package/src/modules/legend/HeatmapGradientLegend.js +76 -45
  210. package/src/modules/legend/Helpers.js +2 -0
  211. package/src/modules/legend/Legend.js +11 -12
  212. package/src/modules/settings/Options.js +7 -0
  213. package/src/modules/streamgraph/StreamLabels.js +1 -0
  214. package/src/modules/tooltip/Tooltip.js +20 -4
  215. package/src/modules/tooltip/Utils.js +8 -0
  216. package/src/modules/trellis/Trellis.js +6 -0
  217. package/src/modules/trellis/TrellisChrome.js +18 -7
  218. package/src/modules/trellis/TrellisSync.js +2 -0
  219. package/src/renderers/canvas/CanvasGraphics.js +1 -0
  220. package/src/ssr/DOMShim.js +10 -0
  221. package/src/types/internal.d.ts +9 -3
  222. package/types/apexcharts.d.ts +31 -12
@@ -208,7 +208,7 @@ export default class TreemapChart {
208
208
  if (w.config.chart.dropShadow.enabled) {
209
209
  const shadow = w.config.chart.dropShadow
210
210
  const filters = new Filters(this.w)
211
- filters.dropShadow(ret, shadow, i)
211
+ filters.dropShadow(elSeries, shadow, i)
212
212
  }
213
213
 
214
214
  const elDataLabelWrap = graphics.group({
@@ -353,6 +353,10 @@ export default class TreemapChart {
353
353
  // See Sunburst: the branch identity a cross-type morph pairs on.
354
354
  elRect.node.setAttribute('data:key', morphKey(leaf._key))
355
355
 
356
+ // The tile's tween (mount grow or data change), which its label
357
+ // rides, and the centre the label rides from (null: it fades in).
358
+ /** @type {any} */
359
+ let tileTween = null
356
360
  let fromRect = {
357
361
  x: x1 + (x2 - x1) / 2,
358
362
  y: y1 + (y2 - y1) / 2,
@@ -390,7 +394,7 @@ export default class TreemapChart {
390
394
  // delay, so they popped in one after another.
391
395
  w.globals.animationEnded = true
392
396
  } else {
393
- this.animateTreemap(
397
+ tileTween = this.animateTreemap(
394
398
  elRect,
395
399
  fromRect,
396
400
  toRect,
@@ -401,10 +405,6 @@ export default class TreemapChart {
401
405
  )
402
406
  }
403
407
  }
404
- // A data change's tile tween, which the tile's label rides, and the
405
- // centre the label rides from (null for a tile the update adds).
406
- /** @type {any} */
407
- let tileTween = null
408
408
  /** @type {{x: number, y: number} | null} */
409
409
  let labelFrom = null
410
410
  // What the tile's label showed before ('' for none, null when not
@@ -516,7 +516,8 @@ export default class TreemapChart {
516
516
  dataLabels.node.setAttribute('data:key', morphKey(leaf._key))
517
517
  elSeries.add(dataLabels)
518
518
  // The label rides its tile from the old centre, on the tile's own
519
- // tween; a tile the update adds fades its label in as it grows.
519
+ // tween; a tile that mounts or the update adds fades its label in
520
+ // as it grows.
520
521
  // It used to sit at its final spot from the first frame, over
521
522
  // whatever tile was still there.
522
523
  if (tileTween) {
@@ -879,7 +880,7 @@ export default class TreemapChart {
879
880
  const elGroup = graphics.group({
880
881
  class: 'apexcharts-treemap-parent',
881
882
  'data:depth': depth,
882
- 'data:name': Utils.escapeString(node.name),
883
+ 'data:name': node.name,
883
884
  })
884
885
 
885
886
  // Cross-type morph: with branch keys on both sides, a container unrolls
@@ -1032,7 +1033,7 @@ export default class TreemapChart {
1032
1033
  if (typeof header.formatter === 'function') {
1033
1034
  text = String(
1034
1035
  header.formatter(node.name, {
1035
- value: node.value,
1036
+ value: node._area,
1036
1037
  depth,
1037
1038
  seriesIndex: i,
1038
1039
  node,
@@ -1040,7 +1041,7 @@ export default class TreemapChart {
1040
1041
  }),
1041
1042
  )
1042
1043
  } else if (header.showValue) {
1043
- text = `${text} ${this._formatValue(node.value)}`
1044
+ text = `${text} ${this._formatValue(node._area, node._si)}`
1044
1045
  }
1045
1046
  headerText = text
1046
1047
 
@@ -1053,6 +1054,8 @@ export default class TreemapChart {
1053
1054
  text,
1054
1055
  maxWidth,
1055
1056
  fontSize,
1057
+ fontFamily: chrome.headerFontFamily,
1058
+ fontWeight: chrome.headerFontWeight,
1056
1059
  })
1057
1060
 
1058
1061
  if (clipped) {
@@ -1158,7 +1161,7 @@ export default class TreemapChart {
1158
1161
  const lead =
1159
1162
  visibleText && String(visibleText).trim()
1160
1163
  ? String(visibleText).replace(/\s+/g, ' ').trim()
1161
- : `${node.name}, ${this._formatValue(node._area)}`
1164
+ : `${node.name}, ${this._formatValue(node._area, node._si)}`
1162
1165
  return `${lead}, ${n} ${n === 1 ? 'item' : 'items'}, ${pct}% of total`
1163
1166
  }
1164
1167
 
@@ -1178,17 +1181,21 @@ export default class TreemapChart {
1178
1181
  * @param {string} [visibleText] the header's rendered text, unclipped
1179
1182
  */
1180
1183
  _makeParentAccessible(el, node, chrome, elRect, visibleText) {
1184
+ const a11y = this.w.config.chart.accessibility
1181
1185
  if (!el || !el.setAttribute) return
1182
- if (!this._zoomEnabled()) return
1186
+ if (!a11y.enabled || !a11y.keyboard.enabled || !this._zoomEnabled()) return
1183
1187
 
1188
+ // The focused branch's strip zooms back out.
1189
+ const open = this.w.globals.treemapFocusKey === node._key
1190
+ el.tmKey = node._key
1184
1191
  el.setAttribute('role', 'button')
1185
1192
  el.setAttribute('tabindex', '0')
1186
1193
  el.setAttribute(
1187
1194
  'aria-label',
1188
- `${this._parentLabel(node, visibleText)}. Zoom in`,
1195
+ `${this._parentLabel(node, visibleText)}. Zoom ${open ? 'out' : 'in'}`,
1189
1196
  )
1190
1197
  // The strip is the affordance, and it labels the group it opens.
1191
- el.setAttribute('aria-expanded', 'false')
1198
+ el.setAttribute('aria-expanded', open)
1192
1199
 
1193
1200
  if (!Environment.isBrowser() || !el.addEventListener) return
1194
1201
 
@@ -1269,20 +1276,21 @@ export default class TreemapChart {
1269
1276
  const z = w.config.plotOptions.treemap.zoom
1270
1277
  if (!z || !z.enabled || !this.showParents) return false
1271
1278
 
1279
+ // An `onDrillDown` resolver drills on every click, so it counts too. The
1280
+ // warned flag lives on the drilldown instance, which outlives a render.
1272
1281
  const dd = w.config.drilldown
1282
+ const d = this.ctx.drilldown
1273
1283
  if (
1274
- this.ctx.drilldown &&
1284
+ d &&
1275
1285
  dd &&
1276
1286
  dd.enabled &&
1277
- Array.isArray(dd.series) &&
1278
- dd.series.length
1287
+ (dd.series?.length || dd.onDrillDown)
1279
1288
  ) {
1280
- if (!this._warnedZoomConflict) {
1281
- this._warnedZoomConflict = true
1289
+ if (!d.zoomWarned) {
1290
+ d.zoomWarned = true
1282
1291
  console.warn(
1283
- 'ApexCharts treemap: `plotOptions.treemap.zoom` and the drilldown ' +
1284
- 'feature both navigate the hierarchy, so zoom is ignored here. ' +
1285
- 'Drop `drilldown.series` to zoom a nested treemap instead.',
1292
+ 'ApexCharts treemap: zoom is ignored while drilldown is active ' +
1293
+ '(plotOptions.treemap.zoom vs drilldown series or onDrillDown).',
1286
1294
  )
1287
1295
  }
1288
1296
  return false
@@ -1293,8 +1301,8 @@ export default class TreemapChart {
1293
1301
  /**
1294
1302
  * The focused branch for this render, looked up by the key stashed on the
1295
1303
  * last click. Keys are rebuilt identically from the same data, so the focus
1296
- * survives a re-render; a key that no longer resolves (the data changed under
1297
- * it) simply falls back to the whole tree.
1304
+ * survives a re-render; a key that no longer resolves, or a branch left with
1305
+ * nothing to draw (the data changed under it), falls back to the whole tree.
1298
1306
  * @param {any[]} drawn
1299
1307
  * @returns {any}
1300
1308
  */
@@ -1314,7 +1322,16 @@ export default class TreemapChart {
1314
1322
  }
1315
1323
  drawn.forEach(walk)
1316
1324
  // Only a branch can be focused; a leaf has nothing to zoom into.
1317
- return found && found.children && found.children.length ? found : null
1325
+ if (
1326
+ found &&
1327
+ found.children &&
1328
+ found.children.length &&
1329
+ this._subtreeArea(found) > 0
1330
+ ) {
1331
+ return found
1332
+ }
1333
+ this.w.globals.treemapFocusKey = null
1334
+ return null
1318
1335
  }
1319
1336
 
1320
1337
  /**
@@ -1328,30 +1345,7 @@ export default class TreemapChart {
1328
1345
  const w = this.w
1329
1346
  if (!node || !node.children || !node.children.length) return
1330
1347
  const next = w.globals.treemapFocusKey === node._key ? null : node._key
1331
- const done = this._refocus(next)
1332
- if (!restoreFocus || !done || typeof done.then !== 'function') return
1333
- done.then(() => {
1334
- if (!Environment.isBrowser()) return
1335
- // The breadcrumb is where you are and how you get back, so it is the
1336
- // right landing spot after the view changes under you.
1337
- const crumb = /** @type {any} */ (
1338
- w.dom.baseEl.querySelector(
1339
- '.apexcharts-breadcrumb .apexcharts-breadcrumb-item',
1340
- )
1341
- )
1342
- if (crumb && crumb.focus) {
1343
- crumb.focus()
1344
- return
1345
- }
1346
- // Zoomed all the way back out: no breadcrumb, so return to the strip of
1347
- // the group that was just closed.
1348
- const header = /** @type {any} */ (
1349
- w.dom.baseEl.querySelector(
1350
- '.apexcharts-treemap-parent-header[tabindex]',
1351
- )
1352
- )
1353
- if (header && header.focus) header.focus()
1354
- })
1348
+ this._refocus(next, restoreFocus)
1355
1349
  }
1356
1350
 
1357
1351
  /**
@@ -1363,16 +1357,17 @@ export default class TreemapChart {
1363
1357
  * left, which replayed the mount animation (every tile growing from
1364
1358
  * nothing) or snapped, while the containers, headers and labels jumped.
1365
1359
  * @param {string | null} next
1366
- * @returns {any} the update's promise
1360
+ * @param {boolean} [restoreFocus] see _zoomTo
1367
1361
  */
1368
- _refocus(next) {
1362
+ _refocus(next, restoreFocus) {
1369
1363
  const w = this.w
1370
1364
  const gl = w.globals
1365
+ const from = gl.treemapFocusKey
1371
1366
  const anim = w.config.chart.animations
1372
1367
  const animate = !!(anim.enabled && anim.dynamicAnimation.enabled)
1373
1368
  gl.treemapZoom =
1374
1369
  animate && Environment.isBrowser()
1375
- ? { from: gl.treemapFocusKey ?? null, to: next }
1370
+ ? { from: from ?? null, to: next }
1376
1371
  : null
1377
1372
  gl.treemapFocusKey = next
1378
1373
  this._hideParentTooltip()
@@ -1380,7 +1375,27 @@ export default class TreemapChart {
1380
1375
  gl.resized = true
1381
1376
  gl.dataChanged = true
1382
1377
  if (gl.treemapZoom) this.ctx.series.getPreviousPaths()
1383
- return this.ctx.update()
1378
+ const done = this.ctx.update()
1379
+ if (restoreFocus) {
1380
+ done.then(() => {
1381
+ const b = w.dom.baseEl
1382
+ const heads = /** @type {any[]} */ (
1383
+ Array.from(
1384
+ b.querySelectorAll('.apexcharts-treemap-parent-header[tabindex]'),
1385
+ )
1386
+ )
1387
+ // The breadcrumb is where you are and how you get back, so it is the
1388
+ // right landing spot after the view changes under you. Zoomed all the
1389
+ // way back out there is none: return to the strip of the group that
1390
+ // was just closed.
1391
+ ;(
1392
+ b.querySelector('.apexcharts-breadcrumb-item') ||
1393
+ heads.find((h) => h.tmKey === from) ||
1394
+ heads[0] ||
1395
+ b
1396
+ ).focus()
1397
+ })
1398
+ }
1384
1399
  }
1385
1400
 
1386
1401
  /**
@@ -1756,8 +1771,9 @@ export default class TreemapChart {
1756
1771
  crumbs: [{ label: 'All', data: null }].concat(
1757
1772
  chain.map((/** @type {any} */ n) => ({ label: n.name, data: n })),
1758
1773
  ),
1759
- onNavigate: (_i, crumb) => {
1760
- this._refocus(crumb.data ? crumb.data._key : null)
1774
+ // A keyboard click (detail 0) keeps focus in the chart.
1775
+ onNavigate: (_i, crumb, e) => {
1776
+ this._refocus(crumb.data ? crumb.data._key : null, !e.detail)
1761
1777
  },
1762
1778
  })
1763
1779
  if (!nav) return
@@ -1817,7 +1833,8 @@ export default class TreemapChart {
1817
1833
  if (!t) return
1818
1834
 
1819
1835
  const total = this._drawnTotal()
1820
- const parentVal = node._parent ? node._parent._area : total
1836
+ // A zoom lays out only the focus, so the parent may have no _area.
1837
+ const parentVal = node._parent ? this._subtreeArea(node._parent) : total
1821
1838
  const pctTotal = total > 0 ? ((node._area / total) * 100).toFixed(1) : '0.0'
1822
1839
  const pctParent =
1823
1840
  parentVal > 0 ? ((node._area / parentVal) * 100).toFixed(1) : pctTotal
@@ -1847,11 +1864,12 @@ export default class TreemapChart {
1847
1864
  `<div class="apexcharts-tooltip-series-group apexcharts-active" style="display:flex;${groupBg}">` +
1848
1865
  `<div class="apexcharts-tooltip-text">` +
1849
1866
  `<div class="apexcharts-tooltip-y-group">` +
1850
- `<span class="apexcharts-tooltip-text-y-label">${Utils.escapeString(
1851
- node.name,
1852
- )}: </span>` +
1867
+ `<span class="apexcharts-tooltip-text-y-label">${String(node.name)
1868
+ .replace(/&/g, '&amp;')
1869
+ .replace(/</g, '&lt;')}: </span>` +
1853
1870
  `<span class="apexcharts-tooltip-text-y-value">${this._formatValue(
1854
1871
  node._area,
1872
+ node._si,
1855
1873
  )}</span>` +
1856
1874
  `</div>` +
1857
1875
  `<div class="apexcharts-tooltip-y-group">` +
@@ -1966,16 +1984,20 @@ export default class TreemapChart {
1966
1984
 
1967
1985
  /**
1968
1986
  * Format an aggregate the way the chart formats its own y values, so a
1969
- * parent's total reads like the tiles it contains.
1987
+ * parent's total reads like the tiles it contains. A branch is no data
1988
+ * point, so dataPointIndex is -1.
1970
1989
  * @param {number} v
1990
+ * @param {number} [si] the branch's series index
1971
1991
  * @returns {string}
1972
1992
  */
1973
- _formatValue(v) {
1993
+ _formatValue(v, si) {
1974
1994
  const w = this.w
1975
1995
  const fmt = w.config.tooltip?.y?.formatter || w.config.yaxis?.[0]?.labels?.formatter
1976
1996
  if (typeof fmt === 'function') {
1977
1997
  try {
1978
- return String(fmt(v, { seriesIndex: 0, dataPointIndex: 0, w }))
1998
+ return String(
1999
+ fmt(v, { seriesIndex: si || 0, dataPointIndex: -1, w }),
2000
+ )
1979
2001
  } catch (_) {
1980
2002
  // A formatter written for leaf rows may expect fields a parent
1981
2003
  // aggregate has no equivalent of; fall through to the plain number.
@@ -2073,7 +2095,7 @@ export default class TreemapChart {
2073
2095
  */
2074
2096
  rotateToFitLabel(elText, fontSize, text, x1, y1, x2, y2) {
2075
2097
  const graphics = new Graphics(this.w)
2076
- const textRect = graphics.getTextRects(text, String(fontSize))
2098
+ const textRect = this._labelRect(graphics, text, fontSize)
2077
2099
 
2078
2100
  // if the label fits better sideways then rotate it
2079
2101
  if (
@@ -2091,6 +2113,25 @@ export default class TreemapChart {
2091
2113
  }
2092
2114
  }
2093
2115
 
2116
+ /**
2117
+ * A tile label's box, measured at the family and weight it is drawn at
2118
+ * (bold is wider than the default regular).
2119
+ * @param {Graphics} graphics
2120
+ * @param {string} text
2121
+ * @param {string | number} fontSize
2122
+ */
2123
+ _labelRect(graphics, text, fontSize) {
2124
+ const st = this.w.config.dataLabels.style
2125
+ return graphics.getTextRects(
2126
+ text,
2127
+ String(fontSize),
2128
+ st.fontFamily,
2129
+ '',
2130
+ true,
2131
+ st.fontWeight,
2132
+ )
2133
+ }
2134
+
2094
2135
  // This is an alternative label formatting method that uses a
2095
2136
  // consistent font size, and trims the edge of long labels
2096
2137
  /**
@@ -2103,7 +2144,7 @@ export default class TreemapChart {
2103
2144
  */
2104
2145
  truncateLabels(text, fontSize, x1, y1, x2, y2) {
2105
2146
  const graphics = new Graphics(this.w)
2106
- const textRect = graphics.getTextRects(text, String(fontSize))
2147
+ const textRect = this._labelRect(graphics, text, fontSize)
2107
2148
 
2108
2149
  // Determine max width based on ideal orientation of text
2109
2150
  const labelMaxWidth =
@@ -2112,9 +2153,10 @@ export default class TreemapChart {
2112
2153
  ? y2 - y1
2113
2154
  : x2 - x1
2114
2155
  const truncatedText = graphics.getTextBasedOnMaxWidth({
2115
- text: text,
2156
+ ...this.w.config.dataLabels.style,
2157
+ text,
2116
2158
  maxWidth: labelMaxWidth,
2117
- fontSize: fontSize,
2159
+ fontSize,
2118
2160
  })
2119
2161
 
2120
2162
  // Return empty label when text has been trimmed for very small rects