1 | import React from "react";
|
2 | import { View } from "react-native";
|
3 | import { Svg, Text, G, Rect, Path } from "react-native-svg";
|
4 | import AbstractChart from "./abstract-chart";
|
5 |
|
6 | const Pie = require("paths-js/pie");
|
7 |
|
8 | class ProgressChart extends AbstractChart {
|
9 | render() {
|
10 | const { width, height, style = {}, data, hideLegend } = this.props;
|
11 | const { borderRadius = 0, margin = 0, marginRight = 0 } = style;
|
12 |
|
13 | if (Array.isArray(data)) {
|
14 | data = {
|
15 | data
|
16 | };
|
17 | }
|
18 |
|
19 | const pies = data.data.map((pieData, i) => {
|
20 | const r = ((height / 2 - 32) / data.data.length) * i + 32;
|
21 | return Pie({
|
22 | r,
|
23 | R: r,
|
24 | center: [0, 0],
|
25 | data: [pieData, 1 - pieData],
|
26 | accessor(x) {
|
27 | return x;
|
28 | }
|
29 | });
|
30 | });
|
31 |
|
32 | const pieBackgrounds = data.data.map((pieData, i) => {
|
33 | const r = ((height / 2 - 32) / data.data.length) * i + 32;
|
34 | return Pie({
|
35 | r,
|
36 | R: r,
|
37 | center: [0, 0],
|
38 | data: [0.999, 0.001],
|
39 | accessor(x) {
|
40 | return x;
|
41 | }
|
42 | });
|
43 | });
|
44 |
|
45 | const withLabel = i => data.labels && data.labels[i];
|
46 |
|
47 | const legend = !hideLegend && (
|
48 | <>
|
49 | <G>
|
50 | {pies.map((_, i) => {
|
51 | return (
|
52 | <Rect
|
53 | key={Math.random()}
|
54 | width="16px"
|
55 | height="16px"
|
56 | fill={this.props.chartConfig.color(0.2 * (i + 1), i)}
|
57 | rx={8}
|
58 | ry={8}
|
59 | x={this.props.width / 2.5 - 24}
|
60 | y={
|
61 | -(this.props.height / 2.5) +
|
62 | ((this.props.height * 0.8) / data.data.length) * i +
|
63 | 12
|
64 | }
|
65 | />
|
66 | );
|
67 | })}
|
68 | </G>
|
69 | <G>
|
70 | {pies.map((_, i) => {
|
71 | return (
|
72 | <Text
|
73 | key={Math.random()}
|
74 | x={this.props.width / 2.5}
|
75 | y={
|
76 | -(this.props.height / 2.5) +
|
77 | ((this.props.height * 0.8) / data.data.length) * i +
|
78 | 12 * 2
|
79 | }
|
80 | {...this.getPropsForLabels()}
|
81 | >
|
82 | {withLabel(i)
|
83 | ? `${data.labels[i]} ${Math.round(100 * data.data[i])}%`
|
84 | : `${Math.round(100 * data.data[i])}%`}
|
85 | </Text>
|
86 | );
|
87 | })}
|
88 | </G>
|
89 | </>
|
90 | );
|
91 |
|
92 | return (
|
93 | <View
|
94 | style={{
|
95 | width,
|
96 | height,
|
97 | padding: 0,
|
98 | ...style
|
99 | }}
|
100 | >
|
101 | <Svg width={width - margin * 2 - marginRight} height={height}>
|
102 | {this.renderDefs({
|
103 | width: this.props.height,
|
104 | height: this.props.height,
|
105 | ...this.props.chartConfig
|
106 | })}
|
107 | <Rect
|
108 | width="100%"
|
109 | height={this.props.height}
|
110 | rx={borderRadius}
|
111 | ry={borderRadius}
|
112 | fill="url(#backgroundGradient)"
|
113 | />
|
114 | <G x={this.props.width / 2.5} y={this.props.height / 2}>
|
115 | <G>
|
116 | {pieBackgrounds.map((pie, i) => {
|
117 | return (
|
118 | <Path
|
119 | key={Math.random()}
|
120 | d={pie.curves[0].sector.path.print()}
|
121 | strokeWidth={16}
|
122 | stroke={this.props.chartConfig.color(0.2, i)}
|
123 | />
|
124 | );
|
125 | })}
|
126 | </G>
|
127 | <G>
|
128 | {pies.map((pie, i) => {
|
129 | return (
|
130 | <Path
|
131 | key={Math.random()}
|
132 | strokeLinecap="round"
|
133 | strokeLinejoin="round"
|
134 | d={pie.curves[0].sector.path.print()}
|
135 | strokeWidth={16}
|
136 | stroke={this.props.chartConfig.color(
|
137 | (i / pies.length) * 0.5 + 0.5,
|
138 | i
|
139 | )}
|
140 | />
|
141 | );
|
142 | })}
|
143 | </G>
|
144 | {legend}
|
145 | </G>
|
146 | </Svg>
|
147 | </View>
|
148 | );
|
149 | }
|
150 | }
|
151 |
|
152 | export default ProgressChart;
|