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
package/src/modules/Theme.js
CHANGED
package/src/modules/Toolbar.js
CHANGED
|
@@ -876,9 +876,10 @@ export default class Toolbar {
|
|
|
876
876
|
}
|
|
877
877
|
|
|
878
878
|
// if user has some series collapsed before hitting zoom reset button,
|
|
879
|
-
// those series should stay collapsed
|
|
879
|
+
// those series should stay collapsed. Cloned from the peek, as
|
|
880
|
+
// reading initialSeries deep clones it first.
|
|
880
881
|
const series = ch.ctx.series.emptyCollapsedSeries(
|
|
881
|
-
Utils.clone(w.globals.
|
|
882
|
+
Utils.clone(w.globals._initialSeriesPeek),
|
|
882
883
|
)
|
|
883
884
|
|
|
884
885
|
ch.updateHelpers._updateSeries(
|
|
@@ -5,6 +5,7 @@ import Toolbar from './Toolbar'
|
|
|
5
5
|
import AxisMapping from './AxisMapping'
|
|
6
6
|
import TooltipUtils from './tooltip/Utils'
|
|
7
7
|
import { Box } from '../svg/index'
|
|
8
|
+
import { BrowserAPIs } from '../ssr/BrowserAPIs.js'
|
|
8
9
|
|
|
9
10
|
// Wheel-zoom feel: scrolling this many deltaY pixels doubles (or halves) the
|
|
10
11
|
// visible x-window. 240px is about two discrete wheel notches per 2x zoom
|
|
@@ -381,6 +382,67 @@ export default class ZoomPanSelection extends Toolbar {
|
|
|
381
382
|
return this._incidentalZoomEnabled(zoom && zoom.allowMouseWheelZoom)
|
|
382
383
|
}
|
|
383
384
|
|
|
385
|
+
/** An explicit `true` zooms on every wheel; 'auto' needs Ctrl/Cmd. */
|
|
386
|
+
_wheelZoomGreedy() {
|
|
387
|
+
return this.w.config.chart.zoom.allowMouseWheelZoom === true
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* Tell a viewer whose bare wheel just scrolled past the chart how to zoom it.
|
|
392
|
+
* Shown over the chart while the scroll goes on and faded out shortly after
|
|
393
|
+
* it stops. Only for a mostly vertical wheel: a sideways trackpad swipe is
|
|
394
|
+
* not someone reaching for zoom.
|
|
395
|
+
*
|
|
396
|
+
* The node lives in elWrap and the timer on w.interact, since a re-render can
|
|
397
|
+
* replace both this instance and the wrapper's contents while it is up.
|
|
398
|
+
*
|
|
399
|
+
* @param {any} e
|
|
400
|
+
*/
|
|
401
|
+
_showWheelHint(e) {
|
|
402
|
+
const w = this.w
|
|
403
|
+
if (w.config.chart.zoom.wheelHint === false) return
|
|
404
|
+
if (Math.abs(e.deltaY) <= Math.abs(e.deltaX)) return
|
|
405
|
+
const wrap = w.dom.elWrap
|
|
406
|
+
if (!wrap) return
|
|
407
|
+
|
|
408
|
+
let el = wrap.querySelector('.apexcharts-wheel-hint')
|
|
409
|
+
if (!el) {
|
|
410
|
+
const win = BrowserAPIs.getWindow()
|
|
411
|
+
const nav = win && win.navigator
|
|
412
|
+
const mac = !!nav && /Mac|iPhone|iPad/.test(nav.platform || nav.userAgent)
|
|
413
|
+
const text = (w.globals.locale.toolbar.wheelZoomHint || '').replace(
|
|
414
|
+
'{key}',
|
|
415
|
+
mac ? '⌘' : 'Ctrl',
|
|
416
|
+
)
|
|
417
|
+
el = BrowserAPIs.createElement('div')
|
|
418
|
+
el.className = 'apexcharts-wheel-hint'
|
|
419
|
+
el.setAttribute('aria-hidden', 'true')
|
|
420
|
+
const label = BrowserAPIs.createElement('span')
|
|
421
|
+
label.textContent = text
|
|
422
|
+
label.style.fontFamily = w.config.chart.fontFamily
|
|
423
|
+
el.appendChild(label)
|
|
424
|
+
wrap.appendChild(el)
|
|
425
|
+
// lay the hidden state out before showing it, so it fades in
|
|
426
|
+
void (/** @type {HTMLElement} */ (el).offsetWidth)
|
|
427
|
+
}
|
|
428
|
+
el.classList.add('apexcharts-wheel-hint-visible')
|
|
429
|
+
|
|
430
|
+
const it = w.interact
|
|
431
|
+
if (it.wheelHintTimer) clearTimeout(it.wheelHintTimer)
|
|
432
|
+
it.wheelHintTimer = setTimeout(() => this._hideWheelHint(), 1200)
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
_hideWheelHint() {
|
|
436
|
+
const w = this.w
|
|
437
|
+
const it = w.interact
|
|
438
|
+
if (it.wheelHintTimer) {
|
|
439
|
+
clearTimeout(it.wheelHintTimer)
|
|
440
|
+
it.wheelHintTimer = null
|
|
441
|
+
}
|
|
442
|
+
const el = w.dom.elWrap?.querySelector('.apexcharts-wheel-hint')
|
|
443
|
+
if (el) el.classList.remove('apexcharts-wheel-hint-visible')
|
|
444
|
+
}
|
|
445
|
+
|
|
384
446
|
/**
|
|
385
447
|
* Put keyboard focus on the chart, where the chart is focusable at all.
|
|
386
448
|
*
|
|
@@ -454,10 +516,28 @@ export default class ZoomPanSelection extends Toolbar {
|
|
|
454
516
|
* @param {any} e
|
|
455
517
|
*/
|
|
456
518
|
mouseWheelEvent(e) {
|
|
457
|
-
e.preventDefault()
|
|
458
|
-
|
|
459
519
|
const st = this._wheel()
|
|
460
520
|
|
|
521
|
+
// Cooperative wheel ('auto'): a bare wheel belongs to the page, so a
|
|
522
|
+
// dashboard of charts scrolls past them instead of zooming each one it
|
|
523
|
+
// crosses. Ctrl/Cmd + wheel zooms, and so does a trackpad pinch, which
|
|
524
|
+
// browsers deliver as a wheel event with ctrlKey set. Once a zoom gesture
|
|
525
|
+
// is under way it keeps the wheel until it settles, so a trackpad's
|
|
526
|
+
// momentum tail after the key comes up does not spill into a page scroll.
|
|
527
|
+
// An explicit `true` keeps the greedy wheel (every scroll zooms).
|
|
528
|
+
if (
|
|
529
|
+
!this._wheelZoomGreedy() &&
|
|
530
|
+
!e.ctrlKey &&
|
|
531
|
+
!e.metaKey &&
|
|
532
|
+
st.endTimer == null
|
|
533
|
+
) {
|
|
534
|
+
this._showWheelHint(e)
|
|
535
|
+
return
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
e.preventDefault()
|
|
539
|
+
this._hideWheelHint()
|
|
540
|
+
|
|
461
541
|
// normalize the delta to pixels (deltaMode 1 = lines, 2 = pages)
|
|
462
542
|
let dy = e.deltaY
|
|
463
543
|
if (e.deltaMode === 1) dy *= 33
|
|
@@ -1295,6 +1375,10 @@ export default class ZoomPanSelection extends Toolbar {
|
|
|
1295
1375
|
}
|
|
1296
1376
|
}
|
|
1297
1377
|
|
|
1378
|
+
// A vertical drag, or one held at the data edge, leaves the window where
|
|
1379
|
+
// it is: no re-render and no `scrolled` for a pan that did not move.
|
|
1380
|
+
if (xLowestValue === minX && xHighestValue === maxX) return
|
|
1381
|
+
|
|
1298
1382
|
const xaxis = {
|
|
1299
1383
|
min: xLowestValue,
|
|
1300
1384
|
max: xHighestValue,
|
|
@@ -1520,6 +1604,43 @@ export default class ZoomPanSelection extends Toolbar {
|
|
|
1520
1604
|
this.ctx.events.fireEvent('scrolled', args)
|
|
1521
1605
|
}
|
|
1522
1606
|
|
|
1607
|
+
/**
|
|
1608
|
+
* Pan a zoomed x-window by `fraction` of its width (keyboard Shift+Arrow),
|
|
1609
|
+
* clamped to the data as a drag pan is, and reported as one (`scrolled`).
|
|
1610
|
+
* @param {number} fraction
|
|
1611
|
+
*/
|
|
1612
|
+
panBy(fraction) {
|
|
1613
|
+
const w = this.w
|
|
1614
|
+
if (!w.interact.zoomed) return
|
|
1615
|
+
const { min, max } = this._currentXWindow()
|
|
1616
|
+
let d = (max - min) * fraction
|
|
1617
|
+
// a category window moves by whole categories
|
|
1618
|
+
if (w.config.xaxis.convertedCatToNumeric) {
|
|
1619
|
+
d = d > 0 ? Math.ceil(d) : Math.floor(d)
|
|
1620
|
+
}
|
|
1621
|
+
// _clampBounds has none for a rangeBar: stop at the ends of its bars
|
|
1622
|
+
if (w.axisFlags.isRangeBar) {
|
|
1623
|
+
const r = w.rangeData
|
|
1624
|
+
let lo = Infinity
|
|
1625
|
+
let hi = -Infinity
|
|
1626
|
+
r.seriesRangeStart
|
|
1627
|
+
.concat(r.seriesRangeEnd)
|
|
1628
|
+
.flat()
|
|
1629
|
+
.forEach((/** @type {any} */ y) => {
|
|
1630
|
+
if (y != null) {
|
|
1631
|
+
lo = Math.min(lo, y)
|
|
1632
|
+
hi = Math.max(hi, y)
|
|
1633
|
+
}
|
|
1634
|
+
})
|
|
1635
|
+
d =
|
|
1636
|
+
d > 0
|
|
1637
|
+
? Math.min(d, Math.max(0, hi - max))
|
|
1638
|
+
: Math.max(d, Math.min(0, lo - min))
|
|
1639
|
+
if (!d) return
|
|
1640
|
+
}
|
|
1641
|
+
if (this._applyXRange(min + d, max + d, false)) this._fireScrolled()
|
|
1642
|
+
}
|
|
1643
|
+
|
|
1523
1644
|
/** @param {number} x @param {number} t */
|
|
1524
1645
|
_pushSample(x, t) {
|
|
1525
1646
|
const s = this._m().samples
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
import Graphics from '../Graphics'
|
|
3
3
|
import TooltipUtils from '../tooltip/Utils'
|
|
4
|
-
import Utils from '../../utils/Utils'
|
|
5
4
|
|
|
6
5
|
/**
|
|
7
6
|
* ApexCharts KeyboardNavigation
|
|
@@ -16,7 +15,7 @@ import Utils from '../../utils/Utils'
|
|
|
16
15
|
* heatmap, the row above / below
|
|
17
16
|
* Home: first data point in current series
|
|
18
17
|
* End: last data point in current series
|
|
19
|
-
* Enter / Space: fire markerClick
|
|
18
|
+
* Enter / Space: select the point and fire markerClick, as a click does
|
|
20
19
|
* Escape: exit keyboard nav, return focus to SVG
|
|
21
20
|
*/
|
|
22
21
|
export default class KeyboardNavigation {
|
|
@@ -107,12 +106,27 @@ export default class KeyboardNavigation {
|
|
|
107
106
|
// keyboard-nav tooltip so it doesn't remain stuck on screen while the chart
|
|
108
107
|
// re-renders with a different set of visible series.
|
|
109
108
|
this.ctx.events.addEventListener('legendClick', this._onLegendClick)
|
|
109
|
+
|
|
110
|
+
// An update (a keyboard zoom or pan among them) replaced a focused SVG:
|
|
111
|
+
// focus this one, with the cursor and a dismissed tooltip as they were
|
|
112
|
+
// (destroy), unless focus has gone somewhere else since
|
|
113
|
+
const kept = w.interact.keyNav
|
|
114
|
+
const doc = svgEl.ownerDocument
|
|
115
|
+
w.interact.keyNav = null
|
|
116
|
+
if (kept && (!doc.activeElement || doc.activeElement === doc.body)) {
|
|
117
|
+
;[this.seriesIndex, this.dataPointIndex, , this._tooltipDismissed] = kept
|
|
118
|
+
// Focus alone, without starting nav, if nav was not running
|
|
119
|
+
if (!kept[2]) this.notePointerFocus()
|
|
120
|
+
svgEl.focus({ preventScroll: true })
|
|
121
|
+
}
|
|
110
122
|
}
|
|
111
123
|
|
|
112
124
|
/**
|
|
113
|
-
* Removes all event listeners. Called from chart.destroy()
|
|
125
|
+
* Removes all event listeners. Called from chart.destroy(), and with
|
|
126
|
+
* `updating` when an update is about to replace the SVG.
|
|
127
|
+
* @param {boolean} [updating]
|
|
114
128
|
*/
|
|
115
|
-
destroy() {
|
|
129
|
+
destroy(updating) {
|
|
116
130
|
const w = this.w
|
|
117
131
|
const svgEl = w.dom.Paper && w.dom.Paper.node
|
|
118
132
|
|
|
@@ -126,6 +140,14 @@ export default class KeyboardNavigation {
|
|
|
126
140
|
|
|
127
141
|
if (!svgEl) return
|
|
128
142
|
|
|
143
|
+
if (updating && svgEl.getRootNode?.().activeElement === svgEl) {
|
|
144
|
+
w.interact.keyNav = [
|
|
145
|
+
this.seriesIndex,
|
|
146
|
+
this.dataPointIndex,
|
|
147
|
+
this.active,
|
|
148
|
+
this._tooltipDismissed,
|
|
149
|
+
]
|
|
150
|
+
}
|
|
129
151
|
svgEl.removeEventListener('focus', this._onFocus)
|
|
130
152
|
svgEl.removeEventListener('blur', this._onBlur)
|
|
131
153
|
svgEl.removeEventListener('keydown', this._onKeyDown)
|
|
@@ -192,7 +214,8 @@ export default class KeyboardNavigation {
|
|
|
192
214
|
// If the chart is zoomed, snap the cursor to the first visible data point
|
|
193
215
|
// so the user doesn't start navigating outside the current viewport.
|
|
194
216
|
this._snapToVisibleRange()
|
|
195
|
-
|
|
217
|
+
// An update re-focusing a chart whose tooltip was dismissed (init)
|
|
218
|
+
if (!this._tooltipDismissed) this._showCurrentPoint()
|
|
196
219
|
}
|
|
197
220
|
|
|
198
221
|
_onBlur() {
|
|
@@ -249,20 +272,18 @@ export default class KeyboardNavigation {
|
|
|
249
272
|
break
|
|
250
273
|
case 'Home':
|
|
251
274
|
e.preventDefault()
|
|
252
|
-
this.
|
|
253
|
-
this._skipNullForward()
|
|
275
|
+
this._seek(0, 1)
|
|
254
276
|
this._showCurrentPoint()
|
|
255
277
|
break
|
|
256
278
|
case 'End':
|
|
257
279
|
e.preventDefault()
|
|
258
|
-
this.
|
|
259
|
-
this._skipNullBackward()
|
|
280
|
+
this._seek(this._getDataPointCount(this.seriesIndex) - 1, -1)
|
|
260
281
|
this._showCurrentPoint()
|
|
261
282
|
break
|
|
262
283
|
case 'Enter':
|
|
263
284
|
case ' ':
|
|
264
285
|
e.preventDefault()
|
|
265
|
-
this._fireClick()
|
|
286
|
+
this._fireClick(e)
|
|
266
287
|
break
|
|
267
288
|
case '+':
|
|
268
289
|
case '=':
|
|
@@ -323,28 +344,16 @@ export default class KeyboardNavigation {
|
|
|
323
344
|
}
|
|
324
345
|
|
|
325
346
|
_canPan() {
|
|
326
|
-
//
|
|
327
|
-
|
|
328
|
-
// toolbar's zoomUpdateOptions clamps to data bounds.
|
|
329
|
-
return this._canZoom()
|
|
347
|
+
// Unzoomed, the whole domain is in view: there is nothing to pan to
|
|
348
|
+
return this._canZoom() && this.w.interact.zoomed
|
|
330
349
|
}
|
|
331
350
|
|
|
332
351
|
/**
|
|
333
|
-
* Shift the visible x-range by ~10% in the given direction.
|
|
352
|
+
* Shift the visible x-range by ~10% in the given direction, as a drag pan.
|
|
334
353
|
* @param {number} direction +1 = right, -1 = left
|
|
335
354
|
*/
|
|
336
355
|
_panBy(direction) {
|
|
337
|
-
|
|
338
|
-
if (!toolbar) return
|
|
339
|
-
|
|
340
|
-
const r = toolbar._currentXRange()
|
|
341
|
-
const minX = Number(r.minX)
|
|
342
|
-
const maxX = Number(r.maxX)
|
|
343
|
-
if (!isFinite(minX) || !isFinite(maxX) || minX === maxX) return
|
|
344
|
-
|
|
345
|
-
const span = maxX - minX
|
|
346
|
-
const step = span * 0.1 * direction
|
|
347
|
-
toolbar.zoomUpdateOptions(minX + step, maxX + step)
|
|
356
|
+
this.ctx.zoomPanSelection?.panBy(direction / 10)
|
|
348
357
|
this._announce(direction > 0 ? 'Panned right' : 'Panned left')
|
|
349
358
|
}
|
|
350
359
|
|
|
@@ -365,13 +374,15 @@ export default class KeyboardNavigation {
|
|
|
365
374
|
// so ↑/↓ series switching would show the same content — suppress it.
|
|
366
375
|
// For irregular time series the tooltip falls back to individual mode
|
|
367
376
|
// (isXoverlap returns false), so up/down navigation is meaningful there.
|
|
368
|
-
// A heatmap or treemap tooltip is always one cell's
|
|
369
|
-
// tooltip.shared says (and it defaults to true), so
|
|
370
|
-
// way to another row.
|
|
377
|
+
// A heatmap or treemap tooltip is always one cell's and a radialBar's
|
|
378
|
+
// one ring's, whatever tooltip.shared says (and it defaults to true), so
|
|
379
|
+
// ↑/↓ is the only way to another row. Without a tooltip nothing shows
|
|
380
|
+
// the other series either.
|
|
371
381
|
const ttCtx = this.w.globals.tooltip
|
|
372
382
|
const type = w.config.chart.type
|
|
373
|
-
const perCell =
|
|
374
|
-
|
|
383
|
+
const perCell =
|
|
384
|
+
type === 'heatmap' || type === 'treemap' || type === 'radialBar'
|
|
385
|
+
if (!perCell && ttCtx?.ttItems && ttCtx.tConfig.shared) {
|
|
375
386
|
const j = this.dataPointIndex
|
|
376
387
|
const isActuallyShared =
|
|
377
388
|
ttCtx.tooltipUtil &&
|
|
@@ -413,20 +424,7 @@ export default class KeyboardNavigation {
|
|
|
413
424
|
|
|
414
425
|
if (dPoint !== 0) {
|
|
415
426
|
// Move between data points (←/→)
|
|
416
|
-
|
|
417
|
-
let di = this.dataPointIndex + dPoint
|
|
418
|
-
|
|
419
|
-
if (di < 0) di = wrapAround ? dpCount - 1 : 0
|
|
420
|
-
if (di >= dpCount) di = wrapAround ? 0 : dpCount - 1
|
|
421
|
-
|
|
422
|
-
this.dataPointIndex = di
|
|
423
|
-
|
|
424
|
-
// Skip null values
|
|
425
|
-
if (dPoint > 0) {
|
|
426
|
-
this._skipNullForward()
|
|
427
|
-
} else {
|
|
428
|
-
this._skipNullBackward()
|
|
429
|
-
}
|
|
427
|
+
this._seek(this.dataPointIndex + dPoint, dPoint)
|
|
430
428
|
|
|
431
429
|
// If the chart is zoomed, skip data points outside the visible range
|
|
432
430
|
if (!this._isDataPointVisible(this.seriesIndex, this.dataPointIndex)) {
|
|
@@ -437,40 +435,26 @@ export default class KeyboardNavigation {
|
|
|
437
435
|
this._showCurrentPoint()
|
|
438
436
|
}
|
|
439
437
|
|
|
440
|
-
/**
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
// Non-axis charts (pie, etc.) have flat numeric series — no nulls to skip
|
|
449
|
-
if (!Array.isArray(w.seriesData.series[si])) return
|
|
450
|
-
|
|
451
|
-
while (attempts < dpCount && w.seriesData.series[si][di] === null) {
|
|
452
|
-
di = (di + 1) % dpCount
|
|
453
|
-
attempts++
|
|
454
|
-
}
|
|
455
|
-
this.dataPointIndex = di
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
/** Retreat dataPointIndex backward past any nulls */
|
|
459
|
-
_skipNullBackward() {
|
|
438
|
+
/**
|
|
439
|
+
* Land on the first non-null point from `di` going `dir`. Past an edge it
|
|
440
|
+
* wraps only with wrapAround; when no point lies ahead the cursor stays.
|
|
441
|
+
* @param {number} di
|
|
442
|
+
* @param {number} dir
|
|
443
|
+
*/
|
|
444
|
+
_seek(di, dir) {
|
|
460
445
|
const w = this.w
|
|
461
|
-
const
|
|
462
|
-
const
|
|
463
|
-
let
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
446
|
+
const row = w.seriesData.series[this.seriesIndex]
|
|
447
|
+
const n = this._getDataPointCount(this.seriesIndex)
|
|
448
|
+
for (let k = 0; k < n; k++, di += dir) {
|
|
449
|
+
if (w.config.chart.accessibility.keyboard.navigation.wrapAround) {
|
|
450
|
+
di = (di + n) % n
|
|
451
|
+
} else if (di < 0 || di >= n) return
|
|
452
|
+
// Non-axis charts (pie, radialBar) have flat values, no nulls
|
|
453
|
+
if (!Array.isArray(row) || row[di] !== null) {
|
|
454
|
+
this.dataPointIndex = di
|
|
455
|
+
return
|
|
456
|
+
}
|
|
472
457
|
}
|
|
473
|
-
this.dataPointIndex = di
|
|
474
458
|
}
|
|
475
459
|
|
|
476
460
|
// ─── Display ──────────────────────────────────────────────────────────────
|
|
@@ -480,13 +464,15 @@ export default class KeyboardNavigation {
|
|
|
480
464
|
const w = this.w
|
|
481
465
|
const ttCtx = w.globals.tooltip
|
|
482
466
|
|
|
483
|
-
|
|
484
|
-
|
|
467
|
+
// Showing a point again undoes an Escape dismissal
|
|
468
|
+
this._tooltipDismissed = false
|
|
485
469
|
// Keep globals consistent with the rest of the system
|
|
486
470
|
w.interact.capturedSeriesIndex = i
|
|
487
471
|
w.interact.capturedDataPointIndex = j
|
|
488
472
|
|
|
489
473
|
this._applyFocusClass(i, j)
|
|
474
|
+
// No tooltip to read out the point, so the live region names it
|
|
475
|
+
if (!ttCtx?.ttItems) return this._announce(this._buildPointLabel(i, j))
|
|
490
476
|
this._showTooltip(i, j, /** @type {any} */ (ttCtx))
|
|
491
477
|
}
|
|
492
478
|
|
|
@@ -571,10 +557,13 @@ export default class KeyboardNavigation {
|
|
|
571
557
|
tooltipEl.removeAttribute('aria-hidden')
|
|
572
558
|
}
|
|
573
559
|
|
|
574
|
-
if (
|
|
560
|
+
if (
|
|
561
|
+
type === 'pie' ||
|
|
562
|
+
type === 'donut' ||
|
|
563
|
+
type === 'polarArea' ||
|
|
564
|
+
type === 'radialBar'
|
|
565
|
+
) {
|
|
575
566
|
this._showTooltipNonAxis(i, j, ttCtx, tooltipEl)
|
|
576
|
-
} else if (type === 'radialBar') {
|
|
577
|
-
this._showTooltipRadialBar(i, j, ttCtx, tooltipEl)
|
|
578
567
|
} else if (type === 'heatmap' || type === 'treemap') {
|
|
579
568
|
this._showTooltipHeatTree(i, j, ttCtx, tooltipEl, type)
|
|
580
569
|
} else if (this._isBarLikeSeries(i)) {
|
|
@@ -1130,19 +1119,17 @@ export default class KeyboardNavigation {
|
|
|
1130
1119
|
}
|
|
1131
1120
|
|
|
1132
1121
|
/**
|
|
1133
|
-
* pie / donut / polarArea
|
|
1122
|
+
* pie / donut / polarArea (a slice per point, i is 0) and radialBar (a ring
|
|
1123
|
+
* per series, j is 0)
|
|
1134
1124
|
* @param {number} i
|
|
1135
1125
|
* @param {number} j
|
|
1136
1126
|
* @param {import('../tooltip/Tooltip').default} ttCtx
|
|
1137
1127
|
* @param {HTMLElement} tooltipEl
|
|
1138
1128
|
*/
|
|
1139
1129
|
_showTooltipNonAxis(i, j, ttCtx, tooltipEl) {
|
|
1140
|
-
const w = this.w
|
|
1141
|
-
|
|
1142
|
-
// For pie-like charts the series index IS the data point / slice index
|
|
1143
1130
|
ttCtx.tooltipLabels.drawSeriesTexts({
|
|
1144
1131
|
ttItems: ttCtx.ttItems,
|
|
1145
|
-
i: j,
|
|
1132
|
+
i: i + j,
|
|
1146
1133
|
shared: false,
|
|
1147
1134
|
})
|
|
1148
1135
|
|
|
@@ -1151,12 +1138,9 @@ export default class KeyboardNavigation {
|
|
|
1151
1138
|
const ttWidth = tooltipBound.width || ttCtx.tooltipRect.ttWidth || 0
|
|
1152
1139
|
const ttHeight = tooltipBound.height || ttCtx.tooltipRect.ttHeight || 0
|
|
1153
1140
|
|
|
1154
|
-
// Anchor on the arc
|
|
1155
|
-
// so keyboard and pointer land
|
|
1156
|
-
|
|
1157
|
-
// path directly, not on the parent group.
|
|
1158
|
-
const sliceEl = w.dom.baseEl.querySelector(`.apexcharts-pie-area[j='${j}']`)
|
|
1159
|
-
const anchor = ttCtx.getSliceAnchor(sliceEl)
|
|
1141
|
+
// Anchor on the arc's stamped centre (data:cx/cy), through the same helper
|
|
1142
|
+
// the mouse path uses so keyboard and pointer land in the same place.
|
|
1143
|
+
const anchor = ttCtx.getSliceAnchor(this._getFocusableElement(i, j))
|
|
1160
1144
|
if (anchor) {
|
|
1161
1145
|
const pos = ttCtx.tooltipPosition.placeOverAnchor(
|
|
1162
1146
|
anchor.x,
|
|
@@ -1169,68 +1153,6 @@ export default class KeyboardNavigation {
|
|
|
1169
1153
|
tooltipEl.style.top = pos.y + 'px'
|
|
1170
1154
|
}
|
|
1171
1155
|
}
|
|
1172
|
-
/**
|
|
1173
|
-
* radialBar — one ring per series, single value each
|
|
1174
|
-
* @param {number} i
|
|
1175
|
-
* @param {any} _j
|
|
1176
|
-
* @param {import('../tooltip/Tooltip').default} ttCtx
|
|
1177
|
-
* @param {HTMLElement} tooltipEl
|
|
1178
|
-
*/
|
|
1179
|
-
_showTooltipRadialBar(i, _j, ttCtx, tooltipEl) {
|
|
1180
|
-
const w = this.w
|
|
1181
|
-
|
|
1182
|
-
ttCtx.tooltipLabels.drawSeriesTexts({
|
|
1183
|
-
ttItems: ttCtx.ttItems,
|
|
1184
|
-
i,
|
|
1185
|
-
shared: false,
|
|
1186
|
-
})
|
|
1187
|
-
|
|
1188
|
-
const { ttWidth = 0, ttHeight = 0 } = ttCtx.getCachedDimensions()
|
|
1189
|
-
|
|
1190
|
-
// Each radial series is a ring; find the path and use its data:angle to
|
|
1191
|
-
// compute the centroid at the midpoint of the arc.
|
|
1192
|
-
const arcEl = w.dom.baseEl.querySelector(
|
|
1193
|
-
`.apexcharts-radialbar-series[data\\:realIndex='${i}'] path`,
|
|
1194
|
-
)
|
|
1195
|
-
if (arcEl) {
|
|
1196
|
-
const angle = parseFloat(arcEl.getAttribute('data:angle') ?? '') || 0
|
|
1197
|
-
// Radial bars start from the top (initialAngle) and sweep clockwise
|
|
1198
|
-
const initialAngle = w.config.plotOptions.radialBar.startAngle || 0
|
|
1199
|
-
const midAngle = initialAngle + angle / 2
|
|
1200
|
-
|
|
1201
|
-
const centerX = w.layout.gridWidth / 2
|
|
1202
|
-
const centerY = w.layout.gridHeight / 2
|
|
1203
|
-
const radialSize =
|
|
1204
|
-
w.globals.radialSize ||
|
|
1205
|
-
Math.min(w.layout.gridWidth, w.layout.gridHeight) / 2
|
|
1206
|
-
|
|
1207
|
-
// Use the outer radius for this particular ring (series i)
|
|
1208
|
-
const seriesCount = w.seriesData.series.length
|
|
1209
|
-
const trackSize = radialSize / Math.max(seriesCount, 1)
|
|
1210
|
-
const outerRadius = radialSize - i * trackSize
|
|
1211
|
-
const innerRadius = outerRadius - trackSize
|
|
1212
|
-
const ringRadius = (outerRadius + innerRadius) / 2
|
|
1213
|
-
|
|
1214
|
-
const centroid = Utils.polarToCartesian(
|
|
1215
|
-
centerX,
|
|
1216
|
-
centerY,
|
|
1217
|
-
ringRadius,
|
|
1218
|
-
midAngle,
|
|
1219
|
-
)
|
|
1220
|
-
const x = centroid.x + (w.layout.translateX || 0)
|
|
1221
|
-
const y = centroid.y + (w.layout.translateY || 0)
|
|
1222
|
-
|
|
1223
|
-
const pos = ttCtx.tooltipPosition.placeOverAnchor(
|
|
1224
|
-
x,
|
|
1225
|
-
y,
|
|
1226
|
-
ttWidth,
|
|
1227
|
-
ttHeight,
|
|
1228
|
-
10,
|
|
1229
|
-
)
|
|
1230
|
-
tooltipEl.style.left = pos.x + 'px'
|
|
1231
|
-
tooltipEl.style.top = pos.y + 'px'
|
|
1232
|
-
}
|
|
1233
|
-
}
|
|
1234
1156
|
/**
|
|
1235
1157
|
* heatmap / treemap — position tooltip using element bounding rect
|
|
1236
1158
|
* @param {number} i
|
|
@@ -1562,11 +1484,7 @@ export default class KeyboardNavigation {
|
|
|
1562
1484
|
const mark = this._canvasMark(i, j)
|
|
1563
1485
|
if (!mark) return this._drawCanvasMarkerFocusRing(i, j)
|
|
1564
1486
|
const w = this.w
|
|
1565
|
-
|
|
1566
|
-
// groups, which a combo has several of).
|
|
1567
|
-
const host = Array.from(
|
|
1568
|
-
w.dom.baseEl.querySelectorAll('.apexcharts-series'),
|
|
1569
|
-
).find((g) => g.getAttribute('data:realIndex') === String(i))
|
|
1487
|
+
const host = this._seriesGroup(i)
|
|
1570
1488
|
if (!host) return null
|
|
1571
1489
|
const ring = new Graphics(w, this.ctx).drawPath({
|
|
1572
1490
|
d: mark.d,
|
|
@@ -1591,9 +1509,7 @@ export default class KeyboardNavigation {
|
|
|
1591
1509
|
const marker = this._canvasMarker(i, j)
|
|
1592
1510
|
if (!marker) return null
|
|
1593
1511
|
const w = this.w
|
|
1594
|
-
const host =
|
|
1595
|
-
w.dom.baseEl.querySelectorAll('.apexcharts-series'),
|
|
1596
|
-
).find((g) => g.getAttribute('data:realIndex') === String(i))
|
|
1512
|
+
const host = this._seriesGroup(i)
|
|
1597
1513
|
if (!host) return null
|
|
1598
1514
|
const ring = new Graphics(w, this.ctx).drawPath({
|
|
1599
1515
|
d: marker.d,
|
|
@@ -1729,9 +1645,7 @@ export default class KeyboardNavigation {
|
|
|
1729
1645
|
}
|
|
1730
1646
|
|
|
1731
1647
|
if (type === 'radialBar') {
|
|
1732
|
-
return baseEl.querySelector(
|
|
1733
|
-
`.apexcharts-radialbar-series[data\\:realIndex='${i}'] path`,
|
|
1734
|
-
)
|
|
1648
|
+
return baseEl.querySelector(`.apexcharts-radialbar-slice-${i}`)
|
|
1735
1649
|
}
|
|
1736
1650
|
|
|
1737
1651
|
if (this._isBarLikeSeries(i)) {
|
|
@@ -1739,31 +1653,44 @@ export default class KeyboardNavigation {
|
|
|
1739
1653
|
// it, _drawCanvasFocusRing), and a jitter path that still carries its
|
|
1740
1654
|
// `j` in the series is no stand-in for it.
|
|
1741
1655
|
if (this._canvasMark(i, j)) return null
|
|
1742
|
-
return
|
|
1743
|
-
`.apexcharts-series[data\\:realIndex='${i}'] path[j='${j}']`,
|
|
1744
|
-
)
|
|
1656
|
+
return this._seriesGroup(i)?.querySelector(`path[j='${j}']`)
|
|
1745
1657
|
}
|
|
1746
1658
|
|
|
1747
1659
|
// line / area / scatter / bubble / radar — try marker element
|
|
1748
|
-
|
|
1749
|
-
`.apexcharts-series[data\\:realIndex='${i}'] .apexcharts-marker[rel='${j}']`,
|
|
1750
|
-
)
|
|
1751
|
-
return marker || null
|
|
1660
|
+
return this._seriesGroup(i)?.querySelector(`.apexcharts-marker[rel='${j}']`)
|
|
1752
1661
|
}
|
|
1753
1662
|
|
|
1754
|
-
|
|
1663
|
+
/**
|
|
1664
|
+
* The series' own group, by realIndex (`rel` counts within a type's groups,
|
|
1665
|
+
* which a combo has several of). Matched in script: not every selector
|
|
1666
|
+
* engine takes the escaped `data\:realIndex` attribute.
|
|
1667
|
+
* @param {number} i
|
|
1668
|
+
* @returns {Element | undefined}
|
|
1669
|
+
*/
|
|
1670
|
+
_seriesGroup(i) {
|
|
1671
|
+
return Array.from(
|
|
1672
|
+
this.w.dom.baseEl.querySelectorAll('.apexcharts-series'),
|
|
1673
|
+
).find((g) => g.getAttribute('data:realIndex') === String(i))
|
|
1674
|
+
}
|
|
1755
1675
|
|
|
1756
|
-
|
|
1757
|
-
const w = this.w
|
|
1758
|
-
const ttCtx = w.globals.tooltip
|
|
1759
|
-
if (!ttCtx) return
|
|
1676
|
+
// ─── Click / Enter ────────────────────────────────────────────────────────
|
|
1760
1677
|
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1678
|
+
/**
|
|
1679
|
+
* What a click on the focused mark does: its mousedown selects it
|
|
1680
|
+
* (dataPointSelection), its mouseup slides a pie slice out and fires
|
|
1681
|
+
* markerClick.
|
|
1682
|
+
* @param {KeyboardEvent} e
|
|
1683
|
+
*/
|
|
1684
|
+
_fireClick(e) {
|
|
1685
|
+
const el = /** @type {any} */ (this._focusedEl)?.instance
|
|
1686
|
+
const pie = this.ctx.pie
|
|
1687
|
+
if (el) new Graphics(this.w, this.ctx).pathMouseDown(el, e)
|
|
1688
|
+
if (pie && pie.getExpandOffset() > 0) pie.pieClicked(this.dataPointIndex)
|
|
1689
|
+
this.w.globals.tooltip?.markerClick(
|
|
1690
|
+
e,
|
|
1691
|
+
this.seriesIndex,
|
|
1692
|
+
this.dataPointIndex,
|
|
1693
|
+
)
|
|
1767
1694
|
}
|
|
1768
1695
|
|
|
1769
1696
|
// ─── Helpers ──────────────────────────────────────────────────────────────
|
|
@@ -1795,8 +1722,9 @@ export default class KeyboardNavigation {
|
|
|
1795
1722
|
if (type === 'pie' || type === 'donut' || type === 'polarArea') {
|
|
1796
1723
|
return w.seriesData.series.length
|
|
1797
1724
|
}
|
|
1798
|
-
|
|
1799
|
-
|
|
1725
|
+
// A radialBar ring is a series of one value
|
|
1726
|
+
const s = w.seriesData.series[si]
|
|
1727
|
+
return Array.isArray(s) ? s.length : 1
|
|
1800
1728
|
}
|
|
1801
1729
|
|
|
1802
1730
|
_clampCursor() {
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
* pop) are intentionally NOT routed through here: `applyProgressiveReveal`
|
|
15
15
|
* inverts `easeOutCubic` for reveal-sync timing, so those stay fixed. This
|
|
16
16
|
* registry governs the GENERIC runner tweens (data-update value transitions,
|
|
17
|
-
* path morphs, marker animate)
|
|
17
|
+
* path morphs, marker animate) and the gauge needle, which resolves
|
|
18
|
+
* 'easeOutBack' and 'easeOutCubic' by name.
|
|
18
19
|
*
|
|
19
20
|
* @module modules/animations/Easing
|
|
20
21
|
*/
|