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
package/src/charts/Violin.js
CHANGED
|
@@ -4,9 +4,10 @@ import { getChartClass } from '../modules/ChartFactory'
|
|
|
4
4
|
import Fill from '../modules/Fill'
|
|
5
5
|
import Graphics from '../modules/Graphics'
|
|
6
6
|
import Series from '../modules/Series'
|
|
7
|
+
import { datumKey } from '../modules/animations/LengthTransition'
|
|
7
8
|
import Utils from '../utils/Utils'
|
|
8
9
|
import { spline, svgPath } from '../libs/monotone-cubic'
|
|
9
|
-
import { buildJitterGroups, renderJitter } from './common/Jitter'
|
|
10
|
+
import { buildJitterGroups, jitterExtent, renderJitter } from './common/Jitter'
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* ApexCharts Violin Class — draws a density curve per category (the
|
|
@@ -67,6 +68,7 @@ class Violin extends BarBase {
|
|
|
67
68
|
|
|
68
69
|
this.violinOptions = w.config.plotOptions.violin
|
|
69
70
|
this.pointsOptions = this.violinOptions.points
|
|
71
|
+
this.jx = jitterExtent(w.violinData.seriesViolinPoints, w)
|
|
70
72
|
this.boxOptions = this.violinOptions.box || {}
|
|
71
73
|
// Cross-axis signs: which side the density is drawn on (0 = symmetric)
|
|
72
74
|
// and which side the jitter lane sits on (0 = centered on the slot).
|
|
@@ -93,7 +95,7 @@ class Violin extends BarBase {
|
|
|
93
95
|
this.series = series
|
|
94
96
|
this.yRatio = this.coreUtils.getLogYRatios(this.yRatio)
|
|
95
97
|
|
|
96
|
-
this.barHelpers.initVariables(series)
|
|
98
|
+
this.barHelpers.initVariables(series, seriesIndex)
|
|
97
99
|
|
|
98
100
|
const ret = graphics.group({
|
|
99
101
|
class: 'apexcharts-violin-series apexcharts-plot-series',
|
|
@@ -285,6 +287,7 @@ class Violin extends BarBase {
|
|
|
285
287
|
visibleSeries: this.visibleI,
|
|
286
288
|
type: 'violin',
|
|
287
289
|
classes: 'apexcharts-raincloud-box',
|
|
290
|
+
noLabel: true,
|
|
288
291
|
})
|
|
289
292
|
})
|
|
290
293
|
}
|
|
@@ -338,15 +341,18 @@ class Violin extends BarBase {
|
|
|
338
341
|
drawVerticalViolin({ indexes, x, xDivision, barWidth, zeroH }) {
|
|
339
342
|
const w = this.w
|
|
340
343
|
const { realIndex, j, translationsIndex } = indexes
|
|
341
|
-
const yRatio = this.yRatio[translationsIndex]
|
|
344
|
+
const yRatio = this.yRatio[translationsIndex] * (this.isReversed ? -1 : 1)
|
|
342
345
|
|
|
346
|
+
// the group of violins at a numeric x is centred on it, as candles are
|
|
347
|
+
let barXPosition = x + barWidth * this.visibleI
|
|
343
348
|
if (w.axisFlags.isXNumeric) {
|
|
344
|
-
x =
|
|
345
|
-
|
|
346
|
-
barWidth
|
|
349
|
+
;({ x, barXPosition } = this.getBarXForNumericXAxis({
|
|
350
|
+
x,
|
|
351
|
+
barWidth,
|
|
352
|
+
realIndex,
|
|
353
|
+
j,
|
|
354
|
+
}))
|
|
347
355
|
}
|
|
348
|
-
|
|
349
|
-
const barXPosition = x + barWidth * this.visibleI
|
|
350
356
|
const center = barXPosition + barWidth / 2
|
|
351
357
|
const halfExtent = barWidth / 2
|
|
352
358
|
|
|
@@ -383,9 +389,7 @@ class Violin extends BarBase {
|
|
|
383
389
|
if (morphFrom) {
|
|
384
390
|
pathFrom = morphFrom
|
|
385
391
|
} else if (w.globals.previousPaths.length > 0) {
|
|
386
|
-
|
|
387
|
-
// (falls through to the collapsed-centerline enter below).
|
|
388
|
-
pathFrom = this.getPreviousPath(realIndex, j, pathTo)
|
|
392
|
+
pathFrom = this._prevBody(realIndex, j, pathTo)
|
|
389
393
|
}
|
|
390
394
|
if (pathFrom == null) {
|
|
391
395
|
pathFrom = this.buildBodyPath({
|
|
@@ -426,7 +430,7 @@ class Violin extends BarBase {
|
|
|
426
430
|
alongFn,
|
|
427
431
|
vertical: true,
|
|
428
432
|
}),
|
|
429
|
-
alongRepresentative: alongFn(
|
|
433
|
+
alongRepresentative: alongFn(w.seriesData.series[realIndex][j] ?? 0),
|
|
430
434
|
}
|
|
431
435
|
}
|
|
432
436
|
|
|
@@ -434,7 +438,7 @@ class Violin extends BarBase {
|
|
|
434
438
|
drawHorizontalViolin({ indexes, y, yDivision, barHeight, zeroW }) {
|
|
435
439
|
const w = this.w
|
|
436
440
|
const { realIndex, j } = indexes
|
|
437
|
-
const yRatio = this.invertedYRatio
|
|
441
|
+
const yRatio = this.invertedYRatio * (this.isReversed ? -1 : 1)
|
|
438
442
|
|
|
439
443
|
// One band per row on its side, a date or number x included: see
|
|
440
444
|
// Bar.drawBarPaths.
|
|
@@ -475,9 +479,7 @@ class Violin extends BarBase {
|
|
|
475
479
|
if (morphFrom) {
|
|
476
480
|
pathFrom = morphFrom
|
|
477
481
|
} else if (w.globals.previousPaths.length > 0) {
|
|
478
|
-
|
|
479
|
-
// (falls through to the collapsed-centerline enter below).
|
|
480
|
-
pathFrom = this.getPreviousPath(realIndex, j, pathTo)
|
|
482
|
+
pathFrom = this._prevBody(realIndex, j, pathTo)
|
|
481
483
|
}
|
|
482
484
|
if (pathFrom == null) {
|
|
483
485
|
pathFrom = this.buildBodyPath({
|
|
@@ -516,7 +518,7 @@ class Violin extends BarBase {
|
|
|
516
518
|
alongFn,
|
|
517
519
|
vertical: false,
|
|
518
520
|
}),
|
|
519
|
-
alongRepresentative: alongFn(
|
|
521
|
+
alongRepresentative: alongFn(w.seriesData.series[realIndex][j] ?? 0),
|
|
520
522
|
}
|
|
521
523
|
}
|
|
522
524
|
|
|
@@ -631,6 +633,25 @@ class Violin extends BarBase {
|
|
|
631
633
|
)
|
|
632
634
|
}
|
|
633
635
|
|
|
636
|
+
/**
|
|
637
|
+
* The survivor's previous body when it can morph to `pathTo`, else null so
|
|
638
|
+
* the violin regrows from its centreline (a changed density node count
|
|
639
|
+
* cannot tween, and bar corner reconciliation does not apply here).
|
|
640
|
+
*
|
|
641
|
+
* @param {number} realIndex
|
|
642
|
+
* @param {number} j
|
|
643
|
+
* @param {string} pathTo
|
|
644
|
+
* @returns {string | null}
|
|
645
|
+
*/
|
|
646
|
+
_prevBody(realIndex, j, pathTo) {
|
|
647
|
+
const d = this._prevKeyedPaths(realIndex)?.get(
|
|
648
|
+
datumKey(this.w, realIndex, j),
|
|
649
|
+
)?.d
|
|
650
|
+
return d && Violin.pathCommandCount(d) === Violin.pathCommandCount(pathTo)
|
|
651
|
+
? d
|
|
652
|
+
: null
|
|
653
|
+
}
|
|
654
|
+
|
|
634
655
|
/**
|
|
635
656
|
* Build the five-number box sub-paths for one category — the raincloud
|
|
636
657
|
* "umbrella", or a violin box overlay. Two sub-paths so each can carry its
|
|
@@ -698,26 +719,23 @@ class Violin extends BarBase {
|
|
|
698
719
|
const full = build(capHalf, boxHalfPx)
|
|
699
720
|
const collapsed = build(0, 0)
|
|
700
721
|
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
}
|
|
709
|
-
return pathFrom == null ? collapsedFrom : pathFrom
|
|
710
|
-
}
|
|
722
|
+
// The box lane rides on its body's captured entry (see
|
|
723
|
+
// Series.capturePreviousPaths), matched by datum key like the body. An
|
|
724
|
+
// entering box grows out of the collapsed lane.
|
|
725
|
+
const keyed = w.globals.previousPaths.length
|
|
726
|
+
? this._prevKeyedPaths(realIndex)
|
|
727
|
+
: null
|
|
728
|
+
const prevBox = keyed?.get(datumKey(w, realIndex, j))?.box || []
|
|
711
729
|
|
|
712
730
|
return [
|
|
713
731
|
{
|
|
714
732
|
pathTo: full.whiskers,
|
|
715
|
-
pathFrom:
|
|
733
|
+
pathFrom: prevBox[0] || collapsed.whiskers,
|
|
716
734
|
filled: false,
|
|
717
735
|
},
|
|
718
736
|
{
|
|
719
737
|
pathTo: full.box,
|
|
720
|
-
pathFrom:
|
|
738
|
+
pathFrom: prevBox[1] || collapsed.box,
|
|
721
739
|
filled: true,
|
|
722
740
|
},
|
|
723
741
|
]
|
|
@@ -809,8 +827,8 @@ class Violin extends BarBase {
|
|
|
809
827
|
? cloudMaxPx
|
|
810
828
|
: halfExtent
|
|
811
829
|
return buildJitterGroups({
|
|
812
|
-
w: this.w,
|
|
813
830
|
points: this.w.violinData.seriesViolinPoints[realIndex]?.[j],
|
|
831
|
+
extent: /** @type {number[]} */ (this.jx),
|
|
814
832
|
seedA: realIndex,
|
|
815
833
|
seedB: j,
|
|
816
834
|
center: scatterCenter,
|
|
@@ -191,7 +191,7 @@ export function clearBreadcrumb(w) {
|
|
|
191
191
|
* @param {any} w
|
|
192
192
|
* @param {{
|
|
193
193
|
* crumbs: Array<{ label: string, data?: any }>,
|
|
194
|
-
* onNavigate: (index: number, crumb: any) => void,
|
|
194
|
+
* onNavigate: (index: number, crumb: any, e: MouseEvent) => void,
|
|
195
195
|
* ariaLabel?: string,
|
|
196
196
|
* config?: any,
|
|
197
197
|
* compact?: boolean,
|
|
@@ -270,7 +270,7 @@ export function renderBreadcrumb(w, opts) {
|
|
|
270
270
|
text.setAttribute('class', 'apexcharts-breadcrumb-label')
|
|
271
271
|
text.textContent = String(label)
|
|
272
272
|
btn.appendChild(text)
|
|
273
|
-
btn.addEventListener('click', () => opts.onNavigate(i, crumb))
|
|
273
|
+
btn.addEventListener('click', (e) => opts.onNavigate(i, crumb, e))
|
|
274
274
|
nav.appendChild(btn)
|
|
275
275
|
})
|
|
276
276
|
|
|
@@ -12,8 +12,9 @@
|
|
|
12
12
|
* a nested view does not pull the feature in)
|
|
13
13
|
*
|
|
14
14
|
* A node is `{ name, value, color?, _key, children? }`. `_key` is the node's
|
|
15
|
-
* identity across data updates: the path of names,
|
|
16
|
-
* siblings stay distinct
|
|
15
|
+
* identity across data updates: the path of names, each counted among its
|
|
16
|
+
* same-named siblings so duplicates stay distinct while an inserted or removed
|
|
17
|
+
* sibling leaves the others alone. Update animations match on it.
|
|
17
18
|
*
|
|
18
19
|
* `value` is left as authored here; call `fillValues` to roll a missing parent
|
|
19
20
|
* value up from its children.
|
|
@@ -38,6 +39,20 @@ export function drilldownById(w, id) {
|
|
|
38
39
|
return list.find((/** @type {any} */ s) => s && s.id === id)
|
|
39
40
|
}
|
|
40
41
|
|
|
42
|
+
/**
|
|
43
|
+
* One key segment: the name ('/' escaped, it is the separator) prefixed by how
|
|
44
|
+
* many earlier siblings share it.
|
|
45
|
+
* @param {any} name
|
|
46
|
+
* @param {Map<string, number>} seen per sibling list
|
|
47
|
+
* @returns {string}
|
|
48
|
+
*/
|
|
49
|
+
function segment(name, seen) {
|
|
50
|
+
const n = String(name).replace(/\//g, '%2F')
|
|
51
|
+
const o = (seen.get(n) ?? -1) + 1
|
|
52
|
+
seen.set(n, o)
|
|
53
|
+
return `${o}:${n}`
|
|
54
|
+
}
|
|
55
|
+
|
|
41
56
|
/**
|
|
42
57
|
* Resolve one datum (and everything under it) into a node.
|
|
43
58
|
*
|
|
@@ -56,6 +71,7 @@ export function drilldownById(w, id) {
|
|
|
56
71
|
* The treemap turns this off unless asked: there, a `drilldown` id has always
|
|
57
72
|
* meant "descend on click" via the drilldown feature, and silently rendering
|
|
58
73
|
* those levels nested instead would change what existing charts draw.
|
|
74
|
+
* @param {Map<string, number>} [seen] names already keyed among the siblings
|
|
59
75
|
* @returns {any}
|
|
60
76
|
*/
|
|
61
77
|
export function toNode(
|
|
@@ -66,28 +82,30 @@ export function toNode(
|
|
|
66
82
|
parentKey,
|
|
67
83
|
seenIds = null,
|
|
68
84
|
opts = {},
|
|
85
|
+
seen = new Map(),
|
|
69
86
|
) {
|
|
70
87
|
const isObj = d && typeof d === 'object'
|
|
71
88
|
const name = isObj ? (d.x ?? d.name ?? '') : ''
|
|
72
|
-
|
|
89
|
+
// null / '' is a missing value (rolled up by fillValues), not a zero.
|
|
90
|
+
const raw = isObj ? (d.y ?? d.value) : d
|
|
91
|
+
const value = raw == null || raw === '' ? NaN : Number(raw)
|
|
73
92
|
/** @type {any} */
|
|
74
93
|
const node = {
|
|
75
94
|
name: String(name),
|
|
76
95
|
value: isNaN(value) ? null : value,
|
|
77
96
|
color: isObj && d.color ? d.color : undefined,
|
|
78
|
-
|
|
79
|
-
// siblings stay distinct). Update animations morph matched keys in place.
|
|
80
|
-
_key: `${parentKey}/${i}:${name}`,
|
|
97
|
+
_key: `${parentKey}/${segment(name, seen)}`,
|
|
81
98
|
}
|
|
82
99
|
if (paletteFromParent && !node.color) {
|
|
83
100
|
node.color = paletteFromParent[i % paletteFromParent.length]
|
|
84
101
|
}
|
|
85
102
|
if (opts.keepDatum) node._datum = d
|
|
86
103
|
|
|
104
|
+
const kids = new Map()
|
|
87
105
|
if (isObj && Array.isArray(d.children) && d.children.length) {
|
|
88
106
|
node.children = d.children.map(
|
|
89
107
|
(/** @type {any} */ c, /** @type {number} */ j) =>
|
|
90
|
-
toNode(w, c, j, null, node._key, seenIds, opts),
|
|
108
|
+
toNode(w, c, j, null, node._key, seenIds, opts, kids),
|
|
91
109
|
)
|
|
92
110
|
} else if (isObj && d.drilldown != null && opts.expandDrilldown !== false) {
|
|
93
111
|
// Drilldown ids resolve indirectly, so a self- or mutually-referential id
|
|
@@ -102,7 +120,7 @@ export function toNode(
|
|
|
102
120
|
const palette = Array.isArray(dd.colors) ? dd.colors : null
|
|
103
121
|
node.children = dd.data.map(
|
|
104
122
|
(/** @type {any} */ c, /** @type {number} */ j) =>
|
|
105
|
-
toNode(w, c, j, palette, node._key, nextSeen, opts),
|
|
123
|
+
toNode(w, c, j, palette, node._key, nextSeen, opts, kids),
|
|
106
124
|
)
|
|
107
125
|
}
|
|
108
126
|
}
|
|
@@ -123,8 +141,9 @@ export function buildHierarchy(w, opts = {}) {
|
|
|
123
141
|
const first = cfgSeries && cfgSeries[0]
|
|
124
142
|
const data = first && Array.isArray(first.data) ? first.data : cfgSeries
|
|
125
143
|
if (!Array.isArray(data)) return []
|
|
144
|
+
const seen = new Map()
|
|
126
145
|
return data.map((/** @type {any} */ d, /** @type {number} */ i) =>
|
|
127
|
-
toNode(w, d, i, null, '', null, opts),
|
|
146
|
+
toNode(w, d, i, null, '', null, opts, seen),
|
|
128
147
|
)
|
|
129
148
|
}
|
|
130
149
|
|
|
@@ -142,9 +161,11 @@ export function buildHierarchy(w, opts = {}) {
|
|
|
142
161
|
export function buildSeriesRoots(w, series, opts = {}) {
|
|
143
162
|
const cfgSeries = /** @type {any} */ (series || w.config.series)
|
|
144
163
|
if (!Array.isArray(cfgSeries)) return []
|
|
164
|
+
const seen = new Map()
|
|
145
165
|
return cfgSeries.map((/** @type {any} */ s, /** @type {number} */ i) => {
|
|
146
166
|
const data = s && Array.isArray(s.data) ? s.data : []
|
|
147
|
-
const key =
|
|
167
|
+
const key = segment(s?.name ?? '', seen)
|
|
168
|
+
const kids = new Map()
|
|
148
169
|
/** @type {any} */
|
|
149
170
|
const root = {
|
|
150
171
|
name: String(s?.name ?? ''),
|
|
@@ -153,7 +174,7 @@ export function buildSeriesRoots(w, series, opts = {}) {
|
|
|
153
174
|
_key: key,
|
|
154
175
|
_seriesIndex: i,
|
|
155
176
|
children: data.map((/** @type {any} */ d, /** @type {number} */ j) =>
|
|
156
|
-
toNode(w, d, j, null, key, null, opts),
|
|
177
|
+
toNode(w, d, j, null, key, null, opts, kids),
|
|
157
178
|
),
|
|
158
179
|
}
|
|
159
180
|
return root
|
|
@@ -14,6 +14,28 @@ import Utils from '../../utils/Utils'
|
|
|
14
14
|
* @module common/Jitter
|
|
15
15
|
**/
|
|
16
16
|
|
|
17
|
+
/**
|
|
18
|
+
* The value range of the drawn series' observations, for a colorScale ramp.
|
|
19
|
+
* Once per draw; stale slots past the series count and non-numbers are skipped.
|
|
20
|
+
* @param {any[]} pool per-series, per-datum observations
|
|
21
|
+
* @param {any} w
|
|
22
|
+
* @returns {number[]}
|
|
23
|
+
*/
|
|
24
|
+
export function jitterExtent(pool, w) {
|
|
25
|
+
let lo = Infinity
|
|
26
|
+
let hi = -Infinity
|
|
27
|
+
pool
|
|
28
|
+
.slice(0, w.seriesData.series.length)
|
|
29
|
+
.flat(2)
|
|
30
|
+
.forEach((v) => {
|
|
31
|
+
if (v === +v) {
|
|
32
|
+
if (v < lo) lo = v
|
|
33
|
+
if (v > hi) hi = v
|
|
34
|
+
}
|
|
35
|
+
})
|
|
36
|
+
return [lo, hi]
|
|
37
|
+
}
|
|
38
|
+
|
|
17
39
|
/**
|
|
18
40
|
* Build the jitter sub-path groups for ONE category. Returns `[]` when points
|
|
19
41
|
* are hidden/absent. Normally one group (single dot colour); with
|
|
@@ -22,8 +44,8 @@ import Utils from '../../utils/Utils'
|
|
|
22
44
|
* caller's resolved default colour.
|
|
23
45
|
*
|
|
24
46
|
* @param {{
|
|
25
|
-
* w: any,
|
|
26
47
|
* points: number[] | undefined,
|
|
48
|
+
* extent: number[],
|
|
27
49
|
* seedA: number,
|
|
28
50
|
* seedB: number,
|
|
29
51
|
* center: number,
|
|
@@ -37,8 +59,8 @@ import Utils from '../../utils/Utils'
|
|
|
37
59
|
* @returns {{fill:string|null, d:string}[]}
|
|
38
60
|
*/
|
|
39
61
|
export function buildJitterGroups({
|
|
40
|
-
w,
|
|
41
62
|
points,
|
|
63
|
+
extent,
|
|
42
64
|
seedA,
|
|
43
65
|
seedB,
|
|
44
66
|
center,
|
|
@@ -67,8 +89,10 @@ export function buildJitterGroups({
|
|
|
67
89
|
const useScale =
|
|
68
90
|
scale && Array.isArray(scale.colors) && scale.colors.length > 0
|
|
69
91
|
const steps = useScale ? Math.max(2, scale.steps || 24) : 1
|
|
70
|
-
|
|
71
|
-
|
|
92
|
+
// The ramp spans the observations (jitterExtent) unless colorScale says
|
|
93
|
+
// otherwise: an axis's nice scale overshoots them, so the ends never showed.
|
|
94
|
+
const sMin = scale?.min ?? extent[0]
|
|
95
|
+
const sMax = scale?.max ?? extent[1]
|
|
72
96
|
const span = sMax - sMin || 1
|
|
73
97
|
/** @type {string[]} */
|
|
74
98
|
const buckets = useScale ? new Array(steps).fill('') : ['']
|
|
@@ -206,13 +230,14 @@ export function renderJitter({
|
|
|
206
230
|
/**
|
|
207
231
|
* Darken a colour toward black by `amount` (0 = unchanged, 1 = black),
|
|
208
232
|
* returning an `rgb(...)` string. Falls back to the input when it can't be
|
|
209
|
-
* parsed
|
|
210
|
-
* @param {string} color
|
|
233
|
+
* parsed (hex, rgb()/rgba(), or a named colour the browser resolves).
|
|
234
|
+
* @param {string} color
|
|
211
235
|
* @param {number} amount 0..1
|
|
212
236
|
* @returns {string}
|
|
213
237
|
*/
|
|
214
238
|
export function darkenColor(color, amount) {
|
|
215
|
-
const rgb =
|
|
239
|
+
const rgb =
|
|
240
|
+
Utils.parseColor(color) || Utils.parseColor(Utils.resolveColor(color))
|
|
216
241
|
if (!rgb) return color
|
|
217
242
|
const f = Math.max(0, 1 - amount)
|
|
218
243
|
return `rgb(${Math.round(rgb[0] * f)},${Math.round(rgb[1] * f)},${Math.round(rgb[2] * f)})`
|