source: node_modules/recharts/lib/cartesian/Funnel.js@ ba17441

Last change on this file since ba17441 was a762898, checked in by istevanoska <ilinastevanoska@…>, 5 months ago

Added visualizations

  • Property mode set to 100644
File size: 18.7 KB
Line 
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.Funnel = Funnel;
7exports.computeFunnelTrapezoids = computeFunnelTrapezoids;
8exports.defaultFunnelProps = void 0;
9var _react = _interopRequireWildcard(require("react"));
10var React = _react;
11var _omit = _interopRequireDefault(require("es-toolkit/compat/omit"));
12var _clsx = require("clsx");
13var _selectors = require("../state/selectors/selectors");
14var _hooks = require("../state/hooks");
15var _Layer = require("../container/Layer");
16var _LabelList = require("../component/LabelList");
17var _DataUtils = require("../util/DataUtils");
18var _ChartUtils = require("../util/ChartUtils");
19var _types = require("../util/types");
20var _FunnelUtils = require("../util/FunnelUtils");
21var _tooltipContext = require("../context/tooltipContext");
22var _SetTooltipEntrySettings = require("../state/SetTooltipEntrySettings");
23var _funnelSelectors = require("../state/selectors/funnelSelectors");
24var _ReactUtils = require("../util/ReactUtils");
25var _Cell = require("../component/Cell");
26var _resolveDefaultProps2 = require("../util/resolveDefaultProps");
27var _hooks2 = require("../hooks");
28var _svgPropertiesNoEvents = require("../util/svgPropertiesNoEvents");
29var _JavascriptAnimate = require("../animation/JavascriptAnimate");
30var _useAnimationId = require("../util/useAnimationId");
31var _RegisterGraphicalItemId = require("../context/RegisterGraphicalItemId");
32var _excluded = ["onMouseEnter", "onClick", "onMouseLeave", "shape", "activeShape"],
33 _excluded2 = ["id"],
34 _excluded3 = ["stroke", "fill", "legendType", "hide", "isAnimationActive", "animationBegin", "animationDuration", "animationEasing", "nameKey", "lastShapeType", "id"],
35 _excluded4 = ["id"];
36function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
37function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
38function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
39function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
40function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
41function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
42function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
43function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
44function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
45function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
46/**
47 * Internal props, combination of external props + defaultProps + private Recharts state
48 */
49
50/**
51 * External props, intended for end users to fill in
52 */
53
54var SetFunnelTooltipEntrySettings = /*#__PURE__*/React.memo(_ref => {
55 var {
56 dataKey,
57 nameKey,
58 stroke,
59 strokeWidth,
60 fill,
61 name,
62 hide,
63 tooltipType,
64 data,
65 trapezoids,
66 id
67 } = _ref;
68 var tooltipEntrySettings = {
69 dataDefinedOnItem: data,
70 getPosition: index => {
71 var _trapezoids$Number;
72 return (_trapezoids$Number = trapezoids[Number(index)]) === null || _trapezoids$Number === void 0 ? void 0 : _trapezoids$Number.tooltipPosition;
73 },
74 settings: {
75 stroke,
76 strokeWidth,
77 fill,
78 dataKey,
79 name,
80 nameKey,
81 hide,
82 type: tooltipType,
83 color: fill,
84 unit: '',
85 // Funnel does not have unit, why?
86 graphicalItemId: id
87 }
88 };
89 return /*#__PURE__*/React.createElement(_SetTooltipEntrySettings.SetTooltipEntrySettings, {
90 tooltipEntrySettings: tooltipEntrySettings
91 });
92});
93function FunnelLabelListProvider(_ref2) {
94 var {
95 showLabels,
96 trapezoids,
97 children
98 } = _ref2;
99 var labelListEntries = (0, _react.useMemo)(() => {
100 if (!showLabels) {
101 return undefined;
102 }
103 return trapezoids === null || trapezoids === void 0 ? void 0 : trapezoids.map(entry => {
104 var viewBox = entry.labelViewBox;
105 return _objectSpread(_objectSpread({}, viewBox), {}, {
106 value: entry.name,
107 payload: entry.payload,
108 parentViewBox: entry.parentViewBox,
109 viewBox,
110 fill: entry.fill
111 });
112 });
113 }, [showLabels, trapezoids]);
114 return /*#__PURE__*/React.createElement(_LabelList.CartesianLabelListContextProvider, {
115 value: labelListEntries
116 }, children);
117}
118function FunnelTrapezoids(props) {
119 var {
120 trapezoids,
121 allOtherFunnelProps
122 } = props;
123 var activeItemIndex = (0, _hooks.useAppSelector)(state => (0, _selectors.selectActiveIndex)(state, 'item', state.tooltip.settings.trigger, undefined));
124 var {
125 onMouseEnter: onMouseEnterFromProps,
126 onClick: onItemClickFromProps,
127 onMouseLeave: onMouseLeaveFromProps,
128 shape,
129 activeShape
130 } = allOtherFunnelProps,
131 restOfAllOtherProps = _objectWithoutProperties(allOtherFunnelProps, _excluded);
132 var onMouseEnterFromContext = (0, _tooltipContext.useMouseEnterItemDispatch)(onMouseEnterFromProps, allOtherFunnelProps.dataKey, allOtherFunnelProps.id);
133 var onMouseLeaveFromContext = (0, _tooltipContext.useMouseLeaveItemDispatch)(onMouseLeaveFromProps);
134 var onClickFromContext = (0, _tooltipContext.useMouseClickItemDispatch)(onItemClickFromProps, allOtherFunnelProps.dataKey, allOtherFunnelProps.id);
135 return /*#__PURE__*/React.createElement(React.Fragment, null, trapezoids.map((entry, i) => {
136 var isActiveIndex = Boolean(activeShape) && activeItemIndex === String(i);
137 var trapezoidOptions = isActiveIndex ? activeShape : shape;
138 var _entry$option$isActiv = _objectSpread(_objectSpread({}, entry), {}, {
139 option: trapezoidOptions,
140 isActive: isActiveIndex,
141 stroke: entry.stroke
142 }),
143 {
144 id
145 } = _entry$option$isActiv,
146 trapezoidProps = _objectWithoutProperties(_entry$option$isActiv, _excluded2);
147 return /*#__PURE__*/React.createElement(_Layer.Layer, _extends({
148 key: "trapezoid-".concat(entry === null || entry === void 0 ? void 0 : entry.x, "-").concat(entry === null || entry === void 0 ? void 0 : entry.y, "-").concat(entry === null || entry === void 0 ? void 0 : entry.name, "-").concat(entry === null || entry === void 0 ? void 0 : entry.value),
149 className: "recharts-funnel-trapezoid"
150 }, (0, _types.adaptEventsOfChild)(restOfAllOtherProps, entry, i), {
151 // @ts-expect-error the types need a bit of attention
152 onMouseEnter: onMouseEnterFromContext(entry, i)
153 // @ts-expect-error the types need a bit of attention
154 ,
155 onMouseLeave: onMouseLeaveFromContext(entry, i)
156 // @ts-expect-error the types need a bit of attention
157 ,
158 onClick: onClickFromContext(entry, i)
159 }), /*#__PURE__*/React.createElement(_FunnelUtils.FunnelTrapezoid, trapezoidProps));
160 }));
161}
162function TrapezoidsWithAnimation(_ref3) {
163 var {
164 previousTrapezoidsRef,
165 props
166 } = _ref3;
167 var {
168 trapezoids,
169 isAnimationActive,
170 animationBegin,
171 animationDuration,
172 animationEasing,
173 onAnimationEnd,
174 onAnimationStart
175 } = props;
176 var prevTrapezoids = previousTrapezoidsRef.current;
177 var [isAnimating, setIsAnimating] = (0, _react.useState)(false);
178 var showLabels = !isAnimating;
179 var animationId = (0, _useAnimationId.useAnimationId)(trapezoids, 'recharts-funnel-');
180 var handleAnimationEnd = (0, _react.useCallback)(() => {
181 if (typeof onAnimationEnd === 'function') {
182 onAnimationEnd();
183 }
184 setIsAnimating(false);
185 }, [onAnimationEnd]);
186 var handleAnimationStart = (0, _react.useCallback)(() => {
187 if (typeof onAnimationStart === 'function') {
188 onAnimationStart();
189 }
190 setIsAnimating(true);
191 }, [onAnimationStart]);
192 return /*#__PURE__*/React.createElement(FunnelLabelListProvider, {
193 showLabels: showLabels,
194 trapezoids: trapezoids
195 }, /*#__PURE__*/React.createElement(_JavascriptAnimate.JavascriptAnimate, {
196 animationId: animationId,
197 begin: animationBegin,
198 duration: animationDuration,
199 isActive: isAnimationActive,
200 easing: animationEasing,
201 key: animationId,
202 onAnimationStart: handleAnimationStart,
203 onAnimationEnd: handleAnimationEnd
204 }, t => {
205 var stepData = t === 1 ? trapezoids : trapezoids.map((entry, index) => {
206 var prev = prevTrapezoids && prevTrapezoids[index];
207 if (prev) {
208 return _objectSpread(_objectSpread({}, entry), {}, {
209 x: (0, _DataUtils.interpolate)(prev.x, entry.x, t),
210 y: (0, _DataUtils.interpolate)(prev.y, entry.y, t),
211 upperWidth: (0, _DataUtils.interpolate)(prev.upperWidth, entry.upperWidth, t),
212 lowerWidth: (0, _DataUtils.interpolate)(prev.lowerWidth, entry.lowerWidth, t),
213 height: (0, _DataUtils.interpolate)(prev.height, entry.height, t)
214 });
215 }
216 return _objectSpread(_objectSpread({}, entry), {}, {
217 x: (0, _DataUtils.interpolate)(entry.x + entry.upperWidth / 2, entry.x, t),
218 y: (0, _DataUtils.interpolate)(entry.y + entry.height / 2, entry.y, t),
219 upperWidth: (0, _DataUtils.interpolate)(0, entry.upperWidth, t),
220 lowerWidth: (0, _DataUtils.interpolate)(0, entry.lowerWidth, t),
221 height: (0, _DataUtils.interpolate)(0, entry.height, t)
222 });
223 });
224 if (t > 0) {
225 // eslint-disable-next-line no-param-reassign
226 previousTrapezoidsRef.current = stepData;
227 }
228 return /*#__PURE__*/React.createElement(_Layer.Layer, null, /*#__PURE__*/React.createElement(FunnelTrapezoids, {
229 trapezoids: stepData,
230 allOtherFunnelProps: props
231 }));
232 }), /*#__PURE__*/React.createElement(_LabelList.LabelListFromLabelProp, {
233 label: props.label
234 }), props.children);
235}
236function RenderTrapezoids(props) {
237 var previousTrapezoidsRef = (0, _react.useRef)(undefined);
238 return /*#__PURE__*/React.createElement(TrapezoidsWithAnimation, {
239 props: props,
240 previousTrapezoidsRef: previousTrapezoidsRef
241 });
242}
243var getRealWidthHeight = (customWidth, offset) => {
244 var {
245 width,
246 height,
247 left,
248 top
249 } = offset;
250 var realWidth = (0, _DataUtils.getPercentValue)(customWidth, width, width);
251 return {
252 realWidth,
253 realHeight: height,
254 offsetX: left,
255 offsetY: top
256 };
257};
258var defaultFunnelProps = exports.defaultFunnelProps = {
259 animationBegin: 400,
260 animationDuration: 1500,
261 animationEasing: 'ease',
262 fill: '#808080',
263 hide: false,
264 isAnimationActive: 'auto',
265 lastShapeType: 'triangle',
266 legendType: 'rect',
267 nameKey: 'name',
268 reversed: false,
269 stroke: '#fff'
270};
271function FunnelImpl(props) {
272 var plotArea = (0, _hooks2.usePlotArea)();
273 var {
274 stroke,
275 fill,
276 legendType,
277 hide,
278 isAnimationActive,
279 animationBegin,
280 animationDuration,
281 animationEasing,
282 nameKey,
283 lastShapeType,
284 id
285 } = props,
286 everythingElse = _objectWithoutProperties(props, _excluded3);
287 var presentationProps = (0, _svgPropertiesNoEvents.svgPropertiesNoEvents)(props);
288 var cells = (0, _ReactUtils.findAllByType)(props.children, _Cell.Cell);
289 var funnelSettings = (0, _react.useMemo)(() => ({
290 dataKey: props.dataKey,
291 nameKey,
292 data: props.data,
293 tooltipType: props.tooltipType,
294 lastShapeType,
295 reversed: props.reversed,
296 customWidth: props.width,
297 cells,
298 presentationProps,
299 id
300 }), [props.dataKey, nameKey, props.data, props.tooltipType, lastShapeType, props.reversed, props.width, cells, presentationProps, id]);
301 var trapezoids = (0, _hooks.useAppSelector)(state => (0, _funnelSelectors.selectFunnelTrapezoids)(state, funnelSettings));
302 if (hide || !trapezoids || !trapezoids.length || !plotArea) {
303 return null;
304 }
305 var {
306 height,
307 width
308 } = plotArea;
309 var layerClass = (0, _clsx.clsx)('recharts-trapezoids', props.className);
310 return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(SetFunnelTooltipEntrySettings, {
311 dataKey: props.dataKey,
312 nameKey: props.nameKey,
313 stroke: props.stroke,
314 strokeWidth: props.strokeWidth,
315 fill: props.fill,
316 name: props.name,
317 hide: props.hide,
318 tooltipType: props.tooltipType,
319 data: props.data,
320 trapezoids: trapezoids,
321 id: id
322 }), /*#__PURE__*/React.createElement(_Layer.Layer, {
323 className: layerClass
324 }, /*#__PURE__*/React.createElement(RenderTrapezoids, _extends({}, everythingElse, {
325 id: id,
326 stroke: stroke,
327 fill: fill,
328 nameKey: nameKey,
329 lastShapeType: lastShapeType,
330 animationBegin: animationBegin,
331 animationDuration: animationDuration,
332 animationEasing: animationEasing,
333 isAnimationActive: isAnimationActive,
334 hide: hide,
335 legendType: legendType,
336 height: height,
337 width: width,
338 trapezoids: trapezoids
339 }))));
340}
341function computeFunnelTrapezoids(_ref4) {
342 var {
343 dataKey,
344 nameKey,
345 displayedData,
346 tooltipType,
347 lastShapeType,
348 reversed,
349 offset,
350 customWidth,
351 graphicalItemId
352 } = _ref4;
353 var {
354 realHeight,
355 realWidth,
356 offsetX,
357 offsetY
358 } = getRealWidthHeight(customWidth, offset);
359 var values = displayedData.map(entry => {
360 var val = (0, _ChartUtils.getValueByDataKey)(entry, dataKey, 0);
361 return typeof val === 'number' ? val : 0;
362 });
363 var maxValue = Math.max.apply(null, values);
364 var len = displayedData.length;
365 var rowHeight = realHeight / len;
366 var parentViewBox = {
367 x: offset.left,
368 y: offset.top,
369 width: offset.width,
370 height: offset.height
371 };
372 var trapezoids = displayedData.map((entry, i) => {
373 // @ts-expect-error getValueByDataKey does not validate the output type
374 var rawVal = (0, _ChartUtils.getValueByDataKey)(entry, dataKey, 0);
375 var name = String((0, _ChartUtils.getValueByDataKey)(entry, nameKey, i));
376 var val = rawVal;
377 var nextVal;
378 if (i !== len - 1) {
379 var nextDataValue = (0, _ChartUtils.getValueByDataKey)(displayedData[i + 1], dataKey, 0);
380 if (typeof nextDataValue === 'number') {
381 nextVal = nextDataValue;
382 } else if (Array.isArray(nextDataValue)) {
383 var [first, second] = nextDataValue;
384 if (typeof first === 'number') {
385 val = first;
386 }
387 if (typeof second === 'number') {
388 nextVal = second;
389 }
390 }
391 } else if (rawVal instanceof Array && rawVal.length === 2) {
392 var [_first, _second] = rawVal;
393 if (typeof _first === 'number') {
394 val = _first;
395 }
396 if (typeof _second === 'number') {
397 nextVal = _second;
398 }
399 } else if (lastShapeType === 'rectangle') {
400 nextVal = val;
401 } else {
402 nextVal = 0;
403 }
404
405 // @ts-expect-error this is a problem if we have ranged values because `val` can be an array
406 var x = (maxValue - val) * realWidth / (2 * maxValue) + offsetX;
407 var y = rowHeight * i + offsetY;
408 // @ts-expect-error getValueByDataKey does not validate the output type
409 var upperWidth = val / maxValue * realWidth;
410 // @ts-expect-error nextVal could be an array
411 var lowerWidth = nextVal / maxValue * realWidth;
412 var tooltipPayload = [{
413 name,
414 value: val,
415 payload: entry,
416 dataKey,
417 type: tooltipType,
418 graphicalItemId
419 }];
420 var tooltipPosition = {
421 x: x + upperWidth / 2,
422 y: y + rowHeight / 2
423 };
424 var trapezoidViewBox = {
425 x,
426 y,
427 upperWidth,
428 lowerWidth,
429 width: Math.max(upperWidth, lowerWidth),
430 height: rowHeight
431 };
432 return _objectSpread(_objectSpread(_objectSpread({}, trapezoidViewBox), {}, {
433 name,
434 val,
435 tooltipPayload,
436 tooltipPosition
437 }, entry != null && typeof entry === 'object' ? (0, _omit.default)(entry, ['width']) : {}), {}, {
438 payload: entry,
439 parentViewBox,
440 labelViewBox: trapezoidViewBox
441 });
442 });
443 if (reversed) {
444 trapezoids = trapezoids.map((entry, index) => {
445 var reversedViewBox = {
446 x: entry.x - (entry.lowerWidth - entry.upperWidth) / 2,
447 y: entry.y - index * rowHeight + (len - 1 - index) * rowHeight,
448 upperWidth: entry.lowerWidth,
449 lowerWidth: entry.upperWidth,
450 width: Math.max(entry.lowerWidth, entry.upperWidth),
451 height: rowHeight
452 };
453 return _objectSpread(_objectSpread(_objectSpread({}, entry), reversedViewBox), {}, {
454 tooltipPosition: _objectSpread(_objectSpread({}, entry.tooltipPosition), {}, {
455 y: entry.y - index * rowHeight + (len - 1 - index) * rowHeight + rowHeight / 2
456 }),
457 labelViewBox: reversedViewBox
458 });
459 });
460 }
461 return trapezoids;
462}
463
464/**
465 * @consumes CartesianViewBoxContext
466 * @provides LabelListContext
467 * @provides CellReader
468 */
469function Funnel(outsideProps) {
470 var _resolveDefaultProps = (0, _resolveDefaultProps2.resolveDefaultProps)(outsideProps, defaultFunnelProps),
471 {
472 id: externalId
473 } = _resolveDefaultProps,
474 props = _objectWithoutProperties(_resolveDefaultProps, _excluded4);
475 return /*#__PURE__*/React.createElement(_RegisterGraphicalItemId.RegisterGraphicalItemId, {
476 id: externalId,
477 type: "funnel"
478 }, id => /*#__PURE__*/React.createElement(FunnelImpl, _extends({}, props, {
479 id: id
480 })));
481}
482Funnel.displayName = 'Funnel';
Note: See TracBrowser for help on using the repository browser.