/
PieChart.js
87 lines (68 loc) · 2.06 KB
/
PieChart.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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import store from '../../data/store';
import {
div,
svg,
path,
circle,
} from '../../utils/elements';
import swapNodes from '../../utils/swapNodes';
if (process.env.IMPORT_SCSS) require(`./PieChart.scss`); // eslint-disable-line global-require
const PieChart = (item) => {
let el;
const render = () => {
const scoreSummary = store.getScoreSummary(item.id);
const total = scoreSummary.total;
if (
!scoreSummary ||
!scoreSummary.results.length ||
!store.scoresLoadedFromDisk ||
total === 0
) return div({ className: `pie-chart` });
let slices;
// Note the svg viewBox is offset so the center of the SVG is 0,0
if (scoreSummary.results && scoreSummary.results.length === 1) {
// if there's only one slice, that's a circle
slices = circle({
r: 1,
style: {
fill: scoreSummary.results[0].score.color || ``, // set empty string to make iOS ignore fill
},
});
} else {
// if there's more than one slice, render paths/arcs
let cumulativeRadians = 0;
slices = scoreSummary.results.map((slice) => {
const percent = slice.count / total;
const startX = Math.cos(cumulativeRadians);
const startY = Math.sin(cumulativeRadians);
cumulativeRadians += 2 * Math.PI * percent;
const endX = Math.cos(cumulativeRadians);
const endY = Math.sin(cumulativeRadians);
const largeArcFlag = percent > 0.5 ? 1 : 0;
const d = [
`M ${startX} ${startY}`,
`A 1 1 0 ${largeArcFlag} 1 ${endX} ${endY}`,
`L 0 0`,
].join(` `);
return path({
d,
style: {
fill: slice.score.color || ``, // set empty string to make iOS ignore fill
},
});
});
}
const result = div({ className: `pie-chart` },
svg({ viewBox: `-1 -1 2 2` },
slices,
),
);
return result;
};
store.listen(`PIE-${item.id}`, () => {
el = swapNodes(el, render());
});
el = render();
return el;
};
export default PieChart;