@automattic/charts 1.8.1 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/dist/index.cjs +530 -52
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +122 -34
- package/dist/index.d.cts +97 -7
- package/dist/index.d.ts +97 -7
- package/dist/index.js +527 -54
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/src/charts/area-chart/area-chart.module.scss +3 -1
- package/src/charts/area-chart/area-chart.tsx +5 -2
- package/src/charts/bar-chart/bar-chart.module.scss +6 -2
- package/src/charts/bar-chart/private/comparison-bars.tsx +6 -0
- package/src/charts/conversion-funnel-chart/conversion-funnel-chart.module.scss +15 -12
- package/src/charts/geo-chart/geo-chart.tsx +6 -1
- package/src/charts/geo-chart/test/geo-chart.test.tsx +11 -1
- package/src/charts/heatmap-chart/heatmap-chart.module.scss +103 -0
- package/src/charts/heatmap-chart/heatmap-chart.tsx +422 -0
- package/src/charts/heatmap-chart/index.ts +4 -0
- package/src/charts/heatmap-chart/private/build-calendar-data.ts +81 -0
- package/src/charts/heatmap-chart/private/heatmap-legend.tsx +53 -0
- package/src/charts/heatmap-chart/private/index.ts +5 -0
- package/src/charts/heatmap-chart/private/use-heatmap-colors.ts +45 -0
- package/src/charts/heatmap-chart/test/build-calendar-data.test.ts +88 -0
- package/src/charts/heatmap-chart/test/heatmap-chart.test.tsx +301 -0
- package/src/charts/heatmap-chart/test/use-heatmap-colors.test.ts +34 -0
- package/src/charts/heatmap-chart/types.ts +42 -0
- package/src/charts/index.ts +1 -0
- package/src/charts/leaderboard-chart/leaderboard-chart.module.scss +18 -6
- package/src/charts/line-chart/line-chart.module.scss +6 -4
- package/src/charts/line-chart/line-chart.tsx +6 -2
- package/src/charts/line-chart/private/line-chart-annotation.tsx +16 -3
- package/src/charts/private/grid-control/grid-control.module.scss +1 -4
- package/src/charts/private/svg-empty-state/svg-empty-state.module.scss +1 -1
- package/src/charts/private/with-responsive/test/with-responsive.test.tsx +14 -0
- package/src/charts/private/with-responsive/with-responsive.tsx +12 -0
- package/src/charts/private/x-zoom.module.scss +6 -3
- package/src/components/legend/private/base-legend.module.scss +3 -1
- package/src/components/tooltip/base-tooltip.module.scss +4 -1
- package/src/components/trend-indicator/trend-indicator.module.scss +5 -3
- package/src/hooks/use-xychart-theme.ts +24 -0
- package/src/index.ts +12 -0
- package/src/providers/chart-context/themes.ts +29 -16
- package/src/types.ts +19 -2
- package/src/utils/color-utils.ts +36 -0
- package/src/utils/test/color-utils.test.ts +33 -0
package/dist/index.cjs
CHANGED
|
@@ -448,6 +448,35 @@ const lightenHexColor = (hex, blend) => {
|
|
|
448
448
|
const newB = Math.round(b + (255 - b) * blend);
|
|
449
449
|
return `#${newR.toString(16).padStart(2, "0")}${newG.toString(16).padStart(2, "0")}${newB.toString(16).padStart(2, "0")}`;
|
|
450
450
|
};
|
|
451
|
+
/**
|
|
452
|
+
* WCAG relative luminance of a hex color (0 = black, 1 = white).
|
|
453
|
+
*
|
|
454
|
+
* @param hex - Hex color string (e.g., '#98C8DF')
|
|
455
|
+
* @return Relative luminance in the range [0, 1]
|
|
456
|
+
* @throws {Error} if hex string is malformed
|
|
457
|
+
*/
|
|
458
|
+
const relativeLuminance = (hex) => {
|
|
459
|
+
validateHexColor(hex);
|
|
460
|
+
const toLinear = (value) => {
|
|
461
|
+
const channel = value / 255;
|
|
462
|
+
return channel <= .03928 ? channel / 12.92 : Math.pow((channel + .055) / 1.055, 2.4);
|
|
463
|
+
};
|
|
464
|
+
const r = toLinear(parseInt(hex.slice(1, 3), 16));
|
|
465
|
+
const g = toLinear(parseInt(hex.slice(3, 5), 16));
|
|
466
|
+
const b = toLinear(parseInt(hex.slice(5, 7), 16));
|
|
467
|
+
return .2126 * r + .7152 * g + .0722 * b;
|
|
468
|
+
};
|
|
469
|
+
/**
|
|
470
|
+
* Whether light text reads better than dark text on the given background, using the W3C
|
|
471
|
+
* luminance threshold (0.179) that maximizes contrast against black vs white.
|
|
472
|
+
*
|
|
473
|
+
* @param backgroundHex - Hex background color
|
|
474
|
+
* @return true if light text should be used; false (dark text) for malformed colors
|
|
475
|
+
*/
|
|
476
|
+
const prefersLightText = (backgroundHex) => {
|
|
477
|
+
if (!isValidHexColor(backgroundHex)) return false;
|
|
478
|
+
return relativeLuminance(backgroundHex) <= .179;
|
|
479
|
+
};
|
|
451
480
|
//#endregion
|
|
452
481
|
//#region src/utils/resolve-css-var.ts
|
|
453
482
|
/**
|
|
@@ -681,7 +710,7 @@ const getChartColor = (index, colorCache) => {
|
|
|
681
710
|
* Default theme configuration
|
|
682
711
|
*/
|
|
683
712
|
const defaultTheme = {
|
|
684
|
-
backgroundColor: "#
|
|
713
|
+
backgroundColor: "var(--wpds-color-bg-surface-neutral-strong, #fff)",
|
|
685
714
|
labelBackgroundColor: "transparent",
|
|
686
715
|
labelTextColor: "#FFFFFF",
|
|
687
716
|
colors: [
|
|
@@ -692,56 +721,59 @@ const defaultTheme = {
|
|
|
692
721
|
"#FF8C8F"
|
|
693
722
|
],
|
|
694
723
|
gridStyles: {
|
|
695
|
-
stroke: "#
|
|
724
|
+
stroke: "var(--wpds-color-stroke-surface-neutral, #dbdbdb)",
|
|
696
725
|
strokeWidth: 1
|
|
697
726
|
},
|
|
698
727
|
tickLength: 4,
|
|
699
728
|
gridColor: "",
|
|
700
729
|
gridColorDark: "",
|
|
701
|
-
xTickLineStyles: {
|
|
730
|
+
xTickLineStyles: {
|
|
731
|
+
stroke: "var(--wpds-color-stroke-surface-neutral, #dbdbdb)",
|
|
732
|
+
strokeWidth: 1
|
|
733
|
+
},
|
|
702
734
|
xAxisLineStyles: {
|
|
703
|
-
stroke: "#
|
|
735
|
+
stroke: "var(--wpds-color-stroke-surface-neutral, #dbdbdb)",
|
|
704
736
|
strokeWidth: 1
|
|
705
737
|
},
|
|
706
738
|
legend: {
|
|
707
|
-
labelStyles: { color: "var(--
|
|
739
|
+
labelStyles: { color: "var(--wpds-color-fg-content-neutral, #1e1e1e)" },
|
|
708
740
|
containerStyles: {},
|
|
709
741
|
shapeStyles: []
|
|
710
742
|
},
|
|
711
743
|
seriesLineStyles: [],
|
|
712
744
|
glyphs: [],
|
|
713
745
|
svgLabelSmall: {
|
|
714
|
-
fill: "var(--
|
|
746
|
+
fill: "var(--wpds-color-fg-content-neutral, #1e1e1e)",
|
|
715
747
|
fontFamily: "inherit"
|
|
716
748
|
},
|
|
717
749
|
svgLabelBig: { fontFamily: "inherit" },
|
|
718
750
|
annotationStyles: {
|
|
719
751
|
label: {
|
|
720
|
-
anchorLineStroke: "var(--
|
|
721
|
-
backgroundFill: "#fff"
|
|
752
|
+
anchorLineStroke: "var(--wpds-color-fg-content-neutral, #1e1e1e)",
|
|
753
|
+
backgroundFill: "var(--wpds-color-bg-surface-neutral-strong, #fff)"
|
|
722
754
|
},
|
|
723
|
-
connector: { stroke: "var(--
|
|
755
|
+
connector: { stroke: "var(--wpds-color-fg-content-neutral, #1e1e1e)" },
|
|
724
756
|
circleSubject: {
|
|
725
757
|
stroke: "transparent",
|
|
726
|
-
fill: "var(--
|
|
758
|
+
fill: "var(--wpds-color-fg-content-neutral, #1e1e1e)",
|
|
727
759
|
radius: 5
|
|
728
760
|
}
|
|
729
761
|
},
|
|
730
|
-
geoChart: { featureFillColor: "var(--
|
|
762
|
+
geoChart: { featureFillColor: "var(--wpds-color-bg-surface-neutral-weak, #f4f4f4)" },
|
|
731
763
|
leaderboardChart: {
|
|
732
764
|
rowGap: 12,
|
|
733
765
|
columnGap: 4,
|
|
734
766
|
labelSpacing: "xs",
|
|
735
767
|
deltaColors: [
|
|
736
|
-
"#
|
|
737
|
-
"#
|
|
738
|
-
"#
|
|
768
|
+
"var(--wpds-color-fg-content-error-weak, #cc1818)",
|
|
769
|
+
"var(--wpds-color-fg-content-neutral-weak, #707070)",
|
|
770
|
+
"var(--wpds-color-fg-content-success-weak, #008030)"
|
|
739
771
|
]
|
|
740
772
|
},
|
|
741
773
|
conversionFunnelChart: {
|
|
742
|
-
backgroundColor: "#
|
|
743
|
-
positiveChangeColor: "#
|
|
744
|
-
negativeChangeColor: "#
|
|
774
|
+
backgroundColor: "var(--wpds-color-bg-surface-neutral-weak, #f4f4f4)",
|
|
775
|
+
positiveChangeColor: "var(--wpds-color-fg-content-success-weak, #008030)",
|
|
776
|
+
negativeChangeColor: "var(--wpds-color-fg-content-error-weak, #cc1818)"
|
|
745
777
|
},
|
|
746
778
|
lineChart: { lineStyles: { comparison: {
|
|
747
779
|
strokeDasharray: "4 4",
|
|
@@ -759,6 +791,10 @@ const defaultTheme = {
|
|
|
759
791
|
left: 2
|
|
760
792
|
},
|
|
761
793
|
strokeWidth: 1.5
|
|
794
|
+
},
|
|
795
|
+
heatmapChart: {
|
|
796
|
+
compactCellGap: 2,
|
|
797
|
+
compactCellSize: 11
|
|
762
798
|
}
|
|
763
799
|
};
|
|
764
800
|
//#endregion
|
|
@@ -971,13 +1007,31 @@ const useDeepMemo = (value) => {
|
|
|
971
1007
|
};
|
|
972
1008
|
//#endregion
|
|
973
1009
|
//#region src/hooks/use-xychart-theme.ts
|
|
1010
|
+
const resolveColor = (value) => value ? resolveCssVariable(value) ?? value : value;
|
|
974
1011
|
const useXYChartTheme = (data) => {
|
|
975
1012
|
const theme = useGlobalChartsTheme();
|
|
976
1013
|
return (0, react$1.useMemo)(() => {
|
|
977
1014
|
const seriesColors = (data ?? []).map((series) => series.options?.stroke).filter((color) => Boolean(color));
|
|
978
1015
|
return (0, _visx_xychart.buildChartTheme)({
|
|
979
1016
|
...theme,
|
|
980
|
-
colors: [...seriesColors, ...theme.colors ?? []]
|
|
1017
|
+
colors: [...seriesColors, ...theme.colors ?? []],
|
|
1018
|
+
backgroundColor: resolveColor(theme.backgroundColor),
|
|
1019
|
+
gridStyles: theme.gridStyles && {
|
|
1020
|
+
...theme.gridStyles,
|
|
1021
|
+
stroke: resolveColor(theme.gridStyles.stroke)
|
|
1022
|
+
},
|
|
1023
|
+
xAxisLineStyles: theme.xAxisLineStyles && {
|
|
1024
|
+
...theme.xAxisLineStyles,
|
|
1025
|
+
stroke: resolveColor(theme.xAxisLineStyles.stroke)
|
|
1026
|
+
},
|
|
1027
|
+
xTickLineStyles: theme.xTickLineStyles && {
|
|
1028
|
+
...theme.xTickLineStyles,
|
|
1029
|
+
stroke: resolveColor(theme.xTickLineStyles.stroke)
|
|
1030
|
+
},
|
|
1031
|
+
svgLabelSmall: theme.svgLabelSmall && {
|
|
1032
|
+
...theme.svgLabelSmall,
|
|
1033
|
+
fill: resolveColor(theme.svgLabelSmall.fill)
|
|
1034
|
+
}
|
|
981
1035
|
});
|
|
982
1036
|
}, [theme, data]);
|
|
983
1037
|
};
|
|
@@ -2806,12 +2860,17 @@ function withResponsive(WrappedComponent) {
|
|
|
2806
2860
|
const effectiveWidth = measuredWidth || width || 0;
|
|
2807
2861
|
const effectiveHeight = measuredHeight || height || 0;
|
|
2808
2862
|
const defaultHeight = hasAspectRatio ? "auto" : "100%";
|
|
2863
|
+
const aspectRatioStyle = hasAspectRatio && aspectRatio ? {
|
|
2864
|
+
aspectRatio: `${1 / aspectRatio}`,
|
|
2865
|
+
maxWidth: width === void 0 ? maxWidth : void 0
|
|
2866
|
+
} : null;
|
|
2809
2867
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2810
2868
|
ref: parentRef,
|
|
2811
2869
|
className: with_responsive_module_default.container,
|
|
2812
2870
|
style: {
|
|
2813
2871
|
width: width ?? "100%",
|
|
2814
|
-
height: height ?? defaultHeight
|
|
2872
|
+
height: height ?? defaultHeight,
|
|
2873
|
+
...aspectRatioStyle
|
|
2815
2874
|
},
|
|
2816
2875
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(WrappedComponent, {
|
|
2817
2876
|
width: effectiveWidth,
|
|
@@ -3252,6 +3311,7 @@ const LineChartAnnotation = ({ datum, title, subtitle, subjectType = "circle", s
|
|
|
3252
3311
|
const labelRef = (0, react$1.useRef)(null);
|
|
3253
3312
|
const [height, setHeight] = (0, react$1.useState)(null);
|
|
3254
3313
|
const styles = (0, deepmerge.default)(providerTheme.annotationStyles ?? {}, datumStyles ?? {});
|
|
3314
|
+
const resolveColor = (value) => value ? resolveCssVariable(value) ?? value : value;
|
|
3255
3315
|
(0, react$1.useEffect)(() => {
|
|
3256
3316
|
if (labelRef.current?.getBBox) setHeight(labelRef.current.getBBox().height);
|
|
3257
3317
|
}, []);
|
|
@@ -3334,8 +3394,15 @@ const LineChartAnnotation = ({ datum, title, subtitle, subjectType = "circle", s
|
|
|
3334
3394
|
dx,
|
|
3335
3395
|
dy,
|
|
3336
3396
|
children: [
|
|
3337
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_visx_annotation.Connector, {
|
|
3338
|
-
|
|
3397
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_visx_annotation.Connector, {
|
|
3398
|
+
...styles?.connector,
|
|
3399
|
+
stroke: resolveColor(styles?.connector?.stroke)
|
|
3400
|
+
}),
|
|
3401
|
+
subjectType === "circle" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_visx_annotation.CircleSubject, {
|
|
3402
|
+
...styles?.circleSubject,
|
|
3403
|
+
fill: resolveColor(styles?.circleSubject?.fill),
|
|
3404
|
+
stroke: resolveColor(styles?.circleSubject?.stroke)
|
|
3405
|
+
}),
|
|
3339
3406
|
subjectType === "line-vertical" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_visx_annotation.LineSubject, {
|
|
3340
3407
|
min: yMax,
|
|
3341
3408
|
max: yMin,
|
|
@@ -3369,6 +3436,8 @@ const LineChartAnnotation = ({ datum, title, subtitle, subjectType = "circle", s
|
|
|
3369
3436
|
title,
|
|
3370
3437
|
subtitle,
|
|
3371
3438
|
...styles?.label,
|
|
3439
|
+
anchorLineStroke: resolveColor(styles?.label?.anchorLineStroke),
|
|
3440
|
+
backgroundFill: resolveColor(styles?.label?.backgroundFill),
|
|
3372
3441
|
...labelPosition,
|
|
3373
3442
|
horizontalAnchor: getHorizontalAnchor(subjectType, isFlippedHorizontally),
|
|
3374
3443
|
verticalAnchor: getVerticalAnchor(subjectType, isFlippedVertically, y, yMax, height ?? ANNOTATION_INIT_HEIGHT)
|
|
@@ -3485,6 +3554,7 @@ const LineChartInternal = (0, react$1.forwardRef)(({ data, chartId: providedChar
|
|
|
3485
3554
|
const legendShape = legend.shape ?? "line";
|
|
3486
3555
|
const legendPosition = legend.position ?? "bottom";
|
|
3487
3556
|
const providerTheme = useGlobalChartsTheme();
|
|
3557
|
+
const resolvedBackgroundColor = resolveCssVariable(providerTheme.backgroundColor) ?? providerTheme.backgroundColor;
|
|
3488
3558
|
const theme = useXYChartTheme(data);
|
|
3489
3559
|
const chartId = useChartId(providedChartId);
|
|
3490
3560
|
const chartRef = (0, react$1.useRef)(null);
|
|
@@ -3732,7 +3802,7 @@ const LineChartInternal = (0, react$1.forwardRef)(({ data, chartId: providedChar
|
|
|
3732
3802
|
from: color,
|
|
3733
3803
|
fromOpacity: .4,
|
|
3734
3804
|
toOpacity: .1,
|
|
3735
|
-
to:
|
|
3805
|
+
to: resolvedBackgroundColor,
|
|
3736
3806
|
...seriesData.options?.gradient,
|
|
3737
3807
|
children: seriesData.options?.gradient?.stops?.map((stop, stopIndex) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("stop", {
|
|
3738
3808
|
offset: stop.offset,
|
|
@@ -4236,7 +4306,7 @@ const AreaChartInternal = (0, react$1.forwardRef)(({ data, chartId: providedChar
|
|
|
4236
4306
|
stacked,
|
|
4237
4307
|
stackOffset,
|
|
4238
4308
|
getElementStyles,
|
|
4239
|
-
strokeColor: providerTheme.backgroundColor
|
|
4309
|
+
strokeColor: resolveCssVariable(providerTheme.backgroundColor) ?? providerTheme.backgroundColor
|
|
4240
4310
|
})] }),
|
|
4241
4311
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(AreaChartScalesRef, {
|
|
4242
4312
|
chartRef: internalChartRef,
|
|
@@ -5600,6 +5670,11 @@ var geo_chart_module_default = { "container": "a8ccharts-8hS2IW-container" };
|
|
|
5600
5670
|
*/
|
|
5601
5671
|
const DEFAULT_FEATURE_FILL_COLOR = "#ffffff";
|
|
5602
5672
|
const DEFAULT_BACKGROUND_COLOR = "#ffffff";
|
|
5673
|
+
const GEO_CHART_PACKAGES = [
|
|
5674
|
+
"corechart",
|
|
5675
|
+
"controls",
|
|
5676
|
+
"geochart"
|
|
5677
|
+
];
|
|
5603
5678
|
/**
|
|
5604
5679
|
* Renders a geographical chart using Google Charts GeoChart to visualize data.
|
|
5605
5680
|
*
|
|
@@ -5688,6 +5763,7 @@ const GeoChartInternal = ({ className, data, width, height, region = "world", re
|
|
|
5688
5763
|
},
|
|
5689
5764
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_google_charts.Chart, {
|
|
5690
5765
|
chartType: "GeoChart",
|
|
5766
|
+
chartPackages: GEO_CHART_PACKAGES,
|
|
5691
5767
|
width,
|
|
5692
5768
|
height,
|
|
5693
5769
|
data: sanitizedData.data,
|
|
@@ -5703,10 +5779,407 @@ const GeoChartWithProvider = (props) => {
|
|
|
5703
5779
|
GeoChartWithProvider.displayName = "GeoChart";
|
|
5704
5780
|
const GeoChartResponsive = withResponsive(GeoChartWithProvider);
|
|
5705
5781
|
//#endregion
|
|
5706
|
-
//#region
|
|
5782
|
+
//#region src/charts/heatmap-chart/heatmap-chart.module.scss
|
|
5783
|
+
var heatmap_chart_module_default = {
|
|
5784
|
+
"heatmap-chart": "a8ccharts-O3YMOW-heatmap-chart",
|
|
5785
|
+
"heatmap-chart__cell": "a8ccharts-O3YMOW-heatmap-chart__cell",
|
|
5786
|
+
"heatmap-chart__cell--filled": "a8ccharts-O3YMOW-heatmap-chart__cell--filled",
|
|
5787
|
+
"heatmap-chart__cell--selected": "a8ccharts-O3YMOW-heatmap-chart__cell--selected",
|
|
5788
|
+
"heatmap-chart__cell--strong": "a8ccharts-O3YMOW-heatmap-chart__cell--strong",
|
|
5789
|
+
"heatmap-chart__cell-value": "a8ccharts-O3YMOW-heatmap-chart__cell-value",
|
|
5790
|
+
"heatmap-chart__col-label": "a8ccharts-O3YMOW-heatmap-chart__col-label",
|
|
5791
|
+
"heatmap-chart__empty": "a8ccharts-O3YMOW-heatmap-chart__empty",
|
|
5792
|
+
"heatmap-chart__grid": "a8ccharts-O3YMOW-heatmap-chart__grid",
|
|
5793
|
+
"heatmap-chart__grid--compact": "a8ccharts-O3YMOW-heatmap-chart__grid--compact",
|
|
5794
|
+
"heatmap-chart__legend-swatch": "a8ccharts-O3YMOW-heatmap-chart__legend-swatch",
|
|
5795
|
+
"heatmap-chart__row": "a8ccharts-O3YMOW-heatmap-chart__row",
|
|
5796
|
+
"heatmap-chart__row-label": "a8ccharts-O3YMOW-heatmap-chart__row-label"
|
|
5797
|
+
};
|
|
5798
|
+
//#endregion
|
|
5799
|
+
//#region src/charts/heatmap-chart/private/use-heatmap-colors.ts
|
|
5800
|
+
const isPresent = (value) => value !== null && value !== void 0 && !isNaN(value);
|
|
5801
|
+
/**
|
|
5802
|
+
* Get the min and max values from heatmap data, ignoring null/NaN.
|
|
5803
|
+
* @param data - The heatmap columns
|
|
5804
|
+
* @return Tuple of [min, max] values
|
|
5805
|
+
*/
|
|
5806
|
+
const getValueExtent = (data) => {
|
|
5807
|
+
let min = Infinity;
|
|
5808
|
+
let max = -Infinity;
|
|
5809
|
+
for (const column of data) for (const cell of column.data) {
|
|
5810
|
+
if (!isPresent(cell.value)) continue;
|
|
5811
|
+
if (cell.value < min) min = cell.value;
|
|
5812
|
+
if (cell.value > max) max = cell.value;
|
|
5813
|
+
}
|
|
5814
|
+
if (min === Infinity) return [0, 0];
|
|
5815
|
+
return [min, max];
|
|
5816
|
+
};
|
|
5817
|
+
/**
|
|
5818
|
+
* Normalize a value to 0–1 within the extent. A flat extent (min === max) maps to 1.
|
|
5819
|
+
* @param value - The value to normalize
|
|
5820
|
+
* @param extent - Tuple of [min, max] values for the normalization range
|
|
5821
|
+
* @return Normalized value between 0 and 1
|
|
5822
|
+
*/
|
|
5823
|
+
const getNormalizedValue = (value, extent) => {
|
|
5824
|
+
const [min, max] = extent;
|
|
5825
|
+
if (min === max) return 1;
|
|
5826
|
+
return Math.min(1, Math.max(0, (value - min) / (max - min)));
|
|
5827
|
+
};
|
|
5828
|
+
//#endregion
|
|
5829
|
+
//#region src/charts/heatmap-chart/private/build-calendar-data.ts
|
|
5830
|
+
/** Rows that get a weekday label (Mon, Wed, Fri with a Monday week start). */
|
|
5831
|
+
const LABELLED_ROWS = [
|
|
5832
|
+
0,
|
|
5833
|
+
2,
|
|
5834
|
+
4
|
|
5835
|
+
];
|
|
5836
|
+
const toDate = (point) => {
|
|
5837
|
+
if (point.date instanceof Date && !isNaN(point.date.getTime())) return point.date;
|
|
5838
|
+
if (point.dateString) {
|
|
5839
|
+
const parsed = (0, date_fns.parseISO)(point.dateString);
|
|
5840
|
+
if (!isNaN(parsed.getTime())) return parsed;
|
|
5841
|
+
}
|
|
5842
|
+
return null;
|
|
5843
|
+
};
|
|
5844
|
+
const buildCalendarHeatmapData = (series, options = {}) => {
|
|
5845
|
+
const weekStartsOn = options.weekStartsOn ?? 1;
|
|
5846
|
+
const entries = series.map((point) => ({
|
|
5847
|
+
date: toDate(point),
|
|
5848
|
+
value: point.value
|
|
5849
|
+
})).filter((entry) => entry.date !== null);
|
|
5850
|
+
if (!entries.length) return {
|
|
5851
|
+
data: [],
|
|
5852
|
+
rowLabels: []
|
|
5853
|
+
};
|
|
5854
|
+
const valueByDay = /* @__PURE__ */ new Map();
|
|
5855
|
+
let minDate = entries[0].date;
|
|
5856
|
+
let maxDate = entries[0].date;
|
|
5857
|
+
for (const { date, value } of entries) {
|
|
5858
|
+
valueByDay.set((0, date_fns.format)(date, "yyyy-MM-dd"), value);
|
|
5859
|
+
if (date < minDate) minDate = date;
|
|
5860
|
+
if (date > maxDate) maxDate = date;
|
|
5861
|
+
}
|
|
5862
|
+
const gridStart = (0, date_fns.startOfWeek)(minDate, { weekStartsOn });
|
|
5863
|
+
const weekCount = (0, date_fns.differenceInCalendarWeeks)(maxDate, gridStart, { weekStartsOn }) + 1;
|
|
5864
|
+
const rowLabels = Array.from({ length: 7 }, (_, row) => LABELLED_ROWS.includes(row) ? (0, date_fns.format)((0, date_fns.addDays)(gridStart, row), "EEE") : "");
|
|
5865
|
+
const data = [];
|
|
5866
|
+
let previousMonth = -1;
|
|
5867
|
+
for (let week = 0; week < weekCount; week++) {
|
|
5868
|
+
const columnStart = (0, date_fns.addDays)(gridStart, week * 7);
|
|
5869
|
+
const month = columnStart.getMonth();
|
|
5870
|
+
const label = month !== previousMonth ? (0, date_fns.format)(columnStart, "MMM") : "";
|
|
5871
|
+
previousMonth = month;
|
|
5872
|
+
const cells = [];
|
|
5873
|
+
for (let row = 0; row < 7; row++) {
|
|
5874
|
+
const day = (0, date_fns.addDays)(gridStart, week * 7 + row);
|
|
5875
|
+
const key = (0, date_fns.format)(day, "yyyy-MM-dd");
|
|
5876
|
+
cells.push({
|
|
5877
|
+
label: (0, date_fns.format)(day, "EEE, MMM d, yyyy"),
|
|
5878
|
+
value: valueByDay.has(key) ? valueByDay.get(key) : null
|
|
5879
|
+
});
|
|
5880
|
+
}
|
|
5881
|
+
data.push({
|
|
5882
|
+
label,
|
|
5883
|
+
data: cells
|
|
5884
|
+
});
|
|
5885
|
+
}
|
|
5886
|
+
return {
|
|
5887
|
+
data,
|
|
5888
|
+
rowLabels
|
|
5889
|
+
};
|
|
5890
|
+
};
|
|
5891
|
+
//#endregion
|
|
5892
|
+
//#region src/charts/heatmap-chart/private/heatmap-legend.tsx
|
|
5893
|
+
const HeatmapLegend = ({ steps = 5, lessLabel, moreLabel }) => {
|
|
5894
|
+
const context = (0, react$1.useContext)(HeatmapContext);
|
|
5895
|
+
const { legend } = useGlobalChartsTheme();
|
|
5896
|
+
if (!context) return null;
|
|
5897
|
+
const { primaryColorHex } = context;
|
|
5898
|
+
const labelStyle = legend.labelStyles;
|
|
5899
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Stack, {
|
|
5900
|
+
direction: "row",
|
|
5901
|
+
gap: "xs",
|
|
5902
|
+
align: "center",
|
|
5903
|
+
children: [
|
|
5904
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Text$2, {
|
|
5905
|
+
variant: "body-sm",
|
|
5906
|
+
style: labelStyle,
|
|
5907
|
+
children: lessLabel ?? (0, _wordpress_i18n.__)("Less", "jetpack-charts")
|
|
5908
|
+
}),
|
|
5909
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Stack, {
|
|
5910
|
+
direction: "row",
|
|
5911
|
+
gap: "xs",
|
|
5912
|
+
children: Array.from({ length: steps }, (_, index) => {
|
|
5913
|
+
const intensity = steps <= 1 ? 1 : index / (steps - 1);
|
|
5914
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
5915
|
+
"aria-hidden": "true",
|
|
5916
|
+
className: heatmap_chart_module_default["heatmap-chart__legend-swatch"],
|
|
5917
|
+
style: {
|
|
5918
|
+
"--heatmap-primary": primaryColorHex,
|
|
5919
|
+
"--intensity": intensity
|
|
5920
|
+
}
|
|
5921
|
+
}, index);
|
|
5922
|
+
})
|
|
5923
|
+
}),
|
|
5924
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Text$2, {
|
|
5925
|
+
variant: "body-sm",
|
|
5926
|
+
style: labelStyle,
|
|
5927
|
+
children: moreLabel ?? (0, _wordpress_i18n.__)("More", "jetpack-charts")
|
|
5928
|
+
})
|
|
5929
|
+
]
|
|
5930
|
+
});
|
|
5931
|
+
};
|
|
5932
|
+
//#endregion
|
|
5933
|
+
//#region src/charts/heatmap-chart/heatmap-chart.tsx
|
|
5934
|
+
const HeatmapContext = (0, react$1.createContext)(null);
|
|
5935
|
+
const CELL_MIX_FLOOR = .15;
|
|
5936
|
+
const HeatmapChartInternal = ({ data, chartId: providedChartId, width = 0, height = 0, className, compact = false, showValues, rowLabels = [], primaryColor, gap = "md", withTooltips = false, renderTooltip, children }) => {
|
|
5937
|
+
const chartId = useChartId(providedChartId);
|
|
5938
|
+
const { getElementStyles, theme } = useGlobalChartsContext();
|
|
5939
|
+
const { heatmapChart: heatmapChartSettings } = theme;
|
|
5940
|
+
const { nonLegendChildren } = useChartChildren(children, "HeatmapChart");
|
|
5941
|
+
const [selectedIndex, setSelectedIndex] = (0, react$1.useState)();
|
|
5942
|
+
const { tooltipOpen, tooltipLeft, tooltipTop, tooltipData, showTooltip, hideTooltip } = (0, _visx_tooltip.useTooltip)();
|
|
5943
|
+
const { containerRef, containerBounds, TooltipInPortal } = (0, _visx_tooltip.useTooltipInPortal)({
|
|
5944
|
+
detectBounds: true,
|
|
5945
|
+
scroll: true
|
|
5946
|
+
});
|
|
5947
|
+
const containerBoundsRef = (0, react$1.useRef)(containerBounds);
|
|
5948
|
+
containerBoundsRef.current = containerBounds;
|
|
5949
|
+
const { color: primaryColorHex } = getElementStyles({
|
|
5950
|
+
index: 0,
|
|
5951
|
+
overrideColor: primaryColor || heatmapChartSettings.primaryColor
|
|
5952
|
+
});
|
|
5953
|
+
const primaryHex = normalizeColorToHex(primaryColorHex);
|
|
5954
|
+
const cellHasLightText = (intensity) => isValidHexColor(primaryHex) && prefersLightText(lightenHexColor(primaryHex, 1 - (CELL_MIX_FLOOR + (1 - CELL_MIX_FLOOR) * intensity)));
|
|
5955
|
+
const extent = (0, react$1.useMemo)(() => getValueExtent(data), [data]);
|
|
5956
|
+
const heatmapContext = (0, react$1.useMemo)(() => ({
|
|
5957
|
+
extent,
|
|
5958
|
+
primaryColorHex
|
|
5959
|
+
}), [extent, primaryColorHex]);
|
|
5960
|
+
const columns = data.length;
|
|
5961
|
+
const rows = Math.max(0, ...data.map((column) => column.data.length));
|
|
5962
|
+
const { compactCellGap, compactCellSize } = heatmapChartSettings;
|
|
5963
|
+
const drawValues = showValues ?? !compact;
|
|
5964
|
+
const buildTooltipData = (0, react$1.useCallback)((columnIndex, rowIndex) => {
|
|
5965
|
+
const cell = data[columnIndex]?.data[rowIndex];
|
|
5966
|
+
return {
|
|
5967
|
+
value: cell?.value ?? null,
|
|
5968
|
+
rowLabel: rowLabels[rowIndex],
|
|
5969
|
+
columnLabel: data[columnIndex]?.label,
|
|
5970
|
+
cellLabel: cell?.label,
|
|
5971
|
+
row: rowIndex,
|
|
5972
|
+
column: columnIndex
|
|
5973
|
+
};
|
|
5974
|
+
}, [data, rowLabels]);
|
|
5975
|
+
const onChartBlur = (0, react$1.useCallback)(() => {
|
|
5976
|
+
setSelectedIndex(void 0);
|
|
5977
|
+
hideTooltip();
|
|
5978
|
+
}, [hideTooltip]);
|
|
5979
|
+
const onChartKeyDown = (0, react$1.useCallback)((event) => {
|
|
5980
|
+
if (![
|
|
5981
|
+
"ArrowLeft",
|
|
5982
|
+
"ArrowRight",
|
|
5983
|
+
"ArrowUp",
|
|
5984
|
+
"ArrowDown",
|
|
5985
|
+
"Escape",
|
|
5986
|
+
"Tab"
|
|
5987
|
+
].includes(event.key)) return;
|
|
5988
|
+
if (event.key === "Tab" || event.key === "Escape") {
|
|
5989
|
+
setSelectedIndex(void 0);
|
|
5990
|
+
hideTooltip();
|
|
5991
|
+
return;
|
|
5992
|
+
}
|
|
5993
|
+
event.preventDefault();
|
|
5994
|
+
if (selectedIndex === void 0) {
|
|
5995
|
+
setSelectedIndex(0);
|
|
5996
|
+
return;
|
|
5997
|
+
}
|
|
5998
|
+
let col = Math.floor(selectedIndex / rows);
|
|
5999
|
+
let row = selectedIndex % rows;
|
|
6000
|
+
if (event.key === "ArrowRight") col = Math.min(col + 1, columns - 1);
|
|
6001
|
+
else if (event.key === "ArrowLeft") col = Math.max(col - 1, 0);
|
|
6002
|
+
else if (event.key === "ArrowDown") row = Math.min(row + 1, rows - 1);
|
|
6003
|
+
else if (event.key === "ArrowUp") row = Math.max(row - 1, 0);
|
|
6004
|
+
setSelectedIndex(col * rows + row);
|
|
6005
|
+
}, [
|
|
6006
|
+
rows,
|
|
6007
|
+
columns,
|
|
6008
|
+
selectedIndex,
|
|
6009
|
+
hideTooltip
|
|
6010
|
+
]);
|
|
6011
|
+
const handleCellMouseMove = (0, react$1.useCallback)((event) => {
|
|
6012
|
+
if (!withTooltips) return;
|
|
6013
|
+
const target = event.currentTarget;
|
|
6014
|
+
const columnIndex = Number(target.dataset.column);
|
|
6015
|
+
const rowIndex = Number(target.dataset.row);
|
|
6016
|
+
const bounds = containerBoundsRef.current;
|
|
6017
|
+
showTooltip({
|
|
6018
|
+
tooltipLeft: event.clientX - bounds.left,
|
|
6019
|
+
tooltipTop: event.clientY - bounds.top,
|
|
6020
|
+
tooltipData: buildTooltipData(columnIndex, rowIndex)
|
|
6021
|
+
});
|
|
6022
|
+
}, [
|
|
6023
|
+
withTooltips,
|
|
6024
|
+
showTooltip,
|
|
6025
|
+
buildTooltipData
|
|
6026
|
+
]);
|
|
6027
|
+
const handleCellMouseLeave = (0, react$1.useCallback)(() => {
|
|
6028
|
+
if (withTooltips && selectedIndex === void 0) hideTooltip();
|
|
6029
|
+
}, [
|
|
6030
|
+
withTooltips,
|
|
6031
|
+
selectedIndex,
|
|
6032
|
+
hideTooltip
|
|
6033
|
+
]);
|
|
6034
|
+
(0, react$1.useEffect)(() => {
|
|
6035
|
+
if (!withTooltips || selectedIndex === void 0) return;
|
|
6036
|
+
const col = Math.floor(selectedIndex / rows);
|
|
6037
|
+
const row = selectedIndex % rows;
|
|
6038
|
+
const rect = (typeof document !== "undefined" ? document.getElementById(`${chartId}-cell-${col}-${row}`) : null)?.getBoundingClientRect();
|
|
6039
|
+
const bounds = containerBoundsRef.current;
|
|
6040
|
+
showTooltip({
|
|
6041
|
+
tooltipLeft: rect ? rect.left + rect.width / 2 - bounds.left : 0,
|
|
6042
|
+
tooltipTop: rect ? rect.top + rect.height / 2 - bounds.top : 0,
|
|
6043
|
+
tooltipData: buildTooltipData(col, row)
|
|
6044
|
+
});
|
|
6045
|
+
}, [
|
|
6046
|
+
selectedIndex,
|
|
6047
|
+
withTooltips,
|
|
6048
|
+
rows,
|
|
6049
|
+
chartId,
|
|
6050
|
+
buildTooltipData,
|
|
6051
|
+
showTooltip
|
|
6052
|
+
]);
|
|
6053
|
+
const defaultRenderTooltip = (0, react$1.useCallback)((info) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("strong", { children: info.cellLabel || `${info.columnLabel ?? ""} ${info.rowLabel ?? ""}`.trim() }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: info.value === null ? (0, _wordpress_i18n.__)("No data", "jetpack-charts") : (0, _automattic_number_formatters.formatNumber)(info.value) })] }), []);
|
|
6054
|
+
if (!columns || !rows) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Center, {
|
|
6055
|
+
className: (0, clsx.default)("heatmap-chart", heatmap_chart_module_default["heatmap-chart"], className),
|
|
6056
|
+
style: {
|
|
6057
|
+
width: width || void 0,
|
|
6058
|
+
height: height || void 0
|
|
6059
|
+
},
|
|
6060
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6061
|
+
className: heatmap_chart_module_default["heatmap-chart__empty"],
|
|
6062
|
+
children: (0, _wordpress_i18n.__)("No data available", "jetpack-charts")
|
|
6063
|
+
})
|
|
6064
|
+
});
|
|
6065
|
+
const trackSize = compact ? "var(--heatmap-cell-size)" : "minmax(0, 1fr)";
|
|
6066
|
+
const gridStyle = {
|
|
6067
|
+
"--heatmap-primary": primaryColorHex,
|
|
6068
|
+
gridTemplateColumns: `auto repeat(${columns}, ${trackSize})`,
|
|
6069
|
+
gridTemplateRows: `auto repeat(${rows}, ${trackSize})`
|
|
6070
|
+
};
|
|
6071
|
+
if (compact) {
|
|
6072
|
+
gridStyle["--heatmap-cell-gap"] = `${compactCellGap}px`;
|
|
6073
|
+
gridStyle["--heatmap-cell-size"] = `${compactCellSize}px`;
|
|
6074
|
+
}
|
|
6075
|
+
const activeDescendant = selectedIndex !== void 0 ? `${chartId}-cell-${Math.floor(selectedIndex / rows)}-${selectedIndex % rows}` : void 0;
|
|
6076
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HeatmapContext.Provider, {
|
|
6077
|
+
value: heatmapContext,
|
|
6078
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SingleChartContext.Provider, {
|
|
6079
|
+
value: { chartId },
|
|
6080
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(ChartLayout, {
|
|
6081
|
+
legendPosition: "bottom",
|
|
6082
|
+
legendChildren: [],
|
|
6083
|
+
trailingContent: nonLegendChildren,
|
|
6084
|
+
gap,
|
|
6085
|
+
className: (0, clsx.default)("heatmap-chart", heatmap_chart_module_default["heatmap-chart"], className),
|
|
6086
|
+
style: {
|
|
6087
|
+
width: width || void 0,
|
|
6088
|
+
height: height || void 0
|
|
6089
|
+
},
|
|
6090
|
+
"data-chart-id": `heatmap-chart-${chartId}`,
|
|
6091
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6092
|
+
ref: containerRef,
|
|
6093
|
+
role: "grid",
|
|
6094
|
+
"aria-label": (0, _wordpress_i18n.__)("Heatmap chart", "jetpack-charts"),
|
|
6095
|
+
"aria-rowcount": rows,
|
|
6096
|
+
"aria-colcount": columns,
|
|
6097
|
+
"aria-activedescendant": activeDescendant,
|
|
6098
|
+
tabIndex: 0,
|
|
6099
|
+
onBlur: onChartBlur,
|
|
6100
|
+
onKeyDown: onChartKeyDown,
|
|
6101
|
+
className: (0, clsx.default)(heatmap_chart_module_default["heatmap-chart__grid"], { [heatmap_chart_module_default["heatmap-chart__grid--compact"]]: compact }),
|
|
6102
|
+
style: gridStyle,
|
|
6103
|
+
children: [
|
|
6104
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { "aria-hidden": "true" }),
|
|
6105
|
+
data.map((column, columnIndex) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6106
|
+
"aria-hidden": "true",
|
|
6107
|
+
className: heatmap_chart_module_default["heatmap-chart__col-label"],
|
|
6108
|
+
children: column.label
|
|
6109
|
+
}, `col-${columnIndex}`)),
|
|
6110
|
+
Array.from({ length: rows }).map((_row, rowIndex) => {
|
|
6111
|
+
const labelVisible = !compact || rowIndex % 2 === 0;
|
|
6112
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6113
|
+
role: "row",
|
|
6114
|
+
"aria-rowindex": rowIndex + 1,
|
|
6115
|
+
className: heatmap_chart_module_default["heatmap-chart__row"],
|
|
6116
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6117
|
+
"aria-hidden": "true",
|
|
6118
|
+
className: heatmap_chart_module_default["heatmap-chart__row-label"],
|
|
6119
|
+
children: labelVisible ? rowLabels[rowIndex] ?? "" : ""
|
|
6120
|
+
}), data.map((column, columnIndex) => {
|
|
6121
|
+
const value = column.data[rowIndex]?.value ?? null;
|
|
6122
|
+
const present = isPresent(value);
|
|
6123
|
+
const normalized = present ? getNormalizedValue(value, extent) : 0;
|
|
6124
|
+
const flatIndex = columnIndex * rows + rowIndex;
|
|
6125
|
+
const info = buildTooltipData(columnIndex, rowIndex);
|
|
6126
|
+
const accessibleLabel = `${info.cellLabel || `${info.columnLabel ?? ""} ${info.rowLabel ?? ""}`.trim()}: ${info.value === null ? (0, _wordpress_i18n.__)("No data", "jetpack-charts") : (0, _automattic_number_formatters.formatNumber)(info.value)}`;
|
|
6127
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6128
|
+
id: `${chartId}-cell-${columnIndex}-${rowIndex}`,
|
|
6129
|
+
role: "gridcell",
|
|
6130
|
+
tabIndex: -1,
|
|
6131
|
+
"aria-colindex": columnIndex + 1,
|
|
6132
|
+
"aria-label": accessibleLabel,
|
|
6133
|
+
"data-column": columnIndex,
|
|
6134
|
+
"data-row": rowIndex,
|
|
6135
|
+
className: (0, clsx.default)(heatmap_chart_module_default["heatmap-chart__cell"], {
|
|
6136
|
+
[heatmap_chart_module_default["heatmap-chart__cell--filled"]]: present,
|
|
6137
|
+
[heatmap_chart_module_default["heatmap-chart__cell--strong"]]: present && cellHasLightText(normalized),
|
|
6138
|
+
[heatmap_chart_module_default["heatmap-chart__cell--selected"]]: selectedIndex === flatIndex
|
|
6139
|
+
}),
|
|
6140
|
+
style: present ? { "--intensity": normalized } : void 0,
|
|
6141
|
+
onMouseMove: handleCellMouseMove,
|
|
6142
|
+
onMouseLeave: handleCellMouseLeave,
|
|
6143
|
+
children: drawValues && present && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6144
|
+
className: heatmap_chart_module_default["heatmap-chart__cell-value"],
|
|
6145
|
+
children: (0, _automattic_number_formatters.formatNumberCompact)(value)
|
|
6146
|
+
})
|
|
6147
|
+
}, `cell-${columnIndex}-${rowIndex}`);
|
|
6148
|
+
})]
|
|
6149
|
+
}, `row-${rowIndex}`);
|
|
6150
|
+
})
|
|
6151
|
+
]
|
|
6152
|
+
}), withTooltips && tooltipOpen && tooltipData && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TooltipInPortal, {
|
|
6153
|
+
top: tooltipTop,
|
|
6154
|
+
left: tooltipLeft,
|
|
6155
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6156
|
+
role: "tooltip",
|
|
6157
|
+
tabIndex: -1,
|
|
6158
|
+
children: (renderTooltip ?? defaultRenderTooltip)(tooltipData)
|
|
6159
|
+
})
|
|
6160
|
+
})]
|
|
6161
|
+
})
|
|
6162
|
+
})
|
|
6163
|
+
});
|
|
6164
|
+
};
|
|
6165
|
+
const HeatmapChartWithProvider = (props) => {
|
|
6166
|
+
if ((0, react$1.useContext)(GlobalChartsContext)) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HeatmapChartInternal, { ...props });
|
|
6167
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GlobalChartsProvider, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HeatmapChartInternal, { ...props }) });
|
|
6168
|
+
};
|
|
6169
|
+
HeatmapChartWithProvider.displayName = "HeatmapChart";
|
|
6170
|
+
const HeatmapChart = attachSubComponents(HeatmapChartWithProvider, { Legend: HeatmapLegend });
|
|
6171
|
+
const HeatmapChartResponsiveInner = (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HeatmapChartWithProvider, {
|
|
6172
|
+
...props,
|
|
6173
|
+
width: void 0,
|
|
6174
|
+
height: void 0
|
|
6175
|
+
});
|
|
6176
|
+
HeatmapChartResponsiveInner.displayName = "HeatmapChart";
|
|
6177
|
+
const HeatmapChartResponsive = attachSubComponents(withResponsive(HeatmapChartResponsiveInner), { Legend: HeatmapLegend });
|
|
6178
|
+
//#endregion
|
|
6179
|
+
//#region ../../../node_modules/.pnpm/@wordpress+warning@3.50.0/node_modules/@wordpress/warning/build-module/utils.mjs
|
|
5707
6180
|
var logged = /* @__PURE__ */ new Set();
|
|
5708
6181
|
//#endregion
|
|
5709
|
-
//#region ../../../node_modules/.pnpm/@wordpress+warning@3.
|
|
6182
|
+
//#region ../../../node_modules/.pnpm/@wordpress+warning@3.50.0/node_modules/@wordpress/warning/build-module/index.mjs
|
|
5710
6183
|
function isDev() {
|
|
5711
6184
|
return globalThis.SCRIPT_DEBUG === true;
|
|
5712
6185
|
}
|
|
@@ -5720,7 +6193,7 @@ function warning(message) {
|
|
|
5720
6193
|
logged.add(message);
|
|
5721
6194
|
}
|
|
5722
6195
|
//#endregion
|
|
5723
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@
|
|
6196
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@36.1.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/context/constants.mjs
|
|
5724
6197
|
var COMPONENT_NAMESPACE = "data-wp-component";
|
|
5725
6198
|
var CONNECTED_NAMESPACE = "data-wp-c16t";
|
|
5726
6199
|
var CONNECT_STATIC_NAMESPACE = "__contextSystemKey__";
|
|
@@ -6158,14 +6631,14 @@ function memize(fn, options) {
|
|
|
6158
6631
|
return memoized;
|
|
6159
6632
|
}
|
|
6160
6633
|
//#endregion
|
|
6161
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@
|
|
6634
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@36.1.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/context/get-styled-class-name-from-key.mjs
|
|
6162
6635
|
var import_dist = require_dist();
|
|
6163
6636
|
function getStyledClassName(namespace) {
|
|
6164
6637
|
return `components-${(0, import_dist.paramCase)(namespace)}`;
|
|
6165
6638
|
}
|
|
6166
6639
|
var getStyledClassNameFromKey = memize(getStyledClassName);
|
|
6167
6640
|
//#endregion
|
|
6168
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@
|
|
6641
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@36.1.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/context/context-connect.mjs
|
|
6169
6642
|
function contextConnect(Component, namespace) {
|
|
6170
6643
|
return _contextConnect(Component, namespace, { forwardsRef: true });
|
|
6171
6644
|
}
|
|
@@ -6250,7 +6723,7 @@ function isPlainObject(o) {
|
|
|
6250
6723
|
return true;
|
|
6251
6724
|
}
|
|
6252
6725
|
//#endregion
|
|
6253
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@
|
|
6726
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@36.1.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/utils/hooks/use-update-effect.mjs
|
|
6254
6727
|
function useUpdateEffect(effect, deps) {
|
|
6255
6728
|
const mountedRef = (0, react$1.useRef)(false);
|
|
6256
6729
|
(0, react$1.useEffect)(() => {
|
|
@@ -6263,7 +6736,7 @@ function useUpdateEffect(effect, deps) {
|
|
|
6263
6736
|
}
|
|
6264
6737
|
var use_update_effect_default = useUpdateEffect;
|
|
6265
6738
|
//#endregion
|
|
6266
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@
|
|
6739
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@36.1.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/context/context-system-provider.mjs
|
|
6267
6740
|
var import_es6 = /* @__PURE__ */ __toESM(require_es6(), 1);
|
|
6268
6741
|
var ComponentsContext = (0, react$1.createContext)(
|
|
6269
6742
|
/** @type {Record<string, any>} */
|
|
@@ -6290,7 +6763,7 @@ var BaseContextSystemProvider = ({ children, value }) => {
|
|
|
6290
6763
|
};
|
|
6291
6764
|
(0, react$1.memo)(BaseContextSystemProvider);
|
|
6292
6765
|
//#endregion
|
|
6293
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@
|
|
6766
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@36.1.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/context/utils.mjs
|
|
6294
6767
|
function getNamespace(componentName) {
|
|
6295
6768
|
return { [COMPONENT_NAMESPACE]: componentName };
|
|
6296
6769
|
}
|
|
@@ -7908,7 +8381,7 @@ _createEmotion.css;
|
|
|
7908
8381
|
_createEmotion.sheet;
|
|
7909
8382
|
_createEmotion.cache;
|
|
7910
8383
|
//#endregion
|
|
7911
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@
|
|
8384
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@36.1.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/utils/hooks/use-cx.mjs
|
|
7912
8385
|
var isSerializedStyles = (o) => typeof o !== "undefined" && o !== null && ["name", "styles"].every((p) => typeof o[p] !== "undefined");
|
|
7913
8386
|
var useCx = () => {
|
|
7914
8387
|
const cache = __unsafe_useEmotionCache();
|
|
@@ -7924,7 +8397,7 @@ var useCx = () => {
|
|
|
7924
8397
|
}, [cache]);
|
|
7925
8398
|
};
|
|
7926
8399
|
//#endregion
|
|
7927
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@
|
|
8400
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@36.1.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/context/use-context-system.mjs
|
|
7928
8401
|
function useContextSystem(props, namespace) {
|
|
7929
8402
|
const contextSystemProps = useComponentsContext();
|
|
7930
8403
|
if (typeof namespace === "undefined") globalThis.SCRIPT_DEBUG === true && warning("useContextSystem: Please provide a namespace");
|
|
@@ -7990,7 +8463,7 @@ var Insertion = function Insertion(_ref) {
|
|
|
7990
8463
|
return null;
|
|
7991
8464
|
};
|
|
7992
8465
|
//#endregion
|
|
7993
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@
|
|
8466
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@36.1.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/view/component.mjs
|
|
7994
8467
|
var PolymorphicDiv = /* @__PURE__ */ function createStyled(tag, options) {
|
|
7995
8468
|
var isReal = tag.__emotion_real === tag;
|
|
7996
8469
|
var baseTag = isReal && tag.__emotion_base || tag;
|
|
@@ -8072,7 +8545,7 @@ function UnforwardedView({ as, ...restProps }, ref) {
|
|
|
8072
8545
|
}
|
|
8073
8546
|
var component_default$1 = Object.assign((0, react$1.forwardRef)(UnforwardedView), { selector: ".components-view" });
|
|
8074
8547
|
//#endregion
|
|
8075
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@
|
|
8548
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@36.1.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/grid/utils.mjs
|
|
8076
8549
|
var ALIGNMENTS = {
|
|
8077
8550
|
bottom: {
|
|
8078
8551
|
alignItems: "flex-end",
|
|
@@ -8120,7 +8593,7 @@ function getAlignmentProps(alignment) {
|
|
|
8120
8593
|
return alignment ? ALIGNMENTS[alignment] : {};
|
|
8121
8594
|
}
|
|
8122
8595
|
//#endregion
|
|
8123
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@
|
|
8596
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@36.1.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/utils/use-responsive-value.mjs
|
|
8124
8597
|
var breakpoints = [
|
|
8125
8598
|
"40em",
|
|
8126
8599
|
"52em",
|
|
@@ -8154,7 +8627,7 @@ function useResponsiveValue(values, options = {}) {
|
|
|
8154
8627
|
return array[index >= array.length ? array.length - 1 : index];
|
|
8155
8628
|
}
|
|
8156
8629
|
//#endregion
|
|
8157
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@
|
|
8630
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@36.1.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/utils/colors-values.mjs
|
|
8158
8631
|
var white = "#fff";
|
|
8159
8632
|
var GRAY = {
|
|
8160
8633
|
900: "#1e1e1e",
|
|
@@ -8181,21 +8654,21 @@ var THEME = {
|
|
|
8181
8654
|
accentDarker10: `var(--wp-components-color-accent-darker-10, var(--wp-admin-theme-color-darker-10, #2145e6))`,
|
|
8182
8655
|
accentDarker20: `var(--wp-components-color-accent-darker-20, var(--wp-admin-theme-color-darker-20, #183ad6))`,
|
|
8183
8656
|
/** Used when placing text on the accent color. */
|
|
8184
|
-
accentInverted: `var(--wp-components-color-accent-inverted,
|
|
8185
|
-
background: `var(--wp-components-color-background,
|
|
8186
|
-
foreground: `var(--wp-components-color-foreground,
|
|
8657
|
+
accentInverted: `var(--wp-components-color-accent-inverted, var(--wpds-color-foreground-interactive-brand-strong, #fff))`,
|
|
8658
|
+
background: `var(--wp-components-color-background, var(--wpds-color-background-surface-neutral-strong, #fff))`,
|
|
8659
|
+
foreground: `var(--wp-components-color-foreground, var(--wpds-color-foreground-content-neutral, #1e1e1e))`,
|
|
8187
8660
|
/** Used when placing text on the foreground color. */
|
|
8188
|
-
foregroundInverted: `var(--wp-components-color-foreground-inverted,
|
|
8661
|
+
foregroundInverted: `var(--wp-components-color-foreground-inverted, var(--wpds-color-background-surface-neutral, #fcfcfc))`,
|
|
8189
8662
|
gray: {
|
|
8190
8663
|
/** @deprecated Use `COLORS.theme.foreground` instead. */
|
|
8191
|
-
900: `var(--wp-components-color-foreground,
|
|
8192
|
-
800: `var(--wp-components-color-gray-800,
|
|
8193
|
-
700: `var(--wp-components-color-gray-700,
|
|
8194
|
-
600: `var(--wp-components-color-gray-600,
|
|
8195
|
-
400: `var(--wp-components-color-gray-400,
|
|
8196
|
-
300: `var(--wp-components-color-gray-300,
|
|
8197
|
-
200: `var(--wp-components-color-gray-200,
|
|
8198
|
-
100: `var(--wp-components-color-gray-100,
|
|
8664
|
+
900: `var(--wp-components-color-foreground, var(--wpds-color-foreground-content-neutral, #1e1e1e))`,
|
|
8665
|
+
800: `var(--wp-components-color-gray-800, var(--wpds-color-foreground-content-neutral, #1e1e1e))`,
|
|
8666
|
+
700: `var(--wp-components-color-gray-700, var(--wpds-color-foreground-content-neutral-weak, #707070))`,
|
|
8667
|
+
600: `var(--wp-components-color-gray-600, var(--wpds-color-stroke-interactive-neutral, #8d8d8d))`,
|
|
8668
|
+
400: `var(--wp-components-color-gray-400, var(--wpds-color-stroke-interactive-neutral, #8d8d8d))`,
|
|
8669
|
+
300: `var(--wp-components-color-gray-300, var(--wpds-color-stroke-surface-neutral, #dbdbdb))`,
|
|
8670
|
+
200: `var(--wp-components-color-gray-200, var(--wpds-color-stroke-surface-neutral, #dbdbdb))`,
|
|
8671
|
+
100: `var(--wp-components-color-gray-100, var(--wpds-color-background-surface-neutral, #fcfcfc))`
|
|
8199
8672
|
}
|
|
8200
8673
|
};
|
|
8201
8674
|
var UI = {
|
|
@@ -8233,7 +8706,7 @@ var COLORS = Object.freeze({
|
|
|
8233
8706
|
ui: UI
|
|
8234
8707
|
});
|
|
8235
8708
|
//#endregion
|
|
8236
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@
|
|
8709
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@36.1.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/utils/config-values.mjs
|
|
8237
8710
|
var CONTROL_HEIGHT = "36px";
|
|
8238
8711
|
var CONTROL_PROPS = {
|
|
8239
8712
|
controlPaddingX: 12,
|
|
@@ -8298,7 +8771,7 @@ var config_values_default = Object.assign({}, CONTROL_PROPS, {
|
|
|
8298
8771
|
transitionTimingFunctionControl: "cubic-bezier(0.12, 0.8, 0.32, 1)"
|
|
8299
8772
|
});
|
|
8300
8773
|
//#endregion
|
|
8301
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@
|
|
8774
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@36.1.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/grid/hook.mjs
|
|
8302
8775
|
function useGrid(props) {
|
|
8303
8776
|
const { align, alignment, className, columnGap, columns = 2, gap = 3, isInline = false, justify, rowGap, rows, templateColumns, templateRows, ...otherProps } = useContextSystem(props, "Grid");
|
|
8304
8777
|
const column = useResponsiveValue(Array.isArray(columns) ? columns : [columns]);
|
|
@@ -8339,7 +8812,7 @@ function useGrid(props) {
|
|
|
8339
8812
|
};
|
|
8340
8813
|
}
|
|
8341
8814
|
//#endregion
|
|
8342
|
-
//#region ../../../node_modules/.pnpm/@wordpress+components@
|
|
8815
|
+
//#region ../../../node_modules/.pnpm/@wordpress+components@36.1.0_@types+react@18.3.28_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@wordpress/components/build-module/grid/component.mjs
|
|
8343
8816
|
function UnconnectedGrid(props, forwardedRef) {
|
|
8344
8817
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(component_default$1, {
|
|
8345
8818
|
...useGrid(props),
|
|
@@ -9479,6 +9952,8 @@ exports.GeoChart = GeoChartResponsive;
|
|
|
9479
9952
|
exports.GeoChartUnresponsive = GeoChartWithProvider;
|
|
9480
9953
|
exports.GlobalChartsContext = GlobalChartsContext;
|
|
9481
9954
|
exports.GlobalChartsProvider = GlobalChartsProvider;
|
|
9955
|
+
exports.HeatmapChart = HeatmapChartResponsive;
|
|
9956
|
+
exports.HeatmapChartUnresponsive = HeatmapChart;
|
|
9482
9957
|
exports.LeaderboardChart = LeaderboardChartResponsive;
|
|
9483
9958
|
exports.LeaderboardChartUnresponsive = LeaderboardChart;
|
|
9484
9959
|
exports.Legend = Legend;
|
|
@@ -9492,6 +9967,7 @@ exports.Sparkline = Sparkline;
|
|
|
9492
9967
|
exports.SparklineUnresponsive = SparklineUnresponsive;
|
|
9493
9968
|
exports.ThemeProvider = GlobalChartsProvider;
|
|
9494
9969
|
exports.TrendIndicator = TrendIndicator;
|
|
9970
|
+
exports.buildCalendarHeatmapData = buildCalendarHeatmapData;
|
|
9495
9971
|
exports.defaultTheme = defaultTheme;
|
|
9496
9972
|
exports.formatMetricValue = formatMetricValue;
|
|
9497
9973
|
exports.formatPercentage = formatPercentage;
|
|
@@ -9504,6 +9980,8 @@ exports.normalizeColorToHex = normalizeColorToHex;
|
|
|
9504
9980
|
exports.parseAsLocalDate = parseAsLocalDate;
|
|
9505
9981
|
exports.parseHslString = parseHslString;
|
|
9506
9982
|
exports.parseRgbString = parseRgbString;
|
|
9983
|
+
exports.prefersLightText = prefersLightText;
|
|
9984
|
+
exports.relativeLuminance = relativeLuminance;
|
|
9507
9985
|
exports.useChartLegendItems = useChartLegendItems;
|
|
9508
9986
|
exports.useGlobalChartsContext = useGlobalChartsContext;
|
|
9509
9987
|
exports.useGlobalChartsTheme = useGlobalChartsTheme;
|