@automattic/charts 4.9.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 +14 -0
- package/dist/index.cjs +159 -66
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +14 -0
- package/dist/index.d.cts +27 -22
- package/dist/index.d.ts +27 -22
- package/dist/index.js +159 -66
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/charts/area-chart/area-chart.tsx +2 -1
- package/src/charts/area-chart/test/area-chart.test.tsx +0 -8
- package/src/charts/area-chart/types.ts +0 -2
- package/src/charts/bar-chart/bar-chart.tsx +7 -2
- package/src/charts/bar-chart/test/bar-chart.test.tsx +0 -8
- package/src/charts/bar-chart/types.ts +0 -2
- package/src/charts/bar-list-chart/bar-list-chart.tsx +3 -0
- 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/test/heatmap-chart.test.tsx +0 -6
- package/src/charts/heatmap-chart/types.ts +0 -2
- package/src/charts/leaderboard-chart/hooks/use-fitted-row-count.ts +2 -2
- package/src/charts/leaderboard-chart/leaderboard-chart.module.scss +6 -0
- package/src/charts/leaderboard-chart/leaderboard-chart.tsx +34 -19
- package/src/charts/leaderboard-chart/test/leaderboard-chart.test.tsx +27 -1
- package/src/charts/leaderboard-chart/types.ts +1 -0
- package/src/charts/line-chart/line-chart.tsx +3 -0
- package/src/charts/line-chart/test/line-chart.test.tsx +0 -8
- package/src/charts/line-chart/types.ts +0 -2
- package/src/charts/pie-chart/pie-chart.module.scss +3 -0
- package/src/charts/pie-chart/pie-chart.tsx +0 -5
- package/src/charts/pie-chart/test/pie-chart.test.tsx +4 -8
- 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 +0 -5
- package/src/charts/private/pie-keyboard-navigation/pie-tooltip.tsx +8 -3
- 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/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 +19 -1
- 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
|
@@ -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
|
]);
|
|
@@ -4726,6 +4771,7 @@ const LineChartInternal = forwardRef(({ data, ariaLabel, chartId: providedChartI
|
|
|
4726
4771
|
const legendInteractive = legend.interactive ?? false;
|
|
4727
4772
|
const legendCollapseGroups = legend.collapseGroups ?? false;
|
|
4728
4773
|
const legendComparisonItem = legend.comparisonItem ?? false;
|
|
4774
|
+
const legendComparisonSeriesItems = legend.comparisonSeriesItems;
|
|
4729
4775
|
const legendShape = legend.shape ?? "line";
|
|
4730
4776
|
const legendPosition = legend.position ?? "bottom";
|
|
4731
4777
|
const formatting = useChartFormatting();
|
|
@@ -4910,12 +4956,14 @@ const LineChartInternal = forwardRef(({ data, ariaLabel, chartId: providedChartI
|
|
|
4910
4956
|
glyphSize: Math.max(0, toNumber(glyphStyle?.radius) ?? 4),
|
|
4911
4957
|
collapseGroups: legendCollapseGroups,
|
|
4912
4958
|
comparisonItem: legendComparisonItem,
|
|
4959
|
+
comparisonSeriesItems: legendComparisonSeriesItems,
|
|
4913
4960
|
renderGlyph
|
|
4914
4961
|
}), [
|
|
4915
4962
|
withLegendGlyph,
|
|
4916
4963
|
glyphStyle?.radius,
|
|
4917
4964
|
legendCollapseGroups,
|
|
4918
4965
|
legendComparisonItem,
|
|
4966
|
+
legendComparisonSeriesItems,
|
|
4919
4967
|
renderGlyph
|
|
4920
4968
|
]), legendShape);
|
|
4921
4969
|
const chartMetadata = useMemo(() => ({
|
|
@@ -5384,8 +5432,13 @@ const AreaChartInternal = forwardRef(({ data, ariaLabel, chartId: providedChartI
|
|
|
5384
5432
|
withGlyph: false,
|
|
5385
5433
|
glyphSize: 0,
|
|
5386
5434
|
collapseGroups: legend.collapseGroups ?? false,
|
|
5387
|
-
comparisonItem: legend.comparisonItem ?? false
|
|
5388
|
-
|
|
5435
|
+
comparisonItem: legend.comparisonItem ?? false,
|
|
5436
|
+
comparisonSeriesItems: legend.comparisonSeriesItems
|
|
5437
|
+
}), [
|
|
5438
|
+
legend.collapseGroups,
|
|
5439
|
+
legend.comparisonItem,
|
|
5440
|
+
legend.comparisonSeriesItems
|
|
5441
|
+
]), legendShape);
|
|
5389
5442
|
const chartMetadata = useMemo(() => ({
|
|
5390
5443
|
stacked,
|
|
5391
5444
|
stackOffset,
|
|
@@ -6378,6 +6431,7 @@ const BarChartInternal = ({ data, ariaLabel, chartId: providedChartId, width, he
|
|
|
6378
6431
|
const legendInteractive = legend.interactive ?? false;
|
|
6379
6432
|
const legendCollapseGroups = legend.collapseGroups ?? false;
|
|
6380
6433
|
const legendComparisonItem = legend.comparisonItem ?? false;
|
|
6434
|
+
const legendComparisonSeriesItems = legend.comparisonSeriesItems;
|
|
6381
6435
|
const horizontal = orientation === "horizontal";
|
|
6382
6436
|
const chartId = useChartId(providedChartId);
|
|
6383
6437
|
const hiddenSeries = useDefaultHiddenSeries(chartId, defaultHiddenSeries);
|
|
@@ -6390,8 +6444,13 @@ const BarChartInternal = ({ data, ariaLabel, chartId: providedChartId, width, he
|
|
|
6390
6444
|
});
|
|
6391
6445
|
const legendItems = useChartLegendItems(dataSorted, useMemo(() => ({
|
|
6392
6446
|
collapseGroups: legendCollapseGroups,
|
|
6393
|
-
comparisonItem: legendComparisonItem
|
|
6394
|
-
|
|
6447
|
+
comparisonItem: legendComparisonItem,
|
|
6448
|
+
comparisonSeriesItems: legendComparisonSeriesItems
|
|
6449
|
+
}), [
|
|
6450
|
+
legendCollapseGroups,
|
|
6451
|
+
legendComparisonItem,
|
|
6452
|
+
legendComparisonSeriesItems
|
|
6453
|
+
]));
|
|
6395
6454
|
const { getElementStyles } = useGlobalChartsContext();
|
|
6396
6455
|
const isSeriesRendered = useCallback((series) => isSeriesVisible(series.label), [isSeriesVisible]);
|
|
6397
6456
|
const hasWholeNumberValues = useMemo(() => hasOnlyWholeNumbers(dataSorted.filter(isSeriesRendered)), [dataSorted, isSeriesRendered]);
|
|
@@ -6902,7 +6961,7 @@ const BarListChartInternal = ({ data, width, height, options = {}, margin = {
|
|
|
6902
6961
|
right: 20,
|
|
6903
6962
|
bottom: 0,
|
|
6904
6963
|
top: 0
|
|
6905
|
-
}, className, ...rest }) => {
|
|
6964
|
+
}, className, ariaLabel, ...rest }) => {
|
|
6906
6965
|
const { getElementStyles } = useGlobalChartsContext();
|
|
6907
6966
|
const tintedData = useMemo(() => {
|
|
6908
6967
|
if (data.length > 1) return data;
|
|
@@ -6977,6 +7036,7 @@ const BarListChartInternal = ({ data, width, height, options = {}, margin = {
|
|
|
6977
7036
|
xScale: chartOptions.xScale,
|
|
6978
7037
|
yScale: chartOptions.yScale
|
|
6979
7038
|
},
|
|
7039
|
+
ariaLabel: ariaLabel ?? __("Bar list chart", "jetpack-charts"),
|
|
6980
7040
|
...rest
|
|
6981
7041
|
});
|
|
6982
7042
|
};
|
|
@@ -7052,6 +7112,8 @@ const useFunnelSelection = (hideTooltip) => {
|
|
|
7052
7112
|
};
|
|
7053
7113
|
//#endregion
|
|
7054
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;
|
|
7055
7117
|
/**
|
|
7056
7118
|
* Internal ConversionFunnelChart component with chart registration
|
|
7057
7119
|
*
|
|
@@ -7063,6 +7125,7 @@ const useFunnelSelection = (hideTooltip) => {
|
|
|
7063
7125
|
* @param props.loading - Whether the chart is in loading state
|
|
7064
7126
|
* @param props.animation - Whether to show chart animation on initial render or not
|
|
7065
7127
|
* @param props.className - Additional CSS class name
|
|
7128
|
+
* @param props.ariaLabel - Accessible name for the chart group
|
|
7066
7129
|
* @param props.height - Height of the chart container. Falls back to style.height if set, otherwise defaults to "100%".
|
|
7067
7130
|
* @param props.style - Custom styling
|
|
7068
7131
|
* @param props.renderStepLabel - Custom render function for step labels
|
|
@@ -7072,7 +7135,7 @@ const useFunnelSelection = (hideTooltip) => {
|
|
|
7072
7135
|
* @param props.tooltipStyle - Inline styles merged over the tooltip box defaults
|
|
7073
7136
|
* @return JSX element representing the conversion funnel chart
|
|
7074
7137
|
*/
|
|
7075
|
-
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 }) => {
|
|
7076
7139
|
const chartId = useChartId(providedChartId);
|
|
7077
7140
|
const { getElementStyles, isColorPaletteResolved } = useGlobalChartsContext();
|
|
7078
7141
|
const chartRef = useRef(null);
|
|
@@ -7081,10 +7144,13 @@ const ConversionFunnelChartInternal = ({ mainRate, changeIndicator, steps, loadi
|
|
|
7081
7144
|
const { tooltipData, tooltipLeft, tooltipTop, tooltipOpen, showTooltip, hideTooltip } = useTooltip();
|
|
7082
7145
|
const { handleBarClick, handleBarKeyDown, clearSelection, getStepState } = useFunnelSelection(hideTooltip);
|
|
7083
7146
|
const standaloneScopeClass = useStandaloneScopeClass();
|
|
7147
|
+
const [measureChartRef, , chartHeight] = useElementSize();
|
|
7148
|
+
const gap = chartHeight > 0 && chartHeight < SHORT_CHART_HEIGHT ? "sm" : "xl";
|
|
7084
7149
|
const setChartRef = useCallback((node) => {
|
|
7085
7150
|
chartRef.current = node;
|
|
7086
7151
|
setScopeNode(node);
|
|
7087
|
-
|
|
7152
|
+
measureChartRef(node);
|
|
7153
|
+
}, [measureChartRef]);
|
|
7088
7154
|
const clearSelectionAndRef = useCallback(() => {
|
|
7089
7155
|
clearSelection();
|
|
7090
7156
|
selectedBarRef.current = null;
|
|
@@ -7232,7 +7298,9 @@ const ConversionFunnelChartInternal = ({ mainRate, changeIndicator, steps, loadi
|
|
|
7232
7298
|
const maxRate = Math.max(...steps.map((step) => step.rate));
|
|
7233
7299
|
return /* @__PURE__ */ jsxs(Stack, {
|
|
7234
7300
|
direction: "column",
|
|
7235
|
-
gap
|
|
7301
|
+
gap,
|
|
7302
|
+
role: "group",
|
|
7303
|
+
"aria-label": ariaLabel ?? __("Conversion funnel chart", "jetpack-charts"),
|
|
7236
7304
|
ref: setChartRef,
|
|
7237
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),
|
|
7238
7306
|
style: {
|
|
@@ -7263,7 +7331,7 @@ const ConversionFunnelChartInternal = ({ mainRate, changeIndicator, steps, loadi
|
|
|
7263
7331
|
return /* @__PURE__ */ jsxs(Stack, {
|
|
7264
7332
|
direction: "column",
|
|
7265
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"]),
|
|
7266
|
-
gap
|
|
7334
|
+
gap,
|
|
7267
7335
|
children: [/* @__PURE__ */ jsxs(Stack, {
|
|
7268
7336
|
direction: "column",
|
|
7269
7337
|
gap: "xs",
|
|
@@ -7457,6 +7525,7 @@ function normalizeGeoChartError(eventArgs) {
|
|
|
7457
7525
|
*
|
|
7458
7526
|
* @param props - The props for the GeoChart component
|
|
7459
7527
|
* @param props.data - Data in Google Charts format (array of arrays with headers)
|
|
7528
|
+
* @param props.ariaLabel - Accessible name of the chart
|
|
7460
7529
|
* @param props.width - Width of the chart in pixels
|
|
7461
7530
|
* @param props.height - Height of the chart in pixels
|
|
7462
7531
|
* @param props.region - Region to display ('world', 'US', or ISO 3166-1 alpha-2 code)
|
|
@@ -7468,7 +7537,7 @@ function normalizeGeoChartError(eventArgs) {
|
|
|
7468
7537
|
* @param props.renderPlaceholder - Optional render function for the loading placeholder
|
|
7469
7538
|
* @return A React component displaying an interactive map with data visualization
|
|
7470
7539
|
*/
|
|
7471
|
-
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 }) => {
|
|
7472
7541
|
const { getElementStyles } = useGlobalChartsContext();
|
|
7473
7542
|
const scopeElement = useChartScopeElement();
|
|
7474
7543
|
const containerRef = useRef(null);
|
|
@@ -7556,8 +7625,14 @@ const GeoChartInternal = ({ className, data, width, height, region = "world", re
|
|
|
7556
7625
|
sanitizedData.hasHtmlTooltips
|
|
7557
7626
|
]);
|
|
7558
7627
|
const chartEvents = useMemo(() => {
|
|
7559
|
-
|
|
7560
|
-
|
|
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, {
|
|
7561
7636
|
eventName: "error",
|
|
7562
7637
|
callback: ({ eventArgs }) => {
|
|
7563
7638
|
onError(normalizeGeoChartError(eventArgs));
|
|
@@ -7566,6 +7641,8 @@ const GeoChartInternal = ({ className, data, width, height, region = "world", re
|
|
|
7566
7641
|
}, [onError]);
|
|
7567
7642
|
return /* @__PURE__ */ jsx(Center, {
|
|
7568
7643
|
ref: containerRef,
|
|
7644
|
+
role: "group",
|
|
7645
|
+
"aria-label": ariaLabel ?? __("Geo chart", "jetpack-charts"),
|
|
7569
7646
|
className: clsx("geo-chart", geo_chart_module_default.container, className),
|
|
7570
7647
|
style: {
|
|
7571
7648
|
width,
|
|
@@ -8120,7 +8197,7 @@ const CELL_VALUE_MODIFIER = {
|
|
|
8120
8197
|
white: heatmap_chart_module_default["heatmap-chart__cell-value--white"]
|
|
8121
8198
|
};
|
|
8122
8199
|
const NO_ROW_LABELS = [];
|
|
8123
|
-
const TOOLTIP_BOX_STYLE = { zIndex: 3 };
|
|
8200
|
+
const TOOLTIP_BOX_STYLE$1 = { zIndex: 3 };
|
|
8124
8201
|
const largest = (root, selector, size) => Math.max(0, ...Array.from(root.querySelectorAll(selector), (el) => el[size]));
|
|
8125
8202
|
const gridBox = (chart, grid) => {
|
|
8126
8203
|
let height = chart.clientHeight;
|
|
@@ -8143,9 +8220,9 @@ const cellName = (info) => info.cellLabel || [
|
|
|
8143
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 }) => {
|
|
8144
8221
|
const chartId = useChartId(providedChartId);
|
|
8145
8222
|
const tooltipBoxStyle = tooltipStyle ? {
|
|
8146
|
-
...TOOLTIP_BOX_STYLE,
|
|
8223
|
+
...TOOLTIP_BOX_STYLE$1,
|
|
8147
8224
|
...tooltipStyle
|
|
8148
|
-
} : TOOLTIP_BOX_STYLE;
|
|
8225
|
+
} : TOOLTIP_BOX_STYLE$1;
|
|
8149
8226
|
const { getElementStyles, theme } = useGlobalChartsContext();
|
|
8150
8227
|
const scopeElement = useChartScopeElement();
|
|
8151
8228
|
const { heatmapChart: heatmapChartSettings } = theme;
|
|
@@ -11270,8 +11347,8 @@ const SUBPIXEL_TOLERANCE = .5;
|
|
|
11270
11347
|
* depends on `--a8c-charts-dimension-leaderboard-row-gap`, label wrapping, and
|
|
11271
11348
|
* whatever a caller renders as a label, so any restated number would drift.
|
|
11272
11349
|
*
|
|
11273
|
-
* Every row is a direct grid child marked with `data-row-index`;
|
|
11274
|
-
*
|
|
11350
|
+
* Every row is a `listitem` div, a direct grid child marked with `data-row-index`;
|
|
11351
|
+
* interactive rows hold a button inside it.
|
|
11275
11352
|
*
|
|
11276
11353
|
* @param enabled - Whether to measure at all. When false every row fits.
|
|
11277
11354
|
* @param rowCount - Total number of rows rendered.
|
|
@@ -11413,6 +11490,7 @@ var leaderboard_chart_module_default = {
|
|
|
11413
11490
|
"overlayLabel": "a8ccharts-GovfoW-overlayLabel",
|
|
11414
11491
|
"row": "a8ccharts-GovfoW-row",
|
|
11415
11492
|
"rowButton": "a8ccharts-GovfoW-rowButton",
|
|
11493
|
+
"rowItem": "a8ccharts-GovfoW-rowItem",
|
|
11416
11494
|
"stretch": "a8ccharts-GovfoW-stretch",
|
|
11417
11495
|
"valueContainer": "a8ccharts-GovfoW-valueContainer"
|
|
11418
11496
|
};
|
|
@@ -11525,9 +11603,10 @@ const BarWithLabel = ({ entry, withComparison, withOverlayLabel, primaryColor, s
|
|
|
11525
11603
|
* @param props.children - Child components for composition API
|
|
11526
11604
|
* @param props.className - Additional CSS class name
|
|
11527
11605
|
* @param props.style - Custom styling for the chart container
|
|
11606
|
+
* @param props.ariaLabel - Accessible name for the list, defaulting to "Leaderboard chart"
|
|
11528
11607
|
* @return JSX element representing the leaderboard chart
|
|
11529
11608
|
*/
|
|
11530
|
-
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 }) => {
|
|
11531
11610
|
const legendInteractive = legend.interactive ?? false;
|
|
11532
11611
|
const legendPosition = legend.position ?? "bottom";
|
|
11533
11612
|
const chartId = useChartId(providedChartId);
|
|
@@ -11658,6 +11737,8 @@ const LeaderboardChartInternal = ({ data, chartId: providedChartId, width: propW
|
|
|
11658
11737
|
className: leaderboard_chart_module_default.emptyState,
|
|
11659
11738
|
children: getAllHiddenMessage(legendInteractive, "series")
|
|
11660
11739
|
}) : /* @__PURE__ */ jsx(component_default, {
|
|
11740
|
+
role: "list",
|
|
11741
|
+
"aria-label": ariaLabel ?? __("Leaderboard chart", "jetpack-charts"),
|
|
11661
11742
|
templateColumns: "minmax(0, 1fr) auto",
|
|
11662
11743
|
rowGap: ROW_GAP,
|
|
11663
11744
|
columnGap: COLUMN_GAP,
|
|
@@ -11705,40 +11786,49 @@ const LeaderboardChartInternal = ({ data, chartId: providedChartId, width: propW
|
|
|
11705
11786
|
})
|
|
11706
11787
|
]
|
|
11707
11788
|
})] });
|
|
11708
|
-
if (entry.onClick && entry.hasInteractiveLabel) return /* @__PURE__ */
|
|
11789
|
+
if (entry.onClick && entry.hasInteractiveLabel) return /* @__PURE__ */ jsx("div", {
|
|
11790
|
+
role: "listitem",
|
|
11709
11791
|
"data-row-index": rowIndex,
|
|
11710
11792
|
style: rowStyle,
|
|
11711
|
-
className:
|
|
11712
|
-
|
|
11713
|
-
|
|
11714
|
-
|
|
11715
|
-
|
|
11716
|
-
|
|
11717
|
-
|
|
11718
|
-
|
|
11719
|
-
|
|
11720
|
-
|
|
11721
|
-
|
|
11722
|
-
|
|
11723
|
-
|
|
11724
|
-
|
|
11725
|
-
|
|
11726
|
-
|
|
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
|
+
})
|
|
11727
11812
|
}, entry.id);
|
|
11728
|
-
if (entry.onClick) return /* @__PURE__ */
|
|
11729
|
-
|
|
11813
|
+
if (entry.onClick) return /* @__PURE__ */ jsx("div", {
|
|
11814
|
+
role: "listitem",
|
|
11730
11815
|
"data-row-index": rowIndex,
|
|
11731
11816
|
style: rowStyle,
|
|
11732
|
-
className:
|
|
11733
|
-
|
|
11734
|
-
|
|
11735
|
-
|
|
11736
|
-
|
|
11737
|
-
|
|
11738
|
-
|
|
11739
|
-
|
|
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
|
+
})
|
|
11740
11829
|
}, entry.id);
|
|
11741
11830
|
return /* @__PURE__ */ jsx("div", {
|
|
11831
|
+
role: "listitem",
|
|
11742
11832
|
"data-row-index": rowIndex,
|
|
11743
11833
|
style: rowStyle,
|
|
11744
11834
|
className: leaderboard_chart_module_default.row,
|
|
@@ -11775,11 +11865,13 @@ const PieSelectionAnnouncement = ({ data }) => /* @__PURE__ */ jsx(VisuallyHidde
|
|
|
11775
11865
|
});
|
|
11776
11866
|
//#endregion
|
|
11777
11867
|
//#region src/charts/private/pie-keyboard-navigation/pie-tooltip.tsx
|
|
11868
|
+
const TOOLTIP_BOX_STYLE = { zIndex: 3 };
|
|
11778
11869
|
const PieTooltip = ({ top, left, selectedIndex, tooltipRef, children }) => {
|
|
11779
11870
|
const standaloneScopeClass = useStandaloneScopeClass();
|
|
11780
11871
|
return /* @__PURE__ */ jsx(BoundedTooltip, {
|
|
11781
11872
|
top,
|
|
11782
11873
|
left,
|
|
11874
|
+
style: TOOLTIP_BOX_STYLE,
|
|
11783
11875
|
children: selectedIndex === void 0 ? /* @__PURE__ */ jsx("div", {
|
|
11784
11876
|
className: standaloneScopeClass,
|
|
11785
11877
|
role: "tooltip",
|
|
@@ -12002,6 +12094,7 @@ function RadialWipeAnimation({ id, radius, innerRadius = 0, durationMs = 1e3, wi
|
|
|
12002
12094
|
//#endregion
|
|
12003
12095
|
//#region src/charts/pie-chart/pie-chart.module.scss
|
|
12004
12096
|
var pie_chart_module_default = {
|
|
12097
|
+
"pie-chart": "a8ccharts-gnszbG-pie-chart",
|
|
12005
12098
|
"pie-chart__label-plate": "a8ccharts-gnszbG-pie-chart__label-plate",
|
|
12006
12099
|
"pie-chart__label-text": "a8ccharts-gnszbG-pie-chart__label-text",
|
|
12007
12100
|
"pie-chart__label-text--black": "a8ccharts-gnszbG-pie-chart__label-text--black",
|