-
Notifications
You must be signed in to change notification settings - Fork 689
/
pack.js
69 lines (63 loc) 路 1.84 KB
/
pack.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import React from 'react';
import { Group } from '@vx/group';
import { Pack } from '@vx/hierarchy';
import { hierarchy } from 'd3-hierarchy';
import { scaleQuantize } from '@vx/scale';
import { exoplanets as data } from '@vx/mock-data';
const extent = (allData, value = d => d) => [
Math.min(...allData.map(value)),
Math.max(...allData.map(value)),
];
const exoplanets = data.filter(d => d.distance === 0);
const planets = data.filter(d => d.distance !== 0);
const pack = { children: [{ children: planets }].concat(exoplanets) };
const colorScale = scaleQuantize({
domain: extent(data, d => d.radius),
range: ['#ffe108', '#ffc10e', '#fd6d6f', '#855af2', '#11d2f9', '#49f4e7'],
});
export default ({
width,
height,
margin = {
top: 10,
left: 30,
right: 40,
bottom: 80,
},
}) => {
if (width < 10) return null;
const root = hierarchy(pack)
.sum(d => d.radius * d.radius)
.sort((a, b) => {
return (
!a.children - !b.children ||
Math.isNaN(a.data.distance) - Math.isNaN(b.data.distance) ||
a.data.distance - b.data.distance
);
});
return (
<svg width={width} height={height}>
<rect width={width} height={height} rx={14} fill="#ffffff" />
<Pack root={root} size={[width * 2, height * 2]}>
{packData => {
const circles = packData.descendants().slice(2);
return (
<Group top={-height - margin.bottom} left={-width / 2}>
{circles.map((circle, i) => {
return (
<circle
key={`cir-${i}`}
r={circle.r}
cx={circle.x}
cy={circle.y}
fill={colorScale(circle.data.radius)}
/>
);
})}
</Group>
);
}}
</Pack>
</svg>
);
};