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/dist/unit.esm.js
CHANGED
|
@@ -18,7 +18,7 @@ var __spreadValues = (a, b) => {
|
|
|
18
18
|
};
|
|
19
19
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
20
|
/*!
|
|
21
|
-
* ApexCharts v8.
|
|
21
|
+
* ApexCharts v8.3.0
|
|
22
22
|
* (c) 2018-2026 ApexCharts
|
|
23
23
|
*/
|
|
24
24
|
import * as _core from "apexcharts/core";
|
|
@@ -217,7 +217,22 @@ function spaceOutLabels(items, minGap, maxY, minY) {
|
|
|
217
217
|
}
|
|
218
218
|
}
|
|
219
219
|
}
|
|
220
|
+
function hash01(n) {
|
|
221
|
+
let h = (n ^ 2654435769) >>> 0;
|
|
222
|
+
h = Math.imul(h ^ h >>> 16, 73244475);
|
|
223
|
+
h = Math.imul(h ^ h >>> 16, 73244475);
|
|
224
|
+
return ((h ^ h >>> 16) >>> 0) / 4294967296;
|
|
225
|
+
}
|
|
220
226
|
const GOLDEN_ANGLE = Math.PI * (3 - Math.sqrt(5));
|
|
227
|
+
const uniqueId = (seen, id) => {
|
|
228
|
+
const n = (seen.get(id) || 0) + 1;
|
|
229
|
+
seen.set(id, n);
|
|
230
|
+
return n > 1 ? id + "#" + n : id;
|
|
231
|
+
};
|
|
232
|
+
const toNum = (v) => {
|
|
233
|
+
if (typeof v === "string") v = parseFloat(v);
|
|
234
|
+
return typeof v === "number" && isFinite(v) ? v : null;
|
|
235
|
+
};
|
|
221
236
|
function easeOutCubic(t) {
|
|
222
237
|
return 1 - Math.pow(1 - t, 3);
|
|
223
238
|
}
|
|
@@ -263,6 +278,9 @@ class Unit {
|
|
|
263
278
|
const w = this.w;
|
|
264
279
|
const graphics = new Graphics(w, this.ctx);
|
|
265
280
|
const ret = graphics.group({ class: "apexcharts-unit" });
|
|
281
|
+
BrowserAPIs.cancelAnimationFrame(w.globals.unitGatherRAF || 0);
|
|
282
|
+
BrowserAPIs.cancelAnimationFrame(w.globals.unitExitRAF || 0);
|
|
283
|
+
w.globals.unitGatherRAF = w.globals.unitExitRAF = null;
|
|
266
284
|
if (w.globals.noData || !Array.isArray(series) || series.length === 0) {
|
|
267
285
|
return ret;
|
|
268
286
|
}
|
|
@@ -272,15 +290,16 @@ class Unit {
|
|
|
272
290
|
const flow = transition === "flow";
|
|
273
291
|
const identity = transition === "identity";
|
|
274
292
|
const unitValue = opts.unitValue > 0 ? opts.unitValue : 1;
|
|
293
|
+
const gridSplit = layout === "grid" && !!(opts.grid && opts.grid.split);
|
|
275
294
|
let counts = series.map((v) => {
|
|
276
295
|
const n = Math.abs(Utils.parseNumber(v)) / unitValue;
|
|
277
|
-
return n > 0 ? Math.max(1, Math.round(n)) : 0;
|
|
296
|
+
return gridSplit ? n : n > 0 ? Math.max(1, Math.round(n)) : 0;
|
|
278
297
|
});
|
|
279
|
-
|
|
298
|
+
if (!gridSplit && layout !== "scatter") {
|
|
299
|
+
counts = this._applyMaxUnits(counts, opts.maxUnits);
|
|
300
|
+
}
|
|
280
301
|
const total = counts.reduce((a, b) => a + b, 0);
|
|
281
302
|
const clusters = layout === "packed" ? this._layoutPacked(counts, opts) : layout === "columns" ? this._layoutColumns(counts, opts) : layout === "grid" ? this._layoutGrid(counts, opts) : layout === "scatter" ? this._layoutScatter(opts) : layout === "arc" ? this._layoutArc(counts, opts) : layout === "custom" ? this._layoutCustom(counts, opts) : this._layoutGrouped(counts, opts);
|
|
282
|
-
const gridSplit = layout === "grid" && !!(opts.grid && opts.grid.split);
|
|
283
|
-
if (gridSplit) this._drawGridTrack(ret, graphics, opts);
|
|
284
303
|
if (layout === "scatter") this._drawScatterAxes(ret, graphics);
|
|
285
304
|
const dotR = this._lastDotR;
|
|
286
305
|
const animate = this._shouldAnimate();
|
|
@@ -311,7 +330,49 @@ class Unit {
|
|
|
311
330
|
const unitData = w.seriesData.unitData || [];
|
|
312
331
|
const sizeStats = this._bubbleStats(unitData, opts, dotR);
|
|
313
332
|
let gIndex = 0;
|
|
314
|
-
|
|
333
|
+
const seen = /* @__PURE__ */ new Map();
|
|
334
|
+
const track = gridSplit && this._gridTrack && this._gridTrack.cells || [];
|
|
335
|
+
const trackG = graphics.group({ class: "apexcharts-unit-track" });
|
|
336
|
+
if (track.length) ret.add(trackG);
|
|
337
|
+
const trackFill = opts.grid && opts.grid.trackColor || "rgba(128,128,128,0.14)";
|
|
338
|
+
const trackSpec = this._baseSpec({ shape: opts.shape === "square" && "square" }, dotR);
|
|
339
|
+
const perTile = track.length / Math.max(1, clusters.length);
|
|
340
|
+
const live = this.ctx && this.ctx._unitSprings;
|
|
341
|
+
const glide = (node, spec, x, y, key, r, at, pair) => {
|
|
342
|
+
const from = prev && prev.get(key);
|
|
343
|
+
const s = live && live.get(key);
|
|
344
|
+
const still = from && from.x === x && from.y === y && from.r === r && (!s || s.x.value === x && s.y.value === y);
|
|
345
|
+
nextPrev.set(key, { x, y, fill: trackFill, r, spec });
|
|
346
|
+
if (prev && animate && !pieceTakeover && !still) {
|
|
347
|
+
const cx0 = from ? from.x : x;
|
|
348
|
+
const cy0 = from ? from.y : y;
|
|
349
|
+
node.style.opacity = from ? "1" : "0";
|
|
350
|
+
this._place(node, spec, cx0, cy0);
|
|
351
|
+
animDots.splice(at, 0, {
|
|
352
|
+
node,
|
|
353
|
+
spec,
|
|
354
|
+
x,
|
|
355
|
+
y,
|
|
356
|
+
cx0,
|
|
357
|
+
cy0,
|
|
358
|
+
key,
|
|
359
|
+
r0: from && from.r != null ? from.r : r,
|
|
360
|
+
r1: r,
|
|
361
|
+
delay: 0,
|
|
362
|
+
isEnter: !from,
|
|
363
|
+
pair
|
|
364
|
+
});
|
|
365
|
+
} else {
|
|
366
|
+
this._place(node, spec, x, y);
|
|
367
|
+
}
|
|
368
|
+
};
|
|
369
|
+
const ride = (k, pair) => {
|
|
370
|
+
const el = this._drawDot(graphics, opts, dotR, trackFill, -1, 0, trackSpec);
|
|
371
|
+
el.node.classList.add("apexcharts-unit-track-cell");
|
|
372
|
+
trackG.add(el);
|
|
373
|
+
glide(el.node, trackSpec, track[k].x, track[k].y, "trk:" + k, dotR, animDots.length, pair);
|
|
374
|
+
};
|
|
375
|
+
clusters.forEach((cluster, ci) => {
|
|
315
376
|
const color = w.globals.colors[cluster.i] || w.globals.colors[0] || "#008FFB";
|
|
316
377
|
const elSeries = graphics.group({
|
|
317
378
|
class: "apexcharts-series",
|
|
@@ -323,7 +384,9 @@ class Unit {
|
|
|
323
384
|
});
|
|
324
385
|
const burstCount = cluster.dots.length;
|
|
325
386
|
const catData = unitData[cluster.i];
|
|
387
|
+
const at = animDots.length;
|
|
326
388
|
cluster.dots.forEach((d, jj) => {
|
|
389
|
+
if (track.length) ride(ci * perTile + jj, true);
|
|
327
390
|
const j = d.j != null ? d.j : jj;
|
|
328
391
|
const datum = catData ? catData[j] : void 0;
|
|
329
392
|
const dotFill = datum && typeof datum === "object" && datum.fillColor ? datum.fillColor : color;
|
|
@@ -334,7 +397,7 @@ class Unit {
|
|
|
334
397
|
let key;
|
|
335
398
|
if (identity) {
|
|
336
399
|
const id = datum && typeof datum === "object" ? datum.id != null ? datum.id : datum.name : void 0;
|
|
337
|
-
key = id != null ? `id:${id}` : `g:${gIndex}`;
|
|
400
|
+
key = id != null ? `id:${uniqueId(seen, String(id))}` : `g:${gIndex}`;
|
|
338
401
|
} else if (flow) {
|
|
339
402
|
key = String(gIndex);
|
|
340
403
|
} else if (d.slot != null) {
|
|
@@ -354,8 +417,9 @@ class Unit {
|
|
|
354
417
|
const anchor = from || (morphActive ? morph.getInitialSlotFor(cluster.i, j, burstCount) : null);
|
|
355
418
|
const enter = opts.gather && opts.gather.enter || "burst";
|
|
356
419
|
const inPlace = gridSplit || enter === "fade" || enter === "rise";
|
|
357
|
-
const
|
|
358
|
-
const
|
|
420
|
+
const start = anchor || gridSplit && prev && prev.get("trk:" + d.slot);
|
|
421
|
+
const cx0 = start ? start.x : inPlace ? d.x : cluster.cx;
|
|
422
|
+
const cy0 = start ? start.y : enter === "rise" && !gridSplit ? d.y + 14 : inPlace ? d.y : cluster.cy;
|
|
359
423
|
el.node.style.opacity = anchor ? "1" : "0";
|
|
360
424
|
this._place(el.node, spec, cx0, cy0);
|
|
361
425
|
animDots.push({
|
|
@@ -385,9 +449,16 @@ class Unit {
|
|
|
385
449
|
this._place(el.node, spec, d.x, d.y);
|
|
386
450
|
}
|
|
387
451
|
});
|
|
452
|
+
for (let k = cluster.dots.length; k < perTile; k++) ride(ci * perTile + k, false);
|
|
388
453
|
if ((layout === "grouped" || layout === "columns" || gridSplit) && opts.clusterLabels && opts.clusterLabels.show && counts[cluster.i] > 0) {
|
|
389
454
|
const labelTotal = gridSplit ? this._gridDenom : total;
|
|
390
|
-
this._drawClusterLabel(elSeries, cluster, counts[cluster.i], labelTotal, opts, color);
|
|
455
|
+
const t = this._drawClusterLabel(elSeries, cluster, counts[cluster.i], labelTotal, opts, color);
|
|
456
|
+
if (t && gridSplit) {
|
|
457
|
+
const spec = { pk: PK_CORNER, hx: 0, hy: 0, r: 0 };
|
|
458
|
+
const lx = +(t.getAttribute("x") || 0);
|
|
459
|
+
const ly = +(t.getAttribute("y") || 0);
|
|
460
|
+
glide(t, spec, lx, ly, "lbl:" + cluster.i, 0, at, animDots.length > at);
|
|
461
|
+
}
|
|
391
462
|
}
|
|
392
463
|
ret.add(elSeries);
|
|
393
464
|
});
|
|
@@ -422,9 +493,13 @@ class Unit {
|
|
|
422
493
|
const total = counts.reduce((a, b) => a + b, 0);
|
|
423
494
|
if (!maxUnits || maxUnits <= 0 || total <= maxUnits) return counts;
|
|
424
495
|
const scale = maxUnits / total;
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
496
|
+
const ctx = this.ctx || {};
|
|
497
|
+
if (!ctx._unitCapWarned) {
|
|
498
|
+
ctx._unitCapWarned = true;
|
|
499
|
+
console.warn(
|
|
500
|
+
`[ApexCharts] unit chart: ${total} dots exceeds maxUnits (${maxUnits}); counts were scaled down proportionally. Raise plotOptions.unit.maxUnits or use plotOptions.unit.unitValue to represent more units per dot.`
|
|
501
|
+
);
|
|
502
|
+
}
|
|
428
503
|
return counts.map((c) => c > 0 ? Math.max(1, Math.round(c * scale)) : 0);
|
|
429
504
|
}
|
|
430
505
|
/**
|
|
@@ -534,7 +609,8 @@ class Unit {
|
|
|
534
609
|
*
|
|
535
610
|
* `id` is the datum's own id/name where the per-unit object form supplies
|
|
536
611
|
* one, so a provider can address a specific unit ("Texas", "employee 41")
|
|
537
|
-
* rather than a positional slot. It falls back to `"<category>:<index>"
|
|
612
|
+
* rather than a positional slot. It falls back to `"<category>:<index>"`, and
|
|
613
|
+
* a repeated one is suffixed (`"Alex#2"`).
|
|
538
614
|
*
|
|
539
615
|
* @param {number[]} counts
|
|
540
616
|
* @param {number} dotR the radius the engine would use, so a provider that
|
|
@@ -546,13 +622,17 @@ class Unit {
|
|
|
546
622
|
const unitData = w.seriesData.unitData || [];
|
|
547
623
|
const names = w.seriesData.seriesNames || [];
|
|
548
624
|
const objects = [];
|
|
625
|
+
const seen = /* @__PURE__ */ new Map();
|
|
549
626
|
let index = 0;
|
|
550
627
|
counts.forEach((n, i) => {
|
|
551
628
|
var _a;
|
|
552
629
|
const catData = unitData[i];
|
|
553
630
|
for (let j = 0; j < n; j++) {
|
|
554
631
|
const datum = catData ? catData[j] : void 0;
|
|
555
|
-
const id =
|
|
632
|
+
const id = uniqueId(
|
|
633
|
+
seen,
|
|
634
|
+
datum && typeof datum === "object" && (datum.id != null || datum.name != null) ? String(datum.id != null ? datum.id : datum.name) : `${i}:${j}`
|
|
635
|
+
);
|
|
556
636
|
objects.push({
|
|
557
637
|
id,
|
|
558
638
|
index,
|
|
@@ -736,11 +816,18 @@ class Unit {
|
|
|
736
816
|
const pad = Math.min(gw, gh) * 0.04;
|
|
737
817
|
const boxW = Math.max(1e-6, b.maxX - b.minX);
|
|
738
818
|
const boxH = Math.max(1e-6, b.maxY - b.minY);
|
|
739
|
-
const
|
|
740
|
-
const
|
|
819
|
+
const fit = (inset) => Math.max(4, Math.min((gw - 2 * pad - inset) / boxW, (gh - 2 * pad - inset) / boxH));
|
|
820
|
+
const seat = (r) => fit(2 * this._arcAllocate(total, r * innerRatio, r, span, opts).dotR);
|
|
821
|
+
let hi = fit(0);
|
|
822
|
+
let r1 = seat(hi);
|
|
823
|
+
for (let k = 0; k < 6; k++) {
|
|
824
|
+
const m = (r1 + hi) / 2;
|
|
825
|
+
if (m <= seat(m)) r1 = m;
|
|
826
|
+
else hi = m;
|
|
827
|
+
}
|
|
741
828
|
const cx = gw / 2 - (b.minX + b.maxX) / 2 * r1;
|
|
742
829
|
const cy = gh / 2 - (b.minY + b.maxY) / 2 * r1;
|
|
743
|
-
const alloc = this._arcAllocate(total,
|
|
830
|
+
const alloc = this._arcAllocate(total, r1 * innerRatio, r1, span, opts);
|
|
744
831
|
this._lastDotR = alloc.dotR;
|
|
745
832
|
const seats = [];
|
|
746
833
|
for (let r = 0; r < alloc.R; r++) {
|
|
@@ -1024,7 +1111,7 @@ class Unit {
|
|
|
1024
1111
|
* value over a denominator (`grid.max`, else the largest count so the leader
|
|
1025
1112
|
* fills its tile and every other tile stays proportionally full - no empty
|
|
1026
1113
|
* tiles for arbitrary data). The unfilled cells are drawn as a faint TRACK
|
|
1027
|
-
* backdrop (
|
|
1114
|
+
* backdrop (drawn by draw()) so each tile reads as a part-to-whole "of N".
|
|
1028
1115
|
* Only VISIBLE (non-zero) categories claim a tile, so a legend hide drops the
|
|
1029
1116
|
* tile and the rest re-flow. Each filled cell is keyed by a physical
|
|
1030
1117
|
* `tile*cells + localCell` slot, so a value change grows/shrinks a tile's fill
|
|
@@ -1042,7 +1129,7 @@ class Unit {
|
|
|
1042
1129
|
const rowsPerTile = Math.max(1, Math.ceil(cellsPerTile / cols));
|
|
1043
1130
|
const visible = counts.map((_2, i) => i).filter((i) => counts[i] > 0);
|
|
1044
1131
|
const K2 = Math.max(1, visible.length);
|
|
1045
|
-
const denom = gcfg.max > 0 ? gcfg.max : Math.max(
|
|
1132
|
+
const denom = gcfg.max > 0 ? gcfg.max : Math.max(...counts) || 1;
|
|
1046
1133
|
const tileCols = Math.max(
|
|
1047
1134
|
1,
|
|
1048
1135
|
Math.round(gcfg.tileColumns > 0 ? gcfg.tileColumns : Math.ceil(Math.sqrt(K2)))
|
|
@@ -1107,40 +1194,6 @@ class Unit {
|
|
|
1107
1194
|
this._gridTrack = { cells: track };
|
|
1108
1195
|
return clusters;
|
|
1109
1196
|
}
|
|
1110
|
-
/**
|
|
1111
|
-
* Draw the faint "track" backdrop for the small-multiple grid: every cell of
|
|
1112
|
-
* every tile's full lattice, so the filled (coloured) cells drawn on top read
|
|
1113
|
-
* as a fraction of the whole. Static (redrawn each render, never animated);
|
|
1114
|
-
* painted BEHIND the series groups. `grid.trackColor` overrides the default
|
|
1115
|
-
* theme-neutral grey.
|
|
1116
|
-
* @param {any} ret @param {Graphics} graphics @param {any} opts
|
|
1117
|
-
*/
|
|
1118
|
-
_drawGridTrack(ret, graphics, opts) {
|
|
1119
|
-
const track = this._gridTrack;
|
|
1120
|
-
if (!track || !track.cells || !track.cells.length) return;
|
|
1121
|
-
const r = this._lastDotR;
|
|
1122
|
-
const gcfg = opts.grid || {};
|
|
1123
|
-
const trackColor = gcfg.trackColor || "rgba(128,128,128,0.14)";
|
|
1124
|
-
const g = graphics.group({ class: "apexcharts-unit-track" });
|
|
1125
|
-
track.cells.forEach((c) => {
|
|
1126
|
-
let el;
|
|
1127
|
-
if (opts.shape === "square") {
|
|
1128
|
-
const side = r * 2;
|
|
1129
|
-
el = graphics.drawRect(0, 0, side, side, opts.borderRadius || 0, trackColor, 1, 0, "none");
|
|
1130
|
-
el.node.setAttribute("fill", trackColor);
|
|
1131
|
-
el.node.setAttribute("x", String(c.x - r));
|
|
1132
|
-
el.node.setAttribute("y", String(c.y - r));
|
|
1133
|
-
} else {
|
|
1134
|
-
el = graphics.drawCircle(r, { fill: trackColor, "stroke-width": 0, stroke: "none" });
|
|
1135
|
-
el.node.setAttribute("fill", trackColor);
|
|
1136
|
-
el.node.setAttribute("cx", String(c.x));
|
|
1137
|
-
el.node.setAttribute("cy", String(c.y));
|
|
1138
|
-
}
|
|
1139
|
-
el.node.classList.add("apexcharts-unit-track-cell");
|
|
1140
|
-
g.add(el);
|
|
1141
|
-
});
|
|
1142
|
-
ret.add(g);
|
|
1143
|
-
}
|
|
1144
1197
|
/**
|
|
1145
1198
|
* Scatter / beeswarm layout: position every unit on a real numeric X value
|
|
1146
1199
|
* axis by its own value (`_unitValueOf`), laned by category on Y. Within a
|
|
@@ -1155,11 +1208,14 @@ class Unit {
|
|
|
1155
1208
|
_layoutScatter(opts) {
|
|
1156
1209
|
const w = this.w;
|
|
1157
1210
|
const scfg = opts.scatter || {};
|
|
1158
|
-
|
|
1159
|
-
|
|
1211
|
+
const unitData = w.seriesData.unitData || [];
|
|
1212
|
+
const lens = unitData.map((c) => c ? c.length : 0);
|
|
1213
|
+
const caps = this._applyMaxUnits(lens, opts.maxUnits);
|
|
1214
|
+
const keep = (ci, j) => Math.floor((j + 1) * caps[ci] / lens[ci]) > Math.floor(j * caps[ci] / lens[ci]);
|
|
1215
|
+
if (scfg.y === "value") return this._layoutScatter2D(opts, keep);
|
|
1216
|
+
if (scfg.orientation === "vertical") return this._layoutScatterVertical(opts, keep);
|
|
1160
1217
|
const gw = w.layout.gridWidth;
|
|
1161
1218
|
const gh = w.layout.gridHeight;
|
|
1162
|
-
const unitData = w.seriesData.unitData || [];
|
|
1163
1219
|
const names = w.seriesData.seriesNames || [];
|
|
1164
1220
|
const valueOf = (d) => this._unitValueOf(d);
|
|
1165
1221
|
const sizeStats = this._scatterSizeStats(scfg, unitData);
|
|
@@ -1184,11 +1240,13 @@ class Unit {
|
|
|
1184
1240
|
vmax = 1;
|
|
1185
1241
|
}
|
|
1186
1242
|
const tickAmount = Math.max(2, Math.round(scfg.tickAmount > 0 ? scfg.tickAmount : 5));
|
|
1187
|
-
const domain = this._scatterValueDomain(scfg, vmin, vmax, tickAmount);
|
|
1243
|
+
const domain = this._scatterValueDomain(scfg.xMin, scfg.xMax, vmin, vmax, tickAmount);
|
|
1188
1244
|
const xMin = domain.min;
|
|
1189
1245
|
const xMax = domain.max;
|
|
1190
1246
|
const xSpan = xMax - xMin || 1;
|
|
1191
|
-
const
|
|
1247
|
+
const font = { fontFamily: w.config.chart.fontFamily, fontWeight: 600 };
|
|
1248
|
+
const laneName = (i) => names[i] || `series-${i + 1}`;
|
|
1249
|
+
const laneW = scfg.laneLabelWidth != null ? Math.max(0, scfg.laneLabelWidth) : Kv > 1 ? Math.min(gw / 3, measureLabelWidth(w, visible.map(laneName), font) + 14) : 8;
|
|
1192
1250
|
const bottomGutter = 30 + (scfg.xTitle ? 20 : 0);
|
|
1193
1251
|
const plotL = laneW;
|
|
1194
1252
|
const plotR = gw - 8;
|
|
@@ -1222,19 +1280,24 @@ class Unit {
|
|
|
1222
1280
|
const maxR = sizeStats ? sizeStats.rMax : r;
|
|
1223
1281
|
visible.forEach((ci, slot) => {
|
|
1224
1282
|
const cy = laneCy(slot);
|
|
1225
|
-
|
|
1226
|
-
const
|
|
1227
|
-
|
|
1283
|
+
let name = laneName(ci);
|
|
1284
|
+
const wid = laneW > 12 ? measureLabelWidth(w, [name], font) : 0;
|
|
1285
|
+
if (wid > laneW - 14 && wid) {
|
|
1286
|
+
name = name.slice(0, Math.max(1, Math.floor(name.length * (laneW - 14) / wid) - 1)) + "…";
|
|
1287
|
+
}
|
|
1288
|
+
lanes.push({ i: ci, cy, name });
|
|
1289
|
+
const pts = [];
|
|
1290
|
+
(unitData[ci] || []).forEach((d, j) => {
|
|
1228
1291
|
const v = valueOf(d);
|
|
1229
|
-
|
|
1292
|
+
if (!isNum(v) || !keep(ci, j)) return;
|
|
1293
|
+
const p = { j, px: plotX(v), y: cy };
|
|
1230
1294
|
if (sizeStats) p.r = this._scatterRadius(d, sizeStats, r);
|
|
1231
|
-
|
|
1295
|
+
pts.push(p);
|
|
1232
1296
|
});
|
|
1233
1297
|
if (jitter) {
|
|
1234
1298
|
const halfLane = Math.max(maxR, laneH / 2 - maxR);
|
|
1235
|
-
pts.forEach((p
|
|
1236
|
-
|
|
1237
|
-
p.y = cy + (t * 2 - 1) * halfLane;
|
|
1299
|
+
pts.forEach((p) => {
|
|
1300
|
+
p.y = cy + (hash01(ci * 7919 + p.j) * 2 - 1) * halfLane;
|
|
1238
1301
|
});
|
|
1239
1302
|
} else {
|
|
1240
1303
|
this._beeswarm(pts, cy, r, step, maxR);
|
|
@@ -1244,7 +1307,7 @@ class Unit {
|
|
|
1244
1307
|
cx: (plotL + plotR) / 2,
|
|
1245
1308
|
cy,
|
|
1246
1309
|
outerR: laneH / 2,
|
|
1247
|
-
dots: pts.map((p) => ({ x: p.px, y: p.y, r: p.r }))
|
|
1310
|
+
dots: pts.map((p) => ({ x: p.px, y: p.y, r: p.r, j: p.j }))
|
|
1248
1311
|
});
|
|
1249
1312
|
});
|
|
1250
1313
|
const ticks = domain.ticks;
|
|
@@ -1271,9 +1334,9 @@ class Unit {
|
|
|
1271
1334
|
* dots horizontally off each column's centre line. The value-axis config keys
|
|
1272
1335
|
* (`xMin`/`xMax`/`xTitle`/`xFormatter`/`tickAmount`) still describe the value
|
|
1273
1336
|
* axis (now Y), so flipping `orientation` keeps the same value settings.
|
|
1274
|
-
* @param {any} opts
|
|
1337
|
+
* @param {any} opts @param {(ci:number, j:number) => boolean} keep
|
|
1275
1338
|
*/
|
|
1276
|
-
_layoutScatterVertical(opts) {
|
|
1339
|
+
_layoutScatterVertical(opts, keep) {
|
|
1277
1340
|
const w = this.w;
|
|
1278
1341
|
const scfg = opts.scatter || {};
|
|
1279
1342
|
const gw = w.layout.gridWidth;
|
|
@@ -1303,7 +1366,7 @@ class Unit {
|
|
|
1303
1366
|
vmax = 1;
|
|
1304
1367
|
}
|
|
1305
1368
|
const tickAmount = Math.max(2, Math.round(scfg.tickAmount > 0 ? scfg.tickAmount : 5));
|
|
1306
|
-
const domain = this._scatterValueDomain(scfg, vmin, vmax, tickAmount);
|
|
1369
|
+
const domain = this._scatterValueDomain(scfg.xMin, scfg.xMax, vmin, vmax, tickAmount);
|
|
1307
1370
|
const vMin = domain.min;
|
|
1308
1371
|
const vMax = domain.max;
|
|
1309
1372
|
const vSpan = vMax - vMin || 1;
|
|
@@ -1342,18 +1405,18 @@ class Unit {
|
|
|
1342
1405
|
visible.forEach((ci, slot) => {
|
|
1343
1406
|
const cx = laneCx(slot);
|
|
1344
1407
|
lanes.push({ i: ci, cx, name: names[ci] || `series-${ci + 1}` });
|
|
1345
|
-
const
|
|
1346
|
-
|
|
1408
|
+
const pts = [];
|
|
1409
|
+
(unitData[ci] || []).forEach((d, j) => {
|
|
1347
1410
|
const v = valueOf(d);
|
|
1348
|
-
|
|
1411
|
+
if (!isNum(v) || !keep(ci, j)) return;
|
|
1412
|
+
const p = { j, py: plotY(v), x: cx };
|
|
1349
1413
|
if (sizeStats) p.r = this._scatterRadius(d, sizeStats, r);
|
|
1350
|
-
|
|
1414
|
+
pts.push(p);
|
|
1351
1415
|
});
|
|
1352
1416
|
if (jitter) {
|
|
1353
1417
|
const halfLane = Math.max(maxR, laneW / 2 - maxR);
|
|
1354
|
-
pts.forEach((p
|
|
1355
|
-
|
|
1356
|
-
p.x = cx + (t * 2 - 1) * halfLane;
|
|
1418
|
+
pts.forEach((p) => {
|
|
1419
|
+
p.x = cx + (hash01(ci * 7919 + p.j) * 2 - 1) * halfLane;
|
|
1357
1420
|
});
|
|
1358
1421
|
} else {
|
|
1359
1422
|
this._beeswarm(pts, cx, r, step, maxR, true);
|
|
@@ -1363,7 +1426,7 @@ class Unit {
|
|
|
1363
1426
|
cx,
|
|
1364
1427
|
cy: (plotT + plotB) / 2,
|
|
1365
1428
|
outerR: laneW / 2,
|
|
1366
|
-
dots: pts.map((p) => ({ x: p.x, y: p.py, r: p.r }))
|
|
1429
|
+
dots: pts.map((p) => ({ x: p.x, y: p.py, r: p.r, j: p.j }))
|
|
1367
1430
|
});
|
|
1368
1431
|
});
|
|
1369
1432
|
const ticks = domain.ticks;
|
|
@@ -1392,17 +1455,17 @@ class Unit {
|
|
|
1392
1455
|
* per category). With `scatter.sizeRange` set, each dot is a BUBBLE scaled (by
|
|
1393
1456
|
* area) from its `sizeField` (default 'z'). Needs the object form with numeric
|
|
1394
1457
|
* `x` + `y`.
|
|
1395
|
-
* @param {any} opts
|
|
1458
|
+
* @param {any} opts @param {(ci:number, j:number) => boolean} keep
|
|
1396
1459
|
*/
|
|
1397
|
-
_layoutScatter2D(opts) {
|
|
1460
|
+
_layoutScatter2D(opts, keep) {
|
|
1398
1461
|
const w = this.w;
|
|
1399
1462
|
const gw = w.layout.gridWidth;
|
|
1400
1463
|
const gh = w.layout.gridHeight;
|
|
1401
1464
|
const scfg = opts.scatter || {};
|
|
1402
1465
|
const unitData = w.seriesData.unitData || [];
|
|
1403
|
-
const isNum = (v) =>
|
|
1404
|
-
const xOf = (d) => d && typeof d === "object" ? d.x : null;
|
|
1405
|
-
const yOf = (d) => d && typeof d === "object" ? d.y != null ? d.y : d.value : null;
|
|
1466
|
+
const isNum = (v) => v != null;
|
|
1467
|
+
const xOf = (d) => d && typeof d === "object" ? toNum(d.x) : null;
|
|
1468
|
+
const yOf = (d) => d && typeof d === "object" ? toNum(d.y != null ? d.y : d.value) : null;
|
|
1406
1469
|
const visible = unitData.map((_2, i) => i).filter(
|
|
1407
1470
|
(i) => (unitData[i] || []).some((d) => isNum(xOf(d)) && isNum(yOf(d)))
|
|
1408
1471
|
);
|
|
@@ -1428,22 +1491,24 @@ class Unit {
|
|
|
1428
1491
|
ymn = 0;
|
|
1429
1492
|
ymx = 1;
|
|
1430
1493
|
}
|
|
1431
|
-
const
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1494
|
+
const dx = this._scatterValueDomain(
|
|
1495
|
+
scfg.xMin,
|
|
1496
|
+
scfg.xMax,
|
|
1497
|
+
xmn,
|
|
1498
|
+
xmx,
|
|
1499
|
+
Math.max(2, Math.round(scfg.tickAmount > 0 ? scfg.tickAmount : 5))
|
|
1437
1500
|
);
|
|
1438
|
-
const
|
|
1439
|
-
scfg.yMin
|
|
1440
|
-
scfg.yMax
|
|
1441
|
-
|
|
1501
|
+
const dy = this._scatterValueDomain(
|
|
1502
|
+
scfg.yMin,
|
|
1503
|
+
scfg.yMax,
|
|
1504
|
+
ymn,
|
|
1505
|
+
ymx,
|
|
1506
|
+
Math.max(2, Math.round(scfg.yTickAmount > 0 ? scfg.yTickAmount : 5))
|
|
1442
1507
|
);
|
|
1443
|
-
const xMin =
|
|
1444
|
-
const xMax =
|
|
1445
|
-
const yMin =
|
|
1446
|
-
const yMax =
|
|
1508
|
+
const xMin = dx.min;
|
|
1509
|
+
const xMax = dx.max;
|
|
1510
|
+
const yMin = dy.min;
|
|
1511
|
+
const yMax = dy.max;
|
|
1447
1512
|
const xSpan = xMax - xMin || 1;
|
|
1448
1513
|
const ySpan = yMax - yMin || 1;
|
|
1449
1514
|
const leftGutter = 46 + (scfg.yTitle ? 18 : 0);
|
|
@@ -1461,15 +1526,17 @@ class Unit {
|
|
|
1461
1526
|
this._lastDotR = baseR;
|
|
1462
1527
|
const clusters = [];
|
|
1463
1528
|
visible.forEach((ci) => {
|
|
1464
|
-
const
|
|
1465
|
-
|
|
1529
|
+
const dots = [];
|
|
1530
|
+
(unitData[ci] || []).forEach((d, j) => {
|
|
1466
1531
|
const x = xOf(d);
|
|
1467
1532
|
const y = yOf(d);
|
|
1468
|
-
return
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1533
|
+
if (x == null || y == null || !keep(ci, j)) return;
|
|
1534
|
+
dots.push({
|
|
1535
|
+
x: plotX(x),
|
|
1536
|
+
y: plotY(y),
|
|
1537
|
+
r: sizeStats ? this._scatterRadius(d, sizeStats, baseR) : void 0,
|
|
1538
|
+
j
|
|
1539
|
+
});
|
|
1473
1540
|
});
|
|
1474
1541
|
clusters.push({
|
|
1475
1542
|
i: ci,
|
|
@@ -1479,18 +1546,6 @@ class Unit {
|
|
|
1479
1546
|
dots
|
|
1480
1547
|
});
|
|
1481
1548
|
});
|
|
1482
|
-
const mkTicks = (lo, hi, span, spacing, pinned, n) => {
|
|
1483
|
-
const out = [];
|
|
1484
|
-
if (pinned) {
|
|
1485
|
-
for (let k = 0; k < n; k++) out.push(lo + span * k / (n - 1));
|
|
1486
|
-
} else {
|
|
1487
|
-
const sp = spacing || span / Math.max(1, n - 1);
|
|
1488
|
-
for (let v = lo; v <= hi + sp * 0.5; v += sp) {
|
|
1489
|
-
out.push(Math.abs(v) < sp * 1e-9 ? 0 : v);
|
|
1490
|
-
}
|
|
1491
|
-
}
|
|
1492
|
-
return out;
|
|
1493
|
-
};
|
|
1494
1549
|
this._scatterAxis = {
|
|
1495
1550
|
mode: "2d",
|
|
1496
1551
|
plotL,
|
|
@@ -1499,22 +1554,8 @@ class Unit {
|
|
|
1499
1554
|
plotB,
|
|
1500
1555
|
plotX,
|
|
1501
1556
|
plotY,
|
|
1502
|
-
xTicks:
|
|
1503
|
-
|
|
1504
|
-
xMax,
|
|
1505
|
-
xSpan,
|
|
1506
|
-
nx.spacing,
|
|
1507
|
-
scfg.xMin != null || scfg.xMax != null,
|
|
1508
|
-
xTicksN
|
|
1509
|
-
),
|
|
1510
|
-
yTicks: mkTicks(
|
|
1511
|
-
yMin,
|
|
1512
|
-
yMax,
|
|
1513
|
-
ySpan,
|
|
1514
|
-
ny.spacing,
|
|
1515
|
-
scfg.yMin != null || scfg.yMax != null,
|
|
1516
|
-
yTicksN
|
|
1517
|
-
),
|
|
1557
|
+
xTicks: dx.ticks,
|
|
1558
|
+
yTicks: dy.ticks,
|
|
1518
1559
|
xTitle: scfg.xTitle,
|
|
1519
1560
|
yTitle: scfg.yTitle,
|
|
1520
1561
|
xFormatter: typeof scfg.xFormatter === "function" ? scfg.xFormatter : null,
|
|
@@ -1621,32 +1662,43 @@ class Unit {
|
|
|
1621
1662
|
});
|
|
1622
1663
|
}
|
|
1623
1664
|
/**
|
|
1624
|
-
* Value-axis domain + ticks for a
|
|
1665
|
+
* Value-axis domain + ticks for a scatter axis. The domain ALWAYS contains
|
|
1625
1666
|
* every datum: a swarm that clips a dot outside the plot box is a bug, so an
|
|
1626
|
-
* explicit `
|
|
1667
|
+
* explicit `lo`/`hi` only FRAMES the axis and is extended by whole
|
|
1627
1668
|
* tick-steps whenever the data would otherwise overflow. Orientation-agnostic:
|
|
1628
1669
|
* the same value axis is X for a horizontal swarm and Y for a vertical one.
|
|
1629
|
-
* @param {
|
|
1670
|
+
* @param {number|undefined} lo pinned minimum @param {number|undefined} hi
|
|
1671
|
+
* pinned maximum
|
|
1630
1672
|
* @param {number} vmin data minimum @param {number} vmax data maximum
|
|
1631
1673
|
* @param {number} tickAmount desired tick count
|
|
1632
1674
|
* @returns {{ min:number, max:number, ticks:number[] }}
|
|
1633
1675
|
*/
|
|
1634
|
-
_scatterValueDomain(
|
|
1676
|
+
_scatterValueDomain(lo, hi, vmin, vmax, tickAmount) {
|
|
1635
1677
|
const buildTicks = (min, max, spacing2) => {
|
|
1636
1678
|
const ticks = [];
|
|
1637
|
-
for (let v = min; v <= max + spacing2 * 0.5; v
|
|
1679
|
+
for (let k = 0, v = min; v <= max + spacing2 * 0.5; v = min + ++k * spacing2) {
|
|
1638
1680
|
ticks.push(Math.abs(v) < spacing2 * 1e-9 ? 0 : v);
|
|
1639
1681
|
}
|
|
1640
1682
|
return ticks;
|
|
1641
1683
|
};
|
|
1642
|
-
if (
|
|
1643
|
-
let min =
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1684
|
+
if (lo != null || hi != null) {
|
|
1685
|
+
let min = (
|
|
1686
|
+
/** @type {number} */
|
|
1687
|
+
lo != null ? lo : hi
|
|
1688
|
+
);
|
|
1689
|
+
let max = (
|
|
1690
|
+
/** @type {number} */
|
|
1691
|
+
hi != null ? hi : lo
|
|
1692
|
+
);
|
|
1693
|
+
const spacing2 = max > min ? (max - min) / Math.max(1, tickAmount - 1) : this._niceScale(Math.min(min, vmin), Math.max(max, vmax), tickAmount).spacing;
|
|
1647
1694
|
if (vmin < min) min -= Math.ceil((min - vmin) / spacing2) * spacing2;
|
|
1648
1695
|
if (vmax > max) max += Math.ceil((vmax - max) / spacing2) * spacing2;
|
|
1649
|
-
|
|
1696
|
+
if (!(max > min)) max = min + spacing2;
|
|
1697
|
+
if ((max - min) / spacing2 <= 2 * tickAmount) {
|
|
1698
|
+
return { min, max, ticks: buildTicks(min, max, spacing2) };
|
|
1699
|
+
}
|
|
1700
|
+
vmin = min;
|
|
1701
|
+
vmax = max;
|
|
1650
1702
|
}
|
|
1651
1703
|
const nice = this._niceScale(vmin, vmax, tickAmount);
|
|
1652
1704
|
const spacing = nice.spacing || (nice.max - nice.min) / Math.max(1, tickAmount - 1);
|
|
@@ -1737,13 +1789,13 @@ class Unit {
|
|
|
1737
1789
|
ax.yTicks.forEach((v) => {
|
|
1738
1790
|
const y = ax.plotY(v);
|
|
1739
1791
|
if (ax.gridlines) line(ax.plotL, y, ax.plotR, y, gridColor);
|
|
1740
|
-
const label = ax.yFormatter ? String(ax.yFormatter(v)) : this._formatTick(v);
|
|
1792
|
+
const label = ax.yFormatter ? String(ax.yFormatter(v)) : this._formatTick(v, ax.yTicks);
|
|
1741
1793
|
text(label, ax.plotL - 8, y, "end", labelColor, 11, 400, "apexcharts-unit-tick");
|
|
1742
1794
|
});
|
|
1743
1795
|
ax.xTicks.forEach((v) => {
|
|
1744
1796
|
const x = ax.plotX(v);
|
|
1745
1797
|
if (ax.gridlines) line(x, ax.plotT, x, ax.plotB, gridColor);
|
|
1746
|
-
const label = ax.xFormatter ? String(ax.xFormatter(v)) : this._formatTick(v);
|
|
1798
|
+
const label = ax.xFormatter ? String(ax.xFormatter(v)) : this._formatTick(v, ax.xTicks);
|
|
1747
1799
|
text(label, x, ax.plotB + 14, "middle", labelColor, 11, 400, "apexcharts-unit-tick");
|
|
1748
1800
|
});
|
|
1749
1801
|
line(ax.plotL, ax.plotB, ax.plotR, ax.plotB, axisColor);
|
|
@@ -1783,7 +1835,7 @@ class Unit {
|
|
|
1783
1835
|
ax.ticks.forEach((v) => {
|
|
1784
1836
|
const y = ax.plotY(v);
|
|
1785
1837
|
if (ax.gridlines) line(ax.plotL, y, ax.plotR, y, gridColor);
|
|
1786
|
-
const label = ax.formatter ? String(ax.formatter(v)) : this._formatTick(v);
|
|
1838
|
+
const label = ax.formatter ? String(ax.formatter(v)) : this._formatTick(v, ax.ticks);
|
|
1787
1839
|
text(label, ax.plotL - 8, y, "end", labelColor, 11, 400, "apexcharts-unit-tick");
|
|
1788
1840
|
});
|
|
1789
1841
|
line(ax.plotL, ax.plotT, ax.plotL, ax.plotB, axisColor);
|
|
@@ -1813,7 +1865,7 @@ class Unit {
|
|
|
1813
1865
|
ax.ticks.forEach((v, idx) => {
|
|
1814
1866
|
const x = ax.plotX(v);
|
|
1815
1867
|
if (ax.gridlines) line(x, ax.plotT, x, ax.plotB, gridColor);
|
|
1816
|
-
const label = ax.formatter ? String(ax.formatter(v)) : this._formatTick(v);
|
|
1868
|
+
const label = ax.formatter ? String(ax.formatter(v)) : this._formatTick(v, ax.ticks);
|
|
1817
1869
|
const anchor = idx === 0 ? "start" : idx === ax.ticks.length - 1 ? "end" : "middle";
|
|
1818
1870
|
text(label, x, ax.plotB + 14, anchor, labelColor, 11, 400, "apexcharts-unit-tick");
|
|
1819
1871
|
});
|
|
@@ -1839,17 +1891,19 @@ class Unit {
|
|
|
1839
1891
|
ret.add(g);
|
|
1840
1892
|
}
|
|
1841
1893
|
/**
|
|
1842
|
-
* Compact tick-value formatting: integers as-is, otherwise trimmed to
|
|
1843
|
-
*
|
|
1844
|
-
* @param {number} v @
|
|
1894
|
+
* Compact tick-value formatting: integers as-is, otherwise trimmed to enough
|
|
1895
|
+
* decimals to tell neighbouring ticks apart; large magnitudes get a k/M suffix.
|
|
1896
|
+
* @param {number} v @param {number[]} ticks the axis ticks (their step sets
|
|
1897
|
+
* the decimals) @returns {string}
|
|
1845
1898
|
*/
|
|
1846
|
-
_formatTick(v) {
|
|
1899
|
+
_formatTick(v, ticks) {
|
|
1847
1900
|
if (!isFinite(v)) return "";
|
|
1848
1901
|
const a = Math.abs(v);
|
|
1849
1902
|
if (a >= 1e6) return `${+(v / 1e6).toFixed(1)}M`;
|
|
1850
1903
|
if (a >= 1e4) return `${+(v / 1e3).toFixed(1)}k`;
|
|
1851
1904
|
if (Number.isInteger(v)) return String(v);
|
|
1852
|
-
|
|
1905
|
+
const step = Math.abs(ticks[1] - ticks[0]) || 1;
|
|
1906
|
+
return String(+v.toFixed(Math.min(20, Math.max(2, 1 - Math.floor(Math.log10(step))))));
|
|
1853
1907
|
}
|
|
1854
1908
|
/**
|
|
1855
1909
|
* Distribute `total` whole cells across `counts` in proportion to each value,
|
|
@@ -1914,17 +1968,12 @@ class Unit {
|
|
|
1914
1968
|
return !!(sbv && sbv.enabled && opts.shape !== "image" && opts.shape !== "square");
|
|
1915
1969
|
}
|
|
1916
1970
|
/**
|
|
1917
|
-
* This datum's numeric value for sizing / tooltip: the number
|
|
1918
|
-
* object's `value` / `y`. Null when there is
|
|
1971
|
+
* This datum's numeric value for sizing / tooltip: the number (or numeric
|
|
1972
|
+
* string) itself, or an object's `value` / `y`. Null when there is none.
|
|
1919
1973
|
* @param {any} d @returns {number | null}
|
|
1920
1974
|
*/
|
|
1921
1975
|
_unitValueOf(d) {
|
|
1922
|
-
|
|
1923
|
-
if (d && typeof d === "object") {
|
|
1924
|
-
const v = d.value != null ? d.value : d.y;
|
|
1925
|
-
return typeof v === "number" ? v : null;
|
|
1926
|
-
}
|
|
1927
|
-
return null;
|
|
1976
|
+
return toNum(d && typeof d === "object" ? d.value != null ? d.value : d.y : d);
|
|
1928
1977
|
}
|
|
1929
1978
|
/**
|
|
1930
1979
|
* Radius for one bubble given the value stats. Default 'area' scaling makes
|
|
@@ -2066,8 +2115,9 @@ class Unit {
|
|
|
2066
2115
|
*
|
|
2067
2116
|
* @param {SVGElement} node @param {UnitMarkSpec} spec
|
|
2068
2117
|
* @param {number} x @param {number} y
|
|
2118
|
+
* @param {number} [k] scale against the spec's size, while a size tweens
|
|
2069
2119
|
*/
|
|
2070
|
-
_place(node, spec, x, y) {
|
|
2120
|
+
_place(node, spec, x, y, k = 1) {
|
|
2071
2121
|
const s = (
|
|
2072
2122
|
/** @type {any} */
|
|
2073
2123
|
spec
|
|
@@ -2075,16 +2125,31 @@ class Unit {
|
|
|
2075
2125
|
if (s.pk === PK_GLYPH) {
|
|
2076
2126
|
node.setAttribute(
|
|
2077
2127
|
"transform",
|
|
2078
|
-
"translate(" + (x - s.ox) + "," + (y - s.oy) + s.tail
|
|
2128
|
+
"translate(" + (x - s.ox * k) + "," + (y - s.oy * k) + (k === 1 ? s.tail : ") scale(" + s.s * k + ")")
|
|
2079
2129
|
);
|
|
2080
2130
|
} else if (s.pk === PK_CORNER) {
|
|
2081
|
-
node.setAttribute("x", String(x - s.hx));
|
|
2082
|
-
node.setAttribute("y", String(y - s.hy));
|
|
2131
|
+
node.setAttribute("x", String(x - s.hx * k));
|
|
2132
|
+
node.setAttribute("y", String(y - s.hy * k));
|
|
2083
2133
|
} else {
|
|
2084
2134
|
node.setAttribute("cx", String(x));
|
|
2085
2135
|
node.setAttribute("cy", String(y));
|
|
2086
2136
|
}
|
|
2087
2137
|
}
|
|
2138
|
+
/**
|
|
2139
|
+
* Size one mark at `k` times its spec's size (a glyph scales in `_place`).
|
|
2140
|
+
* @param {SVGElement} node @param {UnitMarkSpec} spec @param {number} k
|
|
2141
|
+
*/
|
|
2142
|
+
_size(node, spec, k) {
|
|
2143
|
+
const s = (
|
|
2144
|
+
/** @type {any} */
|
|
2145
|
+
spec
|
|
2146
|
+
);
|
|
2147
|
+
if (s.pk === PK_CIRCLE) node.setAttribute("r", String(s.r * k));
|
|
2148
|
+
else if (s.pk === PK_CORNER) {
|
|
2149
|
+
node.setAttribute("width", String(2 * s.hx * k));
|
|
2150
|
+
node.setAttribute("height", String(2 * s.hy * k));
|
|
2151
|
+
}
|
|
2152
|
+
}
|
|
2088
2153
|
/**
|
|
2089
2154
|
* The spec for the chart-wide shape (no pictogram, no per-mark radius).
|
|
2090
2155
|
* @param {any} opts @param {number} [r]
|
|
@@ -2143,7 +2208,7 @@ class Unit {
|
|
|
2143
2208
|
*/
|
|
2144
2209
|
_glyphSpec(mark, dotR, pcfg) {
|
|
2145
2210
|
const qr = Math.round(dotR * 10) / 10;
|
|
2146
|
-
const key = mark.name +
|
|
2211
|
+
const key = mark.name + mark.path + mark.viewBox + mark.fillRule + qr;
|
|
2147
2212
|
const hit = this._specCache.get(key);
|
|
2148
2213
|
if (hit) return hit;
|
|
2149
2214
|
const vb = mark.viewBox || [0, 0, 100, 100];
|
|
@@ -2192,9 +2257,9 @@ class Unit {
|
|
|
2192
2257
|
* Draw one dot (circle, square, or image icon) with the category fill +
|
|
2193
2258
|
* stroke, tagged so the shared non-axis tooltip and hover reuse work.
|
|
2194
2259
|
* @param {Graphics} graphics @param {any} opts @param {number} dotR
|
|
2195
|
-
* @param {string} color @param {number} i @param {number} j
|
|
2196
|
-
*
|
|
2197
|
-
*
|
|
2260
|
+
* @param {string} color @param {number} i @param {number} j (i < 0: an exit
|
|
2261
|
+
* ghost, left untagged so tooltips and morph capture skip it)
|
|
2262
|
+
* @param {UnitMarkSpec} spec this mark's resolved spec
|
|
2198
2263
|
* @returns {any}
|
|
2199
2264
|
*/
|
|
2200
2265
|
_drawDot(graphics, opts, dotR, color, i, j, spec) {
|
|
@@ -2203,7 +2268,7 @@ class Unit {
|
|
|
2203
2268
|
const strokeColor = Array.isArray(w.globals.stroke.colors) ? w.globals.stroke.colors[i] || "none" : "none";
|
|
2204
2269
|
const fillOpacity = typeof w.config.fill.opacity === "number" ? w.config.fill.opacity : 1;
|
|
2205
2270
|
let el;
|
|
2206
|
-
if (spec
|
|
2271
|
+
if (spec.pk === PK_GLYPH) {
|
|
2207
2272
|
el = w.dom.Paper.path(spec.d);
|
|
2208
2273
|
el.node.setAttribute("fill", color);
|
|
2209
2274
|
if (spec.fillRule === "evenodd") {
|
|
@@ -2211,7 +2276,7 @@ class Unit {
|
|
|
2211
2276
|
}
|
|
2212
2277
|
if (fillOpacity < 1) el.node.setAttribute("fill-opacity", String(fillOpacity));
|
|
2213
2278
|
el.node.setAttribute("data:r", String(spec.r));
|
|
2214
|
-
} else if (opts.shape === "image" && opts.image && opts.image.src) {
|
|
2279
|
+
} else if (spec.pk === PK_CORNER && opts.shape === "image" && opts.image && opts.image.src) {
|
|
2215
2280
|
const iw = opts.image.width || 20;
|
|
2216
2281
|
const ih = opts.image.height || 20;
|
|
2217
2282
|
el = w.dom.Paper.image(opts.image.src);
|
|
@@ -2221,7 +2286,7 @@ class Unit {
|
|
|
2221
2286
|
if (opts.image.tint) {
|
|
2222
2287
|
el.node.setAttribute("filter", `url(#${this._tintFilter(color)})`);
|
|
2223
2288
|
}
|
|
2224
|
-
} else if (
|
|
2289
|
+
} else if (spec.pk === PK_CORNER) {
|
|
2225
2290
|
const side = dotR * 2;
|
|
2226
2291
|
el = graphics.drawRect(0, 0, side, side, opts.borderRadius || 0, color, 1, strokeW, strokeColor);
|
|
2227
2292
|
el.node.setAttribute("fill", color);
|
|
@@ -2235,9 +2300,11 @@ class Unit {
|
|
|
2235
2300
|
el.node.setAttribute("fill", color);
|
|
2236
2301
|
if (fillOpacity < 1) el.node.setAttribute("fill-opacity", String(fillOpacity));
|
|
2237
2302
|
}
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2303
|
+
if (i >= 0) {
|
|
2304
|
+
el.node.classList.add("apexcharts-unit-area");
|
|
2305
|
+
el.node.setAttribute("i", String(i));
|
|
2306
|
+
el.node.setAttribute("j", String(j));
|
|
2307
|
+
}
|
|
2241
2308
|
return el;
|
|
2242
2309
|
}
|
|
2243
2310
|
/**
|
|
@@ -2251,10 +2318,12 @@ class Unit {
|
|
|
2251
2318
|
_tintFilter(color) {
|
|
2252
2319
|
const w = this.w;
|
|
2253
2320
|
const NS = "http://www.w3.org/2000/svg";
|
|
2254
|
-
const
|
|
2255
|
-
|
|
2321
|
+
const tints = this._tints || (this._tints = /* @__PURE__ */ new Map());
|
|
2322
|
+
let id = tints.get(color);
|
|
2323
|
+
if (id) return id;
|
|
2324
|
+
id = `apexcharts-unit-tint-${w.globals.chartID}-${tints.size}`;
|
|
2325
|
+
tints.set(color, id);
|
|
2256
2326
|
const svg = w.dom.Paper.node;
|
|
2257
|
-
if (svg.querySelector(`#${id}`)) return id;
|
|
2258
2327
|
let defs = svg.querySelector("defs");
|
|
2259
2328
|
if (!defs) {
|
|
2260
2329
|
defs = BrowserAPIs.createElementNS(NS, "defs");
|
|
@@ -2377,6 +2446,14 @@ class Unit {
|
|
|
2377
2446
|
}
|
|
2378
2447
|
if (this.ctx) this.ctx._unitSprings = springs;
|
|
2379
2448
|
}
|
|
2449
|
+
/**
|
|
2450
|
+
* True once a loop's node no longer belongs to this chart's live SVG.
|
|
2451
|
+
* @param {Element} node @returns {boolean}
|
|
2452
|
+
*/
|
|
2453
|
+
_stale(node) {
|
|
2454
|
+
const P = this.w.dom.Paper;
|
|
2455
|
+
return !!this.w.globals.isDestroyed || !P || !P.node.contains(node);
|
|
2456
|
+
}
|
|
2380
2457
|
/**
|
|
2381
2458
|
* One rAF loop that tweens every dot from its start (cx0/cy0 - either the
|
|
2382
2459
|
* cluster centre on first mount / for entering dots, or its previous slot on
|
|
@@ -2399,8 +2476,8 @@ class Unit {
|
|
|
2399
2476
|
const speed = Math.max(1, w.config.chart.animations.speed || 800);
|
|
2400
2477
|
const maxDelay = Math.min(speed * 0.6, 450);
|
|
2401
2478
|
const n = dots.length;
|
|
2402
|
-
for (let k =
|
|
2403
|
-
dots[k].delay = n > 1 ? k / (n - 1) * maxDelay : 0;
|
|
2479
|
+
for (let k = n; k--; ) {
|
|
2480
|
+
dots[k].delay = dots[k].pair ? dots[k + 1].delay : n > 1 ? k / (n - 1) * maxDelay : 0;
|
|
2404
2481
|
}
|
|
2405
2482
|
const gcfg = opts.gather || {};
|
|
2406
2483
|
const motion = gcfg.motion || "auto";
|
|
@@ -2409,8 +2486,9 @@ class Unit {
|
|
|
2409
2486
|
else if (this.ctx) this.ctx._unitSprings = null;
|
|
2410
2487
|
for (let k = 0; k < n; k++) {
|
|
2411
2488
|
const d = dots[k];
|
|
2412
|
-
if (d.
|
|
2413
|
-
d.node.
|
|
2489
|
+
if (d.r0 !== d.r1) {
|
|
2490
|
+
this._size(d.node, d.spec, d.r0 / d.r1);
|
|
2491
|
+
this._place(d.node, d.spec, d.cx0, d.cy0, d.r0 / d.r1);
|
|
2414
2492
|
}
|
|
2415
2493
|
}
|
|
2416
2494
|
for (let k = 0; k < n; k++) {
|
|
@@ -2421,16 +2499,11 @@ class Unit {
|
|
|
2421
2499
|
}
|
|
2422
2500
|
}
|
|
2423
2501
|
const easePos = gcfg.easing === "outBack" ? easeOutBack(typeof gcfg.overshoot === "number" ? gcfg.overshoot : 1.70158) : gcfg.easing === "inOutCubic" ? easeInOutCubic : easeOutCubic;
|
|
2424
|
-
if (this.w.globals.unitGatherRAF != null) {
|
|
2425
|
-
BrowserAPIs.cancelAnimationFrame(this.w.globals.unitGatherRAF);
|
|
2426
|
-
this.w.globals.unitGatherRAF = null;
|
|
2427
|
-
}
|
|
2428
2502
|
const start = performance.now();
|
|
2429
2503
|
let last = start;
|
|
2430
2504
|
const stepFn = (now) => {
|
|
2431
|
-
if (this.
|
|
2505
|
+
if (this._stale(dots[0].node)) {
|
|
2432
2506
|
this.w.globals.unitGatherRAF = null;
|
|
2433
|
-
this.w.globals.animationEnded = true;
|
|
2434
2507
|
return;
|
|
2435
2508
|
}
|
|
2436
2509
|
const dt = Math.min(MAX_FRAME_STEP, Math.max(0, (now - last) / 1e3));
|
|
@@ -2458,7 +2531,12 @@ class Unit {
|
|
|
2458
2531
|
cx = d.cx0 + (d.x - d.cx0) * e;
|
|
2459
2532
|
cy = d.cy0 + (d.y - d.cy0) * e;
|
|
2460
2533
|
}
|
|
2461
|
-
|
|
2534
|
+
let sk = 1;
|
|
2535
|
+
if (d.r0 !== d.r1) {
|
|
2536
|
+
sk = (d.r0 + (d.r1 - d.r0) * ec) / d.r1;
|
|
2537
|
+
this._size(d.node, d.spec, sk);
|
|
2538
|
+
}
|
|
2539
|
+
this._place(d.node, d.spec, cx, cy, sk);
|
|
2462
2540
|
if (d.isEnter) d.node.style.opacity = String(Math.min(1, t * 2.5));
|
|
2463
2541
|
if (d._c0 && d._c1) {
|
|
2464
2542
|
const cr = Math.round(d._c0[0] + (d._c1[0] - d._c0[0]) * ec);
|
|
@@ -2466,9 +2544,6 @@ class Unit {
|
|
|
2466
2544
|
const cb = Math.round(d._c0[2] + (d._c1[2] - d._c0[2]) * ec);
|
|
2467
2545
|
d.node.setAttribute("fill", `rgb(${cr},${cg},${cb})`);
|
|
2468
2546
|
}
|
|
2469
|
-
if (d.spec.pk === PK_CIRCLE && d.r0 != null && d.r1 != null && d.r0 !== d.r1) {
|
|
2470
|
-
d.node.setAttribute("r", String(d.r0 + (d.r1 - d.r0) * ec));
|
|
2471
|
-
}
|
|
2472
2547
|
if (t < 1) done = false;
|
|
2473
2548
|
}
|
|
2474
2549
|
if (done) {
|
|
@@ -2476,8 +2551,9 @@ class Unit {
|
|
|
2476
2551
|
const d = dots[k];
|
|
2477
2552
|
d.node.style.opacity = "";
|
|
2478
2553
|
if (d._c1 && d.fill1) d.node.setAttribute("fill", d.fill1);
|
|
2479
|
-
if (d.
|
|
2480
|
-
d.node
|
|
2554
|
+
if (d.r0 !== d.r1) {
|
|
2555
|
+
this._size(d.node, d.spec, 1);
|
|
2556
|
+
this._place(d.node, d.spec, d.x, d.y);
|
|
2481
2557
|
}
|
|
2482
2558
|
}
|
|
2483
2559
|
this.w.globals.unitGatherRAF = null;
|
|
@@ -2500,7 +2576,7 @@ class Unit {
|
|
|
2500
2576
|
const cap = Math.max(0, opts.maxUnits || 5e3);
|
|
2501
2577
|
const exits = [];
|
|
2502
2578
|
for (const [key, slot] of prev) {
|
|
2503
|
-
if (!nextPrev.has(key)) {
|
|
2579
|
+
if (!nextPrev.has(key) && key[0] !== "l") {
|
|
2504
2580
|
exits.push(slot);
|
|
2505
2581
|
if (exits.length >= cap) break;
|
|
2506
2582
|
}
|
|
@@ -2527,7 +2603,7 @@ class Unit {
|
|
|
2527
2603
|
exits.forEach((slot) => {
|
|
2528
2604
|
const r = slot.r != null ? slot.r : dotR;
|
|
2529
2605
|
const spec = slot.spec || this._baseSpec(opts, r);
|
|
2530
|
-
const el = this._drawDot(graphics, opts, r, slot.fill,
|
|
2606
|
+
const el = this._drawDot(graphics, opts, r, slot.fill, -1, 0, spec);
|
|
2531
2607
|
el.node.classList.add("apexcharts-unit-exit");
|
|
2532
2608
|
this._place(el.node, spec, slot.x, slot.y);
|
|
2533
2609
|
group.add(el);
|
|
@@ -2538,13 +2614,9 @@ class Unit {
|
|
|
2538
2614
|
return;
|
|
2539
2615
|
}
|
|
2540
2616
|
const speed = Math.max(1, w.config.chart.animations.speed || 800);
|
|
2541
|
-
if (this.w.globals.unitExitRAF != null) {
|
|
2542
|
-
BrowserAPIs.cancelAnimationFrame(this.w.globals.unitExitRAF);
|
|
2543
|
-
this.w.globals.unitExitRAF = null;
|
|
2544
|
-
}
|
|
2545
2617
|
const start = performance.now();
|
|
2546
2618
|
const stepFn = (now) => {
|
|
2547
|
-
if (this.
|
|
2619
|
+
if (this._stale(group.node)) {
|
|
2548
2620
|
this.w.globals.unitExitRAF = null;
|
|
2549
2621
|
return;
|
|
2550
2622
|
}
|
|
@@ -2615,7 +2687,8 @@ ${percent.toFixed(1)}%`;
|
|
|
2615
2687
|
if (!lines.length) return 0;
|
|
2616
2688
|
const width = measureLabelWidth(w, lines, {
|
|
2617
2689
|
fontSize: cfg.fontSize,
|
|
2618
|
-
fontFamily: cfg.fontFamily || w.config.chart.fontFamily
|
|
2690
|
+
fontFamily: cfg.fontFamily || w.config.chart.fontFamily,
|
|
2691
|
+
fontWeight: cfg.fontWeight
|
|
2619
2692
|
});
|
|
2620
2693
|
const gap = conn.gap != null ? conn.gap : 8;
|
|
2621
2694
|
const length = conn.length != null ? conn.length : 22;
|
|
@@ -2752,6 +2825,7 @@ ${percent.toFixed(1)}%`;
|
|
|
2752
2825
|
* the blob in either direction.
|
|
2753
2826
|
* @param {any} elSeries @param {{ i:number, cx:number, cy:number, outerR:number, flat?:boolean }} cluster
|
|
2754
2827
|
* @param {number} value @param {number} total @param {any} opts @param {string} color
|
|
2828
|
+
* @returns {SVGElement|undefined}
|
|
2755
2829
|
*/
|
|
2756
2830
|
_drawClusterLabel(elSeries, cluster, value, total, opts, color) {
|
|
2757
2831
|
const w = this.w;
|
|
@@ -2809,6 +2883,10 @@ ${percent.toFixed(1)}%`;
|
|
|
2809
2883
|
textEl.textContent = str;
|
|
2810
2884
|
}
|
|
2811
2885
|
elSeries.node.appendChild(textEl);
|
|
2886
|
+
return (
|
|
2887
|
+
/** @type {any} */
|
|
2888
|
+
textEl
|
|
2889
|
+
);
|
|
2812
2890
|
}
|
|
2813
2891
|
}
|
|
2814
2892
|
_core__default.use({
|