oolib 2.195.0 → 2.195.1

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.
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.Legend = void 0;
18
+ var react_1 = __importDefault(require("react"));
19
+ var __1 = require("../../../../../..");
20
+ var Typo2_1 = require("../../../../Typo2");
21
+ var LegendTooltipGlyph_1 = require("../LegendTooltipGlyph");
22
+ var Legend = function (_a) {
23
+ var data = _a.data, label = _a.label, _b = _a.orientation, orientation = _b === void 0 ? "vertical" : _b;
24
+ return (react_1.default.createElement("div", { style: __assign(__assign({}, (orientation === 'vertical' ? { maxWidth: '200px' } : {})), { padding: "12px", borderRadius: '8px', border: "1px solid ".concat(__1.colors2.grey5), background: "linear-gradient(to bottom, hsla(0, 0%, 96%, 1), hsla(0, 0%, 100%, 0))" }) },
25
+ label && orientation === 'vertical' && (react_1.default.createElement("div", { style: { paddingBottom: "8px" } },
26
+ react_1.default.createElement(Typo2_1.UI_CAPTION_BOLD_DF, null, label))),
27
+ react_1.default.createElement("div", { style: __assign(__assign({ display: "flex", flexDirection: orientation === "vertical" ? "column" : "row" }, (orientation === 'horizontal' ? { flexWrap: 'wrap' } : {})), { gap: "8px" }) },
28
+ label && orientation === 'horizontal' && (react_1.default.createElement(Typo2_1.UI_CAPTION_BOLD_DF, null, label)),
29
+ data.map(function (d, index) {
30
+ return (react_1.default.createElement("div", { key: index, style: { display: "flex", alignItems: "center", gap: "6px" } },
31
+ react_1.default.createElement(LegendTooltipGlyph_1.LegendTooltipGlyph, { color: d.color }),
32
+ react_1.default.createElement(Typo2_1.UI_CAPTION_DF, null, d.text)));
33
+ }))));
34
+ };
35
+ exports.Legend = Legend;
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+ interface LegendTooltipGlyphProps {
3
+ color: string;
4
+ size?: number;
5
+ }
6
+ export declare const LegendTooltipGlyph: React.FC<LegendTooltipGlyphProps>;
7
+ export {};
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.LegendTooltipGlyph = void 0;
7
+ var react_1 = __importDefault(require("react"));
8
+ var LegendTooltipGlyph = function (_a) {
9
+ var color = _a.color, _b = _a.size, size = _b === void 0 ? 10 : _b;
10
+ return (react_1.default.createElement("div", { style: {
11
+ width: size + 'px',
12
+ height: size + 'px',
13
+ borderRadius: "50%",
14
+ backgroundColor: color,
15
+ } }));
16
+ };
17
+ exports.LegendTooltipGlyph = LegendTooltipGlyph;
@@ -18,6 +18,7 @@ export interface BarChartProps {
18
18
  [key: string]: string;
19
19
  };
20
20
  tooltipLabelsPath: string | string[];
21
+ breakdownCategoryName?: string;
21
22
  labelPath: string;
22
23
  onClick?: (name: string) => void;
23
24
  valueSuffix?: string;
@@ -26,6 +27,8 @@ export interface BarChartProps {
26
27
  breakdownDisplayType?: BreakdownDisplayType;
27
28
  colorIdx?: number;
28
29
  summarizeAfterIdx?: number;
30
+ overflowAfterHeight?: number;
31
+ style?: React.CSSProperties;
29
32
  }
30
33
  export declare const BarChart: React.FC<BarChartProps>;
31
34
  export {};
@@ -51,10 +51,11 @@ exports.BarChart = exports.useTrackMousePosition = void 0;
51
51
  var react_1 = __importStar(require("react"));
52
52
  var recharts_1 = require("recharts");
53
53
  var CustomizedLabel_1 = require("./comps/CustomizedLabel");
54
- var colors_1 = require("../../../themes/colors");
55
54
  var CustomTooltip_1 = __importDefault(require("./comps/CustomTooltip"));
56
55
  var usePrepareData_1 = require("../utils/usePrepareData");
57
56
  var _base_barchart_ui_configs_1 = require("./_base_barchart_ui_configs");
57
+ var Legend_1 = require("./comps/Legend");
58
+ var __1 = require("../../../..");
58
59
  var useTrackMousePosition = function () {
59
60
  var _a = (0, react_1.useState)({
60
61
  x: 0,
@@ -73,23 +74,39 @@ var useTrackMousePosition = function () {
73
74
  return ({ mousePosition: mousePosition });
74
75
  };
75
76
  exports.useTrackMousePosition = useTrackMousePosition;
76
- // CHART_OFFSET_TOP is the y shift on top of the entire chart, because otherwise the chart starts with bar 1 at 0,0 coordinates
77
+ // CHART_OFFSET_TOP & CHART_OFFSET_TOP_BREAKDOWN is the y shift on top of the entire chart, because otherwise the chart starts with bar 1 at 0,0 coordinates
77
78
  var CHART_OFFSET_TOP = _base_barchart_ui_configs_1._base_barchart_ui_configs.labelToBarGap +
78
79
  _base_barchart_ui_configs_1._base_barchart_ui_configs.labelHeight +
79
80
  (_base_barchart_ui_configs_1._base_barchart_ui_configs.labelToNextBarGap / 2 - 2); //this minus 2 is just to correct the extra white space that the labelHeight takes on top of the text
81
+ var CHART_OFFSET_TOP_BREAKDOWN = _base_barchart_ui_configs_1._base_barchart_ui_configs.labelToBarGap +
82
+ _base_barchart_ui_configs_1._base_barchart_ui_configs.labelHeight +
83
+ _base_barchart_ui_configs_1._base_barchart_ui_configs.gapBetweenTwoLabels +
84
+ _base_barchart_ui_configs_1._base_barchart_ui_configs.labelHeight + //twice because the text and the percent are on separate lines
85
+ (_base_barchart_ui_configs_1._base_barchart_ui_configs.labelToNextBarGap / 2 - 2); //this minus 2 is just to correct the extra white space that the labelHeight takes on top of the text
80
86
  var TOT_HEIGHT_SINGLE_BAR_SECTION = _base_barchart_ui_configs_1._base_barchart_ui_configs.barHeight +
81
87
  _base_barchart_ui_configs_1._base_barchart_ui_configs.labelToBarGap +
82
88
  _base_barchart_ui_configs_1._base_barchart_ui_configs.labelHeight +
83
89
  _base_barchart_ui_configs_1._base_barchart_ui_configs.labelToNextBarGap;
90
+ var TOT_HEIGHT_STACKED_BAR_SECTION = _base_barchart_ui_configs_1._base_barchart_ui_configs.barHeight +
91
+ _base_barchart_ui_configs_1._base_barchart_ui_configs.labelToBarGap +
92
+ _base_barchart_ui_configs_1._base_barchart_ui_configs.labelHeight +
93
+ _base_barchart_ui_configs_1._base_barchart_ui_configs.gapBetweenTwoLabels +
94
+ _base_barchart_ui_configs_1._base_barchart_ui_configs.labelHeight +
95
+ _base_barchart_ui_configs_1._base_barchart_ui_configs.labelToNextBarGap;
84
96
  var CALC_SINGLE_BAR_SECTION_Y_POS = function (index) {
85
97
  return (TOT_HEIGHT_SINGLE_BAR_SECTION + _base_barchart_ui_configs_1._base_barchart_ui_configs.gapBetweenBarSections) * index;
86
98
  };
99
+ var CALC_STACKED_BAR_SECTION_Y_POS = function (index) {
100
+ return (TOT_HEIGHT_STACKED_BAR_SECTION + _base_barchart_ui_configs_1._base_barchart_ui_configs.gapBetweenBarSections) * index;
101
+ };
87
102
  var CALC_TOTAL_HEIGHT_GROUPED_BAR_SECTION = function (noOfBarsInGroup) {
88
103
  var totalHeightOfAllBars = noOfBarsInGroup * _base_barchart_ui_configs_1._base_barchart_ui_configs.barHeight +
89
104
  (noOfBarsInGroup - 1) * _base_barchart_ui_configs_1._base_barchart_ui_configs.gapBetweenBarsInGroup;
90
105
  return (totalHeightOfAllBars +
91
106
  _base_barchart_ui_configs_1._base_barchart_ui_configs.labelToBarGap +
92
107
  _base_barchart_ui_configs_1._base_barchart_ui_configs.labelHeight +
108
+ _base_barchart_ui_configs_1._base_barchart_ui_configs.gapBetweenTwoLabels +
109
+ _base_barchart_ui_configs_1._base_barchart_ui_configs.labelHeight + //twice because the text and the percent are on separate lines
93
110
  _base_barchart_ui_configs_1._base_barchart_ui_configs.labelToNextBarGap);
94
111
  };
95
112
  var CALC_GROUPED_BAR_SECTION_Y_POS = function (index, barIndex, noOfBarsInGroup) {
@@ -100,15 +117,19 @@ var CALC_GROUPED_BAR_SECTION_Y_POS = function (index, barIndex, noOfBarsInGroup)
100
117
  barIndex * (_base_barchart_ui_configs_1._base_barchart_ui_configs.barHeight + _base_barchart_ui_configs_1._base_barchart_ui_configs.gapBetweenBarsInGroup));
101
118
  };
102
119
  var CALC_TOTAL_HEIGHT_OF_CHART = function (_a) {
103
- var isBreakdown = _a.isBreakdown, breakdownDisplayType = _a.breakdownDisplayType, data = _a.data;
120
+ var isBreakdown = _a.isBreakdown, breakdownDisplayType = _a.breakdownDisplayType, data = _a.data, showSumOfBreakdownValues = _a.showSumOfBreakdownValues;
104
121
  return isBreakdown && breakdownDisplayType === "grouped"
105
122
  ? CALC_TOTAL_HEIGHT_GROUPED_BAR_SECTION(data[0].length) *
106
123
  data.length +
107
124
  _base_barchart_ui_configs_1._base_barchart_ui_configs.gapBetweenBarSections * (data.length - 1) +
108
125
  _base_barchart_ui_configs_1._base_barchart_ui_configs.hoverRectStrokeWidth * 2
109
- : TOT_HEIGHT_SINGLE_BAR_SECTION * data.length +
110
- _base_barchart_ui_configs_1._base_barchart_ui_configs.gapBetweenBarSections * (data.length - 1) +
111
- _base_barchart_ui_configs_1._base_barchart_ui_configs.hoverRectStrokeWidth * 2;
126
+ : isBreakdown && breakdownDisplayType === 'stacked' && !showSumOfBreakdownValues
127
+ ? (TOT_HEIGHT_STACKED_BAR_SECTION * data.length) +
128
+ _base_barchart_ui_configs_1._base_barchart_ui_configs.gapBetweenBarSections * (data.length - 1) +
129
+ _base_barchart_ui_configs_1._base_barchart_ui_configs.hoverRectStrokeWidth * 2
130
+ : TOT_HEIGHT_SINGLE_BAR_SECTION * data.length +
131
+ _base_barchart_ui_configs_1._base_barchart_ui_configs.gapBetweenBarSections * (data.length - 1) +
132
+ _base_barchart_ui_configs_1._base_barchart_ui_configs.hoverRectStrokeWidth * 2;
112
133
  };
113
134
  var _debug_controls = {
114
135
  mouseEventDetectorOpacity: 0, //only increase this for debugging. nothing else.
@@ -139,110 +160,157 @@ var barConfigs = {
139
160
  },
140
161
  };
141
162
  var renderBar = function (_a) {
142
- var _b = _a.stackIndex, stackIndex = _b === void 0 ? 0 : _b, dataToRender = _a.data, isBreakdownToRender = _a.isBreakdown, breakdownDisplayTypeToRender = _a.breakdownDisplayType, showSumOfBreakdownValues = _a.showSumOfBreakdownValues,
143
- //
144
- colorIdx = _a.colorIdx, showPercent = _a.showPercent, showCount = _a.showCount, activeBar = _a.activeBar, setActiveBar = _a.setActiveBar, onClick = _a.onClick;
145
- var activeConfig = isBreakdownToRender
163
+ var _b = _a.stackIndex, stackIndex = _b === void 0 ? 0 : _b, data = _a.data, isBreakdown = _a.isBreakdown, breakdownDisplayType = _a.breakdownDisplayType, showSumOfBreakdownValues = _a.showSumOfBreakdownValues, showPercent = _a.showPercent, showCount = _a.showCount, activeBar = _a.activeBar, setActiveBar = _a.setActiveBar, onClick = _a.onClick;
164
+ var activeConfig = isBreakdown
146
165
  ? barConfigs.isBreakdown
147
166
  : barConfigs.isNotBreakdown;
148
- var totalStacks = isBreakdownToRender
149
- ? dataToRender[0].length
167
+ var totalStacks = isBreakdown
168
+ ? data[0].length
150
169
  : 1;
151
- var currentStackId = activeConfig.getStackId(stackIndex, breakdownDisplayTypeToRender);
152
- return (react_1.default.createElement(recharts_1.Bar, { key: "stack-".concat(stackIndex), radius: activeConfig.getBarRadius(stackIndex, breakdownDisplayTypeToRender, totalStacks), dataKey: activeConfig.getDataKey(stackIndex), stackId: currentStackId },
153
- (!isBreakdownToRender || stackIndex === 0) && (react_1.default.createElement(recharts_1.LabelList, { dataKey: isBreakdownToRender ? function (dataPoint) { return dataPoint; } : "labels", offset: 0, position: "bottom", content: function (props) { return (react_1.default.createElement(CustomizedLabel_1.CustomizedLabel, __assign({ CALC_SINGLE_BAR_SECTION_Y_POS: CALC_SINGLE_BAR_SECTION_Y_POS, TOT_HEIGHT_SINGLE_BAR_SECTION: TOT_HEIGHT_SINGLE_BAR_SECTION, TOT_HEIGHT_GROUPED_BAR_SECTION: isBreakdownToRender &&
154
- breakdownDisplayTypeToRender === "grouped"
155
- ? CALC_TOTAL_HEIGHT_GROUPED_BAR_SECTION(dataToRender[0].length)
156
- : undefined,
157
- breakdownDisplayType: breakdownDisplayTypeToRender,
158
- y: props.y,
170
+ var currentStackId = activeConfig.getStackId(stackIndex, breakdownDisplayType);
171
+ return (react_1.default.createElement(recharts_1.Bar, { key: "stack-".concat(stackIndex), radius: activeConfig.getBarRadius(stackIndex, breakdownDisplayType, totalStacks), dataKey: activeConfig.getDataKey(stackIndex), stackId: currentStackId },
172
+ (!isBreakdown || stackIndex === 0) && (react_1.default.createElement(recharts_1.LabelList, { dataKey: isBreakdown ? function (dataPoint) { return dataPoint; } : "labels", offset: 0, position: "bottom", content: function (props) { return (react_1.default.createElement(CustomizedLabel_1.CustomizedLabel, __assign({ CALC_SINGLE_BAR_SECTION_Y_POS: CALC_SINGLE_BAR_SECTION_Y_POS, CALC_STACKED_BAR_SECTION_Y_POS: CALC_STACKED_BAR_SECTION_Y_POS, TOT_HEIGHT_SINGLE_BAR_SECTION: TOT_HEIGHT_SINGLE_BAR_SECTION, TOT_HEIGHT_STACKED_BAR_SECTION: TOT_HEIGHT_STACKED_BAR_SECTION, TOT_HEIGHT_GROUPED_BAR_SECTION: isBreakdown &&
173
+ breakdownDisplayType === "grouped"
174
+ ? CALC_TOTAL_HEIGHT_GROUPED_BAR_SECTION(data[0].length)
175
+ : undefined, breakdownDisplayType: breakdownDisplayType, y: props.y,
159
176
  width: props.width,
160
177
  height: props.height,
161
- value: isBreakdownToRender
162
- ? dataToRender[props.index].map(function (item, idx) { return (__assign(__assign({}, item.labels), { color: colors_1.dataVizColorsText[(colorIdx + idx) % colors_1.dataVizColorsText.length] })); })
178
+ value: isBreakdown
179
+ ? data[props.index].map(function (item, idx) { return (__assign({}, item.labels)); })
163
180
  : props.value, showPercent: showPercent, showCount: showCount, showSumOfBreakdownValues: showSumOfBreakdownValues, opacity: 1, activeBar: activeBar, _base_barchart_ui_configs: _base_barchart_ui_configs_1._base_barchart_ui_configs, _debug_controls: _debug_controls }, (onClick
164
181
  ? {
165
182
  onMouseOver: function (e, value) {
166
- setActiveBar(isBreakdownToRender
167
- ? dataToRender[props.index][0].labels.name
183
+ setActiveBar(isBreakdown
184
+ ? data[props.index][0].labels.name
168
185
  : value.name);
169
186
  },
170
- onMouseOut: function () { return setActiveBar(undefined); },
187
+ onMouseOut: function () {
188
+ setActiveBar(undefined);
189
+ },
171
190
  onMouseDown: function (e, value) {
172
- var name = isBreakdownToRender
173
- ? dataToRender[props.index][0].labels.name
191
+ var name = isBreakdown
192
+ ? data[props.index][0].labels.name
174
193
  : value.name;
175
194
  setActiveBar(name);
176
195
  onClick(name);
177
196
  },
178
197
  }
179
198
  : {})))); } })),
180
- dataToRender.map(function (d, index) { return (react_1.default.createElement(recharts_1.Cell, { y: !isBreakdownToRender || breakdownDisplayTypeToRender === "stacked"
181
- ? CALC_SINGLE_BAR_SECTION_Y_POS(index) + CHART_OFFSET_TOP
182
- : CALC_GROUPED_BAR_SECTION_Y_POS(index, stackIndex, dataToRender[0].length) + CHART_OFFSET_TOP, key: "cell-".concat(index, "-").concat(stackIndex), opacity: 1, height: _base_barchart_ui_configs_1._base_barchart_ui_configs.barHeight, fill: activeConfig.getCellFill(colorIdx, stackIndex, colors_1.dataVizColors) })); })));
199
+ data.map(function (d, index) {
200
+ /**
201
+ * note this this map works differently for breakdown & not breakdown
202
+ * for not breakdown - this map renders each of the inidividual bars.
203
+ * for breakdown - this map renders each of the individual bar groups
204
+ */
205
+ return (react_1.default.createElement(recharts_1.Cell, { y: (!isBreakdown || showSumOfBreakdownValues) // this is confusing, but showSumOfBreakdownValues is only used to render the 'compressed' other bar in normal bar charts. hence it has to have properties like a normal, non breakdown bar chart
206
+ ? CALC_SINGLE_BAR_SECTION_Y_POS(index) + CHART_OFFSET_TOP
207
+ : (breakdownDisplayType === "stacked" && !showSumOfBreakdownValues) //show summ happens in the summarized bar, were we dont want the double label approach
208
+ ? CALC_STACKED_BAR_SECTION_Y_POS(index) + CHART_OFFSET_TOP_BREAKDOWN
209
+ : breakdownDisplayType === "grouped" &&
210
+ CALC_GROUPED_BAR_SECTION_Y_POS(index, stackIndex, data[0].length) + CHART_OFFSET_TOP_BREAKDOWN, key: "cell-".concat(index, "-").concat(stackIndex), opacity: 1, height: _base_barchart_ui_configs_1._base_barchart_ui_configs.barHeight, fill: !isBreakdown
211
+ ? d.labels.barColor
212
+ : d[stackIndex].labels.barColor }));
213
+ })));
214
+ };
215
+ var useDecideLegendOrientation = function (options) {
216
+ if (options === void 0) { options = {}; }
217
+ var _a = options.widthThreshold, widthThreshold = _a === void 0 ? 500 : _a;
218
+ var vizWrapperRef = (0, react_1.useRef)(null);
219
+ var _b = (0, react_1.useState)('horizontal'), orientation = _b[0], setOrientation = _b[1];
220
+ (0, react_1.useEffect)(function () {
221
+ var element = vizWrapperRef.current;
222
+ if (!element)
223
+ return;
224
+ var resizeObserver = new ResizeObserver(function (entries) {
225
+ for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) {
226
+ var entry = entries_1[_i];
227
+ var width = entry.contentRect.width;
228
+ // If width is >= threshold, use horizontal, otherwise vertical
229
+ var newOrientation = width >= widthThreshold ? 'vertical' : 'horizontal';
230
+ setOrientation(newOrientation);
231
+ }
232
+ });
233
+ resizeObserver.observe(element);
234
+ // Set initial orientation
235
+ var initialWidth = element.getBoundingClientRect().width;
236
+ setOrientation(initialWidth >= widthThreshold ? 'vertical' : 'horizontal');
237
+ // Cleanup
238
+ return function () {
239
+ resizeObserver.disconnect();
240
+ };
241
+ }, [widthThreshold]);
242
+ return {
243
+ vizWrapperRef: vizWrapperRef,
244
+ orientation: orientation
245
+ };
183
246
  };
184
247
  var BarChartRenderer = function (_a) {
185
- var data = _a.data, isBreakdown = _a.isBreakdown, breakdownDisplayType = _a.breakdownDisplayType, showSumOfBreakdownValues = _a.showSumOfBreakdownValues, colorIdx = _a.colorIdx, showPercent = _a.showPercent, showCount = _a.showCount, activeBar = _a.activeBar, setActiveBar = _a.setActiveBar, onClick = _a.onClick,
248
+ var data = _a.data, isBreakdown = _a.isBreakdown, breakdownDisplayType = _a.breakdownDisplayType, showSumOfBreakdownValues = _a.showSumOfBreakdownValues, showPercent = _a.showPercent, showCount = _a.showCount, activeBar = _a.activeBar, setActiveBar = _a.setActiveBar, onClick = _a.onClick,
186
249
  //
187
- mousePosition = _a.mousePosition, dataMaxValue = _a.dataMaxValue, containerWidth = _a.containerWidth;
188
- return (
189
- // <ResponsiveContainer width="100%" height="100%">
190
- react_1.default.createElement(recharts_1.BarChart, { width: containerWidth, height: CALC_TOTAL_HEIGHT_OF_CHART({
250
+ mousePosition = _a.mousePosition, dataMaxValue = _a.dataMaxValue, breakdownCategoryName = _a.breakdownCategoryName;
251
+ return (react_1.default.createElement(recharts_1.ResponsiveContainer, { width: "100%", height: CALC_TOTAL_HEIGHT_OF_CHART({
191
252
  isBreakdown: isBreakdown,
192
253
  breakdownDisplayType: breakdownDisplayType,
254
+ showSumOfBreakdownValues: showSumOfBreakdownValues,
193
255
  data: data
194
- }), data: data, layout: "vertical", margin: {
195
- top: 0,
196
- right: _base_barchart_ui_configs_1._base_barchart_ui_configs.marginRight,
197
- left: _base_barchart_ui_configs_1._base_barchart_ui_configs.marginLeft,
198
- bottom: 0,
199
- } },
200
- react_1.default.createElement(recharts_1.XAxis, { hide: true, type: "number", domain: [0, dataMaxValue] }),
201
- react_1.default.createElement(recharts_1.YAxis, { hide: true, type: "category" }),
202
- isBreakdown && (react_1.default.createElement(recharts_1.Tooltip, { content: function (props) {
203
- var _a;
204
- return (react_1.default.createElement(CustomTooltip_1.default, __assign({}, props, { mousePosition: mousePosition, showPercent: showPercent,
205
- // god knows why the dataindex gets stored against props.label.
206
- // this is some internal recharts thing for tooltips specifically.
207
- // we dont do this.
208
- value: (_a = data[props.label]) === null || _a === void 0 ? void 0 : _a.map(function (item, idx) { return (__assign(__assign({}, item.labels), { color: colors_1.dataVizColors[(colorIdx + idx) % colors_1.dataVizColors.length] })); }) })));
209
- }, cursor: false, allowEscapeViewBox: { x: true, y: true } })),
210
- isBreakdown
211
- ? data[0].map(function (_, stackIndex) {
212
- return renderBar({
213
- stackIndex: stackIndex,
256
+ }) },
257
+ react_1.default.createElement(recharts_1.BarChart, { data: data, layout: "vertical", margin: {
258
+ top: 0,
259
+ right: _base_barchart_ui_configs_1._base_barchart_ui_configs.marginRight,
260
+ left: _base_barchart_ui_configs_1._base_barchart_ui_configs.marginLeft,
261
+ bottom: 0,
262
+ } },
263
+ react_1.default.createElement(recharts_1.XAxis, { hide: true, type: "number", domain: [0, dataMaxValue] }),
264
+ react_1.default.createElement(recharts_1.YAxis, { hide: true, type: "category" }),
265
+ isBreakdown && (react_1.default.createElement(recharts_1.Tooltip, { content: function (props) {
266
+ var _a;
267
+ return (react_1.default.createElement(CustomTooltip_1.default, __assign({}, props, { breakdownCategoryName: breakdownCategoryName, activeBar: activeBar, mousePosition: mousePosition, showPercent: showPercent,
268
+ // god knows why the dataindex gets stored against props.label.
269
+ // this is some internal recharts thing for tooltips specifically.
270
+ // we dont do this.
271
+ value: (_a = data[props.label]) === null || _a === void 0 ? void 0 : _a.map(function (item, idx) { return (__assign({}, item.labels)); }) })));
272
+ }, cursor: false, allowEscapeViewBox: { x: true, y: true } })),
273
+ isBreakdown
274
+ ? data[0].map(function (_, stackIndex) {
275
+ //note that this map renders the individual bars within a breakdown group
276
+ return renderBar({
277
+ stackIndex: stackIndex,
278
+ data: data,
279
+ isBreakdown: isBreakdown,
280
+ breakdownDisplayType: breakdownDisplayType,
281
+ showSumOfBreakdownValues: showSumOfBreakdownValues,
282
+ showPercent: showPercent,
283
+ showCount: showCount,
284
+ activeBar: activeBar,
285
+ setActiveBar: setActiveBar,
286
+ onClick: onClick,
287
+ });
288
+ })
289
+ : renderBar({
290
+ stackIndex: undefined,
214
291
  data: data,
215
292
  isBreakdown: isBreakdown,
216
293
  breakdownDisplayType: breakdownDisplayType,
217
294
  showSumOfBreakdownValues: showSumOfBreakdownValues,
218
- colorIdx: colorIdx,
219
295
  showPercent: showPercent,
220
296
  showCount: showCount,
221
297
  activeBar: activeBar,
222
298
  setActiveBar: setActiveBar,
223
299
  onClick: onClick,
224
- });
225
- })
226
- : renderBar({
227
- stackIndex: undefined,
228
- data: data,
229
- isBreakdown: isBreakdown,
230
- breakdownDisplayType: breakdownDisplayType,
231
- showSumOfBreakdownValues: showSumOfBreakdownValues,
232
- colorIdx: colorIdx,
233
- showPercent: showPercent,
234
- showCount: showCount,
235
- activeBar: activeBar,
236
- setActiveBar: setActiveBar,
237
- onClick: onClick,
238
- }))
239
- // </ResponsiveContainer>
240
- );
300
+ }))));
301
+ };
302
+ var FadeGradientWhenScroll = function (_a) {
303
+ var _b = _a.style, style = _b === void 0 ? {} : _b;
304
+ return (react_1.default.createElement("div", { style: __assign({ width: '100%', height: '40px', position: 'sticky', left: 0, bottom: 0, background: "linear-gradient(to top, ".concat(__1.colors2.white, ", hsla(0, 0%, 100%, 0))") }, style) }));
241
305
  };
242
306
  var BarChart = function (_a) {
243
- var _data = _a.data, valuePath = _a.valuePath, tooltipLabelsMapping = _a.tooltipLabelsMapping, tooltipLabelsPath = _a.tooltipLabelsPath, _b = _a.labelPath, labelPath = _b === void 0 ? "name" : _b, onClick = _a.onClick, _c = _a.breakdownDisplayType, breakdownDisplayType = _c === void 0 ? "grouped" : _c, _d = _a.showCount, showCount = _d === void 0 ? true : _d, _e = _a.showPercent, showPercent = _e === void 0 ? true : _e, _f = _a.colorIdx, colorIdx = _f === void 0 ? 0 : _f, _g = _a.summarizeAfterIdx, summarizeAfterIdx = _g === void 0 ? 5 : _g;
307
+ var _data = _a.data, valuePath = _a.valuePath, _b = _a.style, style = _b === void 0 ? {} : _b, tooltipLabelsMapping = _a.tooltipLabelsMapping, tooltipLabelsPath = _a.tooltipLabelsPath, breakdownCategoryName = _a.breakdownCategoryName, // basically, if lets say tagCat1 is broken down by tagCat2. then tagCat2's display would be this property
308
+ _c = _a.labelPath, // basically, if lets say tagCat1 is broken down by tagCat2. then tagCat2's display would be this property
309
+ labelPath = _c === void 0 ? "name" : _c, onClick = _a.onClick, _d = _a.breakdownDisplayType, breakdownDisplayType = _d === void 0 ? "grouped" : _d, _e = _a.showCount, showCount = _e === void 0 ? true : _e, _f = _a.showPercent, showPercent = _f === void 0 ? true : _f, _g = _a.colorIdx, colorIdx = _g === void 0 ? 0 : _g, _h = _a.summarizeAfterIdx, summarizeAfterIdx = _h === void 0 ? undefined : _h, //if a number is defined, then from that 'index' onwards, bars will be compressed into a single bar with a tooltip explaining distribution
310
+ _j = _a.overflowAfterHeight, //if a number is defined, then from that 'index' onwards, bars will be compressed into a single bar with a tooltip explaining distribution
311
+ overflowAfterHeight = _j === void 0 ? 550 : _j;
244
312
  var isBreakdown = Array.isArray(valuePath);
245
- var _h = (0, usePrepareData_1.usePrepareData)({
313
+ var _k = (0, usePrepareData_1.usePrepareData)({
246
314
  _data: _data,
247
315
  labelPath: labelPath,
248
316
  valuePath: valuePath,
@@ -251,44 +319,29 @@ var BarChart = function (_a) {
251
319
  isBreakdown: isBreakdown,
252
320
  showPercent: showPercent,
253
321
  summarizeAfterIdx: summarizeAfterIdx,
254
- }), data = _h.data, dataMaxValue = _h.dataMaxValue, dataToSummarize = _h.dataToSummarize;
255
- var _j = (0, react_1.useState)(undefined), activeBar = _j[0], setActiveBar = _j[1];
322
+ colorIdx: colorIdx
323
+ }), data = _k.data, dataMaxValue = _k.dataMaxValue, dataToSummarize = _k.dataToSummarize;
324
+ var _l = useDecideLegendOrientation({
325
+ widthThreshold: 500
326
+ }), vizWrapperRef = _l.vizWrapperRef, orientation = _l.orientation;
327
+ var _m = (0, react_1.useState)(undefined), activeBar = _m[0], setActiveBar = _m[1];
256
328
  var mousePosition = (0, exports.useTrackMousePosition)().mousePosition;
257
329
  // menu options for grouped and stacked
258
330
  if (data.length === 0)
259
331
  return react_1.default.createElement("div", null, "No data available");
260
- // At the top of your component
261
- var _k = (0, react_1.useState)(undefined), containerWidth = _k[0], setContainerWidth = _k[1];
262
- // Use a ref and useEffect to measure parent width
263
- var containerRef = (0, react_1.useRef)(null);
264
- (0, react_1.useEffect)(function () {
265
- var updateWidth = function () {
266
- if (containerRef.current) {
267
- setContainerWidth(containerRef.current.getBoundingClientRect().width);
268
- }
269
- };
270
- updateWidth();
271
- window.addEventListener('resize', updateWidth);
272
- return function () { return window.removeEventListener('resize', updateWidth); };
273
- }, []);
274
- return (react_1.default.createElement("div", { style: {
275
- height: "".concat(CALC_TOTAL_HEIGHT_OF_CHART({
276
- isBreakdown: isBreakdown,
277
- breakdownDisplayType: breakdownDisplayType,
278
- data: data
279
- }) + (isBreakdown ? 0 : CALC_TOTAL_HEIGHT_OF_CHART({
280
- isBreakdown: true,
281
- breakdownDisplayType: 'stacked',
282
- data: dataToSummarize
283
- })), "px"),
284
- width: "100%",
285
- background: _debug_controls.chartWrapperBgColor,
286
- } },
287
- react_1.default.createElement("div", { ref: containerRef, style: { width: '100%', height: '100%' } },
288
- react_1.default.createElement(BarChartRenderer, { containerWidth: containerWidth, data: data, isBreakdown: isBreakdown, breakdownDisplayType: breakdownDisplayType, showSumOfBreakdownValues: false, colorIdx: colorIdx, showPercent: showPercent, showCount: showCount, activeBar: activeBar, setActiveBar: setActiveBar, onClick: onClick, mousePosition: mousePosition, dataMaxValue: dataMaxValue }),
289
- dataToSummarize && (react_1.default.createElement(BarChartRenderer, { containerWidth: containerWidth, data: dataToSummarize,
332
+ return (react_1.default.createElement("div", { ref: vizWrapperRef, style: __assign(__assign({}, style), { width: "100%", background: _debug_controls.chartWrapperBgColor, display: 'flex', gap: '8px', flexDirection: orientation === 'vertical' ? 'row' : 'column', position: 'relative', maxHeight: overflowAfterHeight, overflow: 'scroll' }) },
333
+ react_1.default.createElement("div", { style: { flexGrow: 1, position: 'relative' } },
334
+ react_1.default.createElement(BarChartRenderer, { data: data, dataToSummarize: dataToSummarize, isBreakdown: isBreakdown, breakdownDisplayType: breakdownDisplayType, showSumOfBreakdownValues: false, showPercent: showPercent, showCount: showCount, activeBar: activeBar, setActiveBar: setActiveBar, onClick: onClick, mousePosition: mousePosition, dataMaxValue: dataMaxValue, breakdownCategoryName: breakdownCategoryName }),
335
+ dataToSummarize && (react_1.default.createElement(BarChartRenderer, { data: dataToSummarize,
290
336
  isBreakdown: true,
291
337
  breakdownDisplayType: "stacked",
292
- showSumOfBreakdownValues: true, colorIdx: colorIdx, showPercent: showPercent, showCount: showCount, activeBar: activeBar, setActiveBar: setActiveBar, onClick: onClick, mousePosition: mousePosition, dataMaxValue: dataMaxValue })))));
338
+ showSumOfBreakdownValues: true, showPercent: showPercent, showCount: showCount, activeBar: activeBar, setActiveBar: setActiveBar, onClick: onClick, mousePosition: mousePosition, dataMaxValue: dataMaxValue, breakdownCategoryName: breakdownCategoryName })),
339
+ orientation === 'vertical' && react_1.default.createElement(FadeGradientWhenScroll, null)),
340
+ isBreakdown && react_1.default.createElement("div", { style: __assign({ position: 'sticky' }, (orientation === 'vertical' ? { top: 0 } : { bottom: 0, background: __1.colors2.white })) },
341
+ orientation === 'horizontal' && react_1.default.createElement(FadeGradientWhenScroll, { style: { transform: 'translateY(-100%)', top: 0, bottom: 'unset', position: 'absolute', } }),
342
+ react_1.default.createElement(Legend_1.Legend, { orientation: orientation, label: breakdownCategoryName, data: data[0].map(function (d) { return ({
343
+ text: d.labels.tooltipLabel,
344
+ color: d.labels.barColor
345
+ }); }) }))));
293
346
  };
294
347
  exports.BarChart = BarChart;
@@ -3,7 +3,8 @@ export interface CountVizLabels {
3
3
  count: number;
4
4
  name: string;
5
5
  dataIndex: number;
6
- color: string;
6
+ barColor: string;
7
+ textColor: string;
7
8
  tooltipLabel?: string;
8
9
  }
9
10
  export interface CountVizDatum {
@@ -10,11 +10,12 @@ interface PrepareDataParams {
10
10
  };
11
11
  tooltipLabelsPath: string | string[];
12
12
  summarizeAfterIdx?: number;
13
+ colorIdx?: number;
13
14
  }
14
15
  interface PreparedData {
15
16
  data: CountVizData;
16
17
  dataToSummarize: CountVizData;
17
18
  dataMaxValue: number;
18
19
  }
19
- export declare const usePrepareData: ({ _data, labelPath, valuePath, tooltipLabelsMapping, tooltipLabelsPath, isBreakdown, showPercent, summarizeAfterIdx, }: PrepareDataParams) => PreparedData;
20
+ export declare const usePrepareData: ({ _data, labelPath, valuePath, tooltipLabelsMapping, tooltipLabelsPath, isBreakdown, showPercent, summarizeAfterIdx, colorIdx }: PrepareDataParams) => PreparedData;
20
21
  export {};
@@ -24,8 +24,17 @@ exports.usePrepareData = void 0;
24
24
  var react_1 = require("react");
25
25
  var _EXPORTS_1 = require("../../../../utils/_EXPORTS");
26
26
  var getTotalCount_1 = require("../../../../utils/getTotalCount");
27
+ var colors_1 = require("../../../themes/colors");
28
+ var getBarColorForBreakdownData = function (_a) {
29
+ var colorIdx = _a.colorIdx, index = _a.index;
30
+ return colors_1.dataVizColors[(colorIdx + index) % colors_1.dataVizColors.length];
31
+ };
32
+ var getTextColorForBreakdownData = function (_a) {
33
+ var colorIdx = _a.colorIdx, index = _a.index;
34
+ return colors_1.dataVizColorsText[(colorIdx + index) % colors_1.dataVizColorsText.length];
35
+ };
27
36
  var usePrepareData = function (_a) {
28
- var _data = _a._data, labelPath = _a.labelPath, valuePath = _a.valuePath, tooltipLabelsMapping = _a.tooltipLabelsMapping, tooltipLabelsPath = _a.tooltipLabelsPath, isBreakdown = _a.isBreakdown, showPercent = _a.showPercent, summarizeAfterIdx = _a.summarizeAfterIdx;
37
+ var _data = _a._data, labelPath = _a.labelPath, valuePath = _a.valuePath, tooltipLabelsMapping = _a.tooltipLabelsMapping, tooltipLabelsPath = _a.tooltipLabelsPath, isBreakdown = _a.isBreakdown, showPercent = _a.showPercent, summarizeAfterIdx = _a.summarizeAfterIdx, colorIdx = _a.colorIdx;
29
38
  return (0, react_1.useMemo)(function () {
30
39
  var finalData = __spreadArray([], _data, true);
31
40
  if (finalData.length === 0)
@@ -44,11 +53,17 @@ var usePrepareData = function (_a) {
44
53
  return {
45
54
  labels: __assign(__assign({}, (showPercent
46
55
  ? { percentage: (0, _EXPORTS_1.getPercentage)(count, totalCount) }
47
- : {})), { count: count, name: (0, _EXPORTS_1.getVal)(d, labelPath) }),
56
+ : {})), { count: count, name: (0, _EXPORTS_1.getVal)(d, labelPath), barColor: colors_1.dataVizColors[colorIdx], textColor: colors_1.dataVizColorsText[colorIdx] }),
48
57
  };
49
58
  }
50
59
  return valuePath.map(function (path, i) {
51
60
  var count = (0, _EXPORTS_1.getVal)(d, path) || 0;
61
+ /**
62
+ * for breakdown first we assign a color to each valuepath.
63
+ * and then that color stays consistent for that valuepath across different breakdown groups
64
+ */
65
+ var barColor = getBarColorForBreakdownData({ colorIdx: colorIdx, index: i });
66
+ var textColor = getTextColorForBreakdownData({ colorIdx: colorIdx, index: i });
52
67
  return {
53
68
  labels: __assign(__assign({}, (showPercent
54
69
  ? { percentage: (0, _EXPORTS_1.getPercentage)(count, totalCount[index]) }
@@ -56,7 +71,7 @@ var usePrepareData = function (_a) {
56
71
  ? tooltipLabelsPath[i]
57
72
  ? (0, _EXPORTS_1.getVal)(d, tooltipLabelsPath[i]) || tooltipLabelsPath[i]
58
73
  : path
59
- : (tooltipLabelsMapping === null || tooltipLabelsMapping === void 0 ? void 0 : tooltipLabelsMapping[path]) || path, name: (0, _EXPORTS_1.getVal)(d, labelPath) }),
74
+ : (tooltipLabelsMapping === null || tooltipLabelsMapping === void 0 ? void 0 : tooltipLabelsMapping[path]) || path, name: (0, _EXPORTS_1.getVal)(d, labelPath), barColor: barColor, textColor: textColor }),
60
75
  };
61
76
  });
62
77
  });
@@ -66,6 +81,10 @@ var usePrepareData = function (_a) {
66
81
  return b.labels.count - a.labels.count;
67
82
  }
68
83
  else {
84
+ /**
85
+ * this sorts the order of the entire breakdown group/stack
86
+ * putting the one with the total largest count first all the way to the least
87
+ */
69
88
  var bTotal = b
70
89
  .map(function (bItem) { return bItem.labels.count; })
71
90
  .reduce(function (acc, curr) { return acc + curr; }, 0);
@@ -75,34 +94,57 @@ var usePrepareData = function (_a) {
75
94
  return bTotal - aTotal;
76
95
  }
77
96
  });
97
+ // Sort inner arrays from largest to smallest when it's a breakdown
98
+ if (isBreakdown) {
99
+ finalData.forEach(function (innerArray) {
100
+ innerArray.sort(function (a, b) {
101
+ return b.labels.count - a.labels.count;
102
+ });
103
+ });
104
+ }
78
105
  finalData = isBreakdown
79
106
  ? finalData.map(function (d, i) {
80
107
  return d.map(function (dd, ii) { return (__assign(__assign({}, dd), { labels: __assign(__assign({}, dd.labels), { dataIndex: i }) })); });
81
108
  })
82
109
  : finalData.map(function (d, i) { return (__assign(__assign({}, d), { labels: __assign(__assign({}, d.labels), { dataIndex: i }) })); });
83
110
  var mainData = !isBreakdown
84
- ? finalData.filter(function (_, i) { return i <= summarizeAfterIdx; })
111
+ ? (summarizeAfterIdx ? finalData.filter(function (_, i) { return i <= summarizeAfterIdx; }) : finalData)
85
112
  : finalData;
86
113
  var convertDataToSummrizeIntoBreakdownFormat = function (data) {
87
- var reshaped = data.map(function (d, i) { return (__assign(__assign({}, d), { labels: __assign(__assign({}, d.labels), { name: "Others", tooltipLabel: d.labels.name, dataIndex: i }) })); });
114
+ var reshaped = data.map(function (d, i) { return (__assign(__assign({}, d), { labels: __assign(__assign({}, d.labels), { name: "Others", tooltipLabel: d.labels.name, dataIndex: i, barColor: getBarColorForBreakdownData({ colorIdx: colorIdx + 1, index: i }), textColor: getTextColorForBreakdownData({ colorIdx: colorIdx + 1, index: i }) }) })); });
88
115
  return [reshaped];
89
116
  };
90
- var dataToSummarize = !isBreakdown
117
+ var dataToSummarize = (!isBreakdown && summarizeAfterIdx)
91
118
  ? convertDataToSummrizeIntoBreakdownFormat(finalData.filter(function (_, i) { return i > summarizeAfterIdx; }))
92
119
  : undefined;
93
120
  var calcDataMaxValue = function (mainData, dataToSummarize, isBreakdown) {
94
121
  //now if there is no data to summarize its simple. take the first element and get its count (for !isBreakdown) or accumulate to count for first element (isBreakdown)
95
122
  // with dataToSummarize, its interesting, because a summarized bar is a 'summation' of everything it is summarizing. sooo.. the summation (and not the individual values) should be taken into consideration while figuring out maxValue
123
+ var getHighestNumInArray = function (ary) {
124
+ var highest = 0;
125
+ ary.forEach(function (item) { if (item.labels.count > highest)
126
+ highest = item.labels.count; });
127
+ return highest;
128
+ };
129
+ var getHighestNumInArrayOfArrays = function (ary) {
130
+ var highest = 0;
131
+ ary.forEach(function (subAry) {
132
+ var subHighest = getHighestNumInArray(subAry);
133
+ if (subHighest > highest)
134
+ highest = subHighest;
135
+ });
136
+ return highest;
137
+ };
96
138
  if (!dataToSummarize) {
97
139
  return !isBreakdown
98
- ? mainData[0].labels.count
99
- : mainData[0].reduce(function (acc, b) { return acc + b.labels.count; }, 0);
140
+ ? getHighestNumInArray(mainData) //if not breakdown, simply get the highest count in this single level array structre : [ { labels: { count: <>, ... }}, ... ]
141
+ : getHighestNumInArrayOfArrays(mainData); // if breakdown, get the highest count across all the nested arrays in this structure : [ [ { labels: { count: <>, ... }}, ... ], ... ]
100
142
  }
101
143
  else {
102
144
  var totalCountOfSummarizedData = dataToSummarize[0].reduce(function (acc, b) { return acc + b.labels.count; }, 0);
103
145
  var maxCountFromMainData = !isBreakdown
104
- ? mainData[0].labels.count
105
- : mainData[0].reduce(function (acc, b) { return acc + b.labels.count; }, 0);
146
+ ? getHighestNumInArray(mainData)
147
+ : getHighestNumInArrayOfArrays(mainData);
106
148
  return maxCountFromMainData > totalCountOfSummarizedData
107
149
  ? maxCountFromMainData
108
150
  : totalCountOfSummarizedData;
@@ -105,5 +105,5 @@ exports.colors = {
105
105
  greenBG: greenBG,
106
106
  greenStroke: greenStroke,
107
107
  redBG: redBG,
108
- red: red
108
+ red: red,
109
109
  };