@sproutsocial/seeds-react-data-viz 0.3.0 → 0.4.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/README.md +2 -0
- package/dist/esm/index.js +449 -50
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.mts +143 -19
- package/dist/index.d.ts +143 -19
- package/dist/index.js +456 -50
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -51,18 +51,25 @@ __export(index_exports, {
|
|
|
51
51
|
LineChart: () => LineChart,
|
|
52
52
|
NetworkColorBox: () => NetworkColorBox,
|
|
53
53
|
TIME_SERIES_CHART_HEIGHT: () => TIME_SERIES_CHART_HEIGHT,
|
|
54
|
+
VERTICAL_BAR_CHART_DEFAULT_SERIES_LIMIT: () => VERTICAL_BAR_CHART_DEFAULT_SERIES_LIMIT,
|
|
54
55
|
areaChartOptions: () => areaChartOptions,
|
|
55
56
|
areaChartStyles: () => areaChartStyles,
|
|
56
57
|
baseChartOptions: () => baseChartOptions,
|
|
57
58
|
baseChartStyles: () => baseChartStyles,
|
|
59
|
+
columnChartOptions: () => columnChartOptions,
|
|
58
60
|
donutChartOptions: () => donutChartOptions,
|
|
59
61
|
donutChartStyles: () => donutChartStyles,
|
|
60
62
|
generateChartTooltipPortalId: () => generateChartTooltipPortalId,
|
|
61
63
|
getDatavizColor: () => getDatavizColor,
|
|
62
64
|
getDatavizColorWithAlpha: () => getDatavizColorWithAlpha,
|
|
63
65
|
getDatavizOpacity: () => getDatavizOpacity,
|
|
66
|
+
getStorybookCategoricalData: () => getStorybookCategoricalData,
|
|
67
|
+
getStorybookSparseTimelineData: () => getStorybookSparseTimelineData,
|
|
68
|
+
isCategoricalHourData: () => isCategoricalHourData,
|
|
69
|
+
isHourlyTimeData: () => isHourlyTimeData,
|
|
64
70
|
lineChartOptions: () => lineChartOptions,
|
|
65
71
|
lineChartStyles: () => lineChartStyles,
|
|
72
|
+
timeSeriesChartOptions: () => timeSeriesChartOptions,
|
|
66
73
|
timeSeriesChartStyles: () => timeSeriesChartStyles,
|
|
67
74
|
transformDataToSeries: () => transformDataToSeries,
|
|
68
75
|
transformTimeSeriesTooltipData: () => transformTimeSeriesTooltipData,
|
|
@@ -611,7 +618,12 @@ var ChartXAnnotationMarkerPortal = (0, import_react14.memo)(
|
|
|
611
618
|
);
|
|
612
619
|
|
|
613
620
|
// src/helpers/transformDataToSeries.ts
|
|
614
|
-
var transformDataToSeries = ({
|
|
621
|
+
var transformDataToSeries = ({
|
|
622
|
+
data
|
|
623
|
+
}, type) => {
|
|
624
|
+
const hasCategoricalData = data.some(
|
|
625
|
+
(series) => series.points.some((point) => typeof point.x === "string")
|
|
626
|
+
);
|
|
615
627
|
return data.map((dataItem, dataIndex) => {
|
|
616
628
|
const points = dataItem.points || [];
|
|
617
629
|
const dataPoints = points.map((point, pointsIndex) => {
|
|
@@ -628,12 +640,14 @@ var transformDataToSeries = ({ data }, type) => {
|
|
|
628
640
|
enableMarker = true;
|
|
629
641
|
}
|
|
630
642
|
return {
|
|
631
|
-
x: point.x,
|
|
643
|
+
x: hasCategoricalData ? pointsIndex : point.x,
|
|
632
644
|
y: point.y,
|
|
633
645
|
marker: {
|
|
634
646
|
enabled: enableMarker ? enableMarker : void 0,
|
|
635
647
|
symbol: enableMarker ? "circle" : void 0
|
|
636
|
-
}
|
|
648
|
+
},
|
|
649
|
+
// For categorical data, store the original category name
|
|
650
|
+
...hasCategoricalData && { name: point.x }
|
|
637
651
|
};
|
|
638
652
|
});
|
|
639
653
|
return {
|
|
@@ -663,6 +677,42 @@ var transformTimeSeriesTooltipData = ({
|
|
|
663
677
|
});
|
|
664
678
|
};
|
|
665
679
|
|
|
680
|
+
// src/helpers/yAxisLabelFormatter.ts
|
|
681
|
+
var import_seeds_react_duration2 = require("@sproutsocial/seeds-react-duration");
|
|
682
|
+
var import_seeds_react_numeral2 = require("@sproutsocial/seeds-react-numeral");
|
|
683
|
+
var yAxisLabelFormatter = ({
|
|
684
|
+
numberLocale,
|
|
685
|
+
textLocale,
|
|
686
|
+
tickPositions,
|
|
687
|
+
value,
|
|
688
|
+
currency = "USD",
|
|
689
|
+
numberFormat = "decimal"
|
|
690
|
+
}) => {
|
|
691
|
+
const numberValue = Number(value);
|
|
692
|
+
if (numberValue === 0) {
|
|
693
|
+
return (0, import_seeds_react_numeral2.formatNumeral)({
|
|
694
|
+
locale: numberLocale,
|
|
695
|
+
number: numberValue
|
|
696
|
+
});
|
|
697
|
+
}
|
|
698
|
+
if (numberFormat === "duration") {
|
|
699
|
+
return (0, import_seeds_react_duration2.formatDuration)({
|
|
700
|
+
display: "narrow",
|
|
701
|
+
locale: textLocale,
|
|
702
|
+
milliseconds: numberValue
|
|
703
|
+
});
|
|
704
|
+
}
|
|
705
|
+
const maxValue = tickPositions && tickPositions.length > 0 ? tickPositions[tickPositions.length - 1] : void 0;
|
|
706
|
+
const abbreviate = typeof maxValue === "number" && maxValue > 9999 ? 1e3 : true;
|
|
707
|
+
return (0, import_seeds_react_numeral2.formatNumeral)({
|
|
708
|
+
abbreviate,
|
|
709
|
+
currency,
|
|
710
|
+
format: numberFormat,
|
|
711
|
+
locale: numberLocale,
|
|
712
|
+
number: numberValue
|
|
713
|
+
});
|
|
714
|
+
};
|
|
715
|
+
|
|
666
716
|
// src/helpers/xAxisLabelFormatter.ts
|
|
667
717
|
var xAxisLabelFormatter = ({
|
|
668
718
|
textLocale,
|
|
@@ -672,6 +722,9 @@ var xAxisLabelFormatter = ({
|
|
|
672
722
|
// optional
|
|
673
723
|
timeFormat = "12"
|
|
674
724
|
}) => {
|
|
725
|
+
if (typeof value === "string") {
|
|
726
|
+
return `<span>${value}</span>`;
|
|
727
|
+
}
|
|
675
728
|
const tickIndex = tickPositions.indexOf(value);
|
|
676
729
|
const isFirst = tickIndex === 0;
|
|
677
730
|
const previousValue = tickPositions[tickIndex - 1];
|
|
@@ -717,39 +770,227 @@ var xAxisLabelFormatter = ({
|
|
|
717
770
|
return `<span>${firstPart}</span>${secondPart ? `<span>${secondPart}</span>` : ""}`;
|
|
718
771
|
};
|
|
719
772
|
|
|
720
|
-
// src/helpers/
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
773
|
+
// src/helpers/isHourlyTimeData.ts
|
|
774
|
+
function isHourlyTimeData(data) {
|
|
775
|
+
if (!data.length) return false;
|
|
776
|
+
const xVals = data.flatMap((series) => series.points.map((p) => p.x));
|
|
777
|
+
if (!xVals.length) return false;
|
|
778
|
+
if (xVals.some((x) => typeof x === "string")) return false;
|
|
779
|
+
const dates = xVals.map((x) => {
|
|
780
|
+
const d = new Date(x);
|
|
781
|
+
return `${d.getUTCFullYear()}-${d.getUTCMonth()}-${d.getUTCDate()}`;
|
|
782
|
+
});
|
|
783
|
+
const uniqueDates = new Set(dates);
|
|
784
|
+
if (uniqueDates.size !== 1) return false;
|
|
785
|
+
return xVals.every((x) => {
|
|
786
|
+
const d = new Date(x);
|
|
787
|
+
const hour = d.getUTCHours();
|
|
788
|
+
const minutes = d.getUTCMinutes();
|
|
789
|
+
const seconds = d.getUTCSeconds();
|
|
790
|
+
return hour >= 0 && hour <= 23 && minutes === 0 && seconds === 0;
|
|
791
|
+
});
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
// src/helpers/isCategoricalHourData.ts
|
|
795
|
+
function isCategoricalHourData(data) {
|
|
796
|
+
if (!data.length) return false;
|
|
797
|
+
const xVals = data.flatMap((series) => series.points.map((p) => p.x));
|
|
798
|
+
if (!xVals.length) return false;
|
|
799
|
+
if (xVals.some((x) => typeof x !== "string")) return false;
|
|
800
|
+
const hour12Pattern = /^\d{1,2} (AM|PM)$/;
|
|
801
|
+
const hour24Pattern = /^([01]?\d|2[0-3]):([0-5]\d)$/;
|
|
802
|
+
const stringValues = xVals;
|
|
803
|
+
const allMatch12Hour = stringValues.every((x) => hour12Pattern.test(x));
|
|
804
|
+
const allMatch24Hour = stringValues.every((x) => hour24Pattern.test(x));
|
|
805
|
+
return allMatch12Hour || allMatch24Hour;
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
// src/helpers/getStorybookRandomColor.ts
|
|
809
|
+
var getStorybookRandomColor = () => {
|
|
810
|
+
const letters = "0123456789ABCDEF";
|
|
811
|
+
let color = "#";
|
|
812
|
+
for (let i = 0; i < 6; i++) {
|
|
813
|
+
color += letters[Math.floor(Math.random() * 16)];
|
|
744
814
|
}
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
815
|
+
return color;
|
|
816
|
+
};
|
|
817
|
+
|
|
818
|
+
// src/helpers/getStorybookCategoricalData.ts
|
|
819
|
+
var getStorybookCategoricalData = ({
|
|
820
|
+
showNulls,
|
|
821
|
+
showNegativeValues,
|
|
822
|
+
numberOfSeries,
|
|
823
|
+
yAxisMax,
|
|
824
|
+
showCustomColors,
|
|
825
|
+
showDashedLines,
|
|
826
|
+
categoryType
|
|
827
|
+
}) => {
|
|
828
|
+
const categoryOptions = {
|
|
829
|
+
hours: [
|
|
830
|
+
"12 AM",
|
|
831
|
+
"1 AM",
|
|
832
|
+
"2 AM",
|
|
833
|
+
"3 AM",
|
|
834
|
+
"4 AM",
|
|
835
|
+
"5 AM",
|
|
836
|
+
"6 AM",
|
|
837
|
+
"7 AM",
|
|
838
|
+
"8 AM",
|
|
839
|
+
"9 AM",
|
|
840
|
+
"10 AM",
|
|
841
|
+
"11 AM",
|
|
842
|
+
"12 PM",
|
|
843
|
+
"1 PM",
|
|
844
|
+
"2 PM",
|
|
845
|
+
"3 PM",
|
|
846
|
+
"4 PM",
|
|
847
|
+
"5 PM",
|
|
848
|
+
"6 PM",
|
|
849
|
+
"7 PM",
|
|
850
|
+
"8 PM",
|
|
851
|
+
"9 PM",
|
|
852
|
+
"10 PM",
|
|
853
|
+
"11 PM"
|
|
854
|
+
],
|
|
855
|
+
hours24: [
|
|
856
|
+
"00:00",
|
|
857
|
+
"01:00",
|
|
858
|
+
"02:00",
|
|
859
|
+
"03:00",
|
|
860
|
+
"04:00",
|
|
861
|
+
"05:00",
|
|
862
|
+
"06:00",
|
|
863
|
+
"07:00",
|
|
864
|
+
"08:00",
|
|
865
|
+
"09:00",
|
|
866
|
+
"10:00",
|
|
867
|
+
"11:00",
|
|
868
|
+
"12:00",
|
|
869
|
+
"13:00",
|
|
870
|
+
"14:00",
|
|
871
|
+
"15:00",
|
|
872
|
+
"16:00",
|
|
873
|
+
"17:00",
|
|
874
|
+
"18:00",
|
|
875
|
+
"19:00",
|
|
876
|
+
"20:00",
|
|
877
|
+
"21:00",
|
|
878
|
+
"22:00",
|
|
879
|
+
"23:00"
|
|
880
|
+
],
|
|
881
|
+
days: [
|
|
882
|
+
"Monday",
|
|
883
|
+
"Tuesday",
|
|
884
|
+
"Wednesday",
|
|
885
|
+
"Thursday",
|
|
886
|
+
"Friday",
|
|
887
|
+
"Saturday",
|
|
888
|
+
"Sunday"
|
|
889
|
+
],
|
|
890
|
+
months: [
|
|
891
|
+
"January",
|
|
892
|
+
"February",
|
|
893
|
+
"March",
|
|
894
|
+
"April",
|
|
895
|
+
"May",
|
|
896
|
+
"June",
|
|
897
|
+
"July",
|
|
898
|
+
"August",
|
|
899
|
+
"September",
|
|
900
|
+
"October",
|
|
901
|
+
"November",
|
|
902
|
+
"December"
|
|
903
|
+
],
|
|
904
|
+
custom: [
|
|
905
|
+
"Category A",
|
|
906
|
+
"Category B",
|
|
907
|
+
"Category C",
|
|
908
|
+
"Category D",
|
|
909
|
+
"Category E"
|
|
910
|
+
]
|
|
911
|
+
};
|
|
912
|
+
const categories = categoryOptions[categoryType];
|
|
913
|
+
const numberOfPoints = categories.length;
|
|
914
|
+
return [...Array(numberOfSeries).keys()].map((seriesIndex) => {
|
|
915
|
+
let nullsArray = [];
|
|
916
|
+
if (showNulls) {
|
|
917
|
+
const nullsArrayLength = Math.floor(numberOfPoints / 5);
|
|
918
|
+
nullsArray = [...Array(nullsArrayLength)].map(
|
|
919
|
+
() => Math.floor(Math.random() * numberOfPoints)
|
|
920
|
+
);
|
|
921
|
+
}
|
|
922
|
+
return {
|
|
923
|
+
points: categories.map((category, pointIndex) => {
|
|
924
|
+
const showNull = nullsArray && nullsArray.length > 0 ? nullsArray.includes(pointIndex) : false;
|
|
925
|
+
const randomValue = Math.random();
|
|
926
|
+
const positiveOrNegativeYAxisMax = showNegativeValues ? randomValue < 0.5 ? -yAxisMax : yAxisMax : yAxisMax;
|
|
927
|
+
return {
|
|
928
|
+
x: category,
|
|
929
|
+
y: showNull ? null : Math.floor(randomValue * positiveOrNegativeYAxisMax)
|
|
930
|
+
};
|
|
931
|
+
}),
|
|
932
|
+
name: `Series ${seriesIndex + 1}`,
|
|
933
|
+
styles: {
|
|
934
|
+
color: showCustomColors ? getStorybookRandomColor() : void 0,
|
|
935
|
+
pattern: showDashedLines ? "dashed" : "solid"
|
|
936
|
+
}
|
|
937
|
+
};
|
|
938
|
+
});
|
|
939
|
+
};
|
|
940
|
+
|
|
941
|
+
// src/helpers/getStorybookSparseTimelineData.ts
|
|
942
|
+
var getStorybookSparseTimelineData = ({
|
|
943
|
+
showNulls,
|
|
944
|
+
showNegativeValues,
|
|
945
|
+
numberOfSeries,
|
|
946
|
+
yAxisMax,
|
|
947
|
+
showCustomColors,
|
|
948
|
+
showDashedLines,
|
|
949
|
+
numberOfPoints = 5,
|
|
950
|
+
timeSpanHours = 24
|
|
951
|
+
}) => {
|
|
952
|
+
const seriesNames = [
|
|
953
|
+
"Posts Published",
|
|
954
|
+
"Comments",
|
|
955
|
+
"Likes",
|
|
956
|
+
"Shares",
|
|
957
|
+
"Clicks",
|
|
958
|
+
"Views",
|
|
959
|
+
"Saves",
|
|
960
|
+
"Reposts",
|
|
961
|
+
"Mentions",
|
|
962
|
+
"Reactions"
|
|
963
|
+
];
|
|
964
|
+
const baseDate = /* @__PURE__ */ new Date("2024-01-01T00:00:00Z");
|
|
965
|
+
const timeSpanMs = timeSpanHours * 60 * 60 * 1e3;
|
|
966
|
+
return [...Array(numberOfSeries).keys()].map((seriesIndex) => {
|
|
967
|
+
let nullsArray = [];
|
|
968
|
+
if (showNulls) {
|
|
969
|
+
const nullsArrayLength = Math.floor(numberOfPoints / 5);
|
|
970
|
+
nullsArray = [...Array(nullsArrayLength)].map(
|
|
971
|
+
() => Math.floor(Math.random() * numberOfPoints)
|
|
972
|
+
);
|
|
973
|
+
}
|
|
974
|
+
const timestamps = [...Array(numberOfPoints)].map(() => {
|
|
975
|
+
const randomOffset = Math.random() * timeSpanMs;
|
|
976
|
+
return baseDate.getTime() + randomOffset;
|
|
977
|
+
}).sort((a, b) => a - b);
|
|
978
|
+
return {
|
|
979
|
+
points: timestamps.map((timestamp, pointIndex) => {
|
|
980
|
+
const showNull = nullsArray && nullsArray.length > 0 ? nullsArray.includes(pointIndex) : false;
|
|
981
|
+
const randomValue = Math.random();
|
|
982
|
+
const positiveOrNegativeYAxisMax = showNegativeValues ? randomValue < 0.5 ? -yAxisMax : yAxisMax : yAxisMax;
|
|
983
|
+
return {
|
|
984
|
+
x: timestamp,
|
|
985
|
+
y: showNull ? null : Math.floor(randomValue * positiveOrNegativeYAxisMax)
|
|
986
|
+
};
|
|
987
|
+
}),
|
|
988
|
+
name: seriesNames[seriesIndex] || `Series ${seriesIndex + 1}`,
|
|
989
|
+
styles: {
|
|
990
|
+
color: showCustomColors ? getStorybookRandomColor() : void 0,
|
|
991
|
+
pattern: showDashedLines ? "dashed" : "solid"
|
|
992
|
+
}
|
|
993
|
+
};
|
|
753
994
|
});
|
|
754
995
|
};
|
|
755
996
|
|
|
@@ -839,7 +1080,20 @@ var timeSeriesChartOptions = import_lodash.default.merge({}, baseChartOptions, {
|
|
|
839
1080
|
softMin: 0,
|
|
840
1081
|
title: {
|
|
841
1082
|
text: void 0
|
|
842
|
-
}
|
|
1083
|
+
},
|
|
1084
|
+
plotLines: [
|
|
1085
|
+
/* Adds a custom plotLine at y=0 to represent the chart baseline.
|
|
1086
|
+
This approach allows full control over the line's appearance (e.g., color, z-index),
|
|
1087
|
+
unlike relying on the default xAxis line, which always renders at the bottom of the chart
|
|
1088
|
+
even when y=0 appears elsewhere (e.g., with negative values).
|
|
1089
|
+
*/
|
|
1090
|
+
{
|
|
1091
|
+
className: "y-axis-zero-line",
|
|
1092
|
+
value: 0,
|
|
1093
|
+
zIndex: 3
|
|
1094
|
+
// ensures the line appears over the default y=0 line, which we can't seleect as specifically
|
|
1095
|
+
}
|
|
1096
|
+
]
|
|
843
1097
|
}
|
|
844
1098
|
});
|
|
845
1099
|
var lineChartOptions = import_lodash.default.merge({}, timeSeriesChartOptions, {
|
|
@@ -853,6 +1107,30 @@ var areaChartOptions = import_lodash.default.merge({}, timeSeriesChartOptions, {
|
|
|
853
1107
|
}
|
|
854
1108
|
}
|
|
855
1109
|
});
|
|
1110
|
+
var columnChartOptions = import_lodash.default.merge({}, timeSeriesChartOptions, {
|
|
1111
|
+
plotOptions: {
|
|
1112
|
+
column: {
|
|
1113
|
+
stacking: "normal",
|
|
1114
|
+
pointPadding: 0.25,
|
|
1115
|
+
groupPadding: 0.25,
|
|
1116
|
+
borderRadius: 4
|
|
1117
|
+
}
|
|
1118
|
+
},
|
|
1119
|
+
xAxis: {
|
|
1120
|
+
crosshair: false
|
|
1121
|
+
},
|
|
1122
|
+
yAxis: {
|
|
1123
|
+
plotLines: [
|
|
1124
|
+
{
|
|
1125
|
+
// For stacked column charts with visible borders (e.g., white for contrast),
|
|
1126
|
+
// we raise the zIndex of the y=0 plotLine to ensure it remains visible
|
|
1127
|
+
// and isn't visually covered by overlapping column borders.
|
|
1128
|
+
zIndex: 5
|
|
1129
|
+
}
|
|
1130
|
+
]
|
|
1131
|
+
}
|
|
1132
|
+
});
|
|
1133
|
+
var VERTICAL_BAR_CHART_DEFAULT_SERIES_LIMIT = 10;
|
|
856
1134
|
var DONUT_CHART_HALO_SIZE = 10;
|
|
857
1135
|
var DONUT_CHART_HEIGHT = 250 + DONUT_CHART_HALO_SIZE * 2;
|
|
858
1136
|
var DONUT_CHART_WIDTH = DONUT_CHART_HEIGHT;
|
|
@@ -883,10 +1161,12 @@ var useTimeSeriesChartOptions = ({
|
|
|
883
1161
|
seriesType,
|
|
884
1162
|
textLocale,
|
|
885
1163
|
currency = "USD",
|
|
1164
|
+
disableTooltips = false,
|
|
886
1165
|
numberFormat = "decimal",
|
|
887
1166
|
yAxisLabelFormatter: yAxisLabelFormatter2,
|
|
888
1167
|
onClick,
|
|
889
|
-
timeFormat = "12"
|
|
1168
|
+
timeFormat = "12",
|
|
1169
|
+
xAxisLabelFormatter: xAxisLabelFormatter2
|
|
890
1170
|
}) => {
|
|
891
1171
|
const [chart, setChart] = (0, import_react15.useState)(null);
|
|
892
1172
|
const callback = (0, import_react15.useCallback)((chartInstance) => {
|
|
@@ -920,7 +1200,24 @@ var useTimeSeriesChartOptions = ({
|
|
|
920
1200
|
}
|
|
921
1201
|
};
|
|
922
1202
|
const chartMarginTop = xAnnotations ? 24 : null;
|
|
923
|
-
const
|
|
1203
|
+
const getBaseChartOptions = (type) => {
|
|
1204
|
+
switch (type) {
|
|
1205
|
+
case "areaspline":
|
|
1206
|
+
return areaChartOptions;
|
|
1207
|
+
case "spline":
|
|
1208
|
+
return lineChartOptions;
|
|
1209
|
+
case "column":
|
|
1210
|
+
return columnChartOptions;
|
|
1211
|
+
default:
|
|
1212
|
+
return lineChartOptions;
|
|
1213
|
+
}
|
|
1214
|
+
};
|
|
1215
|
+
const baseChartOptions2 = getBaseChartOptions(seriesType);
|
|
1216
|
+
const hasCategoricalData = data.some(
|
|
1217
|
+
(series) => series.points.some((point) => typeof point.x === "string")
|
|
1218
|
+
);
|
|
1219
|
+
const categories = hasCategoricalData ? data[0]?.points.map((point) => point.x) || [] : [];
|
|
1220
|
+
const hasSparseTimelineData = !hasCategoricalData && seriesType === "column";
|
|
924
1221
|
const options = (0, import_react15.useMemo)(() => {
|
|
925
1222
|
return (0, import_lodash2.merge)({}, baseChartOptions2, {
|
|
926
1223
|
accessibility: {
|
|
@@ -961,20 +1258,101 @@ var useTimeSeriesChartOptions = ({
|
|
|
961
1258
|
return onClick({ x: event.point.x });
|
|
962
1259
|
} : void 0
|
|
963
1260
|
}
|
|
1261
|
+
},
|
|
1262
|
+
column: {
|
|
1263
|
+
// For sparse timeline data, set explicit point width to make columns wider
|
|
1264
|
+
...hasSparseTimelineData && {
|
|
1265
|
+
pointWidth: 20
|
|
1266
|
+
// Fixed width in pixels for sparse timeline data
|
|
1267
|
+
},
|
|
1268
|
+
point: {
|
|
1269
|
+
events: {
|
|
1270
|
+
/*
|
|
1271
|
+
Custom hover behavior for multi-series column charts.
|
|
1272
|
+
|
|
1273
|
+
In multi-series column charts, multiple columns
|
|
1274
|
+
can share the same x-axis position (stacked or grouped). When hovering
|
|
1275
|
+
over one column, we want ALL columns at that x-position to highlight
|
|
1276
|
+
together for better visual feedback. Simple CSS :hover only affects the
|
|
1277
|
+
individual element being hovered, not related columns at the same position.
|
|
1278
|
+
|
|
1279
|
+
This custom behavior ensures that when you hover over any column at a
|
|
1280
|
+
specific x-position, all columns at that same position get the "column-hover"
|
|
1281
|
+
class, creating a unified highlight effect across all series.
|
|
1282
|
+
*/
|
|
1283
|
+
mouseOver: function() {
|
|
1284
|
+
const x = this.x;
|
|
1285
|
+
if (this.series && this.series.chart && this.series.chart.series) {
|
|
1286
|
+
this.series.chart.series.forEach((series) => {
|
|
1287
|
+
if (series.type === "column") {
|
|
1288
|
+
series.data.forEach((point) => {
|
|
1289
|
+
if (point.x === x) {
|
|
1290
|
+
const el = point.graphic && point.graphic.element;
|
|
1291
|
+
if (el) {
|
|
1292
|
+
el.classList.add("column-hover");
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
});
|
|
1296
|
+
}
|
|
1297
|
+
});
|
|
1298
|
+
}
|
|
1299
|
+
},
|
|
1300
|
+
mouseOut: function() {
|
|
1301
|
+
if (this.series && this.series.chart && this.series.chart.series) {
|
|
1302
|
+
this.series.chart.series.forEach((series) => {
|
|
1303
|
+
if (series.type === "column") {
|
|
1304
|
+
series.data.forEach((point) => {
|
|
1305
|
+
const el = point.graphic && point.graphic.element;
|
|
1306
|
+
if (el) {
|
|
1307
|
+
el.classList.remove("column-hover");
|
|
1308
|
+
}
|
|
1309
|
+
});
|
|
1310
|
+
}
|
|
1311
|
+
});
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
964
1316
|
}
|
|
965
1317
|
},
|
|
966
1318
|
series: transformDataToSeries({ data }, seriesType),
|
|
1319
|
+
tooltip: {
|
|
1320
|
+
enabled: !disableTooltips
|
|
1321
|
+
},
|
|
967
1322
|
xAxis: {
|
|
968
1323
|
labels: {
|
|
969
1324
|
formatter: function() {
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
1325
|
+
const tickPositions = (this.axis.tickPositions || []).map(
|
|
1326
|
+
Number
|
|
1327
|
+
);
|
|
1328
|
+
const value = this.value;
|
|
1329
|
+
const unitName = this.tickPositionInfo?.unitName;
|
|
1330
|
+
if (typeof xAxisLabelFormatter2 === "function") {
|
|
1331
|
+
return xAxisLabelFormatter2({
|
|
1332
|
+
textLocale,
|
|
1333
|
+
tickPositions,
|
|
1334
|
+
timeFormat,
|
|
1335
|
+
unitName,
|
|
1336
|
+
value
|
|
1337
|
+
});
|
|
1338
|
+
}
|
|
1339
|
+
if (typeof xAxisLabelFormatterDefault === "function") {
|
|
1340
|
+
return xAxisLabelFormatterDefault({
|
|
1341
|
+
textLocale,
|
|
1342
|
+
tickPositions,
|
|
1343
|
+
timeFormat,
|
|
1344
|
+
unitName,
|
|
1345
|
+
value
|
|
1346
|
+
});
|
|
1347
|
+
}
|
|
1348
|
+
return "";
|
|
977
1349
|
}
|
|
1350
|
+
},
|
|
1351
|
+
// Override xAxis type for categorical data
|
|
1352
|
+
...hasCategoricalData && {
|
|
1353
|
+
type: "category",
|
|
1354
|
+
categories,
|
|
1355
|
+
crosshair: false
|
|
978
1356
|
}
|
|
979
1357
|
},
|
|
980
1358
|
yAxis: {
|
|
@@ -997,8 +1375,11 @@ var useTimeSeriesChartOptions = ({
|
|
|
997
1375
|
});
|
|
998
1376
|
}, [
|
|
999
1377
|
baseChartOptions2,
|
|
1378
|
+
categories,
|
|
1000
1379
|
currency,
|
|
1001
1380
|
data,
|
|
1381
|
+
hasCategoricalData,
|
|
1382
|
+
hasSparseTimelineData,
|
|
1002
1383
|
numberFormat,
|
|
1003
1384
|
numberLocale,
|
|
1004
1385
|
onClick,
|
|
@@ -1006,10 +1387,12 @@ var useTimeSeriesChartOptions = ({
|
|
|
1006
1387
|
textLocale,
|
|
1007
1388
|
timeFormat,
|
|
1008
1389
|
xAnnotations,
|
|
1009
|
-
yAxisLabelFormatter2
|
|
1390
|
+
yAxisLabelFormatter2,
|
|
1391
|
+
xAxisLabelFormatter2
|
|
1010
1392
|
]);
|
|
1011
1393
|
return { options, chart, callback };
|
|
1012
1394
|
};
|
|
1395
|
+
var xAxisLabelFormatterDefault = xAxisLabelFormatter;
|
|
1013
1396
|
|
|
1014
1397
|
// src/styles/chartStyles.ts
|
|
1015
1398
|
var import_styled_components7 = require("styled-components");
|
|
@@ -1028,6 +1411,8 @@ var GlobalChartStyleOverrides = import_styled_components7.createGlobalStyle`
|
|
|
1028
1411
|
}
|
|
1029
1412
|
`;
|
|
1030
1413
|
var baseChartStyles = import_styled_components7.css`
|
|
1414
|
+
--highcharts-background-color: ${({ theme: theme14 }) => theme14.colors.container.background.base};
|
|
1415
|
+
|
|
1031
1416
|
// set color variables and map to each series
|
|
1032
1417
|
${({ $colors }) => $colors.map((color, index) => {
|
|
1033
1418
|
const chartColor = color || import_seeds_react_theme7.theme.colors.DATAVIZ_COLORS_LIST[index];
|
|
@@ -1071,9 +1456,11 @@ var timeSeriesChartStyles = import_styled_components7.css`
|
|
|
1071
1456
|
.highcharts-grid-line {
|
|
1072
1457
|
stroke: ${({ theme: theme14 }) => theme14.colors.container.border.base};
|
|
1073
1458
|
}
|
|
1459
|
+
|
|
1074
1460
|
.highcharts-axis-line {
|
|
1075
1461
|
stroke: ${({ theme: theme14 }) => theme14.colors.container.border.base};
|
|
1076
1462
|
}
|
|
1463
|
+
|
|
1077
1464
|
.highcharts-tick {
|
|
1078
1465
|
stroke: none;
|
|
1079
1466
|
}
|
|
@@ -1114,6 +1501,10 @@ var timeSeriesChartStyles = import_styled_components7.css`
|
|
|
1114
1501
|
fill: transparent;
|
|
1115
1502
|
cursor: pointer;
|
|
1116
1503
|
}`}
|
|
1504
|
+
|
|
1505
|
+
path.highcharts-plot-line.y-axis-zero-line {
|
|
1506
|
+
stroke: ${({ theme: theme14 }) => theme14.colors.container.border.decorative.neutral};
|
|
1507
|
+
}
|
|
1117
1508
|
`;
|
|
1118
1509
|
var lineChartStyles = import_styled_components7.css`
|
|
1119
1510
|
${timeSeriesChartStyles}
|
|
@@ -1185,6 +1576,7 @@ var AreaChartWithData = (0, import_react16.memo)(function AreaChartWithData2({
|
|
|
1185
1576
|
tooltipTotalLabel,
|
|
1186
1577
|
// optional
|
|
1187
1578
|
currency = "USD",
|
|
1579
|
+
disableTooltips = false,
|
|
1188
1580
|
numberFormat = "decimal",
|
|
1189
1581
|
tooltip,
|
|
1190
1582
|
yAxisLabelFormatter: yAxisLabelFormatter2,
|
|
@@ -1196,6 +1588,7 @@ var AreaChartWithData = (0, import_react16.memo)(function AreaChartWithData2({
|
|
|
1196
1588
|
const { options, chart, callback } = useTimeSeriesChartOptions({
|
|
1197
1589
|
currency,
|
|
1198
1590
|
data,
|
|
1591
|
+
disableTooltips,
|
|
1199
1592
|
numberFormat,
|
|
1200
1593
|
numberLocale,
|
|
1201
1594
|
seriesType: "areaspline",
|
|
@@ -1232,7 +1625,7 @@ var AreaChartWithData = (0, import_react16.memo)(function AreaChartWithData2({
|
|
|
1232
1625
|
annotationContext: chart.annotations?.[0]
|
|
1233
1626
|
}
|
|
1234
1627
|
) : null,
|
|
1235
|
-
chart ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1628
|
+
chart && !disableTooltips ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
1236
1629
|
ChartTooltipPortal,
|
|
1237
1630
|
{
|
|
1238
1631
|
chart,
|
|
@@ -1388,6 +1781,7 @@ var DonutChartWithData = (0, import_react19.memo)(
|
|
|
1388
1781
|
textLocale = "en-us",
|
|
1389
1782
|
// optional
|
|
1390
1783
|
currency = "USD",
|
|
1784
|
+
disableTooltips = false,
|
|
1391
1785
|
hideLegend = false,
|
|
1392
1786
|
numberFormat = "decimal",
|
|
1393
1787
|
tooltip
|
|
@@ -1435,7 +1829,10 @@ var DonutChartWithData = (0, import_react19.memo)(
|
|
|
1435
1829
|
};
|
|
1436
1830
|
})
|
|
1437
1831
|
}
|
|
1438
|
-
]
|
|
1832
|
+
],
|
|
1833
|
+
tooltip: {
|
|
1834
|
+
enabled: !disableTooltips
|
|
1835
|
+
}
|
|
1439
1836
|
});
|
|
1440
1837
|
}, [data]);
|
|
1441
1838
|
const colors = data.map(
|
|
@@ -1452,7 +1849,7 @@ var DonutChartWithData = (0, import_react19.memo)(
|
|
|
1452
1849
|
callback
|
|
1453
1850
|
}
|
|
1454
1851
|
),
|
|
1455
|
-
chart ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1852
|
+
chart && !disableTooltips ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
1456
1853
|
ChartTooltipPortal,
|
|
1457
1854
|
{
|
|
1458
1855
|
chart,
|
|
@@ -1674,6 +2071,7 @@ var LineChartWithData = (0, import_react23.memo)(function LineChartWithData2({
|
|
|
1674
2071
|
tooltipDateFormatter,
|
|
1675
2072
|
// optional
|
|
1676
2073
|
currency = "USD",
|
|
2074
|
+
disableTooltips = false,
|
|
1677
2075
|
numberFormat = "decimal",
|
|
1678
2076
|
tooltip,
|
|
1679
2077
|
yAxisLabelFormatter: yAxisLabelFormatter2,
|
|
@@ -1685,6 +2083,7 @@ var LineChartWithData = (0, import_react23.memo)(function LineChartWithData2({
|
|
|
1685
2083
|
const { options, chart, callback } = useTimeSeriesChartOptions({
|
|
1686
2084
|
currency,
|
|
1687
2085
|
data,
|
|
2086
|
+
disableTooltips,
|
|
1688
2087
|
numberFormat,
|
|
1689
2088
|
numberLocale,
|
|
1690
2089
|
seriesType: "spline",
|
|
@@ -1732,7 +2131,7 @@ var LineChartWithData = (0, import_react23.memo)(function LineChartWithData2({
|
|
|
1732
2131
|
annotationContext: chart.annotations?.[0]
|
|
1733
2132
|
}
|
|
1734
2133
|
) : null,
|
|
1735
|
-
chart ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
2134
|
+
chart && !disableTooltips ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
1736
2135
|
ChartTooltipPortal,
|
|
1737
2136
|
{
|
|
1738
2137
|
chart,
|
|
@@ -1791,18 +2190,25 @@ var LineChartWithData = (0, import_react23.memo)(function LineChartWithData2({
|
|
|
1791
2190
|
LineChart,
|
|
1792
2191
|
NetworkColorBox,
|
|
1793
2192
|
TIME_SERIES_CHART_HEIGHT,
|
|
2193
|
+
VERTICAL_BAR_CHART_DEFAULT_SERIES_LIMIT,
|
|
1794
2194
|
areaChartOptions,
|
|
1795
2195
|
areaChartStyles,
|
|
1796
2196
|
baseChartOptions,
|
|
1797
2197
|
baseChartStyles,
|
|
2198
|
+
columnChartOptions,
|
|
1798
2199
|
donutChartOptions,
|
|
1799
2200
|
donutChartStyles,
|
|
1800
2201
|
generateChartTooltipPortalId,
|
|
1801
2202
|
getDatavizColor,
|
|
1802
2203
|
getDatavizColorWithAlpha,
|
|
1803
2204
|
getDatavizOpacity,
|
|
2205
|
+
getStorybookCategoricalData,
|
|
2206
|
+
getStorybookSparseTimelineData,
|
|
2207
|
+
isCategoricalHourData,
|
|
2208
|
+
isHourlyTimeData,
|
|
1804
2209
|
lineChartOptions,
|
|
1805
2210
|
lineChartStyles,
|
|
2211
|
+
timeSeriesChartOptions,
|
|
1806
2212
|
timeSeriesChartStyles,
|
|
1807
2213
|
transformDataToSeries,
|
|
1808
2214
|
transformTimeSeriesTooltipData,
|