1 | import React from "react";
|
2 | import { View } from "react-native";
|
3 | import { Svg, Rect, G } from "react-native-svg";
|
4 | import AbstractChart from "./abstract-chart";
|
5 |
|
6 | const barWidth = 32;
|
7 |
|
8 | class BarChart extends AbstractChart {
|
9 | getBarPercentage = () => {
|
10 | const { barPercentage = 1 } = this.props.chartConfig;
|
11 | return barPercentage;
|
12 | };
|
13 |
|
14 | renderBars = config => {
|
15 | const { data, width, height, paddingTop, paddingRight } = config;
|
16 | const baseHeight = this.calcBaseHeight(data, height);
|
17 | return data.map((x, i) => {
|
18 | const barHeight = this.calcHeight(x, data, height);
|
19 | const barWidth = 32 * this.getBarPercentage();
|
20 | return (
|
21 | <Rect
|
22 | key={Math.random()}
|
23 | x={
|
24 | paddingRight +
|
25 | (i * (width - paddingRight)) / data.length +
|
26 | barWidth / 2
|
27 | }
|
28 | y={
|
29 | ((barHeight > 0 ? baseHeight - barHeight : baseHeight) / 4) * 3 +
|
30 | paddingTop
|
31 | }
|
32 | width={barWidth}
|
33 | height={(Math.abs(barHeight) / 4) * 3}
|
34 | fill="url(#fillShadowGradient)"
|
35 | />
|
36 | );
|
37 | });
|
38 | };
|
39 |
|
40 | renderBarTops = config => {
|
41 | const { data, width, height, paddingTop, paddingRight } = config;
|
42 | const baseHeight = this.calcBaseHeight(data, height);
|
43 | return data.map((x, i) => {
|
44 | const barHeight = this.calcHeight(x, data, height);
|
45 | const barWidth = 32 * this.getBarPercentage();
|
46 | return (
|
47 | <Rect
|
48 | key={Math.random()}
|
49 | x={
|
50 | paddingRight +
|
51 | (i * (width - paddingRight)) / data.length +
|
52 | barWidth / 2
|
53 | }
|
54 | y={((baseHeight - barHeight) / 4) * 3 + paddingTop}
|
55 | width={barWidth}
|
56 | height={2}
|
57 | fill={this.props.chartConfig.color(0.6)}
|
58 | />
|
59 | );
|
60 | });
|
61 | };
|
62 |
|
63 | render() {
|
64 | const {
|
65 | width,
|
66 | height,
|
67 | data,
|
68 | style = {},
|
69 | withHorizontalLabels = true,
|
70 | withVerticalLabels = true,
|
71 | verticalLabelRotation = 0,
|
72 | horizontalLabelRotation = 0,
|
73 | withInnerLines = true
|
74 | } = this.props;
|
75 | const { borderRadius = 0, paddingTop = 16, paddingRight = 64 } = style;
|
76 | const config = {
|
77 | width,
|
78 | height,
|
79 | verticalLabelRotation,
|
80 | horizontalLabelRotation
|
81 | };
|
82 | return (
|
83 | <View style={style}>
|
84 | <Svg height={height} width={width}>
|
85 | {this.renderDefs({
|
86 | ...config,
|
87 | ...this.props.chartConfig
|
88 | })}
|
89 | <Rect
|
90 | width="100%"
|
91 | height={height}
|
92 | rx={borderRadius}
|
93 | ry={borderRadius}
|
94 | fill="url(#backgroundGradient)"
|
95 | />
|
96 | <G>
|
97 | {withInnerLines
|
98 | ? this.renderHorizontalLines({
|
99 | ...config,
|
100 | count: 4,
|
101 | paddingTop
|
102 | })
|
103 | : null}
|
104 | </G>
|
105 | <G>
|
106 | {withHorizontalLabels
|
107 | ? this.renderHorizontalLabels({
|
108 | ...config,
|
109 | count: 4,
|
110 | data: data.datasets[0].data,
|
111 | paddingTop,
|
112 | paddingRight
|
113 | })
|
114 | : null}
|
115 | </G>
|
116 | <G>
|
117 | {withVerticalLabels
|
118 | ? this.renderVerticalLabels({
|
119 | ...config,
|
120 | labels: data.labels,
|
121 | paddingRight,
|
122 | paddingTop,
|
123 | horizontalOffset: barWidth * this.getBarPercentage()
|
124 | })
|
125 | : null}
|
126 | </G>
|
127 | <G>
|
128 | {this.renderBars({
|
129 | ...config,
|
130 | data: data.datasets[0].data,
|
131 | paddingTop,
|
132 | paddingRight
|
133 | })}
|
134 | </G>
|
135 | <G>
|
136 | {this.renderBarTops({
|
137 | ...config,
|
138 | data: data.datasets[0].data,
|
139 | paddingTop,
|
140 | paddingRight
|
141 | })}
|
142 | </G>
|
143 | </Svg>
|
144 | </View>
|
145 | );
|
146 | }
|
147 | }
|
148 |
|
149 | export default BarChart;
|