@automattic/charts 4.6.0 → 4.7.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/CHANGELOG.md +16 -0
- package/TOKENS.md +12 -10
- package/dist/index.cjs +244 -145
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +33 -20
- package/dist/index.d.cts +10 -10
- package/dist/index.d.ts +10 -10
- package/dist/index.js +245 -146
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/charts/conversion-funnel-chart/conversion-funnel-chart.module.scss +0 -10
- package/src/charts/conversion-funnel-chart/conversion-funnel-chart.tsx +4 -2
- package/src/charts/conversion-funnel-chart/test/conversion-funnel-chart.test.tsx +11 -1
- package/src/charts/conversion-funnel-chart/types.ts +3 -0
- package/src/charts/heatmap-chart/heatmap-chart.module.scss +10 -3
- package/src/charts/heatmap-chart/heatmap-chart.tsx +54 -37
- package/src/charts/heatmap-chart/test/heatmap-chart.test.tsx +129 -25
- package/src/charts/heatmap-chart/types.ts +2 -6
- package/src/charts/line-chart/crosshair-style-types.fixture.ts +23 -0
- package/src/charts/line-chart/line-chart.module.scss +0 -5
- package/src/charts/line-chart/line-chart.tsx +8 -40
- package/src/charts/line-chart/test/line-chart.test.tsx +19 -47
- package/src/charts/pie-chart/pie-chart.module.scss +9 -0
- package/src/charts/pie-chart/pie-chart.tsx +22 -76
- package/src/charts/pie-chart/test/pie-chart.test.tsx +21 -8
- package/src/charts/private/chart-composition/chart-html.tsx +1 -1
- package/src/charts/private/chart-composition/chart-svg.tsx +1 -1
- package/src/charts/private/label-text-color.ts +116 -0
- package/src/charts/private/radial-wipe-animation/radial-wipe-animation.tsx +2 -0
- package/src/charts/private/svg-empty-state/svg-empty-state.tsx +1 -1
- package/src/charts/private/test/label-text-color.test.ts +191 -0
- package/src/charts/private/with-responsive/test/with-responsive.test.tsx +1 -0
- package/src/charts/private/with-responsive/with-responsive.tsx +2 -5
- package/src/components/tooltip/accessible-tooltip.tsx +1 -1
- package/src/components/tooltip/base-tooltip.module.scss +12 -8
- package/src/components/tooltip/base-tooltip.tsx +11 -9
- package/src/components/tooltip/private/bounded-tooltip.tsx +27 -8
- package/src/components/tooltip/private/tooltip-theme.tsx +37 -0
- package/src/components/tooltip/test/bounded-tooltip.test.tsx +82 -1
- package/src/components/tooltip/test/tool-tip.test.tsx +5 -0
- package/src/components/tooltip/test/tooltip-theme.test.tsx +61 -0
- package/src/components/tooltip/test/xy-chart-tooltip.test.tsx +41 -28
- package/src/components/tooltip/xy-chart-tooltip.tsx +29 -29
- package/src/components/trend-indicator/trend-indicator.tsx +1 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/test/use-xychart-theme.test.tsx +3 -3
- package/src/hooks/use-isomorphic-layout-effect.ts +5 -0
- package/src/hooks/use-xychart-theme.ts +4 -12
- package/src/providers/chart-context/hooks/use-default-hidden-series.ts +2 -4
- package/src/providers/chart-context/private/perceptual-color.ts +45 -4
- package/src/providers/chart-context/test/perceptual-color.test.ts +31 -0
- package/src/styles/chart-scope-class.ts +5 -0
- package/src/styles/chart-scope.scss +9 -6
- package/src/styles/test/chart-scope.test.ts +3 -3
- package/src/utils/color-utils.ts +2 -1
- package/src/visx/types.ts +1 -1
- package/src/charts/line-chart/test/crosshair-style-types.test.ts +0 -31
package/dist/index.js
CHANGED
|
@@ -11,11 +11,12 @@ import { tzOffset } from "@date-fns/tz";
|
|
|
11
11
|
import { Text, getStringWidth } from "@visx/text";
|
|
12
12
|
import deepmerge from "deepmerge";
|
|
13
13
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
14
|
-
import { Tooltip,
|
|
14
|
+
import { Tooltip, useTooltip } from "@visx/tooltip";
|
|
15
15
|
import { createScale, getTicks, scaleBand, scaleCanBeZeroed, scaleOrdinal, scaleTime } from "@visx/scale";
|
|
16
16
|
import { Group } from "@visx/group";
|
|
17
17
|
import { LegendItem, LegendLabel, LegendOrdinal, LegendShape } from "@visx/legend";
|
|
18
18
|
import { IconButton, Stack, Text as Text$1 } from "@wordpress/ui";
|
|
19
|
+
import { ThemeProvider } from "@wordpress/theme";
|
|
19
20
|
import { createPortal } from "react-dom";
|
|
20
21
|
import { LinearGradient } from "@visx/gradient";
|
|
21
22
|
import { curveCatmullRom, curveLinear, curveMonotoneX } from "@visx/curve";
|
|
@@ -560,7 +561,8 @@ const relativeLuminance = (hex) => {
|
|
|
560
561
|
* Whether light text reads better than dark text on the given background, using the W3C
|
|
561
562
|
* luminance threshold (0.179) that maximizes contrast against black vs white.
|
|
562
563
|
*
|
|
563
|
-
* @
|
|
564
|
+
* @deprecated Assumes black and white text, so it ignores label role overrides and cannot guarantee AA; charts no longer use it, and it will be removed in a future major version.
|
|
565
|
+
* @param backgroundHex - Hex background color
|
|
564
566
|
* @return true if light text should be used; false (dark text) for malformed colors
|
|
565
567
|
*/
|
|
566
568
|
const prefersLightText = (backgroundHex) => {
|
|
@@ -879,14 +881,27 @@ const PROTANOPIA = [
|
|
|
879
881
|
const DEGREES = Math.PI / 180;
|
|
880
882
|
const toLinear = (channel) => channel <= .04045 ? channel / 12.92 : Math.pow((channel + .055) / 1.055, 2.4);
|
|
881
883
|
const fromLinear = (channel) => channel <= .0031308 ? 12.92 * channel : 1.055 * Math.pow(channel, 1 / 2.4) - .055;
|
|
882
|
-
|
|
884
|
+
/**
|
|
885
|
+
* The sRGB channels of a hex color.
|
|
886
|
+
*
|
|
887
|
+
* @param hex - A six-digit hex color.
|
|
888
|
+
* @return Channels from 0 to 255.
|
|
889
|
+
* @throws {Error} if the hex string is malformed
|
|
890
|
+
*/
|
|
891
|
+
const hexToRgb = (hex) => {
|
|
883
892
|
validateHexColor(hex);
|
|
884
|
-
|
|
893
|
+
const [r, g, b] = [
|
|
885
894
|
1,
|
|
886
895
|
3,
|
|
887
896
|
5
|
|
888
|
-
].map((start) =>
|
|
897
|
+
].map((start) => parseInt(hex.slice(start, start + 2), 16));
|
|
898
|
+
return [
|
|
899
|
+
r,
|
|
900
|
+
g,
|
|
901
|
+
b
|
|
902
|
+
];
|
|
889
903
|
};
|
|
904
|
+
const hexToLinear = (hex) => hexToRgb(hex).map((channel) => toLinear(channel / 255));
|
|
890
905
|
const linearToHex = (linear) => "#" + linear.map((channel) => Math.round(Math.min(1, Math.max(0, fromLinear(channel))) * 255).toString(16).padStart(2, "0")).join("");
|
|
891
906
|
const simulate = (matrix, [r, g, b]) => [
|
|
892
907
|
0,
|
|
@@ -1012,6 +1027,35 @@ const hexToOklch = (hex) => {
|
|
|
1012
1027
|
};
|
|
1013
1028
|
};
|
|
1014
1029
|
/**
|
|
1030
|
+
* `foreground` over `background` at `weight`, left unrounded as CSS `color-mix` and alpha compositing leave it.
|
|
1031
|
+
*
|
|
1032
|
+
* A mix rounded to hex can land on the other side of a contrast threshold from the fill the browser paints.
|
|
1033
|
+
*
|
|
1034
|
+
* @param foreground - The color weighted by `weight`.
|
|
1035
|
+
* @param background - The color it is mixed over.
|
|
1036
|
+
* @param weight - Share of `foreground`, from 0 to 1.
|
|
1037
|
+
* @return The mixed channels.
|
|
1038
|
+
*/
|
|
1039
|
+
const blendRgb = (foreground, background, weight) => {
|
|
1040
|
+
const share = Math.min(1, Math.max(0, weight));
|
|
1041
|
+
const [r, g, b] = foreground.map((channel, i) => background[i] + (channel - background[i]) * share);
|
|
1042
|
+
return [
|
|
1043
|
+
r,
|
|
1044
|
+
g,
|
|
1045
|
+
b
|
|
1046
|
+
];
|
|
1047
|
+
};
|
|
1048
|
+
/**
|
|
1049
|
+
* WCAG relative luminance of unrounded sRGB channels.
|
|
1050
|
+
*
|
|
1051
|
+
* @param rgb - Channels from 0 to 255.
|
|
1052
|
+
* @return Relative luminance from 0 to 1.
|
|
1053
|
+
*/
|
|
1054
|
+
const rgbLuminance = (rgb) => {
|
|
1055
|
+
const [r, g, b] = rgb.map((channel) => toLinear(channel / 255));
|
|
1056
|
+
return .2126 * r + .7152 * g + .0722 * b;
|
|
1057
|
+
};
|
|
1058
|
+
/**
|
|
1015
1059
|
* WCAG contrast ratio between two relative luminances.
|
|
1016
1060
|
*
|
|
1017
1061
|
* @param first - First relative luminance.
|
|
@@ -1019,15 +1063,6 @@ const hexToOklch = (hex) => {
|
|
|
1019
1063
|
* @return Ratio from 1 to 21.
|
|
1020
1064
|
*/
|
|
1021
1065
|
const luminanceContrastRatio = (first, second) => (Math.max(first, second) + .05) / (Math.min(first, second) + .05);
|
|
1022
|
-
/**
|
|
1023
|
-
* WCAG contrast ratio between two hex colors.
|
|
1024
|
-
*
|
|
1025
|
-
* @param first - First hex color.
|
|
1026
|
-
* @param second - Second hex color.
|
|
1027
|
-
* @return Ratio from 1 to 21.
|
|
1028
|
-
* @throws {Error} if either hex string is malformed
|
|
1029
|
-
*/
|
|
1030
|
-
const contrastRatio = (first, second) => luminanceContrastRatio(relativeLuminance(first), relativeLuminance(second));
|
|
1031
1066
|
/** WCAG 1.4.3 text contrast, which a label drawn on a fill needs from at least one label color. */
|
|
1032
1067
|
const MIN_LABEL_CONTRAST = 4.5;
|
|
1033
1068
|
/** Degrees of hue one unit of OKLCH chroma is worth when ranking candidates by hue. */
|
|
@@ -1532,15 +1567,13 @@ const useXYChartTheme = (data) => {
|
|
|
1532
1567
|
const resolve = createCssVariableResolver(scopeElement);
|
|
1533
1568
|
const resolveColor = (value) => value ? resolve(value) ?? value : value;
|
|
1534
1569
|
const paletteColors = [...JSON.parse(seriesColorKey), ...CATALOG_POINTERS.series].map((color) => resolveColor(color)).filter((color) => Boolean(color) && !color.includes("var("));
|
|
1535
|
-
const resolvedLabelColor = resolveColor(CATALOG_POINTERS.labelAxis);
|
|
1536
|
-
const htmlLabelColor = resolvedLabelColor ? normalizeColorToHex(resolvedLabelColor) || resolvedLabelColor : resolvedLabelColor;
|
|
1537
1570
|
return buildChartTheme({
|
|
1538
1571
|
...theme,
|
|
1539
1572
|
gridColor: "",
|
|
1540
1573
|
gridColorDark: "",
|
|
1541
1574
|
colors: paletteColors,
|
|
1542
1575
|
backgroundColor: resolveColor(CATALOG_POINTERS.background),
|
|
1543
|
-
htmlLabel:
|
|
1576
|
+
htmlLabel: { color: CATALOG_POINTERS.labelAxis },
|
|
1544
1577
|
gridStyles: {
|
|
1545
1578
|
...theme.gridStyles,
|
|
1546
1579
|
stroke: CATALOG_POINTERS.grid
|
|
@@ -1975,6 +2008,9 @@ function usePrefersReducedMotion() {
|
|
|
1975
2008
|
return prefersReducedMotion;
|
|
1976
2009
|
}
|
|
1977
2010
|
//#endregion
|
|
2011
|
+
//#region src/hooks/use-isomorphic-layout-effect.ts
|
|
2012
|
+
const useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
|
|
2013
|
+
//#endregion
|
|
1978
2014
|
//#region src/providers/chart-context/hooks/use-chart-registration.ts
|
|
1979
2015
|
const useChartRegistration = ({ chartId, legendItems, chartType, isDataValid, metadata }) => {
|
|
1980
2016
|
const { registerChart, unregisterChart } = useGlobalChartsContext();
|
|
@@ -2447,6 +2483,30 @@ var base_tooltip_module_default = {
|
|
|
2447
2483
|
"tooltip": "a8ccharts--zY0xG-tooltip"
|
|
2448
2484
|
};
|
|
2449
2485
|
//#endregion
|
|
2486
|
+
//#region src/components/tooltip/private/tooltip-theme.tsx
|
|
2487
|
+
const DEFAULT_SURFACE = "#1e1e1e";
|
|
2488
|
+
const TOOLTIP_SURFACE = `var(--a8c-charts-color-tooltip-surface, ${DEFAULT_SURFACE})`;
|
|
2489
|
+
const toSeed = (value) => {
|
|
2490
|
+
const parsed = value ? color(value) : null;
|
|
2491
|
+
return parsed && parsed.opacity === 1 ? parsed.formatHex() : DEFAULT_SURFACE;
|
|
2492
|
+
};
|
|
2493
|
+
/**
|
|
2494
|
+
* Themes the tooltip box for its dark surface, as `@wordpress/ui`'s Tooltip themes its popup. The box re-declares the catalog under this theme, so every role it reads is tuned for the surface, whatever theme the chart is in.
|
|
2495
|
+
*
|
|
2496
|
+
* @param props - Component props.
|
|
2497
|
+
* @param props.children - The tooltip box.
|
|
2498
|
+
* @return The themed box.
|
|
2499
|
+
*/
|
|
2500
|
+
const TooltipTheme = ({ children }) => {
|
|
2501
|
+
const scopeElement = useChartScopeElement();
|
|
2502
|
+
const color = useMemo(() => ({ background: toSeed(resolveCssVariable(TOOLTIP_SURFACE, scopeElement)) }), [scopeElement]);
|
|
2503
|
+
if (!ThemeProvider) return /* @__PURE__ */ jsx(Fragment$1, { children });
|
|
2504
|
+
return /* @__PURE__ */ jsx(ThemeProvider, {
|
|
2505
|
+
color,
|
|
2506
|
+
children
|
|
2507
|
+
});
|
|
2508
|
+
};
|
|
2509
|
+
//#endregion
|
|
2450
2510
|
//#region src/components/tooltip/base-tooltip.tsx
|
|
2451
2511
|
const DefaultTooltipContent = ({ data }) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
2452
2512
|
data?.label,
|
|
@@ -2458,10 +2518,9 @@ const BaseTooltip = ({ data, top, left, component: Component = DefaultTooltipCon
|
|
|
2458
2518
|
data,
|
|
2459
2519
|
className
|
|
2460
2520
|
});
|
|
2461
|
-
const standaloneScopeClass = useStandaloneScopeClass();
|
|
2462
2521
|
if (!renderContainer) return content;
|
|
2463
|
-
return /* @__PURE__ */ jsx("div", {
|
|
2464
|
-
className: clsx(
|
|
2522
|
+
return /* @__PURE__ */ jsx(TooltipTheme, { children: /* @__PURE__ */ jsx("div", {
|
|
2523
|
+
className: clsx(CHART_SCOPE_CLASS, base_tooltip_module_default.tooltip),
|
|
2465
2524
|
style: {
|
|
2466
2525
|
top,
|
|
2467
2526
|
left,
|
|
@@ -2469,7 +2528,7 @@ const BaseTooltip = ({ data, top, left, component: Component = DefaultTooltipCon
|
|
|
2469
2528
|
},
|
|
2470
2529
|
role: "tooltip",
|
|
2471
2530
|
children: content
|
|
2472
|
-
});
|
|
2531
|
+
}) });
|
|
2473
2532
|
};
|
|
2474
2533
|
//#endregion
|
|
2475
2534
|
//#region src/components/tooltip/private/bounded-tooltip.tsx
|
|
@@ -2484,6 +2543,11 @@ const isClipping = (element) => {
|
|
|
2484
2543
|
overflowY
|
|
2485
2544
|
].some((value) => value && value !== "visible");
|
|
2486
2545
|
};
|
|
2546
|
+
const findLayoutParent = (node) => {
|
|
2547
|
+
let element = node.parentElement;
|
|
2548
|
+
while (element && getComputedStyle(element).display === "contents") element = element.parentElement;
|
|
2549
|
+
return element;
|
|
2550
|
+
};
|
|
2487
2551
|
const findClippingAncestor = (wrapper) => {
|
|
2488
2552
|
let element = wrapper.parentElement;
|
|
2489
2553
|
while (element && element !== document.body) {
|
|
@@ -2558,19 +2622,20 @@ const getBoundedPosition = ({ left, top, offsetLeft, offsetTop, box, wrapper, bo
|
|
|
2558
2622
|
* @param props.top - Anchor y, in wrapper coordinates.
|
|
2559
2623
|
* @param props.offsetLeft - Gap between the anchor and the box, horizontally.
|
|
2560
2624
|
* @param props.offsetTop - Gap between the anchor and the box, vertically.
|
|
2561
|
-
* @param props.style -
|
|
2562
|
-
* @param props.unstyled -
|
|
2625
|
+
* @param props.style - Inline overrides on the surface; ignored when `unstyled`.
|
|
2626
|
+
* @param props.unstyled - Drop the surface and `style`, leaving the box bare.
|
|
2627
|
+
* @param props.className - Extra classes beside the surface.
|
|
2563
2628
|
* @param props.children - Box content.
|
|
2564
2629
|
* @param props.placement - Below-axis, beside without vertical flipping, or automatic flipping.
|
|
2565
2630
|
* @return The tooltip box.
|
|
2566
2631
|
*/
|
|
2567
|
-
const BoundedTooltip = ({ left = 0, top = 0, offsetLeft = DEFAULT_OFFSET, offsetTop = DEFAULT_OFFSET, style
|
|
2632
|
+
const BoundedTooltip = ({ left = 0, top = 0, offsetLeft = DEFAULT_OFFSET, offsetTop = DEFAULT_OFFSET, style, unstyled = false, className, children, placement = "auto", ...rest }) => {
|
|
2568
2633
|
const nodeRef = useRef(null);
|
|
2569
2634
|
const clipRef = useRef(null);
|
|
2570
2635
|
const [position, setPosition] = useState(null);
|
|
2571
2636
|
useLayoutEffect(() => {
|
|
2572
2637
|
const node = nodeRef.current;
|
|
2573
|
-
const wrapper = node
|
|
2638
|
+
const wrapper = node && findLayoutParent(node);
|
|
2574
2639
|
if (!node || !wrapper) return;
|
|
2575
2640
|
if (clipRef.current?.wrapper !== wrapper) clipRef.current = {
|
|
2576
2641
|
wrapper,
|
|
@@ -2618,8 +2683,9 @@ const BoundedTooltip = ({ left = 0, top = 0, offsetLeft = DEFAULT_OFFSET, offset
|
|
|
2618
2683
|
]);
|
|
2619
2684
|
const x = position?.x ?? left + offsetLeft;
|
|
2620
2685
|
const y = position?.y ?? top + (placement === "below-axis" ? POINTER_HEIGHT : offsetTop);
|
|
2621
|
-
|
|
2686
|
+
const box = /* @__PURE__ */ jsxs(Tooltip, {
|
|
2622
2687
|
ref: nodeRef,
|
|
2688
|
+
className: clsx(!unstyled && ["a8c-charts-tooltip-scope", base_tooltip_module_default.surface], className),
|
|
2623
2689
|
style: {
|
|
2624
2690
|
position: "absolute",
|
|
2625
2691
|
left: 0,
|
|
@@ -2635,13 +2701,14 @@ const BoundedTooltip = ({ left = 0, top = 0, offsetLeft = DEFAULT_OFFSET, offset
|
|
|
2635
2701
|
left: left - x - POINTER_HEIGHT,
|
|
2636
2702
|
top: -6,
|
|
2637
2703
|
width: 12,
|
|
2638
|
-
height:
|
|
2704
|
+
height: 7,
|
|
2639
2705
|
background: "inherit",
|
|
2640
|
-
clipPath:
|
|
2706
|
+
clipPath: `polygon(50% 0, 100% ${POINTER_HEIGHT}px, 100% 100%, 0 100%, 0 ${POINTER_HEIGHT}px)`,
|
|
2641
2707
|
pointerEvents: "none"
|
|
2642
2708
|
}
|
|
2643
2709
|
}), children]
|
|
2644
2710
|
});
|
|
2711
|
+
return unstyled ? box : /* @__PURE__ */ jsx(TooltipTheme, { children: box });
|
|
2645
2712
|
};
|
|
2646
2713
|
//#endregion
|
|
2647
2714
|
//#region src/components/tooltip/xy-chart-tooltip.tsx
|
|
@@ -2748,13 +2815,20 @@ const XyChartTooltipContent = ({ tooltipContext, container, renderTooltip, rende
|
|
|
2748
2815
|
const marginLeft = margin?.left ?? 0;
|
|
2749
2816
|
const TooltipComponent = detectBounds || tooltipPlacement !== "auto" ? BoundedTooltip : Tooltip;
|
|
2750
2817
|
const boxStyle = {
|
|
2751
|
-
...defaultStyles,
|
|
2752
2818
|
zIndex,
|
|
2753
|
-
backgroundColor: theme?.backgroundColor ?? "white",
|
|
2754
|
-
boxShadow: `0 1px 2px ${isValidHexColor(theme?.htmlLabel?.color) ? `${theme.htmlLabel.color}55` : "#22222255"}`,
|
|
2755
|
-
...theme?.htmlLabel,
|
|
2756
2819
|
...style
|
|
2757
2820
|
};
|
|
2821
|
+
const themesOwnBox = TooltipComponent === Tooltip && !tooltipProps.unstyled;
|
|
2822
|
+
const box = /* @__PURE__ */ jsx(TooltipComponent, {
|
|
2823
|
+
left: tooltipLeft,
|
|
2824
|
+
top: tooltipPlacement === "below-axis" ? marginTop + innerHeight + (margin?.bottom ?? 0) : tooltipAnchorTop ?? tooltipTop,
|
|
2825
|
+
style: boxStyle,
|
|
2826
|
+
applyPositionStyle: true,
|
|
2827
|
+
...tooltipProps,
|
|
2828
|
+
className: clsx(themesOwnBox && ["a8c-charts-scope", base_tooltip_module_default.surface], tooltipProps.className),
|
|
2829
|
+
...tooltipPlacement !== "auto" && { placement: tooltipPlacement },
|
|
2830
|
+
children: tooltipContent
|
|
2831
|
+
});
|
|
2758
2832
|
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs("g", {
|
|
2759
2833
|
className: "visx-tooltip-overlay",
|
|
2760
2834
|
pointerEvents: "none",
|
|
@@ -2781,15 +2855,7 @@ const XyChartTooltipContent = ({ tooltipContext, container, renderTooltip, rende
|
|
|
2781
2855
|
}),
|
|
2782
2856
|
glyphs
|
|
2783
2857
|
]
|
|
2784
|
-
}), container && createPortal(/* @__PURE__ */ jsx(
|
|
2785
|
-
left: tooltipLeft,
|
|
2786
|
-
top: tooltipPlacement === "below-axis" ? marginTop + innerHeight + (margin?.bottom ?? 0) : tooltipAnchorTop ?? tooltipTop,
|
|
2787
|
-
style: boxStyle,
|
|
2788
|
-
applyPositionStyle: true,
|
|
2789
|
-
...tooltipProps,
|
|
2790
|
-
...tooltipPlacement !== "auto" && { placement: tooltipPlacement },
|
|
2791
|
-
children: tooltipContent
|
|
2792
|
-
}), container)] });
|
|
2858
|
+
}), container && createPortal(themesOwnBox ? /* @__PURE__ */ jsx(TooltipTheme, { children: box }) : box, container)] });
|
|
2793
2859
|
};
|
|
2794
2860
|
/**
|
|
2795
2861
|
* In-tree replacement for `@visx/xychart`'s `Tooltip`.
|
|
@@ -3056,7 +3122,6 @@ const useKeyboardNavigation = ({ selectedIndex, setSelectedIndex, isNavigating,
|
|
|
3056
3122
|
};
|
|
3057
3123
|
//#endregion
|
|
3058
3124
|
//#region src/providers/chart-context/hooks/use-default-hidden-series.ts
|
|
3059
|
-
const useIsomorphicLayoutEffect$1 = typeof window !== "undefined" ? useLayoutEffect : useEffect;
|
|
3060
3125
|
/**
|
|
3061
3126
|
* Seeds a chart's hidden series once per chart ID, the first time the provider
|
|
3062
3127
|
* sees that ID.
|
|
@@ -3077,7 +3142,7 @@ const useDefaultHiddenSeries = (chartId, seriesLabels) => {
|
|
|
3077
3142
|
labelsRef.current = seriesLabels;
|
|
3078
3143
|
const hasSeriesLabels = seriesLabels !== void 0;
|
|
3079
3144
|
const shouldUseDefaults = hasSeriesLabels && !hasSeededChart(chartId);
|
|
3080
|
-
useIsomorphicLayoutEffect
|
|
3145
|
+
useIsomorphicLayoutEffect(() => {
|
|
3081
3146
|
if (labelsRef.current === void 0) return;
|
|
3082
3147
|
seedChartHiddenSeries(chartId, labelsRef.current);
|
|
3083
3148
|
}, [
|
|
@@ -3702,7 +3767,6 @@ var with_responsive_module_default = {
|
|
|
3702
3767
|
};
|
|
3703
3768
|
//#endregion
|
|
3704
3769
|
//#region src/charts/private/with-responsive/with-responsive.tsx
|
|
3705
|
-
const useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
|
|
3706
3770
|
/**
|
|
3707
3771
|
* A higher-order component that provides responsive dimensions
|
|
3708
3772
|
* to the wrapped chart component using useParentSize from `@visx/responsive`.
|
|
@@ -3986,10 +4050,8 @@ var line_chart_module_default = {
|
|
|
3986
4050
|
"line-chart__annotation-label-popover-content": "a8ccharts-inuQka-line-chart__annotation-label-popover-content",
|
|
3987
4051
|
"line-chart__annotation-label-trigger-button": "a8ccharts-inuQka-line-chart__annotation-label-trigger-button",
|
|
3988
4052
|
"line-chart__annotations-overlay": "a8ccharts-inuQka-line-chart__annotations-overlay",
|
|
3989
|
-
"line-chart__tooltip": "a8ccharts-inuQka-line-chart__tooltip",
|
|
3990
4053
|
"line-chart__tooltip-date": "a8ccharts-inuQka-line-chart__tooltip-date",
|
|
3991
4054
|
"line-chart__tooltip-label": "a8ccharts-inuQka-line-chart__tooltip-label",
|
|
3992
|
-
"line-chart__tooltip-row": "a8ccharts-inuQka-line-chart__tooltip-row",
|
|
3993
4055
|
"line-chart--animated": "a8ccharts-inuQka-line-chart--animated",
|
|
3994
4056
|
"rise": "a8ccharts-inuQka-rise"
|
|
3995
4057
|
};
|
|
@@ -4516,11 +4578,10 @@ const TooltipDate = ({ date, displayResolution }) => {
|
|
|
4516
4578
|
* one row per visible series (label + formatted value), sorted descending by
|
|
4517
4579
|
* value. Reused by AreaChart, which has the same multi-series shape.
|
|
4518
4580
|
*
|
|
4519
|
-
* @param params
|
|
4520
|
-
* @param contentStyle - Explicit tooltip content color overrides.
|
|
4581
|
+
* @param params - visx tooltip data and the chart's optional `bucketInfo`.
|
|
4521
4582
|
* @return Tooltip JSX, or `null` when no datum is hovered.
|
|
4522
4583
|
*/
|
|
4523
|
-
const renderDefaultTooltip = (params
|
|
4584
|
+
const renderDefaultTooltip = (params) => {
|
|
4524
4585
|
const { tooltipData, bucketInfo } = params;
|
|
4525
4586
|
const nearestDatum = tooltipData?.nearestDatum?.datum;
|
|
4526
4587
|
if (!nearestDatum) return null;
|
|
@@ -4533,29 +4594,24 @@ const renderDefaultTooltip = (params, contentStyle) => {
|
|
|
4533
4594
|
if (b.value === null) return -1;
|
|
4534
4595
|
return b.value - a.value;
|
|
4535
4596
|
});
|
|
4536
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
4537
|
-
className: line_chart_module_default["line-chart__tooltip"],
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
className: line_chart_module_default["line-chart__tooltip-value"],
|
|
4555
|
-
children: formatReading(point.value)
|
|
4556
|
-
})]
|
|
4557
|
-
}, point.key))]
|
|
4558
|
-
});
|
|
4597
|
+
return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("div", {
|
|
4598
|
+
className: line_chart_module_default["line-chart__tooltip-date"],
|
|
4599
|
+
children: /* @__PURE__ */ jsx(TooltipDate, {
|
|
4600
|
+
date: nearestDatum.date,
|
|
4601
|
+
displayResolution: bucketInfo?.displayResolution ?? "day"
|
|
4602
|
+
})
|
|
4603
|
+
}), tooltipPoints.map((point) => /* @__PURE__ */ jsxs(Stack, {
|
|
4604
|
+
direction: "row",
|
|
4605
|
+
align: "center",
|
|
4606
|
+
justify: "space-between",
|
|
4607
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
4608
|
+
className: line_chart_module_default["line-chart__tooltip-label"],
|
|
4609
|
+
children: [point.key, ":"]
|
|
4610
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
4611
|
+
className: line_chart_module_default["line-chart__tooltip-value"],
|
|
4612
|
+
children: formatReading(point.value)
|
|
4613
|
+
})]
|
|
4614
|
+
}, point.key))] });
|
|
4559
4615
|
};
|
|
4560
4616
|
const validateData$4 = (data) => {
|
|
4561
4617
|
if (!data?.length) return __("No data available", "jetpack-charts");
|
|
@@ -4815,29 +4871,10 @@ const LineChartInternal = forwardRef(({ data, chartId: providedChartId, width, h
|
|
|
4815
4871
|
xAccessor: (d) => d?.date,
|
|
4816
4872
|
yAccessor: (d) => d?.value
|
|
4817
4873
|
};
|
|
4818
|
-
const
|
|
4819
|
-
if (renderTooltip !== renderDefaultTooltip || !tooltipStyle) return tooltipStyle;
|
|
4820
|
-
if (!tooltipStyle.color || tooltipStyle.background || tooltipStyle.backgroundColor) return tooltipStyle;
|
|
4821
|
-
return {
|
|
4822
|
-
backgroundColor: "var(--a8c-charts-color-tooltip-surface, rgb(0 0 0 / 85%))",
|
|
4823
|
-
...tooltipStyle
|
|
4824
|
-
};
|
|
4825
|
-
}, [renderTooltip, tooltipStyle]);
|
|
4826
|
-
const tooltipRenderer = useMemo(() => (params) => renderTooltip === renderDefaultTooltip ? renderDefaultTooltip({
|
|
4827
|
-
...params,
|
|
4828
|
-
bucketInfo
|
|
4829
|
-
}, {
|
|
4830
|
-
color: tooltipStyle?.color,
|
|
4831
|
-
background: tooltipStyle?.background,
|
|
4832
|
-
backgroundColor: tooltipStyle?.backgroundColor
|
|
4833
|
-
}) : renderTooltip({
|
|
4874
|
+
const tooltipRenderer = useMemo(() => (params) => renderTooltip({
|
|
4834
4875
|
...params,
|
|
4835
4876
|
bucketInfo
|
|
4836
|
-
}), [
|
|
4837
|
-
renderTooltip,
|
|
4838
|
-
bucketInfo,
|
|
4839
|
-
tooltipStyle
|
|
4840
|
-
]);
|
|
4877
|
+
}), [renderTooltip, bucketInfo]);
|
|
4841
4878
|
if (error) return /* @__PURE__ */ jsx("div", {
|
|
4842
4879
|
className: clsx("line-chart", line_chart_module_default["line-chart"]),
|
|
4843
4880
|
children: error
|
|
@@ -4985,7 +5022,7 @@ const LineChartInternal = forwardRef(({ data, chartId: providedChartId, width, h
|
|
|
4985
5022
|
detectBounds: true,
|
|
4986
5023
|
snapTooltipToDatumX: true,
|
|
4987
5024
|
tooltipPlacement,
|
|
4988
|
-
style:
|
|
5025
|
+
style: tooltipStyle,
|
|
4989
5026
|
snapTooltipToDatumY: true,
|
|
4990
5027
|
showSeriesGlyphs: true,
|
|
4991
5028
|
renderTooltip: tooltipRenderer,
|
|
@@ -6893,8 +6930,7 @@ var conversion_funnel_chart_module_default = {
|
|
|
6893
6930
|
"step-rate": "a8ccharts-mGEVca-step-rate",
|
|
6894
6931
|
"stretch": "a8ccharts-mGEVca-stretch",
|
|
6895
6932
|
"tooltip-content": "a8ccharts-mGEVca-tooltip-content",
|
|
6896
|
-
"tooltip-title": "a8ccharts-mGEVca-tooltip-title"
|
|
6897
|
-
"tooltip-wrapper": "a8ccharts-mGEVca-tooltip-wrapper"
|
|
6933
|
+
"tooltip-title": "a8ccharts-mGEVca-tooltip-title"
|
|
6898
6934
|
};
|
|
6899
6935
|
//#endregion
|
|
6900
6936
|
//#region src/charts/conversion-funnel-chart/private/use-funnel-selection.ts
|
|
@@ -6955,9 +6991,10 @@ const useFunnelSelection = (hideTooltip) => {
|
|
|
6955
6991
|
* @param props.renderStepRate - Custom render function for step rates
|
|
6956
6992
|
* @param props.renderMainMetric - Custom render function for the entire main metric section
|
|
6957
6993
|
* @param props.renderTooltip - Custom render function for tooltip content
|
|
6994
|
+
* @param props.tooltipStyle - Inline styles merged over the tooltip box defaults
|
|
6958
6995
|
* @return JSX element representing the conversion funnel chart
|
|
6959
6996
|
*/
|
|
6960
|
-
const ConversionFunnelChartInternal = ({ mainRate, changeIndicator, steps, loading = false, animation, className, chartId: providedChartId, height, style, renderStepLabel, renderStepRate, renderMainMetric, renderTooltip }) => {
|
|
6997
|
+
const ConversionFunnelChartInternal = ({ mainRate, changeIndicator, steps, loading = false, animation, className, chartId: providedChartId, height, style, renderStepLabel, renderStepRate, renderMainMetric, renderTooltip, tooltipStyle }) => {
|
|
6961
6998
|
const chartId = useChartId(providedChartId);
|
|
6962
6999
|
const { getElementStyles, isColorPaletteResolved } = useGlobalChartsContext();
|
|
6963
7000
|
const chartRef = useRef(null);
|
|
@@ -7192,14 +7229,14 @@ const ConversionFunnelChartInternal = ({ mainRate, changeIndicator, steps, loadi
|
|
|
7192
7229
|
step: tooltipData,
|
|
7193
7230
|
index: steps.findIndex((s) => s.id === tooltipData.id),
|
|
7194
7231
|
top: tooltipTop,
|
|
7195
|
-
left: tooltipLeft
|
|
7196
|
-
className: conversion_funnel_chart_module_default["tooltip-wrapper"]
|
|
7232
|
+
left: tooltipLeft
|
|
7197
7233
|
}) : renderDefaultTooltip(tooltipData);
|
|
7198
7234
|
if (!tooltipContent) return null;
|
|
7199
7235
|
return /* @__PURE__ */ jsx(BoundedTooltip, {
|
|
7200
7236
|
top: tooltipTop,
|
|
7201
7237
|
left: tooltipLeft,
|
|
7202
|
-
className:
|
|
7238
|
+
className: standaloneScopeClass,
|
|
7239
|
+
style: tooltipStyle,
|
|
7203
7240
|
children: tooltipContent
|
|
7204
7241
|
});
|
|
7205
7242
|
})()]
|
|
@@ -7485,6 +7522,73 @@ let GoogleDataTableColumnRoleType = /* @__PURE__ */ function(GoogleDataTableColu
|
|
|
7485
7522
|
GoogleDataTableColumnRoleType["domain"] = "domain";
|
|
7486
7523
|
return GoogleDataTableColumnRoleType;
|
|
7487
7524
|
}({});
|
|
7525
|
+
const resolveRole = (pointer, resolve) => {
|
|
7526
|
+
const raw = resolve(pointer);
|
|
7527
|
+
const parsed = raw ? color(raw) : null;
|
|
7528
|
+
if (!parsed) return {
|
|
7529
|
+
kind: "unreadable",
|
|
7530
|
+
raw
|
|
7531
|
+
};
|
|
7532
|
+
const { r, g, b } = parsed.opacity > 0 ? parsed.rgb() : {
|
|
7533
|
+
r: 0,
|
|
7534
|
+
g: 0,
|
|
7535
|
+
b: 0
|
|
7536
|
+
};
|
|
7537
|
+
return {
|
|
7538
|
+
kind: "color",
|
|
7539
|
+
rgb: [
|
|
7540
|
+
r,
|
|
7541
|
+
g,
|
|
7542
|
+
b
|
|
7543
|
+
],
|
|
7544
|
+
alpha: parsed.opacity
|
|
7545
|
+
};
|
|
7546
|
+
};
|
|
7547
|
+
/**
|
|
7548
|
+
* Reads both label roles at the element the label text inherits from, so JS and CSS agree on what paints.
|
|
7549
|
+
*
|
|
7550
|
+
* @param resolve - A CSS variable resolver bound to that element.
|
|
7551
|
+
* @return The resolved label roles.
|
|
7552
|
+
*/
|
|
7553
|
+
const resolveLabelRoles = (resolve) => ({
|
|
7554
|
+
label: resolveRole(CATALOG_POINTERS.label, resolve),
|
|
7555
|
+
labelInverse: resolveRole(CATALOG_POINTERS.labelInverse, resolve)
|
|
7556
|
+
});
|
|
7557
|
+
const roleContrast = (role, fill, fillLuminance) => {
|
|
7558
|
+
if (role.kind === "unreadable") return 0;
|
|
7559
|
+
return luminanceContrastRatio(fillLuminance, rgbLuminance(blendRgb(role.rgb, fill, role.alpha)));
|
|
7560
|
+
};
|
|
7561
|
+
/**
|
|
7562
|
+
* Picks the label color for text drawn on a fill: the role that contrasts more, or black/white when neither reaches AA.
|
|
7563
|
+
*
|
|
7564
|
+
* Both roles set to one color is a host's choice to keep that color, so it never falls back.
|
|
7565
|
+
*
|
|
7566
|
+
* @param fill - The fill the text sits on, as unrounded sRGB channels.
|
|
7567
|
+
* @param roles - The label roles resolved at the chart's element, or null before they are read.
|
|
7568
|
+
* @param defaultRole - The role the chart's stylesheet paints when nothing can be decided.
|
|
7569
|
+
* @return The color the label should paint with.
|
|
7570
|
+
*/
|
|
7571
|
+
const pickLabelTextColorForFill = (fill, roles, defaultRole) => {
|
|
7572
|
+
if (!roles || (0, import_fast_deep_equal.default)(roles.label, roles.labelInverse)) return defaultRole;
|
|
7573
|
+
const fillLuminance = rgbLuminance(fill);
|
|
7574
|
+
const labelContrast = roleContrast(roles.label, fill, fillLuminance);
|
|
7575
|
+
const inverseContrast = roleContrast(roles.labelInverse, fill, fillLuminance);
|
|
7576
|
+
if (Math.max(labelContrast, inverseContrast) >= 4.55) return labelContrast > inverseContrast ? "label" : "label-inverse";
|
|
7577
|
+
return luminanceContrastRatio(fillLuminance, 0) > luminanceContrastRatio(fillLuminance, 1) ? "black" : "white";
|
|
7578
|
+
};
|
|
7579
|
+
/**
|
|
7580
|
+
* `pickLabelTextColorForFill` for a fill given as a color.
|
|
7581
|
+
*
|
|
7582
|
+
* @param fill - The fill, in any color syntax `normalizeColorToHex` reads.
|
|
7583
|
+
* @param roles - The label roles resolved at the chart's element, or null before they are read.
|
|
7584
|
+
* @param defaultRole - The role the chart's stylesheet paints when nothing can be decided.
|
|
7585
|
+
* @return The color the label should paint with.
|
|
7586
|
+
*/
|
|
7587
|
+
const pickLabelTextColor = (fill, roles, defaultRole) => {
|
|
7588
|
+
const fillHex = normalizeColorToHex(fill);
|
|
7589
|
+
if (!isValidHexColor(fillHex)) return defaultRole;
|
|
7590
|
+
return pickLabelTextColorForFill(hexToRgb(fillHex), roles, defaultRole);
|
|
7591
|
+
};
|
|
7488
7592
|
//#endregion
|
|
7489
7593
|
//#region src/charts/heatmap-chart/heatmap-chart.module.scss
|
|
7490
7594
|
var heatmap_chart_module_default = {
|
|
@@ -7494,9 +7598,11 @@ var heatmap_chart_module_default = {
|
|
|
7494
7598
|
"heatmap-chart__cell--hidden": "a8ccharts-O3YMOW-heatmap-chart__cell--hidden",
|
|
7495
7599
|
"heatmap-chart__cell--placeholder": "a8ccharts-O3YMOW-heatmap-chart__cell--placeholder",
|
|
7496
7600
|
"heatmap-chart__cell--selected": "a8ccharts-O3YMOW-heatmap-chart__cell--selected",
|
|
7497
|
-
"heatmap-chart__cell--strong": "a8ccharts-O3YMOW-heatmap-chart__cell--strong",
|
|
7498
7601
|
"heatmap-chart__cell--summary": "a8ccharts-O3YMOW-heatmap-chart__cell--summary",
|
|
7499
7602
|
"heatmap-chart__cell-value": "a8ccharts-O3YMOW-heatmap-chart__cell-value",
|
|
7603
|
+
"heatmap-chart__cell-value--black": "a8ccharts-O3YMOW-heatmap-chart__cell-value--black",
|
|
7604
|
+
"heatmap-chart__cell-value--inverse": "a8ccharts-O3YMOW-heatmap-chart__cell-value--inverse",
|
|
7605
|
+
"heatmap-chart__cell-value--white": "a8ccharts-O3YMOW-heatmap-chart__cell-value--white",
|
|
7500
7606
|
"heatmap-chart__col-label": "a8ccharts-O3YMOW-heatmap-chart__col-label",
|
|
7501
7607
|
"heatmap-chart__col-label--summary": "a8ccharts-O3YMOW-heatmap-chart__col-label--summary",
|
|
7502
7608
|
"heatmap-chart__empty": "a8ccharts-O3YMOW-heatmap-chart__empty",
|
|
@@ -7790,25 +7896,25 @@ const stepCalendarCell = (grid, blocks, from, key) => {
|
|
|
7790
7896
|
//#endregion
|
|
7791
7897
|
//#region src/charts/heatmap-chart/heatmap-chart.tsx
|
|
7792
7898
|
const CELL_MIX_FLOOR = .15;
|
|
7793
|
-
const
|
|
7794
|
-
|
|
7795
|
-
|
|
7796
|
-
|
|
7797
|
-
|
|
7798
|
-
},
|
|
7799
|
-
dark: { zIndex: 3 }
|
|
7899
|
+
const CELL_VALUE_MODIFIER = {
|
|
7900
|
+
label: void 0,
|
|
7901
|
+
"label-inverse": heatmap_chart_module_default["heatmap-chart__cell-value--inverse"],
|
|
7902
|
+
black: heatmap_chart_module_default["heatmap-chart__cell-value--black"],
|
|
7903
|
+
white: heatmap_chart_module_default["heatmap-chart__cell-value--white"]
|
|
7800
7904
|
};
|
|
7905
|
+
const NO_ROW_LABELS = [];
|
|
7906
|
+
const TOOLTIP_BOX_STYLE = { zIndex: 3 };
|
|
7801
7907
|
const cellName = (info) => info.cellLabel || [
|
|
7802
7908
|
info.groupLabel,
|
|
7803
7909
|
info.columnLabel,
|
|
7804
7910
|
info.rowLabel
|
|
7805
7911
|
].filter(Boolean).join(" ");
|
|
7806
|
-
const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, height = 0, className, compact = false, showValues, maxCellWidth, maxCellHeight, minCellWidth, minCellHeight, rowLabels = NO_ROW_LABELS, columnGroups, keyboardNavigation = "grid", ariaLabel, primaryColor, gap = "md", withTooltips = false, renderTooltip,
|
|
7912
|
+
const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, height = 0, className, compact = false, showValues, maxCellWidth, maxCellHeight, minCellWidth, minCellHeight, rowLabels = NO_ROW_LABELS, columnGroups, keyboardNavigation = "grid", ariaLabel, primaryColor, gap = "md", withTooltips = false, renderTooltip, tooltipStyle, children }) => {
|
|
7807
7913
|
const chartId = useChartId(providedChartId);
|
|
7808
7914
|
const tooltipBoxStyle = tooltipStyle ? {
|
|
7809
|
-
...
|
|
7915
|
+
...TOOLTIP_BOX_STYLE,
|
|
7810
7916
|
...tooltipStyle
|
|
7811
|
-
} :
|
|
7917
|
+
} : TOOLTIP_BOX_STYLE;
|
|
7812
7918
|
const { getElementStyles, theme } = useGlobalChartsContext();
|
|
7813
7919
|
const scopeElement = useChartScopeElement();
|
|
7814
7920
|
const { heatmapChart: heatmapChartSettings } = theme;
|
|
@@ -7817,6 +7923,7 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
|
|
|
7817
7923
|
const { tooltipOpen, tooltipLeft, tooltipTop, tooltipData, showTooltip, hideTooltip } = useTooltip();
|
|
7818
7924
|
const standaloneScopeClass = useStandaloneScopeClass();
|
|
7819
7925
|
const containerRef = useRef(null);
|
|
7926
|
+
const [labelRoles, setLabelRoles] = useState(null);
|
|
7820
7927
|
const getTooltipOrigin = useCallback(() => containerRef.current?.closest(`[data-chart-id="heatmap-chart-${chartId}"]`)?.getBoundingClientRect() ?? null, [chartId]);
|
|
7821
7928
|
const { color: primaryColorHex } = getElementStyles({
|
|
7822
7929
|
index: 0,
|
|
@@ -7824,7 +7931,21 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
|
|
|
7824
7931
|
});
|
|
7825
7932
|
const chartBackgroundHex = normalizeColorToHex(CATALOG_POINTERS.background, scopeElement, resolveCssVariable);
|
|
7826
7933
|
const primaryHex = normalizeColorToHex(primaryColorHex);
|
|
7827
|
-
const
|
|
7934
|
+
const cellMix = isValidHexColor(primaryHex) && isValidHexColor(chartBackgroundHex) ? {
|
|
7935
|
+
primary: hexToRgb(primaryHex),
|
|
7936
|
+
background: hexToRgb(chartBackgroundHex)
|
|
7937
|
+
} : null;
|
|
7938
|
+
const cellTextColor = (intensity) => cellMix ? pickLabelTextColorForFill(blendRgb(cellMix.primary, cellMix.background, CELL_MIX_FLOOR + .85 * intensity), labelRoles, "label") : "label";
|
|
7939
|
+
useIsomorphicLayoutEffect(() => {
|
|
7940
|
+
if (!containerRef.current) return;
|
|
7941
|
+
const next = resolveLabelRoles(createCssVariableResolver(containerRef.current));
|
|
7942
|
+
setLabelRoles((previous) => (0, import_fast_deep_equal.default)(previous, next) ? previous : next);
|
|
7943
|
+
}, [
|
|
7944
|
+
data,
|
|
7945
|
+
className,
|
|
7946
|
+
primaryColorHex,
|
|
7947
|
+
chartBackgroundHex
|
|
7948
|
+
]);
|
|
7828
7949
|
const extent = useMemo(() => getValueExtent(data), [data]);
|
|
7829
7950
|
const heatmapContext = useMemo(() => ({
|
|
7830
7951
|
extent,
|
|
@@ -8096,7 +8217,6 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
|
|
|
8096
8217
|
"data-row": rowIndex,
|
|
8097
8218
|
className: clsx(heatmap_chart_module_default["heatmap-chart__cell"], {
|
|
8098
8219
|
[heatmap_chart_module_default["heatmap-chart__cell--filled"]]: filled,
|
|
8099
|
-
[heatmap_chart_module_default["heatmap-chart__cell--strong"]]: filled && cellHasLightText(normalized),
|
|
8100
8220
|
[heatmap_chart_module_default["heatmap-chart__cell--summary"]]: column.summary,
|
|
8101
8221
|
...summaryGaps(columnIndex),
|
|
8102
8222
|
[heatmap_chart_module_default["heatmap-chart__cell--selected"]]: selected?.column === columnIndex && selected?.row === rowIndex
|
|
@@ -8108,7 +8228,7 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
|
|
|
8108
8228
|
onMouseMove: handleCellMouseMove,
|
|
8109
8229
|
onMouseLeave: handleCellMouseLeave,
|
|
8110
8230
|
children: (drawValues || column.summary) && present && /* @__PURE__ */ jsx("span", {
|
|
8111
|
-
className: heatmap_chart_module_default["heatmap-chart__cell-value"],
|
|
8231
|
+
className: clsx(heatmap_chart_module_default["heatmap-chart__cell-value"], filled && CELL_VALUE_MODIFIER[cellTextColor(normalized)]),
|
|
8112
8232
|
children: formatNumberCompact(value)
|
|
8113
8233
|
})
|
|
8114
8234
|
}, `cell-${columnIndex}-${rowIndex}`);
|
|
@@ -8132,7 +8252,6 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
|
|
|
8132
8252
|
}), withTooltips && tooltipOpen && tooltipData && /* @__PURE__ */ jsx(BoundedTooltip, {
|
|
8133
8253
|
top: tooltipTop,
|
|
8134
8254
|
left: tooltipLeft,
|
|
8135
|
-
className: tooltipVariant === "dark" ? base_tooltip_module_default.surface : void 0,
|
|
8136
8255
|
style: tooltipBoxStyle,
|
|
8137
8256
|
children: /* @__PURE__ */ jsx("div", {
|
|
8138
8257
|
className: standaloneScopeClass,
|
|
@@ -11359,7 +11478,9 @@ function RadialWipeAnimation({ id, radius, innerRadius = 0, durationMs = 1e3, wi
|
|
|
11359
11478
|
var pie_chart_module_default = {
|
|
11360
11479
|
"pie-chart__label-plate": "a8ccharts-gnszbG-pie-chart__label-plate",
|
|
11361
11480
|
"pie-chart__label-text": "a8ccharts-gnszbG-pie-chart__label-text",
|
|
11481
|
+
"pie-chart__label-text--black": "a8ccharts-gnszbG-pie-chart__label-text--black",
|
|
11362
11482
|
"pie-chart__label-text--on-light": "a8ccharts-gnszbG-pie-chart__label-text--on-light",
|
|
11483
|
+
"pie-chart__label-text--white": "a8ccharts-gnszbG-pie-chart__label-text--white",
|
|
11363
11484
|
"pie-chart__plot": "a8ccharts-gnszbG-pie-chart__plot",
|
|
11364
11485
|
"pie-chart--responsive": "a8ccharts-gnszbG-pie-chart--responsive"
|
|
11365
11486
|
};
|
|
@@ -11403,24 +11524,11 @@ const validateData$1 = (data) => {
|
|
|
11403
11524
|
message: ""
|
|
11404
11525
|
};
|
|
11405
11526
|
};
|
|
11406
|
-
|
|
11407
|
-
|
|
11408
|
-
|
|
11409
|
-
|
|
11410
|
-
|
|
11411
|
-
* yet resolved, or labels off) keep the default inverse role.
|
|
11412
|
-
*
|
|
11413
|
-
* @param fill - The slice's resolved fill color.
|
|
11414
|
-
* @param pointers - The label pointers, resolved at the chart's own root element.
|
|
11415
|
-
* @return Whether the label needs dark text.
|
|
11416
|
-
*/
|
|
11417
|
-
const labelNeedsDarkText = (fill, pointers) => {
|
|
11418
|
-
if (!pointers || pointers.hasPlate) return false;
|
|
11419
|
-
const fillHex = normalizeColorToHex(fill);
|
|
11420
|
-
if (!isValidHexColor(fillHex) || !isValidHexColor(pointers.labelHex)) return false;
|
|
11421
|
-
if (pointers.isInverseSeeThrough) return true;
|
|
11422
|
-
if (!isValidHexColor(pointers.labelInverseHex)) return false;
|
|
11423
|
-
return contrastRatio(fillHex, pointers.labelHex) > contrastRatio(fillHex, pointers.labelInverseHex);
|
|
11527
|
+
const LABEL_TEXT_MODIFIER = {
|
|
11528
|
+
label: pie_chart_module_default["pie-chart__label-text--on-light"],
|
|
11529
|
+
"label-inverse": void 0,
|
|
11530
|
+
black: pie_chart_module_default["pie-chart__label-text--black"],
|
|
11531
|
+
white: pie_chart_module_default["pie-chart__label-text--white"]
|
|
11424
11532
|
};
|
|
11425
11533
|
/**
|
|
11426
11534
|
* Renders a pie or donut chart using the provided data.
|
|
@@ -11437,7 +11545,7 @@ const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false
|
|
|
11437
11545
|
const standaloneScopeClass = useStandaloneScopeClass();
|
|
11438
11546
|
const containerRef = useRef(null);
|
|
11439
11547
|
const rootRef = useRef(null);
|
|
11440
|
-
const [
|
|
11548
|
+
const [labelRoles, setLabelRoles] = useState(null);
|
|
11441
11549
|
const onMouseLeave = useCallback(() => {
|
|
11442
11550
|
if (!withTooltips) return;
|
|
11443
11551
|
hideTooltip();
|
|
@@ -11448,18 +11556,9 @@ const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false
|
|
|
11448
11556
|
if (!showLabels || !rootRef.current) return;
|
|
11449
11557
|
const resolve = createCssVariableResolver(rootRef.current);
|
|
11450
11558
|
const rawLabelBackground = resolve(CATALOG_POINTERS.labelBackground);
|
|
11451
|
-
const rawLabel = resolve(CATALOG_POINTERS.label);
|
|
11452
|
-
const isLabelOpaque = rawLabel ? color(rawLabel)?.opacity === 1 : false;
|
|
11453
|
-
const rawLabelInverse = resolve(CATALOG_POINTERS.labelInverse);
|
|
11454
|
-
const labelInverseColor = rawLabelInverse ? color(rawLabelInverse) : null;
|
|
11455
11559
|
const plateColor = rawLabelBackground ? color(rawLabelBackground) : null;
|
|
11456
|
-
const next =
|
|
11457
|
-
|
|
11458
|
-
labelHex: isLabelOpaque ? normalizeColorToHex(CATALOG_POINTERS.label, null, resolve) : "",
|
|
11459
|
-
labelInverseHex: normalizeColorToHex(CATALOG_POINTERS.labelInverse, null, resolve),
|
|
11460
|
-
isInverseSeeThrough: labelInverseColor ? labelInverseColor.opacity < 1 : false
|
|
11461
|
-
};
|
|
11462
|
-
setLabelPointers((previous) => previous && previous.hasPlate === next.hasPlate && previous.labelHex === next.labelHex && previous.labelInverseHex === next.labelInverseHex && previous.isInverseSeeThrough === next.isInverseSeeThrough ? previous : next);
|
|
11560
|
+
const next = (rawLabelBackground ? !plateColor || plateColor.opacity > 0 : false) ? null : resolveLabelRoles(resolve);
|
|
11561
|
+
setLabelRoles((previous) => (0, import_fast_deep_equal.default)(previous, next) ? previous : next);
|
|
11463
11562
|
}, [
|
|
11464
11563
|
showLabels,
|
|
11465
11564
|
className,
|
|
@@ -11630,7 +11729,7 @@ const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false
|
|
|
11630
11729
|
ry: 4,
|
|
11631
11730
|
pointerEvents: "none"
|
|
11632
11731
|
}), /* @__PURE__ */ jsx("text", {
|
|
11633
|
-
className: clsx(pie_chart_module_default["pie-chart__label-text"],
|
|
11732
|
+
className: clsx(pie_chart_module_default["pie-chart__label-text"], LABEL_TEXT_MODIFIER[pickLabelTextColor(fill, labelRoles, "label-inverse")]),
|
|
11634
11733
|
x: centroidX,
|
|
11635
11734
|
y: centroidY,
|
|
11636
11735
|
dy: ".33em",
|