1
|
|
|
import React, { Fragment, useEffect, useState } from 'react'; |
2
|
|
|
import CountUp from 'react-countup'; |
3
|
|
|
import { Col, Row, Spinner } from 'reactstrap'; |
4
|
|
|
import CardSummary from '../common/CardSummary'; |
5
|
|
|
import LineChart from '../common/LineChart'; |
6
|
|
|
import { toast } from 'react-toastify'; |
7
|
|
|
import SharePie from '../common/SharePie'; |
8
|
|
|
import loadable from '@loadable/component'; |
9
|
|
|
import { getCookieValue, createCookie, checkEmpty } from '../../../helpers/utils'; |
10
|
|
|
import withRedirect from '../../../hoc/withRedirect'; |
11
|
|
|
import { withTranslation } from 'react-i18next'; |
12
|
|
|
import moment from 'moment'; |
13
|
|
|
import { APIBaseURL, settings } from '../../../config'; |
14
|
|
|
import { v4 as uuid } from 'uuid'; |
15
|
|
|
import annotationPlugin from 'chartjs-plugin-annotation'; |
16
|
|
|
import { Chart as ChartJS } from 'chart.js'; |
17
|
|
|
import BarChart from '../common/BarChart'; |
18
|
|
|
import ChartSpacesStackBar from '../common/ChartSpacesStackBar'; |
19
|
|
|
import RealtimeSensor from '../common/RealtimeSensor'; |
20
|
|
|
import CustomizeMapBox from '../common/CustomizeMapBox'; |
21
|
|
|
|
22
|
|
|
ChartJS.register(annotationPlugin); |
23
|
|
|
|
24
|
|
|
const ChildSpacesTable = loadable(() => import('../common/ChildSpacesTable')); |
25
|
|
|
|
26
|
|
|
const Dashboard = ({ setRedirect, setRedirectUrl, t }) => { |
27
|
|
|
let current_moment = moment(); |
28
|
|
|
const [isFetchDashboard, setIsFetchDashboard] = useState(true); |
29
|
|
|
const [periodType, setPeriodType] = useState('monthly'); |
30
|
|
|
const [basePeriodBeginsDatetime, setBasePeriodBeginsDatetime] = useState( |
31
|
|
|
current_moment.clone().subtract(1, 'years').subtract(1, 'years').startOf('month') |
32
|
|
|
); |
33
|
|
|
const [basePeriodEndsDatetime, setBasePeriodEndsDatetime] = useState(current_moment.clone().subtract(1, 'years')); |
34
|
|
|
const [reportingPeriodBeginsDatetime, setReportingPeriodBeginsDatetime] = useState( |
35
|
|
|
current_moment.clone().subtract(1, 'years').startOf('month') |
36
|
|
|
); |
37
|
|
|
const [reportingPeriodEndsDatetime, setReportingPeriodEndsDatetime] = useState(current_moment); |
38
|
|
|
|
39
|
|
|
const [spinnerHidden, setSpinnerHidden] = useState(false); |
40
|
|
|
|
41
|
|
|
//Results |
42
|
|
|
const [costShareData, setCostShareData] = useState([]); |
43
|
|
|
const [timeOfUseShareData, setTimeOfUseShareData] = useState([]); |
44
|
|
|
const [TCEShareData, setTCEShareData] = useState([]); |
45
|
|
|
const [TCO2EShareData, setTCO2EShareData] = useState([]); |
46
|
|
|
|
47
|
|
|
const [thisYearBarList, setThisYearBarList] = useState([]); |
48
|
|
|
const [lastYearBarList, setLastYearBarList] = useState([]); |
49
|
|
|
const [thisMonthInputCardSummaryList, setThisMonthInputCardSummaryList] = useState([]); |
50
|
|
|
const [thisMonthCostCardSummaryList, setThisMonthCostCardSummaryList] = useState([]); |
51
|
|
|
const [thisMonthOutputCardSummaryList, setThisMonthOutputCardSummaryList] = useState([]); |
52
|
|
|
const [barLabels, setBarLabels] = useState([]); |
53
|
|
|
const [totalInTCE, setTotalInTCE] = useState({}); |
54
|
|
|
const [totalInTCO2E, setTotalInTCO2E] = useState({}); |
55
|
|
|
|
56
|
|
|
const [spaceInputLineChartLabels, setSpaceInputLineChartLabels] = useState([]); |
57
|
|
|
const [spaceInputLineChartData, setSpaceInputLineChartData] = useState({}); |
58
|
|
|
const [spaceInputLineChartOptions, setSpaceInputLineChartOptions] = useState([]); |
59
|
|
|
const [spaceCostLineChartOptions, setSpaceCostLineChartOptions] = useState([]); |
60
|
|
|
const [spaceCostLineChartLabels, setSpaceCostLineChartLabels] = useState([]); |
61
|
|
|
const [spaceCostLineChartData, setSpaceCostLineChartData] = useState({}); |
62
|
|
|
|
63
|
|
|
const [detailedDataTableData, setDetailedDataTableData] = useState([]); |
64
|
|
|
const [detailedDataTableColumns, setDetailedDataTableColumns] = useState([ |
65
|
|
|
{ dataField: 'startdatetime', text: t('Datetime'), sort: true } |
66
|
|
|
]); |
67
|
|
|
|
68
|
|
|
const [childSpacesTableData, setChildSpacesTableData] = useState([]); |
69
|
|
|
const [childSpacesTableColumns, setChildSpacesTableColumns] = useState([ |
70
|
|
|
{ dataField: 'name', text: t('Child Spaces'), sort: true } |
71
|
|
|
]); |
72
|
|
|
|
73
|
|
|
const [childSpacesInputData, setChildSpacesInputData] = useState([]); |
74
|
|
|
const [childSpacesCostData, setChildSpacesCostData] = useState([]); |
75
|
|
|
const [monthLabels, setMonthLabels] = useState([]); |
76
|
|
|
const [geojson, setGeojson] = useState({}); |
77
|
|
|
const [rootLatitude, setRootLatitude] = useState(''); |
78
|
|
|
const [rootLongitude, setRootLongitude] = useState(''); |
79
|
|
|
|
80
|
|
|
const [sensor, setSensor] = useState({}); |
81
|
|
|
const [pointList, setPointList] = useState({}); |
82
|
|
|
|
83
|
|
|
useEffect(() => { |
84
|
|
|
let is_logged_in = getCookieValue('is_logged_in'); |
85
|
|
|
let user_name = getCookieValue('user_name'); |
86
|
|
|
let user_display_name = getCookieValue('user_display_name'); |
87
|
|
|
let user_uuid = getCookieValue('user_uuid'); |
88
|
|
|
let token = getCookieValue('token'); |
89
|
|
|
if (checkEmpty(is_logged_in) || checkEmpty(token) || checkEmpty(user_uuid) || !is_logged_in) { |
90
|
|
|
setRedirectUrl(`/authentication/basic/login`); |
91
|
|
|
setRedirect(true); |
92
|
|
|
} else { |
93
|
|
|
//update expires time of cookies |
94
|
|
|
createCookie('is_logged_in', true, settings.cookieExpireTime); |
95
|
|
|
createCookie('user_name', user_name, settings.cookieExpireTime); |
96
|
|
|
createCookie('user_display_name', user_display_name, settings.cookieExpireTime); |
97
|
|
|
createCookie('user_uuid', user_uuid, settings.cookieExpireTime); |
98
|
|
|
createCookie('token', token, settings.cookieExpireTime); |
99
|
|
|
|
100
|
|
|
let isResponseOK = false; |
101
|
|
|
if (isFetchDashboard) { |
102
|
|
|
setIsFetchDashboard(false); |
103
|
|
|
toast( |
104
|
|
|
<Fragment> |
105
|
|
|
{t('Welcome to MyEMS')} |
106
|
|
|
<br /> |
107
|
|
|
{t('An Industry Leading Open Source Energy Management System')} |
108
|
|
|
</Fragment> |
109
|
|
|
); |
110
|
|
|
|
111
|
|
|
fetch(APIBaseURL + '/reports/dashboard?' + 'useruuid=' + user_uuid + '&periodtype=' + periodType + |
112
|
|
|
'&baseperiodstartdatetime=' + |
113
|
|
|
(basePeriodBeginsDatetime != null ? basePeriodBeginsDatetime.format('YYYY-MM-DDTHH:mm:ss') : '') + |
114
|
|
|
'&baseperiodenddatetime=' + |
115
|
|
|
(basePeriodEndsDatetime != null ? basePeriodEndsDatetime.format('YYYY-MM-DDTHH:mm:ss') : '') + |
116
|
|
|
'&reportingperiodstartdatetime=' + |
117
|
|
|
reportingPeriodBeginsDatetime.format('YYYY-MM-DDTHH:mm:ss') + |
118
|
|
|
'&reportingperiodenddatetime=' + |
119
|
|
|
reportingPeriodEndsDatetime.format('YYYY-MM-DDTHH:mm:ss'), |
120
|
|
|
{ |
121
|
|
|
method: 'GET', |
122
|
|
|
headers: { |
123
|
|
|
'Content-type': 'application/json', |
124
|
|
|
'User-UUID': getCookieValue('user_uuid'), |
125
|
|
|
Token: getCookieValue('token') |
126
|
|
|
}, |
127
|
|
|
body: null |
128
|
|
|
} |
129
|
|
|
) |
130
|
|
|
.then(response => { |
131
|
|
|
if (response.ok) { |
132
|
|
|
isResponseOK = true; |
133
|
|
|
} |
134
|
|
|
return response.json(); |
135
|
|
|
}) |
136
|
|
|
.then(json => { |
137
|
|
|
if (isResponseOK) { |
138
|
|
|
// hide spinner |
139
|
|
|
setSpinnerHidden(true); |
140
|
|
|
let labels = []; |
141
|
|
|
let thisYearBarList = []; |
142
|
|
|
let lastYearBarList = []; |
143
|
|
|
json['reporting_period_input']['names'].forEach((currentValue, index) => { |
144
|
|
|
let cardSummaryItem = {}; |
145
|
|
|
cardSummaryItem['name'] = json['reporting_period_input']['names'][index]; |
146
|
|
|
cardSummaryItem['unit'] = json['reporting_period_input']['units'][index]; |
147
|
|
|
cardSummaryItem['subtotal'] = json['reporting_period_input']['subtotals'][index]; |
148
|
|
|
cardSummaryItem['increment_rate'] = parseFloat(json['reporting_period_input']['increment_rates'][index] * 100).toFixed(2) + '%'; |
149
|
|
|
cardSummaryItem['subtotal_per_unit_area'] = json['space']['area'] > 0 ? parseFloat(cardSummaryItem['subtotal'] / json['space']['area']).toFixed(3) : 0.0; |
150
|
|
|
cardSummaryItem['subtotal_per_capita'] = json['space']['number_of_occupants'] > 0 ? parseFloat(cardSummaryItem['subtotal'] / json['space']['number_of_occupants']).toFixed(3) : 0.0; |
151
|
|
|
labels.push( |
152
|
|
|
t('CATEGORY Consumption UNIT', { CATEGORY: null, UNIT: null }) + |
153
|
|
|
cardSummaryItem['name'] + |
154
|
|
|
cardSummaryItem['unit'] |
155
|
|
|
); |
156
|
|
|
thisYearBarList.push(cardSummaryItem); |
157
|
|
|
}); |
158
|
|
|
|
159
|
|
|
json['reporting_period_cost']['names'].forEach((currentValue, index) => { |
160
|
|
|
let cardSummaryItem = {}; |
161
|
|
|
cardSummaryItem['name'] = json['reporting_period_cost']['names'][index]; |
162
|
|
|
cardSummaryItem['unit'] = json['reporting_period_cost']['units'][index]; |
163
|
|
|
cardSummaryItem['subtotal'] = json['reporting_period_cost']['subtotals'][index]; |
164
|
|
|
cardSummaryItem['increment_rate'] = parseFloat(json['reporting_period_cost']['increment_rates'][index] * 100).toFixed(2) + '%'; |
165
|
|
|
cardSummaryItem['subtotal_per_unit_area'] = json['space']['area'] > 0 ? parseFloat(cardSummaryItem['subtotal'] / json['space']['area']).toFixed(3) : 0.0; |
166
|
|
|
cardSummaryItem['subtotal_per_capita'] = json['space']['number_of_occupants'] > 0 ? parseFloat(cardSummaryItem['subtotal'] / json['space']['number_of_occupants']).toFixed(3) : 0.0; |
167
|
|
|
labels.push( |
168
|
|
|
t('CATEGORY Costs UNIT', { CATEGORY: null, UNIT: null }) + |
169
|
|
|
cardSummaryItem['name'] + |
170
|
|
|
cardSummaryItem['unit'] |
171
|
|
|
); |
172
|
|
|
thisYearBarList.push(cardSummaryItem); |
173
|
|
|
}); |
174
|
|
|
setBarLabels(labels); |
175
|
|
|
setThisYearBarList(thisYearBarList); |
176
|
|
|
|
177
|
|
|
json['base_period_input']['names'].forEach((currentValue, index) => { |
178
|
|
|
let cardSummaryItem = {}; |
179
|
|
|
cardSummaryItem['name'] = json['base_period_input']['names'][index]; |
180
|
|
|
cardSummaryItem['unit'] = json['base_period_input']['units'][index]; |
181
|
|
|
cardSummaryItem['subtotal'] = json['base_period_input']['subtotals'][index]; |
182
|
|
|
cardSummaryItem['increment_rate'] = null; |
183
|
|
|
cardSummaryItem['subtotal_per_unit_area'] = json['space']['area'] > 0 ? parseFloat(cardSummaryItem['subtotal'] / json['space']['area']).toFixed(3) : 0.0; |
184
|
|
|
cardSummaryItem['subtotal_per_capita'] = json['space']['number_of_occupants'] > 0 ? parseFloat(cardSummaryItem['subtotal'] / json['space']['number_of_occupants']).toFixed(3) : 0.0; |
185
|
|
|
lastYearBarList.push(cardSummaryItem); |
186
|
|
|
}); |
187
|
|
|
|
188
|
|
|
json['base_period_cost']['names'].forEach((currentValue, index) => { |
189
|
|
|
let cardSummaryItem = {}; |
190
|
|
|
cardSummaryItem['name'] = json['base_period_cost']['names'][index]; |
191
|
|
|
cardSummaryItem['unit'] = json['base_period_cost']['units'][index]; |
192
|
|
|
cardSummaryItem['subtotal'] = json['base_period_cost']['subtotals'][index]; |
193
|
|
|
cardSummaryItem['increment_rate'] = null; |
194
|
|
|
cardSummaryItem['subtotal_per_unit_area'] = json['space']['area'] > 0 ? parseFloat(cardSummaryItem['subtotal'] / json['space']['area']).toFixed(3) : 0.0; |
195
|
|
|
cardSummaryItem['subtotal_per_capita'] = json['space']['number_of_occupants'] > 0 ? parseFloat(cardSummaryItem['subtotal'] / json['space']['number_of_occupants']).toFixed(3) : 0.0; |
196
|
|
|
lastYearBarList.push(cardSummaryItem); |
197
|
|
|
}); |
198
|
|
|
setLastYearBarList(lastYearBarList); |
199
|
|
|
|
200
|
|
|
let timeOfUseArray = []; |
201
|
|
|
json['reporting_period_input']['energy_category_ids'].forEach((currentValue, index) => { |
202
|
|
|
if (currentValue === 1) { |
203
|
|
|
// energy_category_id 1 electricity |
204
|
|
|
let timeOfUseItem = {}; |
205
|
|
|
timeOfUseItem['id'] = 1; |
206
|
|
|
timeOfUseItem['name'] = t('Top-Peak'); |
207
|
|
|
timeOfUseItem['value'] = json['reporting_period_input']['toppeaks'][index]; |
208
|
|
|
timeOfUseItem['color'] = '#' + (((1 << 24) * Math.random()) | 0).toString(16); |
209
|
|
|
timeOfUseArray.push(timeOfUseItem); |
210
|
|
|
|
211
|
|
|
timeOfUseItem = {}; |
212
|
|
|
timeOfUseItem['id'] = 2; |
213
|
|
|
timeOfUseItem['name'] = t('On-Peak'); |
214
|
|
|
timeOfUseItem['value'] = json['reporting_period_input']['onpeaks'][index]; |
215
|
|
|
timeOfUseItem['color'] = '#' + (((1 << 24) * Math.random()) | 0).toString(16); |
216
|
|
|
timeOfUseArray.push(timeOfUseItem); |
217
|
|
|
|
218
|
|
|
timeOfUseItem = {}; |
219
|
|
|
timeOfUseItem['id'] = 3; |
220
|
|
|
timeOfUseItem['name'] = t('Mid-Peak'); |
221
|
|
|
timeOfUseItem['value'] = json['reporting_period_input']['midpeaks'][index]; |
222
|
|
|
timeOfUseItem['color'] = '#' + (((1 << 24) * Math.random()) | 0).toString(16); |
223
|
|
|
timeOfUseArray.push(timeOfUseItem); |
224
|
|
|
|
225
|
|
|
timeOfUseItem = {}; |
226
|
|
|
timeOfUseItem['id'] = 4; |
227
|
|
|
timeOfUseItem['name'] = t('Off-Peak'); |
228
|
|
|
timeOfUseItem['value'] = json['reporting_period_input']['offpeaks'][index]; |
229
|
|
|
timeOfUseItem['color'] = '#' + (((1 << 24) * Math.random()) | 0).toString(16); |
230
|
|
|
timeOfUseArray.push(timeOfUseItem); |
231
|
|
|
|
232
|
|
|
timeOfUseItem = {}; |
233
|
|
|
timeOfUseItem['id'] = 5; |
234
|
|
|
timeOfUseItem['name'] = t('Deep'); |
235
|
|
|
timeOfUseItem['value'] = json['reporting_period_input']['deeps'][index]; |
236
|
|
|
timeOfUseItem['color'] = '#' + (((1 << 24) * Math.random()) | 0).toString(16); |
237
|
|
|
timeOfUseArray.push(timeOfUseItem); |
238
|
|
|
} |
239
|
|
|
}); |
240
|
|
|
setTimeOfUseShareData(timeOfUseArray); |
241
|
|
|
let totalInTCE = {}; |
242
|
|
|
totalInTCE['value'] = json['reporting_period_input']['total_in_kgce'] / 1000; // convert from kg to t |
243
|
|
|
totalInTCE['increment_rate'] = parseFloat(json['reporting_period_input']['increment_rate_in_kgce'] * 100).toFixed(2) + '%'; |
244
|
|
|
totalInTCE['value_per_unit_area'] = json['space']['area'] > 0 ? parseFloat(totalInTCE['value'] / json['space']['area']).toFixed(3) : 0.0; |
245
|
|
|
totalInTCE['value_per_capita'] = json['space']['number_of_occupants'] > 0 ? parseFloat(totalInTCE['value'] / json['space']['number_of_occupants']).toFixed(3) : 0.0; |
246
|
|
|
setTotalInTCE(totalInTCE); |
247
|
|
|
|
248
|
|
|
let costDataArray = []; |
249
|
|
|
json['reporting_period_cost']['names'].forEach((currentValue, index) => { |
250
|
|
|
let costDataItem = {}; |
251
|
|
|
costDataItem['id'] = index; |
252
|
|
|
costDataItem['name'] = currentValue; |
253
|
|
|
costDataItem['value'] = json['reporting_period_cost']['subtotals'][index]; |
254
|
|
|
costDataItem['color'] = '#' + (((1 << 24) * Math.random()) | 0).toString(16); |
255
|
|
|
costDataArray.push(costDataItem); |
256
|
|
|
}); |
257
|
|
|
|
258
|
|
|
setCostShareData(costDataArray); |
259
|
|
|
let totalInTCO2E = {}; |
260
|
|
|
totalInTCO2E['value'] = json['reporting_period_input']['total_in_kgco2e'] / 1000; // convert from kg to t |
261
|
|
|
totalInTCO2E['increment_rate'] = parseFloat(json['reporting_period_input']['increment_rate_in_kgco2e'] * 100).toFixed(2) + '%'; |
262
|
|
|
totalInTCO2E['value_per_unit_area'] = json['space']['area'] > 0 ? parseFloat(totalInTCO2E['value'] / json['space']['area']).toFixed(3) : 0.0; |
263
|
|
|
totalInTCO2E['value_per_capita'] = json['space']['number_of_occupants'] > 0 ? parseFloat(totalInTCO2E['value'] / json['space']['number_of_occupants']).toFixed(3) : 0.0; |
264
|
|
|
setTotalInTCO2E(totalInTCO2E); |
265
|
|
|
|
266
|
|
|
let TCEDataArray = []; |
267
|
|
|
json['reporting_period_input']['names'].forEach((currentValue, index) => { |
268
|
|
|
let TCEDataItem = {}; |
269
|
|
|
TCEDataItem['id'] = index; |
270
|
|
|
TCEDataItem['name'] = currentValue; |
271
|
|
|
TCEDataItem['value'] = json['reporting_period_input']['subtotals_in_kgce'][index] / 1000; |
272
|
|
|
TCEDataItem['color'] = '#' + (((1 << 24) * Math.random()) | 0).toString(16); |
273
|
|
|
TCEDataArray.push(TCEDataItem); |
274
|
|
|
}); |
275
|
|
|
setTCEShareData(TCEDataArray); |
276
|
|
|
|
277
|
|
|
let TCO2EDataArray = []; |
278
|
|
|
json['reporting_period_input']['names'].forEach((currentValue, index) => { |
279
|
|
|
let TCO2EDataItem = {}; |
280
|
|
|
TCO2EDataItem['id'] = index; |
281
|
|
|
TCO2EDataItem['name'] = currentValue; |
282
|
|
|
TCO2EDataItem['value'] = json['reporting_period_input']['subtotals_in_kgco2e'][index] / 1000; // convert from kg to t |
283
|
|
|
TCO2EDataItem['color'] = '#' + (((1 << 24) * Math.random()) | 0).toString(16); |
284
|
|
|
TCO2EDataArray.push(TCO2EDataItem); |
285
|
|
|
}); |
286
|
|
|
setTCO2EShareData(TCO2EDataArray); |
287
|
|
|
|
288
|
|
|
let timestamps = {}; |
289
|
|
|
json['reporting_period_input']['timestamps'].forEach((currentValue, index) => { |
290
|
|
|
timestamps['a' + index] = currentValue; |
291
|
|
|
}); |
292
|
|
|
setSpaceInputLineChartLabels(timestamps); |
293
|
|
|
|
294
|
|
|
let values = {}; |
295
|
|
|
json['reporting_period_input']['values'].forEach((currentValue, index) => { |
296
|
|
|
values['a' + index] = currentValue; |
297
|
|
|
}); |
298
|
|
|
setSpaceInputLineChartData(values); |
299
|
|
|
|
300
|
|
|
let names = []; |
301
|
|
|
let thisMonthInputArr = []; |
302
|
|
|
json['reporting_period_input']['names'].forEach((currentValue, index) => { |
303
|
|
|
let unit = json['reporting_period_input']['units'][index]; |
304
|
|
|
let thisMonthItem = {}; |
305
|
|
|
names.push({ value: 'a' + index, label: currentValue + ' (' + unit + ')' }); |
306
|
|
|
thisMonthItem['name'] = json['reporting_period_input']['names'][index]; |
307
|
|
|
thisMonthItem['unit'] = json['reporting_period_input']['units'][index]; |
308
|
|
|
thisMonthItem['subtotal'] = |
309
|
|
|
json['reporting_period_input']['values'][index][ |
310
|
|
|
json['reporting_period_input']['values'][index].length - 1 |
311
|
|
|
]; |
312
|
|
|
thisMonthItem['increment_rate'] = |
313
|
|
|
parseFloat(json['reporting_period_input']['increment_rates'][index] * 100).toFixed(2) + '%'; |
314
|
|
|
thisMonthItem['subtotal_per_unit_area'] = json['space']['area'] > 0 ? parseFloat(thisMonthItem['subtotal'] / json['space']['area']).toFixed(3) : 0.0; |
315
|
|
|
thisMonthItem['subtotal_per_capita'] = json['space']['number_of_occupants'] > 0 ? parseFloat(thisMonthItem['subtotal'] / json['space']['number_of_occupants']).toFixed(3) : 0.0; |
316
|
|
|
thisMonthInputArr.push(thisMonthItem); |
317
|
|
|
}); |
318
|
|
|
setSpaceInputLineChartOptions(names); |
319
|
|
|
setThisMonthInputCardSummaryList(thisMonthInputArr); |
320
|
|
|
|
321
|
|
|
let thisMonthOutputArr = []; |
322
|
|
|
json['reporting_period_output']['names'].forEach((currentValue, index) => { |
323
|
|
|
let unit = json['reporting_period_output']['units'][index]; |
324
|
|
|
let thisMonthItem = {}; |
325
|
|
|
names.push({ value: 'a' + index, label: currentValue + ' (' + unit + ')' }); |
326
|
|
|
thisMonthItem['name'] = json['reporting_period_output']['names'][index]; |
327
|
|
|
thisMonthItem['unit'] = json['reporting_period_output']['units'][index]; |
328
|
|
|
thisMonthItem['subtotal'] = |
329
|
|
|
json['reporting_period_output']['values'][index][ |
330
|
|
|
json['reporting_period_output']['values'][index].length - 1 |
331
|
|
|
]; |
332
|
|
|
thisMonthItem['increment_rate'] = parseFloat(json['reporting_period_output']['increment_rates'][index] * 100).toFixed(2) + '%'; |
333
|
|
|
thisMonthItem['subtotal_per_unit_area'] = json['space']['area'] > 0 ? parseFloat(thisMonthItem['subtotal'] / json['space']['area']).toFixed(3) : 0.0; |
334
|
|
|
thisMonthItem['subtotal_per_capita'] = json['space']['number_of_occupants'] > 0 ? parseFloat(thisMonthItem['subtotal'] / json['space']['number_of_occupants']).toFixed(3) : 0.0; |
335
|
|
|
thisMonthOutputArr.push(thisMonthItem); |
336
|
|
|
}); |
337
|
|
|
setThisMonthOutputCardSummaryList(thisMonthOutputArr); |
338
|
|
|
|
339
|
|
|
timestamps = {}; |
340
|
|
|
json['reporting_period_cost']['timestamps'].forEach((currentValue, index) => { |
341
|
|
|
timestamps['a' + index] = currentValue; |
342
|
|
|
}); |
343
|
|
|
setSpaceCostLineChartLabels(timestamps); |
344
|
|
|
|
345
|
|
|
values = {}; |
346
|
|
|
json['reporting_period_cost']['values'].forEach((currentValue, index) => { |
347
|
|
|
values['a' + index] = currentValue; |
348
|
|
|
}); |
349
|
|
|
setSpaceCostLineChartData(values); |
350
|
|
|
|
351
|
|
|
names = []; |
352
|
|
|
let thisMonthCostArr = []; |
353
|
|
|
json['reporting_period_cost']['names'].forEach((currentValue, index) => { |
354
|
|
|
let thisMonthItem = {}; |
355
|
|
|
let unit = json['reporting_period_cost']['units'][index]; |
356
|
|
|
names.push({ value: 'a' + index, label: currentValue + ' (' + unit + ')' }); |
357
|
|
|
thisMonthItem['name'] = json['reporting_period_cost']['names'][index]; |
358
|
|
|
thisMonthItem['unit'] = json['reporting_period_cost']['units'][index]; |
359
|
|
|
thisMonthItem['subtotal'] = |
360
|
|
|
json['reporting_period_cost']['values'][index][ |
361
|
|
|
json['reporting_period_cost']['values'][index].length - 1 |
362
|
|
|
]; |
363
|
|
|
thisMonthItem['increment_rate'] = |
364
|
|
|
parseFloat(json['reporting_period_cost']['increment_rates'][index] * 100).toFixed(2) + '%'; |
365
|
|
|
thisMonthItem['subtotal_per_unit_area'] = json['space']['area'] > 0 ? parseFloat(thisMonthItem['subtotal'] / json['space']['area']).toFixed(3) : 0.0; |
366
|
|
|
thisMonthItem['subtotal_per_capita'] = json['space']['number_of_occupants'] > 0 ? parseFloat(thisMonthItem['subtotal'] / json['space']['number_of_occupants']).toFixed(3) : 0.0; |
367
|
|
|
|
368
|
|
|
thisMonthCostArr.push(thisMonthItem); |
369
|
|
|
}); |
370
|
|
|
setSpaceCostLineChartOptions(names); |
371
|
|
|
setThisMonthCostCardSummaryList(thisMonthCostArr); |
372
|
|
|
|
373
|
|
|
let detailed_value_list = []; |
374
|
|
|
if (json['reporting_period_input']['timestamps'].length > 0) { |
375
|
|
|
json['reporting_period_input']['timestamps'][0].forEach((currentTimestamp, timestampIndex) => { |
376
|
|
|
let detailed_value = {}; |
377
|
|
|
detailed_value['id'] = timestampIndex; |
378
|
|
|
detailed_value['startdatetime'] = currentTimestamp; |
379
|
|
|
json['reporting_period_input']['values'].forEach((currentValue, energyCategoryIndex) => { |
380
|
|
|
detailed_value['a' + energyCategoryIndex] = json['reporting_period_input']['values'][ |
381
|
|
|
energyCategoryIndex |
382
|
|
|
][timestampIndex].toFixed(2); |
383
|
|
|
}); |
384
|
|
|
detailed_value_list.push(detailed_value); |
385
|
|
|
}); |
386
|
|
|
} |
387
|
|
|
|
388
|
|
|
let detailed_value = {}; |
389
|
|
|
detailed_value['id'] = detailed_value_list.length; |
390
|
|
|
detailed_value['startdatetime'] = t('Subtotal'); |
391
|
|
|
json['reporting_period_input']['subtotals'].forEach((currentValue, index) => { |
392
|
|
|
detailed_value['a' + index] = currentValue.toFixed(2); |
393
|
|
|
}); |
394
|
|
|
detailed_value_list.push(detailed_value); |
395
|
|
|
setTimeout(() => { |
396
|
|
|
setDetailedDataTableData(detailed_value_list); |
397
|
|
|
}, 0); |
398
|
|
|
|
399
|
|
|
let detailed_column_list = []; |
400
|
|
|
detailed_column_list.push({ |
401
|
|
|
dataField: 'startdatetime', |
402
|
|
|
text: t('Datetime'), |
403
|
|
|
sort: true |
404
|
|
|
}); |
405
|
|
|
json['reporting_period_input']['names'].forEach((currentValue, index) => { |
406
|
|
|
let unit = json['reporting_period_cost']['units'][index]; |
407
|
|
|
detailed_column_list.push({ |
408
|
|
|
dataField: 'a' + index, |
409
|
|
|
text: currentValue + ' (' + unit + ')', |
410
|
|
|
sort: true |
411
|
|
|
}); |
412
|
|
|
}); |
413
|
|
|
setDetailedDataTableColumns(detailed_column_list); |
414
|
|
|
|
415
|
|
|
let child_space_value_list = []; |
416
|
|
|
if (json['child_space_input']['child_space_names_array'].length > 0) { |
417
|
|
|
json['child_space_input']['child_space_names_array'][0].forEach((currentSpaceName, spaceIndex) => { |
418
|
|
|
let child_space_value = {}; |
419
|
|
|
child_space_value['id'] = spaceIndex; |
420
|
|
|
child_space_value['name'] = currentSpaceName; |
421
|
|
|
json['child_space_input']['energy_category_names'].forEach((currentValue, energyCategoryIndex) => { |
422
|
|
|
child_space_value['a' + energyCategoryIndex] = |
423
|
|
|
json['child_space_input']['subtotals_array'][energyCategoryIndex][spaceIndex]; |
424
|
|
|
child_space_value['b' + energyCategoryIndex] = |
425
|
|
|
json['child_space_cost']['subtotals_array'][energyCategoryIndex][spaceIndex]; |
426
|
|
|
}); |
427
|
|
|
child_space_value_list.push(child_space_value); |
428
|
|
|
}); |
429
|
|
|
} |
430
|
|
|
|
431
|
|
|
setChildSpacesTableData(child_space_value_list); |
432
|
|
|
|
433
|
|
|
let child_space_column_list = []; |
434
|
|
|
child_space_column_list.push({ |
435
|
|
|
dataField: 'name', |
436
|
|
|
text: t('Child Spaces'), |
437
|
|
|
sort: true |
438
|
|
|
}); |
439
|
|
|
json['child_space_input']['energy_category_names'].forEach((currentValue, index) => { |
440
|
|
|
let unit = json['child_space_input']['units'][index]; |
441
|
|
|
child_space_column_list.push({ |
442
|
|
|
dataField: 'a' + index, |
443
|
|
|
text: t('CATEGORY Consumption UNIT', { CATEGORY: currentValue, UNIT: '(' + unit + ')' }), |
444
|
|
|
sort: true, |
445
|
|
|
formatter: function (decimalValue) { |
446
|
|
|
if (typeof decimalValue === 'number') { |
447
|
|
|
return decimalValue.toFixed(2); |
448
|
|
|
} else { |
449
|
|
|
return null; |
450
|
|
|
} |
451
|
|
|
} |
452
|
|
|
}); |
453
|
|
|
}); |
454
|
|
|
json['child_space_cost']['energy_category_names'].forEach((currentValue, index) => { |
455
|
|
|
let unit = json['child_space_cost']['units'][index]; |
456
|
|
|
child_space_column_list.push({ |
457
|
|
|
dataField: 'b' + index, |
458
|
|
|
text: t('CATEGORY Costs UNIT', { CATEGORY: currentValue, UNIT: '(' + unit + ')' }), |
459
|
|
|
sort: true, |
460
|
|
|
formatter: function (decimalValue) { |
461
|
|
|
if (typeof decimalValue === 'number') { |
462
|
|
|
return decimalValue.toFixed(2); |
463
|
|
|
} else { |
464
|
|
|
return null; |
465
|
|
|
} |
466
|
|
|
} |
467
|
|
|
}); |
468
|
|
|
}); |
469
|
|
|
|
470
|
|
|
setChildSpacesTableColumns(child_space_column_list); |
471
|
|
|
setChildSpacesInputData(json['child_space_input']); |
472
|
|
|
setChildSpacesCostData(json['child_space_cost']); |
473
|
|
|
setMonthLabels(json['reporting_period_cost']['timestamps'][0]); |
474
|
|
|
setSensor(json['sensor']); |
475
|
|
|
setPointList(json['point']); |
476
|
|
|
} |
477
|
|
|
}); |
478
|
|
|
} |
479
|
|
|
} |
480
|
|
|
}); |
481
|
|
|
|
482
|
|
|
useEffect(() => { |
483
|
|
|
let timer = setInterval(() => { |
484
|
|
|
let is_logged_in = getCookieValue('is_logged_in'); |
485
|
|
|
if (is_logged_in === null || !is_logged_in) { |
486
|
|
|
setRedirectUrl(`/authentication/basic/login`); |
487
|
|
|
setRedirect(true); |
488
|
|
|
} |
489
|
|
|
}, 1000); |
490
|
|
|
return () => clearInterval(timer); |
491
|
|
|
}, [setRedirect, setRedirectUrl]); |
492
|
|
|
|
493
|
|
|
useEffect(() => { |
494
|
|
|
let is_logged_in = getCookieValue('is_logged_in'); |
495
|
|
|
let user_name = getCookieValue('user_name'); |
496
|
|
|
let user_display_name = getCookieValue('user_display_name'); |
497
|
|
|
let user_uuid = getCookieValue('user_uuid'); |
498
|
|
|
let token = getCookieValue('token'); |
499
|
|
|
if (checkEmpty(is_logged_in) || checkEmpty(token) || checkEmpty(user_uuid) || !is_logged_in) { |
500
|
|
|
setRedirectUrl(`/authentication/basic/login`); |
501
|
|
|
setRedirect(true); |
502
|
|
|
} else { |
503
|
|
|
//update expires time of cookies |
504
|
|
|
createCookie('is_logged_in', true, settings.cookieExpireTime); |
505
|
|
|
createCookie('user_name', user_name, settings.cookieExpireTime); |
506
|
|
|
createCookie('user_display_name', user_display_name, settings.cookieExpireTime); |
507
|
|
|
createCookie('user_uuid', user_uuid, settings.cookieExpireTime); |
508
|
|
|
createCookie('token', token, settings.cookieExpireTime); |
509
|
|
|
|
510
|
|
|
let isResponseOK = false; |
511
|
|
|
fetch(APIBaseURL + '/spaces/tree', { |
512
|
|
|
method: 'GET', |
513
|
|
|
headers: { |
514
|
|
|
'Content-type': 'application/json', |
515
|
|
|
'User-UUID': getCookieValue('user_uuid'), |
516
|
|
|
Token: getCookieValue('token') |
517
|
|
|
}, |
518
|
|
|
body: null |
519
|
|
|
}) |
520
|
|
|
.then(response => { |
521
|
|
|
if (response.ok) { |
522
|
|
|
isResponseOK = true; |
523
|
|
|
} |
524
|
|
|
return response.json(); |
525
|
|
|
}) |
526
|
|
|
.then(json => { |
527
|
|
|
if (isResponseOK) { |
528
|
|
|
// rename keys |
529
|
|
|
json = JSON.parse( |
530
|
|
|
JSON.stringify([json]) |
531
|
|
|
.split('"id":') |
532
|
|
|
.join('"value":') |
533
|
|
|
.split('"name":') |
534
|
|
|
.join('"label":') |
535
|
|
|
); |
536
|
|
|
// get chiildren of root Space |
537
|
|
|
let isResponseOK = false; |
538
|
|
|
fetch(APIBaseURL + '/spaces/' + [json[0]].map(o => o.value) + '/children', { |
539
|
|
|
method: 'GET', |
540
|
|
|
headers: { |
541
|
|
|
'Content-type': 'application/json', |
542
|
|
|
'User-UUID': getCookieValue('user_uuid'), |
543
|
|
|
Token: getCookieValue('token') |
544
|
|
|
}, |
545
|
|
|
body: null |
546
|
|
|
}) |
547
|
|
|
.then(response => { |
548
|
|
|
if (response.ok) { |
549
|
|
|
isResponseOK = true; |
550
|
|
|
} |
551
|
|
|
return response.json(); |
552
|
|
|
}) |
553
|
|
|
.then(json => { |
554
|
|
|
if (isResponseOK) { |
555
|
|
|
json = JSON.parse( |
556
|
|
|
JSON.stringify([json]) |
557
|
|
|
.split('"id":') |
558
|
|
|
.join('"value":') |
559
|
|
|
.split('"name":') |
560
|
|
|
.join('"label":') |
561
|
|
|
); |
562
|
|
|
setRootLongitude(json[0]['current']['longitude']); |
563
|
|
|
setRootLatitude(json[0]['current']['latitude']); |
564
|
|
|
let geojson = {}; |
565
|
|
|
geojson['type'] = 'FeatureCollection'; |
566
|
|
|
let geojsonData = []; |
567
|
|
|
for (const childSpace of json[0]['children']) { |
568
|
|
|
if (childSpace['latitude'] && childSpace['longitude']) { |
569
|
|
|
geojsonData.push({ |
570
|
|
|
type: 'Feature', |
571
|
|
|
geometry: { |
572
|
|
|
type: 'Point', |
573
|
|
|
coordinates: [childSpace['longitude'], childSpace['latitude']] |
574
|
|
|
}, |
575
|
|
|
properties: { |
576
|
|
|
title: childSpace['label'], |
577
|
|
|
description: childSpace['description'], |
578
|
|
|
uuid: childSpace['uuid'], |
579
|
|
|
url: '/space/energycategory' |
580
|
|
|
} |
581
|
|
|
}); |
582
|
|
|
} |
583
|
|
|
} |
584
|
|
|
geojson['features'] = geojsonData; |
585
|
|
|
setGeojson(geojson); |
586
|
|
|
} else { |
587
|
|
|
toast.error(t(json.description)); |
588
|
|
|
} |
589
|
|
|
}) |
590
|
|
|
.catch(err => { |
591
|
|
|
console.log(err); |
592
|
|
|
}); |
593
|
|
|
// end of get children of root Space |
594
|
|
|
} else { |
595
|
|
|
toast.error(t(json.description)); |
596
|
|
|
} |
597
|
|
|
}) |
598
|
|
|
.catch(err => { |
599
|
|
|
console.log(err); |
600
|
|
|
}); |
601
|
|
|
} |
602
|
|
|
}, [setRedirect, setRedirectUrl, t]); |
603
|
|
|
|
604
|
|
|
return ( |
605
|
|
|
<Fragment> |
606
|
|
|
<div className="card-deck"> |
607
|
|
|
<Spinner color="primary" hidden={spinnerHidden} /> |
608
|
|
|
{thisMonthInputCardSummaryList.map(cardSummaryItem => ( |
609
|
|
|
<CardSummary |
610
|
|
|
key={uuid()} |
611
|
|
|
rate={cardSummaryItem['increment_rate']} |
612
|
|
|
title={t("This Month's Consumption CATEGORY VALUE UNIT", { |
613
|
|
|
CATEGORY: cardSummaryItem['name'], |
614
|
|
|
VALUE: null, |
615
|
|
|
UNIT: '(' + cardSummaryItem['unit'] + ')' |
616
|
|
|
})} |
617
|
|
|
color="success" |
618
|
|
|
footnote={t('Per Unit Area')} |
619
|
|
|
footvalue={cardSummaryItem['subtotal_per_unit_area']} |
620
|
|
|
footunit={'(' + cardSummaryItem['unit'] + '/m²)'} |
621
|
|
|
secondfootnote={t('Per Capita')} |
622
|
|
|
secondfootvalue={cardSummaryItem['subtotal_per_capita']} |
623
|
|
|
secondfootunit={'(' + cardSummaryItem['unit'] + ')'} |
624
|
|
|
> |
625
|
|
|
{cardSummaryItem['subtotal'] && ( |
626
|
|
|
<CountUp |
627
|
|
|
end={cardSummaryItem['subtotal']} |
628
|
|
|
duration={2} |
629
|
|
|
prefix="" |
630
|
|
|
separator="," |
631
|
|
|
decimal="." |
632
|
|
|
decimals={0} |
633
|
|
|
/> |
634
|
|
|
)} |
635
|
|
|
</CardSummary> |
636
|
|
|
))} |
637
|
|
|
{thisMonthCostCardSummaryList.map(cardSummaryItem => ( |
638
|
|
|
<CardSummary |
639
|
|
|
key={uuid()} |
640
|
|
|
rate={cardSummaryItem['increment_rate']} |
641
|
|
|
title={t("This Month's Costs CATEGORY VALUE UNIT", { |
642
|
|
|
CATEGORY: cardSummaryItem['name'], |
643
|
|
|
VALUE: null, |
644
|
|
|
UNIT: '(' + cardSummaryItem['unit'] + ')' |
645
|
|
|
})} |
646
|
|
|
color="success" |
647
|
|
|
footnote={t('Per Unit Area')} |
648
|
|
|
footvalue={cardSummaryItem['subtotal_per_unit_area']} |
649
|
|
|
footunit={'(' + cardSummaryItem['unit'] + '/m²)'} |
650
|
|
|
secondfootnote={t('Per Capita')} |
651
|
|
|
secondfootvalue={cardSummaryItem['subtotal_per_capita']} |
652
|
|
|
secondfootunit={'(' + cardSummaryItem['unit'] + ')'} |
653
|
|
|
> |
654
|
|
|
{cardSummaryItem['subtotal'] && ( |
655
|
|
|
<CountUp |
656
|
|
|
end={cardSummaryItem['subtotal']} |
657
|
|
|
duration={2} |
658
|
|
|
prefix="" |
659
|
|
|
separator="," |
660
|
|
|
decimal="." |
661
|
|
|
decimals={0} |
662
|
|
|
/> |
663
|
|
|
)} |
664
|
|
|
</CardSummary> |
665
|
|
|
))} |
666
|
|
|
{thisMonthOutputCardSummaryList.map(cardSummaryItem => ( |
667
|
|
|
<CardSummary |
668
|
|
|
key={uuid()} |
669
|
|
|
rate={cardSummaryItem['increment_rate']} |
670
|
|
|
title={t("This Month's Generation CATEGORY VALUE UNIT", { |
671
|
|
|
CATEGORY: cardSummaryItem['name'], |
672
|
|
|
VALUE: null, |
673
|
|
|
UNIT: '(' + cardSummaryItem['unit'] + ')' |
674
|
|
|
})} |
675
|
|
|
color="success" |
676
|
|
|
footnote={t('Per Unit Area')} |
677
|
|
|
footvalue={cardSummaryItem['subtotal_per_unit_area']} |
678
|
|
|
footunit={'(' + cardSummaryItem['unit'] + '/m²)'} |
679
|
|
|
secondfootnote={t('Per Capita')} |
680
|
|
|
secondfootvalue={cardSummaryItem['subtotal_per_capita']} |
681
|
|
|
secondfootunit={'(' + cardSummaryItem['unit'] + ')'} |
682
|
|
|
> |
683
|
|
|
{cardSummaryItem['subtotal'] && ( |
684
|
|
|
<CountUp |
685
|
|
|
end={cardSummaryItem['subtotal']} |
686
|
|
|
duration={2} |
687
|
|
|
prefix="" |
688
|
|
|
separator="," |
689
|
|
|
decimal="." |
690
|
|
|
decimals={0} |
691
|
|
|
/> |
692
|
|
|
)} |
693
|
|
|
</CardSummary> |
694
|
|
|
))} |
695
|
|
|
</div> |
696
|
|
|
<div className="card-deck"> |
697
|
|
|
{settings.showTCEData ? ( |
698
|
|
|
<CardSummary |
699
|
|
|
rate={totalInTCE['increment_rate'] || ''} |
700
|
|
|
title={t("This Year's Consumption CATEGORY VALUE UNIT", { |
701
|
|
|
CATEGORY: t('Ton of Standard Coal'), |
702
|
|
|
UNIT: '(TCE)' |
703
|
|
|
})} |
704
|
|
|
color="warning" |
705
|
|
|
footnote={t('Per Unit Area')} |
706
|
|
|
footvalue={totalInTCE['value_per_unit_area']} |
707
|
|
|
footunit="(TCE/m²)" |
708
|
|
|
secondfootnote={t('Per Capita')} |
709
|
|
|
secondfootvalue={totalInTCE['value_per_capita']} |
710
|
|
|
secondfootunit="(TCE)" |
711
|
|
|
> |
712
|
|
|
{totalInTCE['value'] && ( |
713
|
|
|
<CountUp end={totalInTCE['value']} duration={2} prefix="" separator="," decimal="." decimals={2} /> |
714
|
|
|
)} |
715
|
|
|
</CardSummary> |
716
|
|
|
) : ( |
717
|
|
|
<></> |
718
|
|
|
)} |
719
|
|
|
<CardSummary |
720
|
|
|
rate={totalInTCO2E['increment_rate'] || ''} |
721
|
|
|
title={t("This Year's Consumption CATEGORY VALUE UNIT", { |
722
|
|
|
CATEGORY: t('Ton of Carbon Dioxide Emissions'), |
723
|
|
|
UNIT: '(TCO2E)' |
724
|
|
|
})} |
725
|
|
|
color="warning" |
726
|
|
|
footnote={t('Per Unit Area')} |
727
|
|
|
footvalue={totalInTCO2E['value_per_unit_area']} |
728
|
|
|
footunit="(TCO2E/m²)" |
729
|
|
|
secondfootnote={t('Per Capita')} |
730
|
|
|
secondfootvalue={totalInTCO2E['value_per_capita']} |
731
|
|
|
secondfootunit="(TCO2E)" |
732
|
|
|
> |
733
|
|
|
{totalInTCO2E['value'] && ( |
734
|
|
|
<CountUp end={totalInTCO2E['value']} duration={2} prefix="" separator="," decimal="." decimals={2} /> |
735
|
|
|
)} |
736
|
|
|
</CardSummary> |
737
|
|
|
<CardSummary |
738
|
|
|
rate={ |
739
|
|
|
totalInTCE['value'] && totalInTCE['value'] !== 0 && totalInTCO2E['value'] && totalInTCO2E['increment_rate'] && totalInTCE['increment_rate'] |
740
|
|
|
? ((parseFloat(totalInTCO2E['increment_rate']) / parseFloat(totalInTCE['increment_rate'])).toFixed(2) + '%') |
741
|
|
|
: '' |
742
|
|
|
} |
743
|
|
|
title={t("This Year's Consumption CATEGORY VALUE UNIT", { |
744
|
|
|
CATEGORY: t('Carbon Emissions Per Unit Of Energy Consumption'), |
745
|
|
|
UNIT: '(TCO2E/TCE)' |
746
|
|
|
})} |
747
|
|
|
color="warning" |
748
|
|
|
footnote={t('Per Unit Area')} |
749
|
|
|
footvalue={ |
750
|
|
|
totalInTCE['value_per_unit_area'] && totalInTCE['value_per_unit_area'] !== 0 && totalInTCO2E['value_per_unit_area'] |
751
|
|
|
? (totalInTCO2E['value_per_unit_area'] / totalInTCE['value_per_unit_area']).toFixed(3) |
752
|
|
|
: '--' |
753
|
|
|
} |
754
|
|
|
footunit={t('(TCO2E/TCE/m²)')} |
755
|
|
|
secondfootnote={t('Per Capita')} |
756
|
|
|
secondfootvalue={ |
757
|
|
|
totalInTCE['value_per_capita'] && totalInTCE['value_per_capita'] !== 0 && totalInTCO2E['value_per_capita'] |
758
|
|
|
? (totalInTCO2E['value_per_capita'] / totalInTCE['value_per_capita']).toFixed(3) |
759
|
|
|
: '--' |
760
|
|
|
} |
761
|
|
|
secondfootunit={t('(TCO2E/TCE)')} |
762
|
|
|
> |
763
|
|
|
{totalInTCE['value'] && totalInTCE['value'] !== 0 && totalInTCO2E['value'] ? ( |
764
|
|
|
<CountUp |
765
|
|
|
end={totalInTCO2E['value'] / totalInTCE['value']} |
766
|
|
|
duration={2} |
767
|
|
|
prefix="" |
768
|
|
|
separator="," |
769
|
|
|
decimal="." |
770
|
|
|
decimals={3} |
771
|
|
|
/> |
772
|
|
|
) : ( |
773
|
|
|
'--' |
774
|
|
|
)} |
775
|
|
|
</CardSummary> |
776
|
|
|
</div> |
777
|
|
|
<div className="card-deck"> |
778
|
|
|
<BarChart |
779
|
|
|
labels={barLabels} |
780
|
|
|
data={lastYearBarList} |
781
|
|
|
compareData={thisYearBarList} |
782
|
|
|
title={t('The Same Period Last Year')} |
783
|
|
|
compareTitle={t('This Year')} |
784
|
|
|
footnote={t('Per Unit Area')} |
785
|
|
|
footunit={'/m²'} |
786
|
|
|
/> |
787
|
|
|
<LineChart |
788
|
|
|
reportingTitle={t("This Year's Consumption CATEGORY VALUE UNIT", { CATEGORY: null, VALUE: null, UNIT: null })} |
789
|
|
|
baseTitle="" |
790
|
|
|
labels={spaceInputLineChartLabels} |
791
|
|
|
data={spaceInputLineChartData} |
792
|
|
|
options={spaceInputLineChartOptions} |
793
|
|
|
/> |
794
|
|
|
<LineChart |
795
|
|
|
reportingTitle={t("This Year's Costs CATEGORY VALUE UNIT", { CATEGORY: null, VALUE: null, UNIT: null })} |
796
|
|
|
baseTitle="" |
797
|
|
|
labels={spaceCostLineChartLabels} |
798
|
|
|
data={spaceCostLineChartData} |
799
|
|
|
options={spaceCostLineChartOptions} |
800
|
|
|
/> |
801
|
|
|
</div> |
802
|
|
|
<div className="wrapper" /> |
803
|
|
|
<div className="card-deck"> |
804
|
|
|
{settings.showOnlineMap ? ( |
805
|
|
|
<div className="mb-3 card" style={{ height: '400px' }}> |
806
|
|
|
<CustomizeMapBox Latitude={rootLatitude} Longitude={rootLongitude} Zoom={10} Geojson={geojson['features']} /> |
807
|
|
|
</div> |
808
|
|
|
) : ( |
809
|
|
|
<></> |
810
|
|
|
)} |
811
|
|
|
{Object.keys(sensor).map(item => ( |
812
|
|
|
<RealtimeSensor key={uuid()} sensor={sensor[item]} pointList={pointList} /> |
813
|
|
|
))} |
814
|
|
|
</div> |
815
|
|
|
<Row noGutters> |
816
|
|
|
<Col className="mb-3 pr-lg-2 mb-3"> |
817
|
|
|
<SharePie data={timeOfUseShareData} title={t('Electricity Consumption by Time-Of-Use')} /> |
818
|
|
|
</Col> |
819
|
|
|
<Col className="mb-3 pr-lg-2 mb-3"> |
820
|
|
|
<SharePie data={costShareData} title={t('Costs by Energy Category')} /> |
821
|
|
|
</Col> |
822
|
|
|
|
823
|
|
|
{settings.showTCEData ? ( |
824
|
|
|
<Col className="mb-3 pr-lg-2 mb-3"> |
825
|
|
|
<SharePie data={TCEShareData} title={t('Ton of Standard Coal by Energy Category')} /> |
826
|
|
|
</Col> |
827
|
|
|
) : ( |
828
|
|
|
<></> |
829
|
|
|
)} |
830
|
|
|
|
831
|
|
|
<Col className="mb-3 pr-lg-2 mb-3"> |
832
|
|
|
<SharePie data={TCO2EShareData} title={t('Ton of Carbon Dioxide Emissions by Energy Category')} /> |
833
|
|
|
</Col> |
834
|
|
|
</Row> |
835
|
|
|
<ChartSpacesStackBar |
836
|
|
|
title={t('Child Spaces Data')} |
837
|
|
|
labels={monthLabels} |
838
|
|
|
inputData={childSpacesInputData} |
839
|
|
|
costData={childSpacesCostData} |
840
|
|
|
childSpaces={spaceInputLineChartOptions} |
841
|
|
|
/> |
842
|
|
|
</Fragment> |
843
|
|
|
); |
844
|
|
|
}; |
845
|
|
|
|
846
|
|
|
export default withTranslation()(withRedirect(Dashboard)); |
847
|
|
|
|