sag_components 2.0.0-beta52 → 2.0.0-beta54
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/dist/index.d.ts +18 -1
- package/dist/index.esm.js +2089 -284
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +2089 -282
- package/dist/index.js.map +1 -1
- package/dist/types/components/BrushChart/BrushChart.d.ts +2 -0
- package/dist/types/components/BrushChart/BrushChart.stories.d.ts +8 -0
- package/dist/types/components/BrushChart/BrushChart.style.d.ts +5 -0
- package/dist/types/components/BrushChart/Charts/BarLine.d.ts +2 -0
- package/dist/types/components/BrushChart/Charts/InnerBar.d.ts +1 -0
- package/dist/types/components/BrushChart/Charts/SingleChart.d.ts +2 -0
- package/dist/types/components/BubbleChart/BubbleChart.d.ts +15 -0
- package/dist/types/components/BubbleChart/BubbleChart.stories.d.ts +93 -0
- package/dist/types/components/BubbleChart/BubbleChart.style.d.ts +13 -0
- package/dist/types/components/SegmentedButton/SegmentedButton.d.ts +3 -0
- package/dist/types/index.d.ts +2 -0
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React$1, { useState, useRef, useEffect, useCallback, useMemo } from 'react';
|
|
2
2
|
import styled, { keyframes, css } from 'styled-components';
|
|
3
|
-
import { ResponsiveContainer, PieChart as PieChart$1, Pie, Cell, Tooltip as Tooltip$2, BarChart as BarChart$1, CartesianGrid, XAxis, YAxis, Bar, LabelList, ReferenceLine, Brush, LineChart, Line, AreaChart as AreaChart$1, Legend, Area } from 'recharts';
|
|
3
|
+
import { ResponsiveContainer, PieChart as PieChart$1, Pie, Cell, Tooltip as Tooltip$2, BarChart as BarChart$1, CartesianGrid, XAxis, YAxis, Bar, LabelList, ReferenceLine, Brush, LineChart, Line, AreaChart as AreaChart$1, Legend, Area, ScatterChart, ZAxis, Scatter, ComposedChart } from 'recharts';
|
|
4
4
|
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
|
|
5
5
|
import { motion, AnimatePresence } from 'framer-motion';
|
|
6
6
|
|
|
@@ -1902,7 +1902,7 @@ const ControlsContainer$a = styled.div`
|
|
|
1902
1902
|
box-sizing: border-box;
|
|
1903
1903
|
}
|
|
1904
1904
|
`;
|
|
1905
|
-
const Controls$
|
|
1905
|
+
const Controls$9 = styled.div`
|
|
1906
1906
|
display: flex;
|
|
1907
1907
|
flex-direction: column;
|
|
1908
1908
|
width: 100%;
|
|
@@ -2026,7 +2026,7 @@ const ControlsContainer$9 = styled.div`
|
|
|
2026
2026
|
//border: 1px solid red;
|
|
2027
2027
|
align-items: center;
|
|
2028
2028
|
`;
|
|
2029
|
-
const Controls$
|
|
2029
|
+
const Controls$8 = styled.div`
|
|
2030
2030
|
position: relative;
|
|
2031
2031
|
border-radius: 100px;
|
|
2032
2032
|
width: ${props => props.width.toString().concat('', 'px')};
|
|
@@ -2282,7 +2282,7 @@ const Benchmark = props => {
|
|
|
2282
2282
|
id: "Tooltip",
|
|
2283
2283
|
content: getTooltipText(),
|
|
2284
2284
|
direction: tooltipDirection
|
|
2285
|
-
}, /*#__PURE__*/React$1.createElement(Controls$
|
|
2285
|
+
}, /*#__PURE__*/React$1.createElement(Controls$8, {
|
|
2286
2286
|
id: "ControlsBenchmark",
|
|
2287
2287
|
height: height,
|
|
2288
2288
|
width: width
|
|
@@ -2407,7 +2407,7 @@ const PieChart = props => {
|
|
|
2407
2407
|
}, legendData.length === 0 || legendData.every(item => item.value === undefined || item.value === null) ? /*#__PURE__*/React$1.createElement(NoDataFoundMessage, {
|
|
2408
2408
|
className: "NoDataFoundMessage",
|
|
2409
2409
|
noDataText: noDataText
|
|
2410
|
-
}) : /*#__PURE__*/React$1.createElement(Controls$
|
|
2410
|
+
}) : /*#__PURE__*/React$1.createElement(Controls$9, {
|
|
2411
2411
|
className: "Controls",
|
|
2412
2412
|
height: height,
|
|
2413
2413
|
width: width
|
|
@@ -10037,6 +10037,7 @@ const RangePicker = _ref => {
|
|
|
10037
10037
|
setValue(e.target.value);
|
|
10038
10038
|
};
|
|
10039
10039
|
const toggleDatePicker = () => {
|
|
10040
|
+
if (disabled) return;
|
|
10040
10041
|
setIsOpen(!isOpen);
|
|
10041
10042
|
};
|
|
10042
10043
|
const handleFocus = () => {
|
|
@@ -24103,22 +24104,21 @@ const DeleteIcon = styled.div`
|
|
|
24103
24104
|
position: absolute;
|
|
24104
24105
|
`;
|
|
24105
24106
|
|
|
24106
|
-
const QuickFilterDropdownSingle =
|
|
24107
|
-
|
|
24108
|
-
|
|
24109
|
-
|
|
24110
|
-
|
|
24111
|
-
|
|
24112
|
-
|
|
24113
|
-
|
|
24114
|
-
|
|
24115
|
-
|
|
24116
|
-
|
|
24117
|
-
|
|
24118
|
-
|
|
24119
|
-
|
|
24120
|
-
|
|
24121
|
-
} = _ref;
|
|
24107
|
+
const QuickFilterDropdownSingle = ({
|
|
24108
|
+
label,
|
|
24109
|
+
hoverColor,
|
|
24110
|
+
options,
|
|
24111
|
+
selectedValue,
|
|
24112
|
+
placeHolder,
|
|
24113
|
+
onChange,
|
|
24114
|
+
disabled,
|
|
24115
|
+
width,
|
|
24116
|
+
error,
|
|
24117
|
+
errorMessage,
|
|
24118
|
+
xIconShow,
|
|
24119
|
+
labelColor,
|
|
24120
|
+
showLabelOnTop
|
|
24121
|
+
}) => {
|
|
24122
24122
|
const [isFocused, setIsFocused] = useState(false);
|
|
24123
24123
|
const [showOptions, setShowOptions] = useState(false);
|
|
24124
24124
|
const [inputValue, setInputValue] = useState("");
|
|
@@ -24516,24 +24516,23 @@ const IconContainer$2 = styled.div`
|
|
|
24516
24516
|
cursor: pointer;
|
|
24517
24517
|
`;
|
|
24518
24518
|
|
|
24519
|
-
const QuickFilterDropdownMultiSelection =
|
|
24520
|
-
|
|
24521
|
-
|
|
24522
|
-
|
|
24523
|
-
|
|
24524
|
-
|
|
24525
|
-
|
|
24526
|
-
|
|
24527
|
-
|
|
24528
|
-
|
|
24529
|
-
|
|
24530
|
-
|
|
24531
|
-
|
|
24532
|
-
|
|
24533
|
-
|
|
24534
|
-
|
|
24535
|
-
|
|
24536
|
-
} = _ref;
|
|
24519
|
+
const QuickFilterDropdownMultiSelection = ({
|
|
24520
|
+
label,
|
|
24521
|
+
labelEmptyValue,
|
|
24522
|
+
options,
|
|
24523
|
+
selectedValue,
|
|
24524
|
+
placeHolder,
|
|
24525
|
+
onChange,
|
|
24526
|
+
required,
|
|
24527
|
+
disabled,
|
|
24528
|
+
width,
|
|
24529
|
+
error,
|
|
24530
|
+
errorMessage,
|
|
24531
|
+
labelColor,
|
|
24532
|
+
xIconShow,
|
|
24533
|
+
checkBoxColor,
|
|
24534
|
+
showLabelOnTop
|
|
24535
|
+
}) => {
|
|
24537
24536
|
const [isFocused, setIsFocused] = useState(false);
|
|
24538
24537
|
const [showOptions, setShowOptions] = useState(false);
|
|
24539
24538
|
const [inputValue, setInputValue] = useState('');
|
|
@@ -25147,8 +25146,8 @@ function styleInject(css, ref) {
|
|
|
25147
25146
|
}
|
|
25148
25147
|
}
|
|
25149
25148
|
|
|
25150
|
-
var css_248z = "@keyframes react-loading-skeleton {\n 100% {\n transform: translateX(100%);\n }\n}\n\n.react-loading-skeleton {\n --base-color: #ebebeb;\n --highlight-color: #f5f5f5;\n --animation-duration: 1.5s;\n --animation-direction: normal;\n --pseudo-element-display: block; /* Enable animation */\n\n background-color: var(--base-color);\n\n width: 100%;\n border-radius: 0.25rem;\n display: inline-flex;\n line-height: 1;\n\n position: relative;\n user-select: none;\n overflow: hidden;\n}\n\n.react-loading-skeleton::after {\n content: ' ';\n display: var(--pseudo-element-display);\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 100%;\n background-repeat: no-repeat;\n background-image: var(\n --custom-highlight-background,\n linear-gradient(\n 90deg,\n var(--base-color) 0%,\n var(--highlight-color) 50%,\n var(--base-color) 100%\n )\n );\n transform: translateX(-100%);\n\n animation-name: react-loading-skeleton;\n animation-direction: var(--animation-direction);\n animation-duration: var(--animation-duration);\n animation-timing-function: ease-in-out;\n animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion) {\n .react-loading-skeleton {\n --pseudo-element-display: none; /* Disable animation */\n }\n}\n";
|
|
25151
|
-
styleInject(css_248z);
|
|
25149
|
+
var css_248z$1 = "@keyframes react-loading-skeleton {\n 100% {\n transform: translateX(100%);\n }\n}\n\n.react-loading-skeleton {\n --base-color: #ebebeb;\n --highlight-color: #f5f5f5;\n --animation-duration: 1.5s;\n --animation-direction: normal;\n --pseudo-element-display: block; /* Enable animation */\n\n background-color: var(--base-color);\n\n width: 100%;\n border-radius: 0.25rem;\n display: inline-flex;\n line-height: 1;\n\n position: relative;\n user-select: none;\n overflow: hidden;\n}\n\n.react-loading-skeleton::after {\n content: ' ';\n display: var(--pseudo-element-display);\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n height: 100%;\n background-repeat: no-repeat;\n background-image: var(\n --custom-highlight-background,\n linear-gradient(\n 90deg,\n var(--base-color) 0%,\n var(--highlight-color) 50%,\n var(--base-color) 100%\n )\n );\n transform: translateX(-100%);\n\n animation-name: react-loading-skeleton;\n animation-direction: var(--animation-direction);\n animation-duration: var(--animation-duration);\n animation-timing-function: ease-in-out;\n animation-iteration-count: infinite;\n}\n\n@media (prefers-reduced-motion) {\n .react-loading-skeleton {\n --pseudo-element-display: none; /* Disable animation */\n }\n}\n";
|
|
25150
|
+
styleInject(css_248z$1);
|
|
25152
25151
|
|
|
25153
25152
|
const OneColumnContainer = props => {
|
|
25154
25153
|
const {
|
|
@@ -25345,7 +25344,7 @@ const ControlsContainer$7 = styled.div`
|
|
|
25345
25344
|
box-sizing: border-box;
|
|
25346
25345
|
}
|
|
25347
25346
|
`;
|
|
25348
|
-
const Controls$
|
|
25347
|
+
const Controls$7 = styled.div`
|
|
25349
25348
|
display: flex;
|
|
25350
25349
|
flex-direction: column;
|
|
25351
25350
|
width: 100%;
|
|
@@ -25413,7 +25412,7 @@ const FormattedValue$3 = props => {
|
|
|
25413
25412
|
height: height,
|
|
25414
25413
|
width: width,
|
|
25415
25414
|
textcolor: textcolor
|
|
25416
|
-
}, /*#__PURE__*/React$1.createElement(Controls$
|
|
25415
|
+
}, /*#__PURE__*/React$1.createElement(Controls$7, {
|
|
25417
25416
|
className: "Controls",
|
|
25418
25417
|
height: height,
|
|
25419
25418
|
width: width
|
|
@@ -25473,7 +25472,7 @@ const ControlsContainer$6 = styled.div`
|
|
|
25473
25472
|
height: ${props => props.height};
|
|
25474
25473
|
min-width: 250px;
|
|
25475
25474
|
`;
|
|
25476
|
-
const Controls$
|
|
25475
|
+
const Controls$6 = styled.div`
|
|
25477
25476
|
height: 100%;
|
|
25478
25477
|
width: 100%;
|
|
25479
25478
|
background: white;
|
|
@@ -25606,7 +25605,7 @@ const ControlsContainer$5 = styled.div`
|
|
|
25606
25605
|
box-sizing: border-box;
|
|
25607
25606
|
}
|
|
25608
25607
|
`;
|
|
25609
|
-
const Controls$
|
|
25608
|
+
const Controls$5 = styled.div`
|
|
25610
25609
|
display: flex;
|
|
25611
25610
|
gap: 20px;
|
|
25612
25611
|
flex-direction: column;
|
|
@@ -25669,7 +25668,7 @@ const PerformanceAnalyticsLegend = props => {
|
|
|
25669
25668
|
className: className,
|
|
25670
25669
|
height: height,
|
|
25671
25670
|
width: width
|
|
25672
|
-
}, legendData?.length > 0 ? /*#__PURE__*/React$1.createElement(Controls$
|
|
25671
|
+
}, legendData?.length > 0 ? /*#__PURE__*/React$1.createElement(Controls$5, {
|
|
25673
25672
|
height: height,
|
|
25674
25673
|
width: width
|
|
25675
25674
|
}, /*#__PURE__*/React$1.createElement(LegendDataContainer, {
|
|
@@ -25837,7 +25836,7 @@ const BarChartsByWeeks = props => {
|
|
|
25837
25836
|
height: height,
|
|
25838
25837
|
width: width,
|
|
25839
25838
|
ref: controlsContainerRef
|
|
25840
|
-
}, /*#__PURE__*/React$1.createElement(Controls$
|
|
25839
|
+
}, /*#__PURE__*/React$1.createElement(Controls$6, {
|
|
25841
25840
|
height: getControlsHeight()
|
|
25842
25841
|
}, showTitle && /*#__PURE__*/React$1.createElement(TitleAndValueContainer$2, null, /*#__PURE__*/React$1.createElement(Title$b, null, title), /*#__PURE__*/React$1.createElement(FormattedValue$3, {
|
|
25843
25842
|
title: headerValueTopTitle,
|
|
@@ -26043,7 +26042,7 @@ const ControlsContainer$4 = styled.div`
|
|
|
26043
26042
|
box-sizing: border-box;
|
|
26044
26043
|
}
|
|
26045
26044
|
`;
|
|
26046
|
-
const Controls$
|
|
26045
|
+
const Controls$4 = styled.div`
|
|
26047
26046
|
display: flex;
|
|
26048
26047
|
flex-direction: column;
|
|
26049
26048
|
width: 100%;
|
|
@@ -26269,7 +26268,7 @@ const TotalDoughnutChart = props => {
|
|
|
26269
26268
|
}, legendData.length === 0 || legendData.every(item => item.value === undefined || item.value === null) ? /*#__PURE__*/React$1.createElement(NoDataFoundMessage, {
|
|
26270
26269
|
className: "NoDataFoundMessage",
|
|
26271
26270
|
noDataText: noDataText
|
|
26272
|
-
}) : /*#__PURE__*/React$1.createElement(Controls$
|
|
26271
|
+
}) : /*#__PURE__*/React$1.createElement(Controls$4, {
|
|
26273
26272
|
className: "Controls",
|
|
26274
26273
|
height: height,
|
|
26275
26274
|
width: width
|
|
@@ -28521,7 +28520,7 @@ const ControlsContainer$1 = styled.div`
|
|
|
28521
28520
|
height: ${props => props.height};
|
|
28522
28521
|
min-width: 250px;
|
|
28523
28522
|
`;
|
|
28524
|
-
const Controls$
|
|
28523
|
+
const Controls$3 = styled.div`
|
|
28525
28524
|
height: 100%;
|
|
28526
28525
|
width: 100%;
|
|
28527
28526
|
background: white;
|
|
@@ -28706,7 +28705,7 @@ const BarChart = props => {
|
|
|
28706
28705
|
height: height,
|
|
28707
28706
|
width: width,
|
|
28708
28707
|
ref: controlsContainerRef
|
|
28709
|
-
}, /*#__PURE__*/React$1.createElement(Controls$
|
|
28708
|
+
}, /*#__PURE__*/React$1.createElement(Controls$3, null, /*#__PURE__*/React$1.createElement(Title$3, null, title), /*#__PURE__*/React$1.createElement(ResponsiveContainer, {
|
|
28710
28709
|
width: "100%",
|
|
28711
28710
|
height: 400
|
|
28712
28711
|
}, /*#__PURE__*/React$1.createElement(BarChart$1, {
|
|
@@ -28870,7 +28869,7 @@ const LegendContainer = styled.div`
|
|
|
28870
28869
|
width: ${props => `${props.width}px`};
|
|
28871
28870
|
bottom: 20px;
|
|
28872
28871
|
`;
|
|
28873
|
-
const Controls$
|
|
28872
|
+
const Controls$2 = styled.div`
|
|
28874
28873
|
/* height: calc(100% - 30px); */
|
|
28875
28874
|
height: 100%;
|
|
28876
28875
|
display: flex;
|
|
@@ -29134,7 +29133,7 @@ const DoubleBarSingleLine = props => {
|
|
|
29134
29133
|
hasScroll: hasScroll
|
|
29135
29134
|
}, data.length === 0 ? /*#__PURE__*/React$1.createElement(NoDataFoundMessage, {
|
|
29136
29135
|
noDataText: noDataText
|
|
29137
|
-
}) : /*#__PURE__*/React$1.createElement(Controls$
|
|
29136
|
+
}) : /*#__PURE__*/React$1.createElement(Controls$2, {
|
|
29138
29137
|
className: "Controls"
|
|
29139
29138
|
}, title && title.trim() !== '' && /*#__PURE__*/React$1.createElement(Title$2, null, title), /*#__PURE__*/React$1.createElement(ChartsWrapper, {
|
|
29140
29139
|
width: hasScroll ? `${data.length * 178}px` : 'auto'
|
|
@@ -29224,7 +29223,7 @@ const AreaChartContaner = styled.div`
|
|
|
29224
29223
|
height: ${props => props.height};
|
|
29225
29224
|
min-width: 1100px;
|
|
29226
29225
|
`;
|
|
29227
|
-
const HeaderContainer$
|
|
29226
|
+
const HeaderContainer$2 = styled.div`
|
|
29228
29227
|
display: flex;
|
|
29229
29228
|
justify-content: space-between;
|
|
29230
29229
|
padding: 10px 40px;
|
|
@@ -29283,7 +29282,7 @@ const ControlsContainer = styled.div`
|
|
|
29283
29282
|
font-family: Poppins;
|
|
29284
29283
|
margin: 0;
|
|
29285
29284
|
`;
|
|
29286
|
-
const Controls = styled.div`
|
|
29285
|
+
const Controls$1 = styled.div`
|
|
29287
29286
|
display: flex;
|
|
29288
29287
|
align-items: center;
|
|
29289
29288
|
`;
|
|
@@ -29329,7 +29328,7 @@ const CheckBox = props => {
|
|
|
29329
29328
|
fontSize: fontSize,
|
|
29330
29329
|
width: width,
|
|
29331
29330
|
height: height
|
|
29332
|
-
}, /*#__PURE__*/React$1.createElement(Controls, {
|
|
29331
|
+
}, /*#__PURE__*/React$1.createElement(Controls$1, {
|
|
29333
29332
|
className: "Controls",
|
|
29334
29333
|
"data-testid": "controls"
|
|
29335
29334
|
}, checkedState ? /*#__PURE__*/React$1.createElement(CheckBoxIconContainer, {
|
|
@@ -29561,7 +29560,7 @@ const AreaChart = props => {
|
|
|
29561
29560
|
noDataText: "",
|
|
29562
29561
|
width: width,
|
|
29563
29562
|
height: height
|
|
29564
|
-
}) : /*#__PURE__*/React$1.createElement(React$1.Fragment, null, /*#__PURE__*/React$1.createElement(HeaderContainer$
|
|
29563
|
+
}) : /*#__PURE__*/React$1.createElement(React$1.Fragment, null, /*#__PURE__*/React$1.createElement(HeaderContainer$2, {
|
|
29565
29564
|
"data-testid": "header-container"
|
|
29566
29565
|
}, /*#__PURE__*/React$1.createElement(Title$1, {
|
|
29567
29566
|
"data-testid": "title"
|
|
@@ -30055,7 +30054,7 @@ const BreakdownPanelContainer = styled.div`
|
|
|
30055
30054
|
height: ${props => props.height};
|
|
30056
30055
|
min-width: 1100px;
|
|
30057
30056
|
`;
|
|
30058
|
-
const HeaderContainer = styled.div`
|
|
30057
|
+
const HeaderContainer$1 = styled.div`
|
|
30059
30058
|
display: flex;
|
|
30060
30059
|
justify-content: space-between;
|
|
30061
30060
|
align-items: center;
|
|
@@ -30128,7 +30127,7 @@ const BreakdownPanel = props => {
|
|
|
30128
30127
|
noDataText: "",
|
|
30129
30128
|
width: width,
|
|
30130
30129
|
height: height
|
|
30131
|
-
}) : /*#__PURE__*/React$1.createElement(React$1.Fragment, null, /*#__PURE__*/React$1.createElement(HeaderContainer, {
|
|
30130
|
+
}) : /*#__PURE__*/React$1.createElement(React$1.Fragment, null, /*#__PURE__*/React$1.createElement(HeaderContainer$1, {
|
|
30132
30131
|
"data-testid": "header-container"
|
|
30133
30132
|
}, /*#__PURE__*/React$1.createElement(Title, {
|
|
30134
30133
|
"data-testid": "title"
|
|
@@ -30154,264 +30153,2070 @@ const BreakdownPanel = props => {
|
|
|
30154
30153
|
}))))));
|
|
30155
30154
|
};
|
|
30156
30155
|
|
|
30157
|
-
const
|
|
30158
|
-
|
|
30159
|
-
|
|
30160
|
-
|
|
30161
|
-
|
|
30162
|
-
|
|
30163
|
-
|
|
30164
|
-
|
|
30165
|
-
|
|
30166
|
-
|
|
30167
|
-
|
|
30168
|
-
|
|
30169
|
-
|
|
30170
|
-
|
|
30171
|
-
|
|
30172
|
-
justify-content: space-between;
|
|
30156
|
+
const BubbleChartContainer = styled.div`
|
|
30157
|
+
position: relative;
|
|
30158
|
+
width: ${props => props.width};
|
|
30159
|
+
height: ${props => props.height};
|
|
30160
|
+
display: flex;
|
|
30161
|
+
flex-direction: column;
|
|
30162
|
+
background-color: ${props => props.backgroundColor};
|
|
30163
|
+
border-radius: 8px;
|
|
30164
|
+
padding: 10px;
|
|
30165
|
+
box-sizing: border-box;
|
|
30166
|
+
font-family: "Poppins", sans-serif;
|
|
30167
|
+
min-width: 800px;
|
|
30168
|
+
|
|
30169
|
+
/* Enable proper overflow handling */
|
|
30170
|
+
overflow: hidden;
|
|
30173
30171
|
`;
|
|
30174
|
-
|
|
30175
|
-
|
|
30176
|
-
|
|
30177
|
-
|
|
30172
|
+
styled.div`
|
|
30173
|
+
position: absolute;
|
|
30174
|
+
font-family: "Poppins", sans-serif;
|
|
30175
|
+
font-size: 12px;
|
|
30176
|
+
font-weight: 500;
|
|
30177
|
+
color: #555;
|
|
30178
|
+
text-align: center;
|
|
30179
|
+
|
|
30180
|
+
&.top-left {
|
|
30181
|
+
top: 20px;
|
|
30182
|
+
left: 20px;
|
|
30183
|
+
}
|
|
30184
|
+
|
|
30185
|
+
&.top-right {
|
|
30186
|
+
top: 20px;
|
|
30187
|
+
right: 20px;
|
|
30188
|
+
}
|
|
30189
|
+
|
|
30190
|
+
&.bottom-left {
|
|
30191
|
+
bottom: 20px;
|
|
30192
|
+
left: 20px;
|
|
30193
|
+
}
|
|
30194
|
+
|
|
30195
|
+
&.bottom-right {
|
|
30196
|
+
bottom: 20px;
|
|
30197
|
+
right: 20px;
|
|
30198
|
+
}
|
|
30178
30199
|
`;
|
|
30179
|
-
const
|
|
30180
|
-
|
|
30181
|
-
|
|
30182
|
-
|
|
30183
|
-
|
|
30184
|
-
|
|
30200
|
+
const CustomTooltipContainer = styled.div`
|
|
30201
|
+
background-color: white;
|
|
30202
|
+
border-radius: 6px;
|
|
30203
|
+
z-index: 1000;
|
|
30204
|
+
padding: 10px 14px;
|
|
30205
|
+
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.15);
|
|
30206
|
+
max-width: 220px;
|
|
30207
|
+
font-family: "Poppins", sans-serif;
|
|
30208
|
+
|
|
30209
|
+
h4 {
|
|
30185
30210
|
margin: 0 0 8px;
|
|
30211
|
+
font-size: 14px;
|
|
30212
|
+
font-weight: 600;
|
|
30213
|
+
}
|
|
30214
|
+
|
|
30215
|
+
p {
|
|
30216
|
+
margin: 3px 0;
|
|
30217
|
+
font-size: 12px;
|
|
30218
|
+
color: #555;
|
|
30219
|
+
}
|
|
30220
|
+
|
|
30221
|
+
@media (max-width: 768px) {
|
|
30222
|
+
padding: 8px 12px;
|
|
30223
|
+
max-width: 180px;
|
|
30224
|
+
|
|
30225
|
+
h4 {
|
|
30226
|
+
font-size: 12px;
|
|
30227
|
+
margin: 0 0 6px;
|
|
30228
|
+
}
|
|
30229
|
+
|
|
30230
|
+
p {
|
|
30231
|
+
font-size: 10px;
|
|
30232
|
+
}
|
|
30233
|
+
}
|
|
30186
30234
|
`;
|
|
30187
|
-
const
|
|
30188
|
-
|
|
30189
|
-
|
|
30235
|
+
const TooltipMetric = styled.div`
|
|
30236
|
+
display: flex;
|
|
30237
|
+
justify-content: space-between;
|
|
30238
|
+
margin: 5px 0;
|
|
30239
|
+
font-size: 12px;
|
|
30240
|
+
|
|
30241
|
+
span:last-child {
|
|
30190
30242
|
font-weight: 500;
|
|
30191
|
-
|
|
30192
|
-
|
|
30193
|
-
|
|
30194
|
-
|
|
30195
|
-
|
|
30196
|
-
|
|
30197
|
-
const ChartWrapper = styled.div`
|
|
30198
|
-
position: relative;
|
|
30199
|
-
width: 110px;
|
|
30200
|
-
`;
|
|
30201
|
-
const GoalValue = styled.div`
|
|
30202
|
-
text-align: center;
|
|
30203
|
-
font-size: 18px;
|
|
30204
|
-
color: #8B8989;
|
|
30205
|
-
line-height: 1;
|
|
30206
|
-
&.overload {
|
|
30207
|
-
position: absolute;
|
|
30208
|
-
top: ${props => props.goalValuePosition}px;
|
|
30209
|
-
left: 0;
|
|
30210
|
-
right: 0;
|
|
30211
|
-
z-index: 2;
|
|
30212
|
-
margin: 0 auto;
|
|
30213
|
-
width: 40%;
|
|
30214
|
-
display: inline;
|
|
30215
|
-
padding: 0px 8px;
|
|
30216
|
-
border: 2px solid #F2F2F2;
|
|
30217
|
-
border-bottom: none;
|
|
30218
|
-
border-radius: 6px 6px 0px 0px;
|
|
30219
|
-
background-color: white;
|
|
30220
|
-
}
|
|
30243
|
+
}
|
|
30244
|
+
|
|
30245
|
+
@media (max-width: 768px) {
|
|
30246
|
+
font-size: 10px;
|
|
30247
|
+
margin: 4px 0;
|
|
30248
|
+
}
|
|
30221
30249
|
`;
|
|
30222
|
-
|
|
30223
|
-
|
|
30224
|
-
|
|
30225
|
-
|
|
30226
|
-
transform: translateY(50%);
|
|
30227
|
-
width: calc(100% + 60px);
|
|
30228
|
-
display: flex;
|
|
30229
|
-
gap: 6px;
|
|
30230
|
-
justify-content: center;
|
|
30231
|
-
padding-left: 4px;
|
|
30232
|
-
align-items: center;
|
|
30233
|
-
z-index: 1;
|
|
30250
|
+
styled.div`
|
|
30251
|
+
position: relative;
|
|
30252
|
+
width: 100%;
|
|
30253
|
+
height: 100%;
|
|
30234
30254
|
`;
|
|
30235
|
-
const
|
|
30236
|
-
|
|
30237
|
-
|
|
30238
|
-
|
|
30255
|
+
const HeaderContainer = styled.div`
|
|
30256
|
+
display: flex;
|
|
30257
|
+
justify-content: space-between;
|
|
30258
|
+
align-items: baseline;
|
|
30259
|
+
padding: 0;
|
|
30260
|
+
margin-bottom: 10px;
|
|
30239
30261
|
`;
|
|
30240
|
-
const
|
|
30241
|
-
|
|
30242
|
-
|
|
30243
|
-
|
|
30262
|
+
const ChartTitle = styled.h2`
|
|
30263
|
+
font-family: "Poppins", sans-serif;
|
|
30264
|
+
font-size: 18px;
|
|
30265
|
+
font-weight: 400;
|
|
30266
|
+
margin: 0;
|
|
30267
|
+
color: #212121;
|
|
30244
30268
|
`;
|
|
30245
|
-
const
|
|
30246
|
-
|
|
30269
|
+
const ChartSubtitle = styled.p`
|
|
30270
|
+
font-family: "Poppins", sans-serif;
|
|
30271
|
+
font-size: 14px;
|
|
30272
|
+
font-weight: 500;
|
|
30273
|
+
color: #484A4C;
|
|
30274
|
+
margin: 0;
|
|
30247
30275
|
`;
|
|
30248
|
-
const
|
|
30249
|
-
|
|
30250
|
-
|
|
30251
|
-
|
|
30252
|
-
|
|
30276
|
+
const ChartContainer = styled.div`
|
|
30277
|
+
position: relative;
|
|
30278
|
+
width: 100%;
|
|
30279
|
+
height: 90%; /* Reduced from 93% to make room for the zoom controls */
|
|
30280
|
+
flex: 1;
|
|
30253
30281
|
`;
|
|
30254
|
-
|
|
30255
|
-
|
|
30256
|
-
|
|
30282
|
+
|
|
30283
|
+
/* Updated Zoom Controls Styles to match the new design */
|
|
30284
|
+
const ZoomControlsContainer = styled.div`
|
|
30285
|
+
display: flex;
|
|
30286
|
+
align-items: center;
|
|
30287
|
+
align-self: flex-start;
|
|
30288
|
+
margin-top: 10px;
|
|
30289
|
+
background: linear-gradient(to right, rgba(255, 255, 255, 0.98), rgba(245, 245, 245, 0.92));
|
|
30290
|
+
border-radius: 8px;
|
|
30291
|
+
padding: 6px 6px 6px 12px;
|
|
30292
|
+
box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.1);
|
|
30293
|
+
z-index: 10;
|
|
30294
|
+
font-family: "Poppins", sans-serif;
|
|
30295
|
+
backdrop-filter: blur(8px);
|
|
30296
|
+
transition: background-color 0.3s ease, box-shadow 0.3s ease;
|
|
30257
30297
|
`;
|
|
30258
|
-
const
|
|
30259
|
-
|
|
30260
|
-
|
|
30261
|
-
|
|
30262
|
-
|
|
30298
|
+
const ZoomPercentage = styled.span`
|
|
30299
|
+
font-size: 18px;
|
|
30300
|
+
font-weight: 500;
|
|
30301
|
+
color: #726F6F;
|
|
30302
|
+
margin: 0;
|
|
30303
|
+
min-width: 50px;
|
|
30263
30304
|
`;
|
|
30264
|
-
const
|
|
30265
|
-
|
|
30266
|
-
|
|
30267
|
-
|
|
30268
|
-
|
|
30269
|
-
|
|
30270
|
-
|
|
30271
|
-
|
|
30272
|
-
|
|
30273
|
-
|
|
30274
|
-
|
|
30275
|
-
|
|
30276
|
-
|
|
30277
|
-
|
|
30278
|
-
|
|
30305
|
+
const ZoomButton = styled.button`
|
|
30306
|
+
width: 26px;
|
|
30307
|
+
height: 20px;
|
|
30308
|
+
border: none;
|
|
30309
|
+
background: none;
|
|
30310
|
+
font-size: 24px;
|
|
30311
|
+
font-weight: 500;
|
|
30312
|
+
color: #726F6F;
|
|
30313
|
+
cursor: pointer;
|
|
30314
|
+
display: flex;
|
|
30315
|
+
align-items: center;
|
|
30316
|
+
justify-content: center;
|
|
30317
|
+
padding: 0;
|
|
30318
|
+
margin: 0 ;
|
|
30319
|
+
|
|
30320
|
+
&:hover {
|
|
30321
|
+
color: #333;
|
|
30322
|
+
}
|
|
30323
|
+
|
|
30324
|
+
&:focus {
|
|
30325
|
+
outline: none;
|
|
30326
|
+
}
|
|
30279
30327
|
`;
|
|
30328
|
+
const ZoomResetButton = styled.button`
|
|
30329
|
+
font-family: "Poppins", sans-serif;
|
|
30330
|
+
font-size: 14px;
|
|
30331
|
+
font-weight: 400;
|
|
30332
|
+
height: 32px;
|
|
30333
|
+
padding: 0 12px;
|
|
30334
|
+
margin-left: 5px;
|
|
30335
|
+
border-radius: 8px;
|
|
30336
|
+
background-color: white;
|
|
30337
|
+
border: 1px solid #ddd;
|
|
30338
|
+
cursor: pointer;
|
|
30339
|
+
color: #212121;
|
|
30340
|
+
background: linear-gradient(to right, rgba(255, 255, 255, 0.98), rgba(245, 245, 245, 0.92));
|
|
30341
|
+
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
30342
|
+
transition: all 0.2s ease-in-out;
|
|
30280
30343
|
|
|
30281
|
-
|
|
30344
|
+
&:hover {
|
|
30345
|
+
background: linear-gradient(to right, #f0f0f0, #eaeaea);
|
|
30346
|
+
border-color: #ccc;
|
|
30347
|
+
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
|
|
30348
|
+
}
|
|
30349
|
+
|
|
30350
|
+
&:active {
|
|
30351
|
+
background: #e0e0e0;
|
|
30352
|
+
transform: scale(0.98);
|
|
30353
|
+
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15);
|
|
30354
|
+
}
|
|
30355
|
+
|
|
30356
|
+
&:focus {
|
|
30357
|
+
outline: none;
|
|
30358
|
+
box-shadow: 0 0 0 3px rgba(100, 150, 250, 0.4);
|
|
30359
|
+
}
|
|
30360
|
+
`;
|
|
30361
|
+
|
|
30362
|
+
// Enhanced color palette with bubble-like transparency and gradients
|
|
30363
|
+
const defaultColorPalette = [
|
|
30364
|
+
// Top Left - Yellow Bubbles
|
|
30365
|
+
'rgba(255, 249, 220, 0.7)',
|
|
30366
|
+
// Inner highlight
|
|
30367
|
+
'rgba(255, 235, 165, 0.4)',
|
|
30368
|
+
// Outer edge
|
|
30369
|
+
|
|
30370
|
+
// Top Right - Green Bubbles
|
|
30371
|
+
'rgba(235, 255, 240, 0.7)',
|
|
30372
|
+
// Inner highlight
|
|
30373
|
+
'rgba(190, 235, 200, 0.4)',
|
|
30374
|
+
// Outer edge
|
|
30375
|
+
|
|
30376
|
+
// Bottom Left - Pink Bubbles
|
|
30377
|
+
'rgba(255, 235, 240, 0.7)',
|
|
30378
|
+
// Inner highlight
|
|
30379
|
+
'rgba(255, 190, 200, 0.4)',
|
|
30380
|
+
// Outer edge
|
|
30381
|
+
|
|
30382
|
+
// Bottom Right - Cream/Yellow Bubbles
|
|
30383
|
+
'rgba(255, 250, 230, 0.7)',
|
|
30384
|
+
// Inner highlight
|
|
30385
|
+
'rgba(255, 235, 180, 0.4)' // Outer edge
|
|
30386
|
+
];
|
|
30387
|
+
|
|
30388
|
+
// Main component
|
|
30389
|
+
const BubbleChart = _ref => {
|
|
30390
|
+
let {
|
|
30391
|
+
data = [],
|
|
30392
|
+
title = 'Event Performance Based on Incrementality',
|
|
30393
|
+
subtitle = '* Total cost is reflected by the circle size',
|
|
30394
|
+
leftHeader = 'Low INC Sales ROI',
|
|
30395
|
+
rightHeader = 'High INC Sales ROI',
|
|
30396
|
+
topHeader = 'High INC Sales',
|
|
30397
|
+
bottomHeader = 'Low INC Sales',
|
|
30398
|
+
colorPalette = defaultColorPalette,
|
|
30399
|
+
height = '600px',
|
|
30400
|
+
width = '100%',
|
|
30401
|
+
backgroundColor = 'white',
|
|
30402
|
+
showAxis = false
|
|
30403
|
+
} = _ref;
|
|
30404
|
+
// Calculate the medians and domain for raw X, Y, and Z values
|
|
30282
30405
|
const {
|
|
30283
|
-
|
|
30284
|
-
|
|
30285
|
-
|
|
30286
|
-
|
|
30287
|
-
|
|
30288
|
-
|
|
30289
|
-
|
|
30290
|
-
|
|
30291
|
-
|
|
30292
|
-
|
|
30293
|
-
|
|
30294
|
-
|
|
30295
|
-
|
|
30296
|
-
|
|
30297
|
-
|
|
30298
|
-
} = props;
|
|
30299
|
-
const [top, setTop] = useState(0);
|
|
30300
|
-
const [goalValuePosition, setGoalValuePosition] = useState(0);
|
|
30301
|
-
const [containerHeight, setContainerHeight] = useState(0); // State to store container height
|
|
30302
|
-
const containerRef = useRef(null); // Ref for BatteryChartContainer
|
|
30406
|
+
xMedian,
|
|
30407
|
+
yMedian,
|
|
30408
|
+
xDomain,
|
|
30409
|
+
yDomain,
|
|
30410
|
+
zRange
|
|
30411
|
+
} = useMemo(() => {
|
|
30412
|
+
if (!data || !Array.isArray(data) || data.length === 0) {
|
|
30413
|
+
return {
|
|
30414
|
+
xMedian: 0,
|
|
30415
|
+
yMedian: 0,
|
|
30416
|
+
xDomain: [0, 100],
|
|
30417
|
+
yDomain: [0, 100],
|
|
30418
|
+
zRange: [0, 3600]
|
|
30419
|
+
};
|
|
30420
|
+
}
|
|
30303
30421
|
|
|
30304
|
-
|
|
30305
|
-
|
|
30306
|
-
|
|
30422
|
+
// Extract x, y, and size values
|
|
30423
|
+
const xValues = data.map(item => item.x).filter(x => x !== undefined && x !== null);
|
|
30424
|
+
const yValues = data.map(item => item.y).filter(y => y !== undefined && y !== null);
|
|
30425
|
+
const sizeValues = data.map(item => item.size).filter(size => size !== undefined && size !== null);
|
|
30426
|
+
|
|
30427
|
+
// Calculate min and max values
|
|
30428
|
+
const minX = Math.min(...xValues);
|
|
30429
|
+
const maxX = Math.max(...xValues);
|
|
30430
|
+
const minY = Math.min(...yValues);
|
|
30431
|
+
const maxY = Math.max(...yValues);
|
|
30432
|
+
Math.min(...sizeValues);
|
|
30433
|
+
const maxSize = Math.max(...sizeValues);
|
|
30434
|
+
|
|
30435
|
+
// Calculate medians
|
|
30436
|
+
const calculateMedian = arr => {
|
|
30437
|
+
if (!arr || arr.length === 0) return 0;
|
|
30438
|
+
const sorted = [...arr].sort((a, b) => a - b);
|
|
30439
|
+
const middle = Math.floor(sorted.length / 2);
|
|
30440
|
+
if (sorted.length % 2 === 1) {
|
|
30441
|
+
return sorted[middle];
|
|
30442
|
+
}
|
|
30443
|
+
return (sorted[middle - 1] + sorted[middle]) / 2;
|
|
30444
|
+
};
|
|
30445
|
+
const medianX = calculateMedian(xValues);
|
|
30446
|
+
const medianY = calculateMedian(yValues);
|
|
30307
30447
|
|
|
30308
|
-
|
|
30309
|
-
|
|
30310
|
-
|
|
30311
|
-
|
|
30312
|
-
|
|
30313
|
-
|
|
30314
|
-
|
|
30315
|
-
// Fill from bottom up
|
|
30316
|
-
color: index >= totalSegmentsLines - completedSegments ? color : "#e5e7eb" // Completed or remaining color
|
|
30317
|
-
}));
|
|
30448
|
+
// Calculate domains based on median-centered logic
|
|
30449
|
+
const calculateDomainBasedOnMedian = (min, max, median) => {
|
|
30450
|
+
const distance = Math.max(Math.abs(max - median), Math.abs(min - median));
|
|
30451
|
+
return [median - distance, median + distance];
|
|
30452
|
+
};
|
|
30453
|
+
const xDom = calculateDomainBasedOnMedian(minX, maxX, medianX);
|
|
30454
|
+
const yDom = calculateDomainBasedOnMedian(minY, maxY, medianY);
|
|
30318
30455
|
|
|
30319
|
-
|
|
30320
|
-
|
|
30321
|
-
|
|
30322
|
-
|
|
30323
|
-
|
|
30324
|
-
|
|
30325
|
-
|
|
30326
|
-
|
|
30327
|
-
|
|
30328
|
-
|
|
30329
|
-
}));
|
|
30456
|
+
// Determine z-axis range scaled appropriately
|
|
30457
|
+
const zRng = [0, maxSize * 7];
|
|
30458
|
+
return {
|
|
30459
|
+
xMedian: medianX,
|
|
30460
|
+
yMedian: medianY,
|
|
30461
|
+
xDomain: xDom,
|
|
30462
|
+
yDomain: yDom,
|
|
30463
|
+
zRange: zRng
|
|
30464
|
+
};
|
|
30465
|
+
}, [data]);
|
|
30330
30466
|
|
|
30331
|
-
|
|
30332
|
-
|
|
30333
|
-
|
|
30467
|
+
// Init viewDomain with calculated domain values
|
|
30468
|
+
const fullDomain = useMemo(() => ({
|
|
30469
|
+
x: xDomain,
|
|
30470
|
+
y: yDomain
|
|
30471
|
+
}), [xDomain, yDomain]);
|
|
30334
30472
|
|
|
30335
|
-
//
|
|
30473
|
+
// State for current view domain
|
|
30474
|
+
const [viewDomain, setViewDomain] = useState(fullDomain);
|
|
30475
|
+
const [zoomLevel, setZoomLevel] = useState(100);
|
|
30476
|
+
|
|
30477
|
+
// Drag state
|
|
30478
|
+
const [isDragging, setIsDragging] = useState(false);
|
|
30479
|
+
const [dragStart, setDragStart] = useState({
|
|
30480
|
+
x: 0,
|
|
30481
|
+
y: 0
|
|
30482
|
+
});
|
|
30483
|
+
const [domainStart, setDomainStart] = useState(fullDomain);
|
|
30484
|
+
|
|
30485
|
+
// Refs for the chart container
|
|
30486
|
+
const containerRef = useRef(null);
|
|
30487
|
+
const scatterChartRef = useRef(null);
|
|
30488
|
+
|
|
30489
|
+
// Set up initial domain
|
|
30336
30490
|
useEffect(() => {
|
|
30337
|
-
|
|
30338
|
-
|
|
30339
|
-
|
|
30340
|
-
|
|
30341
|
-
|
|
30342
|
-
|
|
30343
|
-
|
|
30491
|
+
// Set initial viewDomain from fullDomain
|
|
30492
|
+
setViewDomain(fullDomain);
|
|
30493
|
+
}, [fullDomain]);
|
|
30494
|
+
|
|
30495
|
+
// Function to get gradient fill based on quadrant
|
|
30496
|
+
const getFill = useCallback((x, y) => {
|
|
30497
|
+
if (x < xMedian && y > yMedian) return 'url(#topLeftGradient)'; // Top Left
|
|
30498
|
+
if (x >= xMedian && y > yMedian) return 'url(#topRightGradient)'; // Top Right
|
|
30499
|
+
if (x < xMedian && y <= yMedian) return 'url(#bottomLeftGradient)'; // Bottom Left
|
|
30500
|
+
if (x >= xMedian && y <= yMedian) return 'url(#bottomRightGradient)'; // Bottom Right
|
|
30501
|
+
return 'gray'; // fallback
|
|
30502
|
+
}, [xMedian, yMedian]);
|
|
30503
|
+
|
|
30504
|
+
// CustomTooltip component inside BubbleChart
|
|
30505
|
+
const CustomTooltip = useCallback(_ref2 => {
|
|
30506
|
+
let {
|
|
30507
|
+
active,
|
|
30508
|
+
payload
|
|
30509
|
+
} = _ref2;
|
|
30510
|
+
if (active && payload && payload.length && payload[0].payload.tooltip) {
|
|
30511
|
+
const data = payload[0].payload;
|
|
30512
|
+
return /*#__PURE__*/React$1.createElement(CustomTooltipContainer, {
|
|
30513
|
+
"data-testid": "tooltip-container"
|
|
30514
|
+
}, /*#__PURE__*/React$1.createElement("h4", {
|
|
30515
|
+
"data-testid": "tooltip-title"
|
|
30516
|
+
}, data.tooltip.title), data.tooltip.description && /*#__PURE__*/React$1.createElement(TooltipMetric, {
|
|
30517
|
+
"data-testid": "tooltip-description"
|
|
30518
|
+
}, /*#__PURE__*/React$1.createElement("span", null, data.tooltip.description)), /*#__PURE__*/React$1.createElement(TooltipMetric, {
|
|
30519
|
+
"data-testid": "tooltip-cost"
|
|
30520
|
+
}, /*#__PURE__*/React$1.createElement("span", null, "Total cost:"), /*#__PURE__*/React$1.createElement("span", null, formatCurrency(data.tooltip.cost))), /*#__PURE__*/React$1.createElement(TooltipMetric, {
|
|
30521
|
+
"data-testid": "tooltip-sales"
|
|
30522
|
+
}, /*#__PURE__*/React$1.createElement("span", null, "INC Sales:"), /*#__PURE__*/React$1.createElement("span", null, formatCurrency(data.tooltip.incSales))), /*#__PURE__*/React$1.createElement(TooltipMetric, {
|
|
30523
|
+
"data-testid": "tooltip-roi"
|
|
30524
|
+
}, /*#__PURE__*/React$1.createElement("span", null, "INC Sales ROI:"), /*#__PURE__*/React$1.createElement("span", null, formatROI(data.tooltip.roi))), /*#__PURE__*/React$1.createElement(TooltipMetric, {
|
|
30525
|
+
"data-testid": "tooltip-units"
|
|
30526
|
+
}, /*#__PURE__*/React$1.createElement("span", null, "INC Units:"), /*#__PURE__*/React$1.createElement("span", null, formatUnits(data.tooltip.units))));
|
|
30527
|
+
}
|
|
30528
|
+
return null;
|
|
30529
|
+
}, []);
|
|
30344
30530
|
|
|
30345
|
-
|
|
30346
|
-
|
|
30531
|
+
// Process all chart data - use original data values
|
|
30532
|
+
const allChartData = useMemo(() => {
|
|
30533
|
+
return data.map((item, index) => {
|
|
30534
|
+
if (item.x === undefined || item.y === undefined || item.size === undefined) {
|
|
30535
|
+
console.warn('Skipping data item with missing values:', item);
|
|
30536
|
+
return null;
|
|
30537
|
+
}
|
|
30538
|
+
const tooltipInfo = {
|
|
30539
|
+
title: item.name || 'Marketing event',
|
|
30540
|
+
description: item.description || '',
|
|
30541
|
+
cost: item.size || 0,
|
|
30542
|
+
units: item.units || 0,
|
|
30543
|
+
roi: item.x || 0,
|
|
30544
|
+
incSales: item.y || 0,
|
|
30545
|
+
...(item.tooltip || {})
|
|
30546
|
+
};
|
|
30547
|
+
return {
|
|
30548
|
+
x: item.x,
|
|
30549
|
+
// Use original x value
|
|
30550
|
+
y: item.y,
|
|
30551
|
+
// Use original y value
|
|
30552
|
+
z: item.size,
|
|
30553
|
+
// Use original size value
|
|
30554
|
+
tooltip: tooltipInfo,
|
|
30555
|
+
fill: getFill(item.x, item.y),
|
|
30556
|
+
key: `bubble-${index}` // Use index for stable keys
|
|
30557
|
+
};
|
|
30558
|
+
}).filter(Boolean); // Filter out null items
|
|
30559
|
+
}, [data, getFill]);
|
|
30560
|
+
|
|
30561
|
+
// Function to determine which data points should be visible
|
|
30562
|
+
const getVisibleData = useCallback(() => {
|
|
30563
|
+
return allChartData.filter(item => item.x >= viewDomain.x[0] && item.x <= viewDomain.x[1] && item.y >= viewDomain.y[0] && item.y <= viewDomain.y[1]);
|
|
30564
|
+
}, [allChartData, viewDomain]);
|
|
30565
|
+
|
|
30566
|
+
// Get visible data - memoized
|
|
30567
|
+
const visibleData = useMemo(() => getVisibleData(), [getVisibleData]);
|
|
30568
|
+
|
|
30569
|
+
// Calculate a new domain based on zoom level and center point - memoized
|
|
30570
|
+
const calculateDomain = useCallback((center, zoomFactor) => {
|
|
30571
|
+
// Calculate new domain size
|
|
30572
|
+
const xSize = (fullDomain.x[1] - fullDomain.x[0]) * zoomFactor;
|
|
30573
|
+
const ySize = (fullDomain.y[1] - fullDomain.y[0]) * zoomFactor;
|
|
30574
|
+
|
|
30575
|
+
// Calculate new domain
|
|
30576
|
+
return {
|
|
30577
|
+
x: [center.x - xSize / 2, center.x + xSize / 2],
|
|
30578
|
+
y: [center.y - ySize / 2, center.y + ySize / 2]
|
|
30579
|
+
};
|
|
30580
|
+
}, [fullDomain]);
|
|
30581
|
+
|
|
30582
|
+
// Rendering gradients with enhanced bubble-like appearance
|
|
30583
|
+
const renderGradients = useCallback(() => /*#__PURE__*/React$1.createElement("defs", null, /*#__PURE__*/React$1.createElement("radialGradient", {
|
|
30584
|
+
id: "topLeftGradient",
|
|
30585
|
+
cx: "25%",
|
|
30586
|
+
cy: "25%",
|
|
30587
|
+
r: "70%",
|
|
30588
|
+
fx: "20%",
|
|
30589
|
+
fy: "20%"
|
|
30590
|
+
}, /*#__PURE__*/React$1.createElement("stop", {
|
|
30591
|
+
offset: "0%",
|
|
30592
|
+
stopColor: colorPalette[0]
|
|
30593
|
+
}), /*#__PURE__*/React$1.createElement("stop", {
|
|
30594
|
+
offset: "85%",
|
|
30595
|
+
stopColor: colorPalette[1]
|
|
30596
|
+
})), /*#__PURE__*/React$1.createElement("radialGradient", {
|
|
30597
|
+
id: "topRightGradient",
|
|
30598
|
+
cx: "25%",
|
|
30599
|
+
cy: "25%",
|
|
30600
|
+
r: "70%",
|
|
30601
|
+
fx: "20%",
|
|
30602
|
+
fy: "20%"
|
|
30603
|
+
}, /*#__PURE__*/React$1.createElement("stop", {
|
|
30604
|
+
offset: "0%",
|
|
30605
|
+
stopColor: colorPalette[2]
|
|
30606
|
+
}), /*#__PURE__*/React$1.createElement("stop", {
|
|
30607
|
+
offset: "85%",
|
|
30608
|
+
stopColor: colorPalette[3]
|
|
30609
|
+
})), /*#__PURE__*/React$1.createElement("radialGradient", {
|
|
30610
|
+
id: "bottomLeftGradient",
|
|
30611
|
+
cx: "25%",
|
|
30612
|
+
cy: "25%",
|
|
30613
|
+
r: "70%",
|
|
30614
|
+
fx: "20%",
|
|
30615
|
+
fy: "20%"
|
|
30616
|
+
}, /*#__PURE__*/React$1.createElement("stop", {
|
|
30617
|
+
offset: "0%",
|
|
30618
|
+
stopColor: colorPalette[4]
|
|
30619
|
+
}), /*#__PURE__*/React$1.createElement("stop", {
|
|
30620
|
+
offset: "85%",
|
|
30621
|
+
stopColor: colorPalette[5]
|
|
30622
|
+
})), /*#__PURE__*/React$1.createElement("radialGradient", {
|
|
30623
|
+
id: "bottomRightGradient",
|
|
30624
|
+
cx: "25%",
|
|
30625
|
+
cy: "25%",
|
|
30626
|
+
r: "70%",
|
|
30627
|
+
fx: "20%",
|
|
30628
|
+
fy: "20%"
|
|
30629
|
+
}, /*#__PURE__*/React$1.createElement("stop", {
|
|
30630
|
+
offset: "0%",
|
|
30631
|
+
stopColor: colorPalette[6]
|
|
30632
|
+
}), /*#__PURE__*/React$1.createElement("stop", {
|
|
30633
|
+
offset: "85%",
|
|
30634
|
+
stopColor: colorPalette[7]
|
|
30635
|
+
})), /*#__PURE__*/React$1.createElement("filter", {
|
|
30636
|
+
id: "bubble-blur",
|
|
30637
|
+
x: "-50%",
|
|
30638
|
+
y: "-50%",
|
|
30639
|
+
width: "200%",
|
|
30640
|
+
height: "200%"
|
|
30641
|
+
}, /*#__PURE__*/React$1.createElement("feGaussianBlur", {
|
|
30642
|
+
in: "SourceGraphic",
|
|
30643
|
+
stdDeviation: "0.3"
|
|
30644
|
+
}))), [colorPalette]);
|
|
30645
|
+
|
|
30646
|
+
// Handle mouse down for dragging
|
|
30647
|
+
const handleMouseDown = useCallback(e => {
|
|
30648
|
+
if (containerRef.current?.contains(e.target)) {
|
|
30649
|
+
setIsDragging(true);
|
|
30650
|
+
setDragStart({
|
|
30651
|
+
x: e.clientX,
|
|
30652
|
+
y: e.clientY
|
|
30653
|
+
});
|
|
30654
|
+
setDomainStart({
|
|
30655
|
+
...viewDomain
|
|
30656
|
+
}); // Store current domain, not fullDomain
|
|
30657
|
+
e.preventDefault();
|
|
30658
|
+
}
|
|
30659
|
+
}, [viewDomain]); // Add viewDomain as dependency to capture current value
|
|
30660
|
+
|
|
30661
|
+
// Handle mouse move for dragging
|
|
30662
|
+
const handleMouseMove = useCallback(e => {
|
|
30663
|
+
if (!isDragging) return;
|
|
30664
|
+
const dx = e.clientX - dragStart.x;
|
|
30665
|
+
const dy = e.clientY - dragStart.y;
|
|
30666
|
+
const containerWidth = containerRef.current?.clientWidth || 800;
|
|
30667
|
+
const containerHeight = containerRef.current?.clientHeight || 600;
|
|
30668
|
+
|
|
30669
|
+
// Calculate the domain range from the domainStart (which preserves zoom level)
|
|
30670
|
+
const xRange = domainStart.x[1] - domainStart.x[0];
|
|
30671
|
+
const yRange = domainStart.y[1] - domainStart.y[0];
|
|
30672
|
+
|
|
30673
|
+
// Calculate the shift amount (negative for dx to make drag direction feel natural)
|
|
30674
|
+
const xShift = -(dx / containerWidth) * xRange * 1.5; // Multiply by 1.5 to make dragging more responsive
|
|
30675
|
+
const yShift = dy / containerHeight * yRange * 1.5; // Y is inverted in charts
|
|
30676
|
+
|
|
30677
|
+
// Create new domain values based on the domainStart (preserves zoom level)
|
|
30678
|
+
const newXDomain = [domainStart.x[0] + xShift, domainStart.x[1] + xShift];
|
|
30679
|
+
const newYDomain = [domainStart.y[0] + yShift, domainStart.y[1] + yShift];
|
|
30680
|
+
|
|
30681
|
+
// Update the domain
|
|
30682
|
+
setViewDomain({
|
|
30683
|
+
x: newXDomain,
|
|
30684
|
+
y: newYDomain
|
|
30685
|
+
});
|
|
30686
|
+
}, [isDragging, dragStart, domainStart]);
|
|
30687
|
+
|
|
30688
|
+
// Handle mouse up for dragging
|
|
30689
|
+
const handleMouseUp = useCallback(() => {
|
|
30690
|
+
setIsDragging(false);
|
|
30691
|
+
}, []);
|
|
30692
|
+
|
|
30693
|
+
// Handle zoom in
|
|
30694
|
+
const handleZoomIn = useCallback(() => {
|
|
30695
|
+
if (zoomLevel >= 400) return;
|
|
30696
|
+
const newZoomLevel = zoomLevel + 20;
|
|
30697
|
+
setZoomLevel(newZoomLevel);
|
|
30698
|
+
|
|
30699
|
+
// Calculate zoom factor (smaller factor = more zoomed in)
|
|
30700
|
+
const zoomFactor = 100 / newZoomLevel;
|
|
30701
|
+
|
|
30702
|
+
// Get current domain center
|
|
30703
|
+
const centerX = (viewDomain.x[0] + viewDomain.x[1]) / 2;
|
|
30704
|
+
const centerY = (viewDomain.y[0] + viewDomain.y[1]) / 2;
|
|
30705
|
+
|
|
30706
|
+
// Calculate new domain
|
|
30707
|
+
const newDomain = calculateDomain({
|
|
30708
|
+
x: centerX,
|
|
30709
|
+
y: centerY
|
|
30710
|
+
}, zoomFactor);
|
|
30711
|
+
|
|
30712
|
+
// Update domain
|
|
30713
|
+
setViewDomain(newDomain);
|
|
30714
|
+
}, [zoomLevel, viewDomain, calculateDomain]);
|
|
30715
|
+
|
|
30716
|
+
// Handle zoom out
|
|
30717
|
+
const handleZoomOut = useCallback(() => {
|
|
30718
|
+
if (zoomLevel <= 50) return;
|
|
30719
|
+
const newZoomLevel = zoomLevel - 20;
|
|
30720
|
+
|
|
30721
|
+
// If returning to 100%, reset to full domain
|
|
30722
|
+
if (newZoomLevel === 100) {
|
|
30723
|
+
setViewDomain({
|
|
30724
|
+
...fullDomain
|
|
30725
|
+
});
|
|
30726
|
+
setZoomLevel(100);
|
|
30727
|
+
return;
|
|
30728
|
+
}
|
|
30729
|
+
setZoomLevel(newZoomLevel);
|
|
30730
|
+
|
|
30731
|
+
// Calculate zoom factor (larger factor = more zoomed out)
|
|
30732
|
+
const zoomFactor = 100 / newZoomLevel;
|
|
30733
|
+
|
|
30734
|
+
// Get current domain center
|
|
30735
|
+
const centerX = (viewDomain.x[0] + viewDomain.x[1]) / 2;
|
|
30736
|
+
const centerY = (viewDomain.y[0] + viewDomain.y[1]) / 2;
|
|
30737
|
+
|
|
30738
|
+
// Calculate new domain size
|
|
30739
|
+
const xSize = (fullDomain.x[1] - fullDomain.x[0]) * zoomFactor;
|
|
30740
|
+
const ySize = (fullDomain.y[1] - fullDomain.y[0]) * zoomFactor;
|
|
30741
|
+
|
|
30742
|
+
// If new domain would be larger than full domain, reset to full
|
|
30743
|
+
if (xSize >= fullDomain.x[1] - fullDomain.x[0] || ySize >= fullDomain.y[1] - fullDomain.y[0]) {
|
|
30744
|
+
setViewDomain({
|
|
30745
|
+
...fullDomain
|
|
30746
|
+
});
|
|
30747
|
+
setZoomLevel(100);
|
|
30748
|
+
return;
|
|
30749
|
+
}
|
|
30750
|
+
|
|
30751
|
+
// Calculate new domain
|
|
30752
|
+
const newDomain = calculateDomain({
|
|
30753
|
+
x: centerX,
|
|
30754
|
+
y: centerY
|
|
30755
|
+
}, zoomFactor);
|
|
30756
|
+
|
|
30757
|
+
// Update domain
|
|
30758
|
+
setViewDomain(newDomain);
|
|
30759
|
+
}, [zoomLevel, viewDomain, fullDomain, calculateDomain]);
|
|
30760
|
+
|
|
30761
|
+
// Handle reset
|
|
30762
|
+
const handleReset = useCallback(() => {
|
|
30763
|
+
setZoomLevel(100);
|
|
30764
|
+
setViewDomain({
|
|
30765
|
+
...fullDomain
|
|
30766
|
+
});
|
|
30767
|
+
}, [fullDomain]);
|
|
30768
|
+
|
|
30769
|
+
// Handle mouse wheel
|
|
30770
|
+
const handleWheel = useCallback(e => {
|
|
30771
|
+
e.preventDefault();
|
|
30772
|
+
if (e.deltaY < 0) {
|
|
30773
|
+
handleZoomIn();
|
|
30347
30774
|
} else {
|
|
30348
|
-
|
|
30349
|
-
newTop = (totalSegmentsLines - completedSegments) * barHeight / 1.65;
|
|
30350
|
-
// Position the goal value just above the active chips
|
|
30351
|
-
newGoalValuePosition = newTop;
|
|
30775
|
+
handleZoomOut();
|
|
30352
30776
|
}
|
|
30353
|
-
|
|
30354
|
-
|
|
30355
|
-
|
|
30777
|
+
}, [handleZoomIn, handleZoomOut]);
|
|
30778
|
+
|
|
30779
|
+
// Memoize the visibility condition for the middle value label
|
|
30780
|
+
const isMiddleValueVisible = useMemo(() => xMedian >= viewDomain.x[0] && xMedian <= viewDomain.x[1] && yMedian >= viewDomain.y[0] && yMedian <= viewDomain.y[1], [viewDomain, xMedian, yMedian]);
|
|
30781
|
+
|
|
30782
|
+
// Set up event listeners
|
|
30356
30783
|
useEffect(() => {
|
|
30357
|
-
|
|
30358
|
-
|
|
30359
|
-
|
|
30360
|
-
|
|
30361
|
-
|
|
30784
|
+
const container = containerRef.current;
|
|
30785
|
+
if (!container) return;
|
|
30786
|
+
container.addEventListener('wheel', handleWheel, {
|
|
30787
|
+
passive: false
|
|
30788
|
+
});
|
|
30789
|
+
container.addEventListener('mousedown', handleMouseDown);
|
|
30790
|
+
window.addEventListener('mousemove', handleMouseMove);
|
|
30791
|
+
window.addEventListener('mouseup', handleMouseUp);
|
|
30792
|
+
return () => {
|
|
30793
|
+
container.removeEventListener('wheel', handleWheel);
|
|
30794
|
+
container.removeEventListener('mousedown', handleMouseDown);
|
|
30795
|
+
window.removeEventListener('mousemove', handleMouseMove);
|
|
30796
|
+
window.removeEventListener('mouseup', handleMouseUp);
|
|
30797
|
+
};
|
|
30798
|
+
}, [handleWheel, handleMouseDown, handleMouseMove, handleMouseUp]);
|
|
30799
|
+
|
|
30800
|
+
// Unified arrow component with direction parameter
|
|
30801
|
+
const Arrow = _ref3 => {
|
|
30802
|
+
let {
|
|
30803
|
+
viewBox,
|
|
30804
|
+
direction
|
|
30805
|
+
} = _ref3;
|
|
30806
|
+
// Define points based on direction
|
|
30807
|
+
let points = '';
|
|
30808
|
+
switch (direction) {
|
|
30809
|
+
case 'top':
|
|
30810
|
+
points = `${viewBox.x},${viewBox.y - 10} ${viewBox.x - 5},${viewBox.y} ${viewBox.x + 5},${viewBox.y}`;
|
|
30811
|
+
break;
|
|
30812
|
+
case 'bottom':
|
|
30813
|
+
points = `${viewBox.x},${viewBox.y + viewBox.height + 10} ${viewBox.x - 5},${viewBox.y + viewBox.height} ${viewBox.x + 5},${viewBox.y + viewBox.height}`;
|
|
30814
|
+
break;
|
|
30815
|
+
case 'left':
|
|
30816
|
+
points = `${viewBox.x - 10},${viewBox.y} ${viewBox.x},${viewBox.y - 5} ${viewBox.x},${viewBox.y + 5}`;
|
|
30817
|
+
break;
|
|
30818
|
+
case 'right':
|
|
30819
|
+
points = `${viewBox.x + viewBox.width + 10},${viewBox.y} ${viewBox.x + viewBox.width},${viewBox.y - 5} ${viewBox.x + viewBox.width},${viewBox.y + 5}`;
|
|
30820
|
+
break;
|
|
30362
30821
|
}
|
|
30363
|
-
|
|
30364
|
-
|
|
30365
|
-
|
|
30822
|
+
return /*#__PURE__*/React$1.createElement("polygon", {
|
|
30823
|
+
points: points,
|
|
30824
|
+
fill: "#D0D0D0"
|
|
30825
|
+
});
|
|
30826
|
+
};
|
|
30827
|
+
|
|
30828
|
+
// Function to format currency values
|
|
30829
|
+
const formatCurrency = value => {
|
|
30830
|
+
if (Math.abs(value) >= 1000000) {
|
|
30831
|
+
return `$${(value / 1000000).toFixed(1)}M`;
|
|
30832
|
+
} else if (Math.abs(value) >= 1000) {
|
|
30833
|
+
return `$${(value / 1000).toFixed(1)}K`;
|
|
30834
|
+
}
|
|
30835
|
+
return `$${value.toFixed(1)}`;
|
|
30836
|
+
};
|
|
30837
|
+
|
|
30838
|
+
// Function to format units values
|
|
30839
|
+
const formatUnits = value => {
|
|
30840
|
+
if (Math.abs(value) >= 1000000) {
|
|
30841
|
+
return `${(value / 1000000).toFixed(1)}M`;
|
|
30842
|
+
} else if (Math.abs(value) >= 1000) {
|
|
30843
|
+
return `${(value / 1000).toFixed(1)}K`;
|
|
30844
|
+
}
|
|
30845
|
+
return `${value.toFixed(1)}`;
|
|
30846
|
+
};
|
|
30847
|
+
|
|
30848
|
+
// Function to format ROI values
|
|
30849
|
+
const formatROI = value => {
|
|
30850
|
+
return value.toFixed(1);
|
|
30851
|
+
};
|
|
30852
|
+
|
|
30853
|
+
// Format the median values for display
|
|
30854
|
+
const formattedMedianValue = useMemo(() => {
|
|
30855
|
+
const formattedX = formatROI(xMedian);
|
|
30856
|
+
const formattedY = formatUnits(yMedian);
|
|
30857
|
+
return `${formattedX}, ${formattedY}`;
|
|
30858
|
+
}, [xMedian, yMedian]);
|
|
30859
|
+
|
|
30860
|
+
// Render the component
|
|
30861
|
+
return /*#__PURE__*/React$1.createElement(BubbleChartContainer, {
|
|
30366
30862
|
width: width,
|
|
30367
30863
|
height: height,
|
|
30368
|
-
|
|
30369
|
-
|
|
30370
|
-
|
|
30371
|
-
|
|
30372
|
-
|
|
30373
|
-
|
|
30374
|
-
|
|
30375
|
-
|
|
30376
|
-
|
|
30377
|
-
|
|
30378
|
-
},
|
|
30379
|
-
|
|
30380
|
-
}, /*#__PURE__*/React$1.createElement(
|
|
30381
|
-
|
|
30382
|
-
|
|
30383
|
-
|
|
30384
|
-
|
|
30385
|
-
height:
|
|
30386
|
-
|
|
30387
|
-
|
|
30388
|
-
layout: "vertical",
|
|
30864
|
+
ref: containerRef,
|
|
30865
|
+
style: {
|
|
30866
|
+
cursor: isDragging ? 'grabbing' : 'grab'
|
|
30867
|
+
},
|
|
30868
|
+
backgroundColor: backgroundColor,
|
|
30869
|
+
"data-testid": "bubble-chart-container"
|
|
30870
|
+
}, /*#__PURE__*/React$1.createElement(HeaderContainer, {
|
|
30871
|
+
"data-testid": "header-container"
|
|
30872
|
+
}, /*#__PURE__*/React$1.createElement(ChartTitle, {
|
|
30873
|
+
"data-testid": "chart-title"
|
|
30874
|
+
}, title), /*#__PURE__*/React$1.createElement(ChartSubtitle, {
|
|
30875
|
+
"data-testid": "chart-subtitle"
|
|
30876
|
+
}, subtitle)), /*#__PURE__*/React$1.createElement(ChartContainer, {
|
|
30877
|
+
ref: scatterChartRef,
|
|
30878
|
+
"data-testid": "chart-container"
|
|
30879
|
+
}, /*#__PURE__*/React$1.createElement(ResponsiveContainer, {
|
|
30880
|
+
width: "100%",
|
|
30881
|
+
height: "100%",
|
|
30882
|
+
"data-testid": "responsive-container"
|
|
30883
|
+
}, /*#__PURE__*/React$1.createElement(ScatterChart, {
|
|
30389
30884
|
margin: {
|
|
30390
|
-
top:
|
|
30391
|
-
right:
|
|
30392
|
-
|
|
30393
|
-
|
|
30885
|
+
top: 60,
|
|
30886
|
+
right: 190,
|
|
30887
|
+
bottom: 50,
|
|
30888
|
+
left: 180
|
|
30394
30889
|
},
|
|
30395
|
-
|
|
30396
|
-
}, /*#__PURE__*/React$1.createElement(XAxis, {
|
|
30890
|
+
"data-testid": "scatter-chart"
|
|
30891
|
+
}, renderGradients(), /*#__PURE__*/React$1.createElement(XAxis, {
|
|
30397
30892
|
type: "number",
|
|
30398
|
-
|
|
30399
|
-
domain:
|
|
30893
|
+
dataKey: "x",
|
|
30894
|
+
domain: viewDomain.x,
|
|
30895
|
+
axisLine: showAxis,
|
|
30896
|
+
tickLine: showAxis,
|
|
30897
|
+
tick: showAxis ? {
|
|
30898
|
+
fontSize: 10,
|
|
30899
|
+
fontWeight: 400,
|
|
30900
|
+
fontFamily: 'Poppins'
|
|
30901
|
+
} : false,
|
|
30902
|
+
tickFormatter: value => formatUnits(value),
|
|
30903
|
+
hide: !showAxis,
|
|
30904
|
+
"data-testid": "x-axis",
|
|
30905
|
+
style: {
|
|
30906
|
+
fontSize: '10px',
|
|
30907
|
+
fontWeight: 400,
|
|
30908
|
+
fontFamily: 'Poppins'
|
|
30909
|
+
}
|
|
30400
30910
|
}), /*#__PURE__*/React$1.createElement(YAxis, {
|
|
30401
|
-
type: "
|
|
30402
|
-
|
|
30403
|
-
|
|
30404
|
-
|
|
30405
|
-
|
|
30406
|
-
|
|
30407
|
-
|
|
30408
|
-
|
|
30409
|
-
|
|
30410
|
-
|
|
30411
|
-
|
|
30412
|
-
|
|
30413
|
-
|
|
30911
|
+
type: "number",
|
|
30912
|
+
dataKey: "y",
|
|
30913
|
+
domain: viewDomain.y,
|
|
30914
|
+
axisLine: showAxis,
|
|
30915
|
+
tickLine: showAxis,
|
|
30916
|
+
tick: showAxis ? {
|
|
30917
|
+
fontSize: 10,
|
|
30918
|
+
fontWeight: 400,
|
|
30919
|
+
fontFamily: 'Poppins'
|
|
30920
|
+
} : false,
|
|
30921
|
+
tickFormatter: value => formatUnits(value),
|
|
30922
|
+
hide: !showAxis,
|
|
30923
|
+
"data-testid": "y-axis",
|
|
30924
|
+
style: {
|
|
30925
|
+
fontSize: '10px',
|
|
30926
|
+
fontWeight: 400,
|
|
30927
|
+
fontFamily: 'Poppins'
|
|
30928
|
+
}
|
|
30929
|
+
}), /*#__PURE__*/React$1.createElement(ZAxis, {
|
|
30930
|
+
type: "number",
|
|
30931
|
+
dataKey: "z",
|
|
30932
|
+
range: [0, 7000],
|
|
30933
|
+
domain: [0, Math.max(...data.map(item => item.size || 0))],
|
|
30934
|
+
"data-testid": "z-axis"
|
|
30935
|
+
}), /*#__PURE__*/React$1.createElement(ReferenceLine, {
|
|
30936
|
+
x: xMedian,
|
|
30937
|
+
stroke: "#D0D0D0",
|
|
30938
|
+
strokeDasharray: "4 4",
|
|
30939
|
+
isFront: false,
|
|
30940
|
+
"data-testid": "reference-line-x",
|
|
30941
|
+
label: xMedian >= viewDomain.x[0] && xMedian <= viewDomain.x[1] ? {
|
|
30942
|
+
value: topHeader,
|
|
30943
|
+
position: "top",
|
|
30944
|
+
offset: 40,
|
|
30945
|
+
fill: '#484A4C',
|
|
30946
|
+
fontSize: 16,
|
|
30947
|
+
fontWeight: 500
|
|
30948
|
+
} : null
|
|
30949
|
+
}), xMedian >= viewDomain.x[0] && xMedian <= viewDomain.x[1] && /*#__PURE__*/React$1.createElement(ReferenceLine, {
|
|
30950
|
+
x: xMedian,
|
|
30951
|
+
stroke: "transparent",
|
|
30952
|
+
isFront: true,
|
|
30953
|
+
label: _ref4 => {
|
|
30954
|
+
let {
|
|
30955
|
+
viewBox
|
|
30956
|
+
} = _ref4;
|
|
30957
|
+
return /*#__PURE__*/React$1.createElement(Arrow, {
|
|
30958
|
+
viewBox: viewBox,
|
|
30959
|
+
direction: "top"
|
|
30960
|
+
});
|
|
30961
|
+
}
|
|
30962
|
+
}), /*#__PURE__*/React$1.createElement(ReferenceLine, {
|
|
30963
|
+
x: xMedian,
|
|
30964
|
+
stroke: "transparent",
|
|
30965
|
+
isFront: false,
|
|
30966
|
+
"data-testid": "reference-line-x-bottom",
|
|
30967
|
+
label: xMedian >= viewDomain.x[0] && xMedian <= viewDomain.x[1] ? {
|
|
30968
|
+
value: bottomHeader,
|
|
30969
|
+
position: "bottom",
|
|
30970
|
+
offset: 30,
|
|
30971
|
+
fill: '#484A4C',
|
|
30972
|
+
fontSize: 16,
|
|
30973
|
+
fontWeight: 500
|
|
30974
|
+
} : null
|
|
30975
|
+
}), xMedian >= viewDomain.x[0] && xMedian <= viewDomain.x[1] && /*#__PURE__*/React$1.createElement(ReferenceLine, {
|
|
30976
|
+
x: xMedian,
|
|
30977
|
+
stroke: "transparent",
|
|
30978
|
+
isFront: true,
|
|
30979
|
+
label: _ref5 => {
|
|
30980
|
+
let {
|
|
30981
|
+
viewBox
|
|
30982
|
+
} = _ref5;
|
|
30983
|
+
return /*#__PURE__*/React$1.createElement(Arrow, {
|
|
30984
|
+
viewBox: viewBox,
|
|
30985
|
+
direction: "bottom"
|
|
30986
|
+
});
|
|
30987
|
+
}
|
|
30988
|
+
}), /*#__PURE__*/React$1.createElement(ReferenceLine, {
|
|
30989
|
+
y: yMedian,
|
|
30990
|
+
stroke: "#D0D0D0",
|
|
30991
|
+
strokeDasharray: "4 4",
|
|
30992
|
+
isFront: false,
|
|
30993
|
+
"data-testid": "reference-line-y",
|
|
30994
|
+
label: yMedian >= viewDomain.y[0] && yMedian <= viewDomain.y[1] ? {
|
|
30995
|
+
value: leftHeader,
|
|
30996
|
+
position: "left",
|
|
30997
|
+
offset: 30,
|
|
30998
|
+
fill: '#484A4C',
|
|
30999
|
+
fontSize: 16,
|
|
31000
|
+
fontWeight: 500
|
|
31001
|
+
} : null
|
|
31002
|
+
}), yMedian >= viewDomain.y[0] && yMedian <= viewDomain.y[1] && /*#__PURE__*/React$1.createElement(ReferenceLine, {
|
|
31003
|
+
y: yMedian,
|
|
31004
|
+
isFront: true,
|
|
31005
|
+
stroke: "transparent",
|
|
31006
|
+
label: _ref6 => {
|
|
31007
|
+
let {
|
|
31008
|
+
viewBox
|
|
31009
|
+
} = _ref6;
|
|
31010
|
+
return /*#__PURE__*/React$1.createElement(Arrow, {
|
|
31011
|
+
viewBox: viewBox,
|
|
31012
|
+
direction: "left"
|
|
31013
|
+
});
|
|
31014
|
+
}
|
|
31015
|
+
}), /*#__PURE__*/React$1.createElement(ReferenceLine, {
|
|
31016
|
+
y: yMedian,
|
|
31017
|
+
stroke: "transparent",
|
|
31018
|
+
isFront: false,
|
|
31019
|
+
"data-testid": "reference-line-y-transparent",
|
|
31020
|
+
label: yMedian >= viewDomain.y[0] && yMedian <= viewDomain.y[1] ? {
|
|
31021
|
+
value: rightHeader,
|
|
31022
|
+
position: "right",
|
|
31023
|
+
offset: 30,
|
|
31024
|
+
fill: '#484A4C',
|
|
31025
|
+
fontSize: 16,
|
|
31026
|
+
fontWeight: 500
|
|
31027
|
+
} : null
|
|
31028
|
+
}), yMedian >= viewDomain.y[0] && yMedian <= viewDomain.y[1] && /*#__PURE__*/React$1.createElement(ReferenceLine, {
|
|
31029
|
+
y: yMedian,
|
|
31030
|
+
isFront: true,
|
|
31031
|
+
stroke: "transparent",
|
|
31032
|
+
label: _ref7 => {
|
|
31033
|
+
let {
|
|
31034
|
+
viewBox
|
|
31035
|
+
} = _ref7;
|
|
31036
|
+
return /*#__PURE__*/React$1.createElement(Arrow, {
|
|
31037
|
+
viewBox: viewBox,
|
|
31038
|
+
direction: "right"
|
|
31039
|
+
});
|
|
31040
|
+
}
|
|
31041
|
+
}), /*#__PURE__*/React$1.createElement(Tooltip$2, {
|
|
31042
|
+
content: /*#__PURE__*/React$1.createElement(CustomTooltip, null),
|
|
31043
|
+
cursor: false,
|
|
31044
|
+
wrapperStyle: {
|
|
31045
|
+
zIndex: 9999,
|
|
31046
|
+
position: 'absolute',
|
|
31047
|
+
pointerEvents: 'auto'
|
|
31048
|
+
},
|
|
31049
|
+
allowEscapeViewBox: {
|
|
31050
|
+
x: false,
|
|
31051
|
+
y: false
|
|
31052
|
+
},
|
|
31053
|
+
"data-testid": "tooltip"
|
|
31054
|
+
}), /*#__PURE__*/React$1.createElement(Scatter, {
|
|
31055
|
+
name: "Bubble Chart",
|
|
31056
|
+
data: visibleData,
|
|
31057
|
+
shape: "circle",
|
|
31058
|
+
fill: "transparent",
|
|
31059
|
+
isAnimationActive: false,
|
|
31060
|
+
animationBegin: 0,
|
|
31061
|
+
animationDuration: 0,
|
|
31062
|
+
"data-testid": "scatter"
|
|
31063
|
+
}, visibleData.map((entry, index) => /*#__PURE__*/React$1.createElement(Cell, {
|
|
31064
|
+
key: entry.key,
|
|
31065
|
+
fill: entry.fill,
|
|
31066
|
+
stroke: "rgba(255,255,255,0.6)",
|
|
31067
|
+
strokeWidth: 1.5,
|
|
31068
|
+
filter: "url(#bubble-blur)",
|
|
31069
|
+
"data-testid": `cell-${index}`
|
|
31070
|
+
}))), isMiddleValueVisible && /*#__PURE__*/React$1.createElement(ReferenceLine, {
|
|
31071
|
+
x: xMedian,
|
|
31072
|
+
y: yMedian,
|
|
31073
|
+
stroke: "transparent",
|
|
31074
|
+
isFront: true,
|
|
31075
|
+
"data-testid": "middle-value-reference",
|
|
31076
|
+
label: _ref8 => {
|
|
31077
|
+
let {
|
|
31078
|
+
viewBox
|
|
31079
|
+
} = _ref8;
|
|
31080
|
+
// Calculate the exact position of the median point in the SVG
|
|
31081
|
+
const xPos = viewBox.x + (xMedian - viewDomain.x[0]) / (viewDomain.x[1] - viewDomain.x[0]) * viewBox.width;
|
|
31082
|
+
const yPos = viewBox.y + (1 - (yMedian - viewDomain.y[0]) / (viewDomain.y[1] - viewDomain.y[0])) * viewBox.height;
|
|
31083
|
+
return /*#__PURE__*/React$1.createElement("text", {
|
|
31084
|
+
x: xPos,
|
|
31085
|
+
y: yPos,
|
|
31086
|
+
textAnchor: "middle",
|
|
31087
|
+
dominantBaseline: "middle",
|
|
31088
|
+
fill: "#484A4C",
|
|
31089
|
+
fontSize: 16,
|
|
31090
|
+
fontWeight: 600,
|
|
31091
|
+
style: {
|
|
31092
|
+
backgroundColor: 'rgba(255, 255, 255, 0.7)',
|
|
31093
|
+
padding: '2px'
|
|
31094
|
+
}
|
|
31095
|
+
}, formattedMedianValue);
|
|
31096
|
+
}
|
|
31097
|
+
})))), /*#__PURE__*/React$1.createElement(ZoomControlsContainer, {
|
|
31098
|
+
"data-testid": "zoom-controls-container"
|
|
31099
|
+
}, /*#__PURE__*/React$1.createElement(ZoomPercentage, {
|
|
31100
|
+
"data-testid": "zoom-percentage"
|
|
31101
|
+
}, zoomLevel, "%"), /*#__PURE__*/React$1.createElement(ZoomButton, {
|
|
31102
|
+
onClick: handleZoomOut,
|
|
31103
|
+
title: "Zoom Out",
|
|
31104
|
+
"data-testid": "zoom-out-button"
|
|
31105
|
+
}, "\u2212"), /*#__PURE__*/React$1.createElement(ZoomButton, {
|
|
31106
|
+
onClick: handleZoomIn,
|
|
31107
|
+
title: "Zoom In",
|
|
31108
|
+
"data-testid": "zoom-in-button"
|
|
31109
|
+
}, "+"), /*#__PURE__*/React$1.createElement(ZoomResetButton, {
|
|
31110
|
+
onClick: handleReset,
|
|
31111
|
+
"data-testid": "zoom-reset-button"
|
|
31112
|
+
}, "Reset")));
|
|
31113
|
+
};
|
|
31114
|
+
|
|
31115
|
+
const BatteryChartContainer = styled.div`
|
|
31116
|
+
position: relative;
|
|
31117
|
+
font-family: "Poppins", sans-serif;
|
|
31118
|
+
display: grid;
|
|
31119
|
+
grid-template-columns: auto auto;
|
|
31120
|
+
grid-template-rows: auto 1fr auto;
|
|
31121
|
+
color: #212121;
|
|
31122
|
+
background-color: ${props => props.backgroundColor || 'transparent'};
|
|
31123
|
+
padding: ${props => props.containerPadding || '25px 30px 0'};
|
|
31124
|
+
width: ${props => props.width};
|
|
31125
|
+
height: ${props => props.height};
|
|
31126
|
+
`;
|
|
31127
|
+
const PanelSide = styled.div`
|
|
31128
|
+
display: flex;
|
|
31129
|
+
flex-direction: column;
|
|
31130
|
+
justify-content: space-between;
|
|
31131
|
+
`;
|
|
31132
|
+
const ProgressDetails = styled.div`
|
|
31133
|
+
display: flex;
|
|
31134
|
+
flex-direction: column;
|
|
31135
|
+
flex-grow: 1;
|
|
31136
|
+
`;
|
|
31137
|
+
const HeadingText = styled.p`
|
|
31138
|
+
grid-column: 1 / span 2;
|
|
31139
|
+
color: #212121;
|
|
31140
|
+
font-size: 18px;
|
|
31141
|
+
font-weight: 400;
|
|
31142
|
+
padding-left: 10px;
|
|
31143
|
+
margin: 0 0 8px;
|
|
31144
|
+
`;
|
|
31145
|
+
const HeadingPercentage = styled.p`
|
|
31146
|
+
color: #212121;
|
|
31147
|
+
font-size: 32px;
|
|
31148
|
+
font-weight: 500;
|
|
31149
|
+
padding-left: 10px;
|
|
31150
|
+
margin: 0;
|
|
31151
|
+
`;
|
|
31152
|
+
const ChartSide = styled.div`
|
|
31153
|
+
text-align: center;
|
|
31154
|
+
`;
|
|
31155
|
+
const ChartWrapper = styled.div`
|
|
31156
|
+
position: relative;
|
|
31157
|
+
width: 110px;
|
|
31158
|
+
`;
|
|
31159
|
+
const GoalValue = styled.div`
|
|
31160
|
+
text-align: center;
|
|
31161
|
+
font-size: 18px;
|
|
31162
|
+
color: #8B8989;
|
|
31163
|
+
line-height: 1;
|
|
31164
|
+
&.overload {
|
|
31165
|
+
position: absolute;
|
|
31166
|
+
top: ${props => props.goalValuePosition}px;
|
|
31167
|
+
left: 0;
|
|
31168
|
+
right: 0;
|
|
31169
|
+
z-index: 2;
|
|
31170
|
+
margin: 0 auto;
|
|
31171
|
+
width: 40%;
|
|
31172
|
+
display: inline;
|
|
31173
|
+
padding: 0px 8px;
|
|
31174
|
+
border: 2px solid #F2F2F2;
|
|
31175
|
+
border-bottom: none;
|
|
31176
|
+
border-radius: 6px 6px 0px 0px;
|
|
31177
|
+
background-color: white;
|
|
31178
|
+
}
|
|
31179
|
+
`;
|
|
31180
|
+
const Indicator = styled.div`
|
|
31181
|
+
position: absolute;
|
|
31182
|
+
top: ${props => props.top}px;
|
|
31183
|
+
left: 0;
|
|
31184
|
+
transform: translateY(50%);
|
|
31185
|
+
width: calc(100% + 60px);
|
|
31186
|
+
display: flex;
|
|
31187
|
+
gap: 6px;
|
|
31188
|
+
justify-content: center;
|
|
31189
|
+
padding-left: 4px;
|
|
31190
|
+
align-items: center;
|
|
31191
|
+
z-index: 1;
|
|
31192
|
+
`;
|
|
31193
|
+
const IndicatorLine = styled.div`
|
|
31194
|
+
width: 100%;
|
|
31195
|
+
height: 0;
|
|
31196
|
+
border-top: 4px dashed ${props => props.color};
|
|
31197
|
+
`;
|
|
31198
|
+
const IndicatorText = styled.span`
|
|
31199
|
+
font-size: 18px;
|
|
31200
|
+
font-weight: 400;
|
|
31201
|
+
color: ${props => props.color};
|
|
31202
|
+
`;
|
|
31203
|
+
const ProgressLegend = styled.div`
|
|
31204
|
+
margin-top: 12px;
|
|
31205
|
+
`;
|
|
31206
|
+
const LegendItem = styled.div`
|
|
31207
|
+
display: flex;
|
|
31208
|
+
gap: 4px;
|
|
31209
|
+
align-items: center;
|
|
31210
|
+
margin-bottom: 12px;
|
|
31211
|
+
`;
|
|
31212
|
+
const LegendText = styled.span`
|
|
31213
|
+
color: #8B8989;
|
|
31214
|
+
font-size: 14px;
|
|
31215
|
+
`;
|
|
31216
|
+
const LegendCube = styled.div`
|
|
31217
|
+
border-radius: 3px;
|
|
31218
|
+
width: 17px;
|
|
31219
|
+
height: 17px;
|
|
31220
|
+
background-color: ${props => props.color};
|
|
31221
|
+
`;
|
|
31222
|
+
const ProgressDescription = styled.div`
|
|
31223
|
+
color: #8B8989;
|
|
31224
|
+
font-size: 12px;
|
|
31225
|
+
font-weight: 400;
|
|
31226
|
+
margin-top: auto;
|
|
31227
|
+
`;
|
|
31228
|
+
const ProgressItem = styled.p`
|
|
31229
|
+
margin: 0 0 6px;
|
|
31230
|
+
`;
|
|
31231
|
+
const StarText = styled.span`
|
|
31232
|
+
width: 100%;
|
|
31233
|
+
color: #B1B1B1;
|
|
31234
|
+
font-size: 9px;
|
|
31235
|
+
grid-column: 1 / span 2;
|
|
31236
|
+
padding-top: 10px;
|
|
31237
|
+
`;
|
|
31238
|
+
|
|
31239
|
+
const BatteryChart = props => {
|
|
31240
|
+
const {
|
|
31241
|
+
className,
|
|
31242
|
+
containerPadding,
|
|
31243
|
+
width,
|
|
31244
|
+
height,
|
|
31245
|
+
title,
|
|
31246
|
+
color,
|
|
31247
|
+
backgroundColor,
|
|
31248
|
+
indicatorColor,
|
|
31249
|
+
noCommitment,
|
|
31250
|
+
goalAmount,
|
|
31251
|
+
currentAmount,
|
|
31252
|
+
ask,
|
|
31253
|
+
target,
|
|
31254
|
+
totalSegmentsLines,
|
|
31255
|
+
starText
|
|
31256
|
+
} = props;
|
|
31257
|
+
const [top, setTop] = useState(0);
|
|
31258
|
+
const [goalValuePosition, setGoalValuePosition] = useState(0);
|
|
31259
|
+
const [containerHeight, setContainerHeight] = useState(0); // State to store container height
|
|
31260
|
+
const containerRef = useRef(null); // Ref for BatteryChartContainer
|
|
31261
|
+
|
|
31262
|
+
// Calculate the percentage and completed segments
|
|
31263
|
+
const percentage = Math.round(currentAmount / goalAmount * 100);
|
|
31264
|
+
const completedSegments = Math.min(Math.floor(currentAmount / goalAmount * totalSegmentsLines), totalSegmentsLines);
|
|
31265
|
+
|
|
31266
|
+
// Dynamically create the data for the bar chart
|
|
31267
|
+
let barsChips = Array.from({
|
|
31268
|
+
length: totalSegmentsLines
|
|
31269
|
+
}).map((_, index) => ({
|
|
31270
|
+
name: `segment-${index}`,
|
|
31271
|
+
value: 100,
|
|
31272
|
+
isCompleted: index >= totalSegmentsLines - completedSegments,
|
|
31273
|
+
// Fill from bottom up
|
|
31274
|
+
color: index >= totalSegmentsLines - completedSegments ? color : "#e5e7eb" // Completed or remaining color
|
|
31275
|
+
}));
|
|
31276
|
+
|
|
31277
|
+
// Add 4 extra chips if currentAmount > goalAmount
|
|
31278
|
+
if (currentAmount > goalAmount && !noCommitment) {
|
|
31279
|
+
const extraSegments = 4;
|
|
31280
|
+
const extraData = Array.from({
|
|
31281
|
+
length: extraSegments
|
|
31282
|
+
}).map((_, index) => ({
|
|
31283
|
+
name: `extra-segment-${index}`,
|
|
31284
|
+
value: 100,
|
|
31285
|
+
isCompleted: true,
|
|
31286
|
+
color: "#E8F5EB"
|
|
31287
|
+
}));
|
|
31288
|
+
|
|
31289
|
+
// Prepend the extra segments to the barsChips array
|
|
31290
|
+
barsChips = [...extraData, ...barsChips];
|
|
31291
|
+
}
|
|
31292
|
+
|
|
31293
|
+
// Calculate the top position for the indicator and goal value
|
|
31294
|
+
useEffect(() => {
|
|
31295
|
+
const barHeight = containerHeight / (totalSegmentsLines + (currentAmount > goalAmount ? 4 : 0)); // Adjust for extra chips
|
|
31296
|
+
let newTop;
|
|
31297
|
+
let newGoalValuePosition;
|
|
31298
|
+
if (currentAmount > goalAmount) {
|
|
31299
|
+
// Position the indicator slightly below the top chip
|
|
31300
|
+
newTop = barHeight * 1.5; // Slightly below the 4th chip
|
|
31301
|
+
// Position the goal value just above the active chips
|
|
31302
|
+
|
|
31303
|
+
newGoalValuePosition = barHeight * 2.3;
|
|
31304
|
+
// newGoalValuePosition = (totalSegmentsLines - completedSegments + 4) * barHeight - barHeight / 2;
|
|
31305
|
+
} else {
|
|
31306
|
+
// Normal case: position the indicator above the active chips
|
|
31307
|
+
newTop = (totalSegmentsLines - completedSegments) * barHeight / 1.65;
|
|
31308
|
+
// Position the goal value just above the active chips
|
|
31309
|
+
newGoalValuePosition = newTop;
|
|
31310
|
+
}
|
|
31311
|
+
setTop(newTop);
|
|
31312
|
+
setGoalValuePosition(newGoalValuePosition);
|
|
31313
|
+
}, [completedSegments, totalSegmentsLines, currentAmount, goalAmount, containerHeight]);
|
|
31314
|
+
useEffect(() => {
|
|
31315
|
+
if (containerRef.current) {
|
|
31316
|
+
const height = containerRef.current.offsetHeight;
|
|
31317
|
+
if (height > 0) {
|
|
31318
|
+
setContainerHeight(height);
|
|
31319
|
+
}
|
|
31320
|
+
}
|
|
31321
|
+
}, [containerRef, width, height]);
|
|
31322
|
+
return /*#__PURE__*/React$1.createElement(BatteryChartContainer, {
|
|
31323
|
+
ref: containerRef,
|
|
31324
|
+
width: width,
|
|
31325
|
+
height: height,
|
|
31326
|
+
className: className,
|
|
31327
|
+
containerPadding: containerPadding,
|
|
31328
|
+
backgroundColor: backgroundColor
|
|
31329
|
+
}, /*#__PURE__*/React$1.createElement(HeadingText, null, title), /*#__PURE__*/React$1.createElement(PanelSide, null, /*#__PURE__*/React$1.createElement(ProgressDetails, null, !noCommitment && /*#__PURE__*/React$1.createElement(HeadingPercentage, null, percentage, "%"), /*#__PURE__*/React$1.createElement(ProgressDescription, null, ask && /*#__PURE__*/React$1.createElement(ProgressItem, null, "ASK: ", `$${getFormattedValue(ask, false) + getFormattedUnits(ask)}`), target && /*#__PURE__*/React$1.createElement(ProgressItem, null, "Target: ", `$${getFormattedValue(target, false) + getFormattedUnits(target)}`)), /*#__PURE__*/React$1.createElement(ProgressLegend, null, /*#__PURE__*/React$1.createElement(LegendItem, null, /*#__PURE__*/React$1.createElement(LegendCube, {
|
|
31330
|
+
color: color
|
|
31331
|
+
}), /*#__PURE__*/React$1.createElement(LegendText, null, "Spend")), !noCommitment && /*#__PURE__*/React$1.createElement(LegendItem, null, /*#__PURE__*/React$1.createElement(LegendCube, {
|
|
31332
|
+
color: "#E3E4E5"
|
|
31333
|
+
}), /*#__PURE__*/React$1.createElement(LegendText, null, "Commitment"))))), /*#__PURE__*/React$1.createElement(ChartSide, null, /*#__PURE__*/React$1.createElement(ChartWrapper, null, /*#__PURE__*/React$1.createElement(GoalValue, {
|
|
31334
|
+
className: currentAmount > goalAmount && !noCommitment ? "overload" : "",
|
|
31335
|
+
goalValuePosition: goalValuePosition
|
|
31336
|
+
}, !noCommitment ? `$${getFormattedValue(goalAmount, false) + getFormattedUnits(goalAmount)}` : `$${getFormattedValue(currentAmount, false) + getFormattedUnits(currentAmount)}`), !noCommitment && /*#__PURE__*/React$1.createElement(Indicator, {
|
|
31337
|
+
top: top
|
|
31338
|
+
}, /*#__PURE__*/React$1.createElement(IndicatorLine, {
|
|
31339
|
+
color: indicatorColor
|
|
31340
|
+
}), /*#__PURE__*/React$1.createElement(IndicatorText, {
|
|
31341
|
+
color: indicatorColor
|
|
31342
|
+
}, `$${getFormattedValue(currentAmount, false) + getFormattedUnits(currentAmount)}`)), /*#__PURE__*/React$1.createElement(ResponsiveContainer, {
|
|
31343
|
+
height: Math.max(containerHeight - 105, 210)
|
|
31344
|
+
}, /*#__PURE__*/React$1.createElement(BarChart$1, {
|
|
31345
|
+
data: barsChips,
|
|
31346
|
+
layout: "vertical",
|
|
31347
|
+
margin: {
|
|
31348
|
+
top: 5,
|
|
31349
|
+
right: 5,
|
|
31350
|
+
left: 5,
|
|
31351
|
+
bottom: 5
|
|
31352
|
+
},
|
|
31353
|
+
barSize: 4
|
|
31354
|
+
}, /*#__PURE__*/React$1.createElement(XAxis, {
|
|
31355
|
+
type: "number",
|
|
31356
|
+
hide: true,
|
|
31357
|
+
domain: [0, 100]
|
|
31358
|
+
}), /*#__PURE__*/React$1.createElement(YAxis, {
|
|
31359
|
+
type: "category",
|
|
31360
|
+
hide: true,
|
|
31361
|
+
dataKey: "name"
|
|
31362
|
+
}), /*#__PURE__*/React$1.createElement(Bar, {
|
|
31363
|
+
dataKey: "value",
|
|
31364
|
+
background: {
|
|
31365
|
+
fill: "#f3f4f6"
|
|
31366
|
+
},
|
|
31367
|
+
radius: [8, 8, 8, 8]
|
|
31368
|
+
}, barsChips.map((entry, index) => /*#__PURE__*/React$1.createElement(Cell, {
|
|
31369
|
+
key: `cell-${index}`,
|
|
31370
|
+
fill: entry.color
|
|
31371
|
+
}))))))), starText !== "" && /*#__PURE__*/React$1.createElement(StarText, null, starText));
|
|
31372
|
+
};
|
|
31373
|
+
|
|
31374
|
+
const originalData$1 = [{
|
|
31375
|
+
label: "Vendor Selling Event: Week 28",
|
|
31376
|
+
inc_unit: 20000,
|
|
31377
|
+
inc_roi: 1.2
|
|
31378
|
+
}, {
|
|
31379
|
+
label: "Vendor Selling Event: Week 29",
|
|
31380
|
+
inc_unit: 10000,
|
|
31381
|
+
inc_roi: 1.2
|
|
31382
|
+
}, {
|
|
31383
|
+
label: "Vendor Selling Event: Week 30",
|
|
31384
|
+
inc_unit: 8000,
|
|
31385
|
+
inc_roi: 0.8
|
|
31386
|
+
}, {
|
|
31387
|
+
label: "Vendor Selling Event: Week 33",
|
|
31388
|
+
inc_unit: 12000,
|
|
31389
|
+
inc_roi: 1.1
|
|
31390
|
+
}, {
|
|
31391
|
+
label: "Vendor Selling Event: Week 36",
|
|
31392
|
+
inc_unit: 8000,
|
|
31393
|
+
inc_roi: 1.2
|
|
31394
|
+
}, {
|
|
31395
|
+
label: "Vendor Selling Event: Week 34",
|
|
31396
|
+
inc_unit: 8000,
|
|
31397
|
+
inc_roi: 0.7
|
|
31398
|
+
}, {
|
|
31399
|
+
label: "Vendor Selling Event: Week 35",
|
|
31400
|
+
inc_unit: 8000,
|
|
31401
|
+
inc_roi: 0.8
|
|
31402
|
+
}, {
|
|
31403
|
+
label: "Vendor Selling Event: Week 38",
|
|
31404
|
+
inc_unit: 9000,
|
|
31405
|
+
inc_roi: 1.1
|
|
31406
|
+
}];
|
|
31407
|
+
const dataWithIndex$1 = originalData$1.map((item, index) => ({
|
|
31408
|
+
...item,
|
|
31409
|
+
index,
|
|
31410
|
+
shortLabel: item.label.replace("Vendor Selling Event: ", "Wk ")
|
|
31411
|
+
}));
|
|
31412
|
+
const CustomizedTick$1 = ({
|
|
31413
|
+
x,
|
|
31414
|
+
y,
|
|
31415
|
+
payload
|
|
31416
|
+
}) => {
|
|
31417
|
+
const label = dataWithIndex$1[payload.value]?.label ?? "";
|
|
31418
|
+
const parts = label.replace("Vendor Selling Event: ", "").split(" ");
|
|
31419
|
+
return /*#__PURE__*/React$1.createElement("g", {
|
|
31420
|
+
transform: `translate(${x},${y})`
|
|
31421
|
+
}, /*#__PURE__*/React$1.createElement("text", {
|
|
31422
|
+
x: 0,
|
|
31423
|
+
y: 0,
|
|
31424
|
+
dy: 16,
|
|
31425
|
+
textAnchor: "middle",
|
|
31426
|
+
fill: "#212121",
|
|
31427
|
+
fontSize: 11,
|
|
31428
|
+
fontWeight: "400",
|
|
31429
|
+
fontFamily: "Poppins"
|
|
31430
|
+
}, /*#__PURE__*/React$1.createElement("tspan", {
|
|
31431
|
+
x: 0,
|
|
31432
|
+
dy: 8
|
|
31433
|
+
}, "Vendor Selling"), /*#__PURE__*/React$1.createElement("tspan", {
|
|
31434
|
+
x: 0,
|
|
31435
|
+
dy: 18
|
|
31436
|
+
}, "Event: ", parts.join(" "))));
|
|
31437
|
+
};
|
|
31438
|
+
|
|
31439
|
+
// Common chart configuration
|
|
31440
|
+
const chartMargins = {
|
|
31441
|
+
top: 15,
|
|
31442
|
+
right: 40,
|
|
31443
|
+
left: 20,
|
|
31444
|
+
bottom: 40
|
|
31445
|
+
};
|
|
31446
|
+
const SeparatedLineBarChart = () => {
|
|
31447
|
+
const [viewWindow, setViewWindow] = useState({
|
|
31448
|
+
startIndex: 0,
|
|
31449
|
+
endIndex: dataWithIndex$1.length - 1
|
|
31450
|
+
});
|
|
31451
|
+
return /*#__PURE__*/React$1.createElement("div", {
|
|
31452
|
+
style: {
|
|
31453
|
+
width: "100%",
|
|
31454
|
+
height: 700
|
|
31455
|
+
}
|
|
31456
|
+
}, /*#__PURE__*/React$1.createElement("div", {
|
|
31457
|
+
style: {
|
|
31458
|
+
height: "40%"
|
|
31459
|
+
}
|
|
31460
|
+
}, /*#__PURE__*/React$1.createElement(ResponsiveContainer, {
|
|
31461
|
+
width: "100%",
|
|
31462
|
+
height: "100%"
|
|
31463
|
+
}, /*#__PURE__*/React$1.createElement(LineChart, {
|
|
31464
|
+
data: dataWithIndex$1 // Use full dataset for alignment
|
|
31465
|
+
,
|
|
31466
|
+
margin: chartMargins
|
|
31467
|
+
}, /*#__PURE__*/React$1.createElement(CartesianGrid, {
|
|
31468
|
+
strokeDasharray: "3 3",
|
|
31469
|
+
vertical: false
|
|
31470
|
+
}), /*#__PURE__*/React$1.createElement(XAxis, {
|
|
31471
|
+
dataKey: "index",
|
|
31472
|
+
type: "number",
|
|
31473
|
+
domain: ['dataMin', 'dataMax'],
|
|
31474
|
+
padding: {
|
|
31475
|
+
left: 20,
|
|
31476
|
+
right: 20
|
|
31477
|
+
},
|
|
31478
|
+
hide: true
|
|
31479
|
+
}), /*#__PURE__*/React$1.createElement(YAxis, {
|
|
31480
|
+
domain: [0, 2],
|
|
31481
|
+
hide: true
|
|
31482
|
+
}), /*#__PURE__*/React$1.createElement(Tooltip$2, null), /*#__PURE__*/React$1.createElement(Line, {
|
|
31483
|
+
type: "monotone",
|
|
31484
|
+
dataKey: "inc_roi",
|
|
31485
|
+
stroke: "#F8CD00",
|
|
31486
|
+
strokeWidth: 2,
|
|
31487
|
+
dot: {
|
|
31488
|
+
r: 4,
|
|
31489
|
+
fill: "#F8CD00"
|
|
31490
|
+
},
|
|
31491
|
+
activeDot: false,
|
|
31492
|
+
name: "INC Sales ROI"
|
|
31493
|
+
}, /*#__PURE__*/React$1.createElement(LabelList, {
|
|
31494
|
+
dataKey: "inc_roi",
|
|
31495
|
+
position: "top",
|
|
31496
|
+
formatter: value => value.toFixed(1)
|
|
31497
|
+
}))))), /*#__PURE__*/React$1.createElement("div", {
|
|
31498
|
+
style: {
|
|
31499
|
+
height: "60%"
|
|
31500
|
+
}
|
|
31501
|
+
}, /*#__PURE__*/React$1.createElement(ResponsiveContainer, {
|
|
31502
|
+
width: "100%",
|
|
31503
|
+
height: "100%"
|
|
31504
|
+
}, /*#__PURE__*/React$1.createElement(ComposedChart, {
|
|
31505
|
+
data: dataWithIndex$1,
|
|
31506
|
+
margin: chartMargins
|
|
31507
|
+
}, /*#__PURE__*/React$1.createElement(CartesianGrid, {
|
|
31508
|
+
strokeDasharray: "3 3",
|
|
31509
|
+
vertical: false
|
|
31510
|
+
}), /*#__PURE__*/React$1.createElement(XAxis, {
|
|
31511
|
+
dataKey: "index",
|
|
31512
|
+
type: "number",
|
|
31513
|
+
domain: ['dataMin', 'dataMax'],
|
|
31514
|
+
padding: {
|
|
31515
|
+
left: 20,
|
|
31516
|
+
right: 20
|
|
31517
|
+
},
|
|
31518
|
+
tick: /*#__PURE__*/React$1.createElement(CustomizedTick$1, null),
|
|
31519
|
+
interval: 0 // Force display all ticks
|
|
31520
|
+
,
|
|
31521
|
+
height: 60,
|
|
31522
|
+
tickLine: false,
|
|
31523
|
+
ticks: dataWithIndex$1.map(item => item.index)
|
|
31524
|
+
}), /*#__PURE__*/React$1.createElement(YAxis, {
|
|
31525
|
+
tickFormatter: v => `$${v / 1000}k`,
|
|
31526
|
+
hide: true
|
|
31527
|
+
}), /*#__PURE__*/React$1.createElement(Tooltip$2, null), /*#__PURE__*/React$1.createElement(Bar, {
|
|
31528
|
+
dataKey: "inc_unit",
|
|
31529
|
+
fill: "#CCDCDD",
|
|
31530
|
+
gap: "4px",
|
|
31531
|
+
borderRadius: [4, 4, 0, 8],
|
|
31532
|
+
barSize: 40,
|
|
31533
|
+
name: "INC Sales"
|
|
31534
|
+
}, /*#__PURE__*/React$1.createElement(LabelList, {
|
|
31535
|
+
dataKey: "inc_unit",
|
|
31536
|
+
position: "top",
|
|
31537
|
+
formatter: value => `$${value / 1000}k`,
|
|
31538
|
+
fill: "#212121",
|
|
31539
|
+
fontSize: 12,
|
|
31540
|
+
fontWeight: "400",
|
|
31541
|
+
fontFamily: "Poppins"
|
|
31542
|
+
})), /*#__PURE__*/React$1.createElement(Brush, {
|
|
31543
|
+
dataKey: "index",
|
|
31544
|
+
height: 30,
|
|
31545
|
+
stroke: "#212121",
|
|
31546
|
+
startIndex: viewWindow.startIndex,
|
|
31547
|
+
endIndex: viewWindow.endIndex,
|
|
31548
|
+
onChange: e => {
|
|
31549
|
+
setViewWindow({
|
|
31550
|
+
startIndex: e.startIndex ?? 0,
|
|
31551
|
+
endIndex: e.endIndex ?? dataWithIndex$1.length - 1
|
|
31552
|
+
});
|
|
31553
|
+
},
|
|
31554
|
+
travellerWidth: 12
|
|
31555
|
+
})), /*#__PURE__*/React$1.createElement("div", {
|
|
31556
|
+
style: {
|
|
31557
|
+
marginTop: "-28px"
|
|
31558
|
+
}
|
|
31559
|
+
}, /*#__PURE__*/React$1.createElement(PerformanceAnalyticsLegend, {
|
|
31560
|
+
legendData: [{
|
|
31561
|
+
iconColor: "#CCDCDD",
|
|
31562
|
+
iconType: "Square",
|
|
31563
|
+
title: "INC Sales"
|
|
31564
|
+
}, {
|
|
31565
|
+
iconColor: "#F8CD00",
|
|
31566
|
+
iconType: "LegendUnionIcon",
|
|
31567
|
+
title: "INC Sales ROI"
|
|
31568
|
+
}]
|
|
31569
|
+
})))));
|
|
31570
|
+
};
|
|
31571
|
+
|
|
31572
|
+
const originalData = [{
|
|
31573
|
+
label: "Vendor Selling Event: Week 28",
|
|
31574
|
+
inc_unit: 20000
|
|
31575
|
+
}, {
|
|
31576
|
+
label: "Vendor Selling Event: Week 29",
|
|
31577
|
+
inc_unit: 10000
|
|
31578
|
+
}, {
|
|
31579
|
+
label: "Vendor Selling Event: Week 30",
|
|
31580
|
+
inc_unit: 8000
|
|
31581
|
+
}, {
|
|
31582
|
+
label: "Vendor Selling Event: Week 33",
|
|
31583
|
+
inc_unit: 12000
|
|
31584
|
+
}, {
|
|
31585
|
+
label: "Vendor Selling Event: Week 36",
|
|
31586
|
+
inc_unit: 8000
|
|
31587
|
+
}, {
|
|
31588
|
+
label: "Vendor Selling Event: Week 34",
|
|
31589
|
+
inc_unit: 8000
|
|
31590
|
+
}, {
|
|
31591
|
+
label: "Vendor Selling Event: Week 35",
|
|
31592
|
+
inc_unit: 8000
|
|
31593
|
+
}, {
|
|
31594
|
+
label: "Vendor Selling Event: Week 38",
|
|
31595
|
+
inc_unit: 9000
|
|
31596
|
+
}];
|
|
31597
|
+
|
|
31598
|
+
// Adding index and shortLabel to original data
|
|
31599
|
+
const dataWithIndex = originalData.map((item, index) => ({
|
|
31600
|
+
...item,
|
|
31601
|
+
index,
|
|
31602
|
+
shortLabel: item.label.replace("Vendor Selling Event: ", "Wk ")
|
|
31603
|
+
}));
|
|
31604
|
+
const CustomizedTick = ({
|
|
31605
|
+
x,
|
|
31606
|
+
y,
|
|
31607
|
+
payload
|
|
31608
|
+
}) => {
|
|
31609
|
+
const label = dataWithIndex[payload.value]?.label ?? "";
|
|
31610
|
+
const parts = label.replace("Vendor Selling Event: ", "").split(" ");
|
|
31611
|
+
return /*#__PURE__*/React$1.createElement("g", {
|
|
31612
|
+
transform: `translate(${x},${y})`
|
|
31613
|
+
}, /*#__PURE__*/React$1.createElement("text", {
|
|
31614
|
+
x: 0,
|
|
31615
|
+
y: 0,
|
|
31616
|
+
dy: 16,
|
|
31617
|
+
textAnchor: "middle",
|
|
31618
|
+
fill: "#212121",
|
|
31619
|
+
fontSize: 11,
|
|
31620
|
+
fontWeight: "400",
|
|
31621
|
+
fontFamily: "Poppins"
|
|
31622
|
+
}, /*#__PURE__*/React$1.createElement("tspan", {
|
|
31623
|
+
x: 0,
|
|
31624
|
+
dy: 8
|
|
31625
|
+
}, "Vendor Selling"), /*#__PURE__*/React$1.createElement("tspan", {
|
|
31626
|
+
x: 0,
|
|
31627
|
+
dy: 18
|
|
31628
|
+
}, "Event: ", parts.join(" "))));
|
|
31629
|
+
};
|
|
31630
|
+
const SingleChart = () => {
|
|
31631
|
+
const [startIndex, setStartIndex] = useState(0);
|
|
31632
|
+
const [endIndex, setEndIndex] = useState(dataWithIndex.length - 1);
|
|
31633
|
+
dataWithIndex.slice(startIndex, endIndex + 1);
|
|
31634
|
+
return /*#__PURE__*/React$1.createElement("div", {
|
|
31635
|
+
style: {
|
|
31636
|
+
width: "100%",
|
|
31637
|
+
height: 600
|
|
31638
|
+
}
|
|
31639
|
+
}, /*#__PURE__*/React$1.createElement("div", {
|
|
31640
|
+
style: {
|
|
31641
|
+
height: "100%"
|
|
31642
|
+
}
|
|
31643
|
+
}, /*#__PURE__*/React$1.createElement(ResponsiveContainer, {
|
|
31644
|
+
width: "100%",
|
|
31645
|
+
height: "100%"
|
|
31646
|
+
}, /*#__PURE__*/React$1.createElement(ComposedChart, {
|
|
31647
|
+
data: dataWithIndex,
|
|
31648
|
+
margin: {
|
|
31649
|
+
top: 40,
|
|
31650
|
+
right: 40,
|
|
31651
|
+
left: 20,
|
|
31652
|
+
bottom: 40
|
|
31653
|
+
}
|
|
31654
|
+
}, /*#__PURE__*/React$1.createElement(CartesianGrid, {
|
|
31655
|
+
strokeDasharray: "3 3",
|
|
31656
|
+
vertical: false
|
|
31657
|
+
}), /*#__PURE__*/React$1.createElement(XAxis, {
|
|
31658
|
+
dataKey: "index",
|
|
31659
|
+
tick: /*#__PURE__*/React$1.createElement(CustomizedTick, null),
|
|
31660
|
+
interval: 0,
|
|
31661
|
+
height: 60,
|
|
31662
|
+
padding: {
|
|
31663
|
+
left: 20,
|
|
31664
|
+
right: 20
|
|
31665
|
+
},
|
|
31666
|
+
tickLine: false
|
|
31667
|
+
}), /*#__PURE__*/React$1.createElement(YAxis, {
|
|
31668
|
+
tickFormatter: v => `$${v / 1000}k`,
|
|
31669
|
+
hide: true
|
|
31670
|
+
}), /*#__PURE__*/React$1.createElement(Tooltip$2, null), /*#__PURE__*/React$1.createElement(Bar, {
|
|
31671
|
+
dataKey: "inc_unit",
|
|
31672
|
+
fill: "#CCDCDD",
|
|
31673
|
+
gap: "4px",
|
|
31674
|
+
borderRadius: [4, 4, 0, 8],
|
|
31675
|
+
barSize: 40,
|
|
31676
|
+
name: "INC Sales"
|
|
31677
|
+
}, /*#__PURE__*/React$1.createElement(LabelList, {
|
|
31678
|
+
dataKey: "inc_unit",
|
|
31679
|
+
position: "top",
|
|
31680
|
+
formatter: value => `$${value / 1000}k`,
|
|
31681
|
+
fill: "#212121",
|
|
31682
|
+
fontSize: 12,
|
|
31683
|
+
fontWeight: "400",
|
|
31684
|
+
fontFamily: "Poppins"
|
|
31685
|
+
})), /*#__PURE__*/React$1.createElement(Brush, {
|
|
31686
|
+
dataKey: "index",
|
|
31687
|
+
height: 30,
|
|
31688
|
+
stroke: "#212121",
|
|
31689
|
+
startIndex: startIndex,
|
|
31690
|
+
endIndex: endIndex,
|
|
31691
|
+
onChange: e => {
|
|
31692
|
+
setStartIndex(e.startIndex ?? 0);
|
|
31693
|
+
setEndIndex(e.endIndex ?? dataWithIndex.length - 1);
|
|
31694
|
+
},
|
|
31695
|
+
travellerWidth: 12
|
|
31696
|
+
})), /*#__PURE__*/React$1.createElement(PerformanceAnalyticsLegend, {
|
|
31697
|
+
legendData: [{
|
|
31698
|
+
iconColor: "#CCDCDD",
|
|
31699
|
+
iconType: "Square",
|
|
31700
|
+
title: "INC Units"
|
|
31701
|
+
}]
|
|
31702
|
+
}))));
|
|
31703
|
+
};
|
|
31704
|
+
|
|
31705
|
+
styled.div`
|
|
31706
|
+
display: flex;
|
|
31707
|
+
gap: 28px;
|
|
31708
|
+
@media (max-width: 1536px) {
|
|
31709
|
+
gap: 20px;
|
|
31710
|
+
}
|
|
31711
|
+
@media (max-width: 1366px) {
|
|
31712
|
+
gap: 17px;
|
|
31713
|
+
}
|
|
31714
|
+
`;
|
|
31715
|
+
const ButtonsControlsContainer = styled.div`
|
|
31716
|
+
display: flex;
|
|
31717
|
+
font: ${props => props.fontSize?.toString().concat('', 'px Poppins, sans-serif')};
|
|
31718
|
+
margin: 0;
|
|
31719
|
+
--highlight-width: auto;
|
|
31720
|
+
--highlight-x-pos: 0;
|
|
31721
|
+
-webkit-font-smoothing: antialiased;
|
|
31722
|
+
-moz-osx-font-smoothing: grayscale;
|
|
31723
|
+
float: left;
|
|
31724
|
+
|
|
31725
|
+
&:not(:first-of-type) {
|
|
31726
|
+
padding-left: 40px;
|
|
31727
|
+
@media (max-width: 1536px) {
|
|
31728
|
+
padding-left: 35px;
|
|
31729
|
+
}
|
|
31730
|
+
@media (max-width: 1366px) {
|
|
31731
|
+
padding-left: 24px;
|
|
31732
|
+
}
|
|
31733
|
+
}
|
|
31734
|
+
`;
|
|
31735
|
+
const Controls = styled.div`
|
|
31736
|
+
display: inline-flex;
|
|
31737
|
+
justify-content: space-between;
|
|
31738
|
+
background: #f2f2f2;
|
|
31739
|
+
border-radius: ${props => props.controlradius.toString().concat('', 'px')}; //12px
|
|
31740
|
+
// max-width: 500px; //use this to limit max lenght of the control
|
|
31741
|
+
padding: 6px;
|
|
31742
|
+
gap: ${props => props.gap};
|
|
31743
|
+
overflow: hidden;
|
|
31744
|
+
position: relative;
|
|
31745
|
+
&.controls::before {
|
|
31746
|
+
content: "";
|
|
31747
|
+
color: #212121;
|
|
31748
|
+
background: #FFFFFF;
|
|
31749
|
+
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
|
|
31750
|
+
border-radius: ${props => props.segmentradius.toString().concat('', 'px')};
|
|
31751
|
+
width: var(--highlight-width);
|
|
31752
|
+
transform: translateX(var(--highlight-x-pos));
|
|
31753
|
+
position: absolute;
|
|
31754
|
+
top: 3px;
|
|
31755
|
+
bottom: 3px;
|
|
31756
|
+
left: 0;
|
|
31757
|
+
z-index: 0;
|
|
31758
|
+
}
|
|
31759
|
+
&.controls.ready::before {
|
|
31760
|
+
transition: transform 0.3s ease, width 0.3s ease;
|
|
31761
|
+
}
|
|
31762
|
+
`;
|
|
31763
|
+
const ControlsInput = styled.input`
|
|
31764
|
+
opacity: 0;
|
|
31765
|
+
margin: 0;
|
|
31766
|
+
top: 0;
|
|
31767
|
+
right: 0;
|
|
31768
|
+
bottom: 0;
|
|
31769
|
+
left: 0;
|
|
31770
|
+
position: absolute;
|
|
31771
|
+
width: 100%;
|
|
31772
|
+
cursor: pointer;
|
|
31773
|
+
height: 100%;
|
|
31774
|
+
`;
|
|
31775
|
+
const Segment = styled.div`
|
|
31776
|
+
/* width: 100%; uncomment for each segment to have matching width */
|
|
31777
|
+
width: 50%;
|
|
31778
|
+
min-width: ${props => props.segmentwidth.toString().concat('', 'px')}; //120px;
|
|
31779
|
+
position: relative;
|
|
31780
|
+
text-align: center;
|
|
31781
|
+
z-index: 1;
|
|
31782
|
+
`;
|
|
31783
|
+
const SegmentLabel = styled.label`
|
|
31784
|
+
cursor: pointer;
|
|
31785
|
+
display: block;
|
|
31786
|
+
padding: 0 6px;
|
|
31787
|
+
transition: color 0.5s ease;
|
|
31788
|
+
&.active {
|
|
31789
|
+
color: ${props => props.selectedtextcolor};
|
|
31790
|
+
}
|
|
31791
|
+
&.inactive {
|
|
31792
|
+
color: ${props => props.unselectedtextcolor};
|
|
31793
|
+
}
|
|
31794
|
+
`;
|
|
31795
|
+
|
|
31796
|
+
/* eslint-disable react/require-default-props */
|
|
31797
|
+
|
|
31798
|
+
/* SegmentedButton */
|
|
31799
|
+
const SegmentedButton = props => {
|
|
31800
|
+
const {
|
|
31801
|
+
name,
|
|
31802
|
+
options,
|
|
31803
|
+
width,
|
|
31804
|
+
height,
|
|
31805
|
+
controlradius,
|
|
31806
|
+
segmentradius,
|
|
31807
|
+
fontSize,
|
|
31808
|
+
selectedsegmentcolor,
|
|
31809
|
+
selectedtextcolor,
|
|
31810
|
+
unselectedtextcolor,
|
|
31811
|
+
defaultIndex,
|
|
31812
|
+
onClick,
|
|
31813
|
+
gap
|
|
31814
|
+
} = props;
|
|
31815
|
+
const [activeIndex, setActiveIndex] = useState(defaultIndex);
|
|
31816
|
+
const controlRef = useRef();
|
|
31817
|
+
const componentReady = useRef();
|
|
31818
|
+
const optionsRef = options?.map((item, i) => ({
|
|
31819
|
+
...item,
|
|
31820
|
+
id: i,
|
|
31821
|
+
ref: useRef()
|
|
31822
|
+
}));
|
|
31823
|
+
|
|
31824
|
+
// Determine when the component is "ready"
|
|
31825
|
+
useEffect(() => {
|
|
31826
|
+
componentReady.current = true;
|
|
31827
|
+
}, []);
|
|
31828
|
+
useEffect(() => {
|
|
31829
|
+
if (defaultIndex >= 0 && defaultIndex < options?.length) {
|
|
31830
|
+
setActiveIndex(defaultIndex);
|
|
31831
|
+
}
|
|
31832
|
+
}, [defaultIndex]);
|
|
31833
|
+
useEffect(() => {
|
|
31834
|
+
const activeSegmentRef = optionsRef[activeIndex].ref;
|
|
31835
|
+
const {
|
|
31836
|
+
offsetWidth,
|
|
31837
|
+
offsetLeft
|
|
31838
|
+
} = activeSegmentRef.current;
|
|
31839
|
+
const {
|
|
31840
|
+
style
|
|
31841
|
+
} = controlRef.current;
|
|
31842
|
+
style.setProperty('--highlight-width', `${offsetWidth}px`);
|
|
31843
|
+
style.setProperty('--highlight-x-pos', `${offsetLeft}px`);
|
|
31844
|
+
}, [activeIndex, controlRef, optionsRef]);
|
|
31845
|
+
const onInputChangeHandler = (value, index) => {
|
|
31846
|
+
setActiveIndex(index);
|
|
31847
|
+
onClick({
|
|
31848
|
+
index,
|
|
31849
|
+
value
|
|
31850
|
+
});
|
|
31851
|
+
};
|
|
31852
|
+
let segmentwidth = 120;
|
|
31853
|
+
if (options && options.length > 0 && width && width > 0) {
|
|
31854
|
+
segmentwidth = width / options.length;
|
|
31855
|
+
}
|
|
31856
|
+
return /*#__PURE__*/React$1.createElement(ButtonsControlsContainer, {
|
|
31857
|
+
fontSize: fontSize,
|
|
31858
|
+
ref: controlRef
|
|
31859
|
+
}, /*#__PURE__*/React$1.createElement(Controls, {
|
|
31860
|
+
id: "Controls",
|
|
31861
|
+
selectedsegmentcolor: selectedsegmentcolor,
|
|
31862
|
+
segmentradius: segmentradius,
|
|
31863
|
+
gap: gap,
|
|
31864
|
+
controlradius: controlradius,
|
|
31865
|
+
segmentwidth: segmentwidth,
|
|
31866
|
+
className: `controls ${componentReady.current ? 'ready' : 'idle'}`
|
|
31867
|
+
}, optionsRef?.map((item, i) => /*#__PURE__*/React$1.createElement(Segment, {
|
|
31868
|
+
id: "Segment",
|
|
31869
|
+
key: item.id,
|
|
31870
|
+
selectedsegmentcolor: selectedsegmentcolor,
|
|
31871
|
+
controlradius: controlradius,
|
|
31872
|
+
segmentwidth: segmentwidth,
|
|
31873
|
+
className: `${activeIndex === i ? 'active' : 'inactive'}`,
|
|
31874
|
+
ref: item.ref
|
|
31875
|
+
}, /*#__PURE__*/React$1.createElement(ControlsInput, {
|
|
31876
|
+
type: "radio",
|
|
31877
|
+
value: item.value,
|
|
31878
|
+
id: item.id,
|
|
31879
|
+
name: name,
|
|
31880
|
+
onChange: () => onInputChangeHandler(item.value, item.id),
|
|
31881
|
+
checked: i === activeIndex
|
|
31882
|
+
}), /*#__PURE__*/React$1.createElement(SegmentLabel, {
|
|
31883
|
+
id: "SegmentLabel",
|
|
31884
|
+
selectedtextcolor: selectedtextcolor,
|
|
31885
|
+
unselectedtextcolor: unselectedtextcolor,
|
|
31886
|
+
segmentheight: height / 5,
|
|
31887
|
+
className: `${activeIndex === i ? 'active' : 'inactive'} `,
|
|
31888
|
+
htmlFor: item.value
|
|
31889
|
+
}, item.value)))));
|
|
31890
|
+
};
|
|
31891
|
+
SegmentedButton.propTypes = {
|
|
31892
|
+
name: PropTypes.string,
|
|
31893
|
+
options: PropTypes.arrayOf(PropTypes.shape({
|
|
31894
|
+
value: PropTypes.string
|
|
31895
|
+
})),
|
|
31896
|
+
width: PropTypes.number,
|
|
31897
|
+
height: PropTypes.number,
|
|
31898
|
+
controlradius: PropTypes.number,
|
|
31899
|
+
segmentradius: PropTypes.number,
|
|
31900
|
+
gap: PropTypes.string,
|
|
31901
|
+
fontSize: PropTypes.number,
|
|
31902
|
+
selectedsegmentcolor: PropTypes.string,
|
|
31903
|
+
selectedtextcolor: PropTypes.string,
|
|
31904
|
+
unselectedtextcolor: PropTypes.string,
|
|
31905
|
+
defaultIndex: PropTypes.number,
|
|
31906
|
+
onClick: PropTypes.func
|
|
31907
|
+
};
|
|
31908
|
+
SegmentedButton.defaultProps = {
|
|
31909
|
+
name: '',
|
|
31910
|
+
options: [{
|
|
31911
|
+
value: '4 w'
|
|
31912
|
+
}, {
|
|
31913
|
+
value: '8 w'
|
|
31914
|
+
}, {
|
|
31915
|
+
value: '13 w'
|
|
31916
|
+
}],
|
|
31917
|
+
width: 120,
|
|
31918
|
+
height: 40,
|
|
31919
|
+
controlradius: 8,
|
|
31920
|
+
segmentradius: 8,
|
|
31921
|
+
gap: '0px',
|
|
31922
|
+
fontSize: 14,
|
|
31923
|
+
selectedsegmentcolor: '#3a9df9',
|
|
31924
|
+
selectedtextcolor: '#212121',
|
|
31925
|
+
unselectedtextcolor: 'black',
|
|
31926
|
+
defaultIndex: 0,
|
|
31927
|
+
onClick: () => {}
|
|
31928
|
+
};
|
|
31929
|
+
|
|
31930
|
+
var css_248z = ".BarLine {\r\n font-family: sans-serif;\r\n text-align: center;\r\n }\r\n \r\n /* Make brush background darker */\r\n /* .recharts-brush .recharts-brush-slide {\r\n fill: #a52a2a !important;\r\n stroke: none;\r\n }\r\n \r\n /* Style draggable handles (travellers) */\r\n /* .recharts-brush-traveller {\r\n fill: limegreen !important; /* bright green like in the image */\r\n /* cursor: ew-resize;\r\n } */\r\n */\r\n \r\n /* Optional: center grip arrows (you can fake it with CSS) */\r\n /* .recharts-brush .recharts-brush-traveller > rect {\r\n rx: 2;\r\n ry: 2;\r\n width: 6;\r\n fill: #a52a2a !important; /* dark gray */\r\n /* } */ */\r\n */\r\n \r\n /* Remove tick labels if needed */\r\n .recharts-brush .recharts-layer text {\r\n display: none;\r\n }\r\n ";
|
|
31931
|
+
styleInject(css_248z);
|
|
31932
|
+
|
|
31933
|
+
function InnerBarChart() {
|
|
31934
|
+
const data = [{
|
|
31935
|
+
week: "Week 28",
|
|
31936
|
+
total: 20000,
|
|
31937
|
+
actual: 4000
|
|
31938
|
+
}, {
|
|
31939
|
+
week: "Week 29",
|
|
31940
|
+
total: 10000,
|
|
31941
|
+
actual: 8000
|
|
31942
|
+
}, {
|
|
31943
|
+
week: "Week 30",
|
|
31944
|
+
total: 8000,
|
|
31945
|
+
actual: 950
|
|
31946
|
+
}, {
|
|
31947
|
+
week: "Week 33",
|
|
31948
|
+
total: 12000,
|
|
31949
|
+
actual: 1000
|
|
31950
|
+
}, {
|
|
31951
|
+
week: "Week 36",
|
|
31952
|
+
total: 16000,
|
|
31953
|
+
actual: 13000
|
|
31954
|
+
}, {
|
|
31955
|
+
week: "Week 34",
|
|
31956
|
+
total: 30000,
|
|
31957
|
+
actual: 3000
|
|
31958
|
+
}, {
|
|
31959
|
+
week: "Week 35",
|
|
31960
|
+
total: 8000,
|
|
31961
|
+
actual: 950
|
|
31962
|
+
}, {
|
|
31963
|
+
week: "Week 37",
|
|
31964
|
+
total: 9000,
|
|
31965
|
+
actual: 3000
|
|
31966
|
+
}];
|
|
31967
|
+
const originalData = [{
|
|
31968
|
+
label: "Vendor Selling Event: Week 28",
|
|
31969
|
+
inc_unit: 20000,
|
|
31970
|
+
inc_roi: 1.2
|
|
31971
|
+
}, {
|
|
31972
|
+
label: "Vendor Selling Event: Week 29",
|
|
31973
|
+
inc_unit: 10000,
|
|
31974
|
+
inc_roi: 1.2
|
|
31975
|
+
}, {
|
|
31976
|
+
label: "Vendor Selling Event: Week 30",
|
|
31977
|
+
inc_unit: 8000,
|
|
31978
|
+
inc_roi: 0.8
|
|
31979
|
+
}, {
|
|
31980
|
+
label: "Vendor Selling Event: Week 33",
|
|
31981
|
+
inc_unit: 12000,
|
|
31982
|
+
inc_roi: 1.1
|
|
31983
|
+
}, {
|
|
31984
|
+
label: "Vendor Selling Event: Week 36",
|
|
31985
|
+
inc_unit: 8000,
|
|
31986
|
+
inc_roi: 1.2
|
|
31987
|
+
}, {
|
|
31988
|
+
label: "Vendor Selling Event: Week 34",
|
|
31989
|
+
inc_unit: 8000,
|
|
31990
|
+
inc_roi: 0.7
|
|
31991
|
+
}, {
|
|
31992
|
+
label: "Vendor Selling Event: Week 35",
|
|
31993
|
+
inc_unit: 8000,
|
|
31994
|
+
inc_roi: 0.8
|
|
31995
|
+
}, {
|
|
31996
|
+
label: "Vendor Selling Event: Week 38",
|
|
31997
|
+
inc_unit: 9000,
|
|
31998
|
+
inc_roi: 1.1
|
|
31999
|
+
}];
|
|
32000
|
+
const format = v => v >= 1000 ? `${v / 1000}K` : v;
|
|
32001
|
+
const CustomBarLabel = ({
|
|
32002
|
+
x,
|
|
32003
|
+
y,
|
|
32004
|
+
width,
|
|
32005
|
+
payload
|
|
32006
|
+
}) => {
|
|
32007
|
+
if (!payload || typeof payload.total === "undefined") {
|
|
32008
|
+
console.error("Invalid payload:", payload);
|
|
32009
|
+
return null;
|
|
32010
|
+
}
|
|
32011
|
+
const centerX = x + width / 2;
|
|
32012
|
+
return /*#__PURE__*/React$1.createElement("text", {
|
|
32013
|
+
x: centerX,
|
|
32014
|
+
y: Math.max(y - 8, 10),
|
|
32015
|
+
textAnchor: "middle",
|
|
32016
|
+
fill: "black"
|
|
32017
|
+
}, format(payload.total));
|
|
32018
|
+
};
|
|
32019
|
+
const BarWithInner = props => {
|
|
32020
|
+
const {
|
|
32021
|
+
x,
|
|
32022
|
+
y,
|
|
32023
|
+
width,
|
|
32024
|
+
height,
|
|
32025
|
+
payload
|
|
32026
|
+
} = props;
|
|
32027
|
+
const totalHeight = height;
|
|
32028
|
+
const actualRatio = payload.actual / payload.total;
|
|
32029
|
+
const innerHeight = totalHeight * actualRatio;
|
|
32030
|
+
const innerY = y + (totalHeight - innerHeight);
|
|
32031
|
+
return /*#__PURE__*/React$1.createElement("g", null, /*#__PURE__*/React$1.createElement("rect", {
|
|
32032
|
+
x: x,
|
|
32033
|
+
y: y,
|
|
32034
|
+
width: width,
|
|
32035
|
+
height: height,
|
|
32036
|
+
fill: "#d0e6ea",
|
|
32037
|
+
rx: 4,
|
|
32038
|
+
ry: 4
|
|
32039
|
+
}), /*#__PURE__*/React$1.createElement("text", {
|
|
32040
|
+
x: x + width / 2,
|
|
32041
|
+
y: y - 8,
|
|
32042
|
+
textAnchor: "middle",
|
|
32043
|
+
fontSize: 11,
|
|
32044
|
+
fontWeight: 400,
|
|
32045
|
+
fontFamily: "Poppins",
|
|
32046
|
+
fill: "#212121"
|
|
32047
|
+
}, format(payload.total)), /*#__PURE__*/React$1.createElement("rect", {
|
|
32048
|
+
x: x + width * 0.2,
|
|
32049
|
+
y: innerY,
|
|
32050
|
+
width: width * 0.6,
|
|
32051
|
+
height: innerHeight,
|
|
32052
|
+
fill: "#07575b",
|
|
32053
|
+
rx: 2,
|
|
32054
|
+
ry: 2
|
|
32055
|
+
}), innerHeight > 16 && /*#__PURE__*/React$1.createElement("text", {
|
|
32056
|
+
x: x + width / 2,
|
|
32057
|
+
y: innerY - 6,
|
|
32058
|
+
textAnchor: "middle",
|
|
32059
|
+
fontSize: 11,
|
|
32060
|
+
fontWeight: 400,
|
|
32061
|
+
fontFamily: "Poppins",
|
|
32062
|
+
fill: "#212121"
|
|
32063
|
+
}, format(payload.actual)));
|
|
32064
|
+
};
|
|
32065
|
+
const CustomTooltip = ({
|
|
32066
|
+
active,
|
|
32067
|
+
payload,
|
|
32068
|
+
label
|
|
32069
|
+
}) => {
|
|
32070
|
+
if (!active || !payload || !payload.length) return null;
|
|
32071
|
+
const data = payload[0].payload;
|
|
32072
|
+
return /*#__PURE__*/React$1.createElement("div", {
|
|
32073
|
+
style: {
|
|
32074
|
+
background: "white",
|
|
32075
|
+
border: "1px solid #ccc",
|
|
32076
|
+
padding: "10px",
|
|
32077
|
+
borderRadius: "8px",
|
|
32078
|
+
fontSize: "14px"
|
|
32079
|
+
}
|
|
32080
|
+
}, /*#__PURE__*/React$1.createElement("strong", null, label), /*#__PURE__*/React$1.createElement("div", null, "Actual: ", format(data.actual)), /*#__PURE__*/React$1.createElement("div", null, "Total: ", format(data.total)));
|
|
32081
|
+
};
|
|
32082
|
+
const dataWithIndex = originalData.map((item, index) => ({
|
|
32083
|
+
...item,
|
|
32084
|
+
index,
|
|
32085
|
+
shortLabel: item.label.replace("Vendor Selling Event: ", "Wk ")
|
|
32086
|
+
}));
|
|
32087
|
+
const CustomizedTick = ({
|
|
32088
|
+
x,
|
|
32089
|
+
y,
|
|
32090
|
+
payload
|
|
32091
|
+
}) => {
|
|
32092
|
+
const label = dataWithIndex[payload.value]?.label ?? "";
|
|
32093
|
+
const parts = label.replace("Vendor Selling Event: ", "").split(" ");
|
|
32094
|
+
return /*#__PURE__*/React$1.createElement("g", {
|
|
32095
|
+
transform: `translate(${x},${y})`
|
|
32096
|
+
}, /*#__PURE__*/React$1.createElement("text", {
|
|
32097
|
+
x: 0,
|
|
32098
|
+
y: 0,
|
|
32099
|
+
dy: 16,
|
|
32100
|
+
textAnchor: "middle",
|
|
32101
|
+
fill: "#212121",
|
|
32102
|
+
fontSize: 11,
|
|
32103
|
+
fontWeight: "400",
|
|
32104
|
+
fontFamily: "Poppins"
|
|
32105
|
+
}, /*#__PURE__*/React$1.createElement("tspan", {
|
|
32106
|
+
x: 0,
|
|
32107
|
+
dy: 8
|
|
32108
|
+
}, "Vendor Selling"), /*#__PURE__*/React$1.createElement("tspan", {
|
|
32109
|
+
x: 0,
|
|
32110
|
+
dy: 18
|
|
32111
|
+
}, "Event: ", parts.join(" "))));
|
|
32112
|
+
};
|
|
32113
|
+
return /*#__PURE__*/React$1.createElement(ResponsiveContainer, {
|
|
32114
|
+
width: "100%",
|
|
32115
|
+
height: 400
|
|
32116
|
+
}, /*#__PURE__*/React$1.createElement(BarChart$1, {
|
|
32117
|
+
data: data,
|
|
32118
|
+
margin: {
|
|
32119
|
+
top: 20,
|
|
32120
|
+
right: 30,
|
|
32121
|
+
left: 20,
|
|
32122
|
+
bottom: 10
|
|
32123
|
+
}
|
|
32124
|
+
}, /*#__PURE__*/React$1.createElement(CartesianGrid, {
|
|
32125
|
+
strokeDasharray: "3 3",
|
|
32126
|
+
vertical: false
|
|
32127
|
+
}), /*#__PURE__*/React$1.createElement(XAxis, {
|
|
32128
|
+
dataKey: "week",
|
|
32129
|
+
tick: /*#__PURE__*/React$1.createElement(CustomizedTick, null)
|
|
32130
|
+
}), /*#__PURE__*/React$1.createElement(YAxis, {
|
|
32131
|
+
type: "number",
|
|
32132
|
+
domain: [0, "dataMax + 2000"],
|
|
32133
|
+
hide: true
|
|
32134
|
+
}), /*#__PURE__*/React$1.createElement(Tooltip$2, {
|
|
32135
|
+
content: /*#__PURE__*/React$1.createElement(CustomTooltip, null)
|
|
32136
|
+
}), /*#__PURE__*/React$1.createElement(Brush, {
|
|
32137
|
+
height: 30,
|
|
32138
|
+
travellerWidth: 10,
|
|
32139
|
+
startIndex: 1,
|
|
32140
|
+
endIndex: 5,
|
|
32141
|
+
y: 369
|
|
32142
|
+
}), /*#__PURE__*/React$1.createElement(Bar, {
|
|
32143
|
+
dataKey: "total",
|
|
32144
|
+
shape: /*#__PURE__*/React$1.createElement(BarWithInner, null),
|
|
32145
|
+
label: /*#__PURE__*/React$1.createElement(CustomBarLabel, null),
|
|
32146
|
+
barSize: 30
|
|
32147
|
+
})));
|
|
32148
|
+
}
|
|
32149
|
+
|
|
32150
|
+
styled.div`
|
|
32151
|
+
font-family: sans-serif;
|
|
32152
|
+
text-align: center;
|
|
32153
|
+
`;
|
|
32154
|
+
styled.div`
|
|
32155
|
+
height: 25%;
|
|
32156
|
+
`;
|
|
32157
|
+
styled.div`
|
|
32158
|
+
height: 75%;
|
|
32159
|
+
`;
|
|
32160
|
+
styled.div`
|
|
32161
|
+
height: 100%;
|
|
32162
|
+
display: flex;
|
|
32163
|
+
flex-direction: column;
|
|
32164
|
+
background-color: white;
|
|
32165
|
+
`;
|
|
32166
|
+
const Container = styled.div`
|
|
32167
|
+
width: 100%;
|
|
32168
|
+
height: 100%;
|
|
32169
|
+
display: flex;
|
|
32170
|
+
flex-direction: column;
|
|
32171
|
+
#Segment {
|
|
32172
|
+
width: auto;
|
|
32173
|
+
white-space: nowrap;
|
|
32174
|
+
font-size: 14px;
|
|
32175
|
+
font-weight: 500;
|
|
32176
|
+
font-family: "Poppins"
|
|
32177
|
+
}
|
|
32178
|
+
`;
|
|
32179
|
+
/* Make brush background darker */
|
|
32180
|
+
/* .recharts-brush .recharts-brush-slide {
|
|
32181
|
+
fill: #a52a2a !important;
|
|
32182
|
+
stroke: none;
|
|
32183
|
+
}
|
|
32184
|
+
|
|
32185
|
+
/* Style draggable handles (travellers) */
|
|
32186
|
+
/* .recharts-brush-traveller {
|
|
32187
|
+
fill: limegreen !important; /* bright green like in the image */
|
|
32188
|
+
/* cursor: ew-resize;
|
|
32189
|
+
} */
|
|
32190
|
+
|
|
32191
|
+
/* Optional: center grip arrows (you can fake it with CSS) */
|
|
32192
|
+
/* .recharts-brush .recharts-brush-traveller > rect {
|
|
32193
|
+
rx: 2;
|
|
32194
|
+
ry: 2;
|
|
32195
|
+
width: 6;
|
|
32196
|
+
fill: #a52a2a !important; /* dark gray */
|
|
32197
|
+
/* } */
|
|
32198
|
+
|
|
32199
|
+
/* Remove tick labels if needed */
|
|
32200
|
+
// .recharts-brush .recharts-layer text {
|
|
32201
|
+
// display: none;
|
|
32202
|
+
// }
|
|
32203
|
+
|
|
32204
|
+
const BrushChart = () => {
|
|
32205
|
+
const segmentedbuttonOptions = ["New Shoppers & Repeaters", "INC Sales & ROI", "INC Units", "Basket Lift"];
|
|
32206
|
+
const [selectedOption, setSelectedOption] = useState(segmentedbuttonOptions[0]);
|
|
32207
|
+
return /*#__PURE__*/React$1.createElement(Container, null, /*#__PURE__*/React$1.createElement(SegmentedButton, {
|
|
32208
|
+
gap: '8px',
|
|
32209
|
+
options: segmentedbuttonOptions.map(value => ({
|
|
32210
|
+
value
|
|
32211
|
+
})),
|
|
32212
|
+
onClick: _ref => {
|
|
32213
|
+
let {
|
|
32214
|
+
value
|
|
32215
|
+
} = _ref;
|
|
32216
|
+
return setSelectedOption(value);
|
|
32217
|
+
}
|
|
32218
|
+
}), selectedOption === "New Shoppers & Repeaters" && /*#__PURE__*/React$1.createElement(InnerBarChart, null), selectedOption === "INC Sales & ROI" && /*#__PURE__*/React$1.createElement(SeparatedLineBarChart, null), selectedOption === "INC Units" && /*#__PURE__*/React$1.createElement(SingleChart, null), selectedOption === "Basket Lift" && /*#__PURE__*/React$1.createElement(SingleChart, null));
|
|
30414
32219
|
};
|
|
30415
32220
|
|
|
30416
|
-
export { AreaChart, BannerEventBoxList, BarChart, BarChartsByWeeks, BatteryChart, BreakdownPanel, Button, CollapseHeader, DialogOverlay, DoubleBarSingleLine, DoublePanelDataRow, EventDetailsCard, EventList, FilterPanel, Heatmap, IconButton, LinkButton, LinnerDataBox, MarketShareDescription, OneColumnContainer, PerformanceAnalyticsLegend, PieChart, PopupCharts, QuickFilter, ReportTable, TabMenu, TopToggleList, TotalDoughnutChart, TotalHorizontalCharts };
|
|
32221
|
+
export { AreaChart, BannerEventBoxList, BarChart, BarChartsByWeeks, BatteryChart, BreakdownPanel, BrushChart, BubbleChart, Button, CollapseHeader, DialogOverlay, DoubleBarSingleLine, DoublePanelDataRow, EventDetailsCard, EventList, FilterPanel, Heatmap, IconButton, LinkButton, LinnerDataBox, MarketShareDescription, OneColumnContainer, PerformanceAnalyticsLegend, PieChart, PopupCharts, QuickFilter, ReportTable, TabMenu, TopToggleList, TotalDoughnutChart, TotalHorizontalCharts };
|
|
30417
32222
|
//# sourceMappingURL=index.esm.js.map
|