@primeui/chart-core 0.0.1-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +23 -0
- package/README.md +1 -0
- package/dist/animations/index.d.mts +136 -0
- package/dist/animations/index.mjs +18 -0
- package/dist/annotation.utils-Bm0lOO1o.d.mts +290 -0
- package/dist/borderRadius.utils-Cz73LLR_.d.mts +54 -0
- package/dist/canvas-D4vigq47.d.mts +34 -0
- package/dist/canvas.utils-D2WHi2gL.d.mts +167 -0
- package/dist/cartesian/index.d.mts +94 -0
- package/dist/cartesian/index.mjs +93 -0
- package/dist/chunk-22ST6YPP.mjs +304 -0
- package/dist/chunk-2QK2KOBN.mjs +10 -0
- package/dist/chunk-2QRS4YQ5.mjs +18 -0
- package/dist/chunk-3FFJEX4A.mjs +261 -0
- package/dist/chunk-3IYSJ2U7.mjs +567 -0
- package/dist/chunk-3OZLP4I4.mjs +190 -0
- package/dist/chunk-3WEMHXZI.mjs +198 -0
- package/dist/chunk-3Z62EUJN.mjs +138 -0
- package/dist/chunk-4C6EVJ54.mjs +362 -0
- package/dist/chunk-53HW45JB.mjs +102 -0
- package/dist/chunk-55Y3WI6S.mjs +186 -0
- package/dist/chunk-5JCI2DEB.mjs +97 -0
- package/dist/chunk-66T4MRC5.mjs +113 -0
- package/dist/chunk-6HSEJLSR.mjs +376 -0
- package/dist/chunk-6STOLMCA.mjs +187 -0
- package/dist/chunk-7CMVDIOU.mjs +54 -0
- package/dist/chunk-7QQ6ETB4.mjs +228 -0
- package/dist/chunk-A6ZQZFL2.mjs +272 -0
- package/dist/chunk-ADKLH73T.mjs +1 -0
- package/dist/chunk-AGU3NG6D.mjs +22 -0
- package/dist/chunk-AHYIS6EB.mjs +230 -0
- package/dist/chunk-AP3UYWYT.mjs +4 -0
- package/dist/chunk-ARB5T6MP.mjs +326 -0
- package/dist/chunk-ARRGOEFX.mjs +585 -0
- package/dist/chunk-AUF4CHDP.mjs +422 -0
- package/dist/chunk-B4FTADAZ.mjs +561 -0
- package/dist/chunk-BABQKA6K.mjs +339 -0
- package/dist/chunk-BETFQBM2.mjs +197 -0
- package/dist/chunk-BKP26M4K.mjs +413 -0
- package/dist/chunk-BZN2QHGP.mjs +200 -0
- package/dist/chunk-C36VWQ7A.mjs +86 -0
- package/dist/chunk-CHW4RKY3.mjs +16 -0
- package/dist/chunk-CINXJIRR.mjs +120 -0
- package/dist/chunk-DN6AXQYZ.mjs +667 -0
- package/dist/chunk-DP2IZNN3.mjs +92 -0
- package/dist/chunk-DTWTCFRG.mjs +119 -0
- package/dist/chunk-EAMUNLRU.mjs +172 -0
- package/dist/chunk-EDAKJLNA.mjs +17 -0
- package/dist/chunk-ERVQB2VZ.mjs +59 -0
- package/dist/chunk-FFMT6OCO.mjs +92 -0
- package/dist/chunk-FHTC2YDB.mjs +102 -0
- package/dist/chunk-FRST55HY.mjs +16 -0
- package/dist/chunk-HDFGCN2F.mjs +132 -0
- package/dist/chunk-IEGLX7VL.mjs +42 -0
- package/dist/chunk-ILUWFYGY.mjs +220 -0
- package/dist/chunk-IXOWSEHO.mjs +114 -0
- package/dist/chunk-J4RI2C2G.mjs +172 -0
- package/dist/chunk-J65DBT4R.mjs +13 -0
- package/dist/chunk-JGOVWSKH.mjs +179 -0
- package/dist/chunk-JO7VACY2.mjs +25 -0
- package/dist/chunk-JWFBOPM6.mjs +122 -0
- package/dist/chunk-KNDZP446.mjs +895 -0
- package/dist/chunk-KP2TWD4Z.mjs +90 -0
- package/dist/chunk-KQIFO5I3.mjs +225 -0
- package/dist/chunk-KVDEROP6.mjs +59 -0
- package/dist/chunk-LKC7MZKK.mjs +87 -0
- package/dist/chunk-LVMDQ4OJ.mjs +305 -0
- package/dist/chunk-M7B3JF43.mjs +90 -0
- package/dist/chunk-MTGMXRNF.mjs +136 -0
- package/dist/chunk-N3TIT3OH.mjs +1040 -0
- package/dist/chunk-NHRK5KU2.mjs +890 -0
- package/dist/chunk-NKUYIWAP.mjs +243 -0
- package/dist/chunk-NPDZLYIF.mjs +238 -0
- package/dist/chunk-O2X6FF45.mjs +499 -0
- package/dist/chunk-OGJ6IIBW.mjs +176 -0
- package/dist/chunk-OHGCZZPZ.mjs +403 -0
- package/dist/chunk-OWW3K55O.mjs +351 -0
- package/dist/chunk-OXTFAWSK.mjs +60 -0
- package/dist/chunk-PLSDU3C2.mjs +890 -0
- package/dist/chunk-PRDVPOZX.mjs +223 -0
- package/dist/chunk-Q6PPVIHU.mjs +21 -0
- package/dist/chunk-QQBXUDM4.mjs +885 -0
- package/dist/chunk-QS76E3TD.mjs +111 -0
- package/dist/chunk-QWQ6HY4I.mjs +209 -0
- package/dist/chunk-R6Y3R7EW.mjs +135 -0
- package/dist/chunk-RBLZRT5K.mjs +190 -0
- package/dist/chunk-RO4N6YFS.mjs +167 -0
- package/dist/chunk-RQ3CKQOX.mjs +984 -0
- package/dist/chunk-SALTGZFR.mjs +208 -0
- package/dist/chunk-SANZPAJ4.mjs +14 -0
- package/dist/chunk-SDBPQ5CF.mjs +624 -0
- package/dist/chunk-SSLTFJ3U.mjs +364 -0
- package/dist/chunk-SXHVDJGF.mjs +77 -0
- package/dist/chunk-TA4MVAEX.mjs +243 -0
- package/dist/chunk-TAHCOZHF.mjs +1772 -0
- package/dist/chunk-TQ6S34QZ.mjs +152 -0
- package/dist/chunk-UPRXABX5.mjs +90 -0
- package/dist/chunk-VGLSBZDN.mjs +71 -0
- package/dist/chunk-VN7CKCSE.mjs +364 -0
- package/dist/chunk-VVI3OBPJ.mjs +524 -0
- package/dist/chunk-VWF57TS3.mjs +62 -0
- package/dist/chunk-WA3OVISZ.mjs +179 -0
- package/dist/chunk-WCG35U6M.mjs +964 -0
- package/dist/chunk-WFTX4AQJ.mjs +194 -0
- package/dist/chunk-WFVOQ2QZ.mjs +18 -0
- package/dist/chunk-WH3C3Y7P.mjs +149 -0
- package/dist/chunk-WPFUV7K3.mjs +488 -0
- package/dist/chunk-WRULPWHD.mjs +492 -0
- package/dist/chunk-WS64BZXT.mjs +1 -0
- package/dist/chunk-WY4AURRE.mjs +2419 -0
- package/dist/chunk-WYLILAOO.mjs +167 -0
- package/dist/chunk-X4D7FKUS.mjs +62 -0
- package/dist/chunk-X7T34OLW.mjs +139 -0
- package/dist/chunk-XIHBK5D3.mjs +68 -0
- package/dist/chunk-XQQCGFYB.mjs +50 -0
- package/dist/chunk-XTVE4P3L.mjs +214 -0
- package/dist/chunk-XUAASRXW.mjs +579 -0
- package/dist/chunk-Y3L3D4GQ.mjs +685 -0
- package/dist/chunk-YBJ56XJS.mjs +132 -0
- package/dist/chunk-ZQFK6CAE.mjs +1 -0
- package/dist/chunk-ZT2Z7ERM.mjs +874 -0
- package/dist/chunk-ZTL2FQEW.mjs +714 -0
- package/dist/circular/arc/index.d.mts +8 -0
- package/dist/circular/arc/index.mjs +3 -0
- package/dist/circular/index.d.mts +44 -0
- package/dist/circular/index.mjs +13 -0
- package/dist/collect.utils-DiKB4ciO.d.mts +12 -0
- package/dist/computeChartState-BTVIqwyO.d.mts +304 -0
- package/dist/controller-BJE1AZ3q.d.mts +82 -0
- package/dist/controller-BoNigQJr.d.mts +63 -0
- package/dist/controllers/index.d.mts +16 -0
- package/dist/controllers/index.mjs +110 -0
- package/dist/datalabel.utils-CkjGeB8S.d.mts +122 -0
- package/dist/decimation.utils-CcvJVhI4.d.mts +244 -0
- package/dist/geometry-DUUQJXVM.d.mts +60 -0
- package/dist/index-DseIZa1j.d.mts +167 -0
- package/dist/index.d.mts +88 -0
- package/dist/index.mjs +110 -0
- package/dist/orchestrator/index.d.mts +264 -0
- package/dist/orchestrator/index.mjs +33 -0
- package/dist/plugins/index.d.mts +18 -0
- package/dist/plugins/index.mjs +1 -0
- package/dist/property-animations-D433wXzz.d.mts +580 -0
- package/dist/property-store-NORUWFND.d.mts +17 -0
- package/dist/radial/index.d.mts +14 -0
- package/dist/radial/index.mjs +37 -0
- package/dist/renderers/axis/index.d.mts +39 -0
- package/dist/renderers/axis/index.mjs +8 -0
- package/dist/renderers/circular/index.d.mts +13 -0
- package/dist/renderers/circular/index.mjs +13 -0
- package/dist/renderers/index.d.mts +83 -0
- package/dist/renderers/index.mjs +75 -0
- package/dist/renderers/navigator/index.d.mts +103 -0
- package/dist/renderers/navigator/index.mjs +8 -0
- package/dist/resize.utils-D_2qm6rv.d.mts +142 -0
- package/dist/ring.utils-DXvrxMkU.d.mts +138 -0
- package/dist/scale-KFv30jqZ.d.mts +307 -0
- package/dist/scales-Drf8AIhL.d.mts +75 -0
- package/dist/series/bar/canvas/index.d.mts +8 -0
- package/dist/series/bar/canvas/index.mjs +10 -0
- package/dist/series/bar/controller/index.d.mts +105 -0
- package/dist/series/bar/controller/index.mjs +44 -0
- package/dist/series/bar/controller-canvas/index.d.mts +7 -0
- package/dist/series/bar/controller-canvas/index.mjs +49 -0
- package/dist/series/bar/controller-svg/index.d.mts +7 -0
- package/dist/series/bar/controller-svg/index.mjs +49 -0
- package/dist/series/bar/index.d.mts +60 -0
- package/dist/series/bar/index.mjs +13 -0
- package/dist/series/bar/svg/index.d.mts +8 -0
- package/dist/series/bar/svg/index.mjs +11 -0
- package/dist/series/candlestick/canvas/index.d.mts +8 -0
- package/dist/series/candlestick/canvas/index.mjs +8 -0
- package/dist/series/candlestick/controller/index.d.mts +123 -0
- package/dist/series/candlestick/controller/index.mjs +40 -0
- package/dist/series/candlestick/controller-canvas/index.d.mts +7 -0
- package/dist/series/candlestick/controller-canvas/index.mjs +45 -0
- package/dist/series/candlestick/controller-svg/index.d.mts +7 -0
- package/dist/series/candlestick/controller-svg/index.mjs +45 -0
- package/dist/series/candlestick/index.d.mts +11 -0
- package/dist/series/candlestick/index.mjs +10 -0
- package/dist/series/candlestick/svg/index.d.mts +8 -0
- package/dist/series/candlestick/svg/index.mjs +8 -0
- package/dist/series/heatmap/canvas/index.d.mts +16 -0
- package/dist/series/heatmap/canvas/index.mjs +9 -0
- package/dist/series/heatmap/controller/index.d.mts +110 -0
- package/dist/series/heatmap/controller/index.mjs +23 -0
- package/dist/series/heatmap/controller-canvas/index.d.mts +7 -0
- package/dist/series/heatmap/controller-canvas/index.mjs +28 -0
- package/dist/series/heatmap/controller-svg/index.d.mts +7 -0
- package/dist/series/heatmap/controller-svg/index.mjs +28 -0
- package/dist/series/heatmap/index.d.mts +34 -0
- package/dist/series/heatmap/index.mjs +13 -0
- package/dist/series/heatmap/svg/index.d.mts +15 -0
- package/dist/series/heatmap/svg/index.mjs +10 -0
- package/dist/series/line/canvas/index.d.mts +6 -0
- package/dist/series/line/canvas/index.mjs +9 -0
- package/dist/series/line/controller/index.d.mts +111 -0
- package/dist/series/line/controller/index.mjs +47 -0
- package/dist/series/line/controller-canvas/index.d.mts +7 -0
- package/dist/series/line/controller-canvas/index.mjs +54 -0
- package/dist/series/line/controller-svg/index.d.mts +7 -0
- package/dist/series/line/controller-svg/index.mjs +54 -0
- package/dist/series/line/index.d.mts +49 -0
- package/dist/series/line/index.mjs +13 -0
- package/dist/series/line/svg/index.d.mts +6 -0
- package/dist/series/line/svg/index.mjs +9 -0
- package/dist/series/pie/canvas/index.d.mts +8 -0
- package/dist/series/pie/canvas/index.mjs +10 -0
- package/dist/series/pie/controller/index.d.mts +174 -0
- package/dist/series/pie/controller/index.mjs +110 -0
- package/dist/series/pie/controller-canvas/index.d.mts +8 -0
- package/dist/series/pie/controller-canvas/index.mjs +119 -0
- package/dist/series/pie/controller-svg/index.d.mts +8 -0
- package/dist/series/pie/controller-svg/index.mjs +118 -0
- package/dist/series/pie/index.d.mts +59 -0
- package/dist/series/pie/index.mjs +15 -0
- package/dist/series/pie/svg/index.d.mts +6 -0
- package/dist/series/pie/svg/index.mjs +11 -0
- package/dist/series/polar/canvas/index.d.mts +6 -0
- package/dist/series/polar/canvas/index.mjs +7 -0
- package/dist/series/polar/controller/index.d.mts +102 -0
- package/dist/series/polar/controller/index.mjs +46 -0
- package/dist/series/polar/controller-canvas/index.d.mts +8 -0
- package/dist/series/polar/controller-canvas/index.mjs +52 -0
- package/dist/series/polar/controller-svg/index.d.mts +8 -0
- package/dist/series/polar/controller-svg/index.mjs +52 -0
- package/dist/series/polar/index.d.mts +25 -0
- package/dist/series/polar/index.mjs +16 -0
- package/dist/series/polar/svg/index.d.mts +10 -0
- package/dist/series/polar/svg/index.mjs +8 -0
- package/dist/series/radar/canvas/index.d.mts +6 -0
- package/dist/series/radar/canvas/index.mjs +8 -0
- package/dist/series/radar/controller/index.d.mts +121 -0
- package/dist/series/radar/controller/index.mjs +43 -0
- package/dist/series/radar/controller-canvas/index.d.mts +8 -0
- package/dist/series/radar/controller-canvas/index.mjs +51 -0
- package/dist/series/radar/controller-svg/index.d.mts +8 -0
- package/dist/series/radar/controller-svg/index.mjs +51 -0
- package/dist/series/radar/index.d.mts +40 -0
- package/dist/series/radar/index.mjs +13 -0
- package/dist/series/radar/svg/index.d.mts +12 -0
- package/dist/series/radar/svg/index.mjs +9 -0
- package/dist/series/scatter/canvas/index.d.mts +8 -0
- package/dist/series/scatter/canvas/index.mjs +11 -0
- package/dist/series/scatter/controller/index.d.mts +124 -0
- package/dist/series/scatter/controller/index.mjs +44 -0
- package/dist/series/scatter/controller-canvas/index.d.mts +7 -0
- package/dist/series/scatter/controller-canvas/index.mjs +51 -0
- package/dist/series/scatter/controller-svg/index.d.mts +7 -0
- package/dist/series/scatter/controller-svg/index.mjs +51 -0
- package/dist/series/scatter/index.d.mts +25 -0
- package/dist/series/scatter/index.mjs +14 -0
- package/dist/series/scatter/svg/index.d.mts +8 -0
- package/dist/series/scatter/svg/index.mjs +12 -0
- package/dist/series/treemap/canvas/index.d.mts +50 -0
- package/dist/series/treemap/canvas/index.mjs +10 -0
- package/dist/series/treemap/controller/index.d.mts +130 -0
- package/dist/series/treemap/controller/index.mjs +20 -0
- package/dist/series/treemap/controller-canvas/index.d.mts +7 -0
- package/dist/series/treemap/controller-canvas/index.mjs +25 -0
- package/dist/series/treemap/controller-svg/index.d.mts +7 -0
- package/dist/series/treemap/controller-svg/index.mjs +25 -0
- package/dist/series/treemap/index.d.mts +15 -0
- package/dist/series/treemap/index.mjs +12 -0
- package/dist/series/treemap/svg/index.d.mts +15 -0
- package/dist/series/treemap/svg/index.mjs +9 -0
- package/dist/slices-DtewiwJx.d.mts +72 -0
- package/dist/spatialIndex.utils-B_GJkotZ.d.mts +5 -0
- package/dist/squarify.utils-B9CQBpa1.d.mts +50 -0
- package/dist/stacking-CChuAcLN.d.mts +319 -0
- package/dist/streaming.utils-DH-g1gNP.d.mts +49 -0
- package/dist/sync/index.d.mts +130 -0
- package/dist/sync/index.mjs +5 -0
- package/dist/tooltip.renderer-D5wpSlBa.d.mts +210 -0
- package/dist/utils/color/index.d.mts +58 -0
- package/dist/utils/color/index.mjs +4 -0
- package/dist/utils/data/index.d.mts +180 -0
- package/dist/utils/data/index.mjs +7 -0
- package/dist/utils/export/index.d.mts +14 -0
- package/dist/utils/export/index.mjs +6 -0
- package/dist/utils/index.d.mts +49 -0
- package/dist/utils/index.mjs +29 -0
- package/dist/utils/interaction/index.d.mts +255 -0
- package/dist/utils/interaction/index.mjs +9 -0
- package/dist/utils/layout/index.d.mts +3 -0
- package/dist/utils/layout/index.mjs +10 -0
- package/dist/utils/math/index.d.mts +162 -0
- package/dist/utils/math/index.mjs +1 -0
- package/dist/utils/render/index.d.mts +19 -0
- package/dist/utils/render/index.mjs +3 -0
- package/dist/utils/specialized/index.d.mts +37 -0
- package/dist/utils/specialized/index.mjs +66 -0
- package/dist/utils/text/index.d.mts +39 -0
- package/dist/utils/text/index.mjs +8 -0
- package/dist/utils/theme/index.d.mts +295 -0
- package/dist/utils/theme/index.mjs +5 -0
- package/dist/utils/zoom/index.d.mts +90 -0
- package/dist/utils/zoom/index.mjs +3 -0
- package/package.json +56 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { isGradientColor } from './chunk-O2X6FF45.mjs';
|
|
2
|
+
import { parseColorToRGB, parseHexColor, parseColorToRGBA } from './chunk-SSLTFJ3U.mjs';
|
|
3
|
+
|
|
4
|
+
// src/utils/color/luminance.ts
|
|
5
|
+
function calculateLuminanceFromRGB(r, g, b) {
|
|
6
|
+
return 0.2126 * (r / 255) + 0.7152 * (g / 255) + 0.0722 * (b / 255);
|
|
7
|
+
}
|
|
8
|
+
function perceivedLuminanceFromRGB(r, g, b) {
|
|
9
|
+
return (0.299 * r + 0.587 * g + 0.114 * b) / 255;
|
|
10
|
+
}
|
|
11
|
+
function getColorLuminance(color) {
|
|
12
|
+
const rgb = parseColorToRGB(color);
|
|
13
|
+
if (!rgb) return 0.5;
|
|
14
|
+
return calculateLuminanceFromRGB(rgb.r, rgb.g, rgb.b);
|
|
15
|
+
}
|
|
16
|
+
function getGradientLuminance(stops) {
|
|
17
|
+
if (!stops || stops.length === 0) return 0.5;
|
|
18
|
+
let totalWeight = 0;
|
|
19
|
+
let weightedLuminance = 0;
|
|
20
|
+
for (const stop of stops) {
|
|
21
|
+
const weight = 1 - Math.abs(stop.offset - 0.5) * 0.5;
|
|
22
|
+
weightedLuminance += getColorLuminance(stop.color) * weight;
|
|
23
|
+
totalWeight += weight;
|
|
24
|
+
}
|
|
25
|
+
return totalWeight > 0 ? weightedLuminance / totalWeight : 0.5;
|
|
26
|
+
}
|
|
27
|
+
function getContrastingTextColor(bgColor, threshold = 0.5) {
|
|
28
|
+
let luminance;
|
|
29
|
+
if (isGradientColor(bgColor)) {
|
|
30
|
+
luminance = getGradientLuminance(bgColor.stops);
|
|
31
|
+
} else {
|
|
32
|
+
luminance = getColorLuminance(bgColor);
|
|
33
|
+
}
|
|
34
|
+
return luminance < threshold ? "#ffffff" : "#1f2937";
|
|
35
|
+
}
|
|
36
|
+
function getContrastColor(bgColor) {
|
|
37
|
+
let r = 0, g = 0, b = 0;
|
|
38
|
+
if (bgColor.startsWith("#")) {
|
|
39
|
+
[r, g, b] = parseHexColor(bgColor);
|
|
40
|
+
} else if (bgColor.startsWith("rgb")) {
|
|
41
|
+
const match = bgColor.match(/(\d+)/g);
|
|
42
|
+
if (match && match.length >= 3) {
|
|
43
|
+
r = parseInt(match[0]);
|
|
44
|
+
g = parseInt(match[1]);
|
|
45
|
+
b = parseInt(match[2]);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return perceivedLuminanceFromRGB(r, g, b) > 0.55 ? "#374151" : "#FFFFFF";
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// src/utils/color/scale.ts
|
|
52
|
+
function interpolateColor(colorScale, colorRange, value, fallback = "#808080") {
|
|
53
|
+
if (colorScale.length === 0 || colorRange.length === 0) return fallback;
|
|
54
|
+
if (colorScale.length !== colorRange.length) return fallback;
|
|
55
|
+
const clamped = Math.max(colorScale[0], Math.min(colorScale[colorScale.length - 1], value));
|
|
56
|
+
for (let i = 0; i < colorScale.length - 1; i++) {
|
|
57
|
+
const lo = colorScale[i];
|
|
58
|
+
const hi = colorScale[i + 1];
|
|
59
|
+
if (clamped >= lo && clamped <= hi) {
|
|
60
|
+
const t = hi === lo ? 0 : (clamped - lo) / (hi - lo);
|
|
61
|
+
const [r1, g1, b1] = parseHexColor(colorRange[i]);
|
|
62
|
+
const [r2, g2, b2] = parseHexColor(colorRange[i + 1]);
|
|
63
|
+
const r = Math.round(r1 + (r2 - r1) * t);
|
|
64
|
+
const g = Math.round(g1 + (g2 - g1) * t);
|
|
65
|
+
const b = Math.round(b1 + (b2 - b1) * t);
|
|
66
|
+
return `rgb(${r},${g},${b})`;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return colorRange[colorRange.length - 1];
|
|
70
|
+
}
|
|
71
|
+
var DEFAULT_HEAT_COLORS = ["#fde68a", "#ee1c1c"];
|
|
72
|
+
function buildAutoColorScale(min, max, stops) {
|
|
73
|
+
if (stops <= 0) return [];
|
|
74
|
+
if (stops === 1 || min === max) return [min];
|
|
75
|
+
const scale = [];
|
|
76
|
+
for (let i = 0; i < stops; i++) {
|
|
77
|
+
scale.push(min + (max - min) * (i / (stops - 1)));
|
|
78
|
+
}
|
|
79
|
+
return scale;
|
|
80
|
+
}
|
|
81
|
+
function resolveColorScaleRange(opts, min, max) {
|
|
82
|
+
const { colorScale, colorRange, color, defaultColors = DEFAULT_HEAT_COLORS } = opts;
|
|
83
|
+
if (colorScale && colorRange && colorScale.length > 0 && colorRange.length > 0) {
|
|
84
|
+
return { colorScale, colorRange };
|
|
85
|
+
}
|
|
86
|
+
if (colorRange && colorRange.length > 0) {
|
|
87
|
+
return { colorScale: buildAutoColorScale(min, max, colorRange.length), colorRange };
|
|
88
|
+
}
|
|
89
|
+
if (color) {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
return { colorScale: buildAutoColorScale(min, max, defaultColors.length), colorRange: defaultColors };
|
|
93
|
+
}
|
|
94
|
+
function lerpColor(from, to, t) {
|
|
95
|
+
if (isGradientColor(from) || isGradientColor(to)) {
|
|
96
|
+
return t >= 0.5 ? to : from;
|
|
97
|
+
}
|
|
98
|
+
const fromRGBA = parseColorToRGBA(from);
|
|
99
|
+
const toRGBA = parseColorToRGBA(to);
|
|
100
|
+
if (!fromRGBA) return from;
|
|
101
|
+
if (!toRGBA) return to;
|
|
102
|
+
const effectiveFrom = from.trim().toLowerCase() === "transparent" && toRGBA ? { r: toRGBA.r, g: toRGBA.g, b: toRGBA.b, a: 0 } : fromRGBA;
|
|
103
|
+
const effectiveTo = to.trim().toLowerCase() === "transparent" && fromRGBA ? { r: fromRGBA.r, g: fromRGBA.g, b: fromRGBA.b, a: 0 } : toRGBA;
|
|
104
|
+
const r = Math.round(effectiveFrom.r + (effectiveTo.r - effectiveFrom.r) * t);
|
|
105
|
+
const g = Math.round(effectiveFrom.g + (effectiveTo.g - effectiveFrom.g) * t);
|
|
106
|
+
const b = Math.round(effectiveFrom.b + (effectiveTo.b - effectiveFrom.b) * t);
|
|
107
|
+
const a = effectiveFrom.a + (effectiveTo.a - effectiveFrom.a) * t;
|
|
108
|
+
return `rgba(${r}, ${g}, ${b}, ${a})`;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export { DEFAULT_HEAT_COLORS, buildAutoColorScale, calculateLuminanceFromRGB, getColorLuminance, getContrastColor, getContrastingTextColor, getGradientLuminance, interpolateColor, lerpColor, perceivedLuminanceFromRGB, resolveColorScaleRange };
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { measureTextWidth } from './chunk-XTVE4P3L.mjs';
|
|
2
|
+
|
|
3
|
+
// src/cartesian/crosshair.ts
|
|
4
|
+
function computeCrosshairLayout(input) {
|
|
5
|
+
const { plotArea, ctx, lineColor, dashArray, lineStrokeWidth, showX, showY, cursorX, cursorY, snapX, snapY, categoryText, cursorValueText, barValueText, barColor, badgeBg, badgeTextColor, allSeriesHits } = input;
|
|
6
|
+
const isSharedMode = allSeriesHits != null && allSeriesHits.length > 0;
|
|
7
|
+
const dash = dashArray.join(" ");
|
|
8
|
+
const clampedX = Math.max(plotArea.x, Math.min(cursorX, plotArea.x + plotArea.width));
|
|
9
|
+
const clampedY = Math.max(plotArea.y, Math.min(cursorY, plotArea.y + plotArea.height));
|
|
10
|
+
const badgeFontSize = 11;
|
|
11
|
+
const badgePadH = 6;
|
|
12
|
+
const badgePadV = 3;
|
|
13
|
+
const badgeHeight = badgeFontSize + badgePadV * 2;
|
|
14
|
+
const badgeRadius = 4;
|
|
15
|
+
const badgeGap = 4;
|
|
16
|
+
const catBadgeOffset = 11;
|
|
17
|
+
const catTextWidth = measureTextWidth(categoryText, badgeFontSize);
|
|
18
|
+
const cursorValTextWidth = measureTextWidth(cursorValueText, badgeFontSize);
|
|
19
|
+
const barValTextWidth = measureTextWidth(barValueText, badgeFontSize);
|
|
20
|
+
const catBadgeWidth = catTextWidth + badgePadH * 2;
|
|
21
|
+
const cursorValBadgeWidth = cursorValTextWidth + badgePadH * 2;
|
|
22
|
+
const barValBadgeWidth = barValTextWidth + badgePadH * 2;
|
|
23
|
+
const { orientation, categoryAxisPosition, valueAxisPosition } = ctx;
|
|
24
|
+
let catBadge = null;
|
|
25
|
+
let valBadge = null;
|
|
26
|
+
let barLabel = null;
|
|
27
|
+
let seriesLabels = [];
|
|
28
|
+
if (orientation === "vertical") {
|
|
29
|
+
const catBadgeX = snapX - catBadgeWidth / 2;
|
|
30
|
+
if (categoryAxisPosition === "bottom") {
|
|
31
|
+
const catBadgeY = plotArea.y + plotArea.height + catBadgeOffset;
|
|
32
|
+
catBadge = { x: catBadgeX, y: catBadgeY, w: catBadgeWidth, h: badgeHeight, text: categoryText, textX: snapX, textY: catBadgeY + badgeHeight / 2 };
|
|
33
|
+
} else {
|
|
34
|
+
const catBadgeY = plotArea.y - catBadgeOffset - badgeHeight;
|
|
35
|
+
catBadge = { x: catBadgeX, y: catBadgeY, w: catBadgeWidth, h: badgeHeight, text: categoryText, textX: snapX, textY: catBadgeY + badgeHeight / 2 };
|
|
36
|
+
}
|
|
37
|
+
if (isSharedMode) {
|
|
38
|
+
seriesLabels = computeSeriesLabels(allSeriesHits, "vertical", valueAxisPosition, plotArea, badgePadH, badgeHeight, badgeGap, badgeFontSize);
|
|
39
|
+
} else {
|
|
40
|
+
const valBadgeY = clampedY - badgeHeight / 2;
|
|
41
|
+
if (valueAxisPosition === "left") {
|
|
42
|
+
const valBadgeX = plotArea.x - badgeGap - cursorValBadgeWidth;
|
|
43
|
+
valBadge = { x: valBadgeX, y: valBadgeY, w: cursorValBadgeWidth, h: badgeHeight, text: cursorValueText, textX: valBadgeX + cursorValBadgeWidth / 2, textY: clampedY };
|
|
44
|
+
} else {
|
|
45
|
+
const valBadgeX = plotArea.x + plotArea.width + badgeGap;
|
|
46
|
+
valBadge = { x: valBadgeX, y: valBadgeY, w: cursorValBadgeWidth, h: badgeHeight, text: cursorValueText, textX: valBadgeX + cursorValBadgeWidth / 2, textY: clampedY };
|
|
47
|
+
}
|
|
48
|
+
barLabel = {
|
|
49
|
+
x: snapX - barValBadgeWidth / 2,
|
|
50
|
+
y: snapY - badgeHeight - badgeGap,
|
|
51
|
+
w: barValBadgeWidth,
|
|
52
|
+
h: badgeHeight,
|
|
53
|
+
text: barValueText,
|
|
54
|
+
textX: snapX,
|
|
55
|
+
textY: snapY - badgeHeight / 2 - badgeGap,
|
|
56
|
+
color: barColor
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
} else {
|
|
60
|
+
if (categoryAxisPosition === "left") {
|
|
61
|
+
const catBadgeX = plotArea.x - badgeGap - catBadgeWidth;
|
|
62
|
+
catBadge = { x: catBadgeX, y: snapY - badgeHeight / 2, w: catBadgeWidth, h: badgeHeight, text: categoryText, textX: catBadgeX + catBadgeWidth / 2, textY: snapY };
|
|
63
|
+
} else {
|
|
64
|
+
const catBadgeX = plotArea.x + plotArea.width + badgeGap;
|
|
65
|
+
catBadge = { x: catBadgeX, y: snapY - badgeHeight / 2, w: catBadgeWidth, h: badgeHeight, text: categoryText, textX: catBadgeX + catBadgeWidth / 2, textY: snapY };
|
|
66
|
+
}
|
|
67
|
+
if (isSharedMode) {
|
|
68
|
+
seriesLabels = computeSeriesLabels(allSeriesHits, "horizontal", valueAxisPosition, plotArea, badgePadH, badgeHeight, badgeGap, badgeFontSize);
|
|
69
|
+
} else {
|
|
70
|
+
const valBadgeX = clampedX - cursorValBadgeWidth / 2;
|
|
71
|
+
if (valueAxisPosition === "bottom") {
|
|
72
|
+
const valBadgeYPos = plotArea.y + plotArea.height + badgeGap;
|
|
73
|
+
valBadge = { x: valBadgeX, y: valBadgeYPos, w: cursorValBadgeWidth, h: badgeHeight, text: cursorValueText, textX: clampedX, textY: valBadgeYPos + badgeHeight / 2 };
|
|
74
|
+
} else {
|
|
75
|
+
const valBadgeYPos = plotArea.y - badgeGap - badgeHeight;
|
|
76
|
+
valBadge = { x: valBadgeX, y: valBadgeYPos, w: cursorValBadgeWidth, h: badgeHeight, text: cursorValueText, textX: clampedX, textY: valBadgeYPos + badgeHeight / 2 };
|
|
77
|
+
}
|
|
78
|
+
barLabel = {
|
|
79
|
+
x: snapX + badgeGap,
|
|
80
|
+
y: snapY - badgeHeight / 2,
|
|
81
|
+
w: barValBadgeWidth,
|
|
82
|
+
h: badgeHeight,
|
|
83
|
+
text: barValueText,
|
|
84
|
+
textX: snapX + badgeGap + barValBadgeWidth / 2,
|
|
85
|
+
textY: snapY,
|
|
86
|
+
color: barColor
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
plotArea,
|
|
92
|
+
lineColor,
|
|
93
|
+
dash,
|
|
94
|
+
sw: lineStrokeWidth,
|
|
95
|
+
cursorX: clampedX,
|
|
96
|
+
cursorY: clampedY,
|
|
97
|
+
showX,
|
|
98
|
+
showY,
|
|
99
|
+
catBadge,
|
|
100
|
+
valBadge,
|
|
101
|
+
barLabel,
|
|
102
|
+
seriesLabels,
|
|
103
|
+
badgeBg,
|
|
104
|
+
badgeTextColor,
|
|
105
|
+
badgeRadius,
|
|
106
|
+
badgeFontSize
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function computeSeriesLabels(hits, orientation, valueAxisPosition, plotArea, padH, badgeHeight, gap, fontSize) {
|
|
110
|
+
if (hits.length === 0) return [];
|
|
111
|
+
const raw = hits.map((hit) => {
|
|
112
|
+
const textWidth = measureTextWidth(hit.formattedValue, fontSize);
|
|
113
|
+
const badgeWidth = textWidth + padH * 2;
|
|
114
|
+
return { hit, badgeWidth, snapPixel: hit.snapPixel };
|
|
115
|
+
});
|
|
116
|
+
raw.sort((a, b) => a.snapPixel - b.snapPixel);
|
|
117
|
+
const posMin = orientation === "vertical" ? plotArea.y + badgeHeight / 2 : plotArea.x + badgeHeight / 2;
|
|
118
|
+
const posMax = orientation === "vertical" ? plotArea.y + plotArea.height - badgeHeight / 2 : plotArea.x + plotArea.width - badgeHeight / 2;
|
|
119
|
+
const spacing = badgeHeight + 2;
|
|
120
|
+
const positions = raw.map((r) => Math.max(posMin, Math.min(r.snapPixel, posMax)));
|
|
121
|
+
for (let i = 1; i < positions.length; i++) {
|
|
122
|
+
const prevBottom = positions[i - 1] + spacing;
|
|
123
|
+
if (positions[i] < prevBottom) positions[i] = prevBottom;
|
|
124
|
+
}
|
|
125
|
+
if (positions[positions.length - 1] > posMax) {
|
|
126
|
+
positions[positions.length - 1] = posMax;
|
|
127
|
+
for (let i = positions.length - 2; i >= 0; i--) {
|
|
128
|
+
const nextTop = positions[i + 1] - spacing;
|
|
129
|
+
if (positions[i] > nextTop) positions[i] = nextTop;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const labels = [];
|
|
133
|
+
for (let i = 0; i < raw.length; i++) {
|
|
134
|
+
const { hit, badgeWidth } = raw[i];
|
|
135
|
+
const pos = positions[i];
|
|
136
|
+
let label;
|
|
137
|
+
if (orientation === "vertical") {
|
|
138
|
+
if (valueAxisPosition === "left") {
|
|
139
|
+
const bx = plotArea.x - gap - badgeWidth;
|
|
140
|
+
label = {
|
|
141
|
+
x: bx,
|
|
142
|
+
y: pos - badgeHeight / 2,
|
|
143
|
+
w: badgeWidth,
|
|
144
|
+
h: badgeHeight,
|
|
145
|
+
text: hit.formattedValue,
|
|
146
|
+
textX: bx + badgeWidth / 2,
|
|
147
|
+
textY: pos,
|
|
148
|
+
color: hit.color
|
|
149
|
+
};
|
|
150
|
+
} else {
|
|
151
|
+
const bx = plotArea.x + plotArea.width + gap;
|
|
152
|
+
label = {
|
|
153
|
+
x: bx,
|
|
154
|
+
y: pos - badgeHeight / 2,
|
|
155
|
+
w: badgeWidth,
|
|
156
|
+
h: badgeHeight,
|
|
157
|
+
text: hit.formattedValue,
|
|
158
|
+
textX: bx + badgeWidth / 2,
|
|
159
|
+
textY: pos,
|
|
160
|
+
color: hit.color
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
} else {
|
|
164
|
+
if (valueAxisPosition === "bottom") {
|
|
165
|
+
const by = plotArea.y + plotArea.height + gap;
|
|
166
|
+
label = {
|
|
167
|
+
x: pos - badgeWidth / 2,
|
|
168
|
+
y: by,
|
|
169
|
+
w: badgeWidth,
|
|
170
|
+
h: badgeHeight,
|
|
171
|
+
text: hit.formattedValue,
|
|
172
|
+
textX: pos,
|
|
173
|
+
textY: by + badgeHeight / 2,
|
|
174
|
+
color: hit.color
|
|
175
|
+
};
|
|
176
|
+
} else {
|
|
177
|
+
const by = plotArea.y - gap - badgeHeight;
|
|
178
|
+
label = {
|
|
179
|
+
x: pos - badgeWidth / 2,
|
|
180
|
+
y: by,
|
|
181
|
+
w: badgeWidth,
|
|
182
|
+
h: badgeHeight,
|
|
183
|
+
text: hit.formattedValue,
|
|
184
|
+
textX: pos,
|
|
185
|
+
textY: by + badgeHeight / 2,
|
|
186
|
+
color: hit.color
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
labels.push(label);
|
|
191
|
+
}
|
|
192
|
+
return labels;
|
|
193
|
+
}
|
|
194
|
+
function normalizeCrosshairConfig(crosshair) {
|
|
195
|
+
if (!crosshair) return null;
|
|
196
|
+
if (crosshair === true) {
|
|
197
|
+
return { enabled: true, showX: true, showY: true, width: 1, dashArray: [4, 4] };
|
|
198
|
+
}
|
|
199
|
+
return {
|
|
200
|
+
enabled: true,
|
|
201
|
+
showX: crosshair.x !== false,
|
|
202
|
+
showY: crosshair.y !== false,
|
|
203
|
+
color: crosshair.color,
|
|
204
|
+
width: crosshair.width ?? 1,
|
|
205
|
+
dashArray: crosshair.dashArray ?? [4, 4]
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export { computeCrosshairLayout, normalizeCrosshairConfig };
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { measureTextWidth } from './chunk-XTVE4P3L.mjs';
|
|
2
|
+
|
|
3
|
+
// src/utils/text/label.utils.ts
|
|
4
|
+
function resolveCollisionAvoidance(options) {
|
|
5
|
+
const { labels, positions, isHorizontal, fontSize, fontWeight, fontFamily, autoRotate, autoRotateAngle, manualRotation, tickCount, labelMinSpacing, autoSkip = true } = options;
|
|
6
|
+
if (labels.length <= 1) {
|
|
7
|
+
return { rotation: manualRotation, skipStep: 1 };
|
|
8
|
+
}
|
|
9
|
+
if (!autoSkip) {
|
|
10
|
+
let effectiveRotation2 = manualRotation;
|
|
11
|
+
if (manualRotation === 0 && autoRotate && isHorizontal) {
|
|
12
|
+
if (hasCollisions(labels, positions, fontSize, fontWeight, fontFamily, 0, labelMinSpacing, isHorizontal)) {
|
|
13
|
+
effectiveRotation2 = autoRotateAngle;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return { rotation: effectiveRotation2, skipStep: 1 };
|
|
17
|
+
}
|
|
18
|
+
let effectiveRotation = manualRotation;
|
|
19
|
+
if (manualRotation === 0 && autoRotate && isHorizontal) {
|
|
20
|
+
if (hasCollisions(labels, positions, fontSize, fontWeight, fontFamily, 0, labelMinSpacing, isHorizontal)) {
|
|
21
|
+
effectiveRotation = autoRotateAngle;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
let skipStep = 1;
|
|
25
|
+
if (tickCount !== void 0 && tickCount > 0) {
|
|
26
|
+
if (labels.length > tickCount) {
|
|
27
|
+
skipStep = Math.ceil(labels.length / tickCount);
|
|
28
|
+
}
|
|
29
|
+
const footprints = computeLabelFootprints(labels, fontSize, fontWeight, fontFamily, effectiveRotation, isHorizontal);
|
|
30
|
+
if (hasCollisionsAtStep(labels, positions, footprints, labelMinSpacing, skipStep)) {
|
|
31
|
+
skipStep = findMinSkipStep(labels, positions, fontSize, fontWeight, fontFamily, effectiveRotation, labelMinSpacing, skipStep, isHorizontal);
|
|
32
|
+
}
|
|
33
|
+
} else {
|
|
34
|
+
skipStep = findMinSkipStep(labels, positions, fontSize, fontWeight, fontFamily, effectiveRotation, labelMinSpacing, 1, isHorizontal);
|
|
35
|
+
}
|
|
36
|
+
return { rotation: effectiveRotation, skipStep };
|
|
37
|
+
}
|
|
38
|
+
function computeLabelFootprints(labels, fontSize, fontWeight, fontFamily, rotation, isHorizontal) {
|
|
39
|
+
if (!isHorizontal) {
|
|
40
|
+
const lineHeight = fontSize * 1.2;
|
|
41
|
+
return labels.map(() => lineHeight);
|
|
42
|
+
}
|
|
43
|
+
const footprints = new Array(labels.length);
|
|
44
|
+
for (let i = 0; i < labels.length; i++) {
|
|
45
|
+
footprints[i] = labels[i] ? calculateLabelFootprint(measureTextWidth(labels[i], fontSize, fontWeight, fontFamily), fontSize, rotation) : 0;
|
|
46
|
+
}
|
|
47
|
+
return footprints;
|
|
48
|
+
}
|
|
49
|
+
function hasCollisions(labels, positions, fontSize, fontWeight, fontFamily, rotation, minSpacing, isHorizontal = true) {
|
|
50
|
+
const footprintCache = new Array(labels.length);
|
|
51
|
+
const lineHeight = fontSize * 1.2;
|
|
52
|
+
const footprintAt = (i) => {
|
|
53
|
+
let fp = footprintCache[i];
|
|
54
|
+
if (fp === void 0) {
|
|
55
|
+
fp = !isHorizontal ? lineHeight : labels[i] ? calculateLabelFootprint(measureTextWidth(labels[i], fontSize, fontWeight, fontFamily), fontSize, rotation) : 0;
|
|
56
|
+
footprintCache[i] = fp;
|
|
57
|
+
}
|
|
58
|
+
return fp;
|
|
59
|
+
};
|
|
60
|
+
return hasCollisionsAtStepLazy(labels, positions, footprintAt, minSpacing, 1);
|
|
61
|
+
}
|
|
62
|
+
function hasCollisionsAtStepLazy(labels, positions, footprintAt, minSpacing, step) {
|
|
63
|
+
const visibleIndices = [];
|
|
64
|
+
for (let i = 0; i < labels.length; i++) {
|
|
65
|
+
if (i % step === 0 && labels[i]) visibleIndices.push(i);
|
|
66
|
+
}
|
|
67
|
+
if (visibleIndices.length <= 1) return false;
|
|
68
|
+
for (let k = 0; k < visibleIndices.length - 1; k++) {
|
|
69
|
+
const i = visibleIndices[k];
|
|
70
|
+
const j = visibleIndices[k + 1];
|
|
71
|
+
const gap = Math.abs(positions[j] - positions[i]);
|
|
72
|
+
const minRequired = (footprintAt(i) + footprintAt(j)) / 2 + minSpacing;
|
|
73
|
+
if (gap < minRequired) return true;
|
|
74
|
+
}
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
function hasCollisionsAtStep(labels, positions, footprints, minSpacing, step) {
|
|
78
|
+
const visibleIndices = [];
|
|
79
|
+
for (let i = 0; i < labels.length; i++) {
|
|
80
|
+
if (i % step === 0 && labels[i]) {
|
|
81
|
+
visibleIndices.push(i);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (visibleIndices.length <= 1) return false;
|
|
85
|
+
for (let k = 0; k < visibleIndices.length - 1; k++) {
|
|
86
|
+
const i = visibleIndices[k];
|
|
87
|
+
const j = visibleIndices[k + 1];
|
|
88
|
+
const gap = Math.abs(positions[j] - positions[i]);
|
|
89
|
+
const minRequired = (footprints[i] + footprints[j]) / 2 + minSpacing;
|
|
90
|
+
if (gap < minRequired) {
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
function findMinSkipStep(labels, positions, fontSize, fontWeight, fontFamily, rotation, minSpacing, startStep, isHorizontal = true) {
|
|
97
|
+
const maxStep = Math.max(1, Math.ceil(labels.length / 2));
|
|
98
|
+
const footprints = computeLabelFootprints(labels, fontSize, fontWeight, fontFamily, rotation, isHorizontal);
|
|
99
|
+
for (let step = startStep; step <= maxStep; step++) {
|
|
100
|
+
if (!hasCollisionsAtStep(labels, positions, footprints, minSpacing, step)) {
|
|
101
|
+
return step;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return maxStep;
|
|
105
|
+
}
|
|
106
|
+
function calculateLabelFootprint(labelWidth, fontSize, rotation) {
|
|
107
|
+
if (rotation === 0) return labelWidth;
|
|
108
|
+
const radians = Math.abs(rotation * Math.PI / 180);
|
|
109
|
+
const textHeight = fontSize * 1.2;
|
|
110
|
+
return labelWidth * Math.cos(radians) + textHeight * Math.sin(radians);
|
|
111
|
+
}
|
|
112
|
+
function adjustLabelForRotation(rotation, textAnchor, baseline) {
|
|
113
|
+
if (rotation === 0) return { textAnchor, baseline };
|
|
114
|
+
const absRotation = Math.abs(rotation);
|
|
115
|
+
const isAboveBar = baseline === "auto";
|
|
116
|
+
const isBelowBar = baseline === "hanging";
|
|
117
|
+
if (isAboveBar) {
|
|
118
|
+
return {
|
|
119
|
+
textAnchor: rotation < 0 ? "start" : "end",
|
|
120
|
+
baseline: absRotation > 60 ? "central" : "auto"
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
if (isBelowBar) {
|
|
124
|
+
return {
|
|
125
|
+
textAnchor: rotation < 0 ? "end" : "start",
|
|
126
|
+
baseline: absRotation > 60 ? "central" : "hanging"
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
textAnchor: rotation < 0 ? "end" : "start",
|
|
131
|
+
baseline: "central"
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export { adjustLabelForRotation, calculateLabelFootprint, hasCollisions, resolveCollisionAvoidance };
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import { renderPieCanvas } from './chunk-VWF57TS3.mjs';
|
|
2
|
+
import { renderPieSvg } from './chunk-IXOWSEHO.mjs';
|
|
3
|
+
import { computeSlices, isFullCircle, findSliceAtPoint } from './chunk-LVMDQ4OJ.mjs';
|
|
4
|
+
import { calculateRadiusAndCenter } from './chunk-NPDZLYIF.mjs';
|
|
5
|
+
import { isIndexVisible } from './chunk-5JCI2DEB.mjs';
|
|
6
|
+
import { FIELD_DEFAULTS, batchResolveRequired, batchResolveAccessor, resolveAccessor, makeItemContext } from './chunk-O2X6FF45.mjs';
|
|
7
|
+
import { toRad } from './chunk-RQ3CKQOX.mjs';
|
|
8
|
+
|
|
9
|
+
// src/series/pie/geometry.ts
|
|
10
|
+
var DEFAULT_START_ANGLE = -90;
|
|
11
|
+
var DEFAULT_SWEEP_ANGLE = 360;
|
|
12
|
+
var DEFAULT_INNER_RADIUS = 0;
|
|
13
|
+
function calculatePieLayout(props, chartArea) {
|
|
14
|
+
const { data, valueField, color: colorProp, startAngle = DEFAULT_START_ANGLE, sweepAngle = DEFAULT_SWEEP_ANGLE, visibility } = props;
|
|
15
|
+
const valueAccessor = valueField ?? FIELD_DEFAULTS.valueField;
|
|
16
|
+
const keyField = props.keyField;
|
|
17
|
+
const rawInnerRadius = props.innerRadius ?? DEFAULT_INNER_RADIUS;
|
|
18
|
+
const normalizedInnerRadius = rawInnerRadius > 1 ? rawInnerRadius / 100 : rawInnerRadius;
|
|
19
|
+
const innerRadiusRatio = Math.max(0, Math.min(1, normalizedInnerRadius));
|
|
20
|
+
const values = valueAccessor ? batchResolveRequired(valueAccessor, data, "valueField") : data.map((_, i) => i + 1);
|
|
21
|
+
const seriesExtras = { seriesIndex: props.order ?? 0, seriesId: props.id ?? "" };
|
|
22
|
+
const categoryAccessor = props.categoryField ?? props.labelField ?? FIELD_DEFAULTS.categoryField;
|
|
23
|
+
const categoryFor = (i) => categoryAccessor ? resolveAccessor(categoryAccessor, makeItemContext(data[i], i, { value: values[i], ...seriesExtras })) ?? void 0 : void 0;
|
|
24
|
+
const dataKeys = keyField ? batchResolveAccessor(keyField, data) : [];
|
|
25
|
+
const allIndices = values.map((_, i) => i);
|
|
26
|
+
const sortProp = props.sort;
|
|
27
|
+
const sortedAllIndices = allIndices.slice();
|
|
28
|
+
if (sortProp) {
|
|
29
|
+
const labelAccessor = props.categoryField ?? props.labelField ?? FIELD_DEFAULTS.categoryField;
|
|
30
|
+
sortedAllIndices.sort((a, b) => {
|
|
31
|
+
if (sortProp === "value-asc") return values[a] - values[b];
|
|
32
|
+
if (sortProp === "value-desc") return values[b] - values[a];
|
|
33
|
+
const labelA = labelAccessor ? String(resolveAccessor(labelAccessor, makeItemContext(data[a], a)) ?? "") : "";
|
|
34
|
+
const labelB = labelAccessor ? String(resolveAccessor(labelAccessor, makeItemContext(data[b], b)) ?? "") : "";
|
|
35
|
+
return sortProp === "label-asc" ? labelA.localeCompare(labelB) : labelB.localeCompare(labelA);
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
const visibleValues = [];
|
|
39
|
+
const visibleIndices = [];
|
|
40
|
+
for (const idx of sortedAllIndices) {
|
|
41
|
+
if (isIndexVisible(visibility, idx)) {
|
|
42
|
+
visibleValues.push(values[idx]);
|
|
43
|
+
visibleIndices.push(idx);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const computedSlices = computeSlices(visibleValues, visibleIndices, startAngle, sweepAngle);
|
|
47
|
+
const computedByIndex = new Map(computedSlices.map((s) => [s.originalIndex, s]));
|
|
48
|
+
const slices = sortedAllIndices.map((dataIndex) => {
|
|
49
|
+
const visible = isIndexVisible(visibility, dataIndex);
|
|
50
|
+
const cs = computedByIndex.get(dataIndex);
|
|
51
|
+
if (cs) {
|
|
52
|
+
return { ...cs, visible, dataIndex, dataKey: dataKeys[dataIndex] };
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
value: values[dataIndex],
|
|
56
|
+
percentage: 0,
|
|
57
|
+
rotation: startAngle,
|
|
58
|
+
endAngle: startAngle,
|
|
59
|
+
valueAngle: startAngle,
|
|
60
|
+
originalIndex: dataIndex,
|
|
61
|
+
visible,
|
|
62
|
+
dataIndex,
|
|
63
|
+
dataKey: dataKeys[dataIndex]
|
|
64
|
+
};
|
|
65
|
+
});
|
|
66
|
+
const visibleSlices = slices.filter((s) => s.visible);
|
|
67
|
+
const { center, radius: naturalRadius } = calculateRadiusAndCenter(chartArea, void 0, { rotation: startAngle, sweepAngle });
|
|
68
|
+
const rawOuterRatio = props.outerRadius ?? 1;
|
|
69
|
+
const normalizedOuterRatio = rawOuterRatio > 1 ? rawOuterRatio / 100 : rawOuterRatio;
|
|
70
|
+
const outerRadiusRatio = normalizedOuterRatio <= 0 ? 1 : Math.min(normalizedOuterRatio, 1);
|
|
71
|
+
const offsetProp = props.offset;
|
|
72
|
+
let maxSliceOffset = 0;
|
|
73
|
+
if (offsetProp != null) {
|
|
74
|
+
for (let i = 0; i < data.length; i++) {
|
|
75
|
+
const val = resolveAccessor(offsetProp, makeItemContext(data[i], i, { value: values[i], category: categoryFor(i), ...seriesExtras }), { arrayMode: "clip", fallback: 0 }) ?? 0;
|
|
76
|
+
if (val > maxSliceOffset) maxSliceOffset = val;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const hoverEffects = props.effects;
|
|
80
|
+
const hoverOffset = hoverEffects?.hoverOffset ?? 0;
|
|
81
|
+
const hoverScale = hoverEffects?.hoverScale && hoverEffects.hoverScale > 1 ? hoverEffects.hoverScale : 1;
|
|
82
|
+
const reservedOffset = Math.max(maxSliceOffset, hoverOffset);
|
|
83
|
+
const radius = Math.max(0, naturalRadius - reservedOffset) / hoverScale * outerRadiusRatio;
|
|
84
|
+
const innerRadius = radius * innerRadiusRatio;
|
|
85
|
+
const borderColorProp = props.borderColor;
|
|
86
|
+
const colors = [];
|
|
87
|
+
const borderColors = [];
|
|
88
|
+
for (let i = 0; i < data.length; i++) {
|
|
89
|
+
let color;
|
|
90
|
+
let borderColor;
|
|
91
|
+
if (colorProp != null) {
|
|
92
|
+
const resolved = resolveAccessor(colorProp, makeItemContext(data[i], i, { value: values[i], category: categoryFor(i), ...seriesExtras }));
|
|
93
|
+
if (resolved) color = resolved;
|
|
94
|
+
}
|
|
95
|
+
colors.push(color);
|
|
96
|
+
if (borderColorProp) {
|
|
97
|
+
const resolvedBorderColor = batchResolveAccessor(borderColorProp, [data[i]])[0];
|
|
98
|
+
if (resolvedBorderColor) {
|
|
99
|
+
borderColor = resolvedBorderColor;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
borderColors.push(borderColor ?? "transparent");
|
|
103
|
+
}
|
|
104
|
+
const sliceCenters = slices.map((slice) => {
|
|
105
|
+
const midRadius = (radius + innerRadius) / 2;
|
|
106
|
+
const angleRad = toRad(slice.valueAngle);
|
|
107
|
+
return {
|
|
108
|
+
dataIndex: slice.dataIndex,
|
|
109
|
+
x: center.x + Math.cos(angleRad) * midRadius,
|
|
110
|
+
y: center.y + Math.sin(angleRad) * midRadius,
|
|
111
|
+
angle: slice.valueAngle
|
|
112
|
+
};
|
|
113
|
+
});
|
|
114
|
+
return {
|
|
115
|
+
slices,
|
|
116
|
+
visibleSlices,
|
|
117
|
+
center,
|
|
118
|
+
outerRadius: radius,
|
|
119
|
+
innerRadius,
|
|
120
|
+
colors,
|
|
121
|
+
borderColors,
|
|
122
|
+
isFullCircle: isFullCircle(sweepAngle),
|
|
123
|
+
startAngle,
|
|
124
|
+
sweepAngle,
|
|
125
|
+
sliceCenters
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function hitTestPie(x, y, _props, layout) {
|
|
129
|
+
const { visibleSlices, center, outerRadius, innerRadius } = layout;
|
|
130
|
+
const relX = x - center.x;
|
|
131
|
+
const relY = y - center.y;
|
|
132
|
+
const sliceIndex = findSliceAtPoint(relX, relY, visibleSlices, outerRadius, innerRadius);
|
|
133
|
+
if (sliceIndex === -1) return null;
|
|
134
|
+
return visibleSlices[sliceIndex].dataIndex;
|
|
135
|
+
}
|
|
136
|
+
function calculateMultiRingLayout(ringCount, options = {}) {
|
|
137
|
+
const { ringGap = 0, minInnerRadius = 0, equalWidth = true } = options;
|
|
138
|
+
if (ringCount <= 0) return [];
|
|
139
|
+
if (ringCount === 1) {
|
|
140
|
+
return [{ ringIndex: 0, innerRadiusRatio: minInnerRadius, outerRadiusRatio: 1 }];
|
|
141
|
+
}
|
|
142
|
+
const layouts = [];
|
|
143
|
+
const totalGapSpace = ringGap * (ringCount - 1);
|
|
144
|
+
const availableSpace = 1 - minInnerRadius - totalGapSpace;
|
|
145
|
+
if (equalWidth) {
|
|
146
|
+
const ringWidth = availableSpace / ringCount;
|
|
147
|
+
for (let i = 0; i < ringCount; i++) {
|
|
148
|
+
const outerRadius = 1 - i * (ringWidth + ringGap);
|
|
149
|
+
const innerRadius = outerRadius - ringWidth;
|
|
150
|
+
layouts.push({
|
|
151
|
+
ringIndex: i,
|
|
152
|
+
innerRadiusRatio: Math.max(minInnerRadius, innerRadius),
|
|
153
|
+
outerRadiusRatio: outerRadius
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
} else {
|
|
157
|
+
let currentOuter = 1;
|
|
158
|
+
for (let i = 0; i < ringCount; i++) {
|
|
159
|
+
const proportion = (ringCount - i) / (ringCount * (ringCount + 1) / 2);
|
|
160
|
+
const ringWidth = availableSpace * proportion;
|
|
161
|
+
const innerRadius = currentOuter - ringWidth;
|
|
162
|
+
layouts.push({
|
|
163
|
+
ringIndex: i,
|
|
164
|
+
innerRadiusRatio: Math.max(minInnerRadius, innerRadius),
|
|
165
|
+
outerRadiusRatio: currentOuter
|
|
166
|
+
});
|
|
167
|
+
currentOuter = innerRadius - ringGap;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return layouts;
|
|
171
|
+
}
|
|
172
|
+
function applyRingLayoutToProps(props, ringLayout) {
|
|
173
|
+
return {
|
|
174
|
+
...props,
|
|
175
|
+
// Override inner radius with calculated ring inner radius
|
|
176
|
+
innerRadius: ringLayout.innerRadiusRatio / ringLayout.outerRadiusRatio,
|
|
177
|
+
// Store ring metadata for potential use in rendering
|
|
178
|
+
_ringLayout: ringLayout
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// src/series/pie/index.ts
|
|
183
|
+
var pieRenderer = {
|
|
184
|
+
calculateLayout: calculatePieLayout,
|
|
185
|
+
renderSvg: renderPieSvg,
|
|
186
|
+
renderCanvas: renderPieCanvas,
|
|
187
|
+
hitTest: hitTestPie
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
export { applyRingLayoutToProps, calculateMultiRingLayout, calculatePieLayout, hitTestPie, pieRenderer };
|