1 | import React from "react";
|
2 | import { View } from "react-native";
|
3 | import { Svg, Rect, Text, G, Path } from "react-native-svg";
|
4 | import AbstractChart from "./abstract-chart";
|
5 |
|
6 | const Pie = require("paths-js/pie");
|
7 |
|
8 | class PieChart extends AbstractChart {
|
9 | render() {
|
10 | const {
|
11 | style = {},
|
12 | backgroundColor,
|
13 | absolute = false,
|
14 | hasLegend = true
|
15 | } = this.props;
|
16 | const { borderRadius = 0 } = style;
|
17 | const chart = Pie({
|
18 | center: this.props.center || [0, 0],
|
19 | r: 0,
|
20 | R: this.props.height / 2.5,
|
21 | data: this.props.data,
|
22 | accessor: x => {
|
23 | return x[this.props.accessor];
|
24 | }
|
25 | });
|
26 | const total = this.props.data.reduce((sum, item) => {
|
27 | return sum + item[this.props.accessor];
|
28 | }, 0);
|
29 | const slices = chart.curves.map((c, i) => {
|
30 | let value;
|
31 | if (absolute) {
|
32 | value = c.item[this.props.accessor];
|
33 | } else {
|
34 | if (total === 0) {
|
35 | value = 0 + "%";
|
36 | } else {
|
37 | value = Math.round((100 / total) * c.item[this.props.accessor]) + "%";
|
38 | }
|
39 | }
|
40 |
|
41 | return (
|
42 | <G key={Math.random()}>
|
43 | <Path d={c.sector.path.print()} fill={c.item.color} />
|
44 | {hasLegend ? (
|
45 | <Rect
|
46 | width="16px"
|
47 | height="16px"
|
48 | fill={c.item.color}
|
49 | rx={8}
|
50 | ry={8}
|
51 | x={this.props.width / 2.5 - 24}
|
52 | y={
|
53 | -(this.props.height / 2.5) +
|
54 | ((this.props.height * 0.8) / this.props.data.length) * i +
|
55 | 12
|
56 | }
|
57 | />
|
58 | ) : null}
|
59 | {hasLegend ? (
|
60 | <Text
|
61 | fill={c.item.legendFontColor}
|
62 | fontSize={c.item.legendFontSize}
|
63 | x={this.props.width / 2.5}
|
64 | y={
|
65 | -(this.props.height / 2.5) +
|
66 | ((this.props.height * 0.8) / this.props.data.length) * i +
|
67 | 12 * 2
|
68 | }
|
69 | >
|
70 | {`${value} ${c.item.name}`}
|
71 | </Text>
|
72 | ) : null}
|
73 | </G>
|
74 | );
|
75 | });
|
76 | return (
|
77 | <View
|
78 | style={{
|
79 | width: this.props.width,
|
80 | height: this.props.height,
|
81 | padding: 0,
|
82 | ...style
|
83 | }}
|
84 | >
|
85 | <Svg width={this.props.width} height={this.props.height}>
|
86 | <G>
|
87 | {this.renderDefs({
|
88 | width: this.props.height,
|
89 | height: this.props.height,
|
90 | ...this.props.chartConfig
|
91 | })}
|
92 | </G>
|
93 | <Rect
|
94 | width="100%"
|
95 | height={this.props.height}
|
96 | rx={borderRadius}
|
97 | ry={borderRadius}
|
98 | fill={backgroundColor}
|
99 | />
|
100 | <G
|
101 | x={
|
102 | this.props.width / 2 / 2 +
|
103 | Number(this.props.paddingLeft ? this.props.paddingLeft : 0)
|
104 | }
|
105 | y={this.props.height / 2}
|
106 | >
|
107 | {slices}
|
108 | </G>
|
109 | </Svg>
|
110 | </View>
|
111 | );
|
112 | }
|
113 | }
|
114 |
|
115 | export default PieChart;
|