UNPKG

4.16 kBJavaScriptView Raw
1import React from "react";
2import { View } from "react-native";
3import { Svg, Rect, G, Text } from "react-native-svg";
4import AbstractChart from "./abstract-chart";
5
6const barWidth = 32;
7
8class StackedBarChart extends AbstractChart {
9 renderBars = config => {
10 const {
11 data,
12 width,
13 height,
14 paddingTop,
15 paddingRight,
16 border,
17 colors
18 } = config;
19 return data.map((x, i) => {
20 const barWidth = 32;
21 const ret = [];
22 let h = 0;
23 let st = paddingTop;
24 for (let z = 0; z < x.length; z++) {
25 h = (height - 55) * (x[z] / border);
26 const y = (height / 4) * 3 - h + st;
27 const xC =
28 (paddingRight +
29 (i * (width - paddingRight)) / data.length +
30 barWidth / 2) *
31 0.7;
32 ret.push(
33 <Rect
34 key={Math.random()}
35 x={xC}
36 y={y}
37 width={barWidth}
38 height={h}
39 fill={colors[z]}
40 />
41 );
42 ret.push(
43 <Text
44 key={Math.random()}
45 x={xC + 7 + barWidth / 2}
46 textAnchor="end"
47 y={h > 15 ? y + 15 : y + 7}
48 {...this.getPropsForLabels()}
49 >
50 {x[z]}
51 </Text>
52 );
53
54 st -= h;
55 }
56
57 return ret;
58 });
59 };
60
61 renderLegend = config => {
62 const { legend, colors, width, height } = config;
63 return legend.map((x, i) => {
64 return (
65 <G key={Math.random()}>
66 <Rect
67 width="16px"
68 height="16px"
69 fill={colors[i]}
70 rx={8}
71 ry={8}
72 x={width * 0.71}
73 y={height * 0.7 - i * 50}
74 />
75 <Text
76 x={width * 0.78}
77 y={height * 0.76 - i * 50}
78 {...this.getPropsForLabels()}
79 >
80 {x}
81 </Text>
82 </G>
83 );
84 });
85 };
86
87 render() {
88 const paddingTop = 15;
89 const paddingRight = 50;
90 const {
91 width,
92 height,
93 style = {},
94 data,
95 withHorizontalLabels = true,
96 withVerticalLabels = true
97 } = this.props;
98 const { borderRadius = 0 } = style;
99 const config = {
100 width,
101 height
102 };
103 let border = 0;
104 for (let i = 0; i < data.data.length; i++) {
105 const actual = data.data[i].reduce((pv, cv) => pv + cv, 0);
106 if (actual > border) {
107 border = actual;
108 }
109 }
110
111 return (
112 <View style={style}>
113 <Svg height={height} width={width}>
114 {this.renderDefs({
115 ...config,
116 ...this.props.chartConfig
117 })}
118 <Rect
119 width="100%"
120 height={height}
121 rx={borderRadius}
122 ry={borderRadius}
123 fill="url(#backgroundGradient)"
124 />
125 <G>
126 {this.renderHorizontalLines({
127 ...config,
128 count: 4,
129 paddingTop
130 })}
131 </G>
132 <G>
133 {withHorizontalLabels
134 ? this.renderHorizontalLabels({
135 ...config,
136 count: 4,
137 data: [0, border],
138 paddingTop,
139 paddingRight
140 })
141 : null}
142 </G>
143 <G>
144 {withVerticalLabels
145 ? this.renderVerticalLabels({
146 ...config,
147 labels: data.labels,
148 paddingRight: paddingRight + 28,
149 stackedBar: true,
150 paddingTop,
151 horizontalOffset: barWidth
152 })
153 : null}
154 </G>
155 <G>
156 {this.renderBars({
157 ...config,
158 data: data.data,
159 border,
160 colors: this.props.data.barColors,
161 paddingTop,
162 paddingRight: paddingRight + 20
163 })}
164 </G>
165 {this.renderLegend({
166 ...config,
167 legend: data.legend,
168 colors: this.props.data.barColors
169 })}
170 </Svg>
171 </View>
172 );
173 }
174}
175export default StackedBarChart;