1
|
|
|
import React, { useState, useContext, useEffect, useRef } from 'react'; |
2
|
|
|
import { rgbaColor, themeColors } from '../../../helpers/utils'; |
3
|
|
|
import { Row, Col, Card, CardBody, CustomInput } from 'reactstrap'; |
4
|
|
|
import { |
5
|
|
|
Chart as ChartJS, |
6
|
|
|
CategoryScale, |
7
|
|
|
LinearScale, |
8
|
|
|
BarElement, |
9
|
|
|
Title, |
10
|
|
|
Tooltip, |
11
|
|
|
Legend, |
12
|
|
|
LogarithmicScale |
13
|
|
|
} from 'chart.js'; |
14
|
|
|
import AppContext from '../../../context/Context'; |
15
|
|
|
import { Bar } from 'react-chartjs-2'; |
16
|
|
|
|
17
|
|
|
ChartJS.register( |
18
|
|
|
CategoryScale, |
19
|
|
|
LinearScale, |
20
|
|
|
BarElement, |
21
|
|
|
Title, |
22
|
|
|
Tooltip, |
23
|
|
|
Legend, |
24
|
|
|
LogarithmicScale |
25
|
|
|
); |
26
|
|
|
|
27
|
|
|
const BarChart = ({ |
28
|
|
|
labels, |
29
|
|
|
data, |
30
|
|
|
compareData, |
31
|
|
|
title, |
32
|
|
|
compareTitle, |
33
|
|
|
footnote, |
34
|
|
|
footunit, |
35
|
|
|
}) => { |
36
|
|
|
|
37
|
|
|
const { isDark } = useContext(AppContext); |
38
|
|
|
const chartRef = useRef(null); |
39
|
|
|
const [chartData, setChartData] = useState({ |
40
|
|
|
datasets: [{ |
41
|
|
|
data: [0, 0, 0, 0, 0, 0], |
42
|
|
|
backgroundColor: 'rgba(255, 99, 132, 0.2)', |
43
|
|
|
borderColor: 'rgba(255, 99, 132, 1)', |
44
|
|
|
borderWidth: 1, |
45
|
|
|
}] |
46
|
|
|
}); |
47
|
|
|
|
48
|
|
|
useEffect(() => { |
49
|
|
|
const chart = chartRef.current; |
50
|
|
|
let dataArray = []; |
51
|
|
|
let datasets = []; |
52
|
|
|
let color = rgbaColor("#"+((1<<24)*Math.random()|0).toString(16), 0.8); |
53
|
|
|
if (chart) { |
54
|
|
|
const ctx = chart.ctx; |
55
|
|
|
const gradientFill = isDark |
56
|
|
|
? ctx.createLinearGradient(0, 0, 0, ctx.canvas.height) |
57
|
|
|
: ctx.createLinearGradient(0, 0, 0, 250); |
58
|
|
|
gradientFill.addColorStop(0, isDark ? 'rgba(44,123,229, 0.5)' : 'rgba(255, 255, 255, 0.3)'); |
59
|
|
|
gradientFill.addColorStop(1, isDark ? 'transparent' : 'rgba(255, 255, 255, 0)'); |
60
|
|
|
data.forEach(element => { |
61
|
|
|
dataArray.push(element['subtotal']); |
62
|
|
|
}); |
63
|
|
|
datasets.push({ |
64
|
|
|
label: title, |
65
|
|
|
data: dataArray, |
66
|
|
|
backgroundColor: color, |
67
|
|
|
borderColor: color, |
68
|
|
|
borderWidth: 1, |
69
|
|
|
}); |
70
|
|
|
dataArray = []; |
71
|
|
|
color = rgbaColor("#"+((1<<24)*Math.random()|0).toString(16), 0.8); |
72
|
|
|
compareData.forEach(element => { |
73
|
|
|
dataArray.push(element['subtotal']); |
74
|
|
|
}); |
75
|
|
|
datasets.push({ |
76
|
|
|
label: compareTitle, |
77
|
|
|
data: dataArray, |
78
|
|
|
backgroundColor: color, |
79
|
|
|
borderColor: color, |
80
|
|
|
borderWidth: 1, |
81
|
|
|
}); |
82
|
|
|
setChartData({ |
83
|
|
|
labels: labels, |
84
|
|
|
datasets: datasets |
85
|
|
|
}) |
86
|
|
|
} |
87
|
|
|
}, [data, compareData]); |
88
|
|
|
|
89
|
|
|
const config = { |
90
|
|
|
options: { |
91
|
|
|
scales: { |
92
|
|
|
x: { |
93
|
|
|
display: true, |
94
|
|
|
ticks: { |
95
|
|
|
fontColor: rgbaColor('#fff', 0.8), |
96
|
|
|
fontStyle: 600, |
97
|
|
|
color: isDark ? themeColors.light : themeColors.dark |
98
|
|
|
}, |
99
|
|
|
}, |
100
|
|
|
y: { |
101
|
|
|
display: true, |
102
|
|
|
gridLines: { |
103
|
|
|
color: rgbaColor('#000', 0.1) |
104
|
|
|
}, |
105
|
|
|
type: 'logarithmic', |
106
|
|
|
ticks: { |
107
|
|
|
color: isDark ? themeColors.light : themeColors.dark |
108
|
|
|
} |
109
|
|
|
}, |
110
|
|
|
}, |
111
|
|
|
plugins: { |
112
|
|
|
tooltip: { |
113
|
|
|
callbacks: { |
114
|
|
|
label: function(tooltipItem) { |
115
|
|
|
let arr = {}; |
116
|
|
|
if (tooltipItem.dataset.label === title) { |
117
|
|
|
arr = data[tooltipItem.dataIndex]; |
118
|
|
|
} else { |
119
|
|
|
arr = compareData[tooltipItem.dataIndex]; |
120
|
|
|
} |
121
|
|
|
return tooltipItem.dataset.label + ': ' + arr.name + ' ' + arr.subtotal + arr.unit; |
122
|
|
|
}, |
123
|
|
|
footer: function(tooltipItem) { |
124
|
|
|
let arr = {}; |
125
|
|
|
if (tooltipItem[0].dataset.label === title) { |
126
|
|
|
arr = data[tooltipItem[0].dataIndex]; |
127
|
|
|
} else { |
128
|
|
|
arr = compareData[tooltipItem[0].dataIndex]; |
129
|
|
|
} |
130
|
|
|
let rate = arr['increment_rate'] ? arr['increment_rate'] + '\n' : ''; |
131
|
|
|
let perUnit_area = Math.round((arr['subtotal_per_unit_area'] + Number.EPSILON) * 100) / 100; |
132
|
|
|
return rate + footnote + perUnit_area + ': ' + arr['unit'] + footunit; |
133
|
|
|
} |
134
|
|
|
} |
135
|
|
|
}, |
136
|
|
|
} |
137
|
|
|
} |
138
|
|
|
}; |
139
|
|
|
return ( |
140
|
|
|
<Card className="mb-3 overflow-hidden"> |
141
|
|
|
<CardBody className="position-relative"> |
142
|
|
|
<Bar ref={chartRef} data={chartData} width={160} height={50} options={config.options} /> |
143
|
|
|
</CardBody> |
144
|
|
|
</Card> |
145
|
|
|
); |
146
|
|
|
}; |
147
|
|
|
|
148
|
|
|
export default BarChart; |