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/modules/CoreUtils.js
CHANGED
|
@@ -325,28 +325,6 @@ class CoreUtils {
|
|
|
325
325
|
// for multi axis charts.
|
|
326
326
|
gl.seriesYAxisMap = axisSeriesMap.map((x) => x)
|
|
327
327
|
gl.seriesYAxisReverseMap = seriesYAxisReverseMap.map((x) => x)
|
|
328
|
-
// Set default series group names
|
|
329
|
-
/**
|
|
330
|
-
* @param {Record<string, any>} axisSeries
|
|
331
|
-
* @param {number} ai
|
|
332
|
-
*/
|
|
333
|
-
gl.seriesYAxisMap.forEach((axisSeries, ai) => {
|
|
334
|
-
/**
|
|
335
|
-
* @param {number} si
|
|
336
|
-
*/
|
|
337
|
-
axisSeries.forEach((si) => {
|
|
338
|
-
// series may be bare until loaded in realtime
|
|
339
|
-
if (
|
|
340
|
-
/** @type {any} */ (cnf.series[si]) &&
|
|
341
|
-
/** @type {any} */ (cnf.series[si]).group === undefined
|
|
342
|
-
) {
|
|
343
|
-
// A series with no group defined will be named after the axis that
|
|
344
|
-
// referenced it and thus form a group automatically.
|
|
345
|
-
const _series = /** @type {any} */ (cnf.series[si])
|
|
346
|
-
_series.group = 'apexcharts-axis-'.concat(ai.toString())
|
|
347
|
-
}
|
|
348
|
-
})
|
|
349
|
-
})
|
|
350
328
|
}
|
|
351
329
|
|
|
352
330
|
/**
|
|
@@ -552,18 +530,20 @@ class CoreUtils {
|
|
|
552
530
|
const stackedTotals = excluded.length
|
|
553
531
|
? this.getStackedSeriesTotals(excluded)
|
|
554
532
|
: w.seriesData.stackedSeriesTotals
|
|
555
|
-
//
|
|
556
|
-
// share of the stack at its own x
|
|
557
|
-
const sx =
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
/** @
|
|
533
|
+
// Bars and areas on a numeric axis stack by x, so each point takes its
|
|
534
|
+
// share of the stack at its own x.
|
|
535
|
+
const sx = w.axisFlags.isXNumeric && w.seriesData.seriesX
|
|
536
|
+
// Each series group is its own stack, so it normalises to its own total.
|
|
537
|
+
const gi = w.labelData.seriesGroupIndex
|
|
538
|
+
const byKey = sx || w.labelData.seriesGroups.length > 1
|
|
539
|
+
/** @param {number} i @param {number} j */
|
|
540
|
+
const key = (i, j) => gi[i] + ' ' + (sx ? sx[i][j] : j)
|
|
541
|
+
/** @type {Map<string, number>} */
|
|
562
542
|
const byX = new Map()
|
|
563
|
-
if (
|
|
543
|
+
if (byKey) {
|
|
564
544
|
w.seriesData.series.forEach((s, i) => {
|
|
565
545
|
if (excluded.indexOf(i) < 0) {
|
|
566
|
-
s.forEach((v, j) => byX.set(
|
|
546
|
+
s.forEach((v, j) => byX.set(key(i, j), (byX.get(key(i, j)) || 0) + v))
|
|
567
547
|
}
|
|
568
548
|
})
|
|
569
549
|
}
|
|
@@ -576,7 +556,7 @@ class CoreUtils {
|
|
|
576
556
|
const seriesPercent = []
|
|
577
557
|
if (Array.isArray(ser)) {
|
|
578
558
|
for (let j = 0; j < ser.length; j++) {
|
|
579
|
-
const total =
|
|
559
|
+
const total = byKey ? byX.get(key(i, j)) : stackedTotals[j]
|
|
580
560
|
let percent = 0
|
|
581
561
|
if (total) {
|
|
582
562
|
percent = (100 * ser[j]) / total
|
|
@@ -638,11 +618,9 @@ class CoreUtils {
|
|
|
638
618
|
zRatio = 1
|
|
639
619
|
}
|
|
640
620
|
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
_hasNegsGl.hasNegs = true
|
|
645
|
-
}
|
|
621
|
+
// Negative numbers present in series; reassigned so an update clears it
|
|
622
|
+
const _hasNegsGl = /** @type {any} */ (gl)
|
|
623
|
+
_hasNegsGl.hasNegs = gl.minY !== Number.MIN_VALUE && Math.abs(gl.minY) !== 0
|
|
646
624
|
|
|
647
625
|
// Check we have a map as series may still to be added/updated.
|
|
648
626
|
if (w.globals.seriesYAxisReverseMap.length > 0) {
|
|
@@ -860,7 +838,7 @@ class CoreUtils {
|
|
|
860
838
|
// other series of the same type on the same axis.
|
|
861
839
|
/**
|
|
862
840
|
* @param {Record<string, any>} typeSeries
|
|
863
|
-
* @param {
|
|
841
|
+
* @param {number[]} typeGroups
|
|
864
842
|
* @param {string} type
|
|
865
843
|
* @param {string} chartClass
|
|
866
844
|
*/
|
|
@@ -871,7 +849,7 @@ class CoreUtils {
|
|
|
871
849
|
if (typeSeries.series.length > 0) {
|
|
872
850
|
// draw each group separately
|
|
873
851
|
/**
|
|
874
|
-
* @param {
|
|
852
|
+
* @param {number} gn
|
|
875
853
|
*/
|
|
876
854
|
typeGroups.forEach((/** @type {any} */ gn) => {
|
|
877
855
|
/** @type {any[]} */
|
|
@@ -883,9 +861,7 @@ class CoreUtils {
|
|
|
883
861
|
* @param {number} ii
|
|
884
862
|
*/
|
|
885
863
|
typeSeries.i.forEach((/** @type {any} */ i, /** @type {any} */ ii) => {
|
|
886
|
-
if (
|
|
887
|
-
/** @type {Record<string,any>} */ (w.config.series[i]).group === gn
|
|
888
|
-
) {
|
|
864
|
+
if (w.labelData.seriesGroupIndex[i] === gn) {
|
|
889
865
|
gs.push(typeSeries.series[ii])
|
|
890
866
|
gi.push(i)
|
|
891
867
|
}
|
package/src/modules/Data.js
CHANGED
|
@@ -97,7 +97,7 @@ function isRawSample(d, name, flatY) {
|
|
|
97
97
|
function subtreeTotal(d) {
|
|
98
98
|
if (!d || typeof d !== 'object') return Utils.parseNumber(d) || 0
|
|
99
99
|
const v = d.y ?? d.value
|
|
100
|
-
if (v != null) return Utils.parseNumber(v) || 0
|
|
100
|
+
if (v != null && v !== '') return Utils.parseNumber(v) || 0
|
|
101
101
|
if (!Array.isArray(d.children)) return 0
|
|
102
102
|
return d.children.reduce(
|
|
103
103
|
(/** @type {number} */ s, /** @type {any} */ c) =>
|
|
@@ -1038,22 +1038,21 @@ export default class Data {
|
|
|
1038
1038
|
})
|
|
1039
1039
|
|
|
1040
1040
|
this.coreUtils.setSeriesYAxisMappings()
|
|
1041
|
-
//
|
|
1042
|
-
//
|
|
1043
|
-
//
|
|
1044
|
-
|
|
1041
|
+
// A series with no user defined group is grouped by the yaxis that
|
|
1042
|
+
// references it, so all series of an axis form one group. The name is
|
|
1043
|
+
// derived here, never written back onto the caller's series objects.
|
|
1044
|
+
const rev = this.w.globals.seriesYAxisReverseMap
|
|
1045
|
+
const keys = cnf.series.map(
|
|
1046
|
+
(/** @type {any} */ s, /** @type {number} */ i) =>
|
|
1047
|
+
s.group ?? 'apexcharts-axis-' + rev[i],
|
|
1048
|
+
)
|
|
1045
1049
|
/** @type {any[]} */
|
|
1046
1050
|
const buckets = []
|
|
1047
|
-
|
|
1048
|
-
* @param {Record<string, any>} s
|
|
1049
|
-
*/
|
|
1050
|
-
const groups = [
|
|
1051
|
-
...new Set(cnf.series.map((/** @type {any} */ s) => s.group)),
|
|
1052
|
-
]
|
|
1051
|
+
const groups = [...new Set(keys)]
|
|
1053
1052
|
// Membership is recorded by index: groups may reuse series names.
|
|
1054
|
-
this.w.labelData.seriesGroupIndex =
|
|
1055
|
-
(/** @type {any} */
|
|
1056
|
-
const index = groups.indexOf(
|
|
1053
|
+
this.w.labelData.seriesGroupIndex = keys.map(
|
|
1054
|
+
(/** @type {any} */ k, /** @type {number} */ i) => {
|
|
1055
|
+
const index = groups.indexOf(k)
|
|
1057
1056
|
if (!buckets[index]) buckets[index] = []
|
|
1058
1057
|
|
|
1059
1058
|
buckets[index].push(this.w.seriesData.seriesNames[i])
|
|
@@ -1477,19 +1476,19 @@ export default class Data {
|
|
|
1477
1476
|
if (rootColors && x !== undefined) {
|
|
1478
1477
|
rootColors[labels.length] = dataPoint.color
|
|
1479
1478
|
}
|
|
1480
|
-
if (x !== undefined &&
|
|
1481
|
-
labels.push(String(x))
|
|
1482
|
-
values.push(Utils.parseNumber(y))
|
|
1483
|
-
} else if (x !== undefined && Array.isArray(dataPoint.children)) {
|
|
1479
|
+
if (x !== undefined && Array.isArray(dataPoint.children)) {
|
|
1484
1480
|
// A partition chart (sunburst, icicle) may leave a branch's own
|
|
1485
|
-
// value out and let it be the sum of its children.
|
|
1486
|
-
// resolver does exactly that in `fillValues`, but
|
|
1487
|
-
// after this parse, and dropping the datum here left
|
|
1488
|
-
// an EMPTY series, which makes the renderer bail
|
|
1489
|
-
// builds the tree: a blank chart and a warning about
|
|
1490
|
-
// So roll the subtree up now, which is the same number.
|
|
1481
|
+
// value out (or null / '') and let it be the sum of its children.
|
|
1482
|
+
// The hierarchy resolver does exactly that in `fillValues`, but
|
|
1483
|
+
// that runs long after this parse, and dropping the datum here left
|
|
1484
|
+
// the chart with an EMPTY series, which makes the renderer bail
|
|
1485
|
+
// before it ever builds the tree: a blank chart and a warning about
|
|
1486
|
+
// pie data. So roll the subtree up now, which is the same number.
|
|
1491
1487
|
labels.push(String(x))
|
|
1492
1488
|
values.push(subtreeTotal(dataPoint))
|
|
1489
|
+
} else if (x !== undefined && y !== undefined) {
|
|
1490
|
+
labels.push(String(x))
|
|
1491
|
+
values.push(Utils.parseNumber(y))
|
|
1493
1492
|
} else {
|
|
1494
1493
|
console.warn(
|
|
1495
1494
|
'ApexCharts: Invalid data point format for pie chart. Expected {x, y} format:',
|
|
@@ -118,6 +118,12 @@ class DataLabels {
|
|
|
118
118
|
drawnextLabel = true
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
+
// Record the drawn RECT's index, not the point's: a rangeArea series
|
|
122
|
+
// records two rects per point (its start labels, then its end labels).
|
|
123
|
+
if (drawnextLabel) {
|
|
124
|
+
;(w.globals.lastDrawnDataLabelsIndexes[i] ||= []).push(len + 1)
|
|
125
|
+
}
|
|
126
|
+
|
|
121
127
|
return {
|
|
122
128
|
x,
|
|
123
129
|
y,
|
|
@@ -474,12 +480,6 @@ class DataLabels {
|
|
|
474
480
|
// Progressive reveal: data labels fade in alongside their markers as the
|
|
475
481
|
// line's pen-stroke reaches them. Uses the corrected x (post-offset).
|
|
476
482
|
if (penDrawn(w, i)) applyProgressiveReveal(dataLabelText, x, w)
|
|
477
|
-
|
|
478
|
-
if (typeof w.globals.lastDrawnDataLabelsIndexes[i] === 'undefined') {
|
|
479
|
-
w.globals.lastDrawnDataLabelsIndexes[i] = []
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
w.globals.lastDrawnDataLabelsIndexes[i].push(j)
|
|
483
483
|
}
|
|
484
484
|
|
|
485
485
|
return dataLabelText
|
package/src/modules/Graphics.js
CHANGED
|
@@ -457,6 +457,23 @@ class Graphics {
|
|
|
457
457
|
return arc
|
|
458
458
|
}
|
|
459
459
|
|
|
460
|
+
/**
|
|
461
|
+
* stroke.dashArray of a series, shared with the canvas renderer. A plugin
|
|
462
|
+
* may have claimed it: resolved here rather than written into the config,
|
|
463
|
+
* so the caller's own dashing is untouched and there is nothing to restore
|
|
464
|
+
* when the claim goes. See weave/Claims.
|
|
465
|
+
* @param {number} realIndex
|
|
466
|
+
*/
|
|
467
|
+
seriesDash(realIndex) {
|
|
468
|
+
const d = this.w.config.stroke.dashArray
|
|
469
|
+
return resolveClaimed(
|
|
470
|
+
this.w,
|
|
471
|
+
'stroke.dashArray',
|
|
472
|
+
realIndex,
|
|
473
|
+
Array.isArray(d) ? d[realIndex] : d,
|
|
474
|
+
)
|
|
475
|
+
}
|
|
476
|
+
|
|
460
477
|
/**
|
|
461
478
|
* @memberof Graphics
|
|
462
479
|
* @param {Record<string, any>} opts
|
|
@@ -610,23 +627,6 @@ class Graphics {
|
|
|
610
627
|
}
|
|
611
628
|
}
|
|
612
629
|
|
|
613
|
-
const strokeDashArrayOpt = w.config.stroke.dashArray
|
|
614
|
-
let strokeDashArray = 0
|
|
615
|
-
if (Array.isArray(strokeDashArrayOpt)) {
|
|
616
|
-
strokeDashArray = strokeDashArrayOpt[realIndex]
|
|
617
|
-
} else {
|
|
618
|
-
strokeDashArray = w.config.stroke.dashArray
|
|
619
|
-
}
|
|
620
|
-
// A plugin may have claimed this series' dash. Resolved here rather than
|
|
621
|
-
// written into the config above, so the caller's own dashing is untouched
|
|
622
|
-
// and there is nothing to restore when the claim goes. See weave/Claims.
|
|
623
|
-
strokeDashArray = resolveClaimed(
|
|
624
|
-
w,
|
|
625
|
-
'stroke.dashArray',
|
|
626
|
-
realIndex,
|
|
627
|
-
strokeDashArray,
|
|
628
|
-
)
|
|
629
|
-
|
|
630
630
|
const el = this.drawPath({
|
|
631
631
|
d,
|
|
632
632
|
stroke,
|
|
@@ -635,7 +635,7 @@ class Graphics {
|
|
|
635
635
|
fillOpacity: 1,
|
|
636
636
|
classes: className,
|
|
637
637
|
strokeLinecap,
|
|
638
|
-
strokeDashArray,
|
|
638
|
+
strokeDashArray: this.seriesDash(realIndex),
|
|
639
639
|
})
|
|
640
640
|
|
|
641
641
|
el.attr('index', realIndex)
|
|
@@ -935,13 +935,21 @@ class Graphics {
|
|
|
935
935
|
return g
|
|
936
936
|
}
|
|
937
937
|
|
|
938
|
-
/** @param {{ text: any, maxWidth: any, fontSize: any, fontFamily?: any }} opts */
|
|
939
|
-
getTextBasedOnMaxWidth({ text, maxWidth, fontSize, fontFamily }) {
|
|
940
|
-
const tRects = this.getTextRects(
|
|
941
|
-
|
|
942
|
-
|
|
938
|
+
/** @param {{ text: any, maxWidth: any, fontSize: any, fontFamily?: any, fontWeight?: any }} opts */
|
|
939
|
+
getTextBasedOnMaxWidth({ text, maxWidth, fontSize, fontFamily, fontWeight }) {
|
|
940
|
+
const tRects = this.getTextRects(
|
|
941
|
+
text,
|
|
942
|
+
fontSize,
|
|
943
|
+
fontFamily,
|
|
944
|
+
'',
|
|
945
|
+
true,
|
|
946
|
+
fontWeight,
|
|
947
|
+
)
|
|
948
|
+
// Characters that fit, less the ellipsis. Below zero not even '...'
|
|
949
|
+
// fits (and a negative slice end would keep nearly the whole text).
|
|
950
|
+
const n = Math.floor(maxWidth / (tRects.width / text.length)) - 3
|
|
943
951
|
if (maxWidth < tRects.width) {
|
|
944
|
-
return text.slice(0,
|
|
952
|
+
return n < 0 ? '' : text.slice(0, n) + '...'
|
|
945
953
|
}
|
|
946
954
|
return text
|
|
947
955
|
}
|
|
@@ -984,6 +992,7 @@ class Graphics {
|
|
|
984
992
|
maxWidth,
|
|
985
993
|
fontSize,
|
|
986
994
|
fontFamily,
|
|
995
|
+
fontWeight,
|
|
987
996
|
}
|
|
988
997
|
let elText
|
|
989
998
|
if (Array.isArray(text)) {
|
|
@@ -1226,7 +1235,12 @@ class Graphics {
|
|
|
1226
1235
|
if (w.config.states.hover.filter.type !== 'none') {
|
|
1227
1236
|
if (!w.interact.isTouchDevice) {
|
|
1228
1237
|
const hoverFilter = w.config.states.hover.filter
|
|
1229
|
-
filters.applyFilter(
|
|
1238
|
+
filters.applyFilter(
|
|
1239
|
+
path,
|
|
1240
|
+
Filters.isSliceChart(w) ? j : i,
|
|
1241
|
+
hoverFilter.type,
|
|
1242
|
+
hoverFilter.value,
|
|
1243
|
+
)
|
|
1230
1244
|
}
|
|
1231
1245
|
}
|
|
1232
1246
|
}
|
|
@@ -1267,35 +1281,29 @@ class Graphics {
|
|
|
1267
1281
|
if (Filters.hoverOutlineOwnsHoverState(w)) return
|
|
1268
1282
|
|
|
1269
1283
|
if (w.config.states.hover.filter.type !== 'none') {
|
|
1270
|
-
filters.getDefaultFilter(path, i)
|
|
1284
|
+
filters.getDefaultFilter(path, Filters.isSliceChart(w) ? j : i)
|
|
1271
1285
|
}
|
|
1272
1286
|
}
|
|
1273
1287
|
|
|
1274
1288
|
/**
|
|
1275
1289
|
* Clear every selected data point (single-select mode): reset the selection
|
|
1276
|
-
* array and restore the default filter on
|
|
1277
|
-
*
|
|
1278
|
-
*
|
|
1279
|
-
* @param {any} filters
|
|
1290
|
+
* array and restore the default filter on each selected node, with its own
|
|
1291
|
+
* series index (dropShadow.enabledOnSeries is per series; a pie slice's
|
|
1292
|
+
* shadow is per slice, j).
|
|
1293
|
+
* @param {any} filters
|
|
1280
1294
|
*/
|
|
1281
|
-
_clearAllDataPointSelections(filters
|
|
1295
|
+
_clearAllDataPointSelections(filters) {
|
|
1282
1296
|
const w = this.w
|
|
1283
1297
|
w.interact.selectedDataPoints = []
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
)
|
|
1287
|
-
const elCircles = w.dom.Paper.find(
|
|
1288
|
-
'.apexcharts-series circle:not(.apexcharts-decoration-element), .apexcharts-series rect:not(.apexcharts-decoration-element)',
|
|
1289
|
-
)
|
|
1290
|
-
/** @param {any[]} els */
|
|
1291
|
-
const deSelect = (els) => {
|
|
1292
|
-
Array.prototype.forEach.call(els, (/** @type {any} */ el) => {
|
|
1298
|
+
w.dom.Paper.find('.apexcharts-series [selected="true"]').forEach(
|
|
1299
|
+
(/** @type {any} */ el) => {
|
|
1293
1300
|
el.node.setAttribute('selected', 'false')
|
|
1294
|
-
filters.getDefaultFilter(
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1301
|
+
filters.getDefaultFilter(
|
|
1302
|
+
el,
|
|
1303
|
+
+el.node.getAttribute(Filters.isSliceChart(w) ? 'j' : 'index'),
|
|
1304
|
+
)
|
|
1305
|
+
},
|
|
1306
|
+
)
|
|
1299
1307
|
}
|
|
1300
1308
|
|
|
1301
1309
|
/**
|
|
@@ -1321,7 +1329,7 @@ class Graphics {
|
|
|
1321
1329
|
!w.config.states.active.allowMultipleDataPointsSelection &&
|
|
1322
1330
|
w.interact.selectedDataPoints.length > 0
|
|
1323
1331
|
) {
|
|
1324
|
-
this._clearAllDataPointSelections(filters
|
|
1332
|
+
this._clearAllDataPointSelections(filters)
|
|
1325
1333
|
}
|
|
1326
1334
|
|
|
1327
1335
|
path.node.setAttribute('selected', 'true')
|
|
@@ -1350,11 +1358,11 @@ class Graphics {
|
|
|
1350
1358
|
|
|
1351
1359
|
if (selected === 'true') {
|
|
1352
1360
|
const activeFilter = w.config.states.active.filter
|
|
1353
|
-
if (activeFilter !== 'none') {
|
|
1361
|
+
if (activeFilter.type !== 'none') {
|
|
1354
1362
|
filters.applyFilter(path, i, activeFilter.type, activeFilter.value)
|
|
1355
1363
|
} else {
|
|
1356
1364
|
// Reapply the hover filter in case it was removed by `deselect`when there is no active filter and it is not a touch device
|
|
1357
|
-
if (w.config.states.hover.filter !== 'none') {
|
|
1365
|
+
if (w.config.states.hover.filter.type !== 'none') {
|
|
1358
1366
|
if (!w.interact.isTouchDevice) {
|
|
1359
1367
|
const hoverFilter = w.config.states.hover.filter
|
|
1360
1368
|
filters.applyFilter(path, i, hoverFilter.type, hoverFilter.value)
|
|
@@ -1404,7 +1412,12 @@ class Graphics {
|
|
|
1404
1412
|
|
|
1405
1413
|
if (!crossfilterClick) {
|
|
1406
1414
|
const selected = this._togglePointSelection(path, filters, i, j)
|
|
1407
|
-
this._applyPointSelectionFilter(
|
|
1415
|
+
this._applyPointSelectionFilter(
|
|
1416
|
+
path,
|
|
1417
|
+
filters,
|
|
1418
|
+
Filters.isSliceChart(w) ? j : i,
|
|
1419
|
+
selected,
|
|
1420
|
+
)
|
|
1408
1421
|
}
|
|
1409
1422
|
|
|
1410
1423
|
if (typeof w.config.chart.events.dataPointSelection === 'function') {
|
package/src/modules/Markers.js
CHANGED
|
@@ -143,8 +143,10 @@ export default class Markers {
|
|
|
143
143
|
setGlobalMarkerSize() {
|
|
144
144
|
const w = this.w
|
|
145
145
|
|
|
146
|
+
// A copy: the padding below must not grow (or throw on a frozen) caller
|
|
147
|
+
// array.
|
|
146
148
|
w.globals.markers.size = Array.isArray(w.config.markers.size)
|
|
147
|
-
? w.config.markers.size
|
|
149
|
+
? w.config.markers.size.slice()
|
|
148
150
|
: [w.config.markers.size]
|
|
149
151
|
|
|
150
152
|
if (w.globals.markers.size.length > 0) {
|
package/src/modules/Range.js
CHANGED
|
@@ -634,42 +634,38 @@ class Range {
|
|
|
634
634
|
gl.barGroups = []
|
|
635
635
|
gl.lineGroups = []
|
|
636
636
|
gl.areaGroups = []
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
cnf.series.forEach((s) => {
|
|
641
|
-
const _s = /** @type {any} */ (s)
|
|
642
|
-
const type = _s.type || cnf.chart.type
|
|
643
|
-
switch (type) {
|
|
637
|
+
cnf.series.forEach((s, i) => {
|
|
638
|
+
const g = this.w.labelData.seriesGroupIndex[i]
|
|
639
|
+
switch (/** @type {any} */ (s).type || cnf.chart.type) {
|
|
644
640
|
case 'bar':
|
|
645
641
|
case 'column':
|
|
646
|
-
gl.barGroups.push(
|
|
642
|
+
gl.barGroups.push(g)
|
|
647
643
|
break
|
|
648
644
|
case 'line':
|
|
649
|
-
gl.lineGroups.push(
|
|
645
|
+
gl.lineGroups.push(g)
|
|
650
646
|
break
|
|
651
647
|
case 'area':
|
|
652
|
-
gl.areaGroups.push(
|
|
648
|
+
gl.areaGroups.push(g)
|
|
653
649
|
break
|
|
654
650
|
}
|
|
655
651
|
})
|
|
656
652
|
// Uniquify the group names in each stackable chart type.
|
|
657
653
|
/**
|
|
658
|
-
* @param {
|
|
654
|
+
* @param {number} v
|
|
659
655
|
* @param {number} i
|
|
660
|
-
* @param {
|
|
656
|
+
* @param {number[]} a
|
|
661
657
|
*/
|
|
662
658
|
gl.barGroups = gl.barGroups.filter((v, i, a) => a.indexOf(v) === i)
|
|
663
659
|
/**
|
|
664
|
-
* @param {
|
|
660
|
+
* @param {number} v
|
|
665
661
|
* @param {number} i
|
|
666
|
-
* @param {
|
|
662
|
+
* @param {number[]} a
|
|
667
663
|
*/
|
|
668
664
|
gl.lineGroups = gl.lineGroups.filter((v, i, a) => a.indexOf(v) === i)
|
|
669
665
|
/**
|
|
670
|
-
* @param {
|
|
666
|
+
* @param {number} v
|
|
671
667
|
* @param {number} i
|
|
672
|
-
* @param {
|
|
668
|
+
* @param {number[]} a
|
|
673
669
|
*/
|
|
674
670
|
gl.areaGroups = gl.areaGroups.filter((v, i, a) => a.indexOf(v) === i)
|
|
675
671
|
|
|
@@ -796,9 +792,10 @@ class Range {
|
|
|
796
792
|
ticks = gl.dataPoints - 1
|
|
797
793
|
}
|
|
798
794
|
} else if (cnf.xaxis.tickAmount === 'dataPoints') {
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
795
|
+
ticks = Math.max(
|
|
796
|
+
1,
|
|
797
|
+
(this.w.seriesData.series[gl.maxValsInArrayIndex] || []).length - 1,
|
|
798
|
+
)
|
|
802
799
|
if (this.w.axisFlags.isXNumeric) {
|
|
803
800
|
const diff = Math.round(gl.maxX - gl.minX)
|
|
804
801
|
if (diff < 30) {
|
|
@@ -877,9 +874,30 @@ class Range {
|
|
|
877
874
|
// On its side the chart draws one band per row and one label per
|
|
878
875
|
// band, so each band is labelled with its own row's x. The evenly
|
|
879
876
|
// spaced ticks put "Jan 03" against the row that holds Jan 04.
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
)
|
|
877
|
+
// Series that do not share their x values get a band for every x any
|
|
878
|
+
// of them has, in the longest series' direction, and each bar sits in
|
|
879
|
+
// its own x's band (bar/Helpers barRow).
|
|
880
|
+
const rows = (
|
|
881
|
+
this.w.seriesData.seriesX[gl.maxValsInArrayIndex] || []
|
|
882
|
+
).slice()
|
|
883
|
+
const seen = new Set(rows)
|
|
884
|
+
const n = rows.length
|
|
885
|
+
if (cnf.chart.type === 'bar') {
|
|
886
|
+
this.w.seriesData.seriesX.forEach((s) =>
|
|
887
|
+
s?.forEach((x) => {
|
|
888
|
+
if (x != null && !seen.has(x)) {
|
|
889
|
+
seen.add(x)
|
|
890
|
+
rows.push(x)
|
|
891
|
+
}
|
|
892
|
+
}),
|
|
893
|
+
)
|
|
894
|
+
}
|
|
895
|
+
if (rows.length > n) {
|
|
896
|
+
const dir = rows[0] > rows[n - 1] ? -1 : 1
|
|
897
|
+
rows.sort((a, b) => (a - b) * dir)
|
|
898
|
+
gl.dataPoints = rows.length
|
|
899
|
+
}
|
|
900
|
+
this.w.labelData.labels = /** @type {any} */ (rows)
|
|
883
901
|
} else if (isXNumeric) {
|
|
884
902
|
this.w.labelData.labels = /** @type {any} */ (
|
|
885
903
|
gl.xAxisScale.result.slice()
|
|
@@ -1073,10 +1091,9 @@ class Range {
|
|
|
1073
1091
|
if (!this.w.seriesData.series.length) return
|
|
1074
1092
|
const gIdx = this.w.labelData.seriesGroupIndex
|
|
1075
1093
|
// [positive, negative] sums per stack: the series group (by index, groups
|
|
1076
|
-
// may reuse names), then the x value on a numeric axis as stacked
|
|
1077
|
-
//
|
|
1078
|
-
const byX =
|
|
1079
|
-
this.w.axisFlags.isXNumeric && !this.w.config.plotOptions.bar.horizontal
|
|
1094
|
+
// may reuse names), then the x value on a numeric axis as stacked bars and
|
|
1095
|
+
// lines draw (#4886), else the ordinal.
|
|
1096
|
+
const byX = this.w.axisFlags.isXNumeric
|
|
1080
1097
|
/** @type {Map<string, number[]>} */
|
|
1081
1098
|
const stacks = new Map()
|
|
1082
1099
|
|
|
@@ -1108,9 +1125,7 @@ class Range {
|
|
|
1108
1125
|
|
|
1109
1126
|
const v = this.w.seriesData.series[i][j]
|
|
1110
1127
|
if (stackSeries && v !== null && Utils.isNumber(v)) {
|
|
1111
|
-
v > 0
|
|
1112
|
-
? (st[0] += parseFloat(String(v)) + 0.0001)
|
|
1113
|
-
: (st[1] += parseFloat(String(v)))
|
|
1128
|
+
v > 0 ? (st[0] += v * 1.000001) : (st[1] += +v)
|
|
1114
1129
|
}
|
|
1115
1130
|
}
|
|
1116
1131
|
},
|
|
@@ -143,7 +143,9 @@ export default class RendererController {
|
|
|
143
143
|
return this._activeKind
|
|
144
144
|
}
|
|
145
145
|
// The backend was requested/auto-selected but its feature isn't bundled.
|
|
146
|
-
|
|
146
|
+
// resolve() runs every render, so say it once per chart.
|
|
147
|
+
if (mode === desired && !this._warned) {
|
|
148
|
+
this._warned = 1
|
|
147
149
|
warnMissingFeature(
|
|
148
150
|
`\`chart.renderer: '${desired}'\``,
|
|
149
151
|
`renderer-${desired}`,
|
|
@@ -152,10 +154,15 @@ export default class RendererController {
|
|
|
152
154
|
},
|
|
153
155
|
)
|
|
154
156
|
}
|
|
155
|
-
} else if (
|
|
157
|
+
} else if (
|
|
158
|
+
mode === 'canvas' &&
|
|
159
|
+
!this._warned &&
|
|
160
|
+
hasCanvasUnsupportedFeature(this.w)
|
|
161
|
+
) {
|
|
156
162
|
// Explicit canvas, but a configured feature (gradient/pattern/image fill,
|
|
157
163
|
// or a state color-matrix filter) can't render on canvas yet: 'auto'
|
|
158
|
-
// declines silently, explicit 'canvas' says why.
|
|
164
|
+
// declines silently, explicit 'canvas' says why (once).
|
|
165
|
+
this._warned = 1
|
|
159
166
|
console.warn(
|
|
160
167
|
`[apexcharts] renderer:"canvas" requested but this chart uses a feature the ` +
|
|
161
168
|
`canvas renderer does not render yet (gradient/pattern/image fill or a ` +
|
|
@@ -163,6 +170,13 @@ export default class RendererController {
|
|
|
163
170
|
)
|
|
164
171
|
}
|
|
165
172
|
|
|
173
|
+
// Leaving a non-SVG backend frees it (display list, bitmap); the factory
|
|
174
|
+
// builds a fresh one if the chart crosses back.
|
|
175
|
+
const prev = this._instances[this._activeKind]
|
|
176
|
+
if (prev) {
|
|
177
|
+
prev.destroy()
|
|
178
|
+
delete this._instances[this._activeKind]
|
|
179
|
+
}
|
|
166
180
|
this._activate('svg', this.svg)
|
|
167
181
|
return this._activeKind
|
|
168
182
|
}
|
package/src/modules/Scales.js
CHANGED
|
@@ -655,6 +655,19 @@ export default class Scales {
|
|
|
655
655
|
;/** @type {any} */ (gl).yAxisScale[index] = []
|
|
656
656
|
}
|
|
657
657
|
|
|
658
|
+
// Zero, a negative or the MIN_VALUE sentinel has no logarithm. The floor
|
|
659
|
+
// was the base, clipping smaller values: drop it to the power of the base
|
|
660
|
+
// at or below the smallest positive value this axis plots.
|
|
661
|
+
if (y.logarithmic && minY <= Number.MIN_VALUE) {
|
|
662
|
+
const s = this.w.seriesData.series
|
|
663
|
+
const map = gl.isMultipleYAxis && gl.seriesYAxisMap[index]
|
|
664
|
+
const b = y.logBase || 10
|
|
665
|
+
const m = (map ? map.map((i) => s[i]) : s)
|
|
666
|
+
.flat()
|
|
667
|
+
.reduce((a, v) => (v > 0 && (!a || v < a) ? v : a), 0)
|
|
668
|
+
minY = m && Math.min(b, b ** Math.floor(Math.log(m) / Math.log(b)))
|
|
669
|
+
}
|
|
670
|
+
|
|
658
671
|
const range = Math.abs(maxY - minY)
|
|
659
672
|
|
|
660
673
|
// A log scale is degenerate when the domain spans less than one full
|
|
@@ -719,15 +732,25 @@ export default class Scales {
|
|
|
719
732
|
// no data in the chart. Either all series collapsed or user passed a blank array
|
|
720
733
|
gl.xAxisScale = this.linearScale(0, 10, 10)
|
|
721
734
|
} else {
|
|
722
|
-
const
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
735
|
+
const x = w.config.xaxis
|
|
736
|
+
// a fixed max or a streaming range window wins over the step
|
|
737
|
+
let step = (x.max ?? x.range) === undefined ? x.stepSize : undefined
|
|
738
|
+
// A step fixes the tick count and the axis ends on the last step. One
|
|
739
|
+
// too fine to draw keeps the default count instead.
|
|
740
|
+
const fit = step > 0 && !gl.isBarHorizontal && x.type !== 'datetime'
|
|
741
|
+
if (fit) {
|
|
742
|
+
const n = Math.ceil((maxX - minX) / step - 1e-9)
|
|
743
|
+
n > 1e3 ? (step = undefined) : (gl.xTickAmount = n)
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
let s = this.linearScale(minX, maxX, gl.xTickAmount, 0, step)
|
|
747
|
+
if (fit && step) {
|
|
748
|
+
// linearScale rounds the step, so it can fall short of the data
|
|
749
|
+
while (s.niceMax < maxX)
|
|
750
|
+
s = this.linearScale(minX, maxX, ++gl.xTickAmount, 0, step)
|
|
751
|
+
gl.maxX = s.niceMax
|
|
752
|
+
}
|
|
753
|
+
gl.xAxisScale = s
|
|
731
754
|
}
|
|
732
755
|
return gl.xAxisScale
|
|
733
756
|
}
|