@semcore/d3-chart 2.2.2 → 2.2.5
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.md +22 -1
- package/lib/cjs/Area.js +9 -9
- package/lib/cjs/Area.js.map +1 -1
- package/lib/cjs/Axis.js +19 -17
- package/lib/cjs/Axis.js.map +1 -1
- package/lib/cjs/Bar.js +11 -11
- package/lib/cjs/Bar.js.map +1 -1
- package/lib/cjs/Bubble.js +12 -12
- package/lib/cjs/Bubble.js.map +1 -1
- package/lib/cjs/ClipPath.js +1 -1
- package/lib/cjs/ClipPath.js.map +1 -1
- package/lib/cjs/Donut.js +8 -8
- package/lib/cjs/Donut.js.map +1 -1
- package/lib/cjs/Dots.js +9 -9
- package/lib/cjs/Dots.js.map +1 -1
- package/lib/cjs/GroupBar.js +8 -8
- package/lib/cjs/GroupBar.js.map +1 -1
- package/lib/cjs/HorizontalBar.js +11 -11
- package/lib/cjs/HorizontalBar.js.map +1 -1
- package/lib/cjs/Hover.js +4 -4
- package/lib/cjs/Hover.js.map +1 -1
- package/lib/cjs/Line.js +8 -8
- package/lib/cjs/Line.js.map +1 -1
- package/lib/cjs/Plot.js +4 -4
- package/lib/cjs/Plot.js.map +1 -1
- package/lib/cjs/RadialTree.js +99 -59
- package/lib/cjs/RadialTree.js.map +1 -1
- package/lib/cjs/ReferenceLine.js +10 -10
- package/lib/cjs/ReferenceLine.js.map +1 -1
- package/lib/cjs/ResponsiveContainer.js +2 -1
- package/lib/cjs/ResponsiveContainer.js.map +1 -1
- package/lib/cjs/ScatterPlot.js +7 -7
- package/lib/cjs/ScatterPlot.js.map +1 -1
- package/lib/cjs/StackBar.js +8 -8
- package/lib/cjs/StackBar.js.map +1 -1
- package/lib/cjs/StackedArea.js +8 -8
- package/lib/cjs/StackedArea.js.map +1 -1
- package/lib/cjs/Tooltip.js +15 -11
- package/lib/cjs/Tooltip.js.map +1 -1
- package/lib/cjs/Venn.js +9 -9
- package/lib/cjs/Venn.js.map +1 -1
- package/lib/cjs/color.js.map +1 -1
- package/lib/cjs/createElement.js +1 -1
- package/lib/cjs/createElement.js.map +1 -1
- package/lib/cjs/index.js.map +1 -1
- package/lib/cjs/style/radial-tree.shadow.css +0 -1
- package/lib/cjs/types/index.d.ts +3 -0
- package/lib/cjs/utils.js.map +1 -1
- package/lib/es6/Area.js +9 -9
- package/lib/es6/Area.js.map +1 -1
- package/lib/es6/Axis.js +19 -17
- package/lib/es6/Axis.js.map +1 -1
- package/lib/es6/Bar.js +11 -11
- package/lib/es6/Bar.js.map +1 -1
- package/lib/es6/Bubble.js +12 -12
- package/lib/es6/Bubble.js.map +1 -1
- package/lib/es6/ClipPath.js +1 -1
- package/lib/es6/ClipPath.js.map +1 -1
- package/lib/es6/Donut.js +8 -8
- package/lib/es6/Donut.js.map +1 -1
- package/lib/es6/Dots.js +9 -9
- package/lib/es6/Dots.js.map +1 -1
- package/lib/es6/GroupBar.js +8 -8
- package/lib/es6/GroupBar.js.map +1 -1
- package/lib/es6/HorizontalBar.js +11 -11
- package/lib/es6/HorizontalBar.js.map +1 -1
- package/lib/es6/Hover.js +4 -4
- package/lib/es6/Hover.js.map +1 -1
- package/lib/es6/Line.js +8 -8
- package/lib/es6/Line.js.map +1 -1
- package/lib/es6/Plot.js +4 -4
- package/lib/es6/Plot.js.map +1 -1
- package/lib/es6/RadialTree.js +99 -59
- package/lib/es6/RadialTree.js.map +1 -1
- package/lib/es6/ReferenceLine.js +10 -10
- package/lib/es6/ReferenceLine.js.map +1 -1
- package/lib/es6/ResponsiveContainer.js +2 -1
- package/lib/es6/ResponsiveContainer.js.map +1 -1
- package/lib/es6/ScatterPlot.js +7 -7
- package/lib/es6/ScatterPlot.js.map +1 -1
- package/lib/es6/StackBar.js +8 -8
- package/lib/es6/StackBar.js.map +1 -1
- package/lib/es6/StackedArea.js +8 -8
- package/lib/es6/StackedArea.js.map +1 -1
- package/lib/es6/Tooltip.js +15 -11
- package/lib/es6/Tooltip.js.map +1 -1
- package/lib/es6/Venn.js +9 -9
- package/lib/es6/Venn.js.map +1 -1
- package/lib/es6/color.js.map +1 -1
- package/lib/es6/createElement.js +1 -1
- package/lib/es6/createElement.js.map +1 -1
- package/lib/es6/index.js.map +1 -1
- package/lib/es6/style/radial-tree.shadow.css +0 -1
- package/lib/es6/types/index.d.ts +3 -0
- package/lib/es6/utils.js.map +1 -1
- package/lib/types/index.d.ts +3 -0
- package/package.json +1 -1
- package/src/Area.jsx +0 -137
- package/src/Axis.jsx +0 -314
- package/src/Bar.jsx +0 -149
- package/src/Bubble.jsx +0 -165
- package/src/ClipPath.jsx +0 -47
- package/src/Donut.jsx +0 -319
- package/src/Dots.jsx +0 -97
- package/src/GroupBar.jsx +0 -76
- package/src/HorizontalBar.jsx +0 -135
- package/src/Hover.jsx +0 -153
- package/src/Line.jsx +0 -89
- package/src/Plot.jsx +0 -79
- package/src/RadialTree.tsx +0 -767
- package/src/ReferenceLine.jsx +0 -146
- package/src/ResponsiveContainer.jsx +0 -84
- package/src/ScatterPlot.jsx +0 -112
- package/src/StackBar.jsx +0 -105
- package/src/StackedArea.jsx +0 -65
- package/src/Tooltip.jsx +0 -145
- package/src/Venn.jsx +0 -114
- package/src/color.js +0 -21
- package/src/createElement.jsx +0 -135
- package/src/index.js +0 -27
- package/src/style/area.shadow.css +0 -37
- package/src/style/axis.shadow.css +0 -85
- package/src/style/bar.shadow.css +0 -21
- package/src/style/bubble.shadow.css +0 -45
- package/src/style/donut.shadow.css +0 -24
- package/src/style/dot.shadow.css +0 -29
- package/src/style/hover.shadow.css +0 -9
- package/src/style/line.shadow.css +0 -29
- package/src/style/plot.shadow.css +0 -6
- package/src/style/radial-tree.shadow.css +0 -34
- package/src/style/reference-line.shadow.css +0 -37
- package/src/style/scatterplot.shadow.css +0 -27
- package/src/style/tooltip.shadow.css +0 -36
- package/src/style/var.css +0 -125
- package/src/style/venn.shadow.css +0 -29
- package/src/types/Area.d.ts +0 -48
- package/src/types/Axis.d.ts +0 -64
- package/src/types/Bar.d.ts +0 -52
- package/src/types/Bubble.d.ts +0 -32
- package/src/types/ClipPath.d.ts +0 -26
- package/src/types/Donut.d.ts +0 -46
- package/src/types/GroupBar.d.ts +0 -20
- package/src/types/HorizontalBar.d.ts +0 -29
- package/src/types/Hover.d.ts +0 -15
- package/src/types/Line.d.ts +0 -50
- package/src/types/Plot.d.ts +0 -16
- package/src/types/ReferenceLine.d.ts +0 -31
- package/src/types/ResponsiveContainer.d.ts +0 -20
- package/src/types/ScatterPlot.d.ts +0 -27
- package/src/types/StackBar.d.ts +0 -26
- package/src/types/StackedArea.d.ts +0 -26
- package/src/types/Tooltip.d.ts +0 -33
- package/src/types/Venn.d.ts +0 -45
- package/src/types/context.d.ts +0 -6
- package/src/types/index.d.ts +0 -56
- package/src/utils.ts +0 -227
package/src/RadialTree.tsx
DELETED
|
@@ -1,767 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Component, sstyled, CProps, ReturnEl } from '@semcore/core';
|
|
3
|
-
// @ts-ignore
|
|
4
|
-
import createElement from './createElement';
|
|
5
|
-
import uniqueIDEnhancement from '@semcore/utils/lib/uniqueID';
|
|
6
|
-
import { transition } from 'd3-transition';
|
|
7
|
-
import style from './style/radial-tree.shadow.css';
|
|
8
|
-
import { shade } from '@semcore/utils/lib/color';
|
|
9
|
-
import { measureText } from './utils';
|
|
10
|
-
import assignProps from '@semcore/utils/lib/assignProps';
|
|
11
|
-
import getOriginChildren from '@semcore/utils/lib/getOriginChildren';
|
|
12
|
-
|
|
13
|
-
const baseAngle = -Math.PI / 2; // The top vertical line
|
|
14
|
-
|
|
15
|
-
type RadianData = {
|
|
16
|
-
/**
|
|
17
|
-
* Text label on the end of radian.
|
|
18
|
-
*/
|
|
19
|
-
label: string;
|
|
20
|
-
/**
|
|
21
|
-
* Radian key. Radian, which `key` is equal to `activeKey` is displayed as active.
|
|
22
|
-
*/
|
|
23
|
-
key: string;
|
|
24
|
-
/**
|
|
25
|
-
* Size of the cap (filled circle on the end of the radian).
|
|
26
|
-
* @default 16
|
|
27
|
-
*/
|
|
28
|
-
capSize?: number;
|
|
29
|
-
/**
|
|
30
|
-
* Icon, that displayed in the cap of the active radian (usage example `icon: UserM`).
|
|
31
|
-
*/
|
|
32
|
-
icon?: React.FC;
|
|
33
|
-
/**
|
|
34
|
-
* Color of radian's line, cap and label.
|
|
35
|
-
* @default #008FF8
|
|
36
|
-
*/
|
|
37
|
-
color?: string;
|
|
38
|
-
/**
|
|
39
|
-
* Color of icon.
|
|
40
|
-
* @default #fff
|
|
41
|
-
*/
|
|
42
|
-
iconColor?: string;
|
|
43
|
-
/**
|
|
44
|
-
* Size of icon.
|
|
45
|
-
* @default 16
|
|
46
|
-
*/
|
|
47
|
-
iconSize?: number;
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
export interface IRadialTreeProps {
|
|
51
|
-
/**
|
|
52
|
-
* List of radians. `{ label: string; key: string; capSize?: number; icon?: React.FC; color?: string; iconColor?: string; iconSize?: number; }`
|
|
53
|
-
*/
|
|
54
|
-
data: RadianData[];
|
|
55
|
-
/**
|
|
56
|
-
* Angel (in rads) that rotates chart. 0 means that first radian is exactly on top vertical line.
|
|
57
|
-
* @default 0
|
|
58
|
-
*/
|
|
59
|
-
angleOffset?: number;
|
|
60
|
-
/**
|
|
61
|
-
* Duration of appear and update animation.
|
|
62
|
-
* @default 300
|
|
63
|
-
*/
|
|
64
|
-
duration?: number;
|
|
65
|
-
/**
|
|
66
|
-
* Gap between the chart center and radians start point.
|
|
67
|
-
* @default 50
|
|
68
|
-
*/
|
|
69
|
-
centralMargin?: number;
|
|
70
|
-
/**
|
|
71
|
-
* Gap around text label.
|
|
72
|
-
* @default 2
|
|
73
|
-
*/
|
|
74
|
-
labelMargin?: number;
|
|
75
|
-
/**
|
|
76
|
-
* Color of all radian's line, cap and label.
|
|
77
|
-
* @default #008FF8
|
|
78
|
-
*/
|
|
79
|
-
color?: string;
|
|
80
|
-
/**
|
|
81
|
-
* Size of the cap (filled circle on the end of the radian).
|
|
82
|
-
* @default 16
|
|
83
|
-
*/
|
|
84
|
-
capSize?: number;
|
|
85
|
-
/**
|
|
86
|
-
* Icon, that displayed in the cap of the active radian (usage example `icon: UserM`).
|
|
87
|
-
*/
|
|
88
|
-
icon?: React.FC;
|
|
89
|
-
/**
|
|
90
|
-
* Color of icon.
|
|
91
|
-
* @default #fff
|
|
92
|
-
*/
|
|
93
|
-
iconColor?: string;
|
|
94
|
-
/**
|
|
95
|
-
* Size of icon.
|
|
96
|
-
* @default 16
|
|
97
|
-
*/
|
|
98
|
-
iconSize?: number;
|
|
99
|
-
/**
|
|
100
|
-
* Text size in radians' labels. 1.5x is used as default text size of center text.
|
|
101
|
-
* @default 14
|
|
102
|
-
*/
|
|
103
|
-
textSize?: number;
|
|
104
|
-
/**
|
|
105
|
-
* Used to define the active radian in controlled way. Active radian is highligted with inreased cap size.
|
|
106
|
-
*/
|
|
107
|
-
activeKey?: string | null;
|
|
108
|
-
/**
|
|
109
|
-
* Default value for `activeKey` property.
|
|
110
|
-
*/
|
|
111
|
-
defaultActiveKey?: string | null;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
type RootAsProps = IRadialTreeProps & {
|
|
115
|
-
uid: string;
|
|
116
|
-
styles: React.CSSProperties;
|
|
117
|
-
activeKey: string | null;
|
|
118
|
-
Children: React.FC;
|
|
119
|
-
size: [width: number, height: number];
|
|
120
|
-
data: RadianData[];
|
|
121
|
-
duration: number;
|
|
122
|
-
textSize: number;
|
|
123
|
-
capSize: number;
|
|
124
|
-
centralMargin: number;
|
|
125
|
-
angleOffset: number;
|
|
126
|
-
$rootProps: RootAsProps;
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
class RadialTreeBase extends Component<RootAsProps> {
|
|
130
|
-
static displayName = 'RadialTree';
|
|
131
|
-
static style = style;
|
|
132
|
-
static enhance = [uniqueIDEnhancement()];
|
|
133
|
-
|
|
134
|
-
static defaultProps: Partial<IRadialTreeProps> = {
|
|
135
|
-
angleOffset: 0,
|
|
136
|
-
duration: 300,
|
|
137
|
-
centralMargin: 50,
|
|
138
|
-
labelMargin: 2,
|
|
139
|
-
iconColor: '#fff',
|
|
140
|
-
capSize: 8,
|
|
141
|
-
iconSize: 8,
|
|
142
|
-
textSize: 14,
|
|
143
|
-
defaultActiveKey: null,
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
Element!: React.FC<{ render: string }>;
|
|
147
|
-
|
|
148
|
-
constructor(props: any) {
|
|
149
|
-
super(props);
|
|
150
|
-
this.handleRadianClick = this.handleRadianClick.bind(this);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
uncontrolledProps() {
|
|
154
|
-
return {
|
|
155
|
-
activeKey: null,
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
runAppearAnimation() {
|
|
160
|
-
const { duration, uid } = this.asProps;
|
|
161
|
-
const preferReduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)')?.matches;
|
|
162
|
-
|
|
163
|
-
/** using `!(>)` instead of `<=` to get true on NaN and non numbers stuff */
|
|
164
|
-
if (!(duration > 0)) return;
|
|
165
|
-
if (preferReduceMotion) return;
|
|
166
|
-
|
|
167
|
-
const circlesAnimation = transition()
|
|
168
|
-
.selection()
|
|
169
|
-
.selectAll(`[data-radial-animation=${uid}-cap-circle]`);
|
|
170
|
-
const iconsAnimation = transition()
|
|
171
|
-
.selection()
|
|
172
|
-
.selectAll(`[data-radial-animation=${uid}-cap-icon]`);
|
|
173
|
-
const linesAnimation = transition()
|
|
174
|
-
.selection()
|
|
175
|
-
.selectAll(`[data-radial-animation=${uid}-line]`);
|
|
176
|
-
const labelsAnimation = transition()
|
|
177
|
-
.selection()
|
|
178
|
-
.selectAll(`[data-radial-animation=${uid}-label]`);
|
|
179
|
-
const circlesNodes = circlesAnimation.nodes() as SVGCircleElement[];
|
|
180
|
-
const iconsNodes = iconsAnimation.nodes() as SVGRectElement[];
|
|
181
|
-
const linesNodes = linesAnimation.nodes() as SVGLineElement[];
|
|
182
|
-
const labelsNodes = linesAnimation.nodes() as SVGTextElement[];
|
|
183
|
-
|
|
184
|
-
if (circlesNodes.length > 0) {
|
|
185
|
-
const attrs = circlesNodes.map((node) => {
|
|
186
|
-
const cx = node.cx?.baseVal?.value;
|
|
187
|
-
const cy = node.cy?.baseVal?.value;
|
|
188
|
-
const radianIndex = parseInt(node.dataset.radianIndex!, 10);
|
|
189
|
-
const lineNode = linesNodes[radianIndex];
|
|
190
|
-
return {
|
|
191
|
-
from: {
|
|
192
|
-
cx: lineNode.x1?.baseVal?.value,
|
|
193
|
-
cy: lineNode.y1?.baseVal?.value,
|
|
194
|
-
},
|
|
195
|
-
to: { cx, cy },
|
|
196
|
-
};
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
circlesAnimation
|
|
200
|
-
.attr('opacity', 0)
|
|
201
|
-
.attr('cx', (_, index) => attrs[index].from?.cx)
|
|
202
|
-
.attr('cy', (_, index) => attrs[index].from?.cy);
|
|
203
|
-
circlesAnimation
|
|
204
|
-
.transition()
|
|
205
|
-
.duration(duration)
|
|
206
|
-
.attr('opacity', 1)
|
|
207
|
-
.attr('cx', (_, index) => attrs[index].to?.cx)
|
|
208
|
-
.attr('cy', (_, index) => attrs[index].to?.cy);
|
|
209
|
-
}
|
|
210
|
-
if (iconsNodes.length > 0) {
|
|
211
|
-
const attrs = iconsNodes.map((node) => {
|
|
212
|
-
const x = node.x?.baseVal?.value;
|
|
213
|
-
const y = node.y?.baseVal?.value;
|
|
214
|
-
const width = node.width?.baseVal?.value;
|
|
215
|
-
const height = node.height?.baseVal?.value;
|
|
216
|
-
const radianIndex = parseInt(node.dataset.radianIndex!, 10);
|
|
217
|
-
const lineNode = linesNodes[radianIndex];
|
|
218
|
-
return {
|
|
219
|
-
from: {
|
|
220
|
-
x: lineNode.x1?.baseVal?.value - width / 2,
|
|
221
|
-
y: lineNode.y1?.baseVal?.value - height / 2,
|
|
222
|
-
},
|
|
223
|
-
to: {
|
|
224
|
-
x,
|
|
225
|
-
y,
|
|
226
|
-
},
|
|
227
|
-
};
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
iconsAnimation
|
|
231
|
-
.attr('opacity', 0)
|
|
232
|
-
.attr('x', (_, index) => attrs[index].from?.x)
|
|
233
|
-
.attr('y', (_, index) => attrs[index].from?.y);
|
|
234
|
-
iconsAnimation
|
|
235
|
-
.transition()
|
|
236
|
-
.duration(duration)
|
|
237
|
-
.attr('opacity', 1)
|
|
238
|
-
.attr('x', (_, index) => attrs[index].to?.x)
|
|
239
|
-
.attr('y', (_, index) => attrs[index].to?.y);
|
|
240
|
-
}
|
|
241
|
-
if (linesNodes.length > 0) {
|
|
242
|
-
const attrs = linesNodes.map((node) => {
|
|
243
|
-
const x2 = node.x2?.baseVal?.value;
|
|
244
|
-
const y2 = node.y2?.baseVal?.value;
|
|
245
|
-
return {
|
|
246
|
-
from: {
|
|
247
|
-
x2: node.x1?.baseVal?.value,
|
|
248
|
-
y2: node.y1?.baseVal?.value,
|
|
249
|
-
},
|
|
250
|
-
to: {
|
|
251
|
-
x2,
|
|
252
|
-
y2,
|
|
253
|
-
},
|
|
254
|
-
};
|
|
255
|
-
});
|
|
256
|
-
|
|
257
|
-
linesAnimation
|
|
258
|
-
.attr('opacity', 0)
|
|
259
|
-
.attr('x2', (_, index) => attrs[index].from?.x2)
|
|
260
|
-
.attr('y2', (_, index) => attrs[index].from?.y2);
|
|
261
|
-
linesAnimation
|
|
262
|
-
.transition()
|
|
263
|
-
.duration(duration)
|
|
264
|
-
.attr('opacity', 1)
|
|
265
|
-
.attr('x2', (_, index) => attrs[index].to?.x2)
|
|
266
|
-
.attr('y2', (_, index) => attrs[index].to?.y2);
|
|
267
|
-
}
|
|
268
|
-
if (labelsNodes.length > 0) {
|
|
269
|
-
labelsAnimation.attr('opacity', 0);
|
|
270
|
-
labelsAnimation.transition().duration(duration).attr('opacity', 1);
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
componentDidUpdate(prevProps: RootAsProps) {
|
|
275
|
-
if (prevProps.$rootProps.data?.length !== this.asProps.data?.length) {
|
|
276
|
-
this.runAppearAnimation();
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
componentDidMount() {
|
|
281
|
-
this.runAppearAnimation();
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
handleRadianClick(key: string) {
|
|
285
|
-
return (event: React.MouseEvent) => {
|
|
286
|
-
const newKey = key !== this.asProps.activeKey ? key : null;
|
|
287
|
-
this.handlers.activeKey(newKey, event);
|
|
288
|
-
};
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
computeTextWidth() {
|
|
292
|
-
const { data, textSize } = this.asProps;
|
|
293
|
-
const widths = data.map(({ label }) => measureText(label, textSize));
|
|
294
|
-
|
|
295
|
-
return Math.max(...widths);
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
getTitleProps() {
|
|
299
|
-
const { uid, size, textSize } = this.asProps;
|
|
300
|
-
|
|
301
|
-
const [width, height] = size;
|
|
302
|
-
const center = [width / 2, height / 2];
|
|
303
|
-
const [x, y] = center;
|
|
304
|
-
return {
|
|
305
|
-
x,
|
|
306
|
-
y,
|
|
307
|
-
textSize: textSize * 1.5,
|
|
308
|
-
['data-radial-animation']: `${uid}-label`,
|
|
309
|
-
} as IRadialTreeTitleProps;
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
getRadianProps() {
|
|
313
|
-
const { data, ...restRootProps } = this.asProps;
|
|
314
|
-
const textWidth = this.computeTextWidth();
|
|
315
|
-
|
|
316
|
-
return {
|
|
317
|
-
...restRootProps,
|
|
318
|
-
radiansCount: data.length,
|
|
319
|
-
data,
|
|
320
|
-
textWidth,
|
|
321
|
-
onRadianClick: this.handleRadianClick,
|
|
322
|
-
} as IRadialTreeRadianProps;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
render() {
|
|
326
|
-
const SRadialTree = this.Element;
|
|
327
|
-
const { Children } = this.asProps;
|
|
328
|
-
|
|
329
|
-
return sstyled(this.asProps.styles)(
|
|
330
|
-
<SRadialTree render="g">
|
|
331
|
-
<Children />
|
|
332
|
-
</SRadialTree>,
|
|
333
|
-
);
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
export interface IRadialTreeRadianProps extends IRadialTreeProps {
|
|
338
|
-
radiansCount?: number;
|
|
339
|
-
textWidth?: number;
|
|
340
|
-
onRadianClick?: (key: string) => (event: React.MouseEvent) => void;
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
type RadianAsProps = RootAsProps & {
|
|
344
|
-
radiansCount: number;
|
|
345
|
-
textWidth: number;
|
|
346
|
-
onRadianClick: (key: string) => (event: React.MouseEvent) => void;
|
|
347
|
-
};
|
|
348
|
-
|
|
349
|
-
class RadialTreeRadian extends Component<RadianAsProps> {
|
|
350
|
-
static displayName = 'RadialTreeRadian';
|
|
351
|
-
static style = style;
|
|
352
|
-
|
|
353
|
-
static defaultProps: Partial<IRadialTreeRadianProps> = {
|
|
354
|
-
centralMargin: 50,
|
|
355
|
-
labelMargin: 2,
|
|
356
|
-
iconColor: '#fff',
|
|
357
|
-
capSize: 16,
|
|
358
|
-
iconSize: 16,
|
|
359
|
-
textSize: 14,
|
|
360
|
-
};
|
|
361
|
-
Element!: React.FC<{ render: string }>;
|
|
362
|
-
|
|
363
|
-
constructor(props: any) {
|
|
364
|
-
super(props);
|
|
365
|
-
this.renderRadian = this.renderRadian.bind(this);
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
getInteractiveAreaProps({ $rootProps }: { $rootProps: IRadialTreeProps }, index: number) {
|
|
369
|
-
const data = $rootProps.data![index];
|
|
370
|
-
const { xStart, yStart, xLabelCenter, yLabelCenter, capSize } = this.computeRadianPosition(
|
|
371
|
-
data,
|
|
372
|
-
index,
|
|
373
|
-
);
|
|
374
|
-
|
|
375
|
-
return {
|
|
376
|
-
x1: xStart,
|
|
377
|
-
y1: yStart,
|
|
378
|
-
x2: xLabelCenter,
|
|
379
|
-
y2: yLabelCenter,
|
|
380
|
-
strokeWidth: capSize * 3,
|
|
381
|
-
} as IRadialTreeRadianInteractiveAreaProps;
|
|
382
|
-
}
|
|
383
|
-
getLineProps({ $rootProps }: { $rootProps: IRadialTreeProps }, index: number) {
|
|
384
|
-
const data = $rootProps.data![index];
|
|
385
|
-
const { xStart, yStart, xEnd, yEnd } = this.computeRadianPosition(data, index);
|
|
386
|
-
const { uid } = this.asProps;
|
|
387
|
-
const color = data.color ?? this.asProps.color;
|
|
388
|
-
|
|
389
|
-
return {
|
|
390
|
-
x1: xStart,
|
|
391
|
-
y1: yStart,
|
|
392
|
-
x2: xEnd,
|
|
393
|
-
y2: yEnd,
|
|
394
|
-
stroke: color,
|
|
395
|
-
['data-radial-animation']: `${uid}-line`,
|
|
396
|
-
['data-radian-index']: index,
|
|
397
|
-
} as IRadialTreeRadianLineProps;
|
|
398
|
-
}
|
|
399
|
-
getCapProps({ $rootProps }: { $rootProps: IRadialTreeProps }, index: number) {
|
|
400
|
-
const data = $rootProps.data![index];
|
|
401
|
-
const { xEnd, yEnd, capSize } = this.computeRadianPosition(data, index);
|
|
402
|
-
const { uid } = this.asProps;
|
|
403
|
-
const color = data.color ?? this.asProps.color;
|
|
404
|
-
|
|
405
|
-
return {
|
|
406
|
-
x: xEnd,
|
|
407
|
-
y: yEnd,
|
|
408
|
-
radius: capSize,
|
|
409
|
-
color,
|
|
410
|
-
['data-radial-animation']: `${uid}-cap-circle`,
|
|
411
|
-
['data-radian-index']: index,
|
|
412
|
-
} as IRadialTreeRadianCapProps;
|
|
413
|
-
}
|
|
414
|
-
getIconProps({ $rootProps }: { $rootProps: IRadialTreeProps }, index: number) {
|
|
415
|
-
const data = $rootProps.data![index];
|
|
416
|
-
const { xEnd, yEnd, isActive } = this.computeRadianPosition(data, index);
|
|
417
|
-
const { uid } = this.asProps;
|
|
418
|
-
const iconColor = data.iconColor ?? this.asProps.iconColor;
|
|
419
|
-
const iconSize = data.iconSize ?? this.asProps.iconSize;
|
|
420
|
-
const icon = data.icon ?? this.asProps.icon;
|
|
421
|
-
|
|
422
|
-
return {
|
|
423
|
-
x: xEnd - iconSize! / 2,
|
|
424
|
-
y: yEnd - iconSize! / 2,
|
|
425
|
-
iconSize,
|
|
426
|
-
color: iconColor ?? '#fff',
|
|
427
|
-
['data-radial-animation']: `${uid}-cap-icon`,
|
|
428
|
-
['data-radian-index']: index,
|
|
429
|
-
icon,
|
|
430
|
-
isActive,
|
|
431
|
-
} as IRadialTreeRadianIconProps;
|
|
432
|
-
}
|
|
433
|
-
getLabelProps({ $rootProps }: { $rootProps: IRadialTreeProps }, index: number) {
|
|
434
|
-
const data = $rootProps.data![index];
|
|
435
|
-
const { xLabelCenter, yLabelCenter, labelAngle, isHorizontal } = this.computeRadianPosition(
|
|
436
|
-
data,
|
|
437
|
-
index,
|
|
438
|
-
);
|
|
439
|
-
const { uid, textSize } = this.asProps;
|
|
440
|
-
const { label } = data;
|
|
441
|
-
const color = data.color ?? this.asProps.color;
|
|
442
|
-
|
|
443
|
-
return {
|
|
444
|
-
x: xLabelCenter,
|
|
445
|
-
y: yLabelCenter,
|
|
446
|
-
angle: labelAngle,
|
|
447
|
-
['data-radial-animation']: `${uid}-label`,
|
|
448
|
-
['data-radian-index']: index,
|
|
449
|
-
label,
|
|
450
|
-
color,
|
|
451
|
-
isHorizontal,
|
|
452
|
-
textSize,
|
|
453
|
-
} as IRadialTreeRadianLabelProps;
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
getRadianKey(data: RadianData, index: number) {
|
|
457
|
-
return data.key ?? `radian-${index}`;
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
computeRadianPosition(data: RadianData, index: number) {
|
|
461
|
-
const { centralMargin, angleOffset, activeKey, size, radiansCount, textWidth } = this.asProps;
|
|
462
|
-
const [width, height] = size;
|
|
463
|
-
const key = this.getRadianKey(data, index);
|
|
464
|
-
const isActive = activeKey === key;
|
|
465
|
-
const baseCapSize = data.capSize ?? this.asProps.capSize;
|
|
466
|
-
const capSize = baseCapSize * (isActive ? 1 : 0.5);
|
|
467
|
-
|
|
468
|
-
const minDemSize = Math.min(width, height) / 2;
|
|
469
|
-
const length = Math.max(minDemSize - textWidth - baseCapSize - centralMargin, 10);
|
|
470
|
-
|
|
471
|
-
const angle = baseAngle + angleOffset + (index / radiansCount) * (Math.PI * 2);
|
|
472
|
-
const isHorizontal =
|
|
473
|
-
(angle - baseAngle > (1 / 6) * Math.PI && angle - baseAngle < (5 / 6) * Math.PI) ||
|
|
474
|
-
(angle - baseAngle > (7 / 6) * Math.PI && angle - baseAngle < (11 / 6) * Math.PI);
|
|
475
|
-
const topAngle = -Math.PI / 2;
|
|
476
|
-
const labelAngle = ((angle - topAngle) % Math.PI) + topAngle;
|
|
477
|
-
|
|
478
|
-
const center = [width / 2, height / 2];
|
|
479
|
-
const [xCenter, yCenter] = center;
|
|
480
|
-
const start = [
|
|
481
|
-
xCenter + Math.cos(angle) * centralMargin,
|
|
482
|
-
yCenter + Math.sin(angle) * centralMargin,
|
|
483
|
-
];
|
|
484
|
-
const end = [
|
|
485
|
-
xCenter + Math.cos(angle) * (centralMargin + length),
|
|
486
|
-
yCenter + Math.sin(angle) * (centralMargin + length),
|
|
487
|
-
];
|
|
488
|
-
const [xStart, yStart] = start;
|
|
489
|
-
const [xEnd, yEnd] = end;
|
|
490
|
-
|
|
491
|
-
const labelCenter = [
|
|
492
|
-
xCenter + Math.cos(angle) * (centralMargin + length + baseCapSize + textWidth / 2),
|
|
493
|
-
yCenter + Math.sin(angle) * (centralMargin + length + baseCapSize + textWidth / 2),
|
|
494
|
-
];
|
|
495
|
-
const [xLabelCenter, yLabelCenter] = labelCenter;
|
|
496
|
-
|
|
497
|
-
return {
|
|
498
|
-
xStart,
|
|
499
|
-
yStart,
|
|
500
|
-
xEnd,
|
|
501
|
-
yEnd,
|
|
502
|
-
xLabelCenter,
|
|
503
|
-
yLabelCenter,
|
|
504
|
-
labelAngle,
|
|
505
|
-
isHorizontal,
|
|
506
|
-
capSize,
|
|
507
|
-
isActive,
|
|
508
|
-
};
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
renderRadian(data: RadianData, index: number) {
|
|
512
|
-
const { styles, Children, onRadianClick } = this.asProps;
|
|
513
|
-
const key = this.getRadianKey(data, index);
|
|
514
|
-
const SRadian = 'g';
|
|
515
|
-
|
|
516
|
-
let children = getOriginChildren(Children);
|
|
517
|
-
|
|
518
|
-
if (typeof children === 'function') {
|
|
519
|
-
const _child = this.asProps.children;
|
|
520
|
-
const mergedProps = assignProps(children(this.asProps), this.asProps);
|
|
521
|
-
children = mergedProps.children;
|
|
522
|
-
mergedProps.children = _child;
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
// hidden from publicly typed export
|
|
526
|
-
const InteractiveArea = (RadialTree.Radian as any).InteractiveArea;
|
|
527
|
-
|
|
528
|
-
return sstyled(styles)(
|
|
529
|
-
<SRadian key={key} onClick={onRadianClick(key)}>
|
|
530
|
-
<InteractiveArea />
|
|
531
|
-
{children}
|
|
532
|
-
</SRadian>,
|
|
533
|
-
);
|
|
534
|
-
}
|
|
535
|
-
|
|
536
|
-
render() {
|
|
537
|
-
const { data } = this.asProps;
|
|
538
|
-
const SRadianList = 'g';
|
|
539
|
-
|
|
540
|
-
return sstyled(this.asProps.styles)(
|
|
541
|
-
<SRadianList>{data.map((data, index) => this.renderRadian(data, index))}</SRadianList>,
|
|
542
|
-
);
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
|
|
546
|
-
export interface IRadialTreeRadianInteractiveAreaProps {
|
|
547
|
-
x1?: number;
|
|
548
|
-
y1?: number;
|
|
549
|
-
x2?: number;
|
|
550
|
-
y2?: number;
|
|
551
|
-
strokeWidth?: number;
|
|
552
|
-
}
|
|
553
|
-
type RadialTreeRadianInteractiveAreaAsProps = IRadialTreeRadianInteractiveAreaProps & {
|
|
554
|
-
Element: React.FC<{ render: string } & React.SVGProps<any>>;
|
|
555
|
-
styles: React.CSSProperties;
|
|
556
|
-
};
|
|
557
|
-
const InteractiveArea: React.FC<RadialTreeRadianInteractiveAreaAsProps> = ({
|
|
558
|
-
Element: SInteractiveArea,
|
|
559
|
-
styles,
|
|
560
|
-
}) => {
|
|
561
|
-
return sstyled(styles)(
|
|
562
|
-
<SInteractiveArea stroke="transparent" render="line" />,
|
|
563
|
-
) as React.ReactElement;
|
|
564
|
-
};
|
|
565
|
-
|
|
566
|
-
export interface IRadialTreeRadianLineProps {
|
|
567
|
-
x1?: number;
|
|
568
|
-
y1?: number;
|
|
569
|
-
x2?: number;
|
|
570
|
-
y2?: number;
|
|
571
|
-
stroke?: string;
|
|
572
|
-
['data-radial-animation']?: `${string}-line`;
|
|
573
|
-
['data-radian-index']?: number;
|
|
574
|
-
}
|
|
575
|
-
type RadialTreeRadianLineAsProps = IRadialTreeRadianLineProps & {
|
|
576
|
-
Element: React.FC<{ render: string } & React.SVGProps<any>>;
|
|
577
|
-
styles: React.CSSProperties;
|
|
578
|
-
};
|
|
579
|
-
const Line: React.FC<RadialTreeRadianLineAsProps> = ({ Element: SLine, styles, stroke }) => {
|
|
580
|
-
return sstyled(styles)(<SLine render="line" stroke={stroke} />) as React.ReactElement;
|
|
581
|
-
};
|
|
582
|
-
|
|
583
|
-
export interface IRadialTreeRadianCapProps {
|
|
584
|
-
x?: number;
|
|
585
|
-
y?: number;
|
|
586
|
-
radius?: number;
|
|
587
|
-
color?: string;
|
|
588
|
-
['data-radial-animation']?: `${string}-cap-circle`;
|
|
589
|
-
['data-radian-index']?: number;
|
|
590
|
-
}
|
|
591
|
-
type RadialTreeRadianCapAsProps = IRadialTreeRadianCapProps & {
|
|
592
|
-
Element: React.FC<{ render: string } & React.SVGProps<any>>;
|
|
593
|
-
styles: React.CSSProperties;
|
|
594
|
-
};
|
|
595
|
-
const Cap: React.FC<RadialTreeRadianCapAsProps> = ({
|
|
596
|
-
Element: SCap,
|
|
597
|
-
styles,
|
|
598
|
-
x,
|
|
599
|
-
y,
|
|
600
|
-
radius,
|
|
601
|
-
color,
|
|
602
|
-
}) => {
|
|
603
|
-
return sstyled(styles)(
|
|
604
|
-
<SCap render="circle" cx={x} cy={y} r={radius} fill={color} />,
|
|
605
|
-
) as React.ReactElement;
|
|
606
|
-
};
|
|
607
|
-
|
|
608
|
-
export interface IRadialTreeRadianIconProps {
|
|
609
|
-
x?: number;
|
|
610
|
-
y?: number;
|
|
611
|
-
iconSize?: number;
|
|
612
|
-
color?: string;
|
|
613
|
-
['data-radial-animation']?: `${string}-cap-icon`;
|
|
614
|
-
['data-radian-index']?: number;
|
|
615
|
-
tag?: React.FC;
|
|
616
|
-
isActive?: boolean;
|
|
617
|
-
}
|
|
618
|
-
type RadialTreeRadianIconAsProps = IRadialTreeRadianIconProps & {
|
|
619
|
-
Element: React.FC<{ render: string | React.FC } & React.SVGProps<any>>;
|
|
620
|
-
x: number;
|
|
621
|
-
y: number;
|
|
622
|
-
iconSize: number;
|
|
623
|
-
styles: React.CSSProperties;
|
|
624
|
-
};
|
|
625
|
-
const Icon: React.FC<RadialTreeRadianIconAsProps> = ({
|
|
626
|
-
Element: SIcon,
|
|
627
|
-
styles,
|
|
628
|
-
isActive,
|
|
629
|
-
tag,
|
|
630
|
-
x,
|
|
631
|
-
y,
|
|
632
|
-
iconSize,
|
|
633
|
-
}) => {
|
|
634
|
-
if (!(isActive && tag)) return null;
|
|
635
|
-
const width = iconSize;
|
|
636
|
-
const height = iconSize;
|
|
637
|
-
return sstyled(styles)(
|
|
638
|
-
<SIcon x={x} y={y} width={width} height={height} render={tag} />,
|
|
639
|
-
) as React.ReactElement;
|
|
640
|
-
};
|
|
641
|
-
|
|
642
|
-
export interface IRadialTreeRadianLabelProps {
|
|
643
|
-
x?: number;
|
|
644
|
-
y?: number;
|
|
645
|
-
color?: string;
|
|
646
|
-
textSize?: number;
|
|
647
|
-
['data-radial-animation']?: `${string}-label`;
|
|
648
|
-
['data-radian-index']?: number;
|
|
649
|
-
label?: string;
|
|
650
|
-
isHorizontal?: boolean;
|
|
651
|
-
angle?: number;
|
|
652
|
-
}
|
|
653
|
-
type RadialTreeRadianLabelAsProps = IRadialTreeRadianLabelProps & {
|
|
654
|
-
Element: React.FC<{ render: string } & React.SVGProps<any>>;
|
|
655
|
-
Children: React.FC;
|
|
656
|
-
styles: React.CSSProperties;
|
|
657
|
-
x: number;
|
|
658
|
-
y: number;
|
|
659
|
-
angle: number;
|
|
660
|
-
textSize: number;
|
|
661
|
-
};
|
|
662
|
-
const Label: React.FC<RadialTreeRadianLabelAsProps> = ({
|
|
663
|
-
Element: SLabel,
|
|
664
|
-
Children,
|
|
665
|
-
styles,
|
|
666
|
-
label,
|
|
667
|
-
color,
|
|
668
|
-
isHorizontal,
|
|
669
|
-
x,
|
|
670
|
-
y,
|
|
671
|
-
textSize,
|
|
672
|
-
angle,
|
|
673
|
-
}) => {
|
|
674
|
-
const lines = String(label).split('\n');
|
|
675
|
-
const linesCount = lines.length;
|
|
676
|
-
const SLabelLine = 'tspan';
|
|
677
|
-
|
|
678
|
-
const sstyles = sstyled(styles);
|
|
679
|
-
const sLabelStyles = sstyles.cn('SLabel', {
|
|
680
|
-
color,
|
|
681
|
-
'color-hovered': shade(color, -0.12),
|
|
682
|
-
'text-cursor': isHorizontal ? 'text' : 'vertical-text',
|
|
683
|
-
'transform-origin': `${x.toFixed(2)}px ${y.toFixed(2)}px`,
|
|
684
|
-
});
|
|
685
|
-
|
|
686
|
-
return (
|
|
687
|
-
<SLabel
|
|
688
|
-
render="text"
|
|
689
|
-
textAnchor="middle"
|
|
690
|
-
dominantBaseline="central"
|
|
691
|
-
className={sLabelStyles.className}
|
|
692
|
-
style={sLabelStyles.style}
|
|
693
|
-
x={x.toFixed(2)}
|
|
694
|
-
y={y.toFixed(2)}
|
|
695
|
-
transform={`rotate(${((angle / Math.PI) * 180).toFixed(2)})`}
|
|
696
|
-
>
|
|
697
|
-
{lines.map((lineText, lineIndex) => (
|
|
698
|
-
<SLabelLine
|
|
699
|
-
x={x}
|
|
700
|
-
y={y + (lineIndex - (linesCount - 1) / 2) * textSize}
|
|
701
|
-
key={`#${lineIndex}-${lineText}`}
|
|
702
|
-
>
|
|
703
|
-
{lineText}
|
|
704
|
-
</SLabelLine>
|
|
705
|
-
))}
|
|
706
|
-
<Children />
|
|
707
|
-
</SLabel>
|
|
708
|
-
) as React.ReactElement;
|
|
709
|
-
};
|
|
710
|
-
|
|
711
|
-
const Radian = createElement(RadialTreeRadian, {
|
|
712
|
-
InteractiveArea,
|
|
713
|
-
Line,
|
|
714
|
-
Cap,
|
|
715
|
-
Icon,
|
|
716
|
-
Label,
|
|
717
|
-
});
|
|
718
|
-
|
|
719
|
-
export interface IRadialTreeTitleProps {
|
|
720
|
-
x?: number;
|
|
721
|
-
y?: number;
|
|
722
|
-
textSize?: number;
|
|
723
|
-
['data-radial-animation']?: `${string}-label`;
|
|
724
|
-
color?: string;
|
|
725
|
-
}
|
|
726
|
-
type RadialTreeTitleAsProps = IRadialTreeTitleProps & {
|
|
727
|
-
Element: React.FC<{ render: string } & React.SVGProps<any>>;
|
|
728
|
-
Children: React.FC;
|
|
729
|
-
styles: React.CSSProperties;
|
|
730
|
-
};
|
|
731
|
-
const Title: React.FC<RadialTreeTitleAsProps> = ({
|
|
732
|
-
Element: STitle,
|
|
733
|
-
Children,
|
|
734
|
-
styles,
|
|
735
|
-
textSize,
|
|
736
|
-
color,
|
|
737
|
-
x,
|
|
738
|
-
y,
|
|
739
|
-
}) => {
|
|
740
|
-
return sstyled(styles)(
|
|
741
|
-
<STitle
|
|
742
|
-
render="text"
|
|
743
|
-
textAnchor="middle"
|
|
744
|
-
dominantBaseline="central"
|
|
745
|
-
fontSize={textSize}
|
|
746
|
-
fill={color}
|
|
747
|
-
x={x}
|
|
748
|
-
y={y}
|
|
749
|
-
>
|
|
750
|
-
<Children />
|
|
751
|
-
</STitle>,
|
|
752
|
-
) as React.ReactElement;
|
|
753
|
-
};
|
|
754
|
-
|
|
755
|
-
const RadialTree = createElement(RadialTreeBase, { Title, Radian }) as (<T>(
|
|
756
|
-
props: CProps<IRadialTreeProps & T>,
|
|
757
|
-
) => ReturnEl) & {
|
|
758
|
-
Title: <T>(props: CProps<IRadialTreeTitleProps & T>) => ReturnEl;
|
|
759
|
-
Radian: (<T>(props: CProps<IRadialTreeRadianProps & T>) => ReturnEl) & {
|
|
760
|
-
Line: <T>(props: CProps<IRadialTreeRadianLineProps & T>) => ReturnEl;
|
|
761
|
-
Cap: <T>(props: CProps<IRadialTreeRadianCapProps & T>) => ReturnEl;
|
|
762
|
-
Icon: <T>(props: CProps<IRadialTreeRadianIconProps & T>) => ReturnEl;
|
|
763
|
-
Label: <T>(props: CProps<IRadialTreeRadianLabelProps & T>) => ReturnEl;
|
|
764
|
-
};
|
|
765
|
-
};
|
|
766
|
-
|
|
767
|
-
export default RadialTree;
|