@automattic/charts 4.5.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 +24 -2
- package/TOKENS.md +12 -10
- package/dist/index.cjs +248 -146
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +33 -20
- package/dist/index.d.cts +22 -11
- package/dist/index.d.ts +22 -11
- package/dist/index.js +249 -147
- 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/geo-chart/geo-chart.tsx +4 -0
- package/src/charts/geo-chart/index.ts +7 -1
- package/src/charts/geo-chart/test/geo-chart.test.tsx +8 -0
- package/src/charts/geo-chart/types.ts +12 -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/index.ts +7 -1
- 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
|
})()]
|
|
@@ -7345,13 +7382,14 @@ function normalizeGeoChartError(eventArgs) {
|
|
|
7345
7382
|
* @param props.height - Height of the chart in pixels
|
|
7346
7383
|
* @param props.region - Region to display ('world', 'US', or ISO 3166-1 alpha-2 code)
|
|
7347
7384
|
* @param props.resolution - Resolution level ('countries', 'provinces', or 'metros')
|
|
7385
|
+
* @param props.displayMode - Plot rows as shaded areas ('regions') or markers ('markers')
|
|
7348
7386
|
* @param props.domain - Country code whose viewpoint sets the disputed borders
|
|
7349
7387
|
* @param props.onError - Optional callback for Google Charts errors
|
|
7350
7388
|
* @param props.className - Additional CSS class name for the chart container
|
|
7351
7389
|
* @param props.renderPlaceholder - Optional render function for the loading placeholder
|
|
7352
7390
|
* @return A React component displaying an interactive map with data visualization
|
|
7353
7391
|
*/
|
|
7354
|
-
const GeoChartInternal = ({ className, data, width, height, region = "world", resolution = "countries", domain, onError, renderPlaceholder }) => {
|
|
7392
|
+
const GeoChartInternal = ({ className, data, width, height, region = "world", resolution = "countries", displayMode = "regions", domain, onError, renderPlaceholder }) => {
|
|
7355
7393
|
const { getElementStyles } = useGlobalChartsContext();
|
|
7356
7394
|
const scopeElement = useChartScopeElement();
|
|
7357
7395
|
const containerRef = (0, react.useRef)(null);
|
|
@@ -7415,6 +7453,7 @@ const GeoChartInternal = ({ className, data, width, height, region = "world", re
|
|
|
7415
7453
|
const options = (0, react.useMemo)(() => ({
|
|
7416
7454
|
...region !== "world" && { region },
|
|
7417
7455
|
...resolution !== "countries" && { resolution },
|
|
7456
|
+
...displayMode !== "regions" && { displayMode },
|
|
7418
7457
|
...domain && { domain },
|
|
7419
7458
|
colorAxis: { colors: [lightColorHex, fullColorHex] },
|
|
7420
7459
|
backgroundColor: backgroundColorHex,
|
|
@@ -7429,6 +7468,7 @@ const GeoChartInternal = ({ className, data, width, height, region = "world", re
|
|
|
7429
7468
|
}), [
|
|
7430
7469
|
region,
|
|
7431
7470
|
resolution,
|
|
7471
|
+
displayMode,
|
|
7432
7472
|
domain,
|
|
7433
7473
|
lightColorHex,
|
|
7434
7474
|
fullColorHex,
|
|
@@ -7484,6 +7524,73 @@ let GoogleDataTableColumnRoleType = /* @__PURE__ */ function(GoogleDataTableColu
|
|
|
7484
7524
|
GoogleDataTableColumnRoleType["domain"] = "domain";
|
|
7485
7525
|
return GoogleDataTableColumnRoleType;
|
|
7486
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
|
+
};
|
|
7487
7594
|
//#endregion
|
|
7488
7595
|
//#region src/charts/heatmap-chart/heatmap-chart.module.scss
|
|
7489
7596
|
var heatmap_chart_module_default = {
|
|
@@ -7493,9 +7600,11 @@ var heatmap_chart_module_default = {
|
|
|
7493
7600
|
"heatmap-chart__cell--hidden": "a8ccharts-O3YMOW-heatmap-chart__cell--hidden",
|
|
7494
7601
|
"heatmap-chart__cell--placeholder": "a8ccharts-O3YMOW-heatmap-chart__cell--placeholder",
|
|
7495
7602
|
"heatmap-chart__cell--selected": "a8ccharts-O3YMOW-heatmap-chart__cell--selected",
|
|
7496
|
-
"heatmap-chart__cell--strong": "a8ccharts-O3YMOW-heatmap-chart__cell--strong",
|
|
7497
7603
|
"heatmap-chart__cell--summary": "a8ccharts-O3YMOW-heatmap-chart__cell--summary",
|
|
7498
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",
|
|
7499
7608
|
"heatmap-chart__col-label": "a8ccharts-O3YMOW-heatmap-chart__col-label",
|
|
7500
7609
|
"heatmap-chart__col-label--summary": "a8ccharts-O3YMOW-heatmap-chart__col-label--summary",
|
|
7501
7610
|
"heatmap-chart__empty": "a8ccharts-O3YMOW-heatmap-chart__empty",
|
|
@@ -7789,25 +7898,25 @@ const stepCalendarCell = (grid, blocks, from, key) => {
|
|
|
7789
7898
|
//#endregion
|
|
7790
7899
|
//#region src/charts/heatmap-chart/heatmap-chart.tsx
|
|
7791
7900
|
const CELL_MIX_FLOOR = .15;
|
|
7792
|
-
const
|
|
7793
|
-
|
|
7794
|
-
|
|
7795
|
-
|
|
7796
|
-
|
|
7797
|
-
},
|
|
7798
|
-
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"]
|
|
7799
7906
|
};
|
|
7907
|
+
const NO_ROW_LABELS = [];
|
|
7908
|
+
const TOOLTIP_BOX_STYLE = { zIndex: 3 };
|
|
7800
7909
|
const cellName = (info) => info.cellLabel || [
|
|
7801
7910
|
info.groupLabel,
|
|
7802
7911
|
info.columnLabel,
|
|
7803
7912
|
info.rowLabel
|
|
7804
7913
|
].filter(Boolean).join(" ");
|
|
7805
|
-
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 }) => {
|
|
7806
7915
|
const chartId = useChartId(providedChartId);
|
|
7807
7916
|
const tooltipBoxStyle = tooltipStyle ? {
|
|
7808
|
-
...
|
|
7917
|
+
...TOOLTIP_BOX_STYLE,
|
|
7809
7918
|
...tooltipStyle
|
|
7810
|
-
} :
|
|
7919
|
+
} : TOOLTIP_BOX_STYLE;
|
|
7811
7920
|
const { getElementStyles, theme } = useGlobalChartsContext();
|
|
7812
7921
|
const scopeElement = useChartScopeElement();
|
|
7813
7922
|
const { heatmapChart: heatmapChartSettings } = theme;
|
|
@@ -7816,6 +7925,7 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
|
|
|
7816
7925
|
const { tooltipOpen, tooltipLeft, tooltipTop, tooltipData, showTooltip, hideTooltip } = (0, _visx_tooltip.useTooltip)();
|
|
7817
7926
|
const standaloneScopeClass = useStandaloneScopeClass();
|
|
7818
7927
|
const containerRef = (0, react.useRef)(null);
|
|
7928
|
+
const [labelRoles, setLabelRoles] = (0, react.useState)(null);
|
|
7819
7929
|
const getTooltipOrigin = (0, react.useCallback)(() => containerRef.current?.closest(`[data-chart-id="heatmap-chart-${chartId}"]`)?.getBoundingClientRect() ?? null, [chartId]);
|
|
7820
7930
|
const { color: primaryColorHex } = getElementStyles({
|
|
7821
7931
|
index: 0,
|
|
@@ -7823,7 +7933,21 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
|
|
|
7823
7933
|
});
|
|
7824
7934
|
const chartBackgroundHex = normalizeColorToHex(CATALOG_POINTERS.background, scopeElement, resolveCssVariable);
|
|
7825
7935
|
const primaryHex = normalizeColorToHex(primaryColorHex);
|
|
7826
|
-
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
|
+
]);
|
|
7827
7951
|
const extent = (0, react.useMemo)(() => getValueExtent(data), [data]);
|
|
7828
7952
|
const heatmapContext = (0, react.useMemo)(() => ({
|
|
7829
7953
|
extent,
|
|
@@ -8095,7 +8219,6 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
|
|
|
8095
8219
|
"data-row": rowIndex,
|
|
8096
8220
|
className: (0, clsx.default)(heatmap_chart_module_default["heatmap-chart__cell"], {
|
|
8097
8221
|
[heatmap_chart_module_default["heatmap-chart__cell--filled"]]: filled,
|
|
8098
|
-
[heatmap_chart_module_default["heatmap-chart__cell--strong"]]: filled && cellHasLightText(normalized),
|
|
8099
8222
|
[heatmap_chart_module_default["heatmap-chart__cell--summary"]]: column.summary,
|
|
8100
8223
|
...summaryGaps(columnIndex),
|
|
8101
8224
|
[heatmap_chart_module_default["heatmap-chart__cell--selected"]]: selected?.column === columnIndex && selected?.row === rowIndex
|
|
@@ -8107,7 +8230,7 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
|
|
|
8107
8230
|
onMouseMove: handleCellMouseMove,
|
|
8108
8231
|
onMouseLeave: handleCellMouseLeave,
|
|
8109
8232
|
children: (drawValues || column.summary) && present && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8110
|
-
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)]),
|
|
8111
8234
|
children: (0, _automattic_number_formatters.formatNumberCompact)(value)
|
|
8112
8235
|
})
|
|
8113
8236
|
}, `cell-${columnIndex}-${rowIndex}`);
|
|
@@ -8131,7 +8254,6 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
|
|
|
8131
8254
|
}), withTooltips && tooltipOpen && tooltipData && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BoundedTooltip, {
|
|
8132
8255
|
top: tooltipTop,
|
|
8133
8256
|
left: tooltipLeft,
|
|
8134
|
-
className: tooltipVariant === "dark" ? base_tooltip_module_default.surface : void 0,
|
|
8135
8257
|
style: tooltipBoxStyle,
|
|
8136
8258
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8137
8259
|
className: standaloneScopeClass,
|
|
@@ -11723,7 +11845,9 @@ function RadialWipeAnimation({ id, radius, innerRadius = 0, durationMs = 1e3, wi
|
|
|
11723
11845
|
var pie_chart_module_default = {
|
|
11724
11846
|
"pie-chart__label-plate": "a8ccharts-gnszbG-pie-chart__label-plate",
|
|
11725
11847
|
"pie-chart__label-text": "a8ccharts-gnszbG-pie-chart__label-text",
|
|
11848
|
+
"pie-chart__label-text--black": "a8ccharts-gnszbG-pie-chart__label-text--black",
|
|
11726
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",
|
|
11727
11851
|
"pie-chart__plot": "a8ccharts-gnszbG-pie-chart__plot",
|
|
11728
11852
|
"pie-chart--responsive": "a8ccharts-gnszbG-pie-chart--responsive"
|
|
11729
11853
|
};
|
|
@@ -11767,24 +11891,11 @@ const validateData$1 = (data) => {
|
|
|
11767
11891
|
message: ""
|
|
11768
11892
|
};
|
|
11769
11893
|
};
|
|
11770
|
-
|
|
11771
|
-
|
|
11772
|
-
|
|
11773
|
-
|
|
11774
|
-
|
|
11775
|
-
* yet resolved, or labels off) keep the default inverse role.
|
|
11776
|
-
*
|
|
11777
|
-
* @param fill - The slice's resolved fill color.
|
|
11778
|
-
* @param pointers - The label pointers, resolved at the chart's own root element.
|
|
11779
|
-
* @return Whether the label needs dark text.
|
|
11780
|
-
*/
|
|
11781
|
-
const labelNeedsDarkText = (fill, pointers) => {
|
|
11782
|
-
if (!pointers || pointers.hasPlate) return false;
|
|
11783
|
-
const fillHex = normalizeColorToHex(fill);
|
|
11784
|
-
if (!isValidHexColor(fillHex) || !isValidHexColor(pointers.labelHex)) return false;
|
|
11785
|
-
if (pointers.isInverseSeeThrough) return true;
|
|
11786
|
-
if (!isValidHexColor(pointers.labelInverseHex)) return false;
|
|
11787
|
-
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"]
|
|
11788
11899
|
};
|
|
11789
11900
|
/**
|
|
11790
11901
|
* Renders a pie or donut chart using the provided data.
|
|
@@ -11801,7 +11912,7 @@ const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false
|
|
|
11801
11912
|
const standaloneScopeClass = useStandaloneScopeClass();
|
|
11802
11913
|
const containerRef = (0, react.useRef)(null);
|
|
11803
11914
|
const rootRef = (0, react.useRef)(null);
|
|
11804
|
-
const [
|
|
11915
|
+
const [labelRoles, setLabelRoles] = (0, react.useState)(null);
|
|
11805
11916
|
const onMouseLeave = (0, react.useCallback)(() => {
|
|
11806
11917
|
if (!withTooltips) return;
|
|
11807
11918
|
hideTooltip();
|
|
@@ -11812,18 +11923,9 @@ const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false
|
|
|
11812
11923
|
if (!showLabels || !rootRef.current) return;
|
|
11813
11924
|
const resolve = createCssVariableResolver(rootRef.current);
|
|
11814
11925
|
const rawLabelBackground = resolve(CATALOG_POINTERS.labelBackground);
|
|
11815
|
-
const rawLabel = resolve(CATALOG_POINTERS.label);
|
|
11816
|
-
const isLabelOpaque = rawLabel ? (0, _visx_vendor_d3_color.color)(rawLabel)?.opacity === 1 : false;
|
|
11817
|
-
const rawLabelInverse = resolve(CATALOG_POINTERS.labelInverse);
|
|
11818
|
-
const labelInverseColor = rawLabelInverse ? (0, _visx_vendor_d3_color.color)(rawLabelInverse) : null;
|
|
11819
11926
|
const plateColor = rawLabelBackground ? (0, _visx_vendor_d3_color.color)(rawLabelBackground) : null;
|
|
11820
|
-
const next =
|
|
11821
|
-
|
|
11822
|
-
labelHex: isLabelOpaque ? normalizeColorToHex(CATALOG_POINTERS.label, null, resolve) : "",
|
|
11823
|
-
labelInverseHex: normalizeColorToHex(CATALOG_POINTERS.labelInverse, null, resolve),
|
|
11824
|
-
isInverseSeeThrough: labelInverseColor ? labelInverseColor.opacity < 1 : false
|
|
11825
|
-
};
|
|
11826
|
-
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);
|
|
11827
11929
|
}, [
|
|
11828
11930
|
showLabels,
|
|
11829
11931
|
className,
|
|
@@ -11994,7 +12096,7 @@ const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false
|
|
|
11994
12096
|
ry: 4,
|
|
11995
12097
|
pointerEvents: "none"
|
|
11996
12098
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("text", {
|
|
11997
|
-
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")]),
|
|
11998
12100
|
x: centroidX,
|
|
11999
12101
|
y: centroidY,
|
|
12000
12102
|
dy: ".33em",
|