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.
- package/README.md +7 -7
- package/dist/apexcharts.common.js +2 -2
- package/dist/apexcharts.core.js +19793 -19713
- package/dist/apexcharts.core.min.js +2 -2
- package/dist/apexcharts.css +38 -8
- package/dist/apexcharts.esm.js +1882 -1625
- package/dist/apexcharts.full.js +22044 -21634
- package/dist/apexcharts.full.min.js +2 -2
- package/dist/apexcharts.js +21414 -21124
- package/dist/apexcharts.min.js +2 -2
- package/dist/apexcharts.ssr.common.js +2 -2
- package/dist/apexcharts.ssr.esm.js +21413 -21123
- package/dist/area.common.js +2 -2
- package/dist/area.esm.js +91 -40
- package/dist/bar.common.js +2 -2
- package/dist/bar.esm.js +478 -406
- package/dist/bar.js +2 -2
- package/dist/boxPlot.common.js +2 -2
- package/dist/boxPlot.esm.js +409 -334
- package/dist/bubble.common.js +2 -2
- package/dist/bubble.esm.js +91 -40
- package/dist/candlestick.common.js +2 -2
- package/dist/candlestick.esm.js +409 -334
- package/dist/candlestick.js +2 -2
- package/dist/column.common.js +2 -2
- package/dist/column.esm.js +478 -406
- package/dist/core.common.js +2 -2
- package/dist/core.esm.js +19793 -19713
- package/dist/donut.common.js +2 -2
- package/dist/donut.esm.js +3 -9
- package/dist/dumbbell.common.js +2 -2
- package/dist/dumbbell.esm.js +478 -406
- package/dist/features/all.common.js +2 -2
- package/dist/features/all.esm.js +442 -324
- package/dist/features/annotations.common.js +2 -2
- package/dist/features/annotations.esm.js +65 -48
- package/dist/features/annotations.js +2 -2
- package/dist/features/context-menu.common.js +1 -1
- package/dist/features/context-menu.esm.js +1 -1
- package/dist/features/context-menu.js +1 -1
- package/dist/features/drilldown.common.js +2 -2
- package/dist/features/drilldown.esm.js +4 -2
- package/dist/features/drilldown.js +2 -2
- package/dist/features/dumbbell.common.js +1 -1
- package/dist/features/dumbbell.esm.js +1 -1
- package/dist/features/dumbbell.js +1 -1
- package/dist/features/exports.common.js +2 -2
- package/dist/features/exports.esm.js +10 -4
- package/dist/features/exports.js +2 -2
- package/dist/features/facet.common.js +1 -1
- package/dist/features/facet.esm.js +1 -1
- package/dist/features/facet.js +1 -1
- package/dist/features/highlight-filter.common.js +2 -2
- package/dist/features/highlight-filter.esm.js +14 -9
- package/dist/features/highlight-filter.js +2 -2
- package/dist/features/history.common.js +1 -1
- package/dist/features/history.esm.js +1 -1
- package/dist/features/history.js +1 -1
- package/dist/features/ink.common.js +1 -1
- package/dist/features/ink.esm.js +1 -1
- package/dist/features/ink.js +1 -1
- package/dist/features/keyboard.common.js +2 -2
- package/dist/features/keyboard.esm.js +97 -145
- package/dist/features/keyboard.js +2 -2
- package/dist/features/legend.common.js +2 -2
- package/dist/features/legend.esm.js +64 -44
- package/dist/features/legend.js +2 -2
- package/dist/features/link.common.js +1 -1
- package/dist/features/link.esm.js +1 -1
- package/dist/features/link.js +1 -1
- package/dist/features/marks.common.js +1 -1
- package/dist/features/marks.esm.js +1 -1
- package/dist/features/marks.js +1 -1
- package/dist/features/measure.common.js +1 -1
- package/dist/features/measure.esm.js +1 -1
- package/dist/features/measure.js +1 -1
- package/dist/features/morph.common.js +2 -2
- package/dist/features/morph.esm.js +9 -5
- package/dist/features/morph.js +2 -2
- package/dist/features/perspectives.common.js +2 -2
- package/dist/features/perspectives.esm.js +4 -1
- package/dist/features/perspectives.js +2 -2
- package/dist/features/raincloud.common.js +2 -2
- package/dist/features/raincloud.esm.js +26 -27
- package/dist/features/raincloud.js +2 -2
- package/dist/features/renderer-canvas.common.js +2 -2
- package/dist/features/renderer-canvas.esm.js +2 -1
- package/dist/features/renderer-canvas.js +2 -2
- package/dist/features/stats.common.js +2 -2
- package/dist/features/stats.esm.js +52 -59
- package/dist/features/stats.js +2 -2
- package/dist/features/storyboard.common.js +2 -2
- package/dist/features/storyboard.esm.js +4 -1
- package/dist/features/storyboard.js +2 -2
- package/dist/features/streamgraph.common.js +2 -2
- package/dist/features/streamgraph.esm.js +48 -14
- package/dist/features/streamgraph.js +2 -2
- package/dist/features/toolbar.common.js +2 -2
- package/dist/features/toolbar.esm.js +148 -18
- package/dist/features/toolbar.js +2 -2
- package/dist/features/trellis.common.js +2 -2
- package/dist/features/trellis.esm.js +150 -63
- package/dist/features/trellis.js +2 -2
- package/dist/features/waterfall.common.js +1 -1
- package/dist/features/waterfall.esm.js +1 -1
- package/dist/features/waterfall.js +1 -1
- package/dist/features/weave.common.js +2 -2
- package/dist/features/weave.esm.js +13 -12
- package/dist/features/weave.js +2 -2
- package/dist/full.common.js +2 -2
- package/dist/full.esm.js +1068 -842
- package/dist/heatmap.common.js +2 -2
- package/dist/heatmap.esm.js +3 -17
- package/dist/heatmap.js +2 -2
- package/dist/histogram.common.js +2 -2
- package/dist/histogram.esm.js +529 -464
- package/dist/icicle.common.js +2 -2
- package/dist/icicle.esm.js +80 -46
- package/dist/icicle.js +2 -2
- package/dist/line.common.js +2 -2
- package/dist/line.esm.js +91 -40
- package/dist/line.js +2 -2
- package/dist/locales/en.json +2 -1
- package/dist/locales/ro.json +3 -2
- package/dist/pictograms.common.js +1 -1
- package/dist/pictograms.esm.js +1 -1
- package/dist/pictograms.js +1 -1
- package/dist/pie.common.js +2 -2
- package/dist/pie.esm.js +3 -9
- package/dist/pie.js +2 -2
- package/dist/polarArea.common.js +2 -2
- package/dist/polarArea.esm.js +3 -9
- package/dist/radar.common.js +2 -2
- package/dist/radar.esm.js +5 -4
- package/dist/radar.js +2 -2
- package/dist/radialBar.common.js +2 -2
- package/dist/radialBar.esm.js +5 -12
- package/dist/radialBar.js +2 -2
- package/dist/raincloud.common.js +2 -2
- package/dist/raincloud.esm.js +97 -52
- package/dist/rangeArea.common.js +2 -2
- package/dist/rangeArea.esm.js +91 -40
- package/dist/rangeBar.common.js +2 -2
- package/dist/rangeBar.esm.js +478 -406
- package/dist/scatter.common.js +2 -2
- package/dist/scatter.esm.js +91 -40
- package/dist/streamgraph.common.js +2 -2
- package/dist/streamgraph.esm.js +138 -53
- package/dist/sunburst.common.js +2 -2
- package/dist/sunburst.esm.js +116 -94
- package/dist/sunburst.js +2 -2
- package/dist/treemap.common.js +2 -2
- package/dist/treemap.esm.js +138 -104
- package/dist/treemap.js +2 -2
- package/dist/unit-shapes.common.js +1 -1
- package/dist/unit-shapes.esm.js +1 -1
- package/dist/unit-shapes.js +1 -1
- package/dist/unit.common.js +2 -2
- package/dist/unit.esm.js +280 -202
- package/dist/unit.js +2 -2
- package/dist/violin.common.js +2 -2
- package/dist/violin.esm.js +72 -26
- package/dist/violin.js +2 -2
- package/dist/waterfall.common.js +2 -2
- package/dist/waterfall.esm.js +477 -405
- package/package.json +1 -1
- package/src/apexcharts.js +40 -59
- package/src/assets/apexcharts.css +38 -8
- package/src/charts/Bar.js +62 -55
- package/src/charts/BarStacked.js +80 -88
- package/src/charts/BoxCandleStick.js +28 -31
- package/src/charts/Icicle.js +68 -47
- package/src/charts/Line.js +118 -42
- package/src/charts/Pie.js +2 -8
- package/src/charts/Radar.js +5 -7
- package/src/charts/Radial.js +2 -6
- package/src/charts/RangeBar.js +47 -43
- package/src/charts/Sunburst.js +101 -98
- package/src/charts/Treemap.js +150 -88
- package/src/charts/Unit.js +368 -250
- package/src/charts/Violin.js +48 -30
- package/src/charts/common/Breadcrumb.js +2 -2
- package/src/charts/common/Hierarchy.js +32 -11
- package/src/charts/common/Jitter.js +32 -7
- package/src/charts/common/Stats.js +30 -23
- package/src/charts/common/bar/DataLabels.js +76 -81
- package/src/charts/common/bar/Helpers.js +43 -7
- package/src/charts/common/line/Helpers.js +12 -15
- package/src/charts/common/partition/NodeTooltip.js +29 -7
- package/src/charts/common/partition/Partition.js +33 -1
- package/src/charts/common/treemap/Helpers.js +3 -11
- package/src/charts/common/treemap/Nested.js +2 -3
- package/src/features/raincloud.js +16 -10
- package/src/features/stats.js +67 -62
- package/src/locales/en.json +2 -1
- package/src/locales/ro.json +3 -2
- package/src/modules/Animations.js +102 -95
- package/src/modules/AxisMapping.js +47 -12
- package/src/modules/Core.js +4 -0
- package/src/modules/CoreUtils.js +18 -42
- package/src/modules/Data.js +23 -24
- package/src/modules/DataLabels.js +6 -6
- package/src/modules/Exports.js +12 -5
- package/src/modules/Fill.js +17 -8
- package/src/modules/Filters.js +50 -50
- package/src/modules/Graphics.js +69 -51
- package/src/modules/Markers.js +3 -1
- package/src/modules/MorphTypeChange.js +13 -7
- package/src/modules/Range.js +44 -29
- package/src/modules/RendererController.js +17 -3
- package/src/modules/Scales.js +32 -9
- package/src/modules/Series.js +41 -19
- package/src/modules/Theme.js +1 -1
- package/src/modules/Toolbar.js +3 -2
- package/src/modules/UnitMarkRegistry.js +0 -5
- package/src/modules/ZoomPanSelection.js +123 -2
- package/src/modules/accessibility/KeyboardNavigation.js +114 -186
- package/src/modules/animations/Easing.js +2 -1
- package/src/modules/animations/LengthTransition.js +22 -2
- package/src/modules/annotations/Helpers.js +68 -52
- package/src/modules/axes/Grid.js +21 -7
- package/src/modules/axes/YAxis.js +8 -9
- package/src/modules/dimensions/Dimensions.js +9 -3
- package/src/modules/dimensions/Grid.js +2 -2
- package/src/modules/dimensions/XAxis.js +2 -5
- package/src/modules/drilldown/Breadcrumb.js +5 -2
- package/src/modules/helpers/Destroy.js +1 -1
- package/src/modules/helpers/UpdateHelpers.js +33 -15
- package/src/modules/highlightFilter/HighlightFilter.js +8 -9
- package/src/modules/highlightFilter/TreemapPart.js +2 -2
- package/src/modules/legend/HeatmapGradientLegend.js +76 -45
- package/src/modules/legend/Helpers.js +8 -1
- package/src/modules/legend/Legend.js +11 -12
- package/src/modules/license/LicenseEnforcer.js +5 -0
- package/src/modules/settings/Defaults.js +28 -56
- package/src/modules/settings/Globals.js +5 -0
- package/src/modules/settings/Options.js +7 -7
- package/src/modules/settings/TypeAliases.js +33 -16
- package/src/modules/streamgraph/StreamLabels.js +1 -0
- package/src/modules/tooltip/Labels.js +73 -76
- package/src/modules/tooltip/Marker.js +25 -21
- package/src/modules/tooltip/Position.js +88 -51
- package/src/modules/tooltip/Tooltip.js +242 -255
- package/src/modules/tooltip/Utils.js +71 -130
- package/src/modules/tooltip/constants.js +5 -5
- package/src/modules/trellis/Trellis.js +6 -0
- package/src/modules/trellis/TrellisChrome.js +18 -7
- package/src/modules/trellis/TrellisSync.js +2 -0
- package/src/modules/trellis/TrellisTooltip.js +2 -11
- package/src/modules/weave/WeaveHost.js +18 -12
- package/src/renderers/canvas/CanvasGraphics.js +1 -0
- package/src/ssr/DOMShim.js +10 -0
- package/src/svg/SVGFilter.js +26 -17
- package/src/types/internal.d.ts +9 -3
- package/src/utils/Utils.js +0 -14
- package/types/apexcharts.d.ts +33 -12
|
@@ -22,13 +22,18 @@ export default class Labels {
|
|
|
22
22
|
this.w = tooltipContext.w
|
|
23
23
|
this.ttCtx = tooltipContext
|
|
24
24
|
this.tooltipUtil = new Utils(tooltipContext)
|
|
25
|
+
// Stateless helpers a datetime hover used to build afresh on every move.
|
|
26
|
+
this.xFormat = new Formatters(this.w)
|
|
27
|
+
this.dateTime = new DateTime(this.w)
|
|
25
28
|
}
|
|
26
29
|
|
|
27
30
|
/** @param {{ shared?: boolean, ttItems?: any, i?: number, j?: any, y1?: any, y2?: any, e?: any }} opts */
|
|
28
31
|
drawSeriesTexts({ shared = true, ttItems, i = 0, j = null, y1, y2, e }) {
|
|
29
32
|
const w = this.w
|
|
33
|
+
const custom = w.config.tooltip.custom !== undefined
|
|
34
|
+
const tooltipEl = this.ttCtx.getElTooltip()
|
|
30
35
|
|
|
31
|
-
if (
|
|
36
|
+
if (custom) {
|
|
32
37
|
this.handleCustomTooltip({ i, j, y1, y2, w })
|
|
33
38
|
} else {
|
|
34
39
|
this.toggleActiveInactiveSeries(shared, i)
|
|
@@ -46,11 +51,12 @@ export default class Labels {
|
|
|
46
51
|
ttItems,
|
|
47
52
|
shared,
|
|
48
53
|
e,
|
|
54
|
+
// Markup from tooltip.custom has replaced the built-in rows: formatting
|
|
55
|
+
// them anyway ran every formatter into nodes no one sees.
|
|
56
|
+
rows: !custom || tooltipEl?.contains(ttItems?.[0]),
|
|
49
57
|
})
|
|
50
58
|
|
|
51
59
|
// Re-calculate tooltip dimensions now that we have drawn the text
|
|
52
|
-
const tooltipEl = this.ttCtx.getElTooltip()
|
|
53
|
-
|
|
54
60
|
if (tooltipEl) {
|
|
55
61
|
// One rect read, not two: each call forces a synchronous layout of the
|
|
56
62
|
// whole tooltip, which on a shared tooltip with a row per series is the
|
|
@@ -61,12 +67,28 @@ export default class Labels {
|
|
|
61
67
|
}
|
|
62
68
|
}
|
|
63
69
|
|
|
64
|
-
/** @param {{i: any, j: any, values: any, ttItems: any, shared: any, e: any}} opts */
|
|
65
|
-
printLabels({ i, j, values, ttItems, shared, e }) {
|
|
70
|
+
/** @param {{i: any, j: any, values: any, ttItems: any, shared: any, e: any, rows?: boolean}} opts */
|
|
71
|
+
printLabels({ i, j, values, ttItems, shared, e, rows = true }) {
|
|
66
72
|
const w = this.w
|
|
73
|
+
const ttCtx = this.ttCtx
|
|
67
74
|
const { xVal, zVal, xAxisTTVal } = values
|
|
68
75
|
const seriesLen = w.seriesData.series.length
|
|
69
76
|
|
|
77
|
+
// The title and the x-axis label read the same for every row, so they are
|
|
78
|
+
// written once a hover, not once per series.
|
|
79
|
+
if (ttItems?.[0]) {
|
|
80
|
+
if (rows && ttCtx.showTooltipTitle) {
|
|
81
|
+
ttCtx.tooltipTitle ??= w.dom.baseEl.querySelector(
|
|
82
|
+
'.apexcharts-tooltip-title',
|
|
83
|
+
)
|
|
84
|
+
if (ttCtx.tooltipTitle) ttCtx.tooltipTitle.innerHTML = xVal
|
|
85
|
+
}
|
|
86
|
+
if (ttCtx.isXAxisTooltipEnabled && ttCtx.xaxisTooltipText) {
|
|
87
|
+
ttCtx.xaxisTooltipText.innerHTML = xAxisTTVal !== '' ? xAxisTTVal : xVal
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (!rows) return
|
|
91
|
+
|
|
70
92
|
const basePColor =
|
|
71
93
|
j !== null && w.config.plotOptions.bar.distributed
|
|
72
94
|
? w.globals.colors[j]
|
|
@@ -103,8 +125,6 @@ export default class Labels {
|
|
|
103
125
|
values: {
|
|
104
126
|
val: row.val,
|
|
105
127
|
goalVals: row.goalVals,
|
|
106
|
-
xVal,
|
|
107
|
-
xAxisTTVal,
|
|
108
128
|
zVal,
|
|
109
129
|
},
|
|
110
130
|
seriesName: row.seriesName,
|
|
@@ -122,38 +142,28 @@ export default class Labels {
|
|
|
122
142
|
*/
|
|
123
143
|
computeSeriesRow({ i, j, tIndex, shared, e, basePColor }) {
|
|
124
144
|
const w = this.w
|
|
125
|
-
|
|
145
|
+
// A shared row speaks for series tIndex. Its formatters and name are taken
|
|
146
|
+
// once, not the hovered series' first and then thrown away, which ran the
|
|
147
|
+
// title formatter twice per row.
|
|
148
|
+
const own = w.globals.axisCharts && shared ? tIndex : i
|
|
149
|
+
const f = this.getFormatters(own)
|
|
126
150
|
let pColor = basePColor
|
|
127
151
|
let val
|
|
128
152
|
let goalVals = /** @type {any[]} */ ([])
|
|
129
153
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
)
|
|
141
|
-
: this.getSeriesName({
|
|
142
|
-
fn: f.yLbTitleFormatter,
|
|
143
|
-
index: i,
|
|
144
|
-
seriesIndex: i,
|
|
145
|
-
j,
|
|
146
|
-
})
|
|
154
|
+
const seriesName = this.getSeriesName({
|
|
155
|
+
fn: f.yLbTitleFormatter,
|
|
156
|
+
index: own,
|
|
157
|
+
seriesIndex: i,
|
|
158
|
+
j,
|
|
159
|
+
leaf:
|
|
160
|
+
w.config.chart.type === 'treemap'
|
|
161
|
+
? String(/** @type {any} */ (w.config.series[i]).data[j].x)
|
|
162
|
+
: null,
|
|
163
|
+
})
|
|
147
164
|
|
|
148
165
|
if (w.globals.axisCharts) {
|
|
149
166
|
if (shared) {
|
|
150
|
-
f = this.getFormatters(tIndex)
|
|
151
|
-
seriesName = this.getSeriesName({
|
|
152
|
-
fn: f.yLbTitleFormatter,
|
|
153
|
-
index: tIndex,
|
|
154
|
-
seriesIndex: i,
|
|
155
|
-
j,
|
|
156
|
-
})
|
|
157
167
|
pColor = w.globals.colors[tIndex]
|
|
158
168
|
val = this.formatYValue(f, tIndex, j)
|
|
159
169
|
goalVals = this.formatGoalVals(f, tIndex, j)
|
|
@@ -358,15 +368,22 @@ export default class Labels {
|
|
|
358
368
|
}
|
|
359
369
|
}
|
|
360
370
|
|
|
361
|
-
/**
|
|
362
|
-
|
|
371
|
+
/**
|
|
372
|
+
* A treemap row is named by its leaf, not its series.
|
|
373
|
+
* @param {{fn: any, index: any, seriesIndex: any, j: any, leaf?: string | null}} opts
|
|
374
|
+
*/
|
|
375
|
+
getSeriesName({ fn, index, seriesIndex, j, leaf }) {
|
|
363
376
|
const w = this.w
|
|
364
|
-
|
|
377
|
+
const s = fn(leaf ?? String(w.seriesData.seriesNames[index]), {
|
|
365
378
|
series: w.seriesData.series,
|
|
366
379
|
seriesIndex,
|
|
367
380
|
dataPointIndex: j,
|
|
368
381
|
w,
|
|
369
382
|
})
|
|
383
|
+
// A leaf's name is data and the title is written as HTML. The default
|
|
384
|
+
// title is the name plus ': ', so that shape gets the name's '<' escaped
|
|
385
|
+
// (enough in element text); markup a title formatter adds stays markup.
|
|
386
|
+
return leaf && s === leaf + ': ' ? leaf.replace(/</g, '<') + ': ' : s
|
|
370
387
|
}
|
|
371
388
|
|
|
372
389
|
/**
|
|
@@ -397,7 +414,7 @@ export default class Labels {
|
|
|
397
414
|
const w = this.w
|
|
398
415
|
const ttCtx = this.ttCtx
|
|
399
416
|
|
|
400
|
-
const { val, goalVals,
|
|
417
|
+
const { val, goalVals, zVal } = values
|
|
401
418
|
|
|
402
419
|
// A hover processed mid-render (e.g. during a cross-type updateOptions, where
|
|
403
420
|
// the new type's series count can momentarily outpace the rebuilt tooltip
|
|
@@ -417,25 +434,6 @@ export default class Labels {
|
|
|
417
434
|
ttItemsChildren[0].style.display = 'none'
|
|
418
435
|
}
|
|
419
436
|
|
|
420
|
-
if (ttCtx.showTooltipTitle) {
|
|
421
|
-
if (ttCtx.tooltipTitle === null) {
|
|
422
|
-
// get it once if null, and store it in class property
|
|
423
|
-
ttCtx.tooltipTitle = w.dom.baseEl.querySelector(
|
|
424
|
-
'.apexcharts-tooltip-title',
|
|
425
|
-
)
|
|
426
|
-
}
|
|
427
|
-
if (ttCtx.tooltipTitle) {
|
|
428
|
-
ttCtx.tooltipTitle.innerHTML = xVal
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
// if xaxis tooltip is constructed, we need to replace the innerHTML
|
|
433
|
-
if (ttCtx.isXAxisTooltipEnabled) {
|
|
434
|
-
if (ttCtx.xaxisTooltipText) {
|
|
435
|
-
ttCtx.xaxisTooltipText.innerHTML = xAxisTTVal !== '' ? xAxisTTVal : xVal
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
|
|
439
437
|
const ttYLabel = refs.yLabel
|
|
440
438
|
if (ttYLabel) {
|
|
441
439
|
ttYLabel.innerHTML = seriesName ? seriesName : ''
|
|
@@ -580,12 +578,10 @@ export default class Labels {
|
|
|
580
578
|
// Rows are indexed by series index, except where only one was allocated
|
|
581
579
|
// (the non-shared cartesian case, see Tooltip.createTTElements) and
|
|
582
580
|
// every hovered series writes into row 0.
|
|
583
|
-
const
|
|
584
|
-
|
|
585
|
-
//
|
|
586
|
-
const firstTooltipSeriesGroup =
|
|
587
|
-
`.apexcharts-tooltip-series-group-${rowIndex}`,
|
|
588
|
-
)
|
|
581
|
+
const rows = this.ttCtx.ttItems
|
|
582
|
+
// enable the first tooltip text group, the row already held, not
|
|
583
|
+
// queried for on every move
|
|
584
|
+
const firstTooltipSeriesGroup = rows?.[rows.length === 1 ? 0 : i]
|
|
589
585
|
|
|
590
586
|
if (firstTooltipSeriesGroup) {
|
|
591
587
|
const ftsGroup = /** @type {HTMLElement} */ (firstTooltipSeriesGroup)
|
|
@@ -598,12 +594,7 @@ export default class Labels {
|
|
|
598
594
|
/** @param {{i: any, j: any}} opts */
|
|
599
595
|
getValuesToPrint({ i, j }) {
|
|
600
596
|
const w = this.w
|
|
601
|
-
/**
|
|
602
|
-
* @param {any[]} ser
|
|
603
|
-
*/
|
|
604
|
-
const filteredSeriesX = w.seriesData.seriesX.map(
|
|
605
|
-
(/** @type {any} */ ser) => (ser.length > 0 ? ser : []),
|
|
606
|
-
)
|
|
597
|
+
const seriesX = /** @type {any[][]} */ (w.seriesData.seriesX)
|
|
607
598
|
|
|
608
599
|
let xVal = ''
|
|
609
600
|
let xAxisTTVal = ''
|
|
@@ -623,16 +614,23 @@ export default class Labels {
|
|
|
623
614
|
val = w.seriesData.series[i]
|
|
624
615
|
} else {
|
|
625
616
|
if (w.axisFlags.isXNumeric && w.config.chart.type !== 'treemap') {
|
|
626
|
-
xVal =
|
|
627
|
-
if (
|
|
617
|
+
xVal = seriesX[i][j]
|
|
618
|
+
if (seriesX[i].length === 0) {
|
|
628
619
|
// a series (possibly the first one) might be collapsed, so get the next active index
|
|
629
620
|
const firstActiveSeriesIndex =
|
|
630
|
-
this.tooltipUtil.getFirstActiveXArray(
|
|
631
|
-
xVal =
|
|
621
|
+
this.tooltipUtil.getFirstActiveXArray(seriesX)
|
|
622
|
+
xVal = seriesX[firstActiveSeriesIndex][j]
|
|
632
623
|
}
|
|
633
624
|
} else {
|
|
634
|
-
|
|
635
|
-
|
|
625
|
+
// Asked once a render (drawTooltip starts a new one): asking per move
|
|
626
|
+
// built a Data and scanned the series, and on [{x, y}, null] data
|
|
627
|
+
// logged its mixed-format warning on every move.
|
|
628
|
+
const gen = this.ttCtx.allTooltipSeriesGroups
|
|
629
|
+
if (this._xyGen !== gen) {
|
|
630
|
+
this._xyGen = gen
|
|
631
|
+
this._isXY = new Data(this.w).isFormatXY()
|
|
632
|
+
}
|
|
633
|
+
if (this._isXY) {
|
|
636
634
|
// a null entry is a gap in the data, with no x of its own
|
|
637
635
|
const datum = /** @type {any} */ (w.config.series[i]).data[j]
|
|
638
636
|
xVal = datum == null ? '' : datum.x
|
|
@@ -648,14 +646,13 @@ export default class Labels {
|
|
|
648
646
|
const bufferXVal = xVal
|
|
649
647
|
|
|
650
648
|
if (w.axisFlags.isXNumeric && w.config.xaxis.type === 'datetime') {
|
|
651
|
-
|
|
652
|
-
xVal = xFormat.xLabelFormat(
|
|
649
|
+
xVal = this.xFormat.xLabelFormat(
|
|
653
650
|
/** @type {Function} */ (w.formatters.ttKeyFormatter),
|
|
654
651
|
bufferXVal,
|
|
655
652
|
bufferXVal,
|
|
656
653
|
{
|
|
657
654
|
i: undefined,
|
|
658
|
-
dateFormatter:
|
|
655
|
+
dateFormatter: this.dateTime.formatDate,
|
|
659
656
|
w: this.w,
|
|
660
657
|
},
|
|
661
658
|
)
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
import Graphics from '../Graphics'
|
|
3
3
|
import Position from './Position'
|
|
4
4
|
import Markers from '../../modules/Markers'
|
|
5
|
-
import Utils from '../../utils/Utils'
|
|
6
5
|
import TooltipUtils from './Utils'
|
|
7
6
|
import { BrowserAPIs } from '../../ssr/BrowserAPIs.js'
|
|
8
7
|
import { SVGNS } from '../../svg/math'
|
|
@@ -76,6 +75,8 @@ export default class Marker {
|
|
|
76
75
|
// ones it actually touched. See enlargePoints().
|
|
77
76
|
/** @type {Set<any>} */
|
|
78
77
|
this.enlargedPoints = new Set()
|
|
78
|
+
// A hover may have moved a hover dot since the last resetPointsSize.
|
|
79
|
+
this.dirty = false
|
|
79
80
|
}
|
|
80
81
|
|
|
81
82
|
drawDynamicPoints() {
|
|
@@ -204,6 +205,7 @@ export default class Marker {
|
|
|
204
205
|
enlargePaintedPoint(marker, x, y) {
|
|
205
206
|
const w = this.w
|
|
206
207
|
this.resetPointsSize()
|
|
208
|
+
this.dirty = true
|
|
207
209
|
|
|
208
210
|
// A bubble's radius is its value, so enlargeCurrentPoint leaves an SVG
|
|
209
211
|
// bubble as it is and clears only `markers.hover.size`; a painted one is
|
|
@@ -442,27 +444,29 @@ export default class Marker {
|
|
|
442
444
|
this.enlargedPoints.delete(point)
|
|
443
445
|
}
|
|
444
446
|
|
|
447
|
+
/**
|
|
448
|
+
* Put every marker a hover changed back as drawn: the ones newPointSize
|
|
449
|
+
* grew (tracked) and each visible series' hover dot, the only nodes the
|
|
450
|
+
* dot writers touch. This used to re-path every marker in the chart, on
|
|
451
|
+
* every hide.
|
|
452
|
+
*/
|
|
445
453
|
resetPointsSize() {
|
|
446
|
-
const
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
this.
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
const path = this.ttCtx.tooltipUtil.getPathFromPoint(points[p], size)
|
|
462
|
-
points[p].setAttribute('d', path)
|
|
463
|
-
} else {
|
|
464
|
-
points[p].setAttribute('d', 'M0,0')
|
|
454
|
+
const collapsed = this.w.globals.collapsedSeriesIndices
|
|
455
|
+
this.dirty = false
|
|
456
|
+
this.resetEnlargedPoints()
|
|
457
|
+
this.ttCtx.tooltipUtil.markerWraps().forEach(([i, ...dots]) => {
|
|
458
|
+
if (collapsed.indexOf(i) < 0) {
|
|
459
|
+
dots.forEach((p) => {
|
|
460
|
+
if (!p) return
|
|
461
|
+
const size = parseFloat(p.getAttribute('default-marker-size'))
|
|
462
|
+
p.setAttribute(
|
|
463
|
+
'd',
|
|
464
|
+
size > 0
|
|
465
|
+
? this.ttCtx.tooltipUtil.getPathFromPoint(p, size)
|
|
466
|
+
: 'M0,0',
|
|
467
|
+
)
|
|
468
|
+
})
|
|
465
469
|
}
|
|
466
|
-
}
|
|
470
|
+
})
|
|
467
471
|
}
|
|
468
472
|
}
|
|
@@ -27,6 +27,24 @@ import {
|
|
|
27
27
|
*/
|
|
28
28
|
const CLIP_CACHE_TTL = 1000
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* The bar-like series groups `group` (an attribute test) names, as one
|
|
32
|
+
* selector, down to the path at `j` when given: a violin's body, never the
|
|
33
|
+
* jitter that shares its `j`.
|
|
34
|
+
* @param {string} group
|
|
35
|
+
* @param {number} [j]
|
|
36
|
+
*/
|
|
37
|
+
const barSel = (group, j) =>
|
|
38
|
+
['bar', 'candlestick', 'boxPlot', 'violin', 'rangebar']
|
|
39
|
+
.map(
|
|
40
|
+
(t) =>
|
|
41
|
+
`.apexcharts-${t}-series .apexcharts-series[${group}]` +
|
|
42
|
+
(j == null
|
|
43
|
+
? ''
|
|
44
|
+
: ` path${t === 'violin' ? '.apexcharts-violin-area' : ''}[j='${j}']`),
|
|
45
|
+
)
|
|
46
|
+
.join()
|
|
47
|
+
|
|
30
48
|
/**
|
|
31
49
|
* ApexCharts Tooltip.Position Class to move the tooltip based on x and y position.
|
|
32
50
|
*
|
|
@@ -53,6 +71,11 @@ export default class Position {
|
|
|
53
71
|
* @type {{ clippers?: Array<{ node: Element, x: boolean, y: boolean }> | null, at?: number }}
|
|
54
72
|
*/
|
|
55
73
|
this.clipCache = { clippers: null, at: 0 }
|
|
74
|
+
/**
|
|
75
|
+
* Hover lookups by selector, for one drawTooltip (see `_marks`).
|
|
76
|
+
* @type {any}
|
|
77
|
+
*/
|
|
78
|
+
this._memo = null
|
|
56
79
|
}
|
|
57
80
|
|
|
58
81
|
/**
|
|
@@ -505,11 +528,9 @@ export default class Position {
|
|
|
505
528
|
// grid. Falls back to `translateYAxisX` when the labels group can't
|
|
506
529
|
// be measured (e.g. yaxis.show=false but tooltip still drawn).
|
|
507
530
|
let cx
|
|
508
|
-
const labelsGroup =
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
)
|
|
512
|
-
)
|
|
531
|
+
const labelsGroup = this._marks(
|
|
532
|
+
`.apexcharts-yaxis[rel='${index}'] .apexcharts-yaxis-texts-g`,
|
|
533
|
+
)[0]
|
|
513
534
|
const elWrapRect = w.dom.elWrap.getBoundingClientRect()
|
|
514
535
|
if (labelsGroup) {
|
|
515
536
|
const lr = labelsGroup.getBoundingClientRect()
|
|
@@ -733,12 +754,14 @@ export default class Position {
|
|
|
733
754
|
// WCAG 2.4.11 Focus Not Obscured: when keyboard nav drives the tooltip,
|
|
734
755
|
// make sure the tooltip box doesn't sit on top of the focused data
|
|
735
756
|
// point. If the tooltip's vertical extent overlaps the point, push it
|
|
736
|
-
// above the point by enough margin to clear the focus stroke.
|
|
757
|
+
// above the point by enough margin to clear the focus stroke. The focused
|
|
758
|
+
// node is read off KeyboardNavigation: a query for its class walked the
|
|
759
|
+
// whole chart on every move, with nothing focused just as with something.
|
|
737
760
|
const a11y = w.config?.chart?.accessibility
|
|
738
761
|
if (
|
|
739
762
|
a11y?.enabled &&
|
|
740
763
|
a11y?.keyboard?.navigation?.enabled &&
|
|
741
|
-
|
|
764
|
+
this.ttCtx.ctx?._keyboardNavigation?._focusedEl?.isConnected
|
|
742
765
|
) {
|
|
743
766
|
// Same coord space as `y`: elWrap.
|
|
744
767
|
const refPointY = pointY
|
|
@@ -818,14 +841,19 @@ export default class Position {
|
|
|
818
841
|
}
|
|
819
842
|
if (firstPaint) {
|
|
820
843
|
// Force layout so the position above is committed with transitions
|
|
821
|
-
// disabled; then
|
|
822
|
-
// the caller in the same tick) clear the override so subsequent
|
|
823
|
-
// moves between data points animate smoothly.
|
|
844
|
+
// disabled; then on the next frame (after the active class is added
|
|
845
|
+
// by the caller in the same tick) clear the override so subsequent
|
|
846
|
+
// moves between data points animate smoothly. Where there is no
|
|
847
|
+
// frame clock (server rendering, a DOM shim without one) it clears
|
|
848
|
+
// at once.
|
|
824
849
|
void tooltipEl.offsetWidth
|
|
825
850
|
tooltipEl.dataset.positioned = 'true'
|
|
826
|
-
|
|
851
|
+
const clear = () => {
|
|
827
852
|
tooltipEl.style.transitionProperty = ''
|
|
828
|
-
}
|
|
853
|
+
}
|
|
854
|
+
if (typeof requestAnimationFrame == 'function')
|
|
855
|
+
requestAnimationFrame(clear)
|
|
856
|
+
else clear()
|
|
829
857
|
}
|
|
830
858
|
}
|
|
831
859
|
|
|
@@ -840,23 +868,22 @@ export default class Position {
|
|
|
840
868
|
// batched markers are one path per series, so there is no per-point node
|
|
841
869
|
// to find by `rel` and enlarge: fall through to the dynamic point
|
|
842
870
|
if (w.globals.markers.size[i] > 0 && !w.globals.markers.batched) {
|
|
843
|
-
|
|
844
|
-
|
|
871
|
+
// The one marker at `j`, found by its rel: reading rel off every marker
|
|
872
|
+
// of the series was linear in its points on every move.
|
|
873
|
+
const point = w.dom.baseEl.querySelector(
|
|
874
|
+
` .apexcharts-series[data\\:realIndex='${i}'] .apexcharts-marker[rel='${j}']`,
|
|
845
875
|
)
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
ttCtx.marker.enlargeCurrentPoint(j, allPoints[p])
|
|
858
|
-
break
|
|
859
|
-
}
|
|
876
|
+
if (point) {
|
|
877
|
+
// Put back only what we previously grew. resetPointsSize() re-paths
|
|
878
|
+
// EVERY marker in the chart, which on this (non-shared) path ran per
|
|
879
|
+
// hover and made it cost more than the shared tooltip it is usually
|
|
880
|
+
// reached for to avoid. Everything that enlarges a marker goes
|
|
881
|
+
// through Marker.newPointSize, so the tracked set is complete; the
|
|
882
|
+
// zero-size `M0,0` branch resetPointsSize also handles only applies
|
|
883
|
+
// to dynamic points, which exist solely when largestSize is 0 or
|
|
884
|
+
// markers are batched, neither of which reaches this branch.
|
|
885
|
+
ttCtx.marker.resetEnlargedPoints()
|
|
886
|
+
ttCtx.marker.enlargeCurrentPoint(j, point)
|
|
860
887
|
}
|
|
861
888
|
} else {
|
|
862
889
|
ttCtx.marker.resetPointsSize()
|
|
@@ -1100,20 +1127,10 @@ export default class Position {
|
|
|
1100
1127
|
const painted = !!(/** @type {any} */ (w.globals).barCanvasCoords)
|
|
1101
1128
|
// A violin's mark is its body (`.apexcharts-violin-area`), never the
|
|
1102
1129
|
// jitter path that shares its `j`.
|
|
1103
|
-
let jBar = painted
|
|
1104
|
-
? null
|
|
1105
|
-
: w.dom.baseEl.querySelector(
|
|
1106
|
-
`.apexcharts-bar-series .apexcharts-series[rel='${i}'] path[j='${j}'], .apexcharts-candlestick-series .apexcharts-series[rel='${i}'] path[j='${j}'], .apexcharts-boxPlot-series .apexcharts-series[rel='${i}'] path[j='${j}'], .apexcharts-violin-series .apexcharts-series[rel='${i}'] path.apexcharts-violin-area[j='${j}'], .apexcharts-rangebar-series .apexcharts-series[rel='${i}'] path[j='${j}']`,
|
|
1107
|
-
)
|
|
1130
|
+
let jBar = painted ? null : this._marks(barSel(`rel='${i}'`, j))[0]
|
|
1108
1131
|
if (!jBar && !painted && typeof capturedSeries === 'number') {
|
|
1109
1132
|
// Try with captured series index
|
|
1110
|
-
jBar =
|
|
1111
|
-
`.apexcharts-bar-series .apexcharts-series[data\\:realIndex='${capturedSeries}'] path[j='${j}'],
|
|
1112
|
-
.apexcharts-candlestick-series .apexcharts-series[data\\:realIndex='${capturedSeries}'] path[j='${j}'],
|
|
1113
|
-
.apexcharts-boxPlot-series .apexcharts-series[data\\:realIndex='${capturedSeries}'] path[j='${j}'],
|
|
1114
|
-
.apexcharts-violin-series .apexcharts-series[data\\:realIndex='${capturedSeries}'] path.apexcharts-violin-area[j='${j}'],
|
|
1115
|
-
.apexcharts-rangebar-series .apexcharts-series[data\\:realIndex='${capturedSeries}'] path[j='${j}']`,
|
|
1116
|
-
)
|
|
1133
|
+
jBar = this._marks(barSel(`data\\:realIndex='${capturedSeries}'`, j))[0]
|
|
1117
1134
|
}
|
|
1118
1135
|
const bc = painted ? this._paintedBarFor(i, j, capturedSeries) : null
|
|
1119
1136
|
|
|
@@ -1242,6 +1259,30 @@ export default class Position {
|
|
|
1242
1259
|
}
|
|
1243
1260
|
}
|
|
1244
1261
|
|
|
1262
|
+
/**
|
|
1263
|
+
* The nodes `sel` finds, none included, kept until the tooltip is drawn
|
|
1264
|
+
* again (every render and update does that) or one of them leaves the DOM.
|
|
1265
|
+
* A move along one column re-ran the same whole-chart attribute scans on
|
|
1266
|
+
* every mousemove. Rects are still read per move: the marks can be
|
|
1267
|
+
* mid-animation.
|
|
1268
|
+
* @param {string} sel
|
|
1269
|
+
* @returns {Element[]}
|
|
1270
|
+
*/
|
|
1271
|
+
_marks(sel) {
|
|
1272
|
+
const gen = this.ttCtx.allTooltipSeriesGroups
|
|
1273
|
+
let m = this._memo
|
|
1274
|
+
if (!m || m.gen !== gen || m.size > 99) {
|
|
1275
|
+
m = this._memo = new Map()
|
|
1276
|
+
m.gen = gen
|
|
1277
|
+
}
|
|
1278
|
+
/** @type {Element[]} */
|
|
1279
|
+
let hit = m.get(sel)
|
|
1280
|
+
if (!hit || hit.some((n) => !n.isConnected)) {
|
|
1281
|
+
m.set(sel, (hit = Array.from(this.w.dom.baseEl.querySelectorAll(sel))))
|
|
1282
|
+
}
|
|
1283
|
+
return hit
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1245
1286
|
/**
|
|
1246
1287
|
* The coords cached for the bar-like mark at index `j` painted to canvas
|
|
1247
1288
|
* (Bar.renderSeries), found the way `moveStickyTooltipOverBars` finds the
|
|
@@ -1259,11 +1300,7 @@ export default class Position {
|
|
|
1259
1300
|
const w = this.w
|
|
1260
1301
|
const bcc = /** @type {any} */ (w.globals).barCanvasCoords
|
|
1261
1302
|
if (!bcc) return null
|
|
1262
|
-
const groups =
|
|
1263
|
-
['bar', 'candlestick', 'boxPlot', 'violin', 'rangebar']
|
|
1264
|
-
.map((t) => `.apexcharts-${t}-series .apexcharts-series[rel='${rel}']`)
|
|
1265
|
-
.join(', '),
|
|
1266
|
-
)
|
|
1303
|
+
const groups = this._marks(barSel(`rel='${rel}'`))
|
|
1267
1304
|
for (let g = 0; g < groups.length; g++) {
|
|
1268
1305
|
const realIndex = groups[g].getAttribute('data:realIndex')
|
|
1269
1306
|
if (realIndex !== null && bcc[realIndex]?.[j]) return bcc[realIndex][j]
|
|
@@ -1352,7 +1389,7 @@ export default class Position {
|
|
|
1352
1389
|
if (c?.type === 'violin' && !hidden.includes(Number(key))) take(c.cx)
|
|
1353
1390
|
}
|
|
1354
1391
|
} else {
|
|
1355
|
-
const bodies =
|
|
1392
|
+
const bodies = this._marks(
|
|
1356
1393
|
`.apexcharts-violin-series .apexcharts-series:not(.apexcharts-series-collapsed) path.apexcharts-violin-area[j='${j}']`,
|
|
1357
1394
|
)
|
|
1358
1395
|
for (let k = 0; k < bodies.length; k++) {
|
|
@@ -1374,7 +1411,7 @@ export default class Position {
|
|
|
1374
1411
|
*/
|
|
1375
1412
|
_barsExtentInGrid(j) {
|
|
1376
1413
|
const w = this.w
|
|
1377
|
-
const marks =
|
|
1414
|
+
const marks = this._marks(
|
|
1378
1415
|
`.apexcharts-bar-series path[j='${j}'],` +
|
|
1379
1416
|
`.apexcharts-rangebar-series path[j='${j}'],` +
|
|
1380
1417
|
`.apexcharts-candlestick-series path[j='${j}'],` +
|
|
@@ -1425,7 +1462,7 @@ export default class Position {
|
|
|
1425
1462
|
*/
|
|
1426
1463
|
_datapointCenterXFromBars(j) {
|
|
1427
1464
|
const w = this.w
|
|
1428
|
-
const bars =
|
|
1465
|
+
const bars = this._marks(
|
|
1429
1466
|
`.apexcharts-bar-series path[j='${j}'],` +
|
|
1430
1467
|
`.apexcharts-rangebar-series path[j='${j}']`,
|
|
1431
1468
|
)
|
|
@@ -1435,8 +1472,8 @@ export default class Position {
|
|
|
1435
1472
|
|
|
1436
1473
|
let unionLeft = Infinity
|
|
1437
1474
|
let unionRight = -Infinity
|
|
1475
|
+
const plot = TooltipUtils.plotRect(w)
|
|
1438
1476
|
if (painted) {
|
|
1439
|
-
const plot = TooltipUtils.plotRect(w)
|
|
1440
1477
|
unionLeft = plot.left + painted.left * plot.zoom
|
|
1441
1478
|
unionRight = plot.left + painted.right * plot.zoom
|
|
1442
1479
|
}
|
|
@@ -1452,7 +1489,7 @@ export default class Position {
|
|
|
1452
1489
|
// Convert to data-area-local x from the plot origin, the space `cx` and the
|
|
1453
1490
|
// crosshair are already in. Measuring from the `.apexcharts-grid` element
|
|
1454
1491
|
// rect instead only works while the grid draws nothing outside its own box.
|
|
1455
|
-
return AxisMapping.screenXToPlotPx(w, (unionLeft + unionRight) / 2)
|
|
1492
|
+
return AxisMapping.screenXToPlotPx(w, (unionLeft + unionRight) / 2, plot)
|
|
1456
1493
|
}
|
|
1457
1494
|
|
|
1458
1495
|
/**
|
|
@@ -1476,7 +1513,7 @@ export default class Position {
|
|
|
1476
1513
|
// config-time, but the selector is harmless), and violin, read as its
|
|
1477
1514
|
// whole glyph: body, box lane and jitter or rain, so the box clears a
|
|
1478
1515
|
// raincloud's lanes as well as its cloud.
|
|
1479
|
-
const bars =
|
|
1516
|
+
const bars = this._marks(
|
|
1480
1517
|
`.apexcharts-bar-series path[j='${j}'],` +
|
|
1481
1518
|
`.apexcharts-rangebar-series path[j='${j}'],` +
|
|
1482
1519
|
`.apexcharts-boxPlot-series path[j='${j}'],` +
|