@automattic/charts 4.8.0 → 4.10.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 +28 -0
- package/dist/index.cjs +766 -277
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +72 -8
- package/dist/index.d.cts +54 -15
- package/dist/index.d.ts +54 -15
- package/dist/index.js +770 -281
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/charts/area-chart/area-chart.tsx +7 -3
- package/src/charts/area-chart/test/area-chart.test.tsx +15 -14
- package/src/charts/area-chart/test/tooltip-resolution.test.tsx +2 -2
- package/src/charts/bar-chart/bar-chart.tsx +12 -4
- package/src/charts/bar-chart/test/bar-chart.test.tsx +74 -63
- package/src/charts/bar-list-chart/bar-list-chart.tsx +3 -0
- package/src/charts/bar-list-chart/test/bar-list-chart.test.tsx +3 -1
- package/src/charts/conversion-funnel-chart/conversion-funnel-chart.tsx +23 -7
- package/src/charts/conversion-funnel-chart/test/conversion-funnel-chart.test.tsx +22 -0
- package/src/charts/conversion-funnel-chart/types.ts +1 -1
- package/src/charts/geo-chart/geo-chart.tsx +17 -2
- package/src/charts/geo-chart/test/geo-chart.test.tsx +9 -4
- package/src/charts/geo-chart/types.ts +1 -1
- package/src/charts/heatmap-chart/heatmap-chart.module.scss +10 -4
- package/src/charts/heatmap-chart/heatmap-chart.tsx +144 -37
- package/src/charts/heatmap-chart/private/column-groups.ts +79 -8
- package/src/charts/heatmap-chart/private/fit-compact-cells.ts +72 -0
- package/src/charts/heatmap-chart/private/heatmap-legend.tsx +14 -2
- package/src/charts/heatmap-chart/private/index.ts +4 -2
- package/src/charts/heatmap-chart/test/column-groups.test.ts +41 -4
- package/src/charts/heatmap-chart/test/fit-compact-cells.test.ts +59 -0
- package/src/charts/heatmap-chart/test/heatmap-chart.test.tsx +132 -7
- package/src/charts/heatmap-chart/types.ts +2 -2
- package/src/charts/leaderboard-chart/hooks/use-fitted-row-count.ts +2 -2
- package/src/charts/leaderboard-chart/leaderboard-chart.module.scss +52 -4
- package/src/charts/leaderboard-chart/leaderboard-chart.tsx +60 -9
- package/src/charts/leaderboard-chart/test/leaderboard-chart.test.tsx +80 -1
- package/src/charts/leaderboard-chart/types.ts +7 -1
- package/src/charts/line-chart/line-chart.tsx +8 -2
- package/src/charts/line-chart/private/line-chart-annotation-label-popover.tsx +19 -9
- package/src/charts/line-chart/test/default-tooltip-formatting.test.tsx +1 -1
- package/src/charts/line-chart/test/line-chart.test.tsx +37 -35
- package/src/charts/line-chart/test/tooltip-resolution.test.tsx +2 -2
- package/src/charts/line-chart/types.ts +3 -3
- package/src/charts/pie-chart/pie-chart.module.scss +3 -0
- package/src/charts/pie-chart/pie-chart.tsx +144 -139
- package/src/charts/pie-chart/test/pie-chart.test.tsx +167 -0
- package/src/charts/pie-semi-circle-chart/pie-semi-circle-chart.module.scss +3 -0
- package/src/charts/pie-semi-circle-chart/pie-semi-circle-chart.tsx +117 -120
- package/src/charts/pie-semi-circle-chart/test/pie-semi-circle-chart.test.tsx +54 -0
- package/src/charts/private/chart-composition/use-chart-children.ts +11 -6
- package/src/charts/private/pie-keyboard-navigation/index.ts +4 -0
- package/src/charts/private/pie-keyboard-navigation/order-arcs-for-navigation.ts +10 -0
- package/src/charts/private/pie-keyboard-navigation/pie-keyboard-navigation.module.scss +16 -0
- package/src/charts/private/pie-keyboard-navigation/pie-selection-announcement.tsx +14 -0
- package/src/charts/private/pie-keyboard-navigation/pie-selection-output.tsx +82 -0
- package/src/charts/private/pie-keyboard-navigation/pie-tooltip.tsx +49 -0
- package/src/charts/private/pie-keyboard-navigation/selected-segment-ring.tsx +47 -0
- package/src/charts/private/pie-keyboard-navigation/test/order-arcs-for-navigation.test.ts +34 -0
- package/src/charts/private/pie-keyboard-navigation/test/selected-segment-ring.test.ts +14 -0
- package/src/charts/private/pie-keyboard-navigation/use-pie-keyboard-navigation.ts +139 -0
- package/src/charts/private/x-zoom/test/x-zoom.test.tsx +3 -2
- package/src/charts/test/accessible-name.test.tsx +181 -0
- package/src/components/legend/hooks/test/use-chart-legend-items.test.tsx +63 -3
- package/src/components/legend/hooks/use-chart-legend-items.ts +63 -1
- package/src/components/legend/private/base-legend.tsx +27 -15
- package/src/components/legend/test/legend.test.tsx +42 -0
- package/src/components/legend/types.ts +2 -0
- package/src/components/tooltip/test/xy-chart-tooltip.test.tsx +20 -19
- package/src/components/tooltip/xy-chart-tooltip.tsx +3 -3
- package/src/hooks/test/use-xychart-theme.test.tsx +22 -0
- package/src/hooks/use-xychart-theme.ts +33 -2
- package/src/index.ts +1 -0
- package/src/types.ts +37 -3
- package/src/utils/resolve-font-size.ts +9 -10
- package/src/utils/test/resolve-font-size.test.ts +11 -2
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { AnimatedAreaSeries, AnimatedAreaStack, AreaSeries, Axis, BarGroup, BarS
|
|
|
4
4
|
import { __, _x, sprintf } from "@wordpress/i18n";
|
|
5
5
|
import clsx from "clsx";
|
|
6
6
|
import * as React from "react";
|
|
7
|
-
import { Children, Fragment, createContext, createContext as createContext$1, createElement, forwardRef, forwardRef as forwardRef$1, isValidElement, memo, useCallback, useCallback as useCallback$1, useContext, useContext as useContext$1, useEffect, useEffect as useEffect$1, useId, useImperativeHandle, useLayoutEffect, useMemo, useMemo as useMemo$1, useRef, useRef as useRef$1, useState, useState as useState$1 } from "react";
|
|
7
|
+
import { Children, Fragment, createContext, createContext as createContext$1, createElement, forwardRef, forwardRef as forwardRef$1, isValidElement, memo, useCallback, useCallback as useCallback$1, useContext, useContext as useContext$1, useEffect, useEffect as useEffect$1, useId, useImperativeHandle, useLayoutEffect, useMemo, useMemo as useMemo$1, useRef, useRef as useRef$1, useState, useState as useState$1, version } from "react";
|
|
8
8
|
import { differenceInHours, differenceInYears, isValid, parse, parseISO } from "date-fns";
|
|
9
9
|
import { tzOffset } from "@date-fns/tz";
|
|
10
10
|
import { Text, getStringWidth } from "@visx/text";
|
|
@@ -15,9 +15,9 @@ import { useTooltip } from "@visx/tooltip";
|
|
|
15
15
|
import { createScale, getTicks, scaleBand, scaleCanBeZeroed, scaleOrdinal, scaleTime } from "@visx/scale";
|
|
16
16
|
import { Group } from "@visx/group";
|
|
17
17
|
import { LegendItem, LegendLabel, LegendOrdinal, LegendShape } from "@visx/legend";
|
|
18
|
-
import { IconButton, Stack, Text as Text$1 } from "@wordpress/ui";
|
|
18
|
+
import { IconButton, Stack, Text as Text$1, VisuallyHidden } from "@wordpress/ui";
|
|
19
19
|
import { ThemeProvider } from "@wordpress/theme";
|
|
20
|
-
import { createPortal } from "react-dom";
|
|
20
|
+
import { createPortal, flushSync } from "react-dom";
|
|
21
21
|
import { LinearGradient } from "@visx/gradient";
|
|
22
22
|
import { curveCatmullRom, curveLinear, curveMonotoneX } from "@visx/curve";
|
|
23
23
|
import { useParentSize } from "@visx/responsive";
|
|
@@ -30,7 +30,7 @@ import { __assign } from "tslib";
|
|
|
30
30
|
import "@babel/runtime/helpers/esm/extends";
|
|
31
31
|
import "@babel/runtime/helpers/extends";
|
|
32
32
|
import { Icon, chevronRight } from "@wordpress/icons";
|
|
33
|
-
import {
|
|
33
|
+
import { arc, pie } from "@visx/shape";
|
|
34
34
|
//#region \0rolldown/runtime.js
|
|
35
35
|
var __create = Object.create;
|
|
36
36
|
var __defProp = Object.defineProperty;
|
|
@@ -669,16 +669,17 @@ function readCustomProperty(varName, styles) {
|
|
|
669
669
|
}
|
|
670
670
|
//#endregion
|
|
671
671
|
//#region src/utils/resolve-font-size.ts
|
|
672
|
+
const toFontSize = (size) => Number.isFinite(size) && size >= 0 ? size : void 0;
|
|
672
673
|
/**
|
|
673
674
|
* Resolve a theme `fontSize` value into a plain number suitable for
|
|
674
675
|
* canvas-based measurement (e.g. `getStringWidth`).
|
|
675
676
|
*
|
|
676
677
|
* Accepts:
|
|
677
|
-
* - A number — returned as-is
|
|
678
|
+
* - A finite, non-negative number — returned as-is
|
|
678
679
|
* - A pixel string like `"12px"` — parsed and returned as a number
|
|
679
680
|
*
|
|
680
|
-
* Returns `undefined` for any other input (missing value,
|
|
681
|
-
* relative units like `rem`/`em`/`%`/`vh`) so callers can fall back to
|
|
681
|
+
* Returns `undefined` for any other input (missing value, a non-finite or
|
|
682
|
+
* negative size, or relative units like `rem`/`em`/`%`/`vh`) so callers can fall back to
|
|
682
683
|
* their own default. Relative units are intentionally rejected because
|
|
683
684
|
* we cannot resolve them to absolute pixels here without a parent
|
|
684
685
|
* computed style, and silently returning the unitless prefix
|
|
@@ -688,12 +689,10 @@ function readCustomProperty(varName, styles) {
|
|
|
688
689
|
* @return Parsed numeric font size in pixels, or `undefined` when unresolvable
|
|
689
690
|
*/
|
|
690
691
|
const resolveFontSize = (val) => {
|
|
691
|
-
if (typeof val === "number") return
|
|
692
|
+
if (typeof val === "number") return toFontSize(val);
|
|
692
693
|
if (typeof val === "string") {
|
|
693
|
-
const match = val.trim().match(
|
|
694
|
-
|
|
695
|
-
const parsed = parseFloat(match[1]);
|
|
696
|
-
return isNaN(parsed) ? void 0 : parsed;
|
|
694
|
+
const match = val.trim().match(/^\+?((?:\d*\.)?\d+)(px)?$/);
|
|
695
|
+
return match ? toFontSize(parseFloat(match[1])) : void 0;
|
|
697
696
|
}
|
|
698
697
|
};
|
|
699
698
|
//#endregion
|
|
@@ -1572,6 +1571,20 @@ const useChartScopeElement = () => useContext(ChartScopeContext);
|
|
|
1572
1571
|
const useStandaloneScopeClass = () => useContext(GlobalChartsContext) ? void 0 : CHART_SCOPE_CLASS;
|
|
1573
1572
|
//#endregion
|
|
1574
1573
|
//#region src/hooks/use-xychart-theme.ts
|
|
1574
|
+
const STARTS_LIKE_A_NUMBER = /^[+-]?[\d.]/;
|
|
1575
|
+
const NON_NEGATIVE_CSS_NUMBER = /^\+?(?:\d*\.)?\d+(?:e[+-]?\d+)?(?:[a-z]+|%)?$/i;
|
|
1576
|
+
const isRenderableFontSize = (fontSize) => {
|
|
1577
|
+
if (typeof fontSize === "number") return resolveFontSize(fontSize) !== void 0;
|
|
1578
|
+
const value = fontSize.trim();
|
|
1579
|
+
if (!STARTS_LIKE_A_NUMBER.test(value)) return true;
|
|
1580
|
+
return NON_NEGATIVE_CSS_NUMBER.test(value) && Number.isFinite(parseFloat(value));
|
|
1581
|
+
};
|
|
1582
|
+
const withRenderableFontSize = (style) => {
|
|
1583
|
+
if (style?.fontSize === void 0 || isRenderableFontSize(style.fontSize)) return style;
|
|
1584
|
+
const rest = { ...style };
|
|
1585
|
+
delete rest.fontSize;
|
|
1586
|
+
return rest;
|
|
1587
|
+
};
|
|
1575
1588
|
const useXYChartTheme = (data) => {
|
|
1576
1589
|
const theme = useGlobalChartsTheme();
|
|
1577
1590
|
const scopeElement = useChartScopeElement();
|
|
@@ -1602,9 +1615,10 @@ const useXYChartTheme = (data) => {
|
|
|
1602
1615
|
yAxisLineStyles: { stroke: CATALOG_POINTERS.axisY },
|
|
1603
1616
|
yTickLineStyles: { stroke: CATALOG_POINTERS.tickY },
|
|
1604
1617
|
svgLabelSmall: {
|
|
1605
|
-
...theme.svgLabelSmall,
|
|
1618
|
+
...withRenderableFontSize(theme.svgLabelSmall),
|
|
1606
1619
|
fill: CATALOG_POINTERS.labelAxis
|
|
1607
|
-
}
|
|
1620
|
+
},
|
|
1621
|
+
svgLabelBig: withRenderableFontSize(theme.svgLabelBig)
|
|
1608
1622
|
});
|
|
1609
1623
|
}, [
|
|
1610
1624
|
theme,
|
|
@@ -2117,7 +2131,7 @@ const getLegendItemAriaLabel = (text, value, visible, interactive) => {
|
|
|
2117
2131
|
if (visible) return;
|
|
2118
2132
|
return sprintf(_x("%s: hidden", "hidden non-interactive legend item", "jetpack-charts"), accessibleText);
|
|
2119
2133
|
};
|
|
2120
|
-
const BaseLegend = forwardRef(({ items, className, orientation = "horizontal", alignment = "center", shape = "rect", fill = valueOrIdentityString, size = valueOrIdentityString, labelFormat = valueOrIdentity, labelTransform, itemStyles, itemClassName, labelStyles, labelClassName, shapeStyles, render, interactive = false, chartId }, ref) => {
|
|
2134
|
+
const BaseLegend = forwardRef(({ items: allItems, className, orientation = "horizontal", alignment = "center", shape = "rect", fill = valueOrIdentityString, size = valueOrIdentityString, labelFormat = valueOrIdentity, labelTransform, itemStyles, itemClassName, labelStyles, labelClassName, shapeStyles, render, interactive = false, chartId }, ref) => {
|
|
2121
2135
|
const { margin: itemMargin = "0", flexDirection: itemDirection = "row" } = itemStyles ?? {};
|
|
2122
2136
|
const { justifyContent: labelJustifyContent = "flex-start", flex: labelFlex = "0 0 auto", margin: labelMargin = "0 4px", maxWidth, textOverflow = "wrap" } = labelStyles ?? {};
|
|
2123
2137
|
const { width: shapeWidth = 16, height: shapeHeight = 16, margin: shapeMargin = "2px 4px 2px 0" } = shapeStyles ?? {};
|
|
@@ -2125,6 +2139,16 @@ const BaseLegend = forwardRef(({ items, className, orientation = "horizontal", a
|
|
|
2125
2139
|
const context = useContext(GlobalChartsContext);
|
|
2126
2140
|
const chartInstanceContext = useContext(ChartInstanceContext);
|
|
2127
2141
|
const standaloneScopeClass = useStandaloneScopeClass();
|
|
2142
|
+
const isSeriesVisible = useCallback((seriesLabel) => {
|
|
2143
|
+
if (chartInstanceContext?.isSeriesVisible) return chartInstanceContext.isSeriesVisible(seriesLabel);
|
|
2144
|
+
if (!chartId || !context) return true;
|
|
2145
|
+
return context.isSeriesVisible(chartId, seriesLabel);
|
|
2146
|
+
}, [
|
|
2147
|
+
chartId,
|
|
2148
|
+
chartInstanceContext,
|
|
2149
|
+
context
|
|
2150
|
+
]);
|
|
2151
|
+
const items = useMemo(() => allItems.filter((item) => item.interactive !== false || !item.describesSeries || isSeriesVisible(item.describesSeries)), [allItems, isSeriesVisible]);
|
|
2128
2152
|
const domain = items.map((item) => item.label);
|
|
2129
2153
|
const legendScale = scaleOrdinal({
|
|
2130
2154
|
domain,
|
|
@@ -2147,15 +2171,6 @@ const BaseLegend = forwardRef(({ items, className, orientation = "horizontal", a
|
|
|
2147
2171
|
chartId,
|
|
2148
2172
|
context
|
|
2149
2173
|
]);
|
|
2150
|
-
const isSeriesVisible = useCallback((seriesLabel) => {
|
|
2151
|
-
if (chartInstanceContext?.isSeriesVisible) return chartInstanceContext.isSeriesVisible(seriesLabel);
|
|
2152
|
-
if (!chartId || !context) return true;
|
|
2153
|
-
return context.isSeriesVisible(chartId, seriesLabel);
|
|
2154
|
-
}, [
|
|
2155
|
-
chartId,
|
|
2156
|
-
chartInstanceContext,
|
|
2157
|
-
context
|
|
2158
|
-
]);
|
|
2159
2174
|
const createClickHandler = useCallback((seriesLabels, itemInteractive) => {
|
|
2160
2175
|
if (!itemInteractive) return;
|
|
2161
2176
|
return () => handleLegendClick(seriesLabels);
|
|
@@ -2430,6 +2445,34 @@ function buildComparisonLegendItem(seriesData, items, label, getElementStyles, l
|
|
|
2430
2445
|
};
|
|
2431
2446
|
}
|
|
2432
2447
|
/**
|
|
2448
|
+
* Builds one static item per comparison series folded into another series' item, named after
|
|
2449
|
+
* that item and styled like the comparison series itself.
|
|
2450
|
+
* @param seriesData - The series data to search for comparison series
|
|
2451
|
+
* @param items - The legend items already built from the series
|
|
2452
|
+
* @param formatLabel - Names an item after the label of the item it was folded into
|
|
2453
|
+
* @param getElementStyles - Function to get element styles
|
|
2454
|
+
* @param legendShape - The shape type for legend items (string literal or React component)
|
|
2455
|
+
* @return The legend items, in series order
|
|
2456
|
+
*/
|
|
2457
|
+
function buildPerSeriesComparisonItems(seriesData, items, formatLabel, getElementStyles, legendShape) {
|
|
2458
|
+
return seriesData.flatMap((series, index) => {
|
|
2459
|
+
const owner = items.find((item) => item.seriesLabels?.includes(series.label));
|
|
2460
|
+
if (series.options?.type !== "comparison" || !owner || owner.seriesLabels?.[0] === series.label) return [];
|
|
2461
|
+
const { color, shapeStyles } = getElementStyles({
|
|
2462
|
+
data: series,
|
|
2463
|
+
index,
|
|
2464
|
+
legendShape
|
|
2465
|
+
});
|
|
2466
|
+
return [{
|
|
2467
|
+
label: formatLabel(owner.label),
|
|
2468
|
+
color,
|
|
2469
|
+
shapeStyle: shapeStyles,
|
|
2470
|
+
interactive: false,
|
|
2471
|
+
describesSeries: series.label
|
|
2472
|
+
}];
|
|
2473
|
+
});
|
|
2474
|
+
}
|
|
2475
|
+
/**
|
|
2433
2476
|
* Processes point data into legend items
|
|
2434
2477
|
* @param pointData - The point data to process
|
|
2435
2478
|
* @param getElementStyles - Function to get element styles
|
|
@@ -2465,13 +2508,14 @@ function processPointData(pointData, getElementStyles, showValues, legendValueDi
|
|
|
2465
2508
|
* @return Array of legend items ready for display
|
|
2466
2509
|
*/
|
|
2467
2510
|
function useChartLegendItems(data, options = {}, legendShape) {
|
|
2468
|
-
const { showValues = false, legendValueDisplay = "percentage", withGlyph = false, glyphSize = 8, collapseGroups = false, comparisonItem = false, renderGlyph } = options;
|
|
2511
|
+
const { showValues = false, legendValueDisplay = "percentage", withGlyph = false, glyphSize = 8, collapseGroups = false, comparisonItem = false, comparisonSeriesItems, renderGlyph } = options;
|
|
2469
2512
|
const { getElementStyles } = useGlobalChartsContext();
|
|
2470
2513
|
return useMemo(() => {
|
|
2471
2514
|
if (!data || !Array.isArray(data) || data.length === 0) return [];
|
|
2472
2515
|
if ("data" in data[0]) {
|
|
2473
2516
|
const seriesData = data;
|
|
2474
2517
|
const items = processSeriesData(seriesData, getElementStyles, showValues, withGlyph, glyphSize, collapseGroups, renderGlyph, legendShape);
|
|
2518
|
+
if (comparisonSeriesItems) return [...items, ...buildPerSeriesComparisonItems(seriesData, items, comparisonSeriesItems, getElementStyles, legendShape)];
|
|
2475
2519
|
const comparison = comparisonItem ? buildComparisonLegendItem(seriesData, items, typeof comparisonItem === "string" ? comparisonItem : __("Comparison period", "jetpack-charts"), getElementStyles, legendShape) : null;
|
|
2476
2520
|
return comparison ? [...items, comparison] : items;
|
|
2477
2521
|
}
|
|
@@ -2485,6 +2529,7 @@ function useChartLegendItems(data, options = {}, legendShape) {
|
|
|
2485
2529
|
glyphSize,
|
|
2486
2530
|
collapseGroups,
|
|
2487
2531
|
comparisonItem,
|
|
2532
|
+
comparisonSeriesItems,
|
|
2488
2533
|
renderGlyph,
|
|
2489
2534
|
legendShape
|
|
2490
2535
|
]);
|
|
@@ -3080,7 +3125,7 @@ const XYChartTooltip = ({ renderTooltip, selectedIndex, tooltipRef, keyboardFocu
|
|
|
3080
3125
|
/** @deprecated Use `XYChartTooltip`. */
|
|
3081
3126
|
const AccessibleTooltip = XYChartTooltip;
|
|
3082
3127
|
const useKeyboardNavigation = ({ selectedIndex, setSelectedIndex, isNavigating, setIsNavigating, chartRef, totalPoints, onActivate, preventTooltipScroll = false, visibleSeriesKey }) => {
|
|
3083
|
-
const getChartRoot = useCallback(() => chartRef.current?.closest("[role=\"
|
|
3128
|
+
const getChartRoot = useCallback(() => chartRef.current?.closest("[role=\"application\"]") ?? chartRef.current, [chartRef]);
|
|
3084
3129
|
const focusWithoutScrollIfNeeded = useCallback((element) => {
|
|
3085
3130
|
if (preventTooltipScroll) element?.focus({ preventScroll: true });
|
|
3086
3131
|
else element?.focus();
|
|
@@ -3295,11 +3340,13 @@ function useChartChildren(children, chartType) {
|
|
|
3295
3340
|
}
|
|
3296
3341
|
const displayName = child.type?.displayName;
|
|
3297
3342
|
if (displayName === `${chartType}.SVG` || displayName === "Chart.SVG") {
|
|
3298
|
-
|
|
3343
|
+
const { children: svgChildren } = child.props ?? {};
|
|
3344
|
+
if (svgChildren) Children.forEach(svgChildren, (svgChild) => {
|
|
3299
3345
|
svg.push(svgChild);
|
|
3300
3346
|
});
|
|
3301
3347
|
} else if (displayName === `${chartType}.HTML` || displayName === "Chart.HTML") {
|
|
3302
|
-
|
|
3348
|
+
const { children: htmlChildren } = child.props ?? {};
|
|
3349
|
+
if (htmlChildren) Children.forEach(htmlChildren, (htmlChild) => {
|
|
3303
3350
|
html.push(htmlChild);
|
|
3304
3351
|
});
|
|
3305
3352
|
} else if (child.type === Group) svg.push(child);
|
|
@@ -4121,6 +4168,7 @@ var line_chart_module_default = {
|
|
|
4121
4168
|
"line-chart--animated": "a8ccharts-inuQka-line-chart--animated",
|
|
4122
4169
|
"rise": "a8ccharts-inuQka-rise"
|
|
4123
4170
|
};
|
|
4171
|
+
const isReact18 = version.startsWith("18.");
|
|
4124
4172
|
const CloseIcon = () => /* @__PURE__ */ jsx("svg", {
|
|
4125
4173
|
width: "16",
|
|
4126
4174
|
height: "16",
|
|
@@ -4163,7 +4211,7 @@ const LineChartAnnotationLabelWithPopover = ({ title, subtitle, renderLabel, ren
|
|
|
4163
4211
|
className: line_chart_module_default["line-chart__annotation-label"],
|
|
4164
4212
|
children: [/* @__PURE__ */ jsx("button", {
|
|
4165
4213
|
ref: buttonRef,
|
|
4166
|
-
popovertarget: popoverId,
|
|
4214
|
+
...isReact18 ? { popovertarget: popoverId } : { popoverTarget: popoverId },
|
|
4167
4215
|
className: line_chart_module_default["line-chart__annotation-label-trigger-button"],
|
|
4168
4216
|
style: {
|
|
4169
4217
|
width: `44px`,
|
|
@@ -4191,8 +4239,13 @@ const LineChartAnnotationLabelWithPopover = ({ title, subtitle, renderLabel, ren
|
|
|
4191
4239
|
subtitle
|
|
4192
4240
|
})
|
|
4193
4241
|
}), /* @__PURE__ */ jsx("button", {
|
|
4194
|
-
|
|
4195
|
-
|
|
4242
|
+
...isReact18 ? {
|
|
4243
|
+
popovertarget: popoverId,
|
|
4244
|
+
popovertargetaction: "hide"
|
|
4245
|
+
} : {
|
|
4246
|
+
popoverTarget: popoverId,
|
|
4247
|
+
popoverTargetAction: "hide"
|
|
4248
|
+
},
|
|
4196
4249
|
className: line_chart_module_default["line-chart__annotation-label-popover-close-button"],
|
|
4197
4250
|
"aria-label": __("Close", "jetpack-charts"),
|
|
4198
4251
|
children: /* @__PURE__ */ jsx(CloseIcon, {})
|
|
@@ -4714,10 +4767,11 @@ const LineChartScalesRef = ({ chartRef, width, height, margin }) => {
|
|
|
4714
4767
|
]);
|
|
4715
4768
|
return null;
|
|
4716
4769
|
};
|
|
4717
|
-
const LineChartInternal = forwardRef(({ data, chartId: providedChartId, width, height, className, margin, withTooltips = true, withTooltipCrosshairs, showLegend = false, legend = {}, renderGlyph = defaultRenderGlyph, glyphStyle = {}, withLegendGlyph = false, withGradientFill = false, smoothing = true, curveType, renderTooltip = renderDefaultTooltip, tooltipPlacement, tooltipStyle, withStartGlyphs = false, withEndGlyphs = false, animation, options = {}, onPointerDown = void 0, onPointerUp = void 0, onPointerMove = void 0, onPointerOut = void 0, onDatumActivate = void 0, zoomable = false, rescaleYOnVisibilityChange = true, defaultHiddenSeries, children, gridVisibility, gap = "md" }, ref) => {
|
|
4770
|
+
const LineChartInternal = forwardRef(({ data, ariaLabel, chartId: providedChartId, width, height, className, margin, withTooltips = true, withTooltipCrosshairs, showLegend = false, legend = {}, renderGlyph = defaultRenderGlyph, glyphStyle = {}, withLegendGlyph = false, withGradientFill = false, smoothing = true, curveType, renderTooltip = renderDefaultTooltip, tooltipPlacement, tooltipStyle, withStartGlyphs = false, withEndGlyphs = false, animation, options = {}, onPointerDown = void 0, onPointerUp = void 0, onPointerMove = void 0, onPointerOut = void 0, onDatumActivate = void 0, zoomable = false, rescaleYOnVisibilityChange = true, defaultHiddenSeries, children, gridVisibility, gap = "md" }, ref) => {
|
|
4718
4771
|
const legendInteractive = legend.interactive ?? false;
|
|
4719
4772
|
const legendCollapseGroups = legend.collapseGroups ?? false;
|
|
4720
4773
|
const legendComparisonItem = legend.comparisonItem ?? false;
|
|
4774
|
+
const legendComparisonSeriesItems = legend.comparisonSeriesItems;
|
|
4721
4775
|
const legendShape = legend.shape ?? "line";
|
|
4722
4776
|
const legendPosition = legend.position ?? "bottom";
|
|
4723
4777
|
const formatting = useChartFormatting();
|
|
@@ -4902,12 +4956,14 @@ const LineChartInternal = forwardRef(({ data, chartId: providedChartId, width, h
|
|
|
4902
4956
|
glyphSize: Math.max(0, toNumber(glyphStyle?.radius) ?? 4),
|
|
4903
4957
|
collapseGroups: legendCollapseGroups,
|
|
4904
4958
|
comparisonItem: legendComparisonItem,
|
|
4959
|
+
comparisonSeriesItems: legendComparisonSeriesItems,
|
|
4905
4960
|
renderGlyph
|
|
4906
4961
|
}), [
|
|
4907
4962
|
withLegendGlyph,
|
|
4908
4963
|
glyphStyle?.radius,
|
|
4909
4964
|
legendCollapseGroups,
|
|
4910
4965
|
legendComparisonItem,
|
|
4966
|
+
legendComparisonSeriesItems,
|
|
4911
4967
|
renderGlyph
|
|
4912
4968
|
]), legendShape);
|
|
4913
4969
|
const chartMetadata = useMemo(() => ({
|
|
@@ -4982,8 +5038,8 @@ const LineChartInternal = forwardRef(({ data, chartId: providedChartId, width, h
|
|
|
4982
5038
|
const chartHeight = contentHeight > 0 ? contentHeight : height;
|
|
4983
5039
|
return /* @__PURE__ */ jsx("div", {
|
|
4984
5040
|
ref: chartRef,
|
|
4985
|
-
role: "
|
|
4986
|
-
"aria-label": __("Line chart", "jetpack-charts"),
|
|
5041
|
+
role: "application",
|
|
5042
|
+
"aria-label": ariaLabel ?? __("Line chart", "jetpack-charts"),
|
|
4987
5043
|
tabIndex: 0,
|
|
4988
5044
|
onKeyDown: onChartKeyDown,
|
|
4989
5045
|
onFocus: onChartFocus,
|
|
@@ -4991,6 +5047,7 @@ const LineChartInternal = forwardRef(({ data, chartId: providedChartId, width, h
|
|
|
4991
5047
|
children: chartHeight > 0 && /* @__PURE__ */ jsxs("div", {
|
|
4992
5048
|
className: xy_plot_module_default["xy-plot"],
|
|
4993
5049
|
children: [zoomable && zoom.domain && /* @__PURE__ */ jsx(ZoomResetButton, { onClick: zoom.reset }), /* @__PURE__ */ jsxs(XYChart, {
|
|
5050
|
+
accessibilityLabel: "",
|
|
4994
5051
|
theme,
|
|
4995
5052
|
width,
|
|
4996
5053
|
height: chartHeight,
|
|
@@ -5231,7 +5288,7 @@ const HoverGlyphs = ({ visibleSeries, stacked, stackOffset, getElementStyles, st
|
|
|
5231
5288
|
};
|
|
5232
5289
|
//#endregion
|
|
5233
5290
|
//#region src/charts/area-chart/area-chart.tsx
|
|
5234
|
-
const AreaChartInternal = forwardRef(({ data, chartId: providedChartId, width, height, className, margin, withTooltips = true, withTooltipCrosshairs, showLegend = false, legend = {}, stacked = true, stackOffset = "none", smoothing = true, curveType, fillOpacity, withStroke, renderTooltip = renderDefaultTooltip, animation, options = {}, onPointerDown, onPointerUp, onPointerMove, onPointerOut, zoomable = false, rescaleYOnVisibilityChange = true, defaultHiddenSeries, children, gridVisibility, gap = "md" }, ref) => {
|
|
5291
|
+
const AreaChartInternal = forwardRef(({ data, ariaLabel, chartId: providedChartId, width, height, className, margin, withTooltips = true, withTooltipCrosshairs, showLegend = false, legend = {}, stacked = true, stackOffset = "none", smoothing = true, curveType, fillOpacity, withStroke, renderTooltip = renderDefaultTooltip, animation, options = {}, onPointerDown, onPointerUp, onPointerMove, onPointerOut, zoomable = false, rescaleYOnVisibilityChange = true, defaultHiddenSeries, children, gridVisibility, gap = "md" }, ref) => {
|
|
5235
5292
|
const legendInteractive = legend.interactive ?? false;
|
|
5236
5293
|
const legendShape = legend.shape ?? "rect";
|
|
5237
5294
|
const legendPosition = legend.position ?? "bottom";
|
|
@@ -5375,8 +5432,13 @@ const AreaChartInternal = forwardRef(({ data, chartId: providedChartId, width, h
|
|
|
5375
5432
|
withGlyph: false,
|
|
5376
5433
|
glyphSize: 0,
|
|
5377
5434
|
collapseGroups: legend.collapseGroups ?? false,
|
|
5378
|
-
comparisonItem: legend.comparisonItem ?? false
|
|
5379
|
-
|
|
5435
|
+
comparisonItem: legend.comparisonItem ?? false,
|
|
5436
|
+
comparisonSeriesItems: legend.comparisonSeriesItems
|
|
5437
|
+
}), [
|
|
5438
|
+
legend.collapseGroups,
|
|
5439
|
+
legend.comparisonItem,
|
|
5440
|
+
legend.comparisonSeriesItems
|
|
5441
|
+
]), legendShape);
|
|
5380
5442
|
const chartMetadata = useMemo(() => ({
|
|
5381
5443
|
stacked,
|
|
5382
5444
|
stackOffset,
|
|
@@ -5502,8 +5564,8 @@ const AreaChartInternal = forwardRef(({ data, chartId: providedChartId, width, h
|
|
|
5502
5564
|
const chartHeight = contentHeight > 0 ? contentHeight : height;
|
|
5503
5565
|
return /* @__PURE__ */ jsx("div", {
|
|
5504
5566
|
ref: chartRef,
|
|
5505
|
-
role: "
|
|
5506
|
-
"aria-label": __("Area chart", "jetpack-charts"),
|
|
5567
|
+
role: "application",
|
|
5568
|
+
"aria-label": ariaLabel ?? __("Area chart", "jetpack-charts"),
|
|
5507
5569
|
tabIndex: 0,
|
|
5508
5570
|
onKeyDown: onChartKeyDown,
|
|
5509
5571
|
onFocus: onChartFocus,
|
|
@@ -5511,6 +5573,7 @@ const AreaChartInternal = forwardRef(({ data, chartId: providedChartId, width, h
|
|
|
5511
5573
|
children: chartHeight > 0 && /* @__PURE__ */ jsxs("div", {
|
|
5512
5574
|
className: xy_plot_module_default["xy-plot"],
|
|
5513
5575
|
children: [zoomable && zoom.domain && /* @__PURE__ */ jsx(ZoomResetButton, { onClick: zoom.reset }), /* @__PURE__ */ jsxs(XYChart, {
|
|
5576
|
+
accessibilityLabel: "",
|
|
5514
5577
|
theme,
|
|
5515
5578
|
width,
|
|
5516
5579
|
height: chartHeight,
|
|
@@ -6363,11 +6426,12 @@ const renderTooltipRow = (label, value) => /* @__PURE__ */ jsx("div", {
|
|
|
6363
6426
|
className: bar_chart_module_default["bar-chart__tooltip-row"],
|
|
6364
6427
|
children: sprintf(__("%1$s: %2$s", "jetpack-charts"), label, value)
|
|
6365
6428
|
});
|
|
6366
|
-
const BarChartInternal = ({ data, chartId: providedChartId, width, height, className, margin, withTooltips = false, showLegend = false, legend = {}, gridVisibility: gridVisibilityProp, renderTooltip, tooltipPlacement, tooltipAnchorTop, tooltipStyle, barClassName, options = {}, orientation = "vertical", withPatterns = false, showZeroValues = false, withBandHighlight = false, onBandHighlightChange, defaultHiddenSeries, animation, children, gap = "md", onPointerDown, onPointerUp, onDatumActivate }) => {
|
|
6429
|
+
const BarChartInternal = ({ data, ariaLabel, chartId: providedChartId, width, height, className, margin, withTooltips = false, showLegend = false, legend = {}, gridVisibility: gridVisibilityProp, renderTooltip, tooltipPlacement, tooltipAnchorTop, tooltipStyle, barClassName, options = {}, orientation = "vertical", withPatterns = false, showZeroValues = false, withBandHighlight = false, onBandHighlightChange, defaultHiddenSeries, animation, children, gap = "md", onPointerDown, onPointerUp, onDatumActivate }) => {
|
|
6367
6430
|
if (!withTooltips && (withBandHighlight || onBandHighlightChange)) warnOnce("bar-chart-band-highlight-without-tooltips", "BarChart: withBandHighlight and onBandHighlightChange require withTooltips.");
|
|
6368
6431
|
const legendInteractive = legend.interactive ?? false;
|
|
6369
6432
|
const legendCollapseGroups = legend.collapseGroups ?? false;
|
|
6370
6433
|
const legendComparisonItem = legend.comparisonItem ?? false;
|
|
6434
|
+
const legendComparisonSeriesItems = legend.comparisonSeriesItems;
|
|
6371
6435
|
const horizontal = orientation === "horizontal";
|
|
6372
6436
|
const chartId = useChartId(providedChartId);
|
|
6373
6437
|
const hiddenSeries = useDefaultHiddenSeries(chartId, defaultHiddenSeries);
|
|
@@ -6380,8 +6444,13 @@ const BarChartInternal = ({ data, chartId: providedChartId, width, height, class
|
|
|
6380
6444
|
});
|
|
6381
6445
|
const legendItems = useChartLegendItems(dataSorted, useMemo(() => ({
|
|
6382
6446
|
collapseGroups: legendCollapseGroups,
|
|
6383
|
-
comparisonItem: legendComparisonItem
|
|
6384
|
-
|
|
6447
|
+
comparisonItem: legendComparisonItem,
|
|
6448
|
+
comparisonSeriesItems: legendComparisonSeriesItems
|
|
6449
|
+
}), [
|
|
6450
|
+
legendCollapseGroups,
|
|
6451
|
+
legendComparisonItem,
|
|
6452
|
+
legendComparisonSeriesItems
|
|
6453
|
+
]));
|
|
6385
6454
|
const { getElementStyles } = useGlobalChartsContext();
|
|
6386
6455
|
const isSeriesRendered = useCallback((series) => isSeriesVisible(series.label), [isSeriesVisible]);
|
|
6387
6456
|
const hasWholeNumberValues = useMemo(() => hasOnlyWholeNumbers(dataSorted.filter(isSeriesRendered)), [dataSorted, isSeriesRendered]);
|
|
@@ -6671,9 +6740,9 @@ const BarChartInternal = ({ data, chartId: providedChartId, width, height, class
|
|
|
6671
6740
|
children: ({ contentHeight }) => {
|
|
6672
6741
|
const chartHeight = contentHeight > 0 ? contentHeight : height;
|
|
6673
6742
|
return /* @__PURE__ */ jsx("div", {
|
|
6674
|
-
role: "
|
|
6743
|
+
role: "application",
|
|
6675
6744
|
ref: chartRef,
|
|
6676
|
-
"aria-label": __("Bar chart", "jetpack-charts"),
|
|
6745
|
+
"aria-label": ariaLabel ?? __("Bar chart", "jetpack-charts"),
|
|
6677
6746
|
tabIndex: 0,
|
|
6678
6747
|
onKeyDown: onChartKeyDown,
|
|
6679
6748
|
onFocus: onChartFocus,
|
|
@@ -6681,6 +6750,7 @@ const BarChartInternal = ({ data, chartId: providedChartId, width, height, class
|
|
|
6681
6750
|
children: chartHeight > 0 && /* @__PURE__ */ jsx("div", {
|
|
6682
6751
|
className: xy_plot_module_default["xy-plot"],
|
|
6683
6752
|
children: /* @__PURE__ */ jsxs(XYChart, {
|
|
6753
|
+
accessibilityLabel: "",
|
|
6684
6754
|
theme,
|
|
6685
6755
|
width,
|
|
6686
6756
|
height: chartHeight,
|
|
@@ -6891,7 +6961,7 @@ const BarListChartInternal = ({ data, width, height, options = {}, margin = {
|
|
|
6891
6961
|
right: 20,
|
|
6892
6962
|
bottom: 0,
|
|
6893
6963
|
top: 0
|
|
6894
|
-
}, className, ...rest }) => {
|
|
6964
|
+
}, className, ariaLabel, ...rest }) => {
|
|
6895
6965
|
const { getElementStyles } = useGlobalChartsContext();
|
|
6896
6966
|
const tintedData = useMemo(() => {
|
|
6897
6967
|
if (data.length > 1) return data;
|
|
@@ -6966,6 +7036,7 @@ const BarListChartInternal = ({ data, width, height, options = {}, margin = {
|
|
|
6966
7036
|
xScale: chartOptions.xScale,
|
|
6967
7037
|
yScale: chartOptions.yScale
|
|
6968
7038
|
},
|
|
7039
|
+
ariaLabel: ariaLabel ?? __("Bar list chart", "jetpack-charts"),
|
|
6969
7040
|
...rest
|
|
6970
7041
|
});
|
|
6971
7042
|
};
|
|
@@ -7041,6 +7112,8 @@ const useFunnelSelection = (hideTooltip) => {
|
|
|
7041
7112
|
};
|
|
7042
7113
|
//#endregion
|
|
7043
7114
|
//#region src/charts/conversion-funnel-chart/conversion-funnel-chart.tsx
|
|
7115
|
+
/** Chart height (px) below which the funnel tightens its gaps so the bars keep their room. */
|
|
7116
|
+
const SHORT_CHART_HEIGHT = 180;
|
|
7044
7117
|
/**
|
|
7045
7118
|
* Internal ConversionFunnelChart component with chart registration
|
|
7046
7119
|
*
|
|
@@ -7052,6 +7125,7 @@ const useFunnelSelection = (hideTooltip) => {
|
|
|
7052
7125
|
* @param props.loading - Whether the chart is in loading state
|
|
7053
7126
|
* @param props.animation - Whether to show chart animation on initial render or not
|
|
7054
7127
|
* @param props.className - Additional CSS class name
|
|
7128
|
+
* @param props.ariaLabel - Accessible name for the chart group
|
|
7055
7129
|
* @param props.height - Height of the chart container. Falls back to style.height if set, otherwise defaults to "100%".
|
|
7056
7130
|
* @param props.style - Custom styling
|
|
7057
7131
|
* @param props.renderStepLabel - Custom render function for step labels
|
|
@@ -7061,7 +7135,7 @@ const useFunnelSelection = (hideTooltip) => {
|
|
|
7061
7135
|
* @param props.tooltipStyle - Inline styles merged over the tooltip box defaults
|
|
7062
7136
|
* @return JSX element representing the conversion funnel chart
|
|
7063
7137
|
*/
|
|
7064
|
-
const ConversionFunnelChartInternal = ({ mainRate, changeIndicator, steps, loading = false, animation, className, chartId: providedChartId, height, style, renderStepLabel, renderStepRate, renderMainMetric, renderTooltip, tooltipStyle }) => {
|
|
7138
|
+
const ConversionFunnelChartInternal = ({ mainRate, changeIndicator, steps, loading = false, animation, className, ariaLabel, chartId: providedChartId, height, style, renderStepLabel, renderStepRate, renderMainMetric, renderTooltip, tooltipStyle }) => {
|
|
7065
7139
|
const chartId = useChartId(providedChartId);
|
|
7066
7140
|
const { getElementStyles, isColorPaletteResolved } = useGlobalChartsContext();
|
|
7067
7141
|
const chartRef = useRef(null);
|
|
@@ -7070,10 +7144,13 @@ const ConversionFunnelChartInternal = ({ mainRate, changeIndicator, steps, loadi
|
|
|
7070
7144
|
const { tooltipData, tooltipLeft, tooltipTop, tooltipOpen, showTooltip, hideTooltip } = useTooltip();
|
|
7071
7145
|
const { handleBarClick, handleBarKeyDown, clearSelection, getStepState } = useFunnelSelection(hideTooltip);
|
|
7072
7146
|
const standaloneScopeClass = useStandaloneScopeClass();
|
|
7147
|
+
const [measureChartRef, , chartHeight] = useElementSize();
|
|
7148
|
+
const gap = chartHeight > 0 && chartHeight < SHORT_CHART_HEIGHT ? "sm" : "xl";
|
|
7073
7149
|
const setChartRef = useCallback((node) => {
|
|
7074
7150
|
chartRef.current = node;
|
|
7075
7151
|
setScopeNode(node);
|
|
7076
|
-
|
|
7152
|
+
measureChartRef(node);
|
|
7153
|
+
}, [measureChartRef]);
|
|
7077
7154
|
const clearSelectionAndRef = useCallback(() => {
|
|
7078
7155
|
clearSelection();
|
|
7079
7156
|
selectedBarRef.current = null;
|
|
@@ -7221,7 +7298,9 @@ const ConversionFunnelChartInternal = ({ mainRate, changeIndicator, steps, loadi
|
|
|
7221
7298
|
const maxRate = Math.max(...steps.map((step) => step.rate));
|
|
7222
7299
|
return /* @__PURE__ */ jsxs(Stack, {
|
|
7223
7300
|
direction: "column",
|
|
7224
|
-
gap
|
|
7301
|
+
gap,
|
|
7302
|
+
role: "group",
|
|
7303
|
+
"aria-label": ariaLabel ?? __("Conversion funnel chart", "jetpack-charts"),
|
|
7225
7304
|
ref: setChartRef,
|
|
7226
7305
|
className: clsx("conversion-funnel-chart", conversion_funnel_chart_module_default["conversion-funnel-chart"], loading && conversion_funnel_chart_module_default["conversion-funnel-chart--loading"], className),
|
|
7227
7306
|
style: {
|
|
@@ -7252,7 +7331,7 @@ const ConversionFunnelChartInternal = ({ mainRate, changeIndicator, steps, loadi
|
|
|
7252
7331
|
return /* @__PURE__ */ jsxs(Stack, {
|
|
7253
7332
|
direction: "column",
|
|
7254
7333
|
className: clsx(conversion_funnel_chart_module_default["funnel-step"], isColorPaletteResolved && conversion_funnel_chart_module_default["funnel-step--animated"], isBlurred && conversion_funnel_chart_module_default["funnel-step--blurred"]),
|
|
7255
|
-
gap
|
|
7334
|
+
gap,
|
|
7256
7335
|
children: [/* @__PURE__ */ jsxs(Stack, {
|
|
7257
7336
|
direction: "column",
|
|
7258
7337
|
gap: "xs",
|
|
@@ -7446,6 +7525,7 @@ function normalizeGeoChartError(eventArgs) {
|
|
|
7446
7525
|
*
|
|
7447
7526
|
* @param props - The props for the GeoChart component
|
|
7448
7527
|
* @param props.data - Data in Google Charts format (array of arrays with headers)
|
|
7528
|
+
* @param props.ariaLabel - Accessible name of the chart
|
|
7449
7529
|
* @param props.width - Width of the chart in pixels
|
|
7450
7530
|
* @param props.height - Height of the chart in pixels
|
|
7451
7531
|
* @param props.region - Region to display ('world', 'US', or ISO 3166-1 alpha-2 code)
|
|
@@ -7457,7 +7537,7 @@ function normalizeGeoChartError(eventArgs) {
|
|
|
7457
7537
|
* @param props.renderPlaceholder - Optional render function for the loading placeholder
|
|
7458
7538
|
* @return A React component displaying an interactive map with data visualization
|
|
7459
7539
|
*/
|
|
7460
|
-
const GeoChartInternal = ({ className, data, width, height, region = "world", resolution = "countries", displayMode = "regions", domain, onError, renderPlaceholder }) => {
|
|
7540
|
+
const GeoChartInternal = ({ className, data, ariaLabel, width, height, region = "world", resolution = "countries", displayMode = "regions", domain, onError, renderPlaceholder }) => {
|
|
7461
7541
|
const { getElementStyles } = useGlobalChartsContext();
|
|
7462
7542
|
const scopeElement = useChartScopeElement();
|
|
7463
7543
|
const containerRef = useRef(null);
|
|
@@ -7545,8 +7625,14 @@ const GeoChartInternal = ({ className, data, width, height, region = "world", re
|
|
|
7545
7625
|
sanitizedData.hasHtmlTooltips
|
|
7546
7626
|
]);
|
|
7547
7627
|
const chartEvents = useMemo(() => {
|
|
7548
|
-
|
|
7549
|
-
|
|
7628
|
+
const readyEvent = {
|
|
7629
|
+
eventName: "ready",
|
|
7630
|
+
callback: () => {
|
|
7631
|
+
containerRef.current?.querySelectorAll("svg").forEach((svg) => svg.setAttribute("aria-hidden", "true"));
|
|
7632
|
+
}
|
|
7633
|
+
};
|
|
7634
|
+
if (!onError) return [readyEvent];
|
|
7635
|
+
return [readyEvent, {
|
|
7550
7636
|
eventName: "error",
|
|
7551
7637
|
callback: ({ eventArgs }) => {
|
|
7552
7638
|
onError(normalizeGeoChartError(eventArgs));
|
|
@@ -7555,6 +7641,8 @@ const GeoChartInternal = ({ className, data, width, height, region = "world", re
|
|
|
7555
7641
|
}, [onError]);
|
|
7556
7642
|
return /* @__PURE__ */ jsx(Center, {
|
|
7557
7643
|
ref: containerRef,
|
|
7644
|
+
role: "group",
|
|
7645
|
+
"aria-label": ariaLabel ?? __("Geo chart", "jetpack-charts"),
|
|
7558
7646
|
className: clsx("geo-chart", geo_chart_module_default.container, className),
|
|
7559
7647
|
style: {
|
|
7560
7648
|
width,
|
|
@@ -7686,6 +7774,7 @@ var heatmap_chart_module_default = {
|
|
|
7686
7774
|
"heatmap-chart__legend-label": "a8ccharts-O3YMOW-heatmap-chart__legend-label",
|
|
7687
7775
|
"heatmap-chart__legend-scale--bar": "a8ccharts-O3YMOW-heatmap-chart__legend-scale--bar",
|
|
7688
7776
|
"heatmap-chart__legend-swatch": "a8ccharts-O3YMOW-heatmap-chart__legend-swatch",
|
|
7777
|
+
"heatmap-chart__legend-swatch--empty": "a8ccharts-O3YMOW-heatmap-chart__legend-swatch--empty",
|
|
7689
7778
|
"heatmap-chart__row": "a8ccharts-O3YMOW-heatmap-chart__row",
|
|
7690
7779
|
"heatmap-chart__row-label": "a8ccharts-O3YMOW-heatmap-chart__row-label",
|
|
7691
7780
|
"heatmap-chart--height-capped": "a8ccharts-O3YMOW-heatmap-chart--height-capped"
|
|
@@ -7783,8 +7872,9 @@ const HeatmapLegend = ({ steps = 5, variant = "swatches", lessLabel, moreLabel }
|
|
|
7783
7872
|
const context = useContext(HeatmapContext);
|
|
7784
7873
|
const { legend } = useGlobalChartsTheme();
|
|
7785
7874
|
if (!context) return null;
|
|
7786
|
-
const { fillVars } = context;
|
|
7875
|
+
const { extent, fillVars } = context;
|
|
7787
7876
|
const labelStyle = legend.labelStyles;
|
|
7877
|
+
const showsEmptyCell = isEmptyValue(0, extent);
|
|
7788
7878
|
return /* @__PURE__ */ jsxs(Stack, {
|
|
7789
7879
|
direction: "row",
|
|
7790
7880
|
gap: "xs",
|
|
@@ -7796,12 +7886,12 @@ const HeatmapLegend = ({ steps = 5, variant = "swatches", lessLabel, moreLabel }
|
|
|
7796
7886
|
style: labelStyle,
|
|
7797
7887
|
children: lessLabel ?? __("Less", "jetpack-charts")
|
|
7798
7888
|
}),
|
|
7799
|
-
/* @__PURE__ */
|
|
7889
|
+
/* @__PURE__ */ jsxs(Stack, {
|
|
7800
7890
|
direction: "row",
|
|
7801
7891
|
gap: variant === "bar" ? void 0 : "xs",
|
|
7802
7892
|
"aria-hidden": "true",
|
|
7803
7893
|
className: variant === "bar" ? heatmap_chart_module_default["heatmap-chart__legend-scale--bar"] : void 0,
|
|
7804
|
-
children: Array.from({ length: steps }, (_, index) => {
|
|
7894
|
+
children: [showsEmptyCell && /* @__PURE__ */ jsx("span", { className: clsx(heatmap_chart_module_default["heatmap-chart__legend-swatch"], heatmap_chart_module_default["heatmap-chart__legend-swatch--empty"]) }), Array.from({ length: steps }, (_, index) => {
|
|
7805
7895
|
const intensity = steps <= 1 ? 1 : index / (steps - 1);
|
|
7806
7896
|
return /* @__PURE__ */ jsx("span", {
|
|
7807
7897
|
className: heatmap_chart_module_default["heatmap-chart__legend-swatch"],
|
|
@@ -7810,7 +7900,7 @@ const HeatmapLegend = ({ steps = 5, variant = "swatches", lessLabel, moreLabel }
|
|
|
7810
7900
|
"--a8c-charts-heatmap-cell-intensity": intensity
|
|
7811
7901
|
}
|
|
7812
7902
|
}, index);
|
|
7813
|
-
})
|
|
7903
|
+
})]
|
|
7814
7904
|
}),
|
|
7815
7905
|
/* @__PURE__ */ jsx(Text$1, {
|
|
7816
7906
|
variant: "body-sm",
|
|
@@ -7836,9 +7926,11 @@ const resolveColumnGroups = (groups, columnCount, firstLine) => {
|
|
|
7836
7926
|
const ungrouped = () => ({
|
|
7837
7927
|
columns: Array.from({ length: columnCount }, (_, index) => ({
|
|
7838
7928
|
line: firstLine + index,
|
|
7929
|
+
band: 0,
|
|
7839
7930
|
gapBefore: false
|
|
7840
7931
|
})),
|
|
7841
|
-
groups: []
|
|
7932
|
+
groups: [],
|
|
7933
|
+
bands: 1
|
|
7842
7934
|
});
|
|
7843
7935
|
if (!groups || groups.length === 0 || columnCount === 0) return ungrouped();
|
|
7844
7936
|
const spans = groups.map((group) => group.span);
|
|
@@ -7854,11 +7946,13 @@ const resolveColumnGroups = (groups, columnCount, firstLine) => {
|
|
|
7854
7946
|
if (groupIndex > 0) line += 1;
|
|
7855
7947
|
laidOut.push({
|
|
7856
7948
|
...group,
|
|
7857
|
-
line
|
|
7949
|
+
line,
|
|
7950
|
+
band: 0
|
|
7858
7951
|
});
|
|
7859
7952
|
for (let offset = 0; offset < group.span; offset++) {
|
|
7860
7953
|
columns.push({
|
|
7861
7954
|
line,
|
|
7955
|
+
band: 0,
|
|
7862
7956
|
gapBefore: groupIndex > 0 && offset === 0,
|
|
7863
7957
|
group: groupIndex
|
|
7864
7958
|
});
|
|
@@ -7868,13 +7962,99 @@ const resolveColumnGroups = (groups, columnCount, firstLine) => {
|
|
|
7868
7962
|
while (columns.length < columnCount) {
|
|
7869
7963
|
columns.push({
|
|
7870
7964
|
line,
|
|
7965
|
+
band: 0,
|
|
7871
7966
|
gapBefore: false
|
|
7872
7967
|
});
|
|
7873
7968
|
line += 1;
|
|
7874
7969
|
}
|
|
7875
7970
|
return {
|
|
7876
7971
|
columns,
|
|
7877
|
-
groups: laidOut
|
|
7972
|
+
groups: laidOut,
|
|
7973
|
+
bands: 1
|
|
7974
|
+
};
|
|
7975
|
+
};
|
|
7976
|
+
/**
|
|
7977
|
+
* Wraps the groups onto bands of equal group count, each band starting back at
|
|
7978
|
+
* the first data line so the groups line up in slots down the bands.
|
|
7979
|
+
*
|
|
7980
|
+
* @param layout - The unwrapped layout from `resolveColumnGroups`.
|
|
7981
|
+
* @param bands - Bands to aim for; the groups split as evenly as whole bands allow.
|
|
7982
|
+
* @return The wrapped layout, or null when there is nothing to wrap: one band, one group, or a column outside every group.
|
|
7983
|
+
*/
|
|
7984
|
+
const wrapColumnGroups = (layout, bands) => {
|
|
7985
|
+
const { columns, groups } = layout;
|
|
7986
|
+
if (bands < 2 || groups.length < 2 || columns.some((column) => column.group === void 0)) return null;
|
|
7987
|
+
const perBand = Math.ceil(groups.length / bands);
|
|
7988
|
+
const slotSpans = Array(perBand).fill(0);
|
|
7989
|
+
groups.forEach((group, index) => {
|
|
7990
|
+
const slot = index % perBand;
|
|
7991
|
+
slotSpans[slot] = Math.max(slotSpans[slot], group.span);
|
|
7992
|
+
});
|
|
7993
|
+
const slotLines = [];
|
|
7994
|
+
let line = columns[0].line;
|
|
7995
|
+
slotSpans.forEach((span, slot) => {
|
|
7996
|
+
if (slot > 0) line += 1;
|
|
7997
|
+
slotLines.push(line);
|
|
7998
|
+
line += span;
|
|
7999
|
+
});
|
|
8000
|
+
const wrappedGroups = groups.map((group, index) => ({
|
|
8001
|
+
...group,
|
|
8002
|
+
line: slotLines[index % perBand],
|
|
8003
|
+
band: Math.floor(index / perBand)
|
|
8004
|
+
}));
|
|
8005
|
+
return {
|
|
8006
|
+
columns: columns.map((column) => {
|
|
8007
|
+
const group = column.group;
|
|
8008
|
+
const offset = column.line - groups[group].line;
|
|
8009
|
+
return {
|
|
8010
|
+
...column,
|
|
8011
|
+
line: wrappedGroups[group].line + offset,
|
|
8012
|
+
band: wrappedGroups[group].band,
|
|
8013
|
+
gapBefore: offset === 0 && group % perBand > 0
|
|
8014
|
+
};
|
|
8015
|
+
}),
|
|
8016
|
+
groups: wrappedGroups,
|
|
8017
|
+
bands: Math.ceil(groups.length / perBand),
|
|
8018
|
+
slotSpans
|
|
8019
|
+
};
|
|
8020
|
+
};
|
|
8021
|
+
//#endregion
|
|
8022
|
+
//#region src/charts/heatmap-chart/private/fit-compact-cells.ts
|
|
8023
|
+
/**
|
|
8024
|
+
* Largest whole-pixel square cell, and the band count giving it, for a compact grid in a box.
|
|
8025
|
+
*
|
|
8026
|
+
* @param input - The box, the grid's layout, and its fixed gaps and label sizes.
|
|
8027
|
+
* @return The fit; one band at `minCellSize` when no band count reaches it.
|
|
8028
|
+
*/
|
|
8029
|
+
const fitCompactCells = (input) => {
|
|
8030
|
+
const { width, height, layout, rows, cellGap, groupGap, minCellSize } = input;
|
|
8031
|
+
const columns = layout.columns.length;
|
|
8032
|
+
if (columns === 0 || rows === 0) return {
|
|
8033
|
+
bands: 1,
|
|
8034
|
+
cellSize: minCellSize
|
|
8035
|
+
};
|
|
8036
|
+
const maxBands = Math.max(1, layout.groups.length);
|
|
8037
|
+
const labelHeights = (input.columnLabelHeight ?? 0) + (input.groupLabelHeight ?? 0);
|
|
8038
|
+
const bandTracks = (input.columnLabelHeight === null ? 0 : 1) + rows + (input.groupLabelHeight === null ? 0 : 1);
|
|
8039
|
+
let best = null;
|
|
8040
|
+
for (let target = 1; target <= maxBands; target++) {
|
|
8041
|
+
const wrapped = target > 1 ? wrapColumnGroups(layout, target) : null;
|
|
8042
|
+
const { bands } = wrapped ?? layout;
|
|
8043
|
+
const cellColumns = wrapped ? wrapped.slotSpans.reduce((sum, span) => sum + span, 0) : columns;
|
|
8044
|
+
const gapTracks = wrapped ? wrapped.slotSpans.length - 1 : layout.columns.filter((column) => column.gapBefore).length;
|
|
8045
|
+
const columnTracks = 1 + cellColumns + gapTracks;
|
|
8046
|
+
const byWidth = (width - input.rowLabelWidth - gapTracks * groupGap - (columnTracks - 1) * cellGap) / cellColumns;
|
|
8047
|
+
const rowTracks = bands * bandTracks + (bands - 1);
|
|
8048
|
+
const byHeight = (height - (bands * labelHeights + (bands - 1) * groupGap + (rowTracks - 1) * cellGap)) / (bands * rows);
|
|
8049
|
+
const cellSize = Math.floor(Math.min(byWidth, byHeight));
|
|
8050
|
+
if (cellSize >= minCellSize && (!best || cellSize > best.cellSize)) best = {
|
|
8051
|
+
bands,
|
|
8052
|
+
cellSize
|
|
8053
|
+
};
|
|
8054
|
+
}
|
|
8055
|
+
return best ?? {
|
|
8056
|
+
bands: 1,
|
|
8057
|
+
cellSize: minCellSize
|
|
7878
8058
|
};
|
|
7879
8059
|
};
|
|
7880
8060
|
//#endregion
|
|
@@ -8017,18 +8197,32 @@ const CELL_VALUE_MODIFIER = {
|
|
|
8017
8197
|
white: heatmap_chart_module_default["heatmap-chart__cell-value--white"]
|
|
8018
8198
|
};
|
|
8019
8199
|
const NO_ROW_LABELS = [];
|
|
8020
|
-
const TOOLTIP_BOX_STYLE = { zIndex: 3 };
|
|
8200
|
+
const TOOLTIP_BOX_STYLE$1 = { zIndex: 3 };
|
|
8201
|
+
const largest = (root, selector, size) => Math.max(0, ...Array.from(root.querySelectorAll(selector), (el) => el[size]));
|
|
8202
|
+
const gridBox = (chart, grid) => {
|
|
8203
|
+
let height = chart.clientHeight;
|
|
8204
|
+
const rowGap = parseFloat(getComputedStyle(chart).rowGap) || 0;
|
|
8205
|
+
Array.from(chart.children).forEach((child) => {
|
|
8206
|
+
const { display, position } = getComputedStyle(child);
|
|
8207
|
+
if (child === grid || display === "none" || position === "absolute" || position === "fixed") return;
|
|
8208
|
+
height -= child.offsetHeight + rowGap;
|
|
8209
|
+
});
|
|
8210
|
+
return {
|
|
8211
|
+
width: chart.clientWidth,
|
|
8212
|
+
height
|
|
8213
|
+
};
|
|
8214
|
+
};
|
|
8021
8215
|
const cellName = (info) => info.cellLabel || [
|
|
8022
8216
|
info.groupLabel,
|
|
8023
8217
|
info.columnLabel,
|
|
8024
8218
|
info.rowLabel
|
|
8025
8219
|
].filter(Boolean).join(" ");
|
|
8026
|
-
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 }) => {
|
|
8220
|
+
const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, height = 0, className, compact = false, fitCells = false, showValues, maxCellWidth, maxCellHeight, minCellWidth, minCellHeight, rowLabels = NO_ROW_LABELS, columnGroups, keyboardNavigation = "grid", ariaLabel, primaryColor, gap = "md", withTooltips = false, renderTooltip, tooltipStyle, children }) => {
|
|
8027
8221
|
const chartId = useChartId(providedChartId);
|
|
8028
8222
|
const tooltipBoxStyle = tooltipStyle ? {
|
|
8029
|
-
...TOOLTIP_BOX_STYLE,
|
|
8223
|
+
...TOOLTIP_BOX_STYLE$1,
|
|
8030
8224
|
...tooltipStyle
|
|
8031
|
-
} : TOOLTIP_BOX_STYLE;
|
|
8225
|
+
} : TOOLTIP_BOX_STYLE$1;
|
|
8032
8226
|
const { getElementStyles, theme } = useGlobalChartsContext();
|
|
8033
8227
|
const scopeElement = useChartScopeElement();
|
|
8034
8228
|
const { heatmapChart: heatmapChartSettings } = theme;
|
|
@@ -8037,8 +8231,9 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
|
|
|
8037
8231
|
const { tooltipOpen, tooltipLeft, tooltipTop, tooltipData, showTooltip, hideTooltip } = useTooltip();
|
|
8038
8232
|
const standaloneScopeClass = useStandaloneScopeClass();
|
|
8039
8233
|
const containerRef = useRef(null);
|
|
8234
|
+
const chartRef = useRef(null);
|
|
8040
8235
|
const [labelRoles, setLabelRoles] = useState(null);
|
|
8041
|
-
const getTooltipOrigin = useCallback(() =>
|
|
8236
|
+
const getTooltipOrigin = useCallback(() => chartRef.current?.getBoundingClientRect() ?? null, []);
|
|
8042
8237
|
const { color: primaryColorHex } = getElementStyles({
|
|
8043
8238
|
index: 0,
|
|
8044
8239
|
overrideColor: primaryColor
|
|
@@ -8080,6 +8275,49 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
|
|
|
8080
8275
|
const groupLayout = useMemo(() => resolveColumnGroups(columnGroups, columns, 2), [columnGroups, columns]);
|
|
8081
8276
|
const { compactCellGap, compactCellSize, groupGap } = heatmapChartSettings;
|
|
8082
8277
|
const drawValues = showValues ?? !compact;
|
|
8278
|
+
const hasColumnLabels = data.some((column) => Boolean(column.label));
|
|
8279
|
+
const hasGroups = groupLayout.groups.length > 0;
|
|
8280
|
+
const [fit, setFit] = useState(null);
|
|
8281
|
+
const hasSummary = data.some((column) => column.summary);
|
|
8282
|
+
const fitting = compact && fitCells && !hasSummary;
|
|
8283
|
+
if (fitCells && !fitting) warnOnce("heatmap:fitCells", "fitCells applies only in compact mode without summary columns, so the cells keep their size.");
|
|
8284
|
+
useIsomorphicLayoutEffect(() => {
|
|
8285
|
+
const chart = chartRef.current;
|
|
8286
|
+
const grid = containerRef.current;
|
|
8287
|
+
if (!fitting || !chart || !grid) {
|
|
8288
|
+
setFit(null);
|
|
8289
|
+
return;
|
|
8290
|
+
}
|
|
8291
|
+
const measure = () => {
|
|
8292
|
+
const next = fitCompactCells({
|
|
8293
|
+
...gridBox(chart, grid),
|
|
8294
|
+
layout: groupLayout,
|
|
8295
|
+
rows,
|
|
8296
|
+
cellGap: compactCellGap,
|
|
8297
|
+
groupGap,
|
|
8298
|
+
rowLabelWidth: largest(grid, `.${heatmap_chart_module_default["heatmap-chart__row-label"]}`, "offsetWidth"),
|
|
8299
|
+
columnLabelHeight: hasColumnLabels ? largest(grid, `.${heatmap_chart_module_default["heatmap-chart__col-label"]}`, "offsetHeight") : null,
|
|
8300
|
+
groupLabelHeight: hasGroups ? largest(grid, `.${heatmap_chart_module_default["heatmap-chart__group-label"]}`, "offsetHeight") : null,
|
|
8301
|
+
minCellSize: compactCellSize
|
|
8302
|
+
});
|
|
8303
|
+
setFit((previous) => (0, import_fast_deep_equal.default)(previous, next) ? previous : next);
|
|
8304
|
+
};
|
|
8305
|
+
measure();
|
|
8306
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
8307
|
+
const observer = new ResizeObserver(() => flushSync(measure));
|
|
8308
|
+
observer.observe(chart);
|
|
8309
|
+
return () => observer.disconnect();
|
|
8310
|
+
}, [
|
|
8311
|
+
fitting,
|
|
8312
|
+
groupLayout,
|
|
8313
|
+
rows,
|
|
8314
|
+
hasColumnLabels,
|
|
8315
|
+
hasGroups,
|
|
8316
|
+
compactCellGap,
|
|
8317
|
+
compactCellSize,
|
|
8318
|
+
groupGap
|
|
8319
|
+
]);
|
|
8320
|
+
const wrapped = useMemo(() => fit ? wrapColumnGroups(groupLayout, fit.bands) : null, [fit, groupLayout]);
|
|
8083
8321
|
const buildTooltipData = useCallback((columnIndex, rowIndex) => {
|
|
8084
8322
|
const cell = data[columnIndex]?.data[rowIndex];
|
|
8085
8323
|
const group = groupLayout.columns[columnIndex]?.group;
|
|
@@ -8219,21 +8457,25 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
|
|
|
8219
8457
|
});
|
|
8220
8458
|
const columnTrack = compact ? "var(--a8c-charts-dimension-heatmap-cell-size)" : `minmax(${minCellWidth ?? 0}px, ${maxCellWidth ? `${maxCellWidth}px` : "1fr"})`;
|
|
8221
8459
|
const rowTrack = compact ? "var(--a8c-charts-dimension-heatmap-cell-size)" : `minmax(${minCellHeight ?? 0}px, ${maxCellHeight ? `${maxCellHeight}px` : "1fr"})`;
|
|
8222
|
-
const
|
|
8223
|
-
const
|
|
8224
|
-
const
|
|
8225
|
-
const
|
|
8460
|
+
const placed = wrapped ?? groupLayout;
|
|
8461
|
+
const columnLine = (columnIndex) => placed.columns[columnIndex].line;
|
|
8462
|
+
const bandOf = (columnIndex) => placed.columns[columnIndex].band;
|
|
8463
|
+
const { bands } = placed;
|
|
8464
|
+
const bandRowCount = (hasColumnLabels ? 1 : 0) + rows + (hasGroups ? 1 : 0) + 1;
|
|
8465
|
+
const labelRowOf = (band) => 1 + band * bandRowCount;
|
|
8466
|
+
const dataRowOf = (band, rowIndex) => labelRowOf(band) + (hasColumnLabels ? 1 : 0) + rowIndex;
|
|
8226
8467
|
const dataTrack = (column) => column.summary ? "minmax(auto, max-content)" : columnTrack;
|
|
8227
8468
|
const gapTrack = compact ? `minmax(${groupGap}px, 1fr)` : `${groupGap}px`;
|
|
8228
|
-
const columnTracks = data.map((column, columnIndex) => groupLayout.columns[columnIndex].gapBefore ? `${gapTrack} ${dataTrack(column)}` : dataTrack(column)).join(" ");
|
|
8469
|
+
const columnTracks = wrapped ? wrapped.slotSpans.map((span, slot) => [...slot > 0 ? [gapTrack] : [], ...Array(span).fill(columnTrack)].join(" ")).join(" ") : data.map((column, columnIndex) => groupLayout.columns[columnIndex].gapBefore ? `${gapTrack} ${dataTrack(column)}` : dataTrack(column)).join(" ");
|
|
8470
|
+
const bandTracks = `${hasColumnLabels ? "auto " : ""}repeat(${rows}, ${rowTrack})${hasGroups ? " auto" : ""}`;
|
|
8229
8471
|
const gridStyle = {
|
|
8230
8472
|
...fillVars,
|
|
8231
8473
|
gridTemplateColumns: `auto ${columnTracks}`,
|
|
8232
|
-
gridTemplateRows:
|
|
8474
|
+
gridTemplateRows: Array(bands).fill(bandTracks).join(` ${groupGap}px `)
|
|
8233
8475
|
};
|
|
8234
8476
|
if (compact) {
|
|
8235
8477
|
gridStyle["--a8c-charts-dimension-heatmap-cell-gap"] = `${compactCellGap}px`;
|
|
8236
|
-
gridStyle["--a8c-charts-dimension-heatmap-cell-size"] = `${compactCellSize}px`;
|
|
8478
|
+
gridStyle["--a8c-charts-dimension-heatmap-cell-size"] = `${fit?.cellSize ?? compactCellSize}px`;
|
|
8237
8479
|
}
|
|
8238
8480
|
const summaryGaps = (columnIndex) => {
|
|
8239
8481
|
if (!data[columnIndex]?.summary) return {};
|
|
@@ -8253,6 +8495,7 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
|
|
|
8253
8495
|
legendChildren: [],
|
|
8254
8496
|
trailingContent: nonLegendChildren,
|
|
8255
8497
|
gap,
|
|
8498
|
+
rootRef: chartRef,
|
|
8256
8499
|
className: clsx("heatmap-chart", heatmap_chart_module_default["heatmap-chart"], className, { [heatmap_chart_module_default["heatmap-chart--height-capped"]]: heightCapped }),
|
|
8257
8500
|
style: {
|
|
8258
8501
|
width: width || void 0,
|
|
@@ -8282,11 +8525,11 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
|
|
|
8282
8525
|
className: heatmap_chart_module_default["heatmap-chart__row"],
|
|
8283
8526
|
children: [/* @__PURE__ */ jsx("span", { style: {
|
|
8284
8527
|
gridColumn: 1,
|
|
8285
|
-
gridRow:
|
|
8528
|
+
gridRow: labelRowOf(0)
|
|
8286
8529
|
} }), data.map((column, columnIndex) => /* @__PURE__ */ jsx("span", {
|
|
8287
8530
|
style: {
|
|
8288
8531
|
gridColumn: columnLine(columnIndex),
|
|
8289
|
-
gridRow:
|
|
8532
|
+
gridRow: labelRowOf(bandOf(columnIndex))
|
|
8290
8533
|
},
|
|
8291
8534
|
className: clsx(heatmap_chart_module_default["heatmap-chart__col-label"], {
|
|
8292
8535
|
[heatmap_chart_module_default["heatmap-chart__col-label--summary"]]: column.summary,
|
|
@@ -8297,24 +8540,23 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
|
|
|
8297
8540
|
}),
|
|
8298
8541
|
Array.from({ length: rows }).map((_row, rowIndex) => {
|
|
8299
8542
|
const labelVisible = !compact || rowIndex % 2 === 0;
|
|
8300
|
-
const gridRow = firstDataRow + rowIndex;
|
|
8301
8543
|
return /* @__PURE__ */ jsxs("div", {
|
|
8302
8544
|
role: "row",
|
|
8303
8545
|
"aria-rowindex": rowIndex + 1,
|
|
8304
8546
|
className: heatmap_chart_module_default["heatmap-chart__row"],
|
|
8305
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
8547
|
+
children: [Array.from({ length: bands }).map((_band, band) => /* @__PURE__ */ jsx("span", {
|
|
8306
8548
|
"aria-hidden": "true",
|
|
8307
8549
|
className: heatmap_chart_module_default["heatmap-chart__row-label"],
|
|
8308
8550
|
style: {
|
|
8309
8551
|
gridColumn: 1,
|
|
8310
|
-
gridRow
|
|
8552
|
+
gridRow: dataRowOf(band, rowIndex)
|
|
8311
8553
|
},
|
|
8312
8554
|
children: labelVisible ? rowLabels[rowIndex] ?? "" : ""
|
|
8313
|
-
}), data.map((column, columnIndex) => {
|
|
8555
|
+
}, `row-label-${band}`)), data.map((column, columnIndex) => {
|
|
8314
8556
|
const cell = column.data[rowIndex];
|
|
8315
8557
|
const placement = {
|
|
8316
8558
|
gridColumn: columnLine(columnIndex),
|
|
8317
|
-
gridRow
|
|
8559
|
+
gridRow: dataRowOf(bandOf(columnIndex), rowIndex)
|
|
8318
8560
|
};
|
|
8319
8561
|
if (cell?.hidden) return /* @__PURE__ */ jsx("div", {
|
|
8320
8562
|
"aria-hidden": "true",
|
|
@@ -8364,11 +8606,11 @@ const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, heigh
|
|
|
8364
8606
|
role: "row",
|
|
8365
8607
|
"aria-hidden": "true",
|
|
8366
8608
|
className: heatmap_chart_module_default["heatmap-chart__row"],
|
|
8367
|
-
children:
|
|
8609
|
+
children: placed.groups.map((group, groupIndex) => /* @__PURE__ */ jsx("span", {
|
|
8368
8610
|
className: heatmap_chart_module_default["heatmap-chart__group-label"],
|
|
8369
8611
|
style: {
|
|
8370
8612
|
gridColumn: `${group.line} / span ${group.span}`,
|
|
8371
|
-
gridRow:
|
|
8613
|
+
gridRow: dataRowOf(group.band, rows)
|
|
8372
8614
|
},
|
|
8373
8615
|
children: group.label
|
|
8374
8616
|
}, `group-${groupIndex}`))
|
|
@@ -11105,8 +11347,8 @@ const SUBPIXEL_TOLERANCE = .5;
|
|
|
11105
11347
|
* depends on `--a8c-charts-dimension-leaderboard-row-gap`, label wrapping, and
|
|
11106
11348
|
* whatever a caller renders as a label, so any restated number would drift.
|
|
11107
11349
|
*
|
|
11108
|
-
* Every row is a direct grid child marked with `data-row-index`;
|
|
11109
|
-
*
|
|
11350
|
+
* Every row is a `listitem` div, a direct grid child marked with `data-row-index`;
|
|
11351
|
+
* interactive rows hold a button inside it.
|
|
11110
11352
|
*
|
|
11111
11353
|
* @param enabled - Whether to measure at all. When false every row fits.
|
|
11112
11354
|
* @param rowCount - Total number of rows rendered.
|
|
@@ -11238,6 +11480,7 @@ var leaderboard_chart_module_default = {
|
|
|
11238
11480
|
"interactiveRow": "a8ccharts-GovfoW-interactiveRow",
|
|
11239
11481
|
"is-overlay": "a8ccharts-GovfoW-is-overlay",
|
|
11240
11482
|
"label": "a8ccharts-GovfoW-label",
|
|
11483
|
+
"layeredRow": "a8ccharts-GovfoW-layeredRow",
|
|
11241
11484
|
"leaderboardChart": "a8ccharts-GovfoW-leaderboardChart",
|
|
11242
11485
|
"leaderboardChart__content": "a8ccharts-GovfoW-leaderboardChart__content",
|
|
11243
11486
|
"leaderboardChart__content--fit": "a8ccharts-GovfoW-leaderboardChart__content--fit",
|
|
@@ -11246,6 +11489,8 @@ var leaderboard_chart_module_default = {
|
|
|
11246
11489
|
"overlap": "a8ccharts-GovfoW-overlap",
|
|
11247
11490
|
"overlayLabel": "a8ccharts-GovfoW-overlayLabel",
|
|
11248
11491
|
"row": "a8ccharts-GovfoW-row",
|
|
11492
|
+
"rowButton": "a8ccharts-GovfoW-rowButton",
|
|
11493
|
+
"rowItem": "a8ccharts-GovfoW-rowItem",
|
|
11249
11494
|
"stretch": "a8ccharts-GovfoW-stretch",
|
|
11250
11495
|
"valueContainer": "a8ccharts-GovfoW-valueContainer"
|
|
11251
11496
|
};
|
|
@@ -11296,6 +11541,16 @@ const defaultDeltaFormatter = (value) => {
|
|
|
11296
11541
|
const getBarWidth = (share) => `calc(${share}% - var(--a8c-charts-dimension-leaderboard-bar-hover-inset, 0px) * ${share} / 100)`;
|
|
11297
11542
|
const hasPreviousValue = (entry) => entry.previousValue != null && entry.previousShare != null;
|
|
11298
11543
|
const hasDeltaValue = (entry) => hasPreviousValue(entry) && entry.delta != null;
|
|
11544
|
+
/**
|
|
11545
|
+
* A layered row's cell that takes pointer events of its own (a value tooltip)
|
|
11546
|
+
* sits above the row button; pass its clicks on so they still drill down.
|
|
11547
|
+
*
|
|
11548
|
+
* @param event - The click on the row.
|
|
11549
|
+
*/
|
|
11550
|
+
function forwardCellClickToRowButton(event) {
|
|
11551
|
+
if (event.target.closest("a, button")) return;
|
|
11552
|
+
event.currentTarget.querySelector(":scope > button")?.click();
|
|
11553
|
+
}
|
|
11299
11554
|
const BarLabel = ({ label }) => /* @__PURE__ */ jsx(Fragment$1, { children: typeof label === "string" ? /* @__PURE__ */ jsx(Text$1, {
|
|
11300
11555
|
className: leaderboard_chart_module_default.label,
|
|
11301
11556
|
children: label
|
|
@@ -11348,9 +11603,10 @@ const BarWithLabel = ({ entry, withComparison, withOverlayLabel, primaryColor, s
|
|
|
11348
11603
|
* @param props.children - Child components for composition API
|
|
11349
11604
|
* @param props.className - Additional CSS class name
|
|
11350
11605
|
* @param props.style - Custom styling for the chart container
|
|
11606
|
+
* @param props.ariaLabel - Accessible name for the list, defaulting to "Leaderboard chart"
|
|
11351
11607
|
* @return JSX element representing the leaderboard chart
|
|
11352
11608
|
*/
|
|
11353
|
-
const LeaderboardChartInternal = ({ data, chartId: providedChartId, width: propWidth, height: propHeight, withComparison = false, withOverlayLabel = false, primaryColor, secondaryColor, valueFormatter = defaultValueFormatter, deltaFormatter = defaultDeltaFormatter, animation, loading = false, fitRows = false, showLegend = false, legend = {}, legendLabels, gap = "md", className, style, children }) => {
|
|
11609
|
+
const LeaderboardChartInternal = ({ data, chartId: providedChartId, width: propWidth, height: propHeight, withComparison = false, withOverlayLabel = false, primaryColor, secondaryColor, valueFormatter = defaultValueFormatter, deltaFormatter = defaultDeltaFormatter, animation, loading = false, fitRows = false, showLegend = false, legend = {}, legendLabels, gap = "md", ariaLabel, className, style, children }) => {
|
|
11354
11610
|
const legendInteractive = legend.interactive ?? false;
|
|
11355
11611
|
const legendPosition = legend.position ?? "bottom";
|
|
11356
11612
|
const chartId = useChartId(providedChartId);
|
|
@@ -11481,6 +11737,8 @@ const LeaderboardChartInternal = ({ data, chartId: providedChartId, width: propW
|
|
|
11481
11737
|
className: leaderboard_chart_module_default.emptyState,
|
|
11482
11738
|
children: getAllHiddenMessage(legendInteractive, "series")
|
|
11483
11739
|
}) : /* @__PURE__ */ jsx(component_default, {
|
|
11740
|
+
role: "list",
|
|
11741
|
+
"aria-label": ariaLabel ?? __("Leaderboard chart", "jetpack-charts"),
|
|
11484
11742
|
templateColumns: "minmax(0, 1fr) auto",
|
|
11485
11743
|
rowGap: ROW_GAP,
|
|
11486
11744
|
columnGap: COLUMN_GAP,
|
|
@@ -11528,20 +11786,49 @@ const LeaderboardChartInternal = ({ data, chartId: providedChartId, width: propW
|
|
|
11528
11786
|
})
|
|
11529
11787
|
]
|
|
11530
11788
|
})] });
|
|
11531
|
-
if (entry.onClick) return /* @__PURE__ */
|
|
11532
|
-
|
|
11789
|
+
if (entry.onClick && entry.hasInteractiveLabel) return /* @__PURE__ */ jsx("div", {
|
|
11790
|
+
role: "listitem",
|
|
11533
11791
|
"data-row-index": rowIndex,
|
|
11534
11792
|
style: rowStyle,
|
|
11535
|
-
className:
|
|
11536
|
-
|
|
11537
|
-
|
|
11538
|
-
|
|
11539
|
-
|
|
11540
|
-
|
|
11541
|
-
|
|
11542
|
-
|
|
11793
|
+
className: leaderboard_chart_module_default.rowItem,
|
|
11794
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
11795
|
+
className: clsx(leaderboard_chart_module_default.row, leaderboard_chart_module_default.interactiveRow, leaderboard_chart_module_default.layeredRow),
|
|
11796
|
+
onClick: forwardCellClickToRowButton,
|
|
11797
|
+
children: [
|
|
11798
|
+
rowCells,
|
|
11799
|
+
/* @__PURE__ */ jsx("button", {
|
|
11800
|
+
type: "button",
|
|
11801
|
+
className: leaderboard_chart_module_default.rowButton,
|
|
11802
|
+
onClick: entry.onClick,
|
|
11803
|
+
"aria-label": entry.ariaLabel
|
|
11804
|
+
}),
|
|
11805
|
+
/* @__PURE__ */ jsx(Icon, {
|
|
11806
|
+
className: leaderboard_chart_module_default.chevron,
|
|
11807
|
+
icon: chevronRight,
|
|
11808
|
+
size: 24
|
|
11809
|
+
})
|
|
11810
|
+
]
|
|
11811
|
+
})
|
|
11812
|
+
}, entry.id);
|
|
11813
|
+
if (entry.onClick) return /* @__PURE__ */ jsx("div", {
|
|
11814
|
+
role: "listitem",
|
|
11815
|
+
"data-row-index": rowIndex,
|
|
11816
|
+
style: rowStyle,
|
|
11817
|
+
className: leaderboard_chart_module_default.rowItem,
|
|
11818
|
+
children: /* @__PURE__ */ jsxs("button", {
|
|
11819
|
+
type: "button",
|
|
11820
|
+
className: clsx(leaderboard_chart_module_default.row, leaderboard_chart_module_default.interactiveRow),
|
|
11821
|
+
onClick: entry.onClick,
|
|
11822
|
+
"aria-label": entry.ariaLabel,
|
|
11823
|
+
children: [rowCells, /* @__PURE__ */ jsx(Icon, {
|
|
11824
|
+
className: leaderboard_chart_module_default.chevron,
|
|
11825
|
+
icon: chevronRight,
|
|
11826
|
+
size: 24
|
|
11827
|
+
})]
|
|
11828
|
+
})
|
|
11543
11829
|
}, entry.id);
|
|
11544
11830
|
return /* @__PURE__ */ jsx("div", {
|
|
11831
|
+
role: "listitem",
|
|
11545
11832
|
"data-row-index": rowIndex,
|
|
11546
11833
|
style: rowStyle,
|
|
11547
11834
|
className: leaderboard_chart_module_default.row,
|
|
@@ -11561,6 +11848,212 @@ LeaderboardChartWithProvider.displayName = "LeaderboardChart";
|
|
|
11561
11848
|
const LeaderboardChart = attachSubComponents(LeaderboardChartWithProvider, { Legend });
|
|
11562
11849
|
const LeaderboardChartResponsive = attachSubComponents(withResponsive(LeaderboardChartWithProvider), { Legend });
|
|
11563
11850
|
//#endregion
|
|
11851
|
+
//#region src/charts/private/pie-keyboard-navigation/order-arcs-for-navigation.ts
|
|
11852
|
+
/**
|
|
11853
|
+
* Orders arcs the way they appear: clockwise from 12 o'clock, which for a semi-circle is left to right.
|
|
11854
|
+
*
|
|
11855
|
+
* @param arcs - Arcs from visx's `pie` factory, in data order.
|
|
11856
|
+
* @return A copy of `arcs` sorted by angular midpoint.
|
|
11857
|
+
*/
|
|
11858
|
+
const orderArcsForNavigation = (arcs) => [...arcs].sort((a, b) => a.startAngle + a.endAngle - (b.startAngle + b.endAngle));
|
|
11859
|
+
//#endregion
|
|
11860
|
+
//#region src/charts/private/pie-keyboard-navigation/pie-selection-announcement.tsx
|
|
11861
|
+
const PieSelectionAnnouncement = ({ data }) => /* @__PURE__ */ jsx(VisuallyHidden, {
|
|
11862
|
+
role: "status",
|
|
11863
|
+
"aria-atomic": "true",
|
|
11864
|
+
children: data && /* @__PURE__ */ jsx(LabelValueContent, { data })
|
|
11865
|
+
});
|
|
11866
|
+
//#endregion
|
|
11867
|
+
//#region src/charts/private/pie-keyboard-navigation/pie-tooltip.tsx
|
|
11868
|
+
const TOOLTIP_BOX_STYLE = { zIndex: 3 };
|
|
11869
|
+
const PieTooltip = ({ top, left, selectedIndex, tooltipRef, children }) => {
|
|
11870
|
+
const standaloneScopeClass = useStandaloneScopeClass();
|
|
11871
|
+
return /* @__PURE__ */ jsx(BoundedTooltip, {
|
|
11872
|
+
top,
|
|
11873
|
+
left,
|
|
11874
|
+
style: TOOLTIP_BOX_STYLE,
|
|
11875
|
+
children: selectedIndex === void 0 ? /* @__PURE__ */ jsx("div", {
|
|
11876
|
+
className: standaloneScopeClass,
|
|
11877
|
+
role: "tooltip",
|
|
11878
|
+
children
|
|
11879
|
+
}) : /* @__PURE__ */ jsx("div", {
|
|
11880
|
+
ref: tooltipRef,
|
|
11881
|
+
tabIndex: -1,
|
|
11882
|
+
role: "tooltip",
|
|
11883
|
+
"aria-atomic": "true",
|
|
11884
|
+
className: standaloneScopeClass,
|
|
11885
|
+
children
|
|
11886
|
+
}, `chart-tooltip-${selectedIndex}`)
|
|
11887
|
+
});
|
|
11888
|
+
};
|
|
11889
|
+
//#endregion
|
|
11890
|
+
//#region src/charts/private/pie-keyboard-navigation/pie-selection-output.tsx
|
|
11891
|
+
/**
|
|
11892
|
+
* Reports the selected segment: a focused tooltip for a keyboard selection, a pointer tooltip on hover, or a screen reader announcement without tooltips.
|
|
11893
|
+
*
|
|
11894
|
+
* @param {PieSelectionOutputProps} props - Component props
|
|
11895
|
+
* @return {JSX.Element} The announcement region and the tooltip, if any
|
|
11896
|
+
*/
|
|
11897
|
+
const PieSelectionOutput = ({ withTooltips, selectedIndex, selectedData, keyboardTooltipAnchor, pointerTooltip, chartRef, svgRef, tooltipRef, renderTooltip }) => {
|
|
11898
|
+
const [svgOffset, setSvgOffset] = useState({
|
|
11899
|
+
top: 0,
|
|
11900
|
+
left: 0
|
|
11901
|
+
});
|
|
11902
|
+
const showKeyboardTooltip = withTooltips && selectedData && keyboardTooltipAnchor;
|
|
11903
|
+
useLayoutEffect(() => {
|
|
11904
|
+
const chartBounds = chartRef.current?.getBoundingClientRect();
|
|
11905
|
+
const svgBounds = svgRef.current?.getBoundingClientRect();
|
|
11906
|
+
if (!showKeyboardTooltip || !chartBounds || !svgBounds) return;
|
|
11907
|
+
const top = svgBounds.top - chartBounds.top;
|
|
11908
|
+
const left = svgBounds.left - chartBounds.left;
|
|
11909
|
+
setSvgOffset((current) => current.top === top && current.left === left ? current : {
|
|
11910
|
+
top,
|
|
11911
|
+
left
|
|
11912
|
+
});
|
|
11913
|
+
});
|
|
11914
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
11915
|
+
/* @__PURE__ */ jsx(PieSelectionAnnouncement, { data: withTooltips ? void 0 : selectedData }),
|
|
11916
|
+
showKeyboardTooltip && /* @__PURE__ */ jsx(PieTooltip, {
|
|
11917
|
+
top: svgOffset.top + keyboardTooltipAnchor.top,
|
|
11918
|
+
left: svgOffset.left + keyboardTooltipAnchor.left,
|
|
11919
|
+
selectedIndex,
|
|
11920
|
+
tooltipRef,
|
|
11921
|
+
children: renderTooltip({ tooltipData: selectedData })
|
|
11922
|
+
}),
|
|
11923
|
+
withTooltips && !selectedData && pointerTooltip?.data && /* @__PURE__ */ jsx(PieTooltip, {
|
|
11924
|
+
top: pointerTooltip.top,
|
|
11925
|
+
left: pointerTooltip.left,
|
|
11926
|
+
children: renderTooltip({ tooltipData: pointerTooltip.data })
|
|
11927
|
+
})
|
|
11928
|
+
] });
|
|
11929
|
+
};
|
|
11930
|
+
//#endregion
|
|
11931
|
+
//#region src/charts/private/pie-keyboard-navigation/pie-keyboard-navigation.module.scss
|
|
11932
|
+
var pie_keyboard_navigation_module_default = {
|
|
11933
|
+
"selected-ring__contrast": "a8ccharts-V2HDKq-selected-ring__contrast",
|
|
11934
|
+
"selected-ring__focus": "a8ccharts-V2HDKq-selected-ring__focus"
|
|
11935
|
+
};
|
|
11936
|
+
//#endregion
|
|
11937
|
+
//#region src/charts/private/pie-keyboard-navigation/selected-segment-ring.tsx
|
|
11938
|
+
/**
|
|
11939
|
+
* Encodes `value` for an SVG id, losslessly so distinct chart ids never share a clip path.
|
|
11940
|
+
*
|
|
11941
|
+
* @param value - Any string.
|
|
11942
|
+
* @return `value` with each character outside `[A-Za-z0-9-]` written as `_<hex code point>_`.
|
|
11943
|
+
*/
|
|
11944
|
+
const toSvgId = (value) => Array.from(value, (character) => /[A-Za-z0-9-]/.test(character) ? character : `_${character.codePointAt(0)?.toString(16)}_`).join("");
|
|
11945
|
+
/**
|
|
11946
|
+
* Marks the selected segment with a two-tone ring drawn inside its edge, so the SVG edge cannot cut it off.
|
|
11947
|
+
*
|
|
11948
|
+
* @param {SelectedSegmentRingProps} props - Component props
|
|
11949
|
+
* @return {JSX.Element} The ring
|
|
11950
|
+
*/
|
|
11951
|
+
const SelectedSegmentRing = ({ chartId, d }) => {
|
|
11952
|
+
const clipId = `pie-selected-ring-clip-${toSvgId(chartId)}`;
|
|
11953
|
+
const clipPath = `url(#${clipId})`;
|
|
11954
|
+
return /* @__PURE__ */ jsxs("g", {
|
|
11955
|
+
pointerEvents: "none",
|
|
11956
|
+
"aria-hidden": "true",
|
|
11957
|
+
children: [
|
|
11958
|
+
/* @__PURE__ */ jsx("clipPath", {
|
|
11959
|
+
id: clipId,
|
|
11960
|
+
children: /* @__PURE__ */ jsx("path", { d })
|
|
11961
|
+
}),
|
|
11962
|
+
/* @__PURE__ */ jsx("path", {
|
|
11963
|
+
d,
|
|
11964
|
+
clipPath,
|
|
11965
|
+
className: pie_keyboard_navigation_module_default["selected-ring__contrast"]
|
|
11966
|
+
}),
|
|
11967
|
+
/* @__PURE__ */ jsx("path", {
|
|
11968
|
+
d,
|
|
11969
|
+
clipPath,
|
|
11970
|
+
className: pie_keyboard_navigation_module_default["selected-ring__focus"]
|
|
11971
|
+
})
|
|
11972
|
+
]
|
|
11973
|
+
});
|
|
11974
|
+
};
|
|
11975
|
+
//#endregion
|
|
11976
|
+
//#region src/charts/private/pie-keyboard-navigation/use-pie-keyboard-navigation.ts
|
|
11977
|
+
const usePieKeyboardNavigation = ({ navigationArcs, withTooltips, tooltipOffsetX, tooltipOffsetY }) => {
|
|
11978
|
+
const chartRef = useRef(null);
|
|
11979
|
+
const svgRef = useRef(null);
|
|
11980
|
+
const [selectedIndex, setSelectedIndex] = useState(void 0);
|
|
11981
|
+
const [isNavigating, setIsNavigating] = useState(false);
|
|
11982
|
+
const { tooltipOpen, tooltipLeft, tooltipTop, tooltipData, hideTooltip, showTooltip } = useTooltip();
|
|
11983
|
+
const { tooltipRef: focusTooltip, onChartFocus, onChartBlur, onChartKeyDown, onChartPointerMove } = useKeyboardNavigation({
|
|
11984
|
+
selectedIndex,
|
|
11985
|
+
setSelectedIndex,
|
|
11986
|
+
isNavigating,
|
|
11987
|
+
setIsNavigating,
|
|
11988
|
+
chartRef,
|
|
11989
|
+
totalPoints: navigationArcs.length,
|
|
11990
|
+
visibleSeriesKey: JSON.stringify(navigationArcs.map((arcDatum) => arcDatum.data.label))
|
|
11991
|
+
});
|
|
11992
|
+
const selectedArc = selectedIndex === void 0 ? void 0 : navigationArcs[selectedIndex];
|
|
11993
|
+
const keyboardTooltip = useRef(null);
|
|
11994
|
+
const tooltipLostFocus = useRef(false);
|
|
11995
|
+
const tooltipRef = useCallback((element) => {
|
|
11996
|
+
if (element) {
|
|
11997
|
+
keyboardTooltip.current = element;
|
|
11998
|
+
focusTooltip(element);
|
|
11999
|
+
} else if (keyboardTooltip.current?.ownerDocument.activeElement === keyboardTooltip.current) tooltipLostFocus.current = true;
|
|
12000
|
+
}, [focusTooltip]);
|
|
12001
|
+
useLayoutEffect(() => {
|
|
12002
|
+
if (!tooltipLostFocus.current) return;
|
|
12003
|
+
tooltipLostFocus.current = false;
|
|
12004
|
+
const { activeElement, body } = chartRef.current?.ownerDocument ?? document;
|
|
12005
|
+
if (activeElement === null || activeElement === body) chartRef.current?.focus();
|
|
12006
|
+
});
|
|
12007
|
+
const getSegmentHandlers = (data, navigationIndex) => ({
|
|
12008
|
+
onMouseMove: (event) => {
|
|
12009
|
+
onChartPointerMove(navigationIndex);
|
|
12010
|
+
if (!withTooltips) return;
|
|
12011
|
+
const bounds = chartRef.current?.getBoundingClientRect();
|
|
12012
|
+
if (!bounds) return;
|
|
12013
|
+
showTooltip({
|
|
12014
|
+
tooltipData: data,
|
|
12015
|
+
tooltipLeft: event.clientX - bounds.left + tooltipOffsetX,
|
|
12016
|
+
tooltipTop: event.clientY - bounds.top + tooltipOffsetY
|
|
12017
|
+
});
|
|
12018
|
+
},
|
|
12019
|
+
onMouseLeave: withTooltips ? hideTooltip : void 0
|
|
12020
|
+
});
|
|
12021
|
+
return {
|
|
12022
|
+
chartRef,
|
|
12023
|
+
svgRef,
|
|
12024
|
+
selectedArc,
|
|
12025
|
+
getSegmentHandlers,
|
|
12026
|
+
getKeyboardTooltipAnchor: useCallback((originX, originY, [x, y]) => withTooltips ? {
|
|
12027
|
+
left: originX + x + tooltipOffsetX,
|
|
12028
|
+
top: originY + y + tooltipOffsetY
|
|
12029
|
+
} : void 0, [
|
|
12030
|
+
withTooltips,
|
|
12031
|
+
tooltipOffsetX,
|
|
12032
|
+
tooltipOffsetY
|
|
12033
|
+
]),
|
|
12034
|
+
selectionOutputProps: {
|
|
12035
|
+
withTooltips,
|
|
12036
|
+
selectedIndex,
|
|
12037
|
+
selectedData: selectedArc?.data,
|
|
12038
|
+
chartRef,
|
|
12039
|
+
svgRef,
|
|
12040
|
+
tooltipRef,
|
|
12041
|
+
pointerTooltip: tooltipOpen ? {
|
|
12042
|
+
data: tooltipData,
|
|
12043
|
+
left: tooltipLeft || 0,
|
|
12044
|
+
top: tooltipTop || 0
|
|
12045
|
+
} : void 0
|
|
12046
|
+
},
|
|
12047
|
+
chartProps: {
|
|
12048
|
+
role: "application",
|
|
12049
|
+
tabIndex: 0,
|
|
12050
|
+
onKeyDown: onChartKeyDown,
|
|
12051
|
+
onFocus: onChartFocus,
|
|
12052
|
+
onBlur: onChartBlur
|
|
12053
|
+
}
|
|
12054
|
+
};
|
|
12055
|
+
};
|
|
12056
|
+
//#endregion
|
|
11564
12057
|
//#region src/charts/private/radial-wipe-animation/radial-wipe-animation.tsx
|
|
11565
12058
|
/**
|
|
11566
12059
|
* Renders a SVG mask that creates a radial wipe animation effect.
|
|
@@ -11601,6 +12094,7 @@ function RadialWipeAnimation({ id, radius, innerRadius = 0, durationMs = 1e3, wi
|
|
|
11601
12094
|
//#endregion
|
|
11602
12095
|
//#region src/charts/pie-chart/pie-chart.module.scss
|
|
11603
12096
|
var pie_chart_module_default = {
|
|
12097
|
+
"pie-chart": "a8ccharts-gnszbG-pie-chart",
|
|
11604
12098
|
"pie-chart__label-plate": "a8ccharts-gnszbG-pie-chart__label-plate",
|
|
11605
12099
|
"pie-chart__label-text": "a8ccharts-gnszbG-pie-chart__label-text",
|
|
11606
12100
|
"pie-chart__label-text--black": "a8ccharts-gnszbG-pie-chart__label-text--black",
|
|
@@ -11656,20 +12150,13 @@ const LABEL_TEXT_MODIFIER = {
|
|
|
11656
12150
|
* @param {PieChartProps} props - Component props
|
|
11657
12151
|
* @return {JSX.Element} The rendered chart component
|
|
11658
12152
|
*/
|
|
11659
|
-
const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false, className, showLegend = false, legend = {}, width: propWidth, height: propHeight, size, animation, thickness = 1, padding = 0, gapScale = 0, cornerScale = 0, showLabels = true, legendValueDisplay = "percentage", children = null, tooltipOffsetX = 0, tooltipOffsetY = -15, renderTooltip = renderDefaultPieTooltip, gap = "md" }) => {
|
|
12153
|
+
const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false, className, showLegend = false, legend = {}, width: propWidth, height: propHeight, size, animation, thickness = 1, padding = 0, gapScale = 0, cornerScale = 0, showLabels = true, legendValueDisplay = "percentage", children = null, tooltipOffsetX = 0, tooltipOffsetY = -15, renderTooltip = renderDefaultPieTooltip, ariaLabel, gap = "md" }) => {
|
|
11660
12154
|
const legendInteractive = legend.interactive ?? false;
|
|
11661
12155
|
const legendPosition = legend.position ?? "bottom";
|
|
11662
12156
|
const providerTheme = useGlobalChartsTheme();
|
|
11663
12157
|
const chartId = useChartId(providedChartId);
|
|
11664
|
-
const { tooltipOpen, tooltipLeft, tooltipTop, tooltipData, hideTooltip, showTooltip } = useTooltip();
|
|
11665
|
-
const standaloneScopeClass = useStandaloneScopeClass();
|
|
11666
|
-
const containerRef = useRef(null);
|
|
11667
12158
|
const rootRef = useRef(null);
|
|
11668
12159
|
const [labelRoles, setLabelRoles] = useState(null);
|
|
11669
|
-
const onMouseLeave = useCallback(() => {
|
|
11670
|
-
if (!withTooltips) return;
|
|
11671
|
-
hideTooltip();
|
|
11672
|
-
}, [withTooltips, hideTooltip]);
|
|
11673
12160
|
const { getElementStyles, isSeriesVisible, isColorPaletteResolved } = useGlobalChartsContext();
|
|
11674
12161
|
const { isValid, message } = validateData$1(data);
|
|
11675
12162
|
useLayoutEffect(() => {
|
|
@@ -11713,13 +12200,7 @@ const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false
|
|
|
11713
12200
|
metadata: chartMetadata
|
|
11714
12201
|
});
|
|
11715
12202
|
const prefersReducedMotion = usePrefersReducedMotion();
|
|
11716
|
-
|
|
11717
|
-
className: clsx("pie-chart", pie_chart_module_default["pie-chart"], className),
|
|
11718
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
11719
|
-
className: pie_chart_module_default["error-message"],
|
|
11720
|
-
children: message
|
|
11721
|
-
})
|
|
11722
|
-
});
|
|
12203
|
+
const wipeMask = animation && !prefersReducedMotion ? `url(#radial-wipe-${chartId})` : null;
|
|
11723
12204
|
const padAngle = gapScale * (2 * Math.PI / data.length);
|
|
11724
12205
|
const dataWithIndex = visibleData.map((d) => {
|
|
11725
12206
|
const originalIndex = data.findIndex((item) => item.label === d.label);
|
|
@@ -11737,6 +12218,24 @@ const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false
|
|
|
11737
12218
|
}).color;
|
|
11738
12219
|
}
|
|
11739
12220
|
};
|
|
12221
|
+
const arcs = pie({
|
|
12222
|
+
value: accessors.value,
|
|
12223
|
+
padAngle
|
|
12224
|
+
})(dataWithIndex);
|
|
12225
|
+
const navigationArcs = orderArcsForNavigation(arcs);
|
|
12226
|
+
const { chartRef, svgRef, selectedArc, getSegmentHandlers, getKeyboardTooltipAnchor, selectionOutputProps, chartProps } = usePieKeyboardNavigation({
|
|
12227
|
+
navigationArcs,
|
|
12228
|
+
withTooltips,
|
|
12229
|
+
tooltipOffsetX,
|
|
12230
|
+
tooltipOffsetY
|
|
12231
|
+
});
|
|
12232
|
+
if (!isValid) return /* @__PURE__ */ jsx("div", {
|
|
12233
|
+
className: clsx("pie-chart", pie_chart_module_default["pie-chart"], className),
|
|
12234
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
12235
|
+
className: pie_chart_module_default["error-message"],
|
|
12236
|
+
children: message
|
|
12237
|
+
})
|
|
12238
|
+
});
|
|
11740
12239
|
const legendElement = showLegend && /* @__PURE__ */ jsx(Legend, {
|
|
11741
12240
|
orientation: legend.orientation ?? "horizontal",
|
|
11742
12241
|
position: legendPosition,
|
|
@@ -11775,102 +12274,96 @@ const PieChartInternal = ({ data, chartId: providedChartId, withTooltips = false
|
|
|
11775
12274
|
const innerRadius = thickness === 0 ? 0 : outerRadius * (1 - thickness);
|
|
11776
12275
|
const maxCornerRadius = (outerRadius - innerRadius) / 2;
|
|
11777
12276
|
const cornerRadius = cornerScale ? Math.min(cornerScale * outerRadius, maxCornerRadius) : 0;
|
|
12277
|
+
const path = arc({
|
|
12278
|
+
innerRadius,
|
|
12279
|
+
outerRadius,
|
|
12280
|
+
cornerRadius
|
|
12281
|
+
});
|
|
12282
|
+
const svgLabelSmall = providerTheme.svgLabelSmall;
|
|
12283
|
+
const fontSize = resolveFontSize(svgLabelSmall?.fontSize) ?? 12;
|
|
12284
|
+
const renderLabel = (arcDatum, index) => {
|
|
12285
|
+
if (arcDatum.endAngle - arcDatum.startAngle < .25) return null;
|
|
12286
|
+
const [centroidX, centroidY] = path.centroid(arcDatum);
|
|
12287
|
+
const backgroundWidth = getStringWidth$1(arcDatum.data.label, {
|
|
12288
|
+
fontSize,
|
|
12289
|
+
fontFamily: svgLabelSmall?.fontFamily,
|
|
12290
|
+
fontWeight: svgLabelSmall?.fontWeight
|
|
12291
|
+
}) + 12;
|
|
12292
|
+
const backgroundHeight = fontSize + 12;
|
|
12293
|
+
return /* @__PURE__ */ jsxs("g", { children: [/* @__PURE__ */ jsx("rect", {
|
|
12294
|
+
className: pie_chart_module_default["pie-chart__label-plate"],
|
|
12295
|
+
x: centroidX - backgroundWidth / 2,
|
|
12296
|
+
y: centroidY - backgroundHeight / 2,
|
|
12297
|
+
width: backgroundWidth,
|
|
12298
|
+
height: backgroundHeight,
|
|
12299
|
+
rx: 4,
|
|
12300
|
+
ry: 4,
|
|
12301
|
+
pointerEvents: "none"
|
|
12302
|
+
}), /* @__PURE__ */ jsx("text", {
|
|
12303
|
+
className: clsx(pie_chart_module_default["pie-chart__label-text"], LABEL_TEXT_MODIFIER[pickLabelTextColor(accessors.fill(arcDatum.data), labelRoles, "label-inverse")]),
|
|
12304
|
+
x: centroidX,
|
|
12305
|
+
y: centroidY,
|
|
12306
|
+
dy: ".33em",
|
|
12307
|
+
fontSize,
|
|
12308
|
+
textAnchor: "middle",
|
|
12309
|
+
pointerEvents: "none",
|
|
12310
|
+
children: arcDatum.data.label
|
|
12311
|
+
})] }, `label-${index}`);
|
|
12312
|
+
};
|
|
11778
12313
|
return /* @__PURE__ */ jsxs(Center, {
|
|
11779
|
-
ref:
|
|
12314
|
+
ref: chartRef,
|
|
11780
12315
|
className: pie_chart_module_default["pie-chart__plot"],
|
|
12316
|
+
...chartProps,
|
|
12317
|
+
"aria-label": ariaLabel ?? __("Pie chart", "jetpack-charts"),
|
|
11781
12318
|
children: [/* @__PURE__ */ jsxs("svg", {
|
|
12319
|
+
ref: svgRef,
|
|
11782
12320
|
viewBox: `0 0 ${width} ${height}`,
|
|
11783
12321
|
preserveAspectRatio: "xMidYMid meet",
|
|
11784
12322
|
width,
|
|
11785
12323
|
height,
|
|
11786
|
-
children: [
|
|
11787
|
-
|
|
11788
|
-
|
|
11789
|
-
|
|
11790
|
-
|
|
11791
|
-
|
|
11792
|
-
|
|
11793
|
-
|
|
11794
|
-
|
|
11795
|
-
|
|
11796
|
-
|
|
11797
|
-
|
|
11798
|
-
|
|
11799
|
-
|
|
11800
|
-
|
|
11801
|
-
|
|
11802
|
-
|
|
11803
|
-
|
|
11804
|
-
|
|
11805
|
-
|
|
11806
|
-
|
|
11807
|
-
|
|
11808
|
-
|
|
11809
|
-
|
|
11810
|
-
|
|
11811
|
-
|
|
11812
|
-
|
|
11813
|
-
|
|
11814
|
-
|
|
11815
|
-
|
|
11816
|
-
|
|
11817
|
-
|
|
11818
|
-
|
|
11819
|
-
|
|
11820
|
-
|
|
11821
|
-
|
|
11822
|
-
|
|
11823
|
-
|
|
11824
|
-
|
|
11825
|
-
|
|
11826
|
-
|
|
11827
|
-
|
|
11828
|
-
|
|
11829
|
-
groupProps.onMouseMove = handleMouseMove;
|
|
11830
|
-
groupProps.onMouseLeave = onMouseLeave;
|
|
11831
|
-
}
|
|
11832
|
-
const svgLabelSmall = providerTheme.svgLabelSmall;
|
|
11833
|
-
const fontSize = resolveFontSize(svgLabelSmall?.fontSize) ?? 12;
|
|
11834
|
-
const backgroundWidth = getStringWidth$1(arc.data.label, {
|
|
11835
|
-
fontSize,
|
|
11836
|
-
fontFamily: svgLabelSmall?.fontFamily,
|
|
11837
|
-
fontWeight: svgLabelSmall?.fontWeight
|
|
11838
|
-
}) + 12;
|
|
11839
|
-
const backgroundHeight = fontSize + 12;
|
|
11840
|
-
return /* @__PURE__ */ jsxs("g", {
|
|
11841
|
-
...groupProps,
|
|
11842
|
-
children: [/* @__PURE__ */ jsx("path", { ...pathProps }), showLabels && hasSpaceForLabel && /* @__PURE__ */ jsxs("g", { children: [/* @__PURE__ */ jsx("rect", {
|
|
11843
|
-
className: pie_chart_module_default["pie-chart__label-plate"],
|
|
11844
|
-
x: centroidX - backgroundWidth / 2,
|
|
11845
|
-
y: centroidY - backgroundHeight / 2,
|
|
11846
|
-
width: backgroundWidth,
|
|
11847
|
-
height: backgroundHeight,
|
|
11848
|
-
rx: 4,
|
|
11849
|
-
ry: 4,
|
|
11850
|
-
pointerEvents: "none"
|
|
11851
|
-
}), /* @__PURE__ */ jsx("text", {
|
|
11852
|
-
className: clsx(pie_chart_module_default["pie-chart__label-text"], LABEL_TEXT_MODIFIER[pickLabelTextColor(fill, labelRoles, "label-inverse")]),
|
|
11853
|
-
x: centroidX,
|
|
11854
|
-
y: centroidY,
|
|
11855
|
-
dy: ".33em",
|
|
11856
|
-
fontSize,
|
|
11857
|
-
textAnchor: "middle",
|
|
11858
|
-
pointerEvents: "none",
|
|
11859
|
-
children: arc.data.label
|
|
11860
|
-
})] })]
|
|
11861
|
-
}, `arc-${index}`);
|
|
11862
|
-
});
|
|
11863
|
-
}
|
|
11864
|
-
}), !allSegmentsHidden && svgChildren]
|
|
11865
|
-
})]
|
|
11866
|
-
}), withTooltips && tooltipOpen && tooltipData && /* @__PURE__ */ jsx(BoundedTooltip, {
|
|
11867
|
-
top: tooltipTop || 0,
|
|
11868
|
-
left: tooltipLeft || 0,
|
|
11869
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
11870
|
-
className: standaloneScopeClass,
|
|
11871
|
-
role: "tooltip",
|
|
11872
|
-
children: renderTooltip({ tooltipData })
|
|
11873
|
-
})
|
|
12324
|
+
children: [
|
|
12325
|
+
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(RadialWipeAnimation, {
|
|
12326
|
+
id: `radial-wipe-${chartId}`,
|
|
12327
|
+
radius: outerRadius,
|
|
12328
|
+
innerRadius
|
|
12329
|
+
}) }),
|
|
12330
|
+
/* @__PURE__ */ jsx(Group, {
|
|
12331
|
+
top: centerY,
|
|
12332
|
+
left: centerX,
|
|
12333
|
+
mask: wipeMask,
|
|
12334
|
+
children: allSegmentsHidden ? /* @__PURE__ */ jsx(SvgEmptyState, {
|
|
12335
|
+
x: 0,
|
|
12336
|
+
y: 0,
|
|
12337
|
+
width,
|
|
12338
|
+
height,
|
|
12339
|
+
children: getAllHiddenMessage(legendInteractive, "segments")
|
|
12340
|
+
}) : arcs.map((arcDatum, index) => /* @__PURE__ */ jsx("g", {
|
|
12341
|
+
...getSegmentHandlers(arcDatum.data, navigationArcs.indexOf(arcDatum)),
|
|
12342
|
+
children: /* @__PURE__ */ jsx("path", {
|
|
12343
|
+
d: path(arcDatum) || "",
|
|
12344
|
+
fill: accessors.fill(arcDatum.data)
|
|
12345
|
+
})
|
|
12346
|
+
}, `arc-${index}`))
|
|
12347
|
+
}),
|
|
12348
|
+
selectedArc && /* @__PURE__ */ jsx(Group, {
|
|
12349
|
+
top: centerY,
|
|
12350
|
+
left: centerX,
|
|
12351
|
+
children: /* @__PURE__ */ jsx(SelectedSegmentRing, {
|
|
12352
|
+
chartId,
|
|
12353
|
+
d: path(selectedArc) || ""
|
|
12354
|
+
})
|
|
12355
|
+
}),
|
|
12356
|
+
!allSegmentsHidden && /* @__PURE__ */ jsxs(Group, {
|
|
12357
|
+
top: centerY,
|
|
12358
|
+
left: centerX,
|
|
12359
|
+
mask: wipeMask,
|
|
12360
|
+
children: [showLabels && arcs.map(renderLabel), svgChildren]
|
|
12361
|
+
})
|
|
12362
|
+
]
|
|
12363
|
+
}), /* @__PURE__ */ jsx(PieSelectionOutput, {
|
|
12364
|
+
...selectionOutputProps,
|
|
12365
|
+
keyboardTooltipAnchor: selectedArc && getKeyboardTooltipAnchor(centerX, centerY, path.centroid(selectedArc)),
|
|
12366
|
+
renderTooltip
|
|
11874
12367
|
})]
|
|
11875
12368
|
});
|
|
11876
12369
|
}
|
|
@@ -11938,32 +12431,10 @@ const validateData = (data) => {
|
|
|
11938
12431
|
message: ""
|
|
11939
12432
|
};
|
|
11940
12433
|
};
|
|
11941
|
-
const PieSemiCircleChartInternal = ({ data, chartId: providedChartId, width: propWidth, height: propHeight, thickness = .4, clockwise = true, withTooltips = false, showLegend = false, legend = {}, legendValueDisplay = "percentage", label, animation, note, className, children, tooltipOffsetX = 0, tooltipOffsetY = -15, renderTooltip = renderDefaultPieSemiCircleTooltip, gap = "md" }) => {
|
|
12434
|
+
const PieSemiCircleChartInternal = ({ data, chartId: providedChartId, width: propWidth, height: propHeight, thickness = .4, clockwise = true, withTooltips = false, showLegend = false, legend = {}, legendValueDisplay = "percentage", label, animation, note, className, children, tooltipOffsetX = 0, tooltipOffsetY = -15, renderTooltip = renderDefaultPieSemiCircleTooltip, ariaLabel, gap = "md" }) => {
|
|
11942
12435
|
const legendInteractive = legend.interactive ?? false;
|
|
11943
12436
|
const legendPosition = legend.position ?? "bottom";
|
|
11944
12437
|
const chartId = useChartId(providedChartId);
|
|
11945
|
-
const { tooltipOpen, tooltipLeft, tooltipTop, tooltipData, hideTooltip, showTooltip } = useTooltip();
|
|
11946
|
-
const standaloneScopeClass = useStandaloneScopeClass();
|
|
11947
|
-
const containerRef = useRef(null);
|
|
11948
|
-
const handleMouseMove = useCallback((event, arc) => {
|
|
11949
|
-
const bounds = containerRef.current?.getBoundingClientRect();
|
|
11950
|
-
if (!bounds) return;
|
|
11951
|
-
showTooltip({
|
|
11952
|
-
tooltipData: arc.data,
|
|
11953
|
-
tooltipLeft: event.clientX - bounds.left + tooltipOffsetX,
|
|
11954
|
-
tooltipTop: event.clientY - bounds.top + tooltipOffsetY
|
|
11955
|
-
});
|
|
11956
|
-
}, [
|
|
11957
|
-
showTooltip,
|
|
11958
|
-
tooltipOffsetX,
|
|
11959
|
-
tooltipOffsetY
|
|
11960
|
-
]);
|
|
11961
|
-
const handleMouseLeave = useCallback(() => {
|
|
11962
|
-
hideTooltip();
|
|
11963
|
-
}, [hideTooltip]);
|
|
11964
|
-
const handleArcMouseMove = useCallback((arc) => (event) => {
|
|
11965
|
-
handleMouseMove(event, arc);
|
|
11966
|
-
}, [handleMouseMove]);
|
|
11967
12438
|
const { isValid, message } = validateData(data);
|
|
11968
12439
|
const { getElementStyles, isSeriesVisible } = useGlobalChartsContext();
|
|
11969
12440
|
const dataWithPercentages = useDataWithPercentages(data);
|
|
@@ -11997,7 +12468,31 @@ const PieSemiCircleChartInternal = ({ data, chartId: providedChartId, width: pro
|
|
|
11997
12468
|
metadata: chartMetadata
|
|
11998
12469
|
});
|
|
11999
12470
|
const prefersReducedMotion = usePrefersReducedMotion();
|
|
12471
|
+
const wipeMask = animation && !prefersReducedMotion ? `url(#radial-wipe-${chartId})` : null;
|
|
12000
12472
|
const effectiveWidth = propWidth || DEFAULT_WIDTH$1;
|
|
12473
|
+
const dataWithIndex = visibleData.map((d) => {
|
|
12474
|
+
const originalIndex = data.findIndex((item) => item.label === d.label);
|
|
12475
|
+
return {
|
|
12476
|
+
...d,
|
|
12477
|
+
index: originalIndex >= 0 ? originalIndex : 0
|
|
12478
|
+
};
|
|
12479
|
+
});
|
|
12480
|
+
const startAngle = clockwise ? -Math.PI / 2 : Math.PI / 2;
|
|
12481
|
+
const endAngle = clockwise ? Math.PI / 2 : -Math.PI / 2;
|
|
12482
|
+
const arcs = pie({
|
|
12483
|
+
value: accessors.value,
|
|
12484
|
+
sort: accessors.sort,
|
|
12485
|
+
padAngle: PAD_ANGLE,
|
|
12486
|
+
startAngle,
|
|
12487
|
+
endAngle
|
|
12488
|
+
})(dataWithIndex);
|
|
12489
|
+
const navigationArcs = orderArcsForNavigation(arcs);
|
|
12490
|
+
const { chartRef, svgRef, selectedArc, getSegmentHandlers, getKeyboardTooltipAnchor, selectionOutputProps, chartProps } = usePieKeyboardNavigation({
|
|
12491
|
+
navigationArcs,
|
|
12492
|
+
withTooltips,
|
|
12493
|
+
tooltipOffsetX,
|
|
12494
|
+
tooltipOffsetY
|
|
12495
|
+
});
|
|
12001
12496
|
if (!isValid) {
|
|
12002
12497
|
const errorWidth = propHeight ? Math.min(propWidth || propHeight * 2, propHeight * 2) : effectiveWidth;
|
|
12003
12498
|
const errorHeight = errorWidth / 2;
|
|
@@ -12016,15 +12511,6 @@ const PieSemiCircleChartInternal = ({ data, chartId: providedChartId, width: pro
|
|
|
12016
12511
|
})
|
|
12017
12512
|
});
|
|
12018
12513
|
}
|
|
12019
|
-
const dataWithIndex = visibleData.map((d) => {
|
|
12020
|
-
const originalIndex = data.findIndex((item) => item.label === d.label);
|
|
12021
|
-
return {
|
|
12022
|
-
...d,
|
|
12023
|
-
index: originalIndex >= 0 ? originalIndex : 0
|
|
12024
|
-
};
|
|
12025
|
-
});
|
|
12026
|
-
const startAngle = clockwise ? -Math.PI / 2 : Math.PI / 2;
|
|
12027
|
-
const endAngle = clockwise ? Math.PI / 2 : -Math.PI / 2;
|
|
12028
12514
|
const legendElement = showLegend && /* @__PURE__ */ jsx(Legend, {
|
|
12029
12515
|
orientation: legend.orientation ?? "horizontal",
|
|
12030
12516
|
position: legendPosition,
|
|
@@ -12057,52 +12543,60 @@ const PieSemiCircleChartInternal = ({ data, chartId: providedChartId, width: pro
|
|
|
12057
12543
|
const height = width / 2;
|
|
12058
12544
|
const radius = height;
|
|
12059
12545
|
const innerRadius = radius * (1 - thickness);
|
|
12546
|
+
const path = arc({
|
|
12547
|
+
innerRadius,
|
|
12548
|
+
outerRadius: radius,
|
|
12549
|
+
cornerRadius: 3
|
|
12550
|
+
});
|
|
12060
12551
|
return /* @__PURE__ */ jsxs(Center, {
|
|
12061
|
-
ref:
|
|
12552
|
+
ref: chartRef,
|
|
12062
12553
|
className: pie_semi_circle_chart_module_default["pie-semi-circle-chart__plot"],
|
|
12554
|
+
...chartProps,
|
|
12555
|
+
"aria-label": ariaLabel ?? __("Semi-circle chart", "jetpack-charts"),
|
|
12063
12556
|
children: [/* @__PURE__ */ jsxs("svg", {
|
|
12557
|
+
ref: svgRef,
|
|
12064
12558
|
width,
|
|
12065
12559
|
height,
|
|
12066
12560
|
viewBox: `0 0 ${width} ${height}`,
|
|
12067
|
-
children: [
|
|
12068
|
-
|
|
12069
|
-
|
|
12070
|
-
|
|
12071
|
-
|
|
12072
|
-
|
|
12073
|
-
|
|
12074
|
-
|
|
12075
|
-
|
|
12076
|
-
|
|
12077
|
-
|
|
12078
|
-
|
|
12079
|
-
|
|
12080
|
-
|
|
12081
|
-
|
|
12082
|
-
|
|
12083
|
-
|
|
12084
|
-
|
|
12085
|
-
|
|
12086
|
-
|
|
12087
|
-
|
|
12088
|
-
|
|
12089
|
-
|
|
12090
|
-
|
|
12091
|
-
|
|
12092
|
-
|
|
12093
|
-
|
|
12094
|
-
|
|
12095
|
-
|
|
12096
|
-
|
|
12097
|
-
|
|
12098
|
-
|
|
12099
|
-
|
|
12100
|
-
|
|
12101
|
-
|
|
12102
|
-
|
|
12103
|
-
|
|
12104
|
-
|
|
12105
|
-
/* @__PURE__ */ jsxs(Group, { children: [/* @__PURE__ */ jsx(Text, {
|
|
12561
|
+
children: [
|
|
12562
|
+
/* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx(RadialWipeAnimation, {
|
|
12563
|
+
id: `radial-wipe-${chartId}`,
|
|
12564
|
+
radius,
|
|
12565
|
+
innerRadius,
|
|
12566
|
+
startAngle: "-180deg",
|
|
12567
|
+
wipePercentage: 50
|
|
12568
|
+
}) }),
|
|
12569
|
+
/* @__PURE__ */ jsx(Group, {
|
|
12570
|
+
top: height,
|
|
12571
|
+
left: width / 2,
|
|
12572
|
+
mask: wipeMask,
|
|
12573
|
+
children: allSegmentsHidden ? /* @__PURE__ */ jsx(SvgEmptyState, {
|
|
12574
|
+
x: 0,
|
|
12575
|
+
y: -radius / 2,
|
|
12576
|
+
width,
|
|
12577
|
+
height,
|
|
12578
|
+
children: getAllHiddenMessage(legendInteractive, "segments")
|
|
12579
|
+
}) : arcs.map((arcDatum) => /* @__PURE__ */ jsx("g", {
|
|
12580
|
+
...getSegmentHandlers(arcDatum.data, navigationArcs.indexOf(arcDatum)),
|
|
12581
|
+
children: /* @__PURE__ */ jsx("path", {
|
|
12582
|
+
d: path(arcDatum) || "",
|
|
12583
|
+
fill: accessors.fill(arcDatum.data)
|
|
12584
|
+
})
|
|
12585
|
+
}, arcDatum.data.label))
|
|
12586
|
+
}),
|
|
12587
|
+
selectedArc && /* @__PURE__ */ jsx(Group, {
|
|
12588
|
+
top: height,
|
|
12589
|
+
left: width / 2,
|
|
12590
|
+
children: /* @__PURE__ */ jsx(SelectedSegmentRing, {
|
|
12591
|
+
chartId,
|
|
12592
|
+
d: path(selectedArc) || ""
|
|
12593
|
+
})
|
|
12594
|
+
}),
|
|
12595
|
+
!allSegmentsHidden && /* @__PURE__ */ jsxs(Group, {
|
|
12596
|
+
top: height,
|
|
12597
|
+
left: width / 2,
|
|
12598
|
+
mask: wipeMask,
|
|
12599
|
+
children: [/* @__PURE__ */ jsxs(Group, { children: [/* @__PURE__ */ jsx(Text, {
|
|
12106
12600
|
textAnchor: "middle",
|
|
12107
12601
|
verticalAnchor: "start",
|
|
12108
12602
|
y: -40,
|
|
@@ -12114,18 +12608,13 @@ const PieSemiCircleChartInternal = ({ data, chartId: providedChartId, width: pro
|
|
|
12114
12608
|
y: -20,
|
|
12115
12609
|
className: pie_semi_circle_chart_module_default.note,
|
|
12116
12610
|
children: note
|
|
12117
|
-
})] }),
|
|
12118
|
-
|
|
12119
|
-
|
|
12120
|
-
|
|
12121
|
-
|
|
12122
|
-
|
|
12123
|
-
|
|
12124
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
12125
|
-
className: standaloneScopeClass,
|
|
12126
|
-
role: "tooltip",
|
|
12127
|
-
children: renderTooltip({ tooltipData })
|
|
12128
|
-
})
|
|
12611
|
+
})] }), svgChildren]
|
|
12612
|
+
})
|
|
12613
|
+
]
|
|
12614
|
+
}), /* @__PURE__ */ jsx(PieSelectionOutput, {
|
|
12615
|
+
...selectionOutputProps,
|
|
12616
|
+
keyboardTooltipAnchor: selectedArc && getKeyboardTooltipAnchor(width / 2, height, path.centroid(selectedArc)),
|
|
12617
|
+
renderTooltip
|
|
12129
12618
|
})]
|
|
12130
12619
|
});
|
|
12131
12620
|
}
|