@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.cjs
CHANGED
|
@@ -41,6 +41,7 @@ let _visx_scale = require("@visx/scale");
|
|
|
41
41
|
let _visx_group = require("@visx/group");
|
|
42
42
|
let _visx_legend = require("@visx/legend");
|
|
43
43
|
let _wordpress_ui = require("@wordpress/ui");
|
|
44
|
+
let _wordpress_theme = require("@wordpress/theme");
|
|
44
45
|
let react_dom = require("react-dom");
|
|
45
46
|
let _visx_gradient = require("@visx/gradient");
|
|
46
47
|
let _visx_curve = require("@visx/curve");
|
|
@@ -562,7 +563,8 @@ const relativeLuminance = (hex) => {
|
|
|
562
563
|
* Whether light text reads better than dark text on the given background, using the W3C
|
|
563
564
|
* luminance threshold (0.179) that maximizes contrast against black vs white.
|
|
564
565
|
*
|
|
565
|
-
* @
|
|
566
|
+
* @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.
|
|
567
|
+
* @param backgroundHex - Hex background color
|
|
566
568
|
* @return true if light text should be used; false (dark text) for malformed colors
|
|
567
569
|
*/
|
|
568
570
|
const prefersLightText = (backgroundHex) => {
|
|
@@ -881,14 +883,27 @@ const PROTANOPIA = [
|
|
|
881
883
|
const DEGREES = Math.PI / 180;
|
|
882
884
|
const toLinear = (channel) => channel <= .04045 ? channel / 12.92 : Math.pow((channel + .055) / 1.055, 2.4);
|
|
883
885
|
const fromLinear = (channel) => channel <= .0031308 ? 12.92 * channel : 1.055 * Math.pow(channel, 1 / 2.4) - .055;
|
|
884
|
-
|
|
886
|
+
/**
|
|
887
|
+
* The sRGB channels of a hex color.
|
|
888
|
+
*
|
|
889
|
+
* @param hex - A six-digit hex color.
|
|
890
|
+
* @return Channels from 0 to 255.
|
|
891
|
+
* @throws {Error} if the hex string is malformed
|
|
892
|
+
*/
|
|
893
|
+
const hexToRgb = (hex) => {
|
|
885
894
|
validateHexColor(hex);
|
|
886
|
-
|
|
895
|
+
const [r, g, b] = [
|
|
887
896
|
1,
|
|
888
897
|
3,
|
|
889
898
|
5
|
|
890
|
-
].map((start) =>
|
|
899
|
+
].map((start) => parseInt(hex.slice(start, start + 2), 16));
|
|
900
|
+
return [
|
|
901
|
+
r,
|
|
902
|
+
g,
|
|
903
|
+
b
|
|
904
|
+
];
|
|
891
905
|
};
|
|
906
|
+
const hexToLinear = (hex) => hexToRgb(hex).map((channel) => toLinear(channel / 255));
|
|
892
907
|
const linearToHex = (linear) => "#" + linear.map((channel) => Math.round(Math.min(1, Math.max(0, fromLinear(channel))) * 255).toString(16).padStart(2, "0")).join("");
|
|
893
908
|
const simulate = (matrix, [r, g, b]) => [
|
|
894
909
|
0,
|
|
@@ -1014,6 +1029,35 @@ const hexToOklch = (hex) => {
|
|
|
1014
1029
|
};
|
|
1015
1030
|
};
|
|
1016
1031
|
/**
|
|
1032
|
+
* `foreground` over `background` at `weight`, left unrounded as CSS `color-mix` and alpha compositing leave it.
|
|
1033
|
+
*
|
|
1034
|
+
* A mix rounded to hex can land on the other side of a contrast threshold from the fill the browser paints.
|
|
1035
|
+
*
|
|
1036
|
+
* @param foreground - The color weighted by `weight`.
|
|
1037
|
+
* @param background - The color it is mixed over.
|
|
1038
|
+
* @param weight - Share of `foreground`, from 0 to 1.
|
|
1039
|
+
* @return The mixed channels.
|
|
1040
|
+
*/
|
|
1041
|
+
const blendRgb = (foreground, background, weight) => {
|
|
1042
|
+
const share = Math.min(1, Math.max(0, weight));
|
|
1043
|
+
const [r, g, b] = foreground.map((channel, i) => background[i] + (channel - background[i]) * share);
|
|
1044
|
+
return [
|
|
1045
|
+
r,
|
|
1046
|
+
g,
|
|
1047
|
+
b
|
|
1048
|
+
];
|
|
1049
|
+
};
|
|
1050
|
+
/**
|
|
1051
|
+
* WCAG relative luminance of unrounded sRGB channels.
|
|
1052
|
+
*
|
|
1053
|
+
* @param rgb - Channels from 0 to 255.
|
|
1054
|
+
* @return Relative luminance from 0 to 1.
|
|
1055
|
+
*/
|
|
1056
|
+
const rgbLuminance = (rgb) => {
|
|
1057
|
+
const [r, g, b] = rgb.map((channel) => toLinear(channel / 255));
|
|
1058
|
+
return .2126 * r + .7152 * g + .0722 * b;
|
|
1059
|
+
};
|
|
1060
|
+
/**
|
|
1017
1061
|
* WCAG contrast ratio between two relative luminances.
|
|
1018
1062
|
*
|
|
1019
1063
|
* @param first - First relative luminance.
|
|
@@ -1021,15 +1065,6 @@ const hexToOklch = (hex) => {
|
|
|
1021
1065
|
* @return Ratio from 1 to 21.
|
|
1022
1066
|
*/
|
|
1023
1067
|
const luminanceContrastRatio = (first, second) => (Math.max(first, second) + .05) / (Math.min(first, second) + .05);
|
|
1024
|
-
/**
|
|
1025
|
-
* WCAG contrast ratio between two hex colors.
|
|
1026
|
-
*
|
|
1027
|
-
* @param first - First hex color.
|
|
1028
|
-
* @param second - Second hex color.
|
|
1029
|
-
* @return Ratio from 1 to 21.
|
|
1030
|
-
* @throws {Error} if either hex string is malformed
|
|
1031
|
-
*/
|
|
1032
|
-
const contrastRatio = (first, second) => luminanceContrastRatio(relativeLuminance(first), relativeLuminance(second));
|
|
1033
1068
|
/** WCAG 1.4.3 text contrast, which a label drawn on a fill needs from at least one label color. */
|
|
1034
1069
|
const MIN_LABEL_CONTRAST = 4.5;
|
|
1035
1070
|
/** Degrees of hue one unit of OKLCH chroma is worth when ranking candidates by hue. */
|
|
@@ -1534,15 +1569,13 @@ const useXYChartTheme = (data) => {
|
|
|
1534
1569
|
const resolve = createCssVariableResolver(scopeElement);
|
|
1535
1570
|
const resolveColor = (value) => value ? resolve(value) ?? value : value;
|
|
1536
1571
|
const paletteColors = [...JSON.parse(seriesColorKey), ...CATALOG_POINTERS.series].map((color) => resolveColor(color)).filter((color) => Boolean(color) && !color.includes("var("));
|
|
1537
|
-
const resolvedLabelColor = resolveColor(CATALOG_POINTERS.labelAxis);
|
|
1538
|
-
const htmlLabelColor = resolvedLabelColor ? normalizeColorToHex(resolvedLabelColor) || resolvedLabelColor : resolvedLabelColor;
|
|
1539
1572
|
return (0, _visx_xychart.buildChartTheme)({
|
|
1540
1573
|
...theme,
|
|
1541
1574
|
gridColor: "",
|
|
1542
1575
|
gridColorDark: "",
|
|
1543
1576
|
colors: paletteColors,
|
|
1544
1577
|
backgroundColor: resolveColor(CATALOG_POINTERS.background),
|
|
1545
|
-
htmlLabel:
|
|
1578
|
+
htmlLabel: { color: CATALOG_POINTERS.labelAxis },
|
|
1546
1579
|
gridStyles: {
|
|
1547
1580
|
...theme.gridStyles,
|
|
1548
1581
|
stroke: CATALOG_POINTERS.grid
|
|
@@ -1977,6 +2010,9 @@ function usePrefersReducedMotion() {
|
|
|
1977
2010
|
return prefersReducedMotion;
|
|
1978
2011
|
}
|
|
1979
2012
|
//#endregion
|
|
2013
|
+
//#region src/hooks/use-isomorphic-layout-effect.ts
|
|
2014
|
+
const useIsomorphicLayoutEffect = typeof window !== "undefined" ? react.useLayoutEffect : react.useEffect;
|
|
2015
|
+
//#endregion
|
|
1980
2016
|
//#region src/providers/chart-context/hooks/use-chart-registration.ts
|
|
1981
2017
|
const useChartRegistration = ({ chartId, legendItems, chartType, isDataValid, metadata }) => {
|
|
1982
2018
|
const { registerChart, unregisterChart } = useGlobalChartsContext();
|
|
@@ -2449,6 +2485,30 @@ var base_tooltip_module_default = {
|
|
|
2449
2485
|
"tooltip": "a8ccharts--zY0xG-tooltip"
|
|
2450
2486
|
};
|
|
2451
2487
|
//#endregion
|
|
2488
|
+
//#region src/components/tooltip/private/tooltip-theme.tsx
|
|
2489
|
+
const DEFAULT_SURFACE = "#1e1e1e";
|
|
2490
|
+
const TOOLTIP_SURFACE = `var(--a8c-charts-color-tooltip-surface, ${DEFAULT_SURFACE})`;
|
|
2491
|
+
const toSeed = (value) => {
|
|
2492
|
+
const parsed = value ? (0, _visx_vendor_d3_color.color)(value) : null;
|
|
2493
|
+
return parsed && parsed.opacity === 1 ? parsed.formatHex() : DEFAULT_SURFACE;
|
|
2494
|
+
};
|
|
2495
|
+
/**
|
|
2496
|
+
* 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.
|
|
2497
|
+
*
|
|
2498
|
+
* @param props - Component props.
|
|
2499
|
+
* @param props.children - The tooltip box.
|
|
2500
|
+
* @return The themed box.
|
|
2501
|
+
*/
|
|
2502
|
+
const TooltipTheme = ({ children }) => {
|
|
2503
|
+
const scopeElement = useChartScopeElement();
|
|
2504
|
+
const color = (0, react.useMemo)(() => ({ background: toSeed(resolveCssVariable(TOOLTIP_SURFACE, scopeElement)) }), [scopeElement]);
|
|
2505
|
+
if (!_wordpress_theme.ThemeProvider) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children });
|
|
2506
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_wordpress_theme.ThemeProvider, {
|
|
2507
|
+
color,
|
|
2508
|
+
children
|
|
2509
|
+
});
|
|
2510
|
+
};
|
|
2511
|
+
//#endregion
|
|
2452
2512
|
//#region src/components/tooltip/base-tooltip.tsx
|
|
2453
2513
|
const DefaultTooltipContent = ({ data }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
2454
2514
|
data?.label,
|
|
@@ -2460,10 +2520,9 @@ const BaseTooltip = ({ data, top, left, component: Component = DefaultTooltipCon
|
|
|
2460
2520
|
data,
|
|
2461
2521
|
className
|
|
2462
2522
|
});
|
|
2463
|
-
const standaloneScopeClass = useStandaloneScopeClass();
|
|
2464
2523
|
if (!renderContainer) return content;
|
|
2465
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2466
|
-
className: (0, clsx.default)(
|
|
2524
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TooltipTheme, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2525
|
+
className: (0, clsx.default)(CHART_SCOPE_CLASS, base_tooltip_module_default.tooltip),
|
|
2467
2526
|
style: {
|
|
2468
2527
|
top,
|
|
2469
2528
|
left,
|
|
@@ -2471,7 +2530,7 @@ const BaseTooltip = ({ data, top, left, component: Component = DefaultTooltipCon
|
|
|
2471
2530
|
},
|
|
2472
2531
|
role: "tooltip",
|
|
2473
2532
|
children: content
|
|
2474
|
-
});
|
|
2533
|
+
}) });
|
|
2475
2534
|
};
|
|
2476
2535
|
//#endregion
|
|
2477
2536
|
//#region src/components/tooltip/private/bounded-tooltip.tsx
|
|
@@ -2486,6 +2545,11 @@ const isClipping = (element) => {
|
|
|
2486
2545
|
overflowY
|
|
2487
2546
|
].some((value) => value && value !== "visible");
|
|
2488
2547
|
};
|
|
2548
|
+
const findLayoutParent = (node) => {
|
|
2549
|
+
let element = node.parentElement;
|
|
2550
|
+
while (element && getComputedStyle(element).display === "contents") element = element.parentElement;
|
|
2551
|
+
return element;
|
|
2552
|
+
};
|
|
2489
2553
|
const findClippingAncestor = (wrapper) => {
|
|
2490
2554
|
let element = wrapper.parentElement;
|
|
2491
2555
|
while (element && element !== document.body) {
|
|
@@ -2560,19 +2624,20 @@ const getBoundedPosition = ({ left, top, offsetLeft, offsetTop, box, wrapper, bo
|
|
|
2560
2624
|
* @param props.top - Anchor y, in wrapper coordinates.
|
|
2561
2625
|
* @param props.offsetLeft - Gap between the anchor and the box, horizontally.
|
|
2562
2626
|
* @param props.offsetTop - Gap between the anchor and the box, vertically.
|
|
2563
|
-
* @param props.style -
|
|
2564
|
-
* @param props.unstyled -
|
|
2627
|
+
* @param props.style - Inline overrides on the surface; ignored when `unstyled`.
|
|
2628
|
+
* @param props.unstyled - Drop the surface and `style`, leaving the box bare.
|
|
2629
|
+
* @param props.className - Extra classes beside the surface.
|
|
2565
2630
|
* @param props.children - Box content.
|
|
2566
2631
|
* @param props.placement - Below-axis, beside without vertical flipping, or automatic flipping.
|
|
2567
2632
|
* @return The tooltip box.
|
|
2568
2633
|
*/
|
|
2569
|
-
const BoundedTooltip = ({ left = 0, top = 0, offsetLeft = DEFAULT_OFFSET, offsetTop = DEFAULT_OFFSET, style
|
|
2634
|
+
const BoundedTooltip = ({ left = 0, top = 0, offsetLeft = DEFAULT_OFFSET, offsetTop = DEFAULT_OFFSET, style, unstyled = false, className, children, placement = "auto", ...rest }) => {
|
|
2570
2635
|
const nodeRef = (0, react.useRef)(null);
|
|
2571
2636
|
const clipRef = (0, react.useRef)(null);
|
|
2572
2637
|
const [position, setPosition] = (0, react.useState)(null);
|
|
2573
2638
|
(0, react.useLayoutEffect)(() => {
|
|
2574
2639
|
const node = nodeRef.current;
|
|
2575
|
-
const wrapper = node
|
|
2640
|
+
const wrapper = node && findLayoutParent(node);
|
|
2576
2641
|
if (!node || !wrapper) return;
|
|
2577
2642
|
if (clipRef.current?.wrapper !== wrapper) clipRef.current = {
|
|
2578
2643
|
wrapper,
|
|
@@ -2620,8 +2685,9 @@ const BoundedTooltip = ({ left = 0, top = 0, offsetLeft = DEFAULT_OFFSET, offset
|
|
|
2620
2685
|
]);
|
|
2621
2686
|
const x = position?.x ?? left + offsetLeft;
|
|
2622
2687
|
const y = position?.y ?? top + (placement === "below-axis" ? POINTER_HEIGHT : offsetTop);
|
|
2623
|
-
|
|
2688
|
+
const box = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_visx_tooltip.Tooltip, {
|
|
2624
2689
|
ref: nodeRef,
|
|
2690
|
+
className: (0, clsx.default)(!unstyled && ["a8c-charts-tooltip-scope", base_tooltip_module_default.surface], className),
|
|
2625
2691
|
style: {
|
|
2626
2692
|
position: "absolute",
|
|
2627
2693
|
left: 0,
|
|
@@ -2637,13 +2703,14 @@ const BoundedTooltip = ({ left = 0, top = 0, offsetLeft = DEFAULT_OFFSET, offset
|
|
|
2637
2703
|
left: left - x - POINTER_HEIGHT,
|
|
2638
2704
|
top: -6,
|
|
2639
2705
|
width: 12,
|
|
2640
|
-
height:
|
|
2706
|
+
height: 7,
|
|
2641
2707
|
background: "inherit",
|
|
2642
|
-
clipPath:
|
|
2708
|
+
clipPath: `polygon(50% 0, 100% ${POINTER_HEIGHT}px, 100% 100%, 0 100%, 0 ${POINTER_HEIGHT}px)`,
|
|
2643
2709
|
pointerEvents: "none"
|
|
2644
2710
|
}
|
|
2645
2711
|
}), children]
|
|
2646
2712
|
});
|
|
2713
|
+
return unstyled ? box : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TooltipTheme, { children: box });
|
|
2647
2714
|
};
|
|
2648
2715
|
//#endregion
|
|
2649
2716
|
//#region src/components/tooltip/xy-chart-tooltip.tsx
|
|
@@ -2750,13 +2817,20 @@ const XyChartTooltipContent = ({ tooltipContext, container, renderTooltip, rende
|
|
|
2750
2817
|
const marginLeft = margin?.left ?? 0;
|
|
2751
2818
|
const TooltipComponent = detectBounds || tooltipPlacement !== "auto" ? BoundedTooltip : _visx_tooltip.Tooltip;
|
|
2752
2819
|
const boxStyle = {
|
|
2753
|
-
..._visx_tooltip.defaultStyles,
|
|
2754
2820
|
zIndex,
|
|
2755
|
-
backgroundColor: theme?.backgroundColor ?? "white",
|
|
2756
|
-
boxShadow: `0 1px 2px ${isValidHexColor(theme?.htmlLabel?.color) ? `${theme.htmlLabel.color}55` : "#22222255"}`,
|
|
2757
|
-
...theme?.htmlLabel,
|
|
2758
2821
|
...style
|
|
2759
2822
|
};
|
|
2823
|
+
const themesOwnBox = TooltipComponent === _visx_tooltip.Tooltip && !tooltipProps.unstyled;
|
|
2824
|
+
const box = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TooltipComponent, {
|
|
2825
|
+
left: tooltipLeft,
|
|
2826
|
+
top: tooltipPlacement === "below-axis" ? marginTop + innerHeight + (margin?.bottom ?? 0) : tooltipAnchorTop ?? tooltipTop,
|
|
2827
|
+
style: boxStyle,
|
|
2828
|
+
applyPositionStyle: true,
|
|
2829
|
+
...tooltipProps,
|
|
2830
|
+
className: (0, clsx.default)(themesOwnBox && ["a8c-charts-scope", base_tooltip_module_default.surface], tooltipProps.className),
|
|
2831
|
+
...tooltipPlacement !== "auto" && { placement: tooltipPlacement },
|
|
2832
|
+
children: tooltipContent
|
|
2833
|
+
});
|
|
2760
2834
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("g", {
|
|
2761
2835
|
className: "visx-tooltip-overlay",
|
|
2762
2836
|
pointerEvents: "none",
|
|
@@ -2783,15 +2857,7 @@ const XyChartTooltipContent = ({ tooltipContext, container, renderTooltip, rende
|
|
|
2783
2857
|
}),
|
|
2784
2858
|
glyphs
|
|
2785
2859
|
]
|
|
2786
|
-
}), container && (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2787
|
-
left: tooltipLeft,
|
|
2788
|
-
top: tooltipPlacement === "below-axis" ? marginTop + innerHeight + (margin?.bottom ?? 0) : tooltipAnchorTop ?? tooltipTop,
|
|
2789
|
-
style: boxStyle,
|
|
2790
|
-
applyPositionStyle: true,
|
|
2791
|
-
...tooltipProps,
|
|
2792
|
-
...tooltipPlacement !== "auto" && { placement: tooltipPlacement },
|
|
2793
|
-
children: tooltipContent
|
|
2794
|
-
}), container)] });
|
|
2860
|
+
}), container && (0, react_dom.createPortal)(themesOwnBox ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TooltipTheme, { children: box }) : box, container)] });
|
|
2795
2861
|
};
|
|
2796
2862
|
/**
|
|
2797
2863
|
* In-tree replacement for `@visx/xychart`'s `Tooltip`.
|
|
@@ -3058,7 +3124,6 @@ const useKeyboardNavigation = ({ selectedIndex, setSelectedIndex, isNavigating,
|
|
|
3058
3124
|
};
|
|
3059
3125
|
//#endregion
|
|
3060
3126
|
//#region src/providers/chart-context/hooks/use-default-hidden-series.ts
|
|
3061
|
-
const useIsomorphicLayoutEffect$1 = typeof window !== "undefined" ? react.useLayoutEffect : react.useEffect;
|
|
3062
3127
|
/**
|
|
3063
3128
|
* Seeds a chart's hidden series once per chart ID, the first time the provider
|
|
3064
3129
|
* sees that ID.
|
|
@@ -3079,7 +3144,7 @@ const useDefaultHiddenSeries = (chartId, seriesLabels) => {
|
|
|
3079
3144
|
labelsRef.current = seriesLabels;
|
|
3080
3145
|
const hasSeriesLabels = seriesLabels !== void 0;
|
|
3081
3146
|
const shouldUseDefaults = hasSeriesLabels && !hasSeededChart(chartId);
|
|
3082
|
-
useIsomorphicLayoutEffect
|
|
3147
|
+
useIsomorphicLayoutEffect(() => {
|
|
3083
3148
|
if (labelsRef.current === void 0) return;
|
|
3084
3149
|
seedChartHiddenSeries(chartId, labelsRef.current);
|
|
3085
3150
|
}, [
|
|
@@ -3704,7 +3769,6 @@ var with_responsive_module_default = {
|
|
|
3704
3769
|
};
|
|
3705
3770
|
//#endregion
|
|
3706
3771
|
//#region src/charts/private/with-responsive/with-responsive.tsx
|
|
3707
|
-
const useIsomorphicLayoutEffect = typeof window !== "undefined" ? react.useLayoutEffect : react.useEffect;
|
|
3708
3772
|
/**
|
|
3709
3773
|
* A higher-order component that provides responsive dimensions
|
|
3710
3774
|
* to the wrapped chart component using useParentSize from `@visx/responsive`.
|
|
@@ -3988,10 +4052,8 @@ var line_chart_module_default = {
|
|
|
3988
4052
|
"line-chart__annotation-label-popover-content": "a8ccharts-inuQka-line-chart__annotation-label-popover-content",
|
|
3989
4053
|
"line-chart__annotation-label-trigger-button": "a8ccharts-inuQka-line-chart__annotation-label-trigger-button",
|
|
3990
4054
|
"line-chart__annotations-overlay": "a8ccharts-inuQka-line-chart__annotations-overlay",
|
|
3991
|
-
"line-chart__tooltip": "a8ccharts-inuQka-line-chart__tooltip",
|
|
3992
4055
|
"line-chart__tooltip-date": "a8ccharts-inuQka-line-chart__tooltip-date",
|
|
3993
4056
|
"line-chart__tooltip-label": "a8ccharts-inuQka-line-chart__tooltip-label",
|
|
3994
|
-
"line-chart__tooltip-row": "a8ccharts-inuQka-line-chart__tooltip-row",
|
|
3995
4057
|
"line-chart--animated": "a8ccharts-inuQka-line-chart--animated",
|
|
3996
4058
|
"rise": "a8ccharts-inuQka-rise"
|
|
3997
4059
|
};
|
|
@@ -4518,11 +4580,10 @@ const TooltipDate = ({ date, displayResolution }) => {
|
|
|
4518
4580
|
* one row per visible series (label + formatted value), sorted descending by
|
|
4519
4581
|
* value. Reused by AreaChart, which has the same multi-series shape.
|
|
4520
4582
|
*
|
|
4521
|
-
* @param params
|
|
4522
|
-
* @param contentStyle - Explicit tooltip content color overrides.
|
|
4583
|
+
* @param params - visx tooltip data and the chart's optional `bucketInfo`.
|
|
4523
4584
|
* @return Tooltip JSX, or `null` when no datum is hovered.
|
|
4524
4585
|
*/
|
|
4525
|
-
const renderDefaultTooltip = (params
|
|
4586
|
+
const renderDefaultTooltip = (params) => {
|
|
4526
4587
|
const { tooltipData, bucketInfo } = params;
|
|
4527
4588
|
const nearestDatum = tooltipData?.nearestDatum?.datum;
|
|
4528
4589
|
if (!nearestDatum) return null;
|
|
@@ -4535,29 +4596,24 @@ const renderDefaultTooltip = (params, contentStyle) => {
|
|
|
4535
4596
|
if (b.value === null) return -1;
|
|
4536
4597
|
return b.value - a.value;
|
|
4537
4598
|
});
|
|
4538
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4539
|
-
className: line_chart_module_default["line-chart__tooltip"],
|
|
4540
|
-
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
className: line_chart_module_default["line-chart__tooltip-value"],
|
|
4557
|
-
children: formatReading(point.value)
|
|
4558
|
-
})]
|
|
4559
|
-
}, point.key))]
|
|
4560
|
-
});
|
|
4599
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4600
|
+
className: line_chart_module_default["line-chart__tooltip-date"],
|
|
4601
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TooltipDate, {
|
|
4602
|
+
date: nearestDatum.date,
|
|
4603
|
+
displayResolution: bucketInfo?.displayResolution ?? "day"
|
|
4604
|
+
})
|
|
4605
|
+
}), tooltipPoints.map((point) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_wordpress_ui.Stack, {
|
|
4606
|
+
direction: "row",
|
|
4607
|
+
align: "center",
|
|
4608
|
+
justify: "space-between",
|
|
4609
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
4610
|
+
className: line_chart_module_default["line-chart__tooltip-label"],
|
|
4611
|
+
children: [point.key, ":"]
|
|
4612
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4613
|
+
className: line_chart_module_default["line-chart__tooltip-value"],
|
|
4614
|
+
children: formatReading(point.value)
|
|
4615
|
+
})]
|
|
4616
|
+
}, point.key))] });
|
|
4561
4617
|
};
|
|
4562
4618
|
const validateData$4 = (data) => {
|
|
4563
4619
|
if (!data?.length) return (0, _wordpress_i18n.__)("No data available", "jetpack-charts");
|
|
@@ -4817,29 +4873,10 @@ const LineChartInternal = (0, react.forwardRef)(({ data, chartId: providedChartI
|
|
|
4817
4873
|
xAccessor: (d) => d?.date,
|
|
4818
4874
|
yAccessor: (d) => d?.value
|
|
4819
4875
|
};
|
|
4820
|
-
const
|
|
4821
|
-
if (renderTooltip !== renderDefaultTooltip || !tooltipStyle) return tooltipStyle;
|
|
4822
|
-
if (!tooltipStyle.color || tooltipStyle.background || tooltipStyle.backgroundColor) return tooltipStyle;
|
|
4823
|
-
return {
|
|
4824
|
-
backgroundColor: "var(--a8c-charts-color-tooltip-surface, rgb(0 0 0 / 85%))",
|
|
4825
|
-
...tooltipStyle
|
|
4826
|
-
};
|
|
4827
|
-
}, [renderTooltip, tooltipStyle]);
|
|
4828
|
-
const tooltipRenderer = (0, react.useMemo)(() => (params) => renderTooltip === renderDefaultTooltip ? renderDefaultTooltip({
|
|
4829
|
-
...params,
|
|
4830
|
-
bucketInfo
|
|
4831
|
-
}, {
|
|
4832
|
-
color: tooltipStyle?.color,
|
|
4833
|
-
background: tooltipStyle?.background,
|
|
4834
|
-
backgroundColor: tooltipStyle?.backgroundColor
|
|
4835
|
-
}) : renderTooltip({
|
|
4876
|
+
const tooltipRenderer = (0, react.useMemo)(() => (params) => renderTooltip({
|
|
4836
4877
|
...params,
|
|
4837
4878
|
bucketInfo
|
|
4838
|
-
}), [
|
|
4839
|
-
renderTooltip,
|
|
4840
|
-
bucketInfo,
|
|
4841
|
-
tooltipStyle
|
|
4842
|
-
]);
|
|
4879
|
+
}), [renderTooltip, bucketInfo]);
|
|
4843
4880
|
if (error) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4844
4881
|
className: (0, clsx.default)("line-chart", line_chart_module_default["line-chart"]),
|
|
4845
4882
|
children: error
|
|
@@ -4987,7 +5024,7 @@ const LineChartInternal = (0, react.forwardRef)(({ data, chartId: providedChartI
|
|
|
4987
5024
|
detectBounds: true,
|
|
4988
5025
|
snapTooltipToDatumX: true,
|
|
4989
5026
|
tooltipPlacement,
|
|
4990
|
-
style:
|
|
5027
|
+
style: tooltipStyle,
|
|
4991
5028
|
snapTooltipToDatumY: true,
|
|
4992
5029
|
showSeriesGlyphs: true,
|
|
4993
5030
|
renderTooltip: tooltipRenderer,
|
|
@@ -6895,8 +6932,7 @@ var conversion_funnel_chart_module_default = {
|
|
|
6895
6932
|
"step-rate": "a8ccharts-mGEVca-step-rate",
|
|
6896
6933
|
"stretch": "a8ccharts-mGEVca-stretch",
|
|
6897
6934
|
"tooltip-content": "a8ccharts-mGEVca-tooltip-content",
|
|
6898
|
-
"tooltip-title": "a8ccharts-mGEVca-tooltip-title"
|
|
6899
|
-
"tooltip-wrapper": "a8ccharts-mGEVca-tooltip-wrapper"
|
|
6935
|
+
"tooltip-title": "a8ccharts-mGEVca-tooltip-title"
|
|
6900
6936
|
};
|
|
6901
6937
|
//#endregion
|
|
6902
6938
|
//#region src/charts/conversion-funnel-chart/private/use-funnel-selection.ts
|
|
@@ -6957,9 +6993,10 @@ const useFunnelSelection = (hideTooltip) => {
|
|
|
6957
6993
|
* @param props.renderStepRate - Custom render function for step rates
|
|
6958
6994
|
* @param props.renderMainMetric - Custom render function for the entire main metric section
|
|
6959
6995
|
* @param props.renderTooltip - Custom render function for tooltip content
|
|
6996
|
+
* @param props.tooltipStyle - Inline styles merged over the tooltip box defaults
|
|
6960
6997
|
* @return JSX element representing the conversion funnel chart
|
|
6961
6998
|
*/
|
|
6962
|
-
const ConversionFunnelChartInternal = ({ mainRate, changeIndicator, steps, loading = false, animation, className, chartId: providedChartId, height, style, renderStepLabel, renderStepRate, renderMainMetric, renderTooltip }) => {
|
|
6999
|
+
const ConversionFunnelChartInternal = ({ mainRate, changeIndicator, steps, loading = false, animation, className, chartId: providedChartId, height, style, renderStepLabel, renderStepRate, renderMainMetric, renderTooltip, tooltipStyle }) => {
|
|
6963
7000
|
const chartId = useChartId(providedChartId);
|
|
6964
7001
|
const { getElementStyles, isColorPaletteResolved } = useGlobalChartsContext();
|
|
6965
7002
|
const chartRef = (0, react.useRef)(null);
|
|
@@ -7194,14 +7231,14 @@ const ConversionFunnelChartInternal = ({ mainRate, changeIndicator, steps, loadi
|
|
|
7194
7231
|
step: tooltipData,
|
|
7195
7232
|
index: steps.findIndex((s) => s.id === tooltipData.id),
|
|
7196
7233
|
top: tooltipTop,
|
|
7197
|
-
left: tooltipLeft
|
|
7198
|
-
className: conversion_funnel_chart_module_default["tooltip-wrapper"]
|
|
7234
|
+
left: tooltipLeft
|
|
7199
7235
|
}) : renderDefaultTooltip(tooltipData);
|
|
7200
7236
|
if (!tooltipContent) return null;
|
|
7201
7237
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BoundedTooltip, {
|
|
7202
7238
|
top: tooltipTop,
|
|
7203
7239
|
left: tooltipLeft,
|
|
7204
|
-
className:
|
|
7240
|
+
className: standaloneScopeClass,
|
|
7241
|
+
style: tooltipStyle,
|
|
7205
7242
|
children: tooltipContent
|
|
7206
7243
|
});
|
|
7207
7244
|
})()]
|
|
@@ -7487,6 +7524,73 @@ let GoogleDataTableColumnRoleType = /* @__PURE__ */ function(GoogleDataTableColu
|
|
|
7487
7524
|
GoogleDataTableColumnRoleType["domain"] = "domain";
|
|
7488
7525
|
return GoogleDataTableColumnRoleType;
|
|
7489
7526
|
}({});
|
|
7527
|
+
const resolveRole = (pointer, resolve) => {
|
|
7528
|
+
const raw = resolve(pointer);
|
|
7529
|
+
const parsed = raw ? (0, _visx_vendor_d3_color.color)(raw) : null;
|
|
7530
|
+
if (!parsed) return {
|
|
7531
|
+
kind: "unreadable",
|
|
7532
|
+
raw
|
|
7533
|
+
};
|
|
7534
|
+
const { r, g, b } = parsed.opacity > 0 ? parsed.rgb() : {
|
|
7535
|
+
r: 0,
|
|
7536
|
+
g: 0,
|
|
7537
|
+
b: 0
|
|
7538
|
+
};
|
|
7539
|
+
return {
|
|
7540
|
+
kind: "color",
|
|
7541
|
+
rgb: [
|
|
7542
|
+
r,
|
|
7543
|
+
g,
|
|
7544
|
+
b
|
|
7545
|
+
],
|
|
7546
|
+
alpha: parsed.opacity
|
|
7547
|
+
};
|
|
7548
|
+
};
|
|
7549
|
+
/**
|
|
7550
|
+
* Reads both label roles at the element the label text inherits from, so JS and CSS agree on what paints.
|
|
7551
|
+
*
|
|
7552
|
+
* @param resolve - A CSS variable resolver bound to that element.
|
|
7553
|
+
* @return The resolved label roles.
|
|
7554
|
+
*/
|
|
7555
|
+
const resolveLabelRoles = (resolve) => ({
|
|
7556
|
+
label: resolveRole(CATALOG_POINTERS.label, resolve),
|
|
7557
|
+
labelInverse: resolveRole(CATALOG_POINTERS.labelInverse, resolve)
|
|
7558
|
+
});
|
|
7559
|
+
const roleContrast = (role, fill, fillLuminance) => {
|
|
7560
|
+
if (role.kind === "unreadable") return 0;
|
|
7561
|
+
return luminanceContrastRatio(fillLuminance, rgbLuminance(blendRgb(role.rgb, fill, role.alpha)));
|
|
7562
|
+
};
|
|
7563
|
+
/**
|
|
7564
|
+
* Picks the label color for text drawn on a fill: the role that contrasts more, or black/white when neither reaches AA.
|
|
7565
|
+
*
|
|
7566
|
+
* Both roles set to one color is a host's choice to keep that color, so it never falls back.
|
|
7567
|
+
*
|
|
7568
|
+
* @param fill - The fill the text sits on, as unrounded sRGB channels.
|
|
7569
|
+
* @param roles - The label roles resolved at the chart's element, or null before they are read.
|
|
7570
|
+
* @param defaultRole - The role the chart's stylesheet paints when nothing can be decided.
|
|
7571
|
+
* @return The color the label should paint with.
|
|
7572
|
+
*/
|
|
7573
|
+
const pickLabelTextColorForFill = (fill, roles, defaultRole) => {
|
|
7574
|
+
if (!roles || (0, import_fast_deep_equal.default)(roles.label, roles.labelInverse)) return defaultRole;
|
|
7575
|
+
const fillLuminance = rgbLuminance(fill);
|
|
7576
|
+
const labelContrast = roleContrast(roles.label, fill, fillLuminance);
|
|
7577
|
+
const inverseContrast = roleContrast(roles.labelInverse, fill, fillLuminance);
|
|
7578
|
+
if (Math.max(labelContrast, inverseContrast) >= 4.55) return labelContrast > inverseContrast ? "label" : "label-inverse";
|
|
7579
|
+
return luminanceContrastRatio(fillLuminance, 0) > luminanceContrastRatio(fillLuminance, 1) ? "black" : "white";
|
|
7580
|
+
};
|
|
7581
|
+
/**
|
|
7582
|
+
* `pickLabelTextColorForFill` for a fill given as a color.
|
|
7583
|
+
*
|
|
7584
|
+
* @param fill - The fill, in any color syntax `normalizeColorToHex` reads.
|
|
7585
|
+
* @param roles - The label roles resolved at the chart's element, or null before they are read.
|
|
7586
|
+
* @param defaultRole - The role the chart's stylesheet paints when nothing can be decided.
|
|
7587
|
+
* @return The color the label should paint with.
|
|
7588
|
+
*/
|
|
7589
|
+
const pickLabelTextColor = (fill, roles, defaultRole) => {
|
|
7590
|
+
const fillHex = normalizeColorToHex(fill);
|
|
7591
|
+
if (!isValidHexColor(fillHex)) return defaultRole;
|
|
7592
|
+
return pickLabelTextColorForFill(hexToRgb(fillHex), roles, defaultRole);
|
|
7593
|
+
};
|
|
7490
7594
|
//#endregion
|
|
7491
7595
|
//#region src/charts/heatmap-chart/heatmap-chart.module.scss
|
|
7492
7596
|
var heatmap_chart_module_default = {
|
|
@@ -7496,9 +7600,11 @@ var heatmap_chart_module_default = {
|
|
|
7496
7600
|
"heatmap-chart__cell--hidden": "a8ccharts-O3YMOW-heatmap-chart__cell--hidden",
|
|
7497
7601
|
"heatmap-chart__cell--placeholder": "a8ccharts-O3YMOW-heatmap-chart__cell--placeholder",
|
|
7498
7602
|
"heatmap-chart__cell--selected": "a8ccharts-O3YMOW-heatmap-chart__cell--selected",
|
|
7499
|
-
"heatmap-chart__cell--strong": "a8ccharts-O3YMOW-heatmap-chart__cell--strong",
|
|
7500
7603
|
"heatmap-chart__cell--summary": "a8ccharts-O3YMOW-heatmap-chart__cell--summary",
|
|
7501
7604
|
"heatmap-chart__cell-value": "a8ccharts-O3YMOW-heatmap-chart__cell-value",
|
|
7605
|
+
"heatmap-chart__cell-value--black": "a8ccharts-O3YMOW-heatmap-chart__cell-value--black",
|
|
7606
|
+
"heatmap-chart__cell-value--inverse": "a8ccharts-O3YMOW-heatmap-chart__cell-value--inverse",
|
|
7607
|
+
"heatmap-chart__cell-value--white": "a8ccharts-O3YMOW-heatmap-chart__cell-value--white",
|
|
7502
7608
|
"heatmap-chart__col-label": "a8ccharts-O3YMOW-heatmap-chart__col-label",
|
|
7503
7609
|
"heatmap-chart__col-label--summary": "a8ccharts-O3YMOW-heatmap-chart__col-label--summary",
|
|
7504
7610
|
"heatmap-chart__empty": "a8ccharts-O3YMOW-heatmap-chart__empty",
|
|
@@ -7792,25 +7898,25 @@ const stepCalendarCell = (grid, blocks, from, key) => {
|
|
|
7792
7898
|
//#endregion
|
|
7793
7899
|
//#region src/charts/heatmap-chart/heatmap-chart.tsx
|
|
7794
7900
|
const CELL_MIX_FLOOR = .15;
|
|
7795
|
-
const
|
|
7796
|
-
|
|
7797
|
-
|
|
7798
|
-
|
|
7799
|
-
|
|
7800
|
-
},
|
|
7801
|
-
dark: { zIndex: 3 }
|
|
7901
|
+
const CELL_VALUE_MODIFIER = {
|
|
7902
|
+
label: void 0,
|
|
7903
|
+
"label-inverse": heatmap_chart_module_default["heatmap-chart__cell-value--inverse"],
|
|
7904
|
+
black: heatmap_chart_module_default["heatmap-chart__cell-value--black"],
|
|
7905
|
+
white: heatmap_chart_module_default["heatmap-chart__cell-value--white"]
|
|
7802
7906
|
};
|
|
7907
|
+
const NO_ROW_LABELS = [];
|
|
7908
|
+
const TOOLTIP_BOX_STYLE = { zIndex: 3 };
|
|
7803
7909
|
const cellName = (info) => info.cellLabel || [
|
|
7804
7910
|
info.groupLabel,
|
|
7805
7911
|
info.columnLabel,
|
|
7806
7912
|
info.rowLabel
|
|
7807
7913
|
].filter(Boolean).join(" ");
|
|
7808
|
-
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,
|
|
7914
|
+
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 }) => {
|
|
7809
7915
|
const chartId = useChartId(providedChartId);
|
|
7810
7916
|
const tooltipBoxStyle = tooltipStyle ? {
|
|
7811
|
-
...
|
|
7917
|
+
...TOOLTIP_BOX_STYLE,
|
|
7812
7918
|
...tooltipStyle
|
|
7813
|
-
} :
|
|
7919
|
+
} : TOOLTIP_BOX_STYLE;
|
|
7814
7920
|
const { getElementStyles, theme } = useGlobalChartsContext();
|
|
7815
7921
|
const scopeElement = useChartScopeElement();
|
|
7816
7922
|
const { heatmapChart: heatmapChartSettings } = theme;
|
|
@@ -7819,6 +7925,7 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
|
|
|
7819
7925
|
const { tooltipOpen, tooltipLeft, tooltipTop, tooltipData, showTooltip, hideTooltip } = (0, _visx_tooltip.useTooltip)();
|
|
7820
7926
|
const standaloneScopeClass = useStandaloneScopeClass();
|
|
7821
7927
|
const containerRef = (0, react.useRef)(null);
|
|
7928
|
+
const [labelRoles, setLabelRoles] = (0, react.useState)(null);
|
|
7822
7929
|
const getTooltipOrigin = (0, react.useCallback)(() => containerRef.current?.closest(`[data-chart-id="heatmap-chart-${chartId}"]`)?.getBoundingClientRect() ?? null, [chartId]);
|
|
7823
7930
|
const { color: primaryColorHex } = getElementStyles({
|
|
7824
7931
|
index: 0,
|
|
@@ -7826,7 +7933,21 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
|
|
|
7826
7933
|
});
|
|
7827
7934
|
const chartBackgroundHex = normalizeColorToHex(CATALOG_POINTERS.background, scopeElement, resolveCssVariable);
|
|
7828
7935
|
const primaryHex = normalizeColorToHex(primaryColorHex);
|
|
7829
|
-
const
|
|
7936
|
+
const cellMix = isValidHexColor(primaryHex) && isValidHexColor(chartBackgroundHex) ? {
|
|
7937
|
+
primary: hexToRgb(primaryHex),
|
|
7938
|
+
background: hexToRgb(chartBackgroundHex)
|
|
7939
|
+
} : null;
|
|
7940
|
+
const cellTextColor = (intensity) => cellMix ? pickLabelTextColorForFill(blendRgb(cellMix.primary, cellMix.background, CELL_MIX_FLOOR + .85 * intensity), labelRoles, "label") : "label";
|
|
7941
|
+
useIsomorphicLayoutEffect(() => {
|
|
7942
|
+
if (!containerRef.current) return;
|
|
7943
|
+
const next = resolveLabelRoles(createCssVariableResolver(containerRef.current));
|
|
7944
|
+
setLabelRoles((previous) => (0, import_fast_deep_equal.default)(previous, next) ? previous : next);
|
|
7945
|
+
}, [
|
|
7946
|
+
data,
|
|
7947
|
+
className,
|
|
7948
|
+
primaryColorHex,
|
|
7949
|
+
chartBackgroundHex
|
|
7950
|
+
]);
|
|
7830
7951
|
const extent = (0, react.useMemo)(() => getValueExtent(data), [data]);
|
|
7831
7952
|
const heatmapContext = (0, react.useMemo)(() => ({
|
|
7832
7953
|
extent,
|
|
@@ -8098,7 +8219,6 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
|
|
|
8098
8219
|
"data-row": rowIndex,
|
|
8099
8220
|
className: (0, clsx.default)(heatmap_chart_module_default["heatmap-chart__cell"], {
|
|
8100
8221
|
[heatmap_chart_module_default["heatmap-chart__cell--filled"]]: filled,
|
|
8101
|
-
[heatmap_chart_module_default["heatmap-chart__cell--strong"]]: filled && cellHasLightText(normalized),
|
|
8102
8222
|
[heatmap_chart_module_default["heatmap-chart__cell--summary"]]: column.summary,
|
|
8103
8223
|
...summaryGaps(columnIndex),
|
|
8104
8224
|
[heatmap_chart_module_default["heatmap-chart__cell--selected"]]: selected?.column === columnIndex && selected?.row === rowIndex
|
|
@@ -8110,7 +8230,7 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
|
|
|
8110
8230
|
onMouseMove: handleCellMouseMove,
|
|
8111
8231
|
onMouseLeave: handleCellMouseLeave,
|
|
8112
8232
|
children: (drawValues || column.summary) && present && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8113
|
-
className: heatmap_chart_module_default["heatmap-chart__cell-value"],
|
|
8233
|
+
className: (0, clsx.default)(heatmap_chart_module_default["heatmap-chart__cell-value"], filled && CELL_VALUE_MODIFIER[cellTextColor(normalized)]),
|
|
8114
8234
|
children: (0, _automattic_number_formatters.formatNumberCompact)(value)
|
|
8115
8235
|
})
|
|
8116
8236
|
}, `cell-${columnIndex}-${rowIndex}`);
|
|
@@ -8134,7 +8254,6 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
|
|
|
8134
8254
|
}), withTooltips && tooltipOpen && tooltipData && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BoundedTooltip, {
|
|
8135
8255
|
top: tooltipTop,
|
|
8136
8256
|
left: tooltipLeft,
|
|
8137
|
-
className: tooltipVariant === "dark" ? base_tooltip_module_default.surface : void 0,
|
|
8138
8257
|
style: tooltipBoxStyle,
|
|
8139
8258
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8140
8259
|
className: standaloneScopeClass,
|
|
@@ -11726,7 +11845,9 @@ function RadialWipeAnimation({ id, radius, innerRadius = 0, durationMs = 1e3, wi
|
|
|
11726
11845
|
var pie_chart_module_default = {
|
|
11727
11846
|
"pie-chart__label-plate": "a8ccharts-gnszbG-pie-chart__label-plate",
|
|
11728
11847
|
"pie-chart__label-text": "a8ccharts-gnszbG-pie-chart__label-text",
|
|
11848
|
+
"pie-chart__label-text--black": "a8ccharts-gnszbG-pie-chart__label-text--black",
|
|
11729
11849
|
"pie-chart__label-text--on-light": "a8ccharts-gnszbG-pie-chart__label-text--on-light",
|
|
11850
|
+
"pie-chart__label-text--white": "a8ccharts-gnszbG-pie-chart__label-text--white",
|
|
11730
11851
|
"pie-chart__plot": "a8ccharts-gnszbG-pie-chart__plot",
|
|
11731
11852
|
"pie-chart--responsive": "a8ccharts-gnszbG-pie-chart--responsive"
|
|
11732
11853
|
};
|
|
@@ -11770,24 +11891,11 @@ const validateData$1 = (data) => {
|
|
|
11770
11891
|
message: ""
|
|
11771
11892
|
};
|
|
11772
11893
|
};
|
|
11773
|
-
|
|
11774
|
-
|
|
11775
|
-
|
|
11776
|
-
|
|
11777
|
-
|
|
11778
|
-
* yet resolved, or labels off) keep the default inverse role.
|
|
11779
|
-
*
|
|
11780
|
-
* @param fill - The slice's resolved fill color.
|
|
11781
|
-
* @param pointers - The label pointers, resolved at the chart's own root element.
|
|
11782
|
-
* @return Whether the label needs dark text.
|
|
11783
|
-
*/
|
|
11784
|
-
const labelNeedsDarkText = (fill, pointers) => {
|
|
11785
|
-
if (!pointers || pointers.hasPlate) return false;
|
|
11786
|
-
const fillHex = normalizeColorToHex(fill);
|
|
11787
|
-
if (!isValidHexColor(fillHex) || !isValidHexColor(pointers.labelHex)) return false;
|
|
11788
|
-
if (pointers.isInverseSeeThrough) return true;
|
|
11789
|
-
if (!isValidHexColor(pointers.labelInverseHex)) return false;
|
|
11790
|
-
return contrastRatio(fillHex, pointers.labelHex) > contrastRatio(fillHex, pointers.labelInverseHex);
|
|
11894
|
+
const LABEL_TEXT_MODIFIER = {
|
|
11895
|
+
label: pie_chart_module_default["pie-chart__label-text--on-light"],
|
|
11896
|
+
"label-inverse": void 0,
|
|
11897
|
+
black: pie_chart_module_default["pie-chart__label-text--black"],
|
|
11898
|
+
white: pie_chart_module_default["pie-chart__label-text--white"]
|
|
11791
11899
|
};
|
|
11792
11900
|
/**
|
|
11793
11901
|
* Renders a pie or donut chart using the provided data.
|
|
@@ -11804,7 +11912,7 @@ const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false
|
|
|
11804
11912
|
const standaloneScopeClass = useStandaloneScopeClass();
|
|
11805
11913
|
const containerRef = (0, react.useRef)(null);
|
|
11806
11914
|
const rootRef = (0, react.useRef)(null);
|
|
11807
|
-
const [
|
|
11915
|
+
const [labelRoles, setLabelRoles] = (0, react.useState)(null);
|
|
11808
11916
|
const onMouseLeave = (0, react.useCallback)(() => {
|
|
11809
11917
|
if (!withTooltips) return;
|
|
11810
11918
|
hideTooltip();
|
|
@@ -11815,18 +11923,9 @@ const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false
|
|
|
11815
11923
|
if (!showLabels || !rootRef.current) return;
|
|
11816
11924
|
const resolve = createCssVariableResolver(rootRef.current);
|
|
11817
11925
|
const rawLabelBackground = resolve(CATALOG_POINTERS.labelBackground);
|
|
11818
|
-
const rawLabel = resolve(CATALOG_POINTERS.label);
|
|
11819
|
-
const isLabelOpaque = rawLabel ? (0, _visx_vendor_d3_color.color)(rawLabel)?.opacity === 1 : false;
|
|
11820
|
-
const rawLabelInverse = resolve(CATALOG_POINTERS.labelInverse);
|
|
11821
|
-
const labelInverseColor = rawLabelInverse ? (0, _visx_vendor_d3_color.color)(rawLabelInverse) : null;
|
|
11822
11926
|
const plateColor = rawLabelBackground ? (0, _visx_vendor_d3_color.color)(rawLabelBackground) : null;
|
|
11823
|
-
const next =
|
|
11824
|
-
|
|
11825
|
-
labelHex: isLabelOpaque ? normalizeColorToHex(CATALOG_POINTERS.label, null, resolve) : "",
|
|
11826
|
-
labelInverseHex: normalizeColorToHex(CATALOG_POINTERS.labelInverse, null, resolve),
|
|
11827
|
-
isInverseSeeThrough: labelInverseColor ? labelInverseColor.opacity < 1 : false
|
|
11828
|
-
};
|
|
11829
|
-
setLabelPointers((previous) => previous && previous.hasPlate === next.hasPlate && previous.labelHex === next.labelHex && previous.labelInverseHex === next.labelInverseHex && previous.isInverseSeeThrough === next.isInverseSeeThrough ? previous : next);
|
|
11927
|
+
const next = (rawLabelBackground ? !plateColor || plateColor.opacity > 0 : false) ? null : resolveLabelRoles(resolve);
|
|
11928
|
+
setLabelRoles((previous) => (0, import_fast_deep_equal.default)(previous, next) ? previous : next);
|
|
11830
11929
|
}, [
|
|
11831
11930
|
showLabels,
|
|
11832
11931
|
className,
|
|
@@ -11997,7 +12096,7 @@ const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false
|
|
|
11997
12096
|
ry: 4,
|
|
11998
12097
|
pointerEvents: "none"
|
|
11999
12098
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("text", {
|
|
12000
|
-
className: (0, clsx.default)(pie_chart_module_default["pie-chart__label-text"],
|
|
12099
|
+
className: (0, clsx.default)(pie_chart_module_default["pie-chart__label-text"], LABEL_TEXT_MODIFIER[pickLabelTextColor(fill, labelRoles, "label-inverse")]),
|
|
12001
12100
|
x: centroidX,
|
|
12002
12101
|
y: centroidY,
|
|
12003
12102
|
dy: ".33em",
|