@semcore/d3-chart 2.2.1 → 2.2.4

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.
Files changed (157) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +2 -2
  3. package/lib/cjs/Area.js +9 -9
  4. package/lib/cjs/Area.js.map +1 -1
  5. package/lib/cjs/Axis.js +19 -17
  6. package/lib/cjs/Axis.js.map +1 -1
  7. package/lib/cjs/Bar.js +11 -11
  8. package/lib/cjs/Bar.js.map +1 -1
  9. package/lib/cjs/Bubble.js +12 -12
  10. package/lib/cjs/Bubble.js.map +1 -1
  11. package/lib/cjs/ClipPath.js +1 -1
  12. package/lib/cjs/ClipPath.js.map +1 -1
  13. package/lib/cjs/Donut.js +8 -8
  14. package/lib/cjs/Donut.js.map +1 -1
  15. package/lib/cjs/Dots.js +9 -9
  16. package/lib/cjs/Dots.js.map +1 -1
  17. package/lib/cjs/GroupBar.js +8 -8
  18. package/lib/cjs/GroupBar.js.map +1 -1
  19. package/lib/cjs/HorizontalBar.js +11 -11
  20. package/lib/cjs/HorizontalBar.js.map +1 -1
  21. package/lib/cjs/Hover.js +4 -4
  22. package/lib/cjs/Hover.js.map +1 -1
  23. package/lib/cjs/Line.js +8 -8
  24. package/lib/cjs/Line.js.map +1 -1
  25. package/lib/cjs/Plot.js +4 -4
  26. package/lib/cjs/Plot.js.map +1 -1
  27. package/lib/cjs/RadialTree.js +99 -59
  28. package/lib/cjs/RadialTree.js.map +1 -1
  29. package/lib/cjs/ReferenceLine.js +10 -10
  30. package/lib/cjs/ReferenceLine.js.map +1 -1
  31. package/lib/cjs/ResponsiveContainer.js +1 -1
  32. package/lib/cjs/ResponsiveContainer.js.map +1 -1
  33. package/lib/cjs/ScatterPlot.js +7 -7
  34. package/lib/cjs/ScatterPlot.js.map +1 -1
  35. package/lib/cjs/StackBar.js +8 -8
  36. package/lib/cjs/StackBar.js.map +1 -1
  37. package/lib/cjs/StackedArea.js +8 -8
  38. package/lib/cjs/StackedArea.js.map +1 -1
  39. package/lib/cjs/Tooltip.js +15 -11
  40. package/lib/cjs/Tooltip.js.map +1 -1
  41. package/lib/cjs/Venn.js +9 -9
  42. package/lib/cjs/Venn.js.map +1 -1
  43. package/lib/cjs/color.js.map +1 -1
  44. package/lib/cjs/createElement.js +3 -2
  45. package/lib/cjs/createElement.js.map +1 -1
  46. package/lib/cjs/index.js.map +1 -1
  47. package/lib/cjs/style/radial-tree.shadow.css +0 -1
  48. package/lib/cjs/types/index.d.ts +3 -0
  49. package/lib/cjs/utils.js.map +1 -1
  50. package/lib/es6/Area.js +9 -9
  51. package/lib/es6/Area.js.map +1 -1
  52. package/lib/es6/Axis.js +19 -17
  53. package/lib/es6/Axis.js.map +1 -1
  54. package/lib/es6/Bar.js +11 -11
  55. package/lib/es6/Bar.js.map +1 -1
  56. package/lib/es6/Bubble.js +12 -12
  57. package/lib/es6/Bubble.js.map +1 -1
  58. package/lib/es6/ClipPath.js +1 -1
  59. package/lib/es6/ClipPath.js.map +1 -1
  60. package/lib/es6/Donut.js +8 -8
  61. package/lib/es6/Donut.js.map +1 -1
  62. package/lib/es6/Dots.js +9 -9
  63. package/lib/es6/Dots.js.map +1 -1
  64. package/lib/es6/GroupBar.js +8 -8
  65. package/lib/es6/GroupBar.js.map +1 -1
  66. package/lib/es6/HorizontalBar.js +11 -11
  67. package/lib/es6/HorizontalBar.js.map +1 -1
  68. package/lib/es6/Hover.js +4 -4
  69. package/lib/es6/Hover.js.map +1 -1
  70. package/lib/es6/Line.js +8 -8
  71. package/lib/es6/Line.js.map +1 -1
  72. package/lib/es6/Plot.js +4 -4
  73. package/lib/es6/Plot.js.map +1 -1
  74. package/lib/es6/RadialTree.js +99 -59
  75. package/lib/es6/RadialTree.js.map +1 -1
  76. package/lib/es6/ReferenceLine.js +10 -10
  77. package/lib/es6/ReferenceLine.js.map +1 -1
  78. package/lib/es6/ResponsiveContainer.js +1 -1
  79. package/lib/es6/ResponsiveContainer.js.map +1 -1
  80. package/lib/es6/ScatterPlot.js +7 -7
  81. package/lib/es6/ScatterPlot.js.map +1 -1
  82. package/lib/es6/StackBar.js +8 -8
  83. package/lib/es6/StackBar.js.map +1 -1
  84. package/lib/es6/StackedArea.js +8 -8
  85. package/lib/es6/StackedArea.js.map +1 -1
  86. package/lib/es6/Tooltip.js +15 -11
  87. package/lib/es6/Tooltip.js.map +1 -1
  88. package/lib/es6/Venn.js +9 -9
  89. package/lib/es6/Venn.js.map +1 -1
  90. package/lib/es6/color.js.map +1 -1
  91. package/lib/es6/createElement.js +3 -2
  92. package/lib/es6/createElement.js.map +1 -1
  93. package/lib/es6/index.js.map +1 -1
  94. package/lib/es6/style/radial-tree.shadow.css +0 -1
  95. package/lib/es6/types/index.d.ts +3 -0
  96. package/lib/es6/utils.js.map +1 -1
  97. package/lib/types/index.d.ts +3 -0
  98. package/package.json +1 -1
  99. package/src/Area.jsx +0 -137
  100. package/src/Axis.jsx +0 -314
  101. package/src/Bar.jsx +0 -149
  102. package/src/Bubble.jsx +0 -165
  103. package/src/ClipPath.jsx +0 -47
  104. package/src/Donut.jsx +0 -319
  105. package/src/Dots.jsx +0 -97
  106. package/src/GroupBar.jsx +0 -76
  107. package/src/HorizontalBar.jsx +0 -135
  108. package/src/Hover.jsx +0 -153
  109. package/src/Line.jsx +0 -89
  110. package/src/Plot.jsx +0 -79
  111. package/src/RadialTree.tsx +0 -767
  112. package/src/ReferenceLine.jsx +0 -146
  113. package/src/ResponsiveContainer.jsx +0 -84
  114. package/src/ScatterPlot.jsx +0 -112
  115. package/src/StackBar.jsx +0 -105
  116. package/src/StackedArea.jsx +0 -65
  117. package/src/Tooltip.jsx +0 -145
  118. package/src/Venn.jsx +0 -114
  119. package/src/color.js +0 -21
  120. package/src/createElement.jsx +0 -135
  121. package/src/index.js +0 -27
  122. package/src/style/area.shadow.css +0 -37
  123. package/src/style/axis.shadow.css +0 -85
  124. package/src/style/bar.shadow.css +0 -21
  125. package/src/style/bubble.shadow.css +0 -45
  126. package/src/style/donut.shadow.css +0 -24
  127. package/src/style/dot.shadow.css +0 -29
  128. package/src/style/hover.shadow.css +0 -9
  129. package/src/style/line.shadow.css +0 -29
  130. package/src/style/plot.shadow.css +0 -6
  131. package/src/style/radial-tree.shadow.css +0 -34
  132. package/src/style/reference-line.shadow.css +0 -37
  133. package/src/style/scatterplot.shadow.css +0 -27
  134. package/src/style/tooltip.shadow.css +0 -36
  135. package/src/style/var.css +0 -125
  136. package/src/style/venn.shadow.css +0 -29
  137. package/src/types/Area.d.ts +0 -48
  138. package/src/types/Axis.d.ts +0 -64
  139. package/src/types/Bar.d.ts +0 -52
  140. package/src/types/Bubble.d.ts +0 -32
  141. package/src/types/ClipPath.d.ts +0 -26
  142. package/src/types/Donut.d.ts +0 -46
  143. package/src/types/GroupBar.d.ts +0 -20
  144. package/src/types/HorizontalBar.d.ts +0 -29
  145. package/src/types/Hover.d.ts +0 -15
  146. package/src/types/Line.d.ts +0 -50
  147. package/src/types/Plot.d.ts +0 -16
  148. package/src/types/ReferenceLine.d.ts +0 -31
  149. package/src/types/ResponsiveContainer.d.ts +0 -20
  150. package/src/types/ScatterPlot.d.ts +0 -27
  151. package/src/types/StackBar.d.ts +0 -26
  152. package/src/types/StackedArea.d.ts +0 -26
  153. package/src/types/Tooltip.d.ts +0 -33
  154. package/src/types/Venn.d.ts +0 -45
  155. package/src/types/context.d.ts +0 -6
  156. package/src/types/index.d.ts +0 -56
  157. package/src/utils.ts +0 -227
package/src/Bar.jsx DELETED
@@ -1,149 +0,0 @@
1
- import React from 'react';
2
- import { transition } from 'd3-transition';
3
- import { Component, sstyled } from '@semcore/core';
4
- import uniqueIDEnhancement from '@semcore/utils/lib/uniqueID';
5
- import createElement from './createElement';
6
- import ClipPath from './ClipPath';
7
- import { getBandwidth, roundedPath } from './utils';
8
-
9
- import style from './style/bar.shadow.css';
10
-
11
- class BarRoot extends Component {
12
- static displayName = 'Bar';
13
- static style = style;
14
- static enhance = [uniqueIDEnhancement()];
15
-
16
- static defaultProps = {
17
- offset: [0, 0],
18
- duration: 500,
19
- r: 2,
20
- hMin: 4,
21
- };
22
-
23
- getBackgroundProps(props, index) {
24
- const { x, data } = this.asProps;
25
- return {
26
- value: data[index][x],
27
- };
28
- }
29
-
30
- animationBar() {
31
- const { duration, uid } = this.asProps;
32
- const selectRect = transition().selection().selectAll(`#${uid} rect`);
33
- const selectRectNode = selectRect.node();
34
-
35
- if (duration > 0 && selectRectNode && selectRectNode.getAttribute('y') !== '0') {
36
- selectRect.transition().duration(duration).attr('y', 0);
37
- }
38
- }
39
-
40
- componentDidUpdate() {
41
- this.animationBar();
42
- }
43
-
44
- componentDidMount() {
45
- this.animationBar();
46
- }
47
-
48
- renderBar(d, i) {
49
- const SBar = this.Element;
50
- const {
51
- styles,
52
- color,
53
- x,
54
- y,
55
- y0,
56
- scale,
57
- hide,
58
- offset,
59
- duration,
60
- uid,
61
- r,
62
- hMin,
63
- width: widthProps,
64
- } = this.asProps;
65
-
66
- const [xScale, yScale] = scale;
67
- const barY = yScale(Math.max(d[y0] ?? 0, d[y])) + offset[1] - (Object.is(d[y], 0) ? hMin : 0);
68
- const barX = xScale(d[x]) + offset[0];
69
- const height =
70
- Math.abs(yScale(d[y]) - Math.min(yScale(yScale.domain()[0]), yScale(d[y0] ?? 0))) || hMin;
71
- const width = widthProps || getBandwidth(xScale);
72
- const dSvg = getRect({
73
- x: barX,
74
- y: barY,
75
- width,
76
- height,
77
- radius: Array.isArray(r) ? r[i] : r,
78
- position: d[y] > 0 || Object.is(d[y], 0) ? 'top' : 'bottom',
79
- });
80
-
81
- return sstyled(styles)(
82
- <SBar
83
- key={`bar-${i}`}
84
- render="path"
85
- clipPath={`url(#${uid})`}
86
- __excludeProps={['data', 'scale', 'value']}
87
- childrenPosition="above"
88
- value={d}
89
- index={i}
90
- hide={hide}
91
- color={color}
92
- x={barX}
93
- y={barY}
94
- width={width}
95
- height={height}
96
- d={dSvg}
97
- use:duration={`${duration}ms`}
98
- />,
99
- );
100
- }
101
- render() {
102
- const { data, uid, size, duration } = this.asProps;
103
- return (
104
- <>
105
- {data.map(this.renderBar.bind(this))}
106
- {duration && (
107
- <ClipPath
108
- key={`${uid}-animation`}
109
- id={uid}
110
- x="0"
111
- y={size[1]}
112
- width={size[0]}
113
- height={`${size[1]}px`}
114
- />
115
- )}
116
- </>
117
- );
118
- }
119
- }
120
-
121
- function Background(props) {
122
- const { Element: SBackground, styles, scale, value } = props;
123
-
124
- const [xScale, yScale] = scale;
125
- const yRange = yScale.range();
126
-
127
- return sstyled(styles)(
128
- <SBackground
129
- render="rect"
130
- childrenPosition="above"
131
- width={xScale.bandwidth()}
132
- height={yRange[0] - yRange[1]}
133
- x={xScale(value)}
134
- y={yRange[1]}
135
- />,
136
- );
137
- }
138
-
139
- function getRect({ x, y, width, height, radius, position }) {
140
- if (height <= radius) return '';
141
- if (radius) {
142
- if (position === 'top')
143
- return roundedPath(x, y, width, height, radius, true, true, false, false);
144
- return roundedPath(x, y, width, height, radius, false, false, true, true);
145
- }
146
- return roundedPath(x, y, width, height, radius);
147
- }
148
-
149
- export default createElement(BarRoot, { Background });
package/src/Bubble.jsx DELETED
@@ -1,165 +0,0 @@
1
- import React from 'react';
2
- import { Component, sstyled } from '@semcore/core';
3
- import canUseDOM from '@semcore/utils/lib/canUseDOM';
4
- import { CONSTANT, measureText } from './utils';
5
- import createElement from './createElement';
6
- import uniqueIDEnhancement from '@semcore/utils/lib/uniqueID';
7
- import { transition } from 'd3-transition';
8
- import style from './style/bubble.shadow.css';
9
- import ClipPath from './ClipPath';
10
- import { scaleSqrt } from 'd3-scale';
11
-
12
- class BubbleRoot extends Component {
13
- static displayName = 'Bubble';
14
- static style = style;
15
- static enhance = [uniqueIDEnhancement()];
16
-
17
- static defaultProps = {
18
- offset: [0, 0],
19
- duration: 500,
20
- markedCross: true,
21
- };
22
-
23
- virtualElement = canUseDOM() ? document.createElement('div') : {};
24
-
25
- generateGetBoundingClientRect(x = 0, y = 0) {
26
- return () => ({ width: 0, height: 0, top: y, right: x, bottom: y, left: x });
27
- }
28
-
29
- bindHandlerTooltip =
30
- (visible, props) =>
31
- ({ clientX: x, clientY: y }) => {
32
- const { eventEmitter } = this.asProps;
33
- this.virtualElement.getBoundingClientRect = this.generateGetBoundingClientRect(x, y);
34
- this.virtualElement[CONSTANT.VIRTUAL_ELEMENT] = true;
35
- eventEmitter.emit('onTooltipVisible', visible, props, this.virtualElement);
36
- };
37
-
38
- animationCircle() {
39
- const { duration, uid, data, value } = this.asProps;
40
- const z = scaleSqrt()
41
- .domain([0, Math.max(...data.map((el) => el[value]))])
42
- .range([5.5, 50.5]);
43
-
44
- const selectRect = transition().selection().selectAll(`[id^=${uid}${uid}]`).attr('r', 0);
45
-
46
- const selectRectNode = selectRect.node();
47
- if (duration > 0 && selectRectNode) {
48
- selectRect
49
- .transition()
50
- .duration(duration)
51
- .attr('r', function (_, ind) {
52
- return z(data[ind][value]);
53
- });
54
- }
55
- }
56
-
57
- componentDidUpdate() {
58
- this.animationCircle();
59
- }
60
-
61
- componentDidMount() {
62
- this.animationCircle();
63
- }
64
-
65
- renderCircle(d, i) {
66
- const {
67
- color,
68
- scale,
69
- x,
70
- y,
71
- offset,
72
- styles,
73
- uid,
74
- duration,
75
- value,
76
- label,
77
- markedCross,
78
- size,
79
- data,
80
- } = this.asProps;
81
- const [xScale, yScale] = scale;
82
-
83
- const SBubble = this.Element;
84
- const SCenter = 'text';
85
- const SLabel = 'text';
86
- const z = scaleSqrt()
87
- .domain([0, Math.max(...data.map((el) => el[value]))])
88
- .range([5.5, 50.5]);
89
-
90
- const margin = Math.min(xScale.range()[0], xScale.range()[1]);
91
-
92
- const labelPosition =
93
- size[0] - 2 * margin - (xScale(d[x]) + offset[0] + z(d[value])) < measureText(d[label])
94
- ? 'right'
95
- : 'left';
96
- const labelDistance = {
97
- right: xScale(d[x]) + offset[0] - z(d[value]),
98
- left: xScale(d[x]) + offset[0] + z(d[value]),
99
- }[labelPosition];
100
-
101
- return sstyled(styles)(
102
- <g
103
- key={`circle(#${i})`}
104
- onMouseMove={this.bindHandlerTooltip(true, { ...this.props, xIndex: i })}
105
- onMouseLeave={this.bindHandlerTooltip(false, { ...this.props, xIndex: i })}
106
- >
107
- {markedCross && (
108
- <SCenter
109
- x={xScale(d[x]) + offset[0]}
110
- y={yScale(d[y]) + offset[1]}
111
- dy=".3em"
112
- clipPath={`url(#${uid})`}
113
- color={d[color] ?? color}
114
- >
115
- &#43;
116
- </SCenter>
117
- )}
118
- <SBubble
119
- id={`${uid}${uid}`}
120
- index={i}
121
- render="circle"
122
- clipPath={`url(#${uid})`}
123
- cx={xScale(d[x]) + offset[0]}
124
- cy={yScale(d[y]) + offset[1]}
125
- color={d[color]}
126
- r={z(d[value])}
127
- use:duration={`${duration}ms`}
128
- />
129
- {d[label] && (
130
- <SLabel
131
- x={labelDistance}
132
- y={yScale(d[y]) + offset[1]}
133
- dy=".3em"
134
- clipPath={`url(#${uid})`}
135
- position={labelPosition}
136
- color={d[color]}
137
- >
138
- {d[label]}
139
- </SLabel>
140
- )}
141
- </g>,
142
- );
143
- }
144
-
145
- render() {
146
- const { data, uid, scale } = this.asProps;
147
- const [xScale, yScale] = scale;
148
- const xSize = Math.abs(xScale.range()[0] - xScale.range()[1]);
149
- const ySize = Math.abs(yScale.range()[0] - yScale.range()[1]);
150
- const xMargin = Math.min(xScale.range()[0], xScale.range()[1]);
151
- const yMargin = Math.min(yScale.range()[0], yScale.range()[1]);
152
-
153
- return (
154
- <>
155
- {data.map(this.renderCircle.bind(this))}
156
- {data.map(this.animationCircle.bind(this))}
157
- <ClipPath id={uid} x={xMargin} y={yMargin} width={`${xSize}px`} height={`${ySize}px`} />
158
- </>
159
- );
160
- }
161
- }
162
-
163
- const Bubble = createElement(BubbleRoot);
164
-
165
- export default Bubble;
package/src/ClipPath.jsx DELETED
@@ -1,47 +0,0 @@
1
- import React from 'react';
2
- import createComponent, { Component } from '@semcore/core';
3
- import propsForElement from '@semcore/utils/lib/propsForElement';
4
-
5
- class ClipPath extends Component {
6
- static defaultProps = {
7
- tag: 'rect',
8
- id: '',
9
- transition: '',
10
- setAttributeTag: null,
11
- };
12
-
13
- refClipPath = React.createRef();
14
-
15
- setAttributeTag() {
16
- const { id, tag, setAttributeTag } = this.asProps;
17
- if (setAttributeTag) {
18
- Array.from(document.querySelectorAll(`#${id} ${tag}`)).forEach(setAttributeTag);
19
- }
20
- }
21
-
22
- componentDidMount() {
23
- const { id } = this.asProps;
24
- if (!document || !id || !document.querySelector(`#${id}`)) return;
25
- const svg = document.querySelector(`#${id}`).closest('svg');
26
- Array.from(svg.querySelectorAll(`[clip-path="url(#${id})"]`)).forEach((node) => {
27
- node && node.getTotalLength && node.getTotalLength();
28
- });
29
- this.setAttributeTag();
30
- }
31
-
32
- componentDidUpdate() {
33
- this.setAttributeTag();
34
- }
35
-
36
- render() {
37
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
38
- const { id, transition, tag: Tag, style, className, ...other } = this.asProps;
39
- return (
40
- <clipPath ref={this.refClipPath} id={id}>
41
- <Tag style={{ ...style, transition }} {...propsForElement(other, Tag)} />
42
- </clipPath>
43
- );
44
- }
45
- }
46
-
47
- export default createComponent(ClipPath);
package/src/Donut.jsx DELETED
@@ -1,319 +0,0 @@
1
- import React, { useEffect, useState } from 'react';
2
- import { arc, pie } from 'd3-shape';
3
- import { Component, sstyled } from '@semcore/core';
4
- import canUseDOM from '@semcore/utils/lib/canUseDOM';
5
- import getOriginChildren from '@semcore/utils/lib/getOriginChildren';
6
- import { CONSTANT } from './utils';
7
- import createElement from './createElement';
8
- import uniqueIDEnhancement from '@semcore/utils/lib/uniqueID';
9
- import { interpolate } from 'd3-interpolate';
10
- import { transition } from 'd3-transition';
11
-
12
- import style from './style/donut.shadow.css';
13
-
14
- const DEFAULT_INSTANCE = Symbol('DEFAULT_INSTANCE');
15
-
16
- function animationInitialPie({ halfsize, d3Arc, d3ArcOut, arcs, activeIndexPie }) {
17
- return function (_, ind) {
18
- const d = arcs[ind];
19
- if (!d) return () => '';
20
- const iStart = interpolate(halfsize ? -Math.PI / 2 : 0, d.startAngle);
21
- const iEnd = interpolate(halfsize ? -Math.PI / 2 : 0, d.endAngle);
22
- return function (t) {
23
- d.startAngle = iStart(t);
24
- d.endAngle = iEnd(t);
25
- return ind === activeIndexPie ? d3ArcOut(d) : d3Arc(d);
26
- };
27
- };
28
- }
29
-
30
- function animationUpdatePie({ halfsize, arcs, d3Arc }) {
31
- return function (_, ind) {
32
- const d = arcs[ind];
33
- if (this._current) {
34
- const i = interpolate(this._current, d);
35
- this._current = i(0);
36
- return function (t) {
37
- return d3Arc(i(t));
38
- };
39
- } else {
40
- this._current = d;
41
- return animationInitialPie({ halfsize, arcs, d3Arc })(_, ind);
42
- }
43
- };
44
- }
45
-
46
- function animationHoverPie({ d, selector, duration, innerRadius, outerRadius }) {
47
- if (duration > 0) {
48
- transition()
49
- .selection()
50
- .select(selector)
51
- .transition()
52
- .duration(duration)
53
- .attrTween('d', function () {
54
- if (!d) return () => '';
55
- const [min, max] = outerRadius;
56
- const i = interpolate(min, max);
57
- return function (t) {
58
- const d3ArcOut = arc().innerRadius(innerRadius).outerRadius(i(t));
59
- return d3ArcOut(d);
60
- };
61
- });
62
- }
63
- }
64
-
65
- const increaseFactor = 8;
66
-
67
- function getOuterRadius({ size, halfsize, outerRadius }) {
68
- const [width, height] = size;
69
- const minORmax = halfsize ? Math.max : Math.min;
70
- return outerRadius || minORmax(width - increaseFactor * 2, height - increaseFactor * 2) / 2;
71
- }
72
-
73
- class DonutRoot extends Component {
74
- static displayName = 'Donut';
75
- static style = style;
76
- static enhance = [uniqueIDEnhancement()];
77
-
78
- static defaultProps = ({
79
- innerRadius = 0,
80
- outerRadius,
81
- halfsize = false,
82
- $rootProps: { size },
83
- }) => {
84
- const d3Arc = arc()
85
- .outerRadius(getOuterRadius({ size, halfsize, outerRadius }))
86
- .innerRadius(innerRadius > increaseFactor ? innerRadius - increaseFactor : innerRadius);
87
-
88
- const d3ArcOut = arc()
89
- .outerRadius(getOuterRadius({ size, halfsize, outerRadius }) + increaseFactor)
90
- .innerRadius(innerRadius > increaseFactor ? innerRadius - increaseFactor : innerRadius);
91
-
92
- let d3Pie = pie()
93
- .sort(null)
94
- .value(([, value]) => value);
95
- d3Pie[DEFAULT_INSTANCE] = true;
96
-
97
- if (halfsize) {
98
- d3Pie = d3Pie.startAngle(-Math.PI / 2).endAngle(Math.PI / 2);
99
- }
100
- return {
101
- d3Pie,
102
- d3Arc,
103
- d3ArcOut,
104
- duration: 500,
105
- };
106
- };
107
-
108
- get id() {
109
- const { uid, id } = this.asProps;
110
- return id || uid;
111
- }
112
-
113
- virtualElement = canUseDOM() ? document.createElement('div') : {};
114
- activeIndexPie = undefined;
115
-
116
- generateGetBoundingClientRect(x = 0, y = 0) {
117
- return () => ({ width: 0, height: 0, top: y, right: x, bottom: y, left: x });
118
- }
119
-
120
- getArcs() {
121
- const { Children, data, d3Pie } = this.asProps;
122
- let pieData = Object.entries(data);
123
-
124
- if (d3Pie[DEFAULT_INSTANCE]) {
125
- const keys = React.Children.toArray(getOriginChildren(Children)).reduce((acc, child) => {
126
- if (React.isValidElement(child) && child.type === Donut.Pie) {
127
- acc.push(child.props.dataKey);
128
- }
129
- return acc;
130
- }, []);
131
- pieData = Object.entries(data)
132
- .filter(([key]) => keys.includes(key))
133
- .sort(([a], [b]) => (keys.indexOf(a) > keys.indexOf(b) ? 1 : -1));
134
- }
135
- const minValue =
136
- pieData.reduce((acc, cur) => {
137
- if (cur[1]) acc += cur[1];
138
- return acc;
139
- }, 0) / 100;
140
- pieData = pieData.map((d) => {
141
- if (d[1] && d[1] < minValue) d[1] = minValue;
142
- return d;
143
- });
144
- return d3Pie(pieData);
145
- }
146
-
147
- bindHandlerTooltip =
148
- (visible, props) =>
149
- ({ clientX: x, clientY: y }) => {
150
- const { eventEmitter } = this.asProps;
151
- this.virtualElement.getBoundingClientRect = this.generateGetBoundingClientRect(x, y);
152
- this.virtualElement[CONSTANT.VIRTUAL_ELEMENT] = true;
153
- eventEmitter.emit('onTooltipVisible', visible, props, this.virtualElement);
154
- };
155
-
156
- animationActivePie = (props) => {
157
- let { duration, innerRadius } = this.asProps;
158
- const { active, data, selector } = props;
159
- innerRadius = innerRadius > increaseFactor ? innerRadius - increaseFactor : innerRadius;
160
- const outerRadius = getOuterRadius(this.asProps);
161
- active
162
- ? animationHoverPie({
163
- d: data,
164
- selector: `#${this.id} ${selector}`,
165
- duration: duration === 0 ? 0 : 300,
166
- innerRadius,
167
- outerRadius: [outerRadius, outerRadius + increaseFactor],
168
- })
169
- : animationHoverPie({
170
- d: data,
171
- selector: `#${this.id} ${selector}`,
172
- duration: duration === 0 ? 0 : 300,
173
- innerRadius,
174
- outerRadius: [outerRadius + increaseFactor, outerRadius],
175
- });
176
- };
177
-
178
- getPieProps(props, ind) {
179
- const { d3Arc, d3ArcOut } = this.asProps;
180
- const { active } = props;
181
- const data = this.arcs.find((arc) => arc.data[0] === props.dataKey);
182
- if (active) {
183
- this.activeIndexPie = ind;
184
- }
185
-
186
- return {
187
- data,
188
- d3Arc,
189
- d3ArcOut,
190
- $animationActivePie: this.animationActivePie,
191
- onMouseMove: this.bindHandlerTooltip(true, props),
192
- onMouseLeave: this.bindHandlerTooltip(false, props),
193
- onMouseOver: (e) => {
194
- !active &&
195
- this.animationActivePie({
196
- active: true,
197
- data,
198
- selector: `[d="${e.target.getAttribute('d')}"]`,
199
- });
200
- },
201
- onMouseOut: (e) => {
202
- !active &&
203
- this.animationActivePie({
204
- active: false,
205
- data,
206
- selector: `[d="${e.target.getAttribute('d')}"]`,
207
- });
208
- },
209
- };
210
- }
211
-
212
- getEmptyDataProps() {
213
- const { d3Arc } = this.asProps;
214
- return {
215
- d3Arc,
216
- };
217
- }
218
-
219
- componentDidUpdate(prevProps) {
220
- const { data, duration, d3Arc, halfsize } = this.asProps;
221
- const arcs = this.arcs;
222
- if (prevProps.$rootProps.data !== data && duration > 0) {
223
- transition()
224
- .selection()
225
- .selectAll(`#${this.id} [data-ui-name="Donut.Pie"]`)
226
- .transition()
227
- .duration(duration)
228
- .attrTween('d', animationUpdatePie({ d3Arc, arcs, halfsize }));
229
- }
230
- }
231
-
232
- componentDidMount() {
233
- const { duration, d3Arc, halfsize, d3ArcOut } = this.asProps;
234
- const arcs = this.arcs;
235
-
236
- if (duration > 0) {
237
- transition()
238
- .selection()
239
- .selectAll(`#${this.id} [data-ui-name="Donut.Pie"]`)
240
- .each(function (_, ind) {
241
- this._current = arcs[ind];
242
- })
243
- .transition()
244
- .duration(duration)
245
- .attrTween(
246
- 'd',
247
- animationInitialPie({
248
- halfsize,
249
- d3Arc,
250
- d3ArcOut,
251
- arcs,
252
- activeIndexPie: this.activeIndexPie,
253
- }),
254
- );
255
- }
256
- }
257
-
258
- render() {
259
- const { halfsize, size } = this.asProps;
260
- const [width, height] = size;
261
- const Element = this.Element;
262
- const k = halfsize ? 1 : 2;
263
- this.arcs = this.getArcs();
264
- return (
265
- <Element
266
- id={this.id}
267
- render="g"
268
- childrenPosition="inside"
269
- transform={`translate(${width / 2},${height / k})`}
270
- />
271
- );
272
- }
273
- }
274
-
275
- function Pie({
276
- Element: SPie,
277
- styles,
278
- d3Arc,
279
- data,
280
- color,
281
- $animationActivePie,
282
- active,
283
- d3ArcOut,
284
- ...other
285
- }) {
286
- const [isMount, setIsMount] = useState(false);
287
- useEffect(() => {
288
- //you should't run animation for first render
289
- if (!isMount) {
290
- setIsMount(true);
291
- return;
292
- }
293
- if (active !== undefined && active !== null) {
294
- //name must unique on page
295
- $animationActivePie({ ...other, active, data, selector: `[name="${other.name}"]` });
296
- }
297
- }, [active]);
298
- return sstyled(styles)(
299
- <SPie render="path" color={color} d={active ? d3ArcOut(data) : d3Arc(data)} />,
300
- );
301
- }
302
-
303
- function EmptyData({ Element: SEmptyData, styles, d3Arc, color }) {
304
- return sstyled(styles)(
305
- <SEmptyData render="path" color={color} d={d3Arc({ endAngle: Math.PI * 2, startAngle: 0 })} />,
306
- );
307
- }
308
-
309
- function Label({ Element: SLabel, styles, Children }) {
310
- return sstyled(styles)(
311
- <SLabel render="text" x="0" y="0">
312
- <Children />
313
- </SLabel>,
314
- );
315
- }
316
-
317
- const Donut = createElement(DonutRoot, { Pie, Label, EmptyData });
318
-
319
- export default Donut;