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.
- package/README.md +7 -7
- package/dist/apexcharts.common.js +2 -2
- package/dist/apexcharts.core.js +271 -173
- package/dist/apexcharts.core.min.js +2 -2
- package/dist/apexcharts.css +35 -0
- package/dist/apexcharts.esm.js +1722 -1527
- package/dist/apexcharts.full.js +1459 -1075
- package/dist/apexcharts.full.min.js +2 -2
- package/dist/apexcharts.js +994 -715
- package/dist/apexcharts.min.js +2 -2
- package/dist/apexcharts.ssr.common.js +2 -2
- package/dist/apexcharts.ssr.esm.js +994 -715
- 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 +433 -394
- package/dist/bar.js +2 -2
- package/dist/boxPlot.common.js +2 -2
- package/dist/boxPlot.esm.js +364 -322
- 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 +364 -322
- package/dist/candlestick.js +2 -2
- package/dist/column.common.js +2 -2
- package/dist/column.esm.js +433 -394
- package/dist/core.common.js +2 -2
- package/dist/core.esm.js +271 -173
- package/dist/donut.common.js +1 -1
- package/dist/donut.esm.js +1 -1
- package/dist/dumbbell.common.js +2 -2
- package/dist/dumbbell.esm.js +433 -394
- package/dist/features/all.common.js +2 -2
- package/dist/features/all.esm.js +250 -187
- package/dist/features/annotations.common.js +1 -1
- package/dist/features/annotations.esm.js +1 -1
- package/dist/features/annotations.js +1 -1
- 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 +1 -1
- package/dist/features/exports.esm.js +1 -1
- package/dist/features/exports.js +1 -1
- 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 +63 -43
- 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 +1 -1
- package/dist/features/morph.esm.js +1 -1
- package/dist/features/morph.js +1 -1
- package/dist/features/perspectives.common.js +1 -1
- package/dist/features/perspectives.esm.js +1 -1
- package/dist/features/perspectives.js +1 -1
- package/dist/features/raincloud.common.js +1 -1
- package/dist/features/raincloud.esm.js +1 -1
- package/dist/features/raincloud.js +1 -1
- 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 +1 -1
- package/dist/features/stats.esm.js +1 -1
- package/dist/features/stats.js +1 -1
- package/dist/features/storyboard.common.js +1 -1
- package/dist/features/storyboard.esm.js +1 -1
- package/dist/features/storyboard.js +1 -1
- package/dist/features/streamgraph.common.js +2 -2
- package/dist/features/streamgraph.esm.js +3 -2
- package/dist/features/streamgraph.js +2 -2
- package/dist/features/toolbar.common.js +2 -2
- package/dist/features/toolbar.esm.js +92 -2
- package/dist/features/toolbar.js +2 -2
- package/dist/features/trellis.common.js +2 -2
- package/dist/features/trellis.esm.js +83 -47
- 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 +1 -1
- package/dist/features/weave.esm.js +1 -1
- package/dist/features/weave.js +1 -1
- package/dist/full.common.js +2 -2
- package/dist/full.esm.js +950 -795
- 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 +433 -394
- package/dist/icicle.common.js +2 -2
- package/dist/icicle.esm.js +54 -38
- 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 +1 -1
- package/dist/pie.esm.js +1 -1
- package/dist/pie.js +1 -1
- package/dist/polarArea.common.js +1 -1
- package/dist/polarArea.esm.js +1 -1
- 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 +1 -1
- package/dist/radialBar.esm.js +1 -1
- package/dist/radialBar.js +1 -1
- package/dist/raincloud.common.js +2 -2
- package/dist/raincloud.esm.js +72 -26
- 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 +433 -394
- 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 +93 -41
- package/dist/sunburst.common.js +2 -2
- package/dist/sunburst.esm.js +103 -93
- package/dist/sunburst.js +2 -2
- package/dist/treemap.common.js +2 -2
- package/dist/treemap.esm.js +105 -86
- 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 +432 -393
- package/package.json +1 -1
- package/src/apexcharts.js +13 -6
- package/src/assets/apexcharts.css +35 -0
- 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 +37 -37
- package/src/charts/Line.js +118 -42
- package/src/charts/Radar.js +5 -7
- package/src/charts/RangeBar.js +47 -43
- package/src/charts/Sunburst.js +101 -98
- package/src/charts/Treemap.js +108 -66
- 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/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 +8 -1
- package/src/charts/common/partition/Partition.js +33 -1
- package/src/charts/common/treemap/Helpers.js +3 -11
- package/src/locales/en.json +2 -1
- package/src/locales/ro.json +3 -2
- 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/Graphics.js +62 -49
- package/src/modules/Markers.js +3 -1
- 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 +39 -18
- package/src/modules/Theme.js +1 -1
- package/src/modules/ZoomPanSelection.js +119 -2
- package/src/modules/accessibility/KeyboardNavigation.js +114 -186
- package/src/modules/animations/LengthTransition.js +22 -2
- package/src/modules/drilldown/Breadcrumb.js +5 -2
- package/src/modules/helpers/Destroy.js +1 -1
- 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 +2 -0
- package/src/modules/legend/Legend.js +11 -12
- package/src/modules/settings/Options.js +7 -0
- package/src/modules/streamgraph/StreamLabels.js +1 -0
- package/src/modules/tooltip/Tooltip.js +20 -4
- package/src/modules/tooltip/Utils.js +8 -0
- 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/renderers/canvas/CanvasGraphics.js +1 -0
- package/src/ssr/DOMShim.js +10 -0
- package/src/types/internal.d.ts +9 -3
- package/types/apexcharts.d.ts +31 -12
|
@@ -48,6 +48,8 @@ export default class HeatmapGradientLegend {
|
|
|
48
48
|
this._max = 0
|
|
49
49
|
/** @type {any} */
|
|
50
50
|
this._geom = null
|
|
51
|
+
/** @type {any} */
|
|
52
|
+
this._grad = null
|
|
51
53
|
/** @type {any[]} */
|
|
52
54
|
this._bandHitEls = []
|
|
53
55
|
/** @type {number} Currently highlighted band index (-1 = none). */
|
|
@@ -58,6 +60,8 @@ export default class HeatmapGradientLegend {
|
|
|
58
60
|
* @type {HTMLElement|null}
|
|
59
61
|
*/
|
|
60
62
|
this._targetEl = null
|
|
63
|
+
/** @type {(() => any[])|null} detached mode: every panel's w */
|
|
64
|
+
this.panelsW = null
|
|
61
65
|
this._onCellEnter = this._onCellEnter.bind(this)
|
|
62
66
|
this._onCellLeave = this._onCellLeave.bind(this)
|
|
63
67
|
this._onBandEnter = this._onBandEnter.bind(this)
|
|
@@ -217,15 +221,8 @@ export default class HeatmapGradientLegend {
|
|
|
217
221
|
linearGrad.setAttribute('y2', '0')
|
|
218
222
|
}
|
|
219
223
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
this._max = max
|
|
223
|
-
stops.forEach((s) => {
|
|
224
|
-
const stopEl = BrowserAPIs.createElementNS(SVG_NS, 'stop')
|
|
225
|
-
stopEl.setAttribute('offset', `${(s.percent * 100).toFixed(2)}%`)
|
|
226
|
-
stopEl.setAttribute('stop-color', s.color)
|
|
227
|
-
linearGrad.appendChild(stopEl)
|
|
228
|
-
})
|
|
224
|
+
this._grad = linearGrad
|
|
225
|
+
const { min, max, bands } = this._paintStops()
|
|
229
226
|
defs.appendChild(linearGrad)
|
|
230
227
|
svg.appendChild(defs)
|
|
231
228
|
|
|
@@ -498,6 +495,9 @@ export default class HeatmapGradientLegend {
|
|
|
498
495
|
* Honors `legend.offsetX/offsetY` for user nudging. Safe to call repeatedly.
|
|
499
496
|
*/
|
|
500
497
|
repositionToPlot() {
|
|
498
|
+
// The cells' y extent and hasNegs exist only now (draw runs before
|
|
499
|
+
// coreCalculations), so shade the strip again against them.
|
|
500
|
+
if (this._grad) this._paintStops()
|
|
501
501
|
if (!Environment.isBrowser()) return
|
|
502
502
|
// Detached mode (trellis): the host slot owns layout entirely.
|
|
503
503
|
if (this._targetEl) return
|
|
@@ -672,7 +672,7 @@ export default class HeatmapGradientLegend {
|
|
|
672
672
|
if (idx < 0 || idx === this._activeBandIndex) return
|
|
673
673
|
this._activeBandIndex = idx
|
|
674
674
|
this.ctx?.events?.fireEvent?.('legendHover', [this.ctx, idx, w])
|
|
675
|
-
|
|
675
|
+
this._highlightRange(idx, 'highlight')
|
|
676
676
|
}
|
|
677
677
|
|
|
678
678
|
/** Leaving a band clears the highlight. */
|
|
@@ -680,7 +680,18 @@ export default class HeatmapGradientLegend {
|
|
|
680
680
|
if (this._activeBandIndex < 0) return
|
|
681
681
|
const idx = this._activeBandIndex
|
|
682
682
|
this._activeBandIndex = -1
|
|
683
|
-
|
|
683
|
+
this._highlightRange(idx, 'reset')
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
/**
|
|
687
|
+
* A shared trellis strip sets `panelsW` so a band reaches every panel.
|
|
688
|
+
* @param {number} idx
|
|
689
|
+
* @param {'highlight'|'reset'} action
|
|
690
|
+
*/
|
|
691
|
+
_highlightRange(idx, action) {
|
|
692
|
+
;(this.panelsW?.() || [this.w]).forEach((/** @type {any} */ w) =>
|
|
693
|
+
new Series(w).highlightRangeInSeries(idx, action),
|
|
694
|
+
)
|
|
684
695
|
}
|
|
685
696
|
|
|
686
697
|
_attachHoverListeners() {
|
|
@@ -702,11 +713,12 @@ export default class HeatmapGradientLegend {
|
|
|
702
713
|
* @param {...any} args
|
|
703
714
|
*/
|
|
704
715
|
_onCellEnter(...args) {
|
|
705
|
-
const w = this.w
|
|
706
716
|
if (!this.arrowEl) return
|
|
707
717
|
// The opts object is the last argument.
|
|
708
718
|
const opts = args[args.length - 1]
|
|
709
719
|
if (!opts || typeof opts !== 'object') return
|
|
720
|
+
// the hovered chart: a shared trellis strip hears every panel
|
|
721
|
+
const w = opts.w || this.w
|
|
710
722
|
const i = opts.seriesIndex
|
|
711
723
|
const j = opts.dataPointIndex
|
|
712
724
|
if (typeof i !== 'number' || typeof j !== 'number') return
|
|
@@ -845,6 +857,22 @@ export default class HeatmapGradientLegend {
|
|
|
845
857
|
return polygon
|
|
846
858
|
}
|
|
847
859
|
|
|
860
|
+
/** (Re)write the strip's stops; returns `_computeStops()`. */
|
|
861
|
+
_paintStops() {
|
|
862
|
+
const r = this._computeStops()
|
|
863
|
+
const grad = this._grad
|
|
864
|
+
this._min = r.min
|
|
865
|
+
this._max = r.max
|
|
866
|
+
grad.innerHTML = ''
|
|
867
|
+
r.stops.forEach((s) => {
|
|
868
|
+
const stopEl = BrowserAPIs.createElementNS(SVG_NS, 'stop')
|
|
869
|
+
stopEl.setAttribute('offset', `${(s.percent * 100).toFixed(2)}%`)
|
|
870
|
+
stopEl.setAttribute('stop-color', s.color)
|
|
871
|
+
grad.appendChild(stopEl)
|
|
872
|
+
})
|
|
873
|
+
return r
|
|
874
|
+
}
|
|
875
|
+
|
|
848
876
|
/**
|
|
849
877
|
* Build gradient stops + return effective min/max.
|
|
850
878
|
* - If `colorScale.ranges` is set, stops are placed at each range boundary
|
|
@@ -898,7 +926,9 @@ export default class HeatmapGradientLegend {
|
|
|
898
926
|
// one-sided = the historical expand-not-clamp semantics.
|
|
899
927
|
let min = dataMin
|
|
900
928
|
let max = dataMax
|
|
901
|
-
|
|
929
|
+
const csWindow =
|
|
930
|
+
typeof cs.min !== 'undefined' && typeof cs.max !== 'undefined' && cs.max > cs.min
|
|
931
|
+
if (csWindow) {
|
|
902
932
|
min = cs.min
|
|
903
933
|
max = cs.max
|
|
904
934
|
} else {
|
|
@@ -956,45 +986,46 @@ export default class HeatmapGradientLegend {
|
|
|
956
986
|
// is the documented behavior).
|
|
957
987
|
const baseColor = w.globals.colors[0] || '#008FFB'
|
|
958
988
|
const utils = new Utils()
|
|
959
|
-
const
|
|
989
|
+
const type = w.config.chart.type
|
|
990
|
+
const plot = w.config.plotOptions[type] || {}
|
|
960
991
|
const shadeIntensity = plot.shadeIntensity ?? 0.5
|
|
961
|
-
const
|
|
992
|
+
const g = /** @type {any} */ (w.globals)
|
|
993
|
+
const hasNegs = g.hasNegs
|
|
994
|
+
// A non-distributed heatmap's cells shade against the niced y extent
|
|
995
|
+
// and clamp into it (determineColor); use it once coreCalculations ran.
|
|
996
|
+
// A one-sided colorScale.max past maxY is ignored there, so cap at maxY.
|
|
997
|
+
const yExt =
|
|
998
|
+
type === 'heatmap' && !plot.distributed && !csWindow && g.maxY >= g.minY
|
|
999
|
+
const hi = yExt ? g.maxY : max
|
|
1000
|
+
const total =
|
|
1001
|
+
Math.abs(hi) + Math.abs(yExt ? (cs.min < g.minY ? cs.min : g.minY) : min)
|
|
1002
|
+
const k = shadeIntensity * 1.25
|
|
962
1003
|
const n = Math.max(2, cfg.stops || 16)
|
|
963
1004
|
for (let s = 0; s < n; s++) {
|
|
964
1005
|
const t = s / (n - 1) // 0..1
|
|
965
|
-
// Map t to the shade
|
|
1006
|
+
// Map t to the shade fraction the cell at that t would receive.
|
|
966
1007
|
// determineColor computes percent = 100*val/(|min|+|max|), so the cell
|
|
967
|
-
// sitting at value v = min + t*(max-min) gets
|
|
968
|
-
const
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
colorShadePercent = 1 - percent_v / 100
|
|
986
|
-
}
|
|
987
|
-
// Clamp to a reasonable range to avoid color blowout.
|
|
988
|
-
if (colorShadePercent > 1) colorShadePercent = 1
|
|
989
|
-
if (colorShadePercent < -1) colorShadePercent = -1
|
|
1008
|
+
// sitting at value v = min + t*(max-min) gets p = v / total.
|
|
1009
|
+
const p =
|
|
1010
|
+
total === 0 ? 0 : Math.min(min + t * (max - min), hi) / total
|
|
1011
|
+
// Clamp to a reasonable range to avoid color blowout. Treemap tiles
|
|
1012
|
+
// scale the plain shade too (getShadeColor).
|
|
1013
|
+
const c = Math.max(
|
|
1014
|
+
-1,
|
|
1015
|
+
Math.min(
|
|
1016
|
+
1,
|
|
1017
|
+
hasNegs
|
|
1018
|
+
? plot.reverseNegativeShade
|
|
1019
|
+
? (p < 0 ? p : 1 - p) * k
|
|
1020
|
+
: p <= 0
|
|
1021
|
+
? 1 - (1 + p) * shadeIntensity
|
|
1022
|
+
: (1 - p) * shadeIntensity
|
|
1023
|
+
: (1 - p) * (type === 'treemap' ? k : 1),
|
|
1024
|
+
),
|
|
1025
|
+
)
|
|
990
1026
|
|
|
991
1027
|
const shaded = plot.enableShades
|
|
992
|
-
? utils.shadeColor(
|
|
993
|
-
w.config.theme.mode === 'dark'
|
|
994
|
-
? colorShadePercent * -1
|
|
995
|
-
: colorShadePercent,
|
|
996
|
-
baseColor,
|
|
997
|
-
)
|
|
1028
|
+
? utils.shadeColor(w.config.theme.mode === 'dark' ? -c : c, baseColor)
|
|
998
1029
|
: baseColor
|
|
999
1030
|
stops.push({ percent: t, color: shaded })
|
|
1000
1031
|
}
|
|
@@ -55,6 +55,8 @@ export default class Helpers {
|
|
|
55
55
|
*/
|
|
56
56
|
toggleDataSeries(seriesCnt, isHidden) {
|
|
57
57
|
const w = this.w
|
|
58
|
+
// a legendClick handler may have destroyed the chart
|
|
59
|
+
if (!w.dom.baseEl) return
|
|
58
60
|
if (w.globals.axisCharts || w.config.chart.type === 'radialBar') {
|
|
59
61
|
w.globals.resized = true // we don't want initial animations again
|
|
60
62
|
|
|
@@ -74,6 +74,11 @@ class Legend {
|
|
|
74
74
|
const gl = w.globals
|
|
75
75
|
const cnf = w.config
|
|
76
76
|
|
|
77
|
+
// Tear down any previous gradient legend every render, so hiding the
|
|
78
|
+
// legend does not leave its listeners and repositioning behind.
|
|
79
|
+
this.heatmapGradientLegend?.destroy()
|
|
80
|
+
this.heatmapGradientLegend = null
|
|
81
|
+
|
|
77
82
|
// Recompute each render: the Legend instance is reused across updates, so a
|
|
78
83
|
// value cached in the constructor would go stale when updateOptions changes
|
|
79
84
|
// the type / distributed flag / series count (e.g. a distributed single-series
|
|
@@ -106,12 +111,6 @@ class Legend {
|
|
|
106
111
|
elLegendWrap.removeChild(elLegendWrap.firstChild)
|
|
107
112
|
}
|
|
108
113
|
|
|
109
|
-
// Tear down any previous gradient-legend listeners before re-rendering.
|
|
110
|
-
if (this.heatmapGradientLegend) {
|
|
111
|
-
this.heatmapGradientLegend.destroy()
|
|
112
|
-
this.heatmapGradientLegend = null
|
|
113
|
-
}
|
|
114
|
-
|
|
115
114
|
if (HeatmapGradientLegend.isEnabled(w)) {
|
|
116
115
|
this.heatmapGradientLegend = new HeatmapGradientLegend(w, this.ctx)
|
|
117
116
|
this.heatmapGradientLegend.draw()
|
|
@@ -381,7 +380,8 @@ class Legend {
|
|
|
381
380
|
// by index: groups may reuse series names, and an unnamed series has
|
|
382
381
|
// none to match
|
|
383
382
|
const lg = legendGroups[w.labelData.seriesGroupIndex[i]]
|
|
384
|
-
|
|
383
|
+
// once: re-appending moves the group, reordering interleaved groups
|
|
384
|
+
if (lg && !lg.parentNode) elLegendWrap.appendChild(lg)
|
|
385
385
|
;(lg || elLegendWrap).appendChild(elLegend)
|
|
386
386
|
|
|
387
387
|
elLegendWrap.classList.add(
|
|
@@ -537,10 +537,8 @@ class Legend {
|
|
|
537
537
|
const hoverOverLegend = isLegendItem(target)
|
|
538
538
|
|
|
539
539
|
if (w.config.chart.type !== 'heatmap' && !this.isBarsDistributed) {
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
hoverOverLegend
|
|
543
|
-
) {
|
|
540
|
+
// closest: the text span of a hidden item carries no inactive class
|
|
541
|
+
if (hoverOverLegend && !target.closest('.apexcharts-inactive-legend')) {
|
|
544
542
|
const series = new Series(this.ctx.w)
|
|
545
543
|
series.toggleSeriesOnHover(e, target)
|
|
546
544
|
}
|
|
@@ -585,7 +583,8 @@ class Legend {
|
|
|
585
583
|
// can keep toggling without having to re-tab to the legend.
|
|
586
584
|
if (rel !== null && w.config.legend.onItemClick.toggleDataSeries) {
|
|
587
585
|
requestAnimationFrame(() => {
|
|
588
|
-
|
|
586
|
+
// the chart may have been destroyed before this frame
|
|
587
|
+
const restored = w.dom.baseEl?.querySelector(
|
|
589
588
|
`.apexcharts-legend-series[rel="${rel}"]`,
|
|
590
589
|
)
|
|
591
590
|
if (restored) /** @type {HTMLElement} */ (restored).focus()
|
|
@@ -788,7 +788,14 @@ export default class Options {
|
|
|
788
788
|
// asked for and nobody can undo is a trap. Set either to true to
|
|
789
789
|
// force the gesture on regardless (for a page that supplies its own
|
|
790
790
|
// reset control), or false to turn it off outright.
|
|
791
|
+
//
|
|
792
|
+
// The 'auto' wheel is also cooperative: a bare wheel scrolls the
|
|
793
|
+
// page, and Ctrl/Cmd + wheel (or a trackpad pinch) zooms, so a page
|
|
794
|
+
// of charts scrolls past them. `true` zooms on every wheel.
|
|
791
795
|
allowMouseWheelZoom: 'auto',
|
|
796
|
+
// With the cooperative wheel, a bare scroll over the chart briefly
|
|
797
|
+
// shows how to zoom it ("Use Ctrl + scroll to zoom").
|
|
798
|
+
wheelHint: true,
|
|
792
799
|
// Momentum: two-finger pinch-zoom on touch devices. Zooms the x-axis
|
|
793
800
|
// around the pinch centroid (matching the x-only wheel/toolbar zoom),
|
|
794
801
|
// frame-by-frame rather than the 400ms wheel throttle.
|
|
@@ -2137,14 +2137,28 @@ export default class Tooltip {
|
|
|
2137
2137
|
shared: this.showOnIntersect ? false : this.tConfig.shared,
|
|
2138
2138
|
})
|
|
2139
2139
|
|
|
2140
|
-
|
|
2140
|
+
// A shared tooltip speaks for every series at `j`, so in a combo the
|
|
2141
|
+
// line's hover dots and the columns' hover state both follow it,
|
|
2142
|
+
// whichever series the pointer is nearest. Only the box goes to the
|
|
2143
|
+
// captured series' mark. Gating the bars on the captured series having
|
|
2144
|
+
// no markers left the dots on the last column the line was nearest to.
|
|
2145
|
+
const capturedPoints = hasMarkers || dynamicPoints
|
|
2146
|
+
if (
|
|
2147
|
+
capturedPoints ||
|
|
2148
|
+
(w.globals.comboCharts &&
|
|
2149
|
+
!canvasMode &&
|
|
2150
|
+
this.tooltipUtil.hasVisibleMarkers())
|
|
2151
|
+
) {
|
|
2141
2152
|
handlePoints()
|
|
2142
|
-
}
|
|
2153
|
+
}
|
|
2154
|
+
if (this.tooltipUtil.hasBars()) {
|
|
2143
2155
|
if (canvasMode) {
|
|
2144
2156
|
// canvas: bars/candles paint to the bitmap, so the paths /
|
|
2145
2157
|
// hover-filter machinery below is DOM-only. Position straight off
|
|
2146
2158
|
// the cached bar coords.
|
|
2147
|
-
|
|
2159
|
+
if (!capturedPoints) {
|
|
2160
|
+
ttCtx.tooltipPosition.moveStickyTooltipOverBars(j, capturedSeries)
|
|
2161
|
+
}
|
|
2148
2162
|
} else if (
|
|
2149
2163
|
[...bars].some((/** @type {Element} */ b) => b.querySelector('path'))
|
|
2150
2164
|
) {
|
|
@@ -2157,7 +2171,9 @@ export default class Tooltip {
|
|
|
2157
2171
|
// de-activate first
|
|
2158
2172
|
this.deactivateHoverFilter()
|
|
2159
2173
|
|
|
2160
|
-
|
|
2174
|
+
if (!capturedPoints) {
|
|
2175
|
+
ttCtx.tooltipPosition.moveStickyTooltipOverBars(j, capturedSeries)
|
|
2176
|
+
}
|
|
2161
2177
|
|
|
2162
2178
|
for (let b = 0; b < paths.length; b++) {
|
|
2163
2179
|
graphics.pathMouseEnter(
|
|
@@ -714,6 +714,14 @@ export default class Utils {
|
|
|
714
714
|
return markers.length > 0
|
|
715
715
|
}
|
|
716
716
|
|
|
717
|
+
/**
|
|
718
|
+
* Whether any visible series has a marker node, its points' or its hover
|
|
719
|
+
* dot's.
|
|
720
|
+
*/
|
|
721
|
+
hasVisibleMarkers() {
|
|
722
|
+
return this.getAllMarkers(true).some(Boolean)
|
|
723
|
+
}
|
|
724
|
+
|
|
717
725
|
/**
|
|
718
726
|
* @param {any} point
|
|
719
727
|
* @param {number} size
|
|
@@ -1032,8 +1032,14 @@ export default class Trellis {
|
|
|
1032
1032
|
// gap is the breathing room here).
|
|
1033
1033
|
parentHeightOffset: 0,
|
|
1034
1034
|
toolbar: { show: false },
|
|
1035
|
+
// the shared toolbar owns the one reset (TrellisSync.resetAll); with
|
|
1036
|
+
// toolbar 'none' a panel's own reset is the only way back, unless the
|
|
1037
|
+
// page turned it off
|
|
1035
1038
|
zoom: {
|
|
1036
1039
|
enabled: this.cfg.zoom !== 'none',
|
|
1040
|
+
resetControl:
|
|
1041
|
+
this.cfg.toolbar == 'none' &&
|
|
1042
|
+
w.config.chart.zoom.resetControl !== false,
|
|
1037
1043
|
},
|
|
1038
1044
|
...(animationsOff ? { animations: { enabled: false } } : {}),
|
|
1039
1045
|
// Grid-level canvas auto-selection (P2): a uniform explicit backend,
|
|
@@ -44,6 +44,8 @@ export default class TrellisChrome {
|
|
|
44
44
|
this.gradientLegend = null
|
|
45
45
|
/** @type {(() => void)|null} unsubscribe for a deferred gradient build */
|
|
46
46
|
this._gradPending = null
|
|
47
|
+
/** @type {any} the strip's panel hover wiring (and panelMounted hook) */
|
|
48
|
+
this._gradWire = null
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
/**
|
|
@@ -299,17 +301,24 @@ export default class TrellisChrome {
|
|
|
299
301
|
const legend = new HeatmapGradientLegend(chart.w, chart.ctx)
|
|
300
302
|
legend.draw(slot)
|
|
301
303
|
this.gradientLegend = legend
|
|
304
|
+
// a band highlights its range in every mounted panel
|
|
305
|
+
legend.panelsW = () =>
|
|
306
|
+
t.panels.filter((p) => p.chart).map((p) => /** @type {any} */ (p.chart).w)
|
|
302
307
|
|
|
303
308
|
// The instance's own hover wiring only hears ITS panel; mirror the same
|
|
304
|
-
// handlers onto every other mounted
|
|
305
|
-
// cursor anywhere in the grid.
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
309
|
+
// handlers onto every other panel, mounted now or later, so the arrow
|
|
310
|
+
// follows the cursor anywhere in the grid. Doubles as the host's
|
|
311
|
+
// panelMounted listener (ctx, { chart }).
|
|
312
|
+
/** @type {any} */
|
|
313
|
+
const wire = (/** @type {any} */ _, /** @type {any} */ p) => {
|
|
314
|
+
const ev = p.chart !== chart && p.chart?.ctx.events
|
|
315
|
+
if (!ev) return
|
|
310
316
|
ev.addEventListener('dataPointMouseEnter', legend._onCellEnter)
|
|
311
317
|
ev.addEventListener('dataPointMouseLeave', legend._onCellLeave)
|
|
312
|
-
}
|
|
318
|
+
}
|
|
319
|
+
t.panels.forEach((p) => wire(0, p))
|
|
320
|
+
t.ctx.events.addEventListener('panelMounted', wire)
|
|
321
|
+
this._gradWire = wire
|
|
313
322
|
}
|
|
314
323
|
|
|
315
324
|
/** Tear down the shared gradient strip (P5). */
|
|
@@ -319,6 +328,8 @@ export default class TrellisChrome {
|
|
|
319
328
|
t.ctx.events.removeEventListener?.('panelMounted', this._gradPending)
|
|
320
329
|
this._gradPending = null
|
|
321
330
|
}
|
|
331
|
+
// the panels' own buses die with them right after (teardown)
|
|
332
|
+
t.ctx.events.removeEventListener('panelMounted', this._gradWire)
|
|
322
333
|
if (this.gradientLegend) {
|
|
323
334
|
try {
|
|
324
335
|
this.gradientLegend.destroy()
|
|
@@ -310,6 +310,8 @@ export default class TrellisSync {
|
|
|
310
310
|
})
|
|
311
311
|
}
|
|
312
312
|
const loop = () => {
|
|
313
|
+
// a teardown (rebuild or destroy) under a resting pointer ends the loop
|
|
314
|
+
if (elGrid !== this.trellis.elGrid) return (raf = 0)
|
|
313
315
|
apply()
|
|
314
316
|
raf = hoverTarget ? requestAnimationFrame(loop) : 0
|
|
315
317
|
}
|
|
@@ -1023,6 +1023,7 @@ export default class CanvasGraphics {
|
|
|
1023
1023
|
cmd.strokeWidth = opts.strokeWidth
|
|
1024
1024
|
cmd.fill = opts.fill
|
|
1025
1025
|
cmd.lineCap = opts.strokeLinecap
|
|
1026
|
+
cmd.strokeDash = this._g.seriesDash(opts.realIndex)
|
|
1026
1027
|
cmd.si = opts.realIndex
|
|
1027
1028
|
// Data point identity. Only a mark that stands for one point (a bar-like:
|
|
1028
1029
|
// Bar.renderSeries) passes `j`; a line or area path stands for the whole
|
package/src/ssr/DOMShim.js
CHANGED
|
@@ -59,6 +59,16 @@ class SSRElement {
|
|
|
59
59
|
this.attributes.set(name, value)
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Namespaced attributes serialize by their qualified name.
|
|
64
|
+
* @param {any} _ns
|
|
65
|
+
* @param {string} name
|
|
66
|
+
* @param {any} value
|
|
67
|
+
*/
|
|
68
|
+
setAttributeNS(_ns, name, value) {
|
|
69
|
+
this.setAttribute(name, value)
|
|
70
|
+
}
|
|
71
|
+
|
|
62
72
|
/**
|
|
63
73
|
* @param {string} name
|
|
64
74
|
*/
|
package/src/types/internal.d.ts
CHANGED
|
@@ -110,6 +110,12 @@ export interface InteractState {
|
|
|
110
110
|
rafId: number | null
|
|
111
111
|
endTimer: any
|
|
112
112
|
}
|
|
113
|
+
// Cooperative wheel: fade-out timer for the "Ctrl + scroll to zoom" hint.
|
|
114
|
+
wheelHintTimer?: any
|
|
115
|
+
// Keyboard nav handing focus across an update that replaces the SVG:
|
|
116
|
+
// [seriesIndex, dataPointIndex, active, tooltipDismissed], set on destroy,
|
|
117
|
+
// taken on init.
|
|
118
|
+
keyNav?: [number, number, boolean, boolean] | null
|
|
113
119
|
}
|
|
114
120
|
|
|
115
121
|
/** Label formatter functions — lives on `w.formatters` */
|
|
@@ -569,9 +575,9 @@ export interface ChartGlobals
|
|
|
569
575
|
seriesYvalues: number[][]
|
|
570
576
|
seriesYAxisMap: number[][]
|
|
571
577
|
seriesYAxisReverseMap: number[]
|
|
572
|
-
barGroups:
|
|
573
|
-
lineGroups:
|
|
574
|
-
areaGroups:
|
|
578
|
+
barGroups: number[]
|
|
579
|
+
lineGroups: number[]
|
|
580
|
+
areaGroups: number[]
|
|
575
581
|
hasSeriesGroups: boolean
|
|
576
582
|
|
|
577
583
|
// ── Layout extras (ephemeral) ─────────────────────────────────────────────
|
package/types/apexcharts.d.ts
CHANGED
|
@@ -336,11 +336,11 @@ declare class ApexCharts {
|
|
|
336
336
|
/** Returns the sum of all data points whose x value falls within [minX, maxX]. */
|
|
337
337
|
getSeriesTotalXRange(minX: number, maxX: number): number[]
|
|
338
338
|
|
|
339
|
-
/** Returns the highest y value in the specified series. */
|
|
340
|
-
getHighestValueInSeries(seriesIndex?: number): number
|
|
339
|
+
/** Returns the highest y value in the specified series, or undefined for an index with no series. */
|
|
340
|
+
getHighestValueInSeries(seriesIndex?: number): number | undefined
|
|
341
341
|
|
|
342
|
-
/** Returns the lowest y value in the specified series. */
|
|
343
|
-
getLowestValueInSeries(seriesIndex?: number): number
|
|
342
|
+
/** Returns the lowest y value in the specified series, or undefined for an index with no series. */
|
|
343
|
+
getLowestValueInSeries(seriesIndex?: number): number | undefined
|
|
344
344
|
|
|
345
345
|
/** Returns the sum of each series (totals used for percentage calculations). */
|
|
346
346
|
getSeriesTotal(): number[]
|
|
@@ -2236,13 +2236,21 @@ type ApexChart = {
|
|
|
2236
2236
|
type?: 'x' | 'y' | 'xy'
|
|
2237
2237
|
autoScaleYaxis?: boolean
|
|
2238
2238
|
/**
|
|
2239
|
-
* Cursor-anchored zoom on mouse wheel / trackpad. `'auto'`
|
|
2240
|
-
*
|
|
2241
|
-
*
|
|
2242
|
-
*
|
|
2239
|
+
* Cursor-anchored zoom on mouse wheel / trackpad. `'auto'` is cooperative:
|
|
2240
|
+
* a bare wheel scrolls the page, and Ctrl/Cmd + wheel (or a trackpad
|
|
2241
|
+
* pinch) zooms. It is offered only when the toolbar's reset button is
|
|
2242
|
+
* present, so a zoom is always undoable. `true` zooms on every wheel, even
|
|
2243
|
+
* with the toolbar hidden. Requires `enabled: true`.
|
|
2243
2244
|
* @default 'auto'
|
|
2244
2245
|
*/
|
|
2245
2246
|
allowMouseWheelZoom?: boolean | 'auto'
|
|
2247
|
+
/**
|
|
2248
|
+
* With the cooperative `'auto'` wheel, a bare scroll over the chart
|
|
2249
|
+
* briefly shows how to zoom it. The text is the locale's
|
|
2250
|
+
* `toolbar.wheelZoomHint`, where `{key}` becomes Ctrl or ⌘.
|
|
2251
|
+
* @default true
|
|
2252
|
+
*/
|
|
2253
|
+
wheelHint?: boolean
|
|
2246
2254
|
/**
|
|
2247
2255
|
* Momentum: enable two-finger pinch-zoom on touch devices. Zooms the x-axis
|
|
2248
2256
|
* around the pinch centroid, frame-by-frame. `'auto'` enables it only when
|
|
@@ -2869,6 +2877,8 @@ type ApexLocale = {
|
|
|
2869
2877
|
exportToSVG?: string
|
|
2870
2878
|
exportToPNG?: string
|
|
2871
2879
|
exportToCSV?: string
|
|
2880
|
+
/** The cooperative wheel's hint; `{key}` becomes Ctrl or ⌘. Default 'Use {key} + scroll to zoom'. */
|
|
2881
|
+
wheelZoomHint?: string
|
|
2872
2882
|
}
|
|
2873
2883
|
/** The highlight filter add-on's words. */
|
|
2874
2884
|
highlightFilter?: {
|
|
@@ -3781,7 +3791,8 @@ type ApexPlotOptions = {
|
|
|
3781
3791
|
* recolours) across a regroup - the circles-to-bars transition.
|
|
3782
3792
|
* 'identity': keyed by each datum's `id`/`name`, so a SPECIFIC unit migrates
|
|
3783
3793
|
* across any regroup or relayout keeping its colour and size. Requires the
|
|
3784
|
-
* per-unit object form with unique ids/names
|
|
3794
|
+
* per-unit object form with unique ids/names (a repeated one is tracked by
|
|
3795
|
+
* its order of appearance).
|
|
3785
3796
|
*/
|
|
3786
3797
|
transition?: 'group' | 'flow' | 'identity'
|
|
3787
3798
|
/**
|
|
@@ -3919,7 +3930,10 @@ type ApexPlotOptions = {
|
|
|
3919
3930
|
sizeField?: string
|
|
3920
3931
|
/** `[minRadius, maxRadius]` in px: turns dots into area-scaled bubbles. */
|
|
3921
3932
|
sizeRange?: [number, number]
|
|
3922
|
-
/**
|
|
3933
|
+
/**
|
|
3934
|
+
* Left-gutter width reserved for lane (category) labels (lanes mode).
|
|
3935
|
+
* Defaults to the widest label, up to a third of the plot.
|
|
3936
|
+
*/
|
|
3923
3937
|
laneLabelWidth?: number
|
|
3924
3938
|
/** Draw the faint gridlines. Defaults to true. */
|
|
3925
3939
|
gridlines?: boolean
|
|
@@ -3991,7 +4005,11 @@ type ApexPlotOptions = {
|
|
|
3991
4005
|
borderRadius?: number
|
|
3992
4006
|
/** 1 dot represents this many units of value (waffle scaling). */
|
|
3993
4007
|
unitValue?: number
|
|
3994
|
-
/**
|
|
4008
|
+
/**
|
|
4009
|
+
* Safety cap on total dots; counts scale down proportionally above it (a
|
|
4010
|
+
* scatter keeps an even sample of each category). A split grid draws a
|
|
4011
|
+
* fixed number of cells per tile and is not capped.
|
|
4012
|
+
*/
|
|
3995
4013
|
maxUnits?: number
|
|
3996
4014
|
/** Packed layout: order categories smallest-first (minority centred). */
|
|
3997
4015
|
sortByGroup?: boolean
|
|
@@ -5327,7 +5345,8 @@ interface ApexUnitObject {
|
|
|
5327
5345
|
* Stable identity. The datum's own `id`/`name` when the per-unit object form
|
|
5328
5346
|
* supplies one, so a provider can address a specific unit ("Texas",
|
|
5329
5347
|
* "employee 41") rather than a positional slot; otherwise
|
|
5330
|
-
* `"<seriesIndex>:<dataPointIndex>"`.
|
|
5348
|
+
* `"<seriesIndex>:<dataPointIndex>"`. A repeated one is suffixed by its
|
|
5349
|
+
* order of appearance (`"Alex#2"`).
|
|
5331
5350
|
*/
|
|
5332
5351
|
id: string
|
|
5333
5352
|
/** Global draw order across every category. */
|