@fluentui/react-charting 5.24.15 → 5.24.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.json +49 -1
- package/CHANGELOG.md +23 -2
- package/dist/react-charting.d.ts +1 -1
- package/dist/react-charting.js +1 -1
- package/dist/react-charting.min.js +1 -1
- package/etc/react-charting.api.md +1 -1
- package/lib/components/ChartTable/ChartTable.base.js +83 -4
- package/lib/components/ChartTable/ChartTable.base.js.map +1 -1
- package/lib/components/DeclarativeChart/PlotlySchemaAdapter.js +72 -25
- package/lib/components/DeclarativeChart/PlotlySchemaAdapter.js.map +1 -1
- package/lib/components/FunnelChart/FunnelChart.base.js +44 -15
- package/lib/components/FunnelChart/FunnelChart.base.js.map +1 -1
- package/lib/components/FunnelChart/funnelGeometry.d.ts +8 -8
- package/lib/components/FunnelChart/funnelGeometry.js +4 -4
- package/lib/components/FunnelChart/funnelGeometry.js.map +1 -1
- package/lib/components/ScatterChart/ScatterChart.base.js +15 -9
- package/lib/components/ScatterChart/ScatterChart.base.js.map +1 -1
- package/lib/types/IDataPoint.d.ts +1 -1
- package/lib/types/IDataPoint.js.map +1 -1
- package/lib/utilities/utilities.d.ts +6 -0
- package/lib/utilities/utilities.js +10 -0
- package/lib/utilities/utilities.js.map +1 -1
- package/lib-amd/components/ChartTable/ChartTable.base.js +81 -4
- package/lib-amd/components/ChartTable/ChartTable.base.js.map +1 -1
- package/lib-amd/components/DeclarativeChart/PlotlySchemaAdapter.js +72 -25
- package/lib-amd/components/DeclarativeChart/PlotlySchemaAdapter.js.map +1 -1
- package/lib-amd/components/FunnelChart/FunnelChart.base.js +44 -15
- package/lib-amd/components/FunnelChart/FunnelChart.base.js.map +1 -1
- package/lib-amd/components/FunnelChart/funnelGeometry.d.ts +8 -8
- package/lib-amd/components/FunnelChart/funnelGeometry.js +9 -9
- package/lib-amd/components/FunnelChart/funnelGeometry.js.map +1 -1
- package/lib-amd/components/ScatterChart/ScatterChart.base.js +14 -8
- package/lib-amd/components/ScatterChart/ScatterChart.base.js.map +1 -1
- package/lib-amd/types/IDataPoint.d.ts +1 -1
- package/lib-amd/types/IDataPoint.js.map +1 -1
- package/lib-amd/utilities/utilities.d.ts +6 -0
- package/lib-amd/utilities/utilities.js +12 -1
- package/lib-amd/utilities/utilities.js.map +1 -1
- package/lib-commonjs/components/ChartTable/ChartTable.base.js +82 -3
- package/lib-commonjs/components/ChartTable/ChartTable.base.js.map +1 -1
- package/lib-commonjs/components/DeclarativeChart/PlotlySchemaAdapter.js +72 -25
- package/lib-commonjs/components/DeclarativeChart/PlotlySchemaAdapter.js.map +1 -1
- package/lib-commonjs/components/FunnelChart/FunnelChart.base.js +44 -15
- package/lib-commonjs/components/FunnelChart/FunnelChart.base.js.map +1 -1
- package/lib-commonjs/components/FunnelChart/funnelGeometry.d.ts +8 -8
- package/lib-commonjs/components/FunnelChart/funnelGeometry.js +9 -9
- package/lib-commonjs/components/FunnelChart/funnelGeometry.js.map +1 -1
- package/lib-commonjs/components/ScatterChart/ScatterChart.base.js +14 -8
- package/lib-commonjs/components/ScatterChart/ScatterChart.base.js.map +1 -1
- package/lib-commonjs/types/IDataPoint.d.ts +1 -1
- package/lib-commonjs/types/IDataPoint.js.map +1 -1
- package/lib-commonjs/utilities/utilities.d.ts +6 -0
- package/lib-commonjs/utilities/utilities.js +12 -1
- package/lib-commonjs/utilities/utilities.js.map +1 -1
- package/package.json +2 -2
|
@@ -43,6 +43,12 @@ export var FunnelChartBase = React.forwardRef(function (props, forwardedRef) {
|
|
|
43
43
|
setIsCalloutVisible(true);
|
|
44
44
|
setRefSelected(mouseEvent.currentTarget);
|
|
45
45
|
}
|
|
46
|
+
function _handleFocus(data, focusEvent) {
|
|
47
|
+
focusEvent === null || focusEvent === void 0 ? void 0 : focusEvent.persist();
|
|
48
|
+
setCalloutData(data);
|
|
49
|
+
setIsCalloutVisible(true);
|
|
50
|
+
setRefSelected(focusEvent.currentTarget);
|
|
51
|
+
}
|
|
46
52
|
function _handleStackedHover(stage, subValue, mouseEvent) {
|
|
47
53
|
mouseEvent === null || mouseEvent === void 0 ? void 0 : mouseEvent.persist();
|
|
48
54
|
setHoveredStage(subValue.category);
|
|
@@ -55,6 +61,17 @@ export var FunnelChartBase = React.forwardRef(function (props, forwardedRef) {
|
|
|
55
61
|
setIsCalloutVisible(true);
|
|
56
62
|
setRefSelected(mouseEvent.currentTarget);
|
|
57
63
|
}
|
|
64
|
+
function _handleStackedFocus(stage, subValue, focusEvent) {
|
|
65
|
+
focusEvent === null || focusEvent === void 0 ? void 0 : focusEvent.persist();
|
|
66
|
+
setCalloutData({
|
|
67
|
+
stage: stage,
|
|
68
|
+
value: subValue.value,
|
|
69
|
+
color: subValue.color,
|
|
70
|
+
category: subValue.category,
|
|
71
|
+
});
|
|
72
|
+
setIsCalloutVisible(true);
|
|
73
|
+
setRefSelected(focusEvent.currentTarget);
|
|
74
|
+
}
|
|
58
75
|
function _handleMouseOut() {
|
|
59
76
|
setHoveredStage(null);
|
|
60
77
|
setIsCalloutVisible(false);
|
|
@@ -83,20 +100,28 @@ export var FunnelChartBase = React.forwardRef(function (props, forwardedRef) {
|
|
|
83
100
|
function noLegendHighlighted() {
|
|
84
101
|
return getHighlightedLegend().length === 0;
|
|
85
102
|
}
|
|
86
|
-
function _getEventHandlerProps(data) {
|
|
103
|
+
function _getEventHandlerProps(data, opacity) {
|
|
87
104
|
if ('subValue' in data) {
|
|
88
105
|
return {
|
|
89
106
|
culture: props.culture,
|
|
90
|
-
onMouseOver:
|
|
91
|
-
|
|
107
|
+
onMouseOver: opacity === 1
|
|
108
|
+
? function (event) { return _handleStackedHover(data.stage, data.subValue, event); }
|
|
109
|
+
: undefined,
|
|
110
|
+
onMouseMove: opacity === 1
|
|
111
|
+
? function (event) { return _handleStackedHover(data.stage, data.subValue, event); }
|
|
112
|
+
: undefined,
|
|
113
|
+
onFocus: function (event) { return _handleStackedFocus(data.stage, data.subValue, event); },
|
|
114
|
+
onBlur: function () { return _handleMouseOut(); },
|
|
92
115
|
onMouseOut: function () { return _handleMouseOut(); },
|
|
93
116
|
};
|
|
94
117
|
}
|
|
95
118
|
else {
|
|
96
119
|
return {
|
|
97
120
|
culture: props.culture,
|
|
98
|
-
onMouseOver: function (event) { return _handleHover(data, event); },
|
|
99
|
-
onMouseMove: function (event) { return _handleHover(data, event); },
|
|
121
|
+
onMouseOver: opacity === 1 ? function (event) { return _handleHover(data, event); } : undefined,
|
|
122
|
+
onMouseMove: opacity === 1 ? function (event) { return _handleHover(data, event); } : undefined,
|
|
123
|
+
onFocus: function (event) { return _handleFocus(data, event); },
|
|
124
|
+
onBlur: function () { return _handleMouseOut(); },
|
|
100
125
|
onMouseOut: function () { return _handleMouseOut(); },
|
|
101
126
|
};
|
|
102
127
|
}
|
|
@@ -113,11 +138,11 @@ export var FunnelChartBase = React.forwardRef(function (props, forwardedRef) {
|
|
|
113
138
|
return textElement;
|
|
114
139
|
}
|
|
115
140
|
function _renderFunnelSegment(_a) {
|
|
116
|
-
var key = _a.key, pathD = _a.pathD, fill = _a.fill, opacity = _a.opacity, textProps = _a.textProps, data = _a.data;
|
|
117
|
-
var eventHandlers = _getEventHandlerProps(data);
|
|
141
|
+
var key = _a.key, pathD = _a.pathD, fill = _a.fill, opacity = _a.opacity, textProps = _a.textProps, data = _a.data, isFocusable = _a.isFocusable;
|
|
142
|
+
var eventHandlers = _getEventHandlerProps(data, opacity);
|
|
118
143
|
var textColor = getContrastTextColor(fill, props.theme);
|
|
119
144
|
return (React.createElement("g", { key: key },
|
|
120
|
-
React.createElement("path", __assign({ d: pathD, fill: fill, opacity: opacity }, eventHandlers)),
|
|
145
|
+
React.createElement("path", __assign({ d: pathD, fill: fill, opacity: opacity }, eventHandlers, { "data-is-focusable": isFocusable })),
|
|
121
146
|
textProps && React.createElement("g", __assign({}, eventHandlers), _renderSegmentText(__assign(__assign({}, textProps), { textColor: textColor })))));
|
|
122
147
|
}
|
|
123
148
|
function _createFunnel(containerHeight, containerWidth) {
|
|
@@ -125,9 +150,9 @@ export var FunnelChartBase = React.forwardRef(function (props, forwardedRef) {
|
|
|
125
150
|
var funnelWidth = containerWidth;
|
|
126
151
|
var funnelHeight = containerHeight * 0.8;
|
|
127
152
|
return data.map(function (d, i) {
|
|
128
|
-
var geometryProps = props.orientation === '
|
|
129
|
-
?
|
|
130
|
-
:
|
|
153
|
+
var geometryProps = props.orientation === 'vertical'
|
|
154
|
+
? getVerticalFunnelSegmentGeometry({ d: d, i: i, data: data, funnelWidth: funnelWidth, funnelHeight: funnelHeight, isRTL: isRTL })
|
|
155
|
+
: getHorizontalFunnelSegmentGeometry({ d: d, i: i, data: data, funnelWidth: funnelWidth, funnelHeight: funnelHeight, isRTL: isRTL });
|
|
131
156
|
var pathD = geometryProps.pathD, textX = geometryProps.textX, textY = geometryProps.textY, availableWidth = geometryProps.availableWidth;
|
|
132
157
|
var minTextWidth = 16;
|
|
133
158
|
var eventHandlerProps = _getEventHandlerProps(d);
|
|
@@ -139,6 +164,7 @@ export var FunnelChartBase = React.forwardRef(function (props, forwardedRef) {
|
|
|
139
164
|
opacity: legendHighlighted(d.stage) || noLegendHighlighted() ? 1 : 0.1,
|
|
140
165
|
textProps: textProps,
|
|
141
166
|
data: d,
|
|
167
|
+
isFocusable: legendHighlighted(d.stage) || noLegendHighlighted() ? true : false,
|
|
142
168
|
});
|
|
143
169
|
});
|
|
144
170
|
}
|
|
@@ -148,9 +174,9 @@ export var FunnelChartBase = React.forwardRef(function (props, forwardedRef) {
|
|
|
148
174
|
function _renderStackedSegment(stage, subValue, stageIndex, subValueIndex, geometryParams) {
|
|
149
175
|
// Ensure stages have subValues for geometry functions
|
|
150
176
|
var stagesWithSubValues = geometryParams.stages.map(function (s) { return (__assign(__assign({}, s), { subValues: s.subValues || [] })); });
|
|
151
|
-
var geom = props.orientation === '
|
|
152
|
-
?
|
|
153
|
-
:
|
|
177
|
+
var geom = props.orientation === 'vertical'
|
|
178
|
+
? getStackedVerticalFunnelSegmentGeometry(__assign(__assign({}, geometryParams), { stages: stagesWithSubValues, i: stageIndex, k: subValueIndex }))
|
|
179
|
+
: getStackedHorizontalFunnelSegmentGeometry(__assign(__assign({}, geometryParams), { stages: stagesWithSubValues, i: stageIndex, k: subValueIndex }));
|
|
154
180
|
var minTextWidth = 16;
|
|
155
181
|
var eventHandlerProps = _getEventHandlerProps({ stage: stage.stage, subValue: subValue });
|
|
156
182
|
var textProps = getSegmentTextProps(__assign({ availableWidth: geom.availableWidth, minTextWidth: minTextWidth, textX: geom.textX, textY: geom.textY, value: subValue.value }, eventHandlerProps));
|
|
@@ -161,6 +187,9 @@ export var FunnelChartBase = React.forwardRef(function (props, forwardedRef) {
|
|
|
161
187
|
opacity: (isStackedFunnelData(props.data) && legendHighlighted(subValue.category)) || noLegendHighlighted() ? 1 : 0.1,
|
|
162
188
|
textProps: textProps,
|
|
163
189
|
data: { stage: stage.stage, subValue: subValue },
|
|
190
|
+
isFocusable: (isStackedFunnelData(props.data) && legendHighlighted(subValue.category)) || noLegendHighlighted()
|
|
191
|
+
? true
|
|
192
|
+
: false,
|
|
164
193
|
});
|
|
165
194
|
}
|
|
166
195
|
function _createStackedFunnel(containerHeight, containerWidth) {
|
|
@@ -261,6 +290,6 @@ export var FunnelChartBase = React.forwardRef(function (props, forwardedRef) {
|
|
|
261
290
|
FunnelChartBase.displayName = 'FunnelChart';
|
|
262
291
|
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
263
292
|
FunnelChartBase.defaultProps = {
|
|
264
|
-
orientation: '
|
|
293
|
+
orientation: 'vertical',
|
|
265
294
|
};
|
|
266
295
|
//# sourceMappingURL=FunnelChart.base.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FunnelChart.base.js","sourceRoot":"../src/","sources":["components/FunnelChart/FunnelChart.base.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAOlF,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AACtE,OAAO,EAA6B,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,+CAA+C,CAAC;AAC/E,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAEjE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAC/E,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EACL,kCAAkC,EAClC,gCAAgC,EAChC,mBAAmB,EACnB,yCAAyC,EACzC,uCAAuC,GACxC,MAAM,kBAAkB,CAAC;AAE1B,IAAM,aAAa,GAAG,kBAAkB,EAA8C,CAAC;AAEvF,MAAM,CAAC,IAAM,eAAe,GAA+C,KAAK,CAAC,UAAU,CAGzF,UAAC,KAAK,EAAE,YAAY;;IACpB,IAAM,UAAU,GAAW,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC1D,IAAM,aAAa,GAAW,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAC1D,IAAM,KAAK,GAAG,MAAM,EAAE,CAAC;IAEjB,IAAA,KAAkC,KAAK,CAAC,QAAQ,CAAgB,IAAI,CAAC,EAApE,YAAY,QAAA,EAAE,eAAe,QAAuC,CAAC;IACtE,IAAA,KAA0C,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,EAA9D,gBAAgB,QAAA,EAAE,mBAAmB,QAAyB,CAAC;IAChE,IAAA,KAAgC,KAAK,CAAC,QAAQ,CAA+B,IAAI,CAAC,EAAjF,WAAW,QAAA,EAAE,cAAc,QAAsD,CAAC;IACnF,IAAA,KAAgC,KAAK,CAAC,QAAQ,CAAoB,IAAI,CAAC,EAAtE,WAAW,QAAA,EAAE,cAAc,QAA2C,CAAC;IACxE,IAAA,KAAwC,KAAK,CAAC,QAAQ,CAAW,EAAE,CAAC,EAAnE,eAAe,QAAA,EAAE,kBAAkB,QAAgC,CAAC;IAC3E,IAAM,iBAAiB,GAAG,KAAK,CAAC,MAAM,CAAwB,IAAI,CAAC,CAAC;IACpE,IAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAA0B,IAAI,CAAC,CAAC;IAC/D,IAAM,SAAS,GAAG,mBAAmB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAElD,KAAK,CAAC,SAAS,CAAC;;QACd,IAAI,MAAA,KAAK,CAAC,WAAW,0CAAE,eAAe,EAAE,CAAC;YACvC,kBAAkB,CAAC,KAAK,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC;QACxD,CAAC;IACH,CAAC,EAAE,CAAC,MAAA,KAAK,CAAC,WAAW,0CAAE,eAAe,CAAC,CAAC,CAAC;IAEzC,KAAK,CAAC,mBAAmB,CACvB,KAAK,CAAC,YAAY,EAClB,cAAM,OAAA,CAAC;QACL,cAAc,EAAE,iBAAiB,aAAjB,iBAAiB,cAAjB,iBAAiB,GAAI,IAAI;QACzC,OAAO,EAAE,UAAC,IAA0B;;YAClC,OAAO,cAAc,CAAC,iBAAiB,CAAC,OAAO,EAAE,MAAA,UAAU,CAAC,OAAO,0CAAE,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,CAAC;QAC9F,CAAC;KACF,CAAC,EALI,CAKJ,EACF,EAAE,CACH,CAAC;IAEF,SAAS,YAAY,CAAC,IAA2B,EAAE,UAAwC;QACzF,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,OAAO,EAAE,CAAC;QACtB,eAAe,CAAC,IAAI,CAAC,KAAe,CAAC,CAAC;QACtC,cAAc,CAAC,IAAI,CAAC,CAAC;QACrB,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAC1B,cAAc,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IAC3C,CAAC;IAED,SAAS,mBAAmB,CAC1B,KAAa,EACb,QAA4D,EAC5D,UAAwC;QAExC,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,OAAO,EAAE,CAAC;QACtB,eAAe,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACnC,cAAc,CAAC;YACb,KAAK,OAAA;YACL,KAAK,EAAE,QAAQ,CAAC,KAAK;YACrB,KAAK,EAAE,QAAQ,CAAC,KAAK;YACrB,QAAQ,EAAE,QAAQ,CAAC,QAAQ;SACH,CAAC,CAAC;QAC5B,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAC1B,cAAc,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IAC3C,CAAC;IAED,SAAS,eAAe;QACtB,eAAe,CAAC,IAAI,CAAC,CAAC;QACtB,mBAAmB,CAAC,KAAK,CAAC,CAAC;QAC3B,cAAc,CAAC,IAAI,CAAC,CAAC;QACrB,cAAc,CAAC,IAAI,CAAC,CAAC;IACvB,CAAC;IAED,SAAS,wBAAwB,CAC/B,eAAyB,EACzB,KAA0C,EAC1C,aAAuB;;QAEvB,IAAI,MAAA,KAAK,CAAC,WAAW,0CAAE,wBAAwB,EAAE,CAAC;YAChD,kBAAkB,CAAC,eAAe,CAAC,CAAC;QACtC,CAAC;aAAM,CAAC;YACN,kBAAkB,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAChD,CAAC;QAED,IAAI,MAAA,KAAK,CAAC,WAAW,0CAAE,QAAQ,EAAE,CAAC;YAChC,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,eAAe,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED,IAAM,gCAAgC,GAAG,KAAK,CAAC,WAAW,CAAC,wBAAwB,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;IAE1G,SAAS,oBAAoB;QAC3B,OAAO,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3F,CAAC;IAED,SAAS,iBAAiB,CAAC,MAAc;QACvC,OAAO,oBAAoB,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACjD,CAAC;IAED,SAAS,mBAAmB;QAC1B,OAAO,oBAAoB,EAAE,CAAC,MAAM,KAAK,CAAC,CAAC;IAC7C,CAAC;IAED,SAAS,qBAAqB,CAC5B,IAA6G;QAE7G,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;YACvB,OAAO;gBACL,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,WAAW,EAAE,UAAC,KAAmC,IAAK,OAAA,mBAAmB,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,EAArD,CAAqD;gBAC3G,WAAW,EAAE,UAAC,KAAmC,IAAK,OAAA,mBAAmB,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,EAArD,CAAqD;gBAC3G,UAAU,EAAE,cAAM,OAAA,eAAe,EAAE,EAAjB,CAAiB;aACpC,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,OAAO;gBACL,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,WAAW,EAAE,UAAC,KAAmC,IAAK,OAAA,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,EAAzB,CAAyB;gBAC/E,WAAW,EAAE,UAAC,KAAmC,IAAK,OAAA,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,EAAzB,CAAyB;gBAC/E,UAAU,EAAE,cAAM,OAAA,eAAe,EAAE,EAAjB,CAAiB;aACpC,CAAC;QACJ,CAAC;IACH,CAAC;IAED,SAAS,kBAAkB,CAAC,EAY3B;YAXC,IAAI,UAAA,EACJ,CAAC,OAAA,EACD,CAAC,OAAA,EACD,KAAK,WAAA,EACL,SAAS,eAAA;QAQT,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAM,WAAW,GAAG,CAClB,8BAAM,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,UAAU,EAAC,QAAQ,EAAC,iBAAiB,EAAC,QAAQ,EAAC,IAAI,EAAE,SAAS,IACvG,oBAAoB,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,KAAK,CAAC,OAAO,CAAoB,CACpE,CACR,CAAC;QAEF,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,2BAAG,SAAS,EAAE,gCAAyB,CAAC,WAAW,QAAK,IAAG,WAAW,CAAK,CAAC;QACrF,CAAC;QACD,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,SAAS,oBAAoB,CAAC,EAmB7B;YAlBC,GAAG,SAAA,EACH,KAAK,WAAA,EACL,IAAI,UAAA,EACJ,OAAO,aAAA,EACP,SAAS,eAAA,EACT,IAAI,UAAA;QAcJ,IAAM,aAAa,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;QAClD,IAAM,SAAS,GAAG,oBAAoB,CAAC,IAAI,EAAE,KAAK,CAAC,KAAM,CAAC,CAAC;QAE3D,OAAO,CACL,2BAAG,GAAG,EAAE,GAAG;YACT,uCAAM,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,IAAM,aAAa,EAAI;YAClE,SAAS,IAAI,sCAAO,aAAa,GAAG,kBAAkB,uBAAM,SAAS,KAAE,SAAS,WAAA,IAAG,CAAK,CACvF,CACL,CAAC;IACJ,CAAC;IAED,SAAS,aAAa,CACpB,eAAuB,EACvB,cAAsB;QAGd,IAAA,IAAI,GAAK,KAAK,KAAV,CAAW;QACvB,IAAM,WAAW,GAAG,cAAc,CAAC;QACnC,IAAM,YAAY,GAAG,eAAe,GAAG,GAAG,CAAC;QAE3C,OAAO,IAAI,CAAC,GAAG,CAAC,UAAC,CAAC,EAAE,CAAC;YACnB,IAAM,aAAa,GACjB,KAAK,CAAC,WAAW,KAAK,YAAY;gBAChC,CAAC,CAAC,kCAAkC,CAAC,EAAE,CAAC,GAAA,EAAE,CAAC,GAAA,EAAE,IAAI,MAAA,EAAE,WAAW,aAAA,EAAE,YAAY,cAAA,EAAE,KAAK,OAAA,EAAE,CAAC;gBACtF,CAAC,CAAC,gCAAgC,CAAC,EAAE,CAAC,GAAA,EAAE,CAAC,GAAA,EAAE,IAAI,MAAA,EAAE,WAAW,aAAA,EAAE,YAAY,cAAA,EAAE,KAAK,OAAA,EAAE,CAAC,CAAC;YAEjF,IAAA,KAAK,GAAmC,aAAa,MAAhD,EAAE,KAAK,GAA4B,aAAa,MAAzC,EAAE,KAAK,GAAqB,aAAa,MAAlC,EAAE,cAAc,GAAK,aAAa,eAAlB,CAAmB;YAC9D,IAAM,YAAY,GAAG,EAAE,CAAC;YACxB,IAAM,iBAAiB,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAAC;YACnD,IAAM,SAAS,GAAG,mBAAmB,YACnC,cAAc,gBAAA,EACd,YAAY,cAAA,EACZ,KAAK,OAAA,EACL,KAAK,OAAA,EACL,KAAK,EAAE,CAAC,CAAC,KAAM,IACZ,iBAAiB,EACpB,CAAC;YAEH,OAAO,oBAAoB,CAAC;gBAC1B,GAAG,EAAE,CAAC;gBACN,KAAK,OAAA;gBACL,IAAI,EAAE,CAAC,CAAC,KAAM;gBACd,OAAO,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAe,CAAC,IAAI,mBAAmB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG;gBAChF,SAAS,WAAA;gBACT,IAAI,EAAE,CAAC;aACR,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,SAAS,mBAAmB,CAAC,IAA6B;QACxD,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,UAAA,KAAK,IAAI,OAAA,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,EAA9B,CAA8B,CAAC,CAAC;IACpF,CAAC;IAED,SAAS,qBAAqB,CAC5B,KAA4B,EAC5B,QAA4D,EAC5D,UAAkB,EAClB,aAAqB,EACrB,cAOC;QAGD,sDAAsD;QACtD,IAAM,mBAAmB,GAAG,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,UAAA,CAAC,IAAI,OAAA,uBACtD,CAAC,KACJ,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,EAAE,IAC5B,EAHyD,CAGzD,CAAC,CAAC;QAEJ,IAAM,IAAI,GACR,KAAK,CAAC,WAAW,KAAK,YAAY;YAChC,CAAC,CAAC,yCAAyC,uBACpC,cAAc,KACjB,MAAM,EAAE,mBAAmB,EAC3B,CAAC,EAAE,UAAU,EACb,CAAC,EAAE,aAAa,IAChB;YACJ,CAAC,CAAC,uCAAuC,uBAClC,cAAc,KACjB,MAAM,EAAE,mBAAmB,EAC3B,CAAC,EAAE,UAAU,EACb,CAAC,EAAE,aAAa,IAChB,CAAC;QAET,IAAM,YAAY,GAAG,EAAE,CAAC;QACxB,IAAM,iBAAiB,GAAG,qBAAqB,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAe,EAAE,QAAQ,UAAA,EAAE,CAAC,CAAC;QAC5F,IAAM,SAAS,GAAG,mBAAmB,YACnC,cAAc,EAAE,IAAI,CAAC,cAAc,EACnC,YAAY,cAAA,EACZ,KAAK,EAAE,IAAI,CAAC,KAAK,EACjB,KAAK,EAAE,IAAI,CAAC,KAAK,EACjB,KAAK,EAAE,QAAQ,CAAC,KAAK,IAClB,iBAAiB,EACpB,CAAC;QAEH,OAAO,oBAAoB,CAAC;YAC1B,GAAG,EAAE,UAAG,UAAU,cAAI,aAAa,CAAE;YACrC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI,EAAE,QAAQ,CAAC,KAAK;YACpB,OAAO,EACL,CAAC,mBAAmB,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,iBAAiB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,IAAI,mBAAmB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG;YAC9G,SAAS,WAAA;YACT,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAe,EAAE,QAAQ,UAAA,EAAE;SACjD,CAAC,CAAC;IACL,CAAC;IAED,SAAS,oBAAoB,CAC3B,eAAuB,EACvB,cAAsB;;QAGd,IAAA,IAAI,GAAK,KAAK,KAAV,CAAW;QAEvB,IAAM,MAAM,GAAG,IAAI,CAAC;QACpB,IAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,UAAA,CAAC,gBAAI,OAAA,MAAA,MAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,SAAS,0CAAE,MAAM,CAAC,UAAC,GAAG,EAAE,QAAQ,IAAK,OAAA,GAAG,GAAG,QAAQ,CAAC,KAAK,EAApB,CAAoB,EAAE,CAAC,CAAC,mCAAI,CAAC,CAAA,EAAA,CAAC,CAAC;QACtG,IAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,OAAR,IAAI,EAAQ,MAAM,CAAC,CAAC;QAErC,IAAM,WAAW,GAAG,cAAc,CAAC;QACnC,IAAM,YAAY,GAAG,eAAe,GAAG,GAAG,CAAC;QAE3C,4DAA4D;QAC5D,IAAM,KAAK,GAAkB,EAAE,CAAC;QAEhC,IAAM,cAAc,GAAG;YACrB,MAAM,QAAA;YACN,MAAM,QAAA;YACN,QAAQ,UAAA;YACR,WAAW,aAAA;YACX,YAAY,cAAA;YACZ,KAAK,OAAA;SACN,CAAC;QAEF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,IAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;YACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,MAAA,GAAG,CAAC,SAAS,mCAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACtD,IAAM,CAAC,GAAG,MAAA,GAAG,CAAC,SAAS,0CAAG,CAAC,CAAC,CAAC;gBAC7B,IAAI,CAAC,CAAC,EAAE,CAAC;oBACP,SAAS;gBACX,CAAC;gBACD,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC;YAClE,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,SAAS,cAAc;QAErB,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;YACrB,OAAO,yCAAK,CAAC;QACf,CAAC;QACD,IAAI,OAAkB,CAAC;QAEvB,IAAI,SAAS,EAAE,CAAC;YACd,4CAA4C;YAC5C,IAAM,aAAW,GAA2B,EAAE,CAAC;YAC/C,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,UAAC,KAA4B;gBAC9C,CAAC,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,UAAA,GAAG;oBACjC,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ,IAAI,aAAW,CAAC,EAAE,CAAC;wBACnC,aAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC;oBACxC,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YACH,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,aAAW,CAAC,CAAC,GAAG,CAAC,UAAC,EAAiB;oBAAhB,QAAQ,QAAA,EAAE,KAAK,QAAA;gBAAM,OAAA,CAAC;oBAChE,KAAK,EAAE,QAAQ;oBACf,KAAK,OAAA;oBACL,WAAW,EAAE,cAAM,OAAA,eAAe,CAAC,QAAQ,CAAC,EAAzB,CAAyB;oBAC5C,gBAAgB,EAAE,cAAM,OAAA,eAAe,CAAC,IAAI,CAAC,EAArB,CAAqB;iBAC9C,CAAC;YAL+D,CAK/D,CAAC,CAAC;QACN,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,UAAC,CAAwB,IAAK,OAAA,CAAC;gBACtD,KAAK,EAAE,CAAC,CAAC,KAAe;gBACxB,KAAK,EAAE,CAAC,CAAC,KAAM;gBACf,WAAW,EAAE,cAAM,OAAA,eAAe,CAAC,CAAC,CAAC,KAAe,CAAC,EAAlC,CAAkC;gBACrD,gBAAgB,EAAE,cAAM,OAAA,eAAe,CAAC,IAAI,CAAC,EAArB,CAAqB;aAC9C,CAAC,EALqD,CAKrD,CAAC,CAAC;QACN,CAAC;QAED,OAAO,CACL,6BAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE;YACvD,oBAAC,OAAO,aACN,GAAG,EAAE,UAAU,EACf,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,IAAI,EACnB,QAAQ,EAAE,gCAAgC,IACtC,KAAK,CAAC,WAAW,EACrB,CACE,CACP,CAAC;IACJ,CAAC;IAED,SAAS,aAAa;QACpB,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAChD,CAAC;IAED,IAAM,YAAY,cAChB,gBAAgB,kBAAA,EAChB,eAAe,EAAE,eAAe,CAAC,WAAW,EAC5C,EAAE,EAAE,iBAAU,UAAU,CAAE,EAC1B,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,KAAK,EACzB,MAAM,EAAE,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,KAAK,EAC1B,MAAM,EAAE,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,KAAK,EAC1B,aAAa,EAAE,KAAK,EACpB,QAAQ,EAAE,EAAE,EACZ,SAAS,EAAE;YACT,mBAAmB,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC,EACD,yBAAyB,EAAE,IAAI,IAC5B,KAAK,CAAC,YAAY,CACtB,CAAC;IAEF,IAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,GAAG,CAAC;IACjC,IAAM,MAAM,GAAG,KAAK,CAAC,MAAM,IAAI,GAAG,CAAC;IACnC,IAAM,UAAU,GAAG,aAAa,CAAC,KAAK,CAAC,MAAO,EAAE;QAC9C,KAAK,EAAE,KAAK,CAAC,KAAM;QACnB,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,UAAU,EAAE,KAAK;QACjB,WAAW,EAAE,MAAM;KACpB,CAAC,CAAC;IAEH,IAAM,eAAe,GAAG,EAAE,CAAC;IAC3B,IAAM,WAAW,GAAG,KAAK,GAAG,GAAG,CAAC;IAChC,IAAM,aAAa,GAAG,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAEhD,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CACxB,6BAAK,GAAG,EAAE,iBAAiB,EAAE,SAAS,EAAE,UAAU,CAAC,IAAI;QACrD,oBAAC,SAAS,IAAC,SAAS,EAAE,kBAAkB,CAAC,UAAU;YACjD,6BAAK,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,gBAAc,KAAK,CAAC,UAAU;gBACvG,2BACE,SAAS,EACP,KAAK;wBACH,CAAC,CAAC,oBAAa,aAAa,GAAG,WAAW,eAAK,eAAe,kBAAe;wBAC7E,CAAC,CAAC,oBAAa,aAAa,eAAK,eAAe,MAAG,IAGtD,SAAS;oBACR,CAAC,CAAC,oBAAoB,CAAC,MAAM,GAAG,eAAe,EAAE,WAAW,CAAC;oBAC7D,CAAC,CAAC,aAAa,CAAC,MAAM,GAAG,eAAe,EAAE,WAAW,CAAC,CACtD;gBACH,gBAAgB,IAAI,CACnB,oBAAC,OAAO,eAAK,YAAY;oBACvB,oBAAC,cAAc,IACb,MAAM,EAAE,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,MAAgB,EACtC,MAAM,EAAE,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,MAAM,EAC5B,KAAK,EAAE,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAE,KAAK,GAC1B,CACM,CACX,CACG,CACI;QACX,cAAc,EAAE,CACb,CACP,CAAC,CAAC,CAAC,CACF,6BAAK,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,gBAAc,8BAA8B,GAAI,CAC/G,CAAC;AACJ,CAAC,CAAC,CAAC;AACH,eAAe,CAAC,WAAW,GAAG,aAAa,CAAC;AAC5C,4DAA4D;AAC5D,eAAe,CAAC,YAAY,GAAG;IAC7B,WAAW,EAAE,YAAY;CAC1B,CAAC","sourcesContent":["import * as React from 'react';\nimport { classNamesFunction, getId, getRTL } from '@fluentui/react/lib/Utilities';\nimport {\n IFunnelChartDataPoint,\n IFunnelChartProps,\n IFunnelChartStyleProps,\n IFunnelChartStyles,\n} from './FunnelChart.types';\nimport { FocusZone, FocusZoneDirection } from '@fluentui/react-focus';\nimport { ILegend, ILegendContainer, Legends } from '../Legends/index';\nimport { Callout, DirectionalHint } from '@fluentui/react/lib/Callout';\nimport { ChartHoverCard } from '../../utilities/ChartHoverCard/ChartHoverCard';\nimport { formatToLocaleString } from '@fluentui/chart-utilities';\nimport { IImageExportOptions } from '../../types/index';\nimport { toImage as convertToImage } from '../../utilities/image-export-utils';\nimport { getContrastTextColor } from '../../utilities/utilities';\nimport {\n getHorizontalFunnelSegmentGeometry,\n getVerticalFunnelSegmentGeometry,\n getSegmentTextProps,\n getStackedHorizontalFunnelSegmentGeometry,\n getStackedVerticalFunnelSegmentGeometry,\n} from './funnelGeometry';\n\nconst getClassNames = classNamesFunction<IFunnelChartStyleProps, IFunnelChartStyles>();\n\nexport const FunnelChartBase: React.FunctionComponent<IFunnelChartProps> = React.forwardRef<\n HTMLDivElement,\n IFunnelChartProps\n>((props, forwardedRef) => {\n const _tooltipId: string = getId('FunnelChartTooltipId_');\n const _emptyChartId: string = getId('_FunnelChart_empty');\n const isRTL = getRTL();\n\n const [hoveredStage, setHoveredStage] = React.useState<string | null>(null);\n const [isCalloutVisible, setIsCalloutVisible] = React.useState(false);\n const [calloutData, setCalloutData] = React.useState<IFunnelChartDataPoint | null>(null);\n const [refSelected, setRefSelected] = React.useState<SVGElement | null>(null);\n const [selectedLegends, setSelectedLegends] = React.useState<string[]>([]);\n const chartContainerRef = React.useRef<HTMLDivElement | null>(null);\n const legendsRef = React.useRef<ILegendContainer | null>(null);\n const isStacked = isStackedFunnelData(props.data);\n\n React.useEffect(() => {\n if (props.legendProps?.selectedLegends) {\n setSelectedLegends(props.legendProps.selectedLegends);\n }\n }, [props.legendProps?.selectedLegends]);\n\n React.useImperativeHandle(\n props.componentRef,\n () => ({\n chartContainer: chartContainerRef ?? null,\n toImage: (opts?: IImageExportOptions): Promise<string> => {\n return convertToImage(chartContainerRef.current, legendsRef.current?.toSVG, getRTL(), opts);\n },\n }),\n [],\n );\n\n function _handleHover(data: IFunnelChartDataPoint, mouseEvent: React.MouseEvent<SVGElement>) {\n mouseEvent?.persist();\n setHoveredStage(data.stage as string);\n setCalloutData(data);\n setIsCalloutVisible(true);\n setRefSelected(mouseEvent.currentTarget);\n }\n\n function _handleStackedHover(\n stage: string,\n subValue: { category: string; value: number; color: string },\n mouseEvent: React.MouseEvent<SVGElement>,\n ) {\n mouseEvent?.persist();\n setHoveredStage(subValue.category);\n setCalloutData({\n stage,\n value: subValue.value,\n color: subValue.color,\n category: subValue.category,\n } as IFunnelChartDataPoint);\n setIsCalloutVisible(true);\n setRefSelected(mouseEvent.currentTarget);\n }\n\n function _handleMouseOut() {\n setHoveredStage(null);\n setIsCalloutVisible(false);\n setCalloutData(null);\n setRefSelected(null);\n }\n\n function _onLegendSelectionChange(\n legendsSelected: string[],\n event: React.MouseEvent<HTMLButtonElement>,\n currentLegend?: ILegend,\n ): void {\n if (props.legendProps?.canSelectMultipleLegends) {\n setSelectedLegends(legendsSelected);\n } else {\n setSelectedLegends(legendsSelected.slice(-1));\n }\n\n if (props.legendProps?.onChange) {\n props.legendProps.onChange(legendsSelected, event, currentLegend);\n }\n }\n\n const _onLegendSelectionChangeCallback = React.useCallback(_onLegendSelectionChange, [props.legendProps]);\n\n function getHighlightedLegend(): string[] {\n return selectedLegends.length > 0 ? selectedLegends : hoveredStage ? [hoveredStage] : [];\n }\n\n function legendHighlighted(legend: string): boolean {\n return getHighlightedLegend().includes(legend);\n }\n\n function noLegendHighlighted(): boolean {\n return getHighlightedLegend().length === 0;\n }\n\n function _getEventHandlerProps(\n data: IFunnelChartDataPoint | { stage: string; subValue: { category: string; value: number; color: string } },\n ) {\n if ('subValue' in data) {\n return {\n culture: props.culture,\n onMouseOver: (event: React.MouseEvent<SVGElement>) => _handleStackedHover(data.stage, data.subValue, event),\n onMouseMove: (event: React.MouseEvent<SVGElement>) => _handleStackedHover(data.stage, data.subValue, event),\n onMouseOut: () => _handleMouseOut(),\n };\n } else {\n return {\n culture: props.culture,\n onMouseOver: (event: React.MouseEvent<SVGElement>) => _handleHover(data, event),\n onMouseMove: (event: React.MouseEvent<SVGElement>) => _handleHover(data, event),\n onMouseOut: () => _handleMouseOut(),\n };\n }\n }\n\n function _renderSegmentText({\n show,\n x,\n y,\n value,\n textColor,\n }: {\n show: boolean;\n x: number;\n y: number;\n value: number;\n textColor: string;\n }) {\n if (!show) {\n return null;\n }\n\n const textElement = (\n <text x={isRTL ? funnelWidth - x : x} y={y} textAnchor=\"middle\" alignmentBaseline=\"middle\" fill={textColor}>\n {formatToLocaleString(value.toString(), props.culture) as React.ReactNode}\n </text>\n );\n\n if (isRTL) {\n return <g transform={`scale(-1,1) translate(${-funnelWidth},0)`}>{textElement}</g>;\n }\n return textElement;\n }\n\n function _renderFunnelSegment({\n key,\n pathD,\n fill,\n opacity,\n textProps,\n data,\n }: {\n key: string | number;\n pathD: string;\n fill: string;\n opacity: number;\n textProps?: {\n show: boolean;\n x: number;\n y: number;\n value: number;\n };\n data: IFunnelChartDataPoint | { stage: string; subValue: { category: string; value: number; color: string } };\n }) {\n const eventHandlers = _getEventHandlerProps(data);\n const textColor = getContrastTextColor(fill, props.theme!);\n\n return (\n <g key={key}>\n <path d={pathD} fill={fill} opacity={opacity} {...eventHandlers} />\n {textProps && <g {...eventHandlers}>{_renderSegmentText({ ...textProps, textColor })}</g>}\n </g>\n );\n }\n\n function _createFunnel(\n containerHeight: number,\n containerWidth: number,\n ): // eslint-disable-next-line @typescript-eslint/no-deprecated\n JSX.Element[] {\n const { data } = props;\n const funnelWidth = containerWidth;\n const funnelHeight = containerHeight * 0.8;\n\n return data.map((d, i) => {\n const geometryProps =\n props.orientation === 'horizontal'\n ? getHorizontalFunnelSegmentGeometry({ d, i, data, funnelWidth, funnelHeight, isRTL })\n : getVerticalFunnelSegmentGeometry({ d, i, data, funnelWidth, funnelHeight, isRTL });\n\n const { pathD, textX, textY, availableWidth } = geometryProps;\n const minTextWidth = 16;\n const eventHandlerProps = _getEventHandlerProps(d);\n const textProps = getSegmentTextProps({\n availableWidth,\n minTextWidth,\n textX,\n textY,\n value: d.value!,\n ...eventHandlerProps,\n });\n\n return _renderFunnelSegment({\n key: i,\n pathD,\n fill: d.color!,\n opacity: legendHighlighted(d.stage as string) || noLegendHighlighted() ? 1 : 0.1,\n textProps,\n data: d,\n });\n });\n }\n\n function isStackedFunnelData(data: IFunnelChartDataPoint[]): boolean {\n return Array.isArray(data) && data.every(stage => Array.isArray(stage.subValues));\n }\n\n function _renderStackedSegment(\n stage: IFunnelChartDataPoint,\n subValue: { value: number; color: string; category: string },\n stageIndex: number,\n subValueIndex: number,\n geometryParams: {\n stages: IFunnelChartDataPoint[];\n totals: number[];\n maxTotal: number;\n funnelWidth: number;\n funnelHeight: number;\n isRTL: boolean;\n },\n ): // eslint-disable-next-line @typescript-eslint/no-deprecated\n JSX.Element {\n // Ensure stages have subValues for geometry functions\n const stagesWithSubValues = geometryParams.stages.map(s => ({\n ...s,\n subValues: s.subValues || [],\n }));\n\n const geom =\n props.orientation === 'horizontal'\n ? getStackedHorizontalFunnelSegmentGeometry({\n ...geometryParams,\n stages: stagesWithSubValues,\n i: stageIndex,\n k: subValueIndex,\n })\n : getStackedVerticalFunnelSegmentGeometry({\n ...geometryParams,\n stages: stagesWithSubValues,\n i: stageIndex,\n k: subValueIndex,\n });\n\n const minTextWidth = 16;\n const eventHandlerProps = _getEventHandlerProps({ stage: stage.stage as string, subValue });\n const textProps = getSegmentTextProps({\n availableWidth: geom.availableWidth,\n minTextWidth,\n textX: geom.textX,\n textY: geom.textY,\n value: subValue.value,\n ...eventHandlerProps,\n });\n\n return _renderFunnelSegment({\n key: `${stageIndex}-${subValueIndex}`,\n pathD: geom.pathD,\n fill: subValue.color,\n opacity:\n (isStackedFunnelData(props.data) && legendHighlighted(subValue.category)) || noLegendHighlighted() ? 1 : 0.1,\n textProps,\n data: { stage: stage.stage as string, subValue },\n });\n }\n\n function _createStackedFunnel(\n containerHeight: number,\n containerWidth: number,\n ): // eslint-disable-next-line @typescript-eslint/no-deprecated\n JSX.Element[] {\n const { data } = props;\n\n const stages = data;\n const totals = stages.map(s => s?.subValues?.reduce((sum, subValue) => sum + subValue.value, 0) ?? 0);\n const maxTotal = Math.max(...totals);\n\n const funnelWidth = containerWidth;\n const funnelHeight = containerHeight * 0.8;\n\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n const paths: JSX.Element[] = [];\n\n const geometryParams = {\n stages,\n totals,\n maxTotal,\n funnelWidth,\n funnelHeight,\n isRTL,\n };\n\n for (let i = 0; i < stages.length; i++) {\n const cur = stages[i];\n for (let k = 0; k < (cur.subValues ?? []).length; k++) {\n const v = cur.subValues?.[k];\n if (!v) {\n continue;\n }\n paths.push(_renderStackedSegment(cur, v, i, k, geometryParams));\n }\n }\n return paths;\n }\n\n function _renderLegends(): // eslint-disable-next-line @typescript-eslint/no-deprecated\n JSX.Element {\n if (props.hideLegend) {\n return <></>;\n }\n let legends: ILegend[];\n\n if (isStacked) {\n // Collect unique categories and their color\n const categoryMap: Record<string, string> = {};\n props.data.forEach((stage: IFunnelChartDataPoint) => {\n (stage.subValues || []).forEach(sub => {\n if (!(sub.category in categoryMap)) {\n categoryMap[sub.category] = sub.color;\n }\n });\n });\n legends = Object.entries(categoryMap).map(([category, color]) => ({\n title: category,\n color,\n hoverAction: () => setHoveredStage(category),\n onMouseOutAction: () => setHoveredStage(null),\n }));\n } else {\n legends = props.data.map((d: IFunnelChartDataPoint) => ({\n title: d.stage as string,\n color: d.color!,\n hoverAction: () => setHoveredStage(d.stage as string),\n onMouseOutAction: () => setHoveredStage(null),\n }));\n }\n\n return (\n <div style={{ display: 'flex', justifyContent: 'center' }}>\n <Legends\n ref={legendsRef}\n legends={legends}\n centerLegends={true}\n onChange={_onLegendSelectionChangeCallback}\n {...props.legendProps}\n />\n </div>\n );\n }\n\n function _isChartEmpty(): boolean {\n return !(props.data && props.data.length > 0);\n }\n\n const calloutProps = {\n isCalloutVisible,\n directionalHint: DirectionalHint.topAutoEdge,\n id: `toolTip${_tooltipId}`,\n target: refSelected,\n color: calloutData?.color,\n XValue: calloutData?.stage,\n YValue: calloutData?.value,\n isBeakVisible: false,\n gapSpace: 15,\n onDismiss: () => {\n setIsCalloutVisible(false);\n },\n preventDismissOnLostFocus: true,\n ...props.calloutProps,\n };\n\n const width = props.width || 350;\n const height = props.height || 500;\n const classNames = getClassNames(props.styles!, {\n theme: props.theme!,\n className: props.className,\n chartWidth: width,\n chartHeight: height,\n });\n\n const funnelMarginTop = 40;\n const funnelWidth = width * 0.8;\n const funnelOffsetX = (width - funnelWidth) / 2;\n\n return !_isChartEmpty() ? (\n <div ref={chartContainerRef} className={classNames.root}>\n <FocusZone direction={FocusZoneDirection.horizontal}>\n <svg width={width} height={height} className={classNames.chart} role={'img'} aria-label={props.chartTitle}>\n <g\n transform={\n isRTL\n ? `translate(${funnelOffsetX + funnelWidth}, ${funnelMarginTop}) scale(-1,1)`\n : `translate(${funnelOffsetX}, ${funnelMarginTop})`\n }\n >\n {isStacked\n ? _createStackedFunnel(height - funnelMarginTop, funnelWidth)\n : _createFunnel(height - funnelMarginTop, funnelWidth)}\n </g>\n {isCalloutVisible && (\n <Callout {...calloutProps}>\n <ChartHoverCard\n XValue={calloutProps?.XValue as string}\n YValue={calloutProps?.YValue}\n color={calloutProps?.color}\n />\n </Callout>\n )}\n </svg>\n </FocusZone>\n {_renderLegends()}\n </div>\n ) : (\n <div id={_emptyChartId} role={'alert'} style={{ opacity: '0' }} aria-label={'Graph has no data to display'} />\n );\n});\nFunnelChartBase.displayName = 'FunnelChart';\n// eslint-disable-next-line @typescript-eslint/no-deprecated\nFunnelChartBase.defaultProps = {\n orientation: 'horizontal',\n};\n"]}
|
|
1
|
+
{"version":3,"file":"FunnelChart.base.js","sourceRoot":"../src/","sources":["components/FunnelChart/FunnelChart.base.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\nimport { classNamesFunction, getId, getRTL } from '@fluentui/react/lib/Utilities';\nimport {\n IFunnelChartDataPoint,\n IFunnelChartProps,\n IFunnelChartStyleProps,\n IFunnelChartStyles,\n} from './FunnelChart.types';\nimport { FocusZone, FocusZoneDirection } from '@fluentui/react-focus';\nimport { ILegend, ILegendContainer, Legends } from '../Legends/index';\nimport { Callout, DirectionalHint } from '@fluentui/react/lib/Callout';\nimport { ChartHoverCard } from '../../utilities/ChartHoverCard/ChartHoverCard';\nimport { formatToLocaleString } from '@fluentui/chart-utilities';\nimport { IImageExportOptions } from '../../types/index';\nimport { toImage as convertToImage } from '../../utilities/image-export-utils';\nimport { getContrastTextColor } from '../../utilities/utilities';\nimport {\n getHorizontalFunnelSegmentGeometry,\n getVerticalFunnelSegmentGeometry,\n getSegmentTextProps,\n getStackedHorizontalFunnelSegmentGeometry,\n getStackedVerticalFunnelSegmentGeometry,\n} from './funnelGeometry';\n\nconst getClassNames = classNamesFunction<IFunnelChartStyleProps, IFunnelChartStyles>();\n\nexport const FunnelChartBase: React.FunctionComponent<IFunnelChartProps> = React.forwardRef<\n HTMLDivElement,\n IFunnelChartProps\n>((props, forwardedRef) => {\n const _tooltipId: string = getId('FunnelChartTooltipId_');\n const _emptyChartId: string = getId('_FunnelChart_empty');\n const isRTL = getRTL();\n\n const [hoveredStage, setHoveredStage] = React.useState<string | null>(null);\n const [isCalloutVisible, setIsCalloutVisible] = React.useState(false);\n const [calloutData, setCalloutData] = React.useState<IFunnelChartDataPoint | null>(null);\n const [refSelected, setRefSelected] = React.useState<SVGElement | null>(null);\n const [selectedLegends, setSelectedLegends] = React.useState<string[]>([]);\n const chartContainerRef = React.useRef<HTMLDivElement | null>(null);\n const legendsRef = React.useRef<ILegendContainer | null>(null);\n const isStacked = isStackedFunnelData(props.data);\n\n React.useEffect(() => {\n if (props.legendProps?.selectedLegends) {\n setSelectedLegends(props.legendProps.selectedLegends);\n }\n }, [props.legendProps?.selectedLegends]);\n\n React.useImperativeHandle(\n props.componentRef,\n () => ({\n chartContainer: chartContainerRef ?? null,\n toImage: (opts?: IImageExportOptions): Promise<string> => {\n return convertToImage(chartContainerRef.current, legendsRef.current?.toSVG, getRTL(), opts);\n },\n }),\n [],\n );\n\n function _handleHover(data: IFunnelChartDataPoint, mouseEvent: React.MouseEvent<SVGElement>) {\n mouseEvent?.persist();\n setHoveredStage(data.stage as string);\n setCalloutData(data);\n setIsCalloutVisible(true);\n setRefSelected(mouseEvent.currentTarget);\n }\n\n function _handleFocus(data: IFunnelChartDataPoint, focusEvent: React.FocusEvent<SVGPathElement>) {\n focusEvent?.persist();\n setCalloutData(data);\n setIsCalloutVisible(true);\n setRefSelected(focusEvent.currentTarget);\n }\n\n function _handleStackedHover(\n stage: string,\n subValue: { category: string; value: number; color: string },\n mouseEvent: React.MouseEvent<SVGElement>,\n ) {\n mouseEvent?.persist();\n setHoveredStage(subValue.category);\n setCalloutData({\n stage,\n value: subValue.value,\n color: subValue.color,\n category: subValue.category,\n } as IFunnelChartDataPoint);\n setIsCalloutVisible(true);\n setRefSelected(mouseEvent.currentTarget);\n }\n\n function _handleStackedFocus(\n stage: string,\n subValue: { category: string; value: number; color: string },\n focusEvent: React.FocusEvent<SVGPathElement>,\n ) {\n focusEvent?.persist();\n setCalloutData({\n stage,\n value: subValue.value,\n color: subValue.color,\n category: subValue.category,\n } as IFunnelChartDataPoint);\n setIsCalloutVisible(true);\n setRefSelected(focusEvent.currentTarget);\n }\n\n function _handleMouseOut() {\n setHoveredStage(null);\n setIsCalloutVisible(false);\n setCalloutData(null);\n setRefSelected(null);\n }\n\n function _onLegendSelectionChange(\n legendsSelected: string[],\n event: React.MouseEvent<HTMLButtonElement>,\n currentLegend?: ILegend,\n ): void {\n if (props.legendProps?.canSelectMultipleLegends) {\n setSelectedLegends(legendsSelected);\n } else {\n setSelectedLegends(legendsSelected.slice(-1));\n }\n\n if (props.legendProps?.onChange) {\n props.legendProps.onChange(legendsSelected, event, currentLegend);\n }\n }\n\n const _onLegendSelectionChangeCallback = React.useCallback(_onLegendSelectionChange, [props.legendProps]);\n\n function getHighlightedLegend(): string[] {\n return selectedLegends.length > 0 ? selectedLegends : hoveredStage ? [hoveredStage] : [];\n }\n\n function legendHighlighted(legend: string): boolean {\n return getHighlightedLegend().includes(legend);\n }\n\n function noLegendHighlighted(): boolean {\n return getHighlightedLegend().length === 0;\n }\n\n function _getEventHandlerProps(\n data: IFunnelChartDataPoint | { stage: string; subValue: { category: string; value: number; color: string } },\n opacity?: number,\n ) {\n if ('subValue' in data) {\n return {\n culture: props.culture,\n onMouseOver:\n opacity === 1\n ? (event: React.MouseEvent<SVGElement>) => _handleStackedHover(data.stage, data.subValue, event)\n : undefined,\n onMouseMove:\n opacity === 1\n ? (event: React.MouseEvent<SVGElement>) => _handleStackedHover(data.stage, data.subValue, event)\n : undefined,\n onFocus: (event: React.FocusEvent<SVGPathElement>) => _handleStackedFocus(data.stage, data.subValue, event),\n onBlur: () => _handleMouseOut(),\n onMouseOut: () => _handleMouseOut(),\n };\n } else {\n return {\n culture: props.culture,\n onMouseOver: opacity === 1 ? (event: React.MouseEvent<SVGElement>) => _handleHover(data, event) : undefined,\n onMouseMove: opacity === 1 ? (event: React.MouseEvent<SVGElement>) => _handleHover(data, event) : undefined,\n onFocus: (event: React.FocusEvent<SVGPathElement>) => _handleFocus(data, event),\n onBlur: () => _handleMouseOut(),\n onMouseOut: () => _handleMouseOut(),\n };\n }\n }\n\n function _renderSegmentText({\n show,\n x,\n y,\n value,\n textColor,\n }: {\n show: boolean;\n x: number;\n y: number;\n value: number;\n textColor: string;\n }) {\n if (!show) {\n return null;\n }\n\n const textElement = (\n <text x={isRTL ? funnelWidth - x : x} y={y} textAnchor=\"middle\" alignmentBaseline=\"middle\" fill={textColor}>\n {formatToLocaleString(value.toString(), props.culture) as React.ReactNode}\n </text>\n );\n\n if (isRTL) {\n return <g transform={`scale(-1,1) translate(${-funnelWidth},0)`}>{textElement}</g>;\n }\n return textElement;\n }\n\n function _renderFunnelSegment({\n key,\n pathD,\n fill,\n opacity,\n textProps,\n data,\n isFocusable,\n }: {\n key: string | number;\n pathD: string;\n fill: string;\n opacity: number;\n textProps?: {\n show: boolean;\n x: number;\n y: number;\n value: number;\n };\n data: IFunnelChartDataPoint | { stage: string; subValue: { category: string; value: number; color: string } };\n isFocusable?: boolean;\n }) {\n const eventHandlers = _getEventHandlerProps(data, opacity);\n const textColor = getContrastTextColor(fill, props.theme!);\n\n return (\n <g key={key}>\n <path d={pathD} fill={fill} opacity={opacity} {...eventHandlers} data-is-focusable={isFocusable} />\n {textProps && <g {...eventHandlers}>{_renderSegmentText({ ...textProps, textColor })}</g>}\n </g>\n );\n }\n\n function _createFunnel(\n containerHeight: number,\n containerWidth: number,\n ): // eslint-disable-next-line @typescript-eslint/no-deprecated\n JSX.Element[] {\n const { data } = props;\n const funnelWidth = containerWidth;\n const funnelHeight = containerHeight * 0.8;\n\n return data.map((d, i) => {\n const geometryProps =\n props.orientation === 'vertical'\n ? getVerticalFunnelSegmentGeometry({ d, i, data, funnelWidth, funnelHeight, isRTL })\n : getHorizontalFunnelSegmentGeometry({ d, i, data, funnelWidth, funnelHeight, isRTL });\n\n const { pathD, textX, textY, availableWidth } = geometryProps;\n const minTextWidth = 16;\n const eventHandlerProps = _getEventHandlerProps(d);\n const textProps = getSegmentTextProps({\n availableWidth,\n minTextWidth,\n textX,\n textY,\n value: d.value!,\n ...eventHandlerProps,\n });\n\n return _renderFunnelSegment({\n key: i,\n pathD,\n fill: d.color!,\n opacity: legendHighlighted(d.stage as string) || noLegendHighlighted() ? 1 : 0.1,\n textProps,\n data: d,\n isFocusable: legendHighlighted(d.stage as string) || noLegendHighlighted() ? true : false,\n });\n });\n }\n\n function isStackedFunnelData(data: IFunnelChartDataPoint[]): boolean {\n return Array.isArray(data) && data.every(stage => Array.isArray(stage.subValues));\n }\n\n function _renderStackedSegment(\n stage: IFunnelChartDataPoint,\n subValue: { value: number; color: string; category: string },\n stageIndex: number,\n subValueIndex: number,\n geometryParams: {\n stages: IFunnelChartDataPoint[];\n totals: number[];\n maxTotal: number;\n funnelWidth: number;\n funnelHeight: number;\n isRTL: boolean;\n },\n ): // eslint-disable-next-line @typescript-eslint/no-deprecated\n JSX.Element {\n // Ensure stages have subValues for geometry functions\n const stagesWithSubValues = geometryParams.stages.map(s => ({\n ...s,\n subValues: s.subValues || [],\n }));\n\n const geom =\n props.orientation === 'vertical'\n ? getStackedVerticalFunnelSegmentGeometry({\n ...geometryParams,\n stages: stagesWithSubValues,\n i: stageIndex,\n k: subValueIndex,\n })\n : getStackedHorizontalFunnelSegmentGeometry({\n ...geometryParams,\n stages: stagesWithSubValues,\n i: stageIndex,\n k: subValueIndex,\n });\n\n const minTextWidth = 16;\n const eventHandlerProps = _getEventHandlerProps({ stage: stage.stage as string, subValue });\n const textProps = getSegmentTextProps({\n availableWidth: geom.availableWidth,\n minTextWidth,\n textX: geom.textX,\n textY: geom.textY,\n value: subValue.value,\n ...eventHandlerProps,\n });\n\n return _renderFunnelSegment({\n key: `${stageIndex}-${subValueIndex}`,\n pathD: geom.pathD,\n fill: subValue.color,\n opacity:\n (isStackedFunnelData(props.data) && legendHighlighted(subValue.category)) || noLegendHighlighted() ? 1 : 0.1,\n textProps,\n data: { stage: stage.stage as string, subValue },\n isFocusable:\n (isStackedFunnelData(props.data) && legendHighlighted(subValue.category)) || noLegendHighlighted()\n ? true\n : false,\n });\n }\n\n function _createStackedFunnel(\n containerHeight: number,\n containerWidth: number,\n ): // eslint-disable-next-line @typescript-eslint/no-deprecated\n JSX.Element[] {\n const { data } = props;\n\n const stages = data;\n const totals = stages.map(s => s?.subValues?.reduce((sum, subValue) => sum + subValue.value, 0) ?? 0);\n const maxTotal = Math.max(...totals);\n\n const funnelWidth = containerWidth;\n const funnelHeight = containerHeight * 0.8;\n\n // eslint-disable-next-line @typescript-eslint/no-deprecated\n const paths: JSX.Element[] = [];\n\n const geometryParams = {\n stages,\n totals,\n maxTotal,\n funnelWidth,\n funnelHeight,\n isRTL,\n };\n\n for (let i = 0; i < stages.length; i++) {\n const cur = stages[i];\n for (let k = 0; k < (cur.subValues ?? []).length; k++) {\n const v = cur.subValues?.[k];\n if (!v) {\n continue;\n }\n paths.push(_renderStackedSegment(cur, v, i, k, geometryParams));\n }\n }\n return paths;\n }\n\n function _renderLegends(): // eslint-disable-next-line @typescript-eslint/no-deprecated\n JSX.Element {\n if (props.hideLegend) {\n return <></>;\n }\n let legends: ILegend[];\n\n if (isStacked) {\n // Collect unique categories and their color\n const categoryMap: Record<string, string> = {};\n props.data.forEach((stage: IFunnelChartDataPoint) => {\n (stage.subValues || []).forEach(sub => {\n if (!(sub.category in categoryMap)) {\n categoryMap[sub.category] = sub.color;\n }\n });\n });\n legends = Object.entries(categoryMap).map(([category, color]) => ({\n title: category,\n color,\n hoverAction: () => setHoveredStage(category),\n onMouseOutAction: () => setHoveredStage(null),\n }));\n } else {\n legends = props.data.map((d: IFunnelChartDataPoint) => ({\n title: d.stage as string,\n color: d.color!,\n hoverAction: () => setHoveredStage(d.stage as string),\n onMouseOutAction: () => setHoveredStage(null),\n }));\n }\n\n return (\n <div style={{ display: 'flex', justifyContent: 'center' }}>\n <Legends\n ref={legendsRef}\n legends={legends}\n centerLegends={true}\n onChange={_onLegendSelectionChangeCallback}\n {...props.legendProps}\n />\n </div>\n );\n }\n\n function _isChartEmpty(): boolean {\n return !(props.data && props.data.length > 0);\n }\n\n const calloutProps = {\n isCalloutVisible,\n directionalHint: DirectionalHint.topAutoEdge,\n id: `toolTip${_tooltipId}`,\n target: refSelected,\n color: calloutData?.color,\n XValue: calloutData?.stage,\n YValue: calloutData?.value,\n isBeakVisible: false,\n gapSpace: 15,\n onDismiss: () => {\n setIsCalloutVisible(false);\n },\n preventDismissOnLostFocus: true,\n ...props.calloutProps,\n };\n\n const width = props.width || 350;\n const height = props.height || 500;\n const classNames = getClassNames(props.styles!, {\n theme: props.theme!,\n className: props.className,\n chartWidth: width,\n chartHeight: height,\n });\n\n const funnelMarginTop = 40;\n const funnelWidth = width * 0.8;\n const funnelOffsetX = (width - funnelWidth) / 2;\n\n return !_isChartEmpty() ? (\n <div ref={chartContainerRef} className={classNames.root}>\n <FocusZone direction={FocusZoneDirection.horizontal}>\n <svg width={width} height={height} className={classNames.chart} role={'img'} aria-label={props.chartTitle}>\n <g\n transform={\n isRTL\n ? `translate(${funnelOffsetX + funnelWidth}, ${funnelMarginTop}) scale(-1,1)`\n : `translate(${funnelOffsetX}, ${funnelMarginTop})`\n }\n >\n {isStacked\n ? _createStackedFunnel(height - funnelMarginTop, funnelWidth)\n : _createFunnel(height - funnelMarginTop, funnelWidth)}\n </g>\n {isCalloutVisible && (\n <Callout {...calloutProps}>\n <ChartHoverCard\n XValue={calloutProps?.XValue as string}\n YValue={calloutProps?.YValue}\n color={calloutProps?.color}\n />\n </Callout>\n )}\n </svg>\n </FocusZone>\n {_renderLegends()}\n </div>\n ) : (\n <div id={_emptyChartId} role={'alert'} style={{ opacity: '0' }} aria-label={'Graph has no data to display'} />\n );\n});\nFunnelChartBase.displayName = 'FunnelChart';\n// eslint-disable-next-line @typescript-eslint/no-deprecated\nFunnelChartBase.defaultProps = {\n orientation: 'vertical',\n};\n"]}
|
|
@@ -20,7 +20,7 @@ interface ISubValue {
|
|
|
20
20
|
interface IStage {
|
|
21
21
|
subValues: ISubValue[];
|
|
22
22
|
}
|
|
23
|
-
export declare function
|
|
23
|
+
export declare function getVerticalFunnelSegmentGeometry({ d, i, data, funnelWidth, funnelHeight, isRTL, }: {
|
|
24
24
|
d: IFunnelChartDataPoint;
|
|
25
25
|
i: number;
|
|
26
26
|
data: IFunnelChartDataPoint[];
|
|
@@ -28,7 +28,7 @@ export declare function getHorizontalFunnelSegmentGeometry({ d, i, data, funnelW
|
|
|
28
28
|
funnelHeight: number;
|
|
29
29
|
isRTL: boolean;
|
|
30
30
|
}): IFunnelSegmentGeometry;
|
|
31
|
-
export declare function
|
|
31
|
+
export declare function getHorizontalFunnelSegmentGeometry({ d, i, data, funnelWidth, funnelHeight, isRTL, }: {
|
|
32
32
|
d: IFunnelChartDataPoint;
|
|
33
33
|
i: number;
|
|
34
34
|
data: IFunnelChartDataPoint[];
|
|
@@ -36,7 +36,7 @@ export declare function getVerticalFunnelSegmentGeometry({ d, i, data, funnelWid
|
|
|
36
36
|
funnelHeight: number;
|
|
37
37
|
isRTL: boolean;
|
|
38
38
|
}): IFunnelSegmentGeometry;
|
|
39
|
-
export declare function
|
|
39
|
+
export declare function getStackedVerticalFunnelSegmentGeometry({ i, k, stages, totals, maxTotal, funnelWidth, funnelHeight, }: {
|
|
40
40
|
i: number;
|
|
41
41
|
k: number;
|
|
42
42
|
stages: IStage[];
|
|
@@ -45,7 +45,7 @@ export declare function getStackedHorizontalFunnelSegmentGeometry({ i, k, stages
|
|
|
45
45
|
funnelWidth: number;
|
|
46
46
|
funnelHeight: number;
|
|
47
47
|
}): IStackedFunnelSegmentGeometry;
|
|
48
|
-
export declare function
|
|
48
|
+
export declare function getStackedHorizontalFunnelSegmentGeometry({ i, k, stages, totals, maxTotal, funnelWidth, funnelHeight, }: {
|
|
49
49
|
i: number;
|
|
50
50
|
k: number;
|
|
51
51
|
stages: IStage[];
|
|
@@ -61,8 +61,8 @@ export declare function getSegmentTextProps({ availableWidth, minTextWidth, text
|
|
|
61
61
|
textY: number;
|
|
62
62
|
value: number;
|
|
63
63
|
culture: string | undefined;
|
|
64
|
-
onMouseOver: (event: React.MouseEvent<SVGElement>) => void;
|
|
65
|
-
onMouseMove: (event: React.MouseEvent<SVGElement>) => void;
|
|
64
|
+
onMouseOver: ((event: React.MouseEvent<SVGElement>) => void) | undefined;
|
|
65
|
+
onMouseMove: ((event: React.MouseEvent<SVGElement>) => void) | undefined;
|
|
66
66
|
onMouseOut: () => void;
|
|
67
67
|
}): {
|
|
68
68
|
show: boolean;
|
|
@@ -70,8 +70,8 @@ export declare function getSegmentTextProps({ availableWidth, minTextWidth, text
|
|
|
70
70
|
y: number;
|
|
71
71
|
value: number;
|
|
72
72
|
culture: string | undefined;
|
|
73
|
-
onMouseOver: (event: React.MouseEvent<SVGElement>) => void;
|
|
74
|
-
onMouseMove: (event: React.MouseEvent<SVGElement>) => void;
|
|
73
|
+
onMouseOver: ((event: React.MouseEvent<SVGElement>) => void) | undefined;
|
|
74
|
+
onMouseMove: ((event: React.MouseEvent<SVGElement>) => void) | undefined;
|
|
75
75
|
onMouseOut: () => void;
|
|
76
76
|
};
|
|
77
77
|
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export function
|
|
1
|
+
export function getVerticalFunnelSegmentGeometry(_a) {
|
|
2
2
|
var d = _a.d, i = _a.i, data = _a.data, funnelWidth = _a.funnelWidth, funnelHeight = _a.funnelHeight, isRTL = _a.isRTL;
|
|
3
3
|
var segmentHeight = funnelHeight / data.length;
|
|
4
4
|
var widthScale = function (value) { return (value / Math.max.apply(Math, data.map(function (dataPoint) { return dataPoint.value; }))) * funnelWidth; };
|
|
@@ -23,7 +23,7 @@ export function getHorizontalFunnelSegmentGeometry(_a) {
|
|
|
23
23
|
var pathD = "M".concat(xStart, ",").concat(i * segmentHeight, "\n L").concat(funnelWidth - xStart, ",").concat(i * segmentHeight, "\n L").concat(funnelWidth - xEnd, ",").concat((i + 1) * segmentHeight, "\n L").concat(xEnd, ",").concat((i + 1) * segmentHeight, "\n Z");
|
|
24
24
|
return { pathD: pathD, textX: textX, textY: textY, availableWidth: availableWidth };
|
|
25
25
|
}
|
|
26
|
-
export function
|
|
26
|
+
export function getHorizontalFunnelSegmentGeometry(_a) {
|
|
27
27
|
var d = _a.d, i = _a.i, data = _a.data, funnelWidth = _a.funnelWidth, funnelHeight = _a.funnelHeight, isRTL = _a.isRTL;
|
|
28
28
|
var segmentWidth = funnelWidth / data.length;
|
|
29
29
|
var heightScale = function (value) { return (value / Math.max.apply(Math, data.map(function (dataPoint) { return dataPoint.value; }))) * funnelHeight; };
|
|
@@ -64,7 +64,7 @@ export function getVerticalFunnelSegmentGeometry(_a) {
|
|
|
64
64
|
var pathD = "M".concat(x0, ",").concat(yOffset, "\n L").concat(x1, ",").concat(nextYOffset, "\n L").concat(x1, ",").concat(funnelHeight - nextYOffset, "\n L").concat(x0, ",").concat(funnelHeight - yOffset, "\n Z");
|
|
65
65
|
return { pathD: pathD, textX: textX, textY: textY, availableWidth: availableWidth };
|
|
66
66
|
}
|
|
67
|
-
export function
|
|
67
|
+
export function getStackedVerticalFunnelSegmentGeometry(_a) {
|
|
68
68
|
var _b, _c;
|
|
69
69
|
var i = _a.i, k = _a.k, stages = _a.stages, totals = _a.totals, maxTotal = _a.maxTotal, funnelWidth = _a.funnelWidth, funnelHeight = _a.funnelHeight;
|
|
70
70
|
var segmentHeight = funnelHeight / stages.length;
|
|
@@ -113,7 +113,7 @@ export function getStackedHorizontalFunnelSegmentGeometry(_a) {
|
|
|
113
113
|
var pathD = "M".concat(topStart, ",").concat(i * segmentHeight, "\n L").concat(topEnd, ",").concat(i * segmentHeight, "\n L").concat(botEnd, ",").concat((i + 1) * segmentHeight, "\n L").concat(botStart, ",").concat((i + 1) * segmentHeight, "\n Z");
|
|
114
114
|
return { pathD: pathD, textX: textX, textY: textY, availableWidth: availableWidth };
|
|
115
115
|
}
|
|
116
|
-
export function
|
|
116
|
+
export function getStackedHorizontalFunnelSegmentGeometry(_a) {
|
|
117
117
|
var _b, _c;
|
|
118
118
|
var i = _a.i, k = _a.k, stages = _a.stages, totals = _a.totals, maxTotal = _a.maxTotal, funnelWidth = _a.funnelWidth, funnelHeight = _a.funnelHeight;
|
|
119
119
|
var segmentWidth = funnelWidth / stages.length;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"funnelGeometry.js","sourceRoot":"../src/","sources":["components/FunnelChart/funnelGeometry.ts"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\nimport { IFunnelChartDataPoint } from './FunnelChart.types';\n\nexport interface IFunnelSegmentGeometry {\n pathD: string;\n textX: number;\n textY: number;\n availableWidth: number;\n}\n\nexport interface IStackedFunnelSegmentGeometry {\n pathD: string;\n textX: number;\n textY: number;\n availableWidth: number;\n}\n\ninterface ISubValue {\n category: string;\n value: number;\n color: string;\n}\n\ninterface IStage {\n subValues: ISubValue[];\n}\n\nexport function getHorizontalFunnelSegmentGeometry({\n d,\n i,\n data,\n funnelWidth,\n funnelHeight,\n isRTL,\n}: {\n d: IFunnelChartDataPoint;\n i: number;\n data: IFunnelChartDataPoint[];\n funnelWidth: number;\n funnelHeight: number;\n isRTL: boolean;\n}): IFunnelSegmentGeometry {\n const segmentHeight = funnelHeight / data.length;\n const widthScale = (value: number) => (value / Math.max(...data.map(dataPoint => dataPoint.value!))) * funnelWidth;\n const topWidth = widthScale(d.value!);\n const bottomWidth = i < data.length - 1 ? widthScale(data[i + 1].value!) : 0;\n const xOffset = (funnelWidth - topWidth) / 2;\n const nextXOffset = (funnelWidth - bottomWidth) / 2;\n const xStart = isRTL ? funnelWidth - xOffset : xOffset;\n const xEnd = isRTL ? funnelWidth - nextXOffset : nextXOffset;\n\n const isLastSegment = i === data.length - 1;\n const textY = isLastSegment ? i * segmentHeight + segmentHeight * 0.33 : i * segmentHeight + segmentHeight / 2;\n\n const textX = funnelWidth / 2;\n let availableWidth = topWidth;\n if (isLastSegment) {\n const yFromTop = textY - i * segmentHeight;\n const widthAtY = topWidth * (1 - yFromTop / segmentHeight);\n availableWidth = Math.max(widthAtY * 0.8, 0);\n } else {\n availableWidth = Math.min(topWidth, bottomWidth) * 0.9;\n }\n const pathD = `M${xStart},${i * segmentHeight}\n L${funnelWidth - xStart},${i * segmentHeight}\n L${funnelWidth - xEnd},${(i + 1) * segmentHeight}\n L${xEnd},${(i + 1) * segmentHeight}\n Z`;\n return { pathD, textX, textY, availableWidth };\n}\n\nexport function getVerticalFunnelSegmentGeometry({\n d,\n i,\n data,\n funnelWidth,\n funnelHeight,\n isRTL,\n}: {\n d: IFunnelChartDataPoint;\n i: number;\n data: IFunnelChartDataPoint[];\n funnelWidth: number;\n funnelHeight: number;\n isRTL: boolean;\n}): IFunnelSegmentGeometry {\n const segmentWidth = funnelWidth / data.length;\n const heightScale = (value: number) => (value / Math.max(...data.map(dataPoint => dataPoint.value!))) * funnelHeight;\n const leftHeight = heightScale(d.value!);\n const rightHeight = i < data.length - 1 ? heightScale(data[i + 1].value!) : 0;\n const yOffset = (funnelHeight - leftHeight) / 2;\n const nextYOffset = (funnelHeight - rightHeight) / 2;\n const x0 = i * segmentWidth;\n const x1 = (i + 1) * segmentWidth;\n\n const isLastSegment = i === data.length - 1;\n let textX: number;\n let textY: number;\n let availableWidth = segmentWidth * 0.8;\n\n if (isLastSegment) {\n // For the triangular last segment, position text at 1/4 from the left edge\n textX = x0 + (x1 - x0) * 0.25;\n textY = funnelHeight / 2;\n\n // For triangular segments, we need to check both height and width constraints\n // The segment needs to be large enough to contain text\n const segmentArea = (leftHeight * segmentWidth) / 2; // Area of triangle\n const minAreaForText = 800; // Minimum area needed to show text\n\n if (leftHeight < 40 || segmentArea < minAreaForText) {\n // Hide text if height is too small or area is insufficient\n availableWidth = 0;\n } else {\n // Calculate available width at text position\n const widthAtTextPosition = (x1 - x0) * 0.75;\n availableWidth = widthAtTextPosition * 0.6;\n }\n } else {\n textX = (x0 + x1) / 2;\n textY = funnelHeight / 2;\n const minHeight = Math.min(leftHeight, rightHeight);\n availableWidth = minHeight > 20 ? segmentWidth * 0.8 : 0;\n }\n\n const pathD = `M${x0},${yOffset}\n L${x1},${nextYOffset}\n L${x1},${funnelHeight - nextYOffset}\n L${x0},${funnelHeight - yOffset}\n Z`;\n return { pathD, textX, textY, availableWidth };\n}\n\nexport function getStackedHorizontalFunnelSegmentGeometry({\n i,\n k,\n stages,\n totals,\n maxTotal,\n funnelWidth,\n funnelHeight,\n}: {\n i: number;\n k: number;\n stages: IStage[];\n totals: number[];\n maxTotal: number;\n funnelWidth: number;\n funnelHeight: number;\n}): IStackedFunnelSegmentGeometry {\n const segmentHeight = funnelHeight / stages.length;\n const cur = stages[i];\n const next = stages[i + 1] || { subValues: [] };\n const curTotal = totals[i] || 1;\n const nextTotal = totals[i + 1] || 0;\n\n let cumTop = 0;\n let cumBot = 0;\n for (let idx = 0; idx < k; idx++) {\n const v = cur.subValues[idx];\n const vNext = next.subValues?.find((x: ISubValue) => x.category === v.category);\n const val = v.value;\n const nextVal = vNext ? vNext.value : 0;\n cumTop += (val / curTotal) * (curTotal / maxTotal) * funnelWidth;\n cumBot += (nextVal / nextTotal || 0) * (nextTotal / maxTotal) * funnelWidth;\n }\n const v = cur.subValues[k];\n const vNext = next.subValues?.find((x: ISubValue) => x.category === v.category);\n const val = v.value;\n const nextVal = vNext ? vNext.value : 0;\n const topW = (val / curTotal) * (curTotal / maxTotal) * funnelWidth;\n const botW = (nextVal / nextTotal || 0) * (nextTotal / maxTotal) * funnelWidth;\n const topStart = (funnelWidth - (curTotal / maxTotal) * funnelWidth) / 2 + cumTop;\n const topEnd = topStart + topW;\n const botStart = (funnelWidth - (nextTotal / maxTotal) * funnelWidth) / 2 + cumBot;\n const botEnd = botStart + botW;\n const textX = (topStart + topEnd + botStart + botEnd) / 4;\n\n const isLastSegment = i === stages.length - 1;\n const textY = isLastSegment ? i * segmentHeight + segmentHeight * 0.33 : (i + 0.5) * segmentHeight;\n\n // Calculate available width based on this specific segment's width\n let availableWidth: number;\n if (isLastSegment) {\n // For triangular last segment, use the width at text Y position\n const yFromTop = textY - i * segmentHeight;\n const widthRatio = 1 - yFromTop / segmentHeight;\n availableWidth = topW * widthRatio;\n } else {\n // For trapezoidal segments, use the actual segment width\n availableWidth = Math.min(topW, botW);\n }\n\n const pathD = `M${topStart},${i * segmentHeight}\n L${topEnd},${i * segmentHeight}\n L${botEnd},${(i + 1) * segmentHeight}\n L${botStart},${(i + 1) * segmentHeight}\n Z`;\n return { pathD, textX, textY, availableWidth };\n}\n\nexport function getStackedVerticalFunnelSegmentGeometry({\n i,\n k,\n stages,\n totals,\n maxTotal,\n funnelWidth,\n funnelHeight,\n}: {\n i: number;\n k: number;\n stages: IStage[];\n totals: number[];\n maxTotal: number;\n funnelWidth: number;\n funnelHeight: number;\n}): IStackedFunnelSegmentGeometry {\n const segmentWidth = funnelWidth / stages.length;\n const cur = stages[i];\n const next = stages[i + 1] || { subValues: [] };\n const curTotal = totals[i] || 1;\n const nextTotal = totals[i + 1] || 0;\n\n let cumTop = 0;\n let cumBot = 0;\n for (let idx = 0; idx < k; idx++) {\n const v = cur.subValues[idx];\n const vNext = next.subValues?.find((x: ISubValue) => x.category === v.category);\n const val = v.value;\n const nextVal = vNext ? vNext.value : 0;\n cumTop += (val / curTotal) * (curTotal / maxTotal) * funnelHeight;\n cumBot += (nextVal / nextTotal || 0) * (nextTotal / maxTotal) * funnelHeight;\n }\n const v = cur.subValues[k];\n const vNext = next.subValues?.find((x: ISubValue) => x.category === v.category);\n const val = v.value;\n const nextVal = vNext ? vNext.value : 0;\n const topH = (val / curTotal) * (curTotal / maxTotal) * funnelHeight;\n const botH = (nextVal / nextTotal || 0) * (nextTotal / maxTotal) * funnelHeight;\n const leftStart = i * segmentWidth;\n const leftEnd = (i + 1) * segmentWidth;\n const topStart = (funnelHeight - (curTotal / maxTotal) * funnelHeight) / 2 + cumTop;\n const topEnd = topStart + topH;\n const botStart = (funnelHeight - (nextTotal / maxTotal) * funnelHeight) / 2 + cumBot;\n const botEnd = botStart + botH;\n\n const isLastSegment = i === stages.length - 1;\n let textX: number;\n let textY: number;\n let availableWidth: number;\n\n if (isLastSegment) {\n textX = leftStart + (leftEnd - leftStart) * 0.25;\n textY = (topStart + topEnd) / 2;\n // For triangular segments, calculate available width at text position\n const segmentWidthAtTextPos = (leftEnd - leftStart) * 0.5;\n availableWidth = segmentWidthAtTextPos * 0.8;\n\n // For triangular last segments, also check if there's enough height\n // The segment area should be large enough to contain text\n const segmentArea = (topH * segmentWidth) / 2;\n if (topH < 24 || segmentArea < 600) {\n availableWidth = 0;\n }\n } else {\n textX = (leftStart + leftEnd) / 2;\n textY = (topStart + topEnd + botStart + botEnd) / 4;\n // For trapezoidal segments, use full segment width\n availableWidth = Math.abs(leftEnd - leftStart) * 0.9;\n\n // Check if the segment has sufficient height for text\n // For non-last segments, we need to ensure there's enough vertical space\n const avgHeight = (topH + botH) / 2;\n if (avgHeight < 20) {\n availableWidth = 0;\n }\n }\n\n const pathD = `M${leftStart},${topStart}\n L${leftEnd},${botStart}\n L${leftEnd},${botEnd}\n L${leftStart},${topEnd}\n Z`;\n return { pathD, textX, textY, availableWidth };\n}\n\nexport function getSegmentTextProps({\n availableWidth,\n minTextWidth = 24,\n textX,\n textY,\n value,\n culture,\n onMouseOver,\n onMouseMove,\n onMouseOut,\n}: {\n availableWidth: number;\n minTextWidth?: number;\n textX: number;\n textY: number;\n value: number;\n culture: string | undefined;\n onMouseOver: (event: React.MouseEvent<SVGElement>) => void;\n onMouseMove: (event: React.MouseEvent<SVGElement>) => void;\n onMouseOut: () => void;\n}) {\n return {\n show: availableWidth > minTextWidth && availableWidth > 0,\n x: textX,\n y: textY,\n value,\n culture,\n onMouseOver,\n onMouseMove,\n onMouseOut,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"funnelGeometry.js","sourceRoot":"../src/","sources":["components/FunnelChart/funnelGeometry.ts"],"names":[],"mappings":"AA2BA,MAAM,UAAU,gCAAgC,CAAC,EAchD;QAbC,CAAC,OAAA,EACD,CAAC,OAAA,EACD,IAAI,UAAA,EACJ,WAAW,iBAAA,EACX,YAAY,kBAAA,EACZ,KAAK,WAAA;IASL,IAAM,aAAa,GAAG,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC;IACjD,IAAM,UAAU,GAAG,UAAC,KAAa,IAAK,OAAA,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,OAAR,IAAI,EAAQ,IAAI,CAAC,GAAG,CAAC,UAAA,SAAS,IAAI,OAAA,SAAS,CAAC,KAAM,EAAhB,CAAgB,CAAC,CAAC,CAAC,GAAG,WAAW,EAA5E,CAA4E,CAAC;IACnH,IAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,KAAM,CAAC,CAAC;IACtC,IAAM,WAAW,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7E,IAAM,OAAO,GAAG,CAAC,WAAW,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC7C,IAAM,WAAW,GAAG,CAAC,WAAW,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IACpD,IAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;IACvD,IAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,WAAW,GAAG,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC;IAE7D,IAAM,aAAa,GAAG,CAAC,KAAK,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IAC5C,IAAM,KAAK,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,aAAa,GAAG,aAAa,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,aAAa,GAAG,aAAa,GAAG,CAAC,CAAC;IAE/G,IAAM,KAAK,GAAG,WAAW,GAAG,CAAC,CAAC;IAC9B,IAAI,cAAc,GAAG,QAAQ,CAAC;IAC9B,IAAI,aAAa,EAAE,CAAC;QAClB,IAAM,QAAQ,GAAG,KAAK,GAAG,CAAC,GAAG,aAAa,CAAC;QAC3C,IAAM,QAAQ,GAAG,QAAQ,GAAG,CAAC,CAAC,GAAG,QAAQ,GAAG,aAAa,CAAC,CAAC;QAC3D,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;IAC/C,CAAC;SAAM,CAAC;QACN,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,GAAG,CAAC;IACzD,CAAC;IACD,IAAM,KAAK,GAAG,WAAI,MAAM,cAAI,CAAC,GAAG,aAAa,oBACxC,WAAW,GAAG,MAAM,cAAI,CAAC,GAAG,aAAa,oBACzC,WAAW,GAAG,IAAI,cAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,aAAa,oBAC7C,IAAI,cAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,aAAa,YAChC,CAAC;IACL,OAAO,EAAE,KAAK,OAAA,EAAE,KAAK,OAAA,EAAE,KAAK,OAAA,EAAE,cAAc,gBAAA,EAAE,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,kCAAkC,CAAC,EAclD;QAbC,CAAC,OAAA,EACD,CAAC,OAAA,EACD,IAAI,UAAA,EACJ,WAAW,iBAAA,EACX,YAAY,kBAAA,EACZ,KAAK,WAAA;IASL,IAAM,YAAY,GAAG,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC;IAC/C,IAAM,WAAW,GAAG,UAAC,KAAa,IAAK,OAAA,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,OAAR,IAAI,EAAQ,IAAI,CAAC,GAAG,CAAC,UAAA,SAAS,IAAI,OAAA,SAAS,CAAC,KAAM,EAAhB,CAAgB,CAAC,CAAC,CAAC,GAAG,YAAY,EAA7E,CAA6E,CAAC;IACrH,IAAM,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,KAAM,CAAC,CAAC;IACzC,IAAM,WAAW,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9E,IAAM,OAAO,GAAG,CAAC,YAAY,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;IAChD,IAAM,WAAW,GAAG,CAAC,YAAY,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IACrD,IAAM,EAAE,GAAG,CAAC,GAAG,YAAY,CAAC;IAC5B,IAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,YAAY,CAAC;IAElC,IAAM,aAAa,GAAG,CAAC,KAAK,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IAC5C,IAAI,KAAa,CAAC;IAClB,IAAI,KAAa,CAAC;IAClB,IAAI,cAAc,GAAG,YAAY,GAAG,GAAG,CAAC;IAExC,IAAI,aAAa,EAAE,CAAC;QAClB,2EAA2E;QAC3E,KAAK,GAAG,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC;QAC9B,KAAK,GAAG,YAAY,GAAG,CAAC,CAAC;QAEzB,8EAA8E;QAC9E,uDAAuD;QACvD,IAAM,WAAW,GAAG,CAAC,UAAU,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,mBAAmB;QACxE,IAAM,cAAc,GAAG,GAAG,CAAC,CAAC,mCAAmC;QAE/D,IAAI,UAAU,GAAG,EAAE,IAAI,WAAW,GAAG,cAAc,EAAE,CAAC;YACpD,2DAA2D;YAC3D,cAAc,GAAG,CAAC,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,6CAA6C;YAC7C,IAAM,mBAAmB,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC;YAC7C,cAAc,GAAG,mBAAmB,GAAG,GAAG,CAAC;QAC7C,CAAC;IACH,CAAC;SAAM,CAAC;QACN,KAAK,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;QACtB,KAAK,GAAG,YAAY,GAAG,CAAC,CAAC;QACzB,IAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;QACpD,cAAc,GAAG,SAAS,GAAG,EAAE,CAAC,CAAC,CAAC,YAAY,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED,IAAM,KAAK,GAAG,WAAI,EAAE,cAAI,OAAO,oBAC1B,EAAE,cAAI,WAAW,oBACjB,EAAE,cAAI,YAAY,GAAG,WAAW,oBAChC,EAAE,cAAI,YAAY,GAAG,OAAO,YAC7B,CAAC;IACL,OAAO,EAAE,KAAK,OAAA,EAAE,KAAK,OAAA,EAAE,KAAK,OAAA,EAAE,cAAc,gBAAA,EAAE,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,uCAAuC,CAAC,EAgBvD;;QAfC,CAAC,OAAA,EACD,CAAC,OAAA,EACD,MAAM,YAAA,EACN,MAAM,YAAA,EACN,QAAQ,cAAA,EACR,WAAW,iBAAA,EACX,YAAY,kBAAA;IAUZ,IAAM,aAAa,GAAG,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC;IACnD,IAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACtB,IAAM,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;IAChD,IAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAChC,IAAM,SAAS,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;IAErC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,MAAM,GAAG,CAAC,CAAC;4BACN,GAAG;QACV,IAAM,GAAC,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAM,OAAK,GAAG,MAAA,IAAI,CAAC,SAAS,0CAAE,IAAI,CAAC,UAAC,CAAY,IAAK,OAAA,CAAC,CAAC,QAAQ,KAAK,GAAC,CAAC,QAAQ,EAAzB,CAAyB,CAAC,CAAC;QAChF,IAAM,KAAG,GAAG,GAAC,CAAC,KAAK,CAAC;QACpB,IAAM,SAAO,GAAG,OAAK,CAAC,CAAC,CAAC,OAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACxC,MAAM,IAAI,CAAC,KAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC,GAAG,WAAW,CAAC;QACjE,MAAM,IAAI,CAAC,SAAO,GAAG,SAAS,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,GAAG,QAAQ,CAAC,GAAG,WAAW,CAAC;;IAN9E,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC,EAAE,GAAG,EAAE;gBAAvB,GAAG;KAOX;IACD,IAAM,CAAC,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAC3B,IAAM,KAAK,GAAG,MAAA,IAAI,CAAC,SAAS,0CAAE,IAAI,CAAC,UAAC,CAAY,IAAK,OAAA,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,QAAQ,EAAzB,CAAyB,CAAC,CAAC;IAChF,IAAM,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC;IACpB,IAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACxC,IAAM,IAAI,GAAG,CAAC,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC,GAAG,WAAW,CAAC;IACpE,IAAM,IAAI,GAAG,CAAC,OAAO,GAAG,SAAS,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,GAAG,QAAQ,CAAC,GAAG,WAAW,CAAC;IAC/E,IAAM,QAAQ,GAAG,CAAC,WAAW,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;IAClF,IAAM,MAAM,GAAG,QAAQ,GAAG,IAAI,CAAC;IAC/B,IAAM,QAAQ,GAAG,CAAC,WAAW,GAAG,CAAC,SAAS,GAAG,QAAQ,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;IACnF,IAAM,MAAM,GAAG,QAAQ,GAAG,IAAI,CAAC;IAC/B,IAAM,KAAK,GAAG,CAAC,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAE1D,IAAM,aAAa,GAAG,CAAC,KAAK,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;IAC9C,IAAM,KAAK,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,aAAa,GAAG,aAAa,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,aAAa,CAAC;IAEnG,mEAAmE;IACnE,IAAI,cAAsB,CAAC;IAC3B,IAAI,aAAa,EAAE,CAAC;QAClB,gEAAgE;QAChE,IAAM,QAAQ,GAAG,KAAK,GAAG,CAAC,GAAG,aAAa,CAAC;QAC3C,IAAM,UAAU,GAAG,CAAC,GAAG,QAAQ,GAAG,aAAa,CAAC;QAChD,cAAc,GAAG,IAAI,GAAG,UAAU,CAAC;IACrC,CAAC;SAAM,CAAC;QACN,yDAAyD;QACzD,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACxC,CAAC;IAED,IAAM,KAAK,GAAG,WAAI,QAAQ,cAAI,CAAC,GAAG,aAAa,oBAC1C,MAAM,cAAI,CAAC,GAAG,aAAa,oBAC3B,MAAM,cAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,aAAa,oBACjC,QAAQ,cAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,aAAa,YACpC,CAAC;IACL,OAAO,EAAE,KAAK,OAAA,EAAE,KAAK,OAAA,EAAE,KAAK,OAAA,EAAE,cAAc,gBAAA,EAAE,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,yCAAyC,CAAC,EAgBzD;;QAfC,CAAC,OAAA,EACD,CAAC,OAAA,EACD,MAAM,YAAA,EACN,MAAM,YAAA,EACN,QAAQ,cAAA,EACR,WAAW,iBAAA,EACX,YAAY,kBAAA;IAUZ,IAAM,YAAY,GAAG,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC;IACjD,IAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACtB,IAAM,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC;IAChD,IAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAChC,IAAM,SAAS,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;IAErC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,MAAM,GAAG,CAAC,CAAC;4BACN,GAAG;QACV,IAAM,GAAC,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAM,OAAK,GAAG,MAAA,IAAI,CAAC,SAAS,0CAAE,IAAI,CAAC,UAAC,CAAY,IAAK,OAAA,CAAC,CAAC,QAAQ,KAAK,GAAC,CAAC,QAAQ,EAAzB,CAAyB,CAAC,CAAC;QAChF,IAAM,KAAG,GAAG,GAAC,CAAC,KAAK,CAAC;QACpB,IAAM,SAAO,GAAG,OAAK,CAAC,CAAC,CAAC,OAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACxC,MAAM,IAAI,CAAC,KAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC,GAAG,YAAY,CAAC;QAClE,MAAM,IAAI,CAAC,SAAO,GAAG,SAAS,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,GAAG,QAAQ,CAAC,GAAG,YAAY,CAAC;;IAN/E,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC,EAAE,GAAG,EAAE;gBAAvB,GAAG;KAOX;IACD,IAAM,CAAC,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAC3B,IAAM,KAAK,GAAG,MAAA,IAAI,CAAC,SAAS,0CAAE,IAAI,CAAC,UAAC,CAAY,IAAK,OAAA,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,QAAQ,EAAzB,CAAyB,CAAC,CAAC;IAChF,IAAM,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC;IACpB,IAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACxC,IAAM,IAAI,GAAG,CAAC,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC,GAAG,YAAY,CAAC;IACrE,IAAM,IAAI,GAAG,CAAC,OAAO,GAAG,SAAS,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,GAAG,QAAQ,CAAC,GAAG,YAAY,CAAC;IAChF,IAAM,SAAS,GAAG,CAAC,GAAG,YAAY,CAAC;IACnC,IAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,YAAY,CAAC;IACvC,IAAM,QAAQ,GAAG,CAAC,YAAY,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;IACpF,IAAM,MAAM,GAAG,QAAQ,GAAG,IAAI,CAAC;IAC/B,IAAM,QAAQ,GAAG,CAAC,YAAY,GAAG,CAAC,SAAS,GAAG,QAAQ,CAAC,GAAG,YAAY,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;IACrF,IAAM,MAAM,GAAG,QAAQ,GAAG,IAAI,CAAC;IAE/B,IAAM,aAAa,GAAG,CAAC,KAAK,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;IAC9C,IAAI,KAAa,CAAC;IAClB,IAAI,KAAa,CAAC;IAClB,IAAI,cAAsB,CAAC;IAE3B,IAAI,aAAa,EAAE,CAAC;QAClB,KAAK,GAAG,SAAS,GAAG,CAAC,OAAO,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC;QACjD,KAAK,GAAG,CAAC,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAChC,sEAAsE;QACtE,IAAM,qBAAqB,GAAG,CAAC,OAAO,GAAG,SAAS,CAAC,GAAG,GAAG,CAAC;QAC1D,cAAc,GAAG,qBAAqB,GAAG,GAAG,CAAC;QAE7C,oEAAoE;QACpE,0DAA0D;QAC1D,IAAM,WAAW,GAAG,CAAC,IAAI,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QAC9C,IAAI,IAAI,GAAG,EAAE,IAAI,WAAW,GAAG,GAAG,EAAE,CAAC;YACnC,cAAc,GAAG,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;SAAM,CAAC;QACN,KAAK,GAAG,CAAC,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAClC,KAAK,GAAG,CAAC,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QACpD,mDAAmD;QACnD,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,GAAG,SAAS,CAAC,GAAG,GAAG,CAAC;QAErD,sDAAsD;QACtD,yEAAyE;QACzE,IAAM,SAAS,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,SAAS,GAAG,EAAE,EAAE,CAAC;YACnB,cAAc,GAAG,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAED,IAAM,KAAK,GAAG,WAAI,SAAS,cAAI,QAAQ,oBAClC,OAAO,cAAI,QAAQ,oBACnB,OAAO,cAAI,MAAM,oBACjB,SAAS,cAAI,MAAM,YACpB,CAAC;IACL,OAAO,EAAE,KAAK,OAAA,EAAE,KAAK,OAAA,EAAE,KAAK,OAAA,EAAE,cAAc,gBAAA,EAAE,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,EAoBnC;QAnBC,cAAc,oBAAA,EACd,oBAAiB,EAAjB,YAAY,mBAAG,EAAE,KAAA,EACjB,KAAK,WAAA,EACL,KAAK,WAAA,EACL,KAAK,WAAA,EACL,OAAO,aAAA,EACP,WAAW,iBAAA,EACX,WAAW,iBAAA,EACX,UAAU,gBAAA;IAYV,OAAO;QACL,IAAI,EAAE,cAAc,GAAG,YAAY,IAAI,cAAc,GAAG,CAAC;QACzD,CAAC,EAAE,KAAK;QACR,CAAC,EAAE,KAAK;QACR,KAAK,OAAA;QACL,OAAO,SAAA;QACP,WAAW,aAAA;QACX,WAAW,aAAA;QACX,UAAU,YAAA;KACX,CAAC;AACJ,CAAC","sourcesContent":["import * as React from 'react';\nimport { IFunnelChartDataPoint } from './FunnelChart.types';\n\nexport interface IFunnelSegmentGeometry {\n pathD: string;\n textX: number;\n textY: number;\n availableWidth: number;\n}\n\nexport interface IStackedFunnelSegmentGeometry {\n pathD: string;\n textX: number;\n textY: number;\n availableWidth: number;\n}\n\ninterface ISubValue {\n category: string;\n value: number;\n color: string;\n}\n\ninterface IStage {\n subValues: ISubValue[];\n}\n\nexport function getVerticalFunnelSegmentGeometry({\n d,\n i,\n data,\n funnelWidth,\n funnelHeight,\n isRTL,\n}: {\n d: IFunnelChartDataPoint;\n i: number;\n data: IFunnelChartDataPoint[];\n funnelWidth: number;\n funnelHeight: number;\n isRTL: boolean;\n}): IFunnelSegmentGeometry {\n const segmentHeight = funnelHeight / data.length;\n const widthScale = (value: number) => (value / Math.max(...data.map(dataPoint => dataPoint.value!))) * funnelWidth;\n const topWidth = widthScale(d.value!);\n const bottomWidth = i < data.length - 1 ? widthScale(data[i + 1].value!) : 0;\n const xOffset = (funnelWidth - topWidth) / 2;\n const nextXOffset = (funnelWidth - bottomWidth) / 2;\n const xStart = isRTL ? funnelWidth - xOffset : xOffset;\n const xEnd = isRTL ? funnelWidth - nextXOffset : nextXOffset;\n\n const isLastSegment = i === data.length - 1;\n const textY = isLastSegment ? i * segmentHeight + segmentHeight * 0.33 : i * segmentHeight + segmentHeight / 2;\n\n const textX = funnelWidth / 2;\n let availableWidth = topWidth;\n if (isLastSegment) {\n const yFromTop = textY - i * segmentHeight;\n const widthAtY = topWidth * (1 - yFromTop / segmentHeight);\n availableWidth = Math.max(widthAtY * 0.8, 0);\n } else {\n availableWidth = Math.min(topWidth, bottomWidth) * 0.9;\n }\n const pathD = `M${xStart},${i * segmentHeight}\n L${funnelWidth - xStart},${i * segmentHeight}\n L${funnelWidth - xEnd},${(i + 1) * segmentHeight}\n L${xEnd},${(i + 1) * segmentHeight}\n Z`;\n return { pathD, textX, textY, availableWidth };\n}\n\nexport function getHorizontalFunnelSegmentGeometry({\n d,\n i,\n data,\n funnelWidth,\n funnelHeight,\n isRTL,\n}: {\n d: IFunnelChartDataPoint;\n i: number;\n data: IFunnelChartDataPoint[];\n funnelWidth: number;\n funnelHeight: number;\n isRTL: boolean;\n}): IFunnelSegmentGeometry {\n const segmentWidth = funnelWidth / data.length;\n const heightScale = (value: number) => (value / Math.max(...data.map(dataPoint => dataPoint.value!))) * funnelHeight;\n const leftHeight = heightScale(d.value!);\n const rightHeight = i < data.length - 1 ? heightScale(data[i + 1].value!) : 0;\n const yOffset = (funnelHeight - leftHeight) / 2;\n const nextYOffset = (funnelHeight - rightHeight) / 2;\n const x0 = i * segmentWidth;\n const x1 = (i + 1) * segmentWidth;\n\n const isLastSegment = i === data.length - 1;\n let textX: number;\n let textY: number;\n let availableWidth = segmentWidth * 0.8;\n\n if (isLastSegment) {\n // For the triangular last segment, position text at 1/4 from the left edge\n textX = x0 + (x1 - x0) * 0.25;\n textY = funnelHeight / 2;\n\n // For triangular segments, we need to check both height and width constraints\n // The segment needs to be large enough to contain text\n const segmentArea = (leftHeight * segmentWidth) / 2; // Area of triangle\n const minAreaForText = 800; // Minimum area needed to show text\n\n if (leftHeight < 40 || segmentArea < minAreaForText) {\n // Hide text if height is too small or area is insufficient\n availableWidth = 0;\n } else {\n // Calculate available width at text position\n const widthAtTextPosition = (x1 - x0) * 0.75;\n availableWidth = widthAtTextPosition * 0.6;\n }\n } else {\n textX = (x0 + x1) / 2;\n textY = funnelHeight / 2;\n const minHeight = Math.min(leftHeight, rightHeight);\n availableWidth = minHeight > 20 ? segmentWidth * 0.8 : 0;\n }\n\n const pathD = `M${x0},${yOffset}\n L${x1},${nextYOffset}\n L${x1},${funnelHeight - nextYOffset}\n L${x0},${funnelHeight - yOffset}\n Z`;\n return { pathD, textX, textY, availableWidth };\n}\n\nexport function getStackedVerticalFunnelSegmentGeometry({\n i,\n k,\n stages,\n totals,\n maxTotal,\n funnelWidth,\n funnelHeight,\n}: {\n i: number;\n k: number;\n stages: IStage[];\n totals: number[];\n maxTotal: number;\n funnelWidth: number;\n funnelHeight: number;\n}): IStackedFunnelSegmentGeometry {\n const segmentHeight = funnelHeight / stages.length;\n const cur = stages[i];\n const next = stages[i + 1] || { subValues: [] };\n const curTotal = totals[i] || 1;\n const nextTotal = totals[i + 1] || 0;\n\n let cumTop = 0;\n let cumBot = 0;\n for (let idx = 0; idx < k; idx++) {\n const v = cur.subValues[idx];\n const vNext = next.subValues?.find((x: ISubValue) => x.category === v.category);\n const val = v.value;\n const nextVal = vNext ? vNext.value : 0;\n cumTop += (val / curTotal) * (curTotal / maxTotal) * funnelWidth;\n cumBot += (nextVal / nextTotal || 0) * (nextTotal / maxTotal) * funnelWidth;\n }\n const v = cur.subValues[k];\n const vNext = next.subValues?.find((x: ISubValue) => x.category === v.category);\n const val = v.value;\n const nextVal = vNext ? vNext.value : 0;\n const topW = (val / curTotal) * (curTotal / maxTotal) * funnelWidth;\n const botW = (nextVal / nextTotal || 0) * (nextTotal / maxTotal) * funnelWidth;\n const topStart = (funnelWidth - (curTotal / maxTotal) * funnelWidth) / 2 + cumTop;\n const topEnd = topStart + topW;\n const botStart = (funnelWidth - (nextTotal / maxTotal) * funnelWidth) / 2 + cumBot;\n const botEnd = botStart + botW;\n const textX = (topStart + topEnd + botStart + botEnd) / 4;\n\n const isLastSegment = i === stages.length - 1;\n const textY = isLastSegment ? i * segmentHeight + segmentHeight * 0.33 : (i + 0.5) * segmentHeight;\n\n // Calculate available width based on this specific segment's width\n let availableWidth: number;\n if (isLastSegment) {\n // For triangular last segment, use the width at text Y position\n const yFromTop = textY - i * segmentHeight;\n const widthRatio = 1 - yFromTop / segmentHeight;\n availableWidth = topW * widthRatio;\n } else {\n // For trapezoidal segments, use the actual segment width\n availableWidth = Math.min(topW, botW);\n }\n\n const pathD = `M${topStart},${i * segmentHeight}\n L${topEnd},${i * segmentHeight}\n L${botEnd},${(i + 1) * segmentHeight}\n L${botStart},${(i + 1) * segmentHeight}\n Z`;\n return { pathD, textX, textY, availableWidth };\n}\n\nexport function getStackedHorizontalFunnelSegmentGeometry({\n i,\n k,\n stages,\n totals,\n maxTotal,\n funnelWidth,\n funnelHeight,\n}: {\n i: number;\n k: number;\n stages: IStage[];\n totals: number[];\n maxTotal: number;\n funnelWidth: number;\n funnelHeight: number;\n}): IStackedFunnelSegmentGeometry {\n const segmentWidth = funnelWidth / stages.length;\n const cur = stages[i];\n const next = stages[i + 1] || { subValues: [] };\n const curTotal = totals[i] || 1;\n const nextTotal = totals[i + 1] || 0;\n\n let cumTop = 0;\n let cumBot = 0;\n for (let idx = 0; idx < k; idx++) {\n const v = cur.subValues[idx];\n const vNext = next.subValues?.find((x: ISubValue) => x.category === v.category);\n const val = v.value;\n const nextVal = vNext ? vNext.value : 0;\n cumTop += (val / curTotal) * (curTotal / maxTotal) * funnelHeight;\n cumBot += (nextVal / nextTotal || 0) * (nextTotal / maxTotal) * funnelHeight;\n }\n const v = cur.subValues[k];\n const vNext = next.subValues?.find((x: ISubValue) => x.category === v.category);\n const val = v.value;\n const nextVal = vNext ? vNext.value : 0;\n const topH = (val / curTotal) * (curTotal / maxTotal) * funnelHeight;\n const botH = (nextVal / nextTotal || 0) * (nextTotal / maxTotal) * funnelHeight;\n const leftStart = i * segmentWidth;\n const leftEnd = (i + 1) * segmentWidth;\n const topStart = (funnelHeight - (curTotal / maxTotal) * funnelHeight) / 2 + cumTop;\n const topEnd = topStart + topH;\n const botStart = (funnelHeight - (nextTotal / maxTotal) * funnelHeight) / 2 + cumBot;\n const botEnd = botStart + botH;\n\n const isLastSegment = i === stages.length - 1;\n let textX: number;\n let textY: number;\n let availableWidth: number;\n\n if (isLastSegment) {\n textX = leftStart + (leftEnd - leftStart) * 0.25;\n textY = (topStart + topEnd) / 2;\n // For triangular segments, calculate available width at text position\n const segmentWidthAtTextPos = (leftEnd - leftStart) * 0.5;\n availableWidth = segmentWidthAtTextPos * 0.8;\n\n // For triangular last segments, also check if there's enough height\n // The segment area should be large enough to contain text\n const segmentArea = (topH * segmentWidth) / 2;\n if (topH < 24 || segmentArea < 600) {\n availableWidth = 0;\n }\n } else {\n textX = (leftStart + leftEnd) / 2;\n textY = (topStart + topEnd + botStart + botEnd) / 4;\n // For trapezoidal segments, use full segment width\n availableWidth = Math.abs(leftEnd - leftStart) * 0.9;\n\n // Check if the segment has sufficient height for text\n // For non-last segments, we need to ensure there's enough vertical space\n const avgHeight = (topH + botH) / 2;\n if (avgHeight < 20) {\n availableWidth = 0;\n }\n }\n\n const pathD = `M${leftStart},${topStart}\n L${leftEnd},${botStart}\n L${leftEnd},${botEnd}\n L${leftStart},${topEnd}\n Z`;\n return { pathD, textX, textY, availableWidth };\n}\n\nexport function getSegmentTextProps({\n availableWidth,\n minTextWidth = 24,\n textX,\n textY,\n value,\n culture,\n onMouseOver,\n onMouseMove,\n onMouseOut,\n}: {\n availableWidth: number;\n minTextWidth?: number;\n textX: number;\n textY: number;\n value: number;\n culture: string | undefined;\n onMouseOver: ((event: React.MouseEvent<SVGElement>) => void) | undefined;\n onMouseMove: ((event: React.MouseEvent<SVGElement>) => void) | undefined;\n onMouseOut: () => void;\n}) {\n return {\n show: availableWidth > minTextWidth && availableWidth > 0,\n x: textX,\n y: textY,\n value,\n culture,\n onMouseOver,\n onMouseMove,\n onMouseOut,\n };\n}\n"]}
|
|
@@ -3,7 +3,7 @@ import * as React from 'react';
|
|
|
3
3
|
import { select as d3Select } from 'd3-selection';
|
|
4
4
|
import { Legends } from '../Legends/index';
|
|
5
5
|
import { max as d3Max, min as d3Min } from 'd3-array';
|
|
6
|
-
import { areArraysEqual, createNumericYAxis, createStringYAxis, domainRangeOfDateForScatterChart, domainRangeOfNumericForScatterChart, domainRangeOfXStringAxis, findNumericMinMaxOfY, isScatterPolarSeries, } from '../../utilities/index';
|
|
6
|
+
import { areArraysEqual, createNumericYAxis, createStringYAxis, domainRangeOfDateForScatterChart, domainRangeOfNumericForScatterChart, domainRangeOfXStringAxis, findNumericMinMaxOfY, isScatterPolarSeries, isTextMode, } from '../../utilities/index';
|
|
7
7
|
import { CartesianChart, } from '../../index';
|
|
8
8
|
import { calloutData, ChartTypes, XAxisTypes, tooltipOfAxislabels, getTypeOfAxis, getNextColor, getColorFromToken, } from '../../utilities/index';
|
|
9
9
|
import { classNamesFunction, DirectionalHint, find, getId, getRTL } from '@fluentui/react';
|
|
@@ -54,6 +54,7 @@ export var ScatterChartBase = React.forwardRef(function (props, forwardedRef) {
|
|
|
54
54
|
var _m = React.useState(''), refSelected = _m[0], setRefSelected = _m[1];
|
|
55
55
|
var prevSelectedLegendsRef = React.useRef(undefined);
|
|
56
56
|
var _isScatterPolarRef = React.useRef(false);
|
|
57
|
+
var _isTextMode = React.useRef(false);
|
|
57
58
|
var classNames = getClassNames(props.styles, {
|
|
58
59
|
theme: props.theme,
|
|
59
60
|
});
|
|
@@ -341,13 +342,17 @@ export var ScatterChartBase = React.forwardRef(function (props, forwardedRef) {
|
|
|
341
342
|
var isLegendSelected = _legendHighlighted(legendVal) || _noLegendHighlighted() || isSelectedLegend;
|
|
342
343
|
var currentPointHidden = ((_s = (_r = _points.current) === null || _r === void 0 ? void 0 : _r[i]) === null || _s === void 0 ? void 0 : _s.hideNonActiveDots) && activePoint !== circleId;
|
|
343
344
|
var text = (_u = (_t = _points.current) === null || _t === void 0 ? void 0 : _t[i].data[j]) === null || _u === void 0 ? void 0 : _u.text;
|
|
344
|
-
|
|
345
|
-
React.createElement(
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
345
|
+
if (!_isTextMode.current) {
|
|
346
|
+
pointsForSeries.push(React.createElement(React.Fragment, null,
|
|
347
|
+
React.createElement("circle", __assign({ id: circleId, key: circleId, r: Math.max(circleRadius, 4), cx: ((_v = _xAxisScale.current) === null || _v === void 0 ? void 0 : _v.call(_xAxisScale, x)) + _xBandwidth.current, cy: (_w = _yAxisScale.current) === null || _w === void 0 ? void 0 : _w.call(_yAxisScale, y), "data-is-focusable": isLegendSelected, onMouseOver: function (event) {
|
|
348
|
+
return _handleHover(x, y, verticaLineHeight, xAxisCalloutData, circleId, xAxisCalloutAccessibilityData, event);
|
|
349
|
+
}, onMouseMove: function (event) {
|
|
350
|
+
return _handleHover(x, y, verticaLineHeight, xAxisCalloutData, circleId, xAxisCalloutAccessibilityData, event);
|
|
351
|
+
}, onMouseOut: _handleMouseOut, onFocus: function () { return _handleFocus(seriesId, x, xAxisCalloutData, circleId, xAxisCalloutAccessibilityData); }, onBlur: _handleMouseOut }, _getClickHandler((_z = (_y = (_x = _points.current) === null || _x === void 0 ? void 0 : _x[i]) === null || _y === void 0 ? void 0 : _y.data[j]) === null || _z === void 0 ? void 0 : _z.onDataPointClick), { opacity: isLegendSelected && !currentPointHidden ? 1 : 0.1, fill: _getPointFill(seriesColor, circleId), stroke: seriesColor, role: "img", "aria-label": _getAriaLabel(i, j), tabIndex: ((_1 = (_0 = _points.current) === null || _0 === void 0 ? void 0 : _0[i]) === null || _1 === void 0 ? void 0 : _1.legend) !== '' ? 0 : undefined }))));
|
|
352
|
+
}
|
|
353
|
+
if ((!_isScatterPolarRef.current || _isTextMode) && text) {
|
|
354
|
+
pointsForSeries.push(React.createElement("text", { key: "".concat(circleId, "-label"), x: ((_2 = _xAxisScale.current) === null || _2 === void 0 ? void 0 : _2.call(_xAxisScale, x)) + _xBandwidth.current, y: ((_3 = _yAxisScale.current) === null || _3 === void 0 ? void 0 : _3.call(_yAxisScale, y)) + Math.max(circleRadius + 12, 16), className: classNames.markerLabel }, text));
|
|
355
|
+
}
|
|
351
356
|
};
|
|
352
357
|
for (var j = 0; j < ((_l = (_k = (_j = _points.current) === null || _j === void 0 ? void 0 : _j[i]) === null || _k === void 0 ? void 0 : _k.data) === null || _l === void 0 ? void 0 : _l.length); j++) {
|
|
353
358
|
_loop_2(j);
|
|
@@ -422,6 +427,7 @@ export var ScatterChartBase = React.forwardRef(function (props, forwardedRef) {
|
|
|
422
427
|
_xAxisScale.current = xScale;
|
|
423
428
|
_yAxisScale.current = yScale;
|
|
424
429
|
_isScatterPolarRef.current = isScatterPolarSeries(_points.current);
|
|
430
|
+
_isTextMode.current = isTextMode(_points.current);
|
|
425
431
|
renderSeries.current = _createPlot(xElement, containerHeight);
|
|
426
432
|
}, [renderSeries, _xAxisScale, _yAxisScale, _createPlot]);
|
|
427
433
|
/**
|
|
@@ -470,7 +476,7 @@ export var ScatterChartBase = React.forwardRef(function (props, forwardedRef) {
|
|
|
470
476
|
// reduce computation cost by only creating legendBars
|
|
471
477
|
// if when hideLegend is false.
|
|
472
478
|
// NOTE: they are rendered only when hideLegend is false in CartesianChart.
|
|
473
|
-
if (!props.hideLegend) {
|
|
479
|
+
if (!props.hideLegend && !_isTextMode.current) {
|
|
474
480
|
legendBars = _createLegends(_points.current); // ToDo: Memoize legends to improve performance.
|
|
475
481
|
}
|
|
476
482
|
var calloutProps = __assign({ isCalloutVisible: isCalloutVisible, directionalHint: DirectionalHint.topAutoEdge, YValueHover: YValueHover, hoverXValue: hoverXValue, id: "toolTip".concat(_uniqueCallOutID.current), target: refSelected, isBeakVisible: false, gapSpace: 15, onDismiss: _closeCallout, preventDismissOnEvent: function () { return true; }, hidden: !(!props.hideTooltip && isCalloutVisible), descriptionMessage: props.getCalloutDescriptionMessage && stackCalloutProps
|