source: node_modules/recharts/es6/chart/Treemap.js

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

Added visualizations

  • Property mode set to 100644
File size: 27.4 KB
Line 
1var _excluded = ["width", "height", "className", "style", "children", "type"];
2function _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; }
3function _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; }
4function _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); }
5function 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; }
6function _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; }
7function _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; }
8function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
9function _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); }
10import * as React from 'react';
11import { PureComponent, useCallback, useState } from 'react';
12import omit from 'es-toolkit/compat/omit';
13import get from 'es-toolkit/compat/get';
14import { Layer } from '../container/Layer';
15import { Surface } from '../container/Surface';
16import { Polygon } from '../shape/Polygon';
17import { Rectangle } from '../shape/Rectangle';
18import { getValueByDataKey } from '../util/ChartUtils';
19import { COLOR_PANEL } from '../util/Constants';
20import { isNan, noop, uniqueId } from '../util/DataUtils';
21import { getStringSize } from '../util/DOMUtils';
22import { ReportChartMargin, useChartHeight, useChartWidth } from '../context/chartLayoutContext';
23import { TooltipPortalContext } from '../context/tooltipPortalContext';
24import { RechartsWrapper } from './RechartsWrapper';
25import { setActiveClickItemIndex, setActiveMouseOverItemIndex } from '../state/tooltipSlice';
26import { SetTooltipEntrySettings } from '../state/SetTooltipEntrySettings';
27import { RechartsStoreProvider } from '../state/RechartsStoreProvider';
28import { useAppDispatch } from '../state/hooks';
29import { isPositiveNumber } from '../util/isWellBehavedNumber';
30import { svgPropertiesNoEvents } from '../util/svgPropertiesNoEvents';
31import { CSSTransitionAnimate } from '../animation/CSSTransitionAnimate';
32import { resolveDefaultProps } from '../util/resolveDefaultProps';
33import { RegisterGraphicalItemId } from '../context/RegisterGraphicalItemId';
34var NODE_VALUE_KEY = 'value';
35
36/**
37 * This is what end users defines as `data` on Treemap.
38 */
39
40/**
41 * This is what is returned from `squarify`, the final treemap data structure
42 * that gets rendered and is stored in
43 */
44
45function isTreemapNode(value) {
46 return value != null && typeof value === 'object' && 'x' in value && 'y' in value && 'width' in value && 'height' in value && typeof value.x === 'number' && typeof value.y === 'number' && typeof value.width === 'number' && typeof value.height === 'number';
47}
48export var treemapPayloadSearcher = (data, activeIndex) => {
49 if (!data || !activeIndex) {
50 return undefined;
51 }
52 return get(data, activeIndex);
53};
54export var addToTreemapNodeIndex = function addToTreemapNodeIndex(indexInChildrenArr) {
55 var activeTooltipIndexSoFar = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
56 return "".concat(activeTooltipIndexSoFar, "children[").concat(indexInChildrenArr, "]");
57};
58var options = {
59 chartName: 'Treemap',
60 defaultTooltipEventType: 'item',
61 validateTooltipEventTypes: ['item'],
62 tooltipPayloadSearcher: treemapPayloadSearcher,
63 eventEmitter: undefined
64};
65export var computeNode = _ref => {
66 var {
67 depth,
68 node,
69 index,
70 dataKey,
71 nameKey,
72 nestedActiveTooltipIndex
73 } = _ref;
74 var currentTooltipIndex = depth === 0 ? '' : addToTreemapNodeIndex(index, nestedActiveTooltipIndex);
75 var {
76 children
77 } = node;
78 var childDepth = depth + 1;
79 var computedChildren = children && children.length ? children.map((child, i) => computeNode({
80 depth: childDepth,
81 node: child,
82 index: i,
83 dataKey,
84 nameKey,
85 nestedActiveTooltipIndex: currentTooltipIndex
86 })) : null;
87 var nodeValue;
88 if (computedChildren && computedChildren.length) {
89 nodeValue = computedChildren.reduce((result, child) => result + child.value, 0);
90 } else {
91 // TODO need to verify dataKey
92 var rawNodeValue = node[dataKey];
93 var numericValue = typeof rawNodeValue === 'number' ? rawNodeValue : 0;
94 nodeValue = isNan(numericValue) || numericValue <= 0 ? 0 : numericValue;
95 }
96 return _objectSpread(_objectSpread({}, node), {}, {
97 children: computedChildren,
98 // @ts-expect-error getValueByDataKey does not validate the output type
99 name: getValueByDataKey(node, nameKey, ''),
100 [NODE_VALUE_KEY]: nodeValue,
101 depth,
102 index,
103 tooltipIndex: currentTooltipIndex
104 });
105};
106var filterRect = node => ({
107 x: node.x,
108 y: node.y,
109 width: node.width,
110 height: node.height
111});
112// Compute the area for each child based on value & scale.
113var getAreaOfChildren = (children, areaValueRatio) => {
114 var ratio = areaValueRatio < 0 ? 0 : areaValueRatio;
115 return children.map(child => {
116 var area = child[NODE_VALUE_KEY] * ratio;
117 return _objectSpread(_objectSpread({}, child), {}, {
118 area: isNan(area) || area <= 0 ? 0 : area
119 });
120 });
121};
122
123// Computes the score for the specified row, as the worst aspect ratio.
124var getWorstScore = (row, parentSize, aspectRatio) => {
125 var parentArea = parentSize * parentSize;
126 var rowArea = row.area * row.area;
127 var {
128 min,
129 max
130 } = row.reduce((result, child) => ({
131 min: Math.min(result.min, child.area),
132 max: Math.max(result.max, child.area)
133 }), {
134 min: Infinity,
135 max: 0
136 });
137 return rowArea ? Math.max(parentArea * max * aspectRatio / rowArea, rowArea / (parentArea * min * aspectRatio)) : Infinity;
138};
139var horizontalPosition = (row, parentSize, parentRect, isFlush) => {
140 var rowHeight = parentSize ? Math.round(row.area / parentSize) : 0;
141 if (isFlush || rowHeight > parentRect.height) {
142 rowHeight = parentRect.height;
143 }
144 var curX = parentRect.x;
145 var child;
146 for (var i = 0, len = row.length; i < len; i++) {
147 child = row[i];
148 if (child == null) {
149 continue;
150 }
151 child.x = curX;
152 child.y = parentRect.y;
153 child.height = rowHeight;
154 child.width = Math.min(rowHeight ? Math.round(child.area / rowHeight) : 0, parentRect.x + parentRect.width - curX);
155 curX += child.width;
156 }
157 // add the remain x to the last one of row
158 if (child != null) {
159 child.width += parentRect.x + parentRect.width - curX;
160 }
161 return _objectSpread(_objectSpread({}, parentRect), {}, {
162 y: parentRect.y + rowHeight,
163 height: parentRect.height - rowHeight
164 });
165};
166var verticalPosition = (row, parentSize, parentRect, isFlush) => {
167 var rowWidth = parentSize ? Math.round(row.area / parentSize) : 0;
168 if (isFlush || rowWidth > parentRect.width) {
169 rowWidth = parentRect.width;
170 }
171 var curY = parentRect.y;
172 var child;
173 for (var i = 0, len = row.length; i < len; i++) {
174 child = row[i];
175 if (child == null) {
176 continue;
177 }
178 child.x = parentRect.x;
179 child.y = curY;
180 child.width = rowWidth;
181 child.height = Math.min(rowWidth ? Math.round(child.area / rowWidth) : 0, parentRect.y + parentRect.height - curY);
182 curY += child.height;
183 }
184 if (child) {
185 child.height += parentRect.y + parentRect.height - curY;
186 }
187 return _objectSpread(_objectSpread({}, parentRect), {}, {
188 x: parentRect.x + rowWidth,
189 width: parentRect.width - rowWidth
190 });
191};
192var position = (row, parentSize, parentRect, isFlush) => {
193 if (parentSize === parentRect.width) {
194 return horizontalPosition(row, parentSize, parentRect, isFlush);
195 }
196 return verticalPosition(row, parentSize, parentRect, isFlush);
197};
198// Recursively arranges the specified node's children into squarified rows.
199var squarify = (node, aspectRatio) => {
200 var {
201 children
202 } = node;
203 if (children && children.length) {
204 var rect = filterRect(node);
205 // @ts-expect-error we can't create an array with static property on a single line so typescript will complain.
206 var row = [];
207 var best = Infinity; // the best row score so far
208 var child, score; // the current row score
209 var size = Math.min(rect.width, rect.height); // initial orientation
210 var scaleChildren = getAreaOfChildren(children, rect.width * rect.height / node[NODE_VALUE_KEY]);
211 var tempChildren = scaleChildren.slice();
212
213 // why are we setting static properties on an array?
214 row.area = 0;
215 while (tempChildren.length > 0) {
216 [child] = tempChildren;
217 if (child == null) {
218 continue;
219 }
220 // row first
221 row.push(child);
222 row.area += child.area;
223 score = getWorstScore(row, size, aspectRatio);
224 if (score <= best) {
225 // continue with this orientation
226 tempChildren.shift();
227 best = score;
228 } else {
229 var _row$pop$area, _row$pop;
230 // abort, and try a different orientation
231 row.area -= (_row$pop$area = (_row$pop = row.pop()) === null || _row$pop === void 0 ? void 0 : _row$pop.area) !== null && _row$pop$area !== void 0 ? _row$pop$area : 0;
232 rect = position(row, size, rect, false);
233 size = Math.min(rect.width, rect.height);
234 row.length = row.area = 0;
235 best = Infinity;
236 }
237 }
238 if (row.length) {
239 rect = position(row, size, rect, true);
240 row.length = row.area = 0;
241 }
242 return _objectSpread(_objectSpread({}, node), {}, {
243 children: scaleChildren.map(c => squarify(c, aspectRatio))
244 });
245 }
246 return node;
247};
248export var defaultTreeMapProps = {
249 aspectRatio: 0.5 * (1 + Math.sqrt(5)),
250 dataKey: 'value',
251 nameKey: 'name',
252 type: 'flat',
253 isAnimationActive: 'auto',
254 isUpdateAnimationActive: 'auto',
255 animationBegin: 0,
256 animationDuration: 1500,
257 animationEasing: 'linear'
258};
259var defaultState = {
260 isAnimationFinished: false,
261 formatRoot: null,
262 currentRoot: undefined,
263 nestIndex: [],
264 prevAspectRatio: defaultTreeMapProps.aspectRatio,
265 prevDataKey: defaultTreeMapProps.dataKey
266};
267function ContentItem(_ref2) {
268 var {
269 content,
270 nodeProps,
271 type,
272 colorPanel,
273 onMouseEnter,
274 onMouseLeave,
275 onClick
276 } = _ref2;
277 if (/*#__PURE__*/React.isValidElement(content)) {
278 return /*#__PURE__*/React.createElement(Layer, {
279 onMouseEnter: onMouseEnter,
280 onMouseLeave: onMouseLeave,
281 onClick: onClick
282 }, /*#__PURE__*/React.cloneElement(content, nodeProps));
283 }
284 if (typeof content === 'function') {
285 return /*#__PURE__*/React.createElement(Layer, {
286 onMouseEnter: onMouseEnter,
287 onMouseLeave: onMouseLeave,
288 onClick: onClick
289 }, content(nodeProps));
290 }
291 // optimize default shape
292 var {
293 x,
294 y,
295 width,
296 height,
297 index
298 } = nodeProps;
299 var arrow = null;
300 if (width > 10 && height > 10 && nodeProps.children && type === 'nest') {
301 arrow = /*#__PURE__*/React.createElement(Polygon, {
302 points: [{
303 x: x + 2,
304 y: y + height / 2
305 }, {
306 x: x + 6,
307 y: y + height / 2 + 3
308 }, {
309 x: x + 2,
310 y: y + height / 2 + 6
311 }]
312 });
313 }
314 var text = null;
315 var nameSize = getStringSize(nodeProps.name);
316 if (width > 20 && height > 20 && nameSize.width < width && nameSize.height < height) {
317 text = /*#__PURE__*/React.createElement("text", {
318 x: x + 8,
319 y: y + height / 2 + 7,
320 fontSize: 14
321 }, nodeProps.name);
322 }
323 var colors = colorPanel || COLOR_PANEL;
324 return /*#__PURE__*/React.createElement("g", null, /*#__PURE__*/React.createElement(Rectangle, _extends({
325 fill: nodeProps.depth < 2 ? colors[index % colors.length] : 'rgba(255,255,255,0)',
326 stroke: "#fff"
327 }, omit(nodeProps, ['children']), {
328 onMouseEnter: onMouseEnter,
329 onMouseLeave: onMouseLeave,
330 onClick: onClick,
331 "data-recharts-item-index": nodeProps.tooltipIndex
332 })), arrow, text);
333}
334function ContentItemWithEvents(props) {
335 var dispatch = useAppDispatch();
336 var activeCoordinate = {
337 x: props.nodeProps.x + props.nodeProps.width / 2,
338 y: props.nodeProps.y + props.nodeProps.height / 2
339 };
340 var onMouseEnter = () => {
341 dispatch(setActiveMouseOverItemIndex({
342 activeIndex: props.nodeProps.tooltipIndex,
343 activeDataKey: props.dataKey,
344 activeCoordinate,
345 activeGraphicalItemId: props.id
346 }));
347 };
348 var onMouseLeave = () => {
349 // clearing state on mouseLeaveItem causes re-rendering issues
350 // we don't actually want to do this for TreeMap - we clear state when we leave the entire chart instead
351 };
352 var onClick = () => {
353 dispatch(setActiveClickItemIndex({
354 activeIndex: props.nodeProps.tooltipIndex,
355 activeDataKey: props.dataKey,
356 activeCoordinate,
357 activeGraphicalItemId: props.id
358 }));
359 };
360 return /*#__PURE__*/React.createElement(ContentItem, _extends({}, props, {
361 onMouseEnter: onMouseEnter,
362 onMouseLeave: onMouseLeave,
363 onClick: onClick
364 }));
365}
366var SetTreemapTooltipEntrySettings = /*#__PURE__*/React.memo(_ref3 => {
367 var {
368 dataKey,
369 nameKey,
370 stroke,
371 fill,
372 currentRoot,
373 id
374 } = _ref3;
375 var tooltipEntrySettings = {
376 dataDefinedOnItem: currentRoot,
377 getPosition: noop,
378 // TODO I think Treemap has the capability of computing positions and supporting defaultIndex? Except it doesn't yet
379 settings: {
380 stroke,
381 strokeWidth: undefined,
382 fill,
383 dataKey,
384 nameKey,
385 name: undefined,
386 // Each TreemapNode has its own name
387 hide: false,
388 type: undefined,
389 color: fill,
390 unit: '',
391 graphicalItemId: id
392 }
393 };
394 return /*#__PURE__*/React.createElement(SetTooltipEntrySettings, {
395 tooltipEntrySettings: tooltipEntrySettings
396 });
397});
398
399// Why is margin not a treemap prop? No clue. Probably it should be
400var defaultTreemapMargin = {
401 top: 0,
402 right: 0,
403 bottom: 0,
404 left: 0
405};
406function TreemapItem(_ref4) {
407 var {
408 content,
409 nodeProps,
410 isLeaf,
411 treemapProps,
412 onNestClick
413 } = _ref4;
414 var {
415 id,
416 isAnimationActive,
417 animationBegin,
418 animationDuration,
419 animationEasing,
420 isUpdateAnimationActive,
421 type,
422 colorPanel,
423 dataKey,
424 onAnimationStart,
425 onAnimationEnd,
426 onMouseEnter: onMouseEnterFromProps,
427 onClick: onItemClickFromProps,
428 onMouseLeave: onMouseLeaveFromProps
429 } = treemapProps;
430 var {
431 width,
432 height,
433 x,
434 y
435 } = nodeProps;
436 var translateX = -x - width;
437 var translateY = 0;
438 var onMouseEnter = e => {
439 if ((isLeaf || type === 'nest') && typeof onMouseEnterFromProps === 'function') {
440 onMouseEnterFromProps(nodeProps, e);
441 }
442 };
443 var onMouseLeave = e => {
444 if ((isLeaf || type === 'nest') && typeof onMouseLeaveFromProps === 'function') {
445 onMouseLeaveFromProps(nodeProps, e);
446 }
447 };
448 var onClick = () => {
449 if (type === 'nest') {
450 onNestClick(nodeProps);
451 }
452 if ((isLeaf || type === 'nest') && typeof onItemClickFromProps === 'function') {
453 onItemClickFromProps(nodeProps);
454 }
455 };
456 var handleAnimationEnd = useCallback(() => {
457 if (typeof onAnimationEnd === 'function') {
458 onAnimationEnd();
459 }
460 }, [onAnimationEnd]);
461 var handleAnimationStart = useCallback(() => {
462 if (typeof onAnimationStart === 'function') {
463 onAnimationStart();
464 }
465 }, [onAnimationStart]);
466 return /*#__PURE__*/React.createElement(CSSTransitionAnimate, {
467 animationId: "treemap-".concat(nodeProps.tooltipIndex),
468 from: "translate(".concat(translateX, "px, ").concat(translateY, "px)"),
469 to: "translate(0, 0)",
470 attributeName: "transform",
471 begin: animationBegin,
472 easing: animationEasing,
473 isActive: isAnimationActive,
474 duration: animationDuration,
475 onAnimationStart: handleAnimationStart,
476 onAnimationEnd: handleAnimationEnd
477 }, style => /*#__PURE__*/React.createElement(Layer, {
478 onMouseEnter: onMouseEnter,
479 onMouseLeave: onMouseLeave,
480 onClick: onClick,
481 style: _objectSpread(_objectSpread({}, style), {}, {
482 transformOrigin: "".concat(x, " ").concat(y)
483 })
484 }, /*#__PURE__*/React.createElement(ContentItemWithEvents, {
485 id: id,
486 content: content,
487 dataKey: dataKey,
488 nodeProps: _objectSpread(_objectSpread({}, nodeProps), {}, {
489 isAnimationActive,
490 isUpdateAnimationActive: !isUpdateAnimationActive,
491 width,
492 height,
493 x,
494 y
495 }),
496 type: type,
497 colorPanel: colorPanel
498 })));
499}
500class TreemapWithState extends PureComponent {
501 constructor() {
502 super(...arguments);
503 _defineProperty(this, "state", _objectSpread({}, defaultState));
504 _defineProperty(this, "handleClick", node => {
505 var {
506 onClick,
507 type
508 } = this.props;
509 if (type === 'nest' && node.children) {
510 var {
511 width,
512 height,
513 dataKey,
514 nameKey,
515 aspectRatio
516 } = this.props;
517 var root = computeNode({
518 depth: 0,
519 node: _objectSpread(_objectSpread({}, node), {}, {
520 x: 0,
521 y: 0,
522 width,
523 height
524 }),
525 index: 0,
526 dataKey,
527 nameKey,
528 // with Treemap nesting, should this continue nesting the index or start from empty string?
529 nestedActiveTooltipIndex: node.tooltipIndex
530 });
531 var formatRoot = squarify(root, aspectRatio);
532 var {
533 nestIndex
534 } = this.state;
535 nestIndex.push(node);
536 this.setState({
537 formatRoot,
538 currentRoot: root,
539 nestIndex
540 });
541 }
542 if (onClick) {
543 onClick(node);
544 }
545 });
546 _defineProperty(this, "handleTouchMove", e => {
547 var touchEvent = e.touches[0];
548 if (touchEvent == null) {
549 return;
550 }
551 var target = document.elementFromPoint(touchEvent.clientX, touchEvent.clientY);
552 if (!target || !target.getAttribute || this.state.formatRoot == null) {
553 return;
554 }
555 var itemIndex = target.getAttribute('data-recharts-item-index');
556 var activeNode = treemapPayloadSearcher(this.state.formatRoot, itemIndex);
557 if (!isTreemapNode(activeNode)) {
558 return;
559 }
560 var {
561 dataKey,
562 dispatch
563 } = this.props;
564 var activeCoordinate = {
565 x: activeNode.x + activeNode.width / 2,
566 y: activeNode.y + activeNode.height / 2
567 };
568
569 // Treemap does not support onTouchMove prop, but it could
570 // onTouchMove?.(activeNode, Number(itemIndex), e);
571 dispatch(setActiveMouseOverItemIndex({
572 activeIndex: itemIndex,
573 activeDataKey: dataKey,
574 activeCoordinate,
575 activeGraphicalItemId: this.props.id
576 }));
577 });
578 }
579 static getDerivedStateFromProps(nextProps, prevState) {
580 if (nextProps.data !== prevState.prevData || nextProps.type !== prevState.prevType || nextProps.width !== prevState.prevWidth || nextProps.height !== prevState.prevHeight || nextProps.dataKey !== prevState.prevDataKey || nextProps.aspectRatio !== prevState.prevAspectRatio) {
581 var root = computeNode({
582 depth: 0,
583 // @ts-expect-error missing properties
584 node: {
585 children: nextProps.data,
586 x: 0,
587 y: 0,
588 width: nextProps.width,
589 height: nextProps.height
590 },
591 index: 0,
592 dataKey: nextProps.dataKey,
593 nameKey: nextProps.nameKey
594 });
595 var formatRoot = squarify(root, nextProps.aspectRatio);
596 return _objectSpread(_objectSpread({}, prevState), {}, {
597 formatRoot,
598 currentRoot: root,
599 nestIndex: [root],
600 prevAspectRatio: nextProps.aspectRatio,
601 prevData: nextProps.data,
602 prevWidth: nextProps.width,
603 prevHeight: nextProps.height,
604 prevDataKey: nextProps.dataKey,
605 prevType: nextProps.type
606 });
607 }
608 return null;
609 }
610 handleNestIndex(node, i) {
611 var {
612 nestIndex
613 } = this.state;
614 var {
615 width,
616 height,
617 dataKey,
618 nameKey,
619 aspectRatio
620 } = this.props;
621 var root = computeNode({
622 depth: 0,
623 node: _objectSpread(_objectSpread({}, node), {}, {
624 x: 0,
625 y: 0,
626 width,
627 height
628 }),
629 index: 0,
630 dataKey,
631 nameKey,
632 // with Treemap nesting, should this continue nesting the index or start from empty string?
633 nestedActiveTooltipIndex: node.tooltipIndex
634 });
635 var formatRoot = squarify(root, aspectRatio);
636 nestIndex = nestIndex.slice(0, i + 1);
637 this.setState({
638 formatRoot,
639 currentRoot: node,
640 nestIndex
641 });
642 }
643 renderNode(root, node) {
644 var {
645 content,
646 type
647 } = this.props;
648 var nodeProps = _objectSpread(_objectSpread(_objectSpread({}, svgPropertiesNoEvents(this.props)), node), {}, {
649 root
650 });
651 var isLeaf = !node.children || !node.children.length;
652 var {
653 currentRoot
654 } = this.state;
655 var isCurrentRootChild = ((currentRoot === null || currentRoot === void 0 ? void 0 : currentRoot.children) || []).filter(item => item.depth === node.depth && item.name === node.name);
656 if (!isCurrentRootChild.length && root.depth && type === 'nest') {
657 return null;
658 }
659 return /*#__PURE__*/React.createElement(Layer, {
660 key: "recharts-treemap-node-".concat(nodeProps.x, "-").concat(nodeProps.y, "-").concat(nodeProps.name),
661 className: "recharts-treemap-depth-".concat(node.depth)
662 }, /*#__PURE__*/React.createElement(TreemapItem, {
663 isLeaf: isLeaf,
664 content: content,
665 nodeProps: nodeProps,
666 treemapProps: this.props,
667 onNestClick: this.handleClick
668 }), node.children && node.children.length ? node.children.map(child => this.renderNode(node, child)) : null);
669 }
670 renderAllNodes() {
671 var {
672 formatRoot
673 } = this.state;
674 if (!formatRoot) {
675 return null;
676 }
677 return this.renderNode(formatRoot, formatRoot);
678 }
679
680 // render nest treemap
681 renderNestIndex() {
682 var {
683 nameKey,
684 nestIndexContent
685 } = this.props;
686 var {
687 nestIndex
688 } = this.state;
689 return /*#__PURE__*/React.createElement("div", {
690 className: "recharts-treemap-nest-index-wrapper",
691 style: {
692 marginTop: '8px',
693 textAlign: 'center'
694 }
695 }, nestIndex.map((item, i) => {
696 // TODO need to verify nameKey type
697 var rawName = get(item, nameKey, 'root');
698 var name = typeof rawName === 'string' ? rawName : 'root';
699 var content;
700 if (/*#__PURE__*/React.isValidElement(nestIndexContent)) {
701 // the cloned content is ignored at all times - let's remove it?
702 content = /*#__PURE__*/React.cloneElement(nestIndexContent, item, i);
703 }
704 if (typeof nestIndexContent === 'function') {
705 content = nestIndexContent(item, i);
706 } else {
707 content = name;
708 }
709 return (
710 /*#__PURE__*/
711 // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions
712 React.createElement("div", {
713 onClick: this.handleNestIndex.bind(this, item, i),
714 key: "nest-index-".concat(uniqueId()),
715 className: "recharts-treemap-nest-index-box",
716 style: {
717 cursor: 'pointer',
718 display: 'inline-block',
719 padding: '0 7px',
720 background: '#000',
721 color: '#fff',
722 marginRight: '3px'
723 }
724 }, content)
725 );
726 }));
727 }
728 render() {
729 var _this$props = this.props,
730 {
731 width,
732 height,
733 className,
734 style,
735 children,
736 type
737 } = _this$props,
738 others = _objectWithoutProperties(_this$props, _excluded);
739 var attrs = svgPropertiesNoEvents(others);
740 return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(SetTreemapTooltipEntrySettings, {
741 dataKey: this.props.dataKey,
742 nameKey: this.props.nameKey,
743 stroke: this.props.stroke,
744 fill: this.props.fill,
745 currentRoot: this.state.currentRoot,
746 id: this.props.id
747 }), /*#__PURE__*/React.createElement(Surface, _extends({}, attrs, {
748 width: width,
749 height: type === 'nest' ? height - 30 : height,
750 onTouchMove: this.handleTouchMove
751 }), this.renderAllNodes(), children), type === 'nest' && this.renderNestIndex());
752 }
753}
754_defineProperty(TreemapWithState, "displayName", 'Treemap');
755function TreemapDispatchInject(props) {
756 var dispatch = useAppDispatch();
757 var width = useChartWidth();
758 var height = useChartHeight();
759 if (!isPositiveNumber(width) || !isPositiveNumber(height)) {
760 return null;
761 }
762 var {
763 id: externalId
764 } = props;
765 return /*#__PURE__*/React.createElement(RegisterGraphicalItemId, {
766 id: externalId,
767 type: "treemap"
768 }, id => /*#__PURE__*/React.createElement(TreemapWithState, _extends({}, props, {
769 id: id,
770 width: width,
771 height: height,
772 dispatch: dispatch
773 })));
774}
775
776/**
777 * The Treemap chart is used to visualize hierarchical data using nested rectangles.
778 *
779 * @consumes ResponsiveContainerContext
780 * @provides TooltipEntrySettings
781 */
782export function Treemap(outsideProps) {
783 var _props$className;
784 var props = resolveDefaultProps(outsideProps, defaultTreeMapProps);
785 var {
786 className,
787 style,
788 width,
789 height
790 } = props;
791 var [tooltipPortal, setTooltipPortal] = useState(null);
792 return /*#__PURE__*/React.createElement(RechartsStoreProvider, {
793 preloadedState: {
794 options
795 },
796 reduxStoreName: (_props$className = props.className) !== null && _props$className !== void 0 ? _props$className : 'Treemap'
797 }, /*#__PURE__*/React.createElement(ReportChartMargin, {
798 margin: defaultTreemapMargin
799 }), /*#__PURE__*/React.createElement(RechartsWrapper, {
800 dispatchTouchEvents: false,
801 className: className,
802 style: style,
803 width: width,
804 height: height
805 /*
806 * Treemap has a bug where it doesn't include strokeWidth in its dimension calculation
807 * which makes the actual chart exactly {strokeWidth} larger than asked for.
808 * It's not a huge deal usually, but it makes the responsive option cycle infinitely.
809 */,
810 responsive: false,
811 ref: node => {
812 if (tooltipPortal == null && node != null) {
813 setTooltipPortal(node);
814 }
815 },
816 onMouseEnter: undefined,
817 onMouseLeave: undefined,
818 onClick: undefined,
819 onMouseMove: undefined,
820 onMouseDown: undefined,
821 onMouseUp: undefined,
822 onContextMenu: undefined,
823 onDoubleClick: undefined,
824 onTouchStart: undefined,
825 onTouchMove: undefined,
826 onTouchEnd: undefined
827 }, /*#__PURE__*/React.createElement(TooltipPortalContext.Provider, {
828 value: tooltipPortal
829 }, /*#__PURE__*/React.createElement(TreemapDispatchInject, props))));
830}
Note: See TracBrowser for help on using the repository browser.