source: node_modules/recharts/es6/chart/SunburstChart.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: 11.9 KB
RevLine 
[a762898]1function _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); }
2function 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; }
3function _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; }
4function _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; }
5function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
6function _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); }
7import * as React from 'react';
8import { useState } from 'react';
9import { scaleLinear } from 'victory-vendor/d3-scale';
10import { clsx } from 'clsx';
11import get from 'es-toolkit/compat/get';
12import { Surface } from '../container/Surface';
13import { Layer } from '../container/Layer';
14import { Sector } from '../shape/Sector';
15import { Text } from '../component/Text';
16import { polarToCartesian } from '../util/PolarUtils';
17import { ReportChartMargin, ReportChartSize, useChartHeight, useChartWidth } from '../context/chartLayoutContext';
18import { TooltipPortalContext } from '../context/tooltipPortalContext';
19import { RechartsWrapper } from './RechartsWrapper';
20import { mouseLeaveItem, setActiveClickItemIndex, setActiveMouseOverItemIndex } from '../state/tooltipSlice';
21import { SetTooltipEntrySettings } from '../state/SetTooltipEntrySettings';
22import { RechartsStoreProvider } from '../state/RechartsStoreProvider';
23import { useAppDispatch } from '../state/hooks';
24import { RegisterGraphicalItemId } from '../context/RegisterGraphicalItemId';
25import { resolveDefaultProps } from '../util/resolveDefaultProps';
26
27/**
28 * We require tooltipIndex on each node internally to track which node is active in the tooltip.
29 * This is not required from the outside user - we can calculate it as we traverse the tree.
30 */
31
32var defaultTextProps = {
33 fontWeight: 'bold',
34 paintOrder: 'stroke fill',
35 fontSize: '.75rem',
36 stroke: '#FFF',
37 fill: 'black',
38 pointerEvents: 'none'
39};
40function getMaxDepthOf(node) {
41 if (!node.children || node.children.length === 0) return 1;
42
43 // Calculate depth for each child and find the maximum
44 var childDepths = node.children.map(d => getMaxDepthOf(d));
45 return 1 + Math.max(...childDepths);
46}
47var SetSunburstTooltipEntrySettings = /*#__PURE__*/React.memo(_ref => {
48 var {
49 dataKey,
50 nameKey,
51 data,
52 stroke,
53 fill,
54 positions,
55 id
56 } = _ref;
57 var tooltipEntrySettings = {
58 dataDefinedOnItem: data.children,
59 getPosition: index => positions.get(index),
60 // Sunburst does not support many of the properties as other charts do so there's plenty of defaults here
61 settings: {
62 stroke,
63 strokeWidth: undefined,
64 fill,
65 nameKey,
66 dataKey,
67 // if there is a nameKey use it, otherwise make the name of the tooltip the dataKey itself
68 name: nameKey ? undefined : dataKey,
69 hide: false,
70 type: undefined,
71 color: fill,
72 unit: '',
73 graphicalItemId: id
74 }
75 };
76 return /*#__PURE__*/React.createElement(SetTooltipEntrySettings, {
77 tooltipEntrySettings: tooltipEntrySettings
78 });
79});
80
81// Why is margin not a sunburst prop? No clue. Probably it should be
82var defaultSunburstMargin = {
83 top: 0,
84 right: 0,
85 bottom: 0,
86 left: 0
87};
88export var payloadSearcher = (data, activeIndex) => {
89 if (activeIndex == null) {
90 return undefined;
91 }
92 return get(data, activeIndex);
93};
94var addToSunburstNodeIndex = function addToSunburstNodeIndex(indexInChildrenArr) {
95 var activeTooltipIndexSoFar = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
96 return "".concat(activeTooltipIndexSoFar, "children[").concat(indexInChildrenArr, "]");
97};
98var preloadedState = {
99 options: {
100 validateTooltipEventTypes: ['item'],
101 defaultTooltipEventType: 'item',
102 chartName: 'Sunburst',
103 tooltipPayloadSearcher: payloadSearcher,
104 eventEmitter: undefined
105 }
106};
107export var defaultSunburstChartProps = {
108 padding: 2,
109 dataKey: 'value',
110 nameKey: 'name',
111 ringPadding: 2,
112 innerRadius: 50,
113 fill: '#333',
114 stroke: '#FFF',
115 textOptions: defaultTextProps,
116 startAngle: 0,
117 endAngle: 360,
118 responsive: false
119};
120var SunburstChartImpl = _ref2 => {
121 var {
122 className,
123 data,
124 children,
125 padding,
126 dataKey,
127 nameKey,
128 ringPadding,
129 innerRadius,
130 fill,
131 stroke,
132 textOptions,
133 outerRadius: outerRadiusFromProps,
134 cx: cxFromProps,
135 cy: cyFromProps,
136 startAngle,
137 endAngle,
138 onClick,
139 onMouseEnter,
140 onMouseLeave,
141 id
142 } = _ref2;
143 var dispatch = useAppDispatch();
144 var width = useChartWidth();
145 var height = useChartHeight();
146 if (width == null || height == null) {
147 return null;
148 }
149 var outerRadius = outerRadiusFromProps !== null && outerRadiusFromProps !== void 0 ? outerRadiusFromProps : Math.min(width, height) / 2;
150 var cx = cxFromProps !== null && cxFromProps !== void 0 ? cxFromProps : width / 2;
151 var cy = cyFromProps !== null && cyFromProps !== void 0 ? cyFromProps : height / 2;
152 var rScale = scaleLinear([0, data[dataKey]], [0, endAngle]);
153 var treeDepth = getMaxDepthOf(data);
154 var thickness = (outerRadius - innerRadius) / treeDepth;
155 var sectors = [];
156 var positions = new Map([]);
157
158 // event handlers
159 function handleMouseEnter(node, e) {
160 if (onMouseEnter) onMouseEnter(node, e);
161 dispatch(setActiveMouseOverItemIndex({
162 activeIndex: node.tooltipIndex,
163 activeDataKey: dataKey,
164 activeCoordinate: positions.get(node.name),
165 activeGraphicalItemId: id
166 }));
167 }
168 function handleMouseLeave(node, e) {
169 if (onMouseLeave) onMouseLeave(node, e);
170 dispatch(mouseLeaveItem());
171 }
172 function handleClick(node) {
173 if (onClick) onClick(node);
174 dispatch(setActiveClickItemIndex({
175 activeIndex: node.tooltipIndex,
176 activeDataKey: dataKey,
177 activeCoordinate: positions.get(node.name),
178 activeGraphicalItemId: id
179 }));
180 }
181
182 // recursively add nodes for each data point and its children
183 function drawArcs(childNodes, options) {
184 var depth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
185 var {
186 radius,
187 innerR,
188 initialAngle,
189 childColor,
190 nestedActiveTooltipIndex
191 } = options;
192 var currentAngle = initialAngle;
193 if (!childNodes) return; // base case: no children of this node
194
195 childNodes.forEach((d, i) => {
196 var _ref3, _d$fill;
197 var currentTooltipIndex = depth === 1 ? "[".concat(i, "]") : addToSunburstNodeIndex(i, nestedActiveTooltipIndex);
198 var nodeWithIndex = _objectSpread(_objectSpread({}, d), {}, {
199 tooltipIndex: currentTooltipIndex
200 });
201 var arcLength = rScale(d[dataKey]);
202 var start = currentAngle;
203 // color priority - if there's a color on the individual point use that, otherwise use parent color or default
204 var fillColor = (_ref3 = (_d$fill = d === null || d === void 0 ? void 0 : d.fill) !== null && _d$fill !== void 0 ? _d$fill : childColor) !== null && _ref3 !== void 0 ? _ref3 : fill;
205 var {
206 x: textX,
207 y: textY
208 } = polarToCartesian(0, 0, innerR + radius / 2, -(start + arcLength - arcLength / 2));
209 currentAngle += arcLength;
210 sectors.push(/*#__PURE__*/React.createElement("g", {
211 key: "sunburst-sector-".concat(d.name, "-").concat(i)
212 }, /*#__PURE__*/React.createElement(Sector, {
213 onClick: () => handleClick(nodeWithIndex),
214 onMouseEnter: e => handleMouseEnter(nodeWithIndex, e),
215 onMouseLeave: e => handleMouseLeave(nodeWithIndex, e),
216 fill: fillColor,
217 stroke: stroke,
218 strokeWidth: padding,
219 startAngle: start,
220 endAngle: start + arcLength,
221 innerRadius: innerR,
222 outerRadius: innerR + radius,
223 cx: cx,
224 cy: cy
225 }), /*#__PURE__*/React.createElement(Text, _extends({}, textOptions, {
226 alignmentBaseline: "middle",
227 textAnchor: "middle",
228 x: textX + cx,
229 y: cy - textY
230 }), d[dataKey])));
231 var {
232 x: tooltipX,
233 y: tooltipY
234 } = polarToCartesian(cx, cy, innerR + radius / 2, start);
235 positions.set(d.name, {
236 x: tooltipX,
237 y: tooltipY
238 });
239 return drawArcs(d.children, {
240 radius,
241 innerR: innerR + radius + ringPadding,
242 initialAngle: start,
243 childColor: fillColor,
244 nestedActiveTooltipIndex: currentTooltipIndex
245 }, depth + 1);
246 });
247 }
248 drawArcs(data.children, {
249 radius: thickness,
250 innerR: innerRadius,
251 initialAngle: startAngle
252 });
253 var layerClass = clsx('recharts-sunburst', className);
254 return /*#__PURE__*/React.createElement(Surface, {
255 width: width,
256 height: height
257 }, /*#__PURE__*/React.createElement(Layer, {
258 className: layerClass
259 }, sectors), /*#__PURE__*/React.createElement(SetSunburstTooltipEntrySettings, {
260 dataKey: dataKey,
261 nameKey: nameKey,
262 data: data,
263 stroke: stroke,
264 fill: fill,
265 positions: positions,
266 id: id
267 }), children);
268};
269
270/**
271 * The sunburst is a hierarchical chart, similar to a {@link Treemap}, plotted in polar coordinates.
272 * Sunburst charts effectively convey the hierarchical relationships and proportions within each level.
273 * It is easy to see all the middle layers in the hierarchy, which might get lost in other visualizations.
274 * For some datasets, the radial layout may be more visually appealing and intuitive than a traditional {@link Treemap}.
275 *
276 * @consumes ResponsiveContainerContext
277 * @provides TooltipEntrySettings
278 */
279export var SunburstChart = outsideProps => {
280 var props = resolveDefaultProps(outsideProps, defaultSunburstChartProps);
281 var {
282 className,
283 width,
284 height,
285 responsive,
286 style,
287 id: externalId
288 } = props;
289 var [tooltipPortal, setTooltipPortal] = useState(null);
290 return /*#__PURE__*/React.createElement(RechartsStoreProvider, {
291 preloadedState: preloadedState,
292 reduxStoreName: className !== null && className !== void 0 ? className : 'SunburstChart'
293 }, /*#__PURE__*/React.createElement(ReportChartSize, {
294 width: width,
295 height: height
296 }), /*#__PURE__*/React.createElement(ReportChartMargin, {
297 margin: defaultSunburstMargin
298 }), /*#__PURE__*/React.createElement(TooltipPortalContext.Provider, {
299 value: tooltipPortal
300 }, /*#__PURE__*/React.createElement(RechartsWrapper, {
301 className: className,
302 width: width,
303 height: height,
304 responsive: responsive,
305 style: style,
306 ref: node => {
307 if (tooltipPortal == null && node != null) {
308 setTooltipPortal(node);
309 }
310 },
311 onMouseEnter: undefined,
312 onMouseLeave: undefined,
313 onClick: undefined,
314 onMouseMove: undefined,
315 onMouseDown: undefined,
316 onMouseUp: undefined,
317 onContextMenu: undefined,
318 onDoubleClick: undefined,
319 onTouchStart: undefined,
320 onTouchMove: undefined,
321 onTouchEnd: undefined
322 }, /*#__PURE__*/React.createElement(RegisterGraphicalItemId, {
323 id: externalId,
324 type: "sunburst"
325 }, id => /*#__PURE__*/React.createElement(SunburstChartImpl, _extends({}, props, {
326 id: id
327 }))))));
328};
Note: See TracBrowser for help on using the repository browser.