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