@aclymatepackages/modules 1.0.15 → 1.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/EmissionsChart.js +38 -223
- package/dist/components/EmissionsPieChart.js +2 -2
- package/dist/components/ReportSummaryBlock.js +60 -47
- package/dist/index.js +7 -0
- package/package.json +3 -7
- package/src/components/EmissionsChart.js +7 -282
- package/src/components/EmissionsPieChart.js +3 -3
- package/src/components/ReportSummaryBlock.js +53 -45
- package/src/index.js +2 -0
|
@@ -15,8 +15,6 @@ var _dayOfYear = _interopRequireDefault(require("dayjs/plugin/dayOfYear"));
|
|
|
15
15
|
var _recharts = require("recharts");
|
|
16
16
|
var _material = require("@mui/material");
|
|
17
17
|
var _formatters = require("@aclymatepackages/formatters");
|
|
18
|
-
var _dateHelpers = require("@aclymatepackages/date-helpers");
|
|
19
|
-
var _constants = require("@aclymatepackages/constants");
|
|
20
18
|
var _otherHelpers = require("@aclymatepackages/other-helpers");
|
|
21
19
|
var _EmissionsCustomTooltip = _interopRequireDefault(require("./EmissionsCustomTooltip"));
|
|
22
20
|
var _useChartWarningLabels = _interopRequireDefault(require("./useChartWarningLabels"));
|
|
@@ -34,164 +32,19 @@ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key i
|
|
|
34
32
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : String(i); }
|
|
35
33
|
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
36
34
|
_dayjs.default.extend(_dayOfYear.default);
|
|
37
|
-
const DAYS_IN_QUARTER = _constants.DAYS_PER_YEAR / 4;
|
|
38
35
|
const findObjectValuesSum = object => Object.values(object).reduce((sum, value) => sum + value, 0);
|
|
39
|
-
const
|
|
40
|
-
if (period === "quarter") {
|
|
41
|
-
return (0, _dateHelpers.findQuarterDate)(label);
|
|
42
|
-
}
|
|
43
|
-
if (period === "year") {
|
|
44
|
-
return (0, _dateHelpers.findYearFirstDate)(label);
|
|
45
|
-
}
|
|
46
|
-
return (0, _dayjs.default)(label, "MM-YY");
|
|
47
|
-
};
|
|
48
|
-
const isDateFirstDateOfPeriod = (date, period) => {
|
|
49
|
-
if (period === "quarter") {
|
|
50
|
-
const quarterFirstDate = (0, _dateHelpers.findQuarterDate)(date);
|
|
51
|
-
return (0, _dayjs.default)(date).isSame(quarterFirstDate, "day");
|
|
52
|
-
}
|
|
53
|
-
if (period === "year") {
|
|
54
|
-
const yearFirstDate = (0, _dateHelpers.findYearFirstDate)(date);
|
|
55
|
-
return (0, _dayjs.default)(date).isSame(yearFirstDate, "day");
|
|
56
|
-
}
|
|
57
|
-
return (0, _dayjs.default)(date).date() === 1;
|
|
58
|
-
};
|
|
59
|
-
const findIsEstimatedFirstDateLabel = _ref => {
|
|
36
|
+
const buildGroupedChartData = _ref => {
|
|
60
37
|
let {
|
|
61
|
-
startDate,
|
|
62
|
-
earliestEmissionDate,
|
|
63
|
-
label,
|
|
64
|
-
period
|
|
65
|
-
} = _ref;
|
|
66
|
-
const labelDate = findLabelDate(period, label);
|
|
67
|
-
const labelStartDateDifference = (0, _dateHelpers.findInclusiveDateDifference)(labelDate, startDate, period);
|
|
68
|
-
const labelDateIsFirstOfPeriod = isDateFirstDateOfPeriod(earliestEmissionDate, period);
|
|
69
|
-
return labelStartDateDifference === 1 && !labelDateIsFirstOfPeriod;
|
|
70
|
-
};
|
|
71
|
-
const findIsFirstPeriodEstimated = (chartLabelsArray, period) => !chartLabelsArray.reduce((acc, label) => acc && !findIsEstimatedFirstDateLabel({
|
|
72
|
-
label,
|
|
73
|
-
period
|
|
74
|
-
}), true);
|
|
75
|
-
const findIsDataProjected = latestEmissionDate => {
|
|
76
|
-
if (!(0, _dayjs.default)(latestEmissionDate).isSame((0, _dayjs.default)(), "month")) {
|
|
77
|
-
return false;
|
|
78
|
-
}
|
|
79
|
-
return (0, _dayjs.default)(latestEmissionDate).date() !== (0, _dayjs.default)().daysInMonth();
|
|
80
|
-
};
|
|
81
|
-
const findProjectedSubcategoryValueFromEmissions = _ref2 => {
|
|
82
|
-
let {
|
|
83
|
-
emissions,
|
|
84
|
-
projectionMultiplier
|
|
85
|
-
} = _ref2;
|
|
86
|
-
return subcategory => {
|
|
87
|
-
const recurringSubcategoryEmissionsSum = (0, _chartHelpers.sumEmissionsTonsBySubcategory)(emissions, subcategory);
|
|
88
|
-
return projectionMultiplier * recurringSubcategoryEmissionsSum;
|
|
89
|
-
};
|
|
90
|
-
};
|
|
91
|
-
const buildSubcategoriesProjectionObj = (emissions, projectionMultiplier) => {
|
|
92
|
-
const findProjectedSubcategoryValue = findProjectedSubcategoryValueFromEmissions({
|
|
93
|
-
emissions,
|
|
94
|
-
projectionMultiplier
|
|
95
|
-
});
|
|
96
|
-
return {
|
|
97
|
-
"commuting-auto_projected": findProjectedSubcategoryValue("commuting-auto"),
|
|
98
|
-
"home-office_projected": findProjectedSubcategoryValue("home-office"),
|
|
99
|
-
utilities_projected: findProjectedSubcategoryValue("utilities")
|
|
100
|
-
};
|
|
101
|
-
};
|
|
102
|
-
const buildScopesProjectionObj = (emissions, projectionMultiplier) => {
|
|
103
|
-
const findProjectedSubcategoryValue = findProjectedSubcategoryValueFromEmissions({
|
|
104
|
-
emissions,
|
|
105
|
-
projectionMultiplier
|
|
106
|
-
});
|
|
107
|
-
const projectedCommutingEmissionsTons = findProjectedSubcategoryValue("commuting-auto");
|
|
108
|
-
const projectedHomeOfficeEmissionsTons = findProjectedSubcategoryValue("homeOffice");
|
|
109
|
-
const projectedElectricityEmissionsTons = findProjectedSubcategoryValue("electricity");
|
|
110
|
-
const projectedGasEmissionsTons = findProjectedSubcategoryValue("gas");
|
|
111
|
-
return {
|
|
112
|
-
scope1_projected: projectedGasEmissionsTons,
|
|
113
|
-
scope2_projected: projectedElectricityEmissionsTons,
|
|
114
|
-
scope3_projected: projectedHomeOfficeEmissionsTons + projectedCommutingEmissionsTons
|
|
115
|
-
};
|
|
116
|
-
};
|
|
117
|
-
const buildGroupedChartData = _ref3 => {
|
|
118
|
-
let {
|
|
119
|
-
startDate = "",
|
|
120
|
-
period,
|
|
121
|
-
isDataProjected,
|
|
122
|
-
isFirstPeriodEstimated,
|
|
123
38
|
groupedEmissions,
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
showProjection
|
|
127
|
-
} = _ref3;
|
|
128
|
-
const findPeriodPosition = idx => {
|
|
129
|
-
if (!idx) {
|
|
130
|
-
return "first";
|
|
131
|
-
}
|
|
132
|
-
if (idx === groupedEmissions.length - 1) {
|
|
133
|
-
return "last";
|
|
134
|
-
}
|
|
135
|
-
return "middle";
|
|
136
|
-
};
|
|
137
|
-
const forwardProjectionPeriodFraction = period => {
|
|
138
|
-
if (period === "month") {
|
|
139
|
-
const daysInMonth = (0, _dayjs.default)().daysInMonth();
|
|
140
|
-
return (0, _dayjs.default)().date() / daysInMonth;
|
|
141
|
-
}
|
|
142
|
-
if (period === "quarter") {
|
|
143
|
-
const firstDayInQuarter = (0, _dateHelpers.findQuarterDate)((0, _dayjs.default)());
|
|
144
|
-
const currentDaysIntoQuarter = (0, _dayjs.default)().diff(firstDayInQuarter, "day");
|
|
145
|
-
return currentDaysIntoQuarter / DAYS_IN_QUARTER;
|
|
146
|
-
}
|
|
147
|
-
const currentDaysIntoYear = (0, _dayjs.default)().dayOfYear();
|
|
148
|
-
return currentDaysIntoYear / _constants.DAYS_PER_YEAR;
|
|
149
|
-
};
|
|
150
|
-
const backwardsProjectionPeriodFraction = period => {
|
|
151
|
-
const formattedStartDate = (0, _dayjs.default)(startDate);
|
|
152
|
-
if (period === "month") {
|
|
153
|
-
const daysInMonth = formattedStartDate.daysInMonth();
|
|
154
|
-
const daysFromEndOfMonth = daysInMonth - formattedStartDate.date();
|
|
155
|
-
return daysFromEndOfMonth / daysInMonth;
|
|
156
|
-
}
|
|
157
|
-
if (period === "quarter") {
|
|
158
|
-
const lastDateInQuarter = (0, _dateHelpers.findQuarterDate)(startDate, false);
|
|
159
|
-
const daysFromEndOfQuarter = Math.abs(formattedStartDate.diff(lastDateInQuarter, "day")) + 1;
|
|
160
|
-
return daysFromEndOfQuarter / DAYS_IN_QUARTER;
|
|
161
|
-
}
|
|
162
|
-
const daysFromEndOfYear = Math.abs(formattedStartDate.diff((0, _dayjs.default)(new Date(formattedStartDate.year(), 12, 31)), "day"));
|
|
163
|
-
return daysFromEndOfYear / _constants.DAYS_PER_YEAR;
|
|
164
|
-
};
|
|
165
|
-
const findPeriodProjectionMultiplier = _ref4 => {
|
|
166
|
-
let {
|
|
167
|
-
period,
|
|
168
|
-
position
|
|
169
|
-
} = _ref4;
|
|
170
|
-
if (!showProjection || position === "middle" || position === "first" && !isFirstPeriodEstimated || position === "last" && !isDataProjected) {
|
|
171
|
-
return 0;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
//TODO: -UPDATE: this projection function doesn't take into account closed offices or terminated employee, so we probably need to rethink it
|
|
175
|
-
const projectionFraction = position === "first" ? backwardsProjectionPeriodFraction(period) : forwardProjectionPeriodFraction(period);
|
|
176
|
-
return 1 / projectionFraction - 1;
|
|
177
|
-
};
|
|
39
|
+
buildRealDataObj
|
|
40
|
+
} = _ref;
|
|
178
41
|
return groupedEmissions.map((emissionsArray, idx) => {
|
|
179
|
-
const position = findPeriodPosition(idx, groupedEmissions);
|
|
180
|
-
const projectionMultiplier = findPeriodProjectionMultiplier({
|
|
181
|
-
startDate,
|
|
182
|
-
position,
|
|
183
|
-
period,
|
|
184
|
-
isDataProjected,
|
|
185
|
-
isFirstPeriodEstimated
|
|
186
|
-
});
|
|
187
|
-
const projectedCategoriesObj = buildProjectionObj(emissionsArray, projectionMultiplier);
|
|
188
42
|
const subcategoriesObj = buildRealDataObj(emissionsArray, _subcategories.allSubcategoriesWithOther);
|
|
189
|
-
const chartCategoriesObj = _objectSpread(_objectSpread({}, projectedCategoriesObj), subcategoriesObj);
|
|
190
43
|
const buildWarningObj = () => {
|
|
191
|
-
const singleEmissionWarning = emissionsArray.find(
|
|
44
|
+
const singleEmissionWarning = emissionsArray.find(_ref2 => {
|
|
192
45
|
let {
|
|
193
46
|
warning
|
|
194
|
-
} =
|
|
47
|
+
} = _ref2;
|
|
195
48
|
return !!warning;
|
|
196
49
|
});
|
|
197
50
|
if (!singleEmissionWarning) {
|
|
@@ -202,27 +55,26 @@ const buildGroupedChartData = _ref3 => {
|
|
|
202
55
|
} = singleEmissionWarning;
|
|
203
56
|
return warning;
|
|
204
57
|
};
|
|
205
|
-
return _objectSpread(_objectSpread({},
|
|
58
|
+
return _objectSpread(_objectSpread({}, subcategoriesObj), {}, {
|
|
206
59
|
warning: buildWarningObj(),
|
|
207
60
|
id: "emissions-chart-group-".concat(idx),
|
|
208
61
|
emissionsSumTons: (0, _otherHelpers.sumTonsCo2e)(emissionsArray),
|
|
209
|
-
totalEmissionsSumTons: findObjectValuesSum(
|
|
210
|
-
projectedEmissionsSumTons: findObjectValuesSum(projectedCategoriesObj)
|
|
62
|
+
totalEmissionsSumTons: findObjectValuesSum(subcategoriesObj)
|
|
211
63
|
});
|
|
212
64
|
});
|
|
213
65
|
};
|
|
214
66
|
const addTrendlineToChartData = chartData => {
|
|
215
67
|
const averageX = (chartData.length - 1) / 2;
|
|
216
|
-
const averageY = chartData.reduce((sum,
|
|
68
|
+
const averageY = chartData.reduce((sum, _ref3) => {
|
|
217
69
|
let {
|
|
218
70
|
totalEmissionsSumTons
|
|
219
|
-
} =
|
|
71
|
+
} = _ref3;
|
|
220
72
|
return Number(sum) + Number(totalEmissionsSumTons);
|
|
221
73
|
}, 0) / chartData.length;
|
|
222
|
-
const trendLineCalcData = chartData.map((
|
|
74
|
+
const trendLineCalcData = chartData.map((_ref4, idx) => {
|
|
223
75
|
let {
|
|
224
76
|
totalEmissionsSumTons
|
|
225
|
-
} =
|
|
77
|
+
} = _ref4;
|
|
226
78
|
const xDifferenceFromMean = idx - averageX;
|
|
227
79
|
const yDifferenceFromMean = totalEmissionsSumTons - averageY;
|
|
228
80
|
const xDifferenceSquared = xDifferenceFromMean * xDifferenceFromMean;
|
|
@@ -232,32 +84,32 @@ const addTrendlineToChartData = chartData => {
|
|
|
232
84
|
xyDifferenceFromMean
|
|
233
85
|
};
|
|
234
86
|
});
|
|
235
|
-
const xDifferenceSquaredSum = trendLineCalcData.reduce((sum,
|
|
87
|
+
const xDifferenceSquaredSum = trendLineCalcData.reduce((sum, _ref5) => {
|
|
236
88
|
let {
|
|
237
89
|
xDifferenceSquared
|
|
238
|
-
} =
|
|
90
|
+
} = _ref5;
|
|
239
91
|
return sum + xDifferenceSquared;
|
|
240
92
|
}, 0);
|
|
241
|
-
const xyDifferenceFromMeanSum = trendLineCalcData.reduce((sum,
|
|
93
|
+
const xyDifferenceFromMeanSum = trendLineCalcData.reduce((sum, _ref6) => {
|
|
242
94
|
let {
|
|
243
95
|
xyDifferenceFromMean
|
|
244
|
-
} =
|
|
96
|
+
} = _ref6;
|
|
245
97
|
return sum + xyDifferenceFromMean;
|
|
246
98
|
}, 0);
|
|
247
99
|
const trendlineSlope = xyDifferenceFromMeanSum / xDifferenceSquaredSum;
|
|
248
100
|
const trendlineIntercept = averageY - trendlineSlope * averageX;
|
|
249
101
|
const findTrendlineValue = x => trendlineSlope * x + trendlineIntercept;
|
|
250
|
-
return chartData.map((
|
|
102
|
+
return chartData.map((_ref7, idx) => {
|
|
251
103
|
let {
|
|
252
104
|
totalEmissionsSumTons
|
|
253
|
-
} =
|
|
254
|
-
otherProps = _objectWithoutProperties(
|
|
105
|
+
} = _ref7,
|
|
106
|
+
otherProps = _objectWithoutProperties(_ref7, _excluded);
|
|
255
107
|
return _objectSpread(_objectSpread({}, otherProps), {}, {
|
|
256
108
|
trendline: findTrendlineValue(idx)
|
|
257
109
|
});
|
|
258
110
|
});
|
|
259
111
|
};
|
|
260
|
-
const LabeledEmissionsChart =
|
|
112
|
+
const LabeledEmissionsChart = _ref8 => {
|
|
261
113
|
var _data$, _data;
|
|
262
114
|
let {
|
|
263
115
|
data,
|
|
@@ -267,7 +119,7 @@ const LabeledEmissionsChart = _ref11 => {
|
|
|
267
119
|
chartArray,
|
|
268
120
|
aspect = 3,
|
|
269
121
|
showTooltip = true
|
|
270
|
-
} =
|
|
122
|
+
} = _ref8;
|
|
271
123
|
const {
|
|
272
124
|
palette
|
|
273
125
|
} = (0, _material.useTheme)();
|
|
@@ -307,12 +159,12 @@ const LabeledEmissionsChart = _ref11 => {
|
|
|
307
159
|
categoriesArray: chartArray,
|
|
308
160
|
displayUnitLabel: displayUnitLabel
|
|
309
161
|
})
|
|
310
|
-
}), chartArray.map(
|
|
162
|
+
}), chartArray.map(_ref9 => {
|
|
311
163
|
let {
|
|
312
164
|
subcategory,
|
|
313
165
|
color
|
|
314
|
-
} =
|
|
315
|
-
otherProps = _objectWithoutProperties(
|
|
166
|
+
} = _ref9,
|
|
167
|
+
otherProps = _objectWithoutProperties(_ref9, _excluded2);
|
|
316
168
|
return /*#__PURE__*/_react.default.createElement(ChartElement, _extends({
|
|
317
169
|
key: "emissions-chart-element-".concat(subcategory),
|
|
318
170
|
type: "monotone",
|
|
@@ -332,7 +184,7 @@ const LabeledEmissionsChart = _ref11 => {
|
|
|
332
184
|
strokeDasharray: "5 5"
|
|
333
185
|
}))), warningLabels);
|
|
334
186
|
};
|
|
335
|
-
const EmissionsChart =
|
|
187
|
+
const EmissionsChart = _ref10 => {
|
|
336
188
|
let {
|
|
337
189
|
dataArray: emissions,
|
|
338
190
|
type,
|
|
@@ -340,7 +192,6 @@ const EmissionsChart = _ref13 => {
|
|
|
340
192
|
graphPeriod,
|
|
341
193
|
chartRef,
|
|
342
194
|
showTrendline,
|
|
343
|
-
showProjection,
|
|
344
195
|
displayUnit,
|
|
345
196
|
unitConverter,
|
|
346
197
|
aspect,
|
|
@@ -349,74 +200,54 @@ const EmissionsChart = _ref13 => {
|
|
|
349
200
|
startDate,
|
|
350
201
|
convertCarbonUnits,
|
|
351
202
|
displayUnitLabel,
|
|
352
|
-
|
|
353
|
-
} =
|
|
203
|
+
branding
|
|
204
|
+
} = _ref10;
|
|
354
205
|
const {
|
|
355
206
|
chartLabelsArray,
|
|
356
|
-
latestEmissionDate,
|
|
357
207
|
scopesArray,
|
|
358
208
|
subcategoriesArray,
|
|
359
|
-
period,
|
|
360
209
|
groupedEmissions
|
|
361
|
-
} = (0, _chartHelpers.buildEmissionGroupData)(emissions, graphPeriod, startDate,
|
|
362
|
-
const isDataProjected = findIsDataProjected(latestEmissionDate);
|
|
363
|
-
const isFirstPeriodEstimated = findIsFirstPeriodEstimated(chartLabelsArray, graphPeriod);
|
|
364
|
-
const buildProjectionObj = viewMode === "subcategories" ? buildSubcategoriesProjectionObj : buildScopesProjectionObj;
|
|
210
|
+
} = (0, _chartHelpers.buildEmissionGroupData)(emissions, graphPeriod, startDate, branding);
|
|
365
211
|
const buildRealDataObj = viewMode === "subcategories" ? _chartHelpers.buildSubcategoriesDataObj : _chartHelpers.buildScopesRealDataObj;
|
|
366
212
|
const buildChartData = () => {
|
|
367
213
|
const preliminaryChartData = buildGroupedChartData({
|
|
368
|
-
startDate,
|
|
369
|
-
period,
|
|
370
|
-
isDataProjected,
|
|
371
|
-
isFirstPeriodEstimated,
|
|
372
214
|
groupedEmissions,
|
|
373
|
-
|
|
374
|
-
buildRealDataObj,
|
|
375
|
-
showProjection
|
|
376
|
-
});
|
|
377
|
-
const formattedLabels = chartLabelsArray.map((label, idx) => {
|
|
378
|
-
if (idx === chartLabelsArray.length - 1 && isDataProjected) {
|
|
379
|
-
return "".concat(label, "*");
|
|
380
|
-
}
|
|
381
|
-
if (idx || !isFirstPeriodEstimated) {
|
|
382
|
-
return label;
|
|
383
|
-
}
|
|
384
|
-
return "".concat(label, "**");
|
|
215
|
+
buildRealDataObj
|
|
385
216
|
});
|
|
386
|
-
const convertChartDataObject = (chartDataObj, converter) => Object.fromEntries(Object.entries(chartDataObj).map(
|
|
387
|
-
let [key, value] =
|
|
217
|
+
const convertChartDataObject = (chartDataObj, converter) => Object.fromEntries(Object.entries(chartDataObj).map(_ref11 => {
|
|
218
|
+
let [key, value] = _ref11;
|
|
388
219
|
if (typeof value !== "number") {
|
|
389
220
|
return [key, value];
|
|
390
221
|
}
|
|
391
222
|
return [key, converter(value)];
|
|
392
223
|
}));
|
|
393
224
|
const labelChartData = chartData => chartData.map((data, idx) => _objectSpread(_objectSpread({}, data), {}, {
|
|
394
|
-
label:
|
|
225
|
+
label: chartLabelsArray[idx]
|
|
395
226
|
}));
|
|
396
227
|
if (isPercentageChart) {
|
|
397
228
|
const percentageConvertedChartData = preliminaryChartData.map(chartDataObj => {
|
|
398
|
-
const objectSubcategoryProperties = Object.keys(chartDataObj).filter(key => _subcategories.subcategories.find(
|
|
229
|
+
const objectSubcategoryProperties = Object.keys(chartDataObj).filter(key => _subcategories.subcategories.find(_ref12 => {
|
|
399
230
|
let {
|
|
400
231
|
subcategory
|
|
401
|
-
} =
|
|
232
|
+
} = _ref12;
|
|
402
233
|
return subcategory === key;
|
|
403
234
|
}));
|
|
404
235
|
const objectSubcategoryValues = objectSubcategoryProperties.map(subcategory => ({
|
|
405
236
|
key: subcategory,
|
|
406
237
|
value: chartDataObj[subcategory]
|
|
407
238
|
}));
|
|
408
|
-
const periodEmissionsSum = objectSubcategoryValues.reduce((sum,
|
|
239
|
+
const periodEmissionsSum = objectSubcategoryValues.reduce((sum, _ref13) => {
|
|
409
240
|
let {
|
|
410
241
|
value
|
|
411
|
-
} =
|
|
242
|
+
} = _ref13;
|
|
412
243
|
return value + sum;
|
|
413
244
|
}, 0);
|
|
414
245
|
const percentageConverter = value => value / periodEmissionsSum * 100;
|
|
415
|
-
const newObject = Object.fromEntries(objectSubcategoryValues.map(
|
|
246
|
+
const newObject = Object.fromEntries(objectSubcategoryValues.map(_ref14 => {
|
|
416
247
|
let {
|
|
417
248
|
key,
|
|
418
249
|
value
|
|
419
|
-
} =
|
|
250
|
+
} = _ref14;
|
|
420
251
|
return [key, value];
|
|
421
252
|
}));
|
|
422
253
|
return convertChartDataObject(newObject, percentageConverter);
|
|
@@ -445,22 +276,6 @@ const EmissionsChart = _ref13 => {
|
|
|
445
276
|
chartArray: chartArray,
|
|
446
277
|
aspect: aspect,
|
|
447
278
|
showTooltip: showTooltip
|
|
448
|
-
}))
|
|
449
|
-
item: true,
|
|
450
|
-
container: true,
|
|
451
|
-
justifyContent: "flex-end"
|
|
452
|
-
}, /*#__PURE__*/_react.default.createElement(_material.Grid, {
|
|
453
|
-
item: true
|
|
454
|
-
}, isDataProjected && showProjection && /*#__PURE__*/_react.default.createElement(_material.Typography, {
|
|
455
|
-
variant: "caption",
|
|
456
|
-
color: "textSecondary",
|
|
457
|
-
display: "block",
|
|
458
|
-
align: "right"
|
|
459
|
-
}, "*Data in the most recent period is projected since this period isn't complete yet."), isFirstPeriodEstimated && showProjection && /*#__PURE__*/_react.default.createElement(_material.Typography, {
|
|
460
|
-
variant: "caption",
|
|
461
|
-
color: "textSecondary",
|
|
462
|
-
display: "block",
|
|
463
|
-
align: "right"
|
|
464
|
-
}, "**Data in the first period is estimated since your start date is in the middle of this period."))));
|
|
279
|
+
})));
|
|
465
280
|
};
|
|
466
281
|
var _default = exports.default = EmissionsChart;
|
|
@@ -64,10 +64,10 @@ const EmissionsPieChart = _ref2 => {
|
|
|
64
64
|
dataArray: emissions,
|
|
65
65
|
viewMode = "subcategories",
|
|
66
66
|
pieChartRef,
|
|
67
|
-
|
|
67
|
+
branding
|
|
68
68
|
} = _ref2;
|
|
69
69
|
const subcategoriesArray = (0, _subcategories.buildSubcategoriesArray)(emissions);
|
|
70
|
-
const scopesArray =
|
|
70
|
+
const scopesArray = (0, _subcategories.buildScopesWithColors)(branding);
|
|
71
71
|
const emissionsSum = (0, _otherHelpers.sumTonsCo2e)(emissions);
|
|
72
72
|
const formatChartPieSlices = () => {
|
|
73
73
|
const filterFunction = subcategory => emission => {
|
|
@@ -12,19 +12,21 @@ require("core-js/modules/es.regexp.to-string.js");
|
|
|
12
12
|
require("core-js/modules/es.array.sort.js");
|
|
13
13
|
var _react = _interopRequireDefault(require("react"));
|
|
14
14
|
var _material = require("@mui/material");
|
|
15
|
-
var _modules = require("@aclymatepackages/modules");
|
|
16
15
|
var _otherHelpers = require("@aclymatepackages/other-helpers");
|
|
17
16
|
var _emissionsCalcs = require("@aclymatepackages/emissions-calcs");
|
|
18
17
|
var _converters = require("@aclymatepackages/converters");
|
|
19
18
|
var _themes = _interopRequireDefault(require("@aclymatepackages/themes"));
|
|
20
19
|
var _subcategories = require("@aclymatepackages/subcategories");
|
|
21
|
-
var _EmissionsSummarySentence = _interopRequireDefault(require("./EmissionsSummarySentence"));
|
|
22
20
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
23
21
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
24
22
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
25
23
|
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
26
24
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : String(i); }
|
|
27
25
|
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
26
|
+
// import ReportGraphContentLayout from "./ReportGraphContentLayout";
|
|
27
|
+
// import EmissionsPieChart from "./EmissionsPieChart";
|
|
28
|
+
// import EmissionsSummarySentence from "./EmissionsSummarySentence";
|
|
29
|
+
|
|
28
30
|
const adjustHexColorHue = function adjustHexColorHue(hexColor) {
|
|
29
31
|
let hueChange = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 20;
|
|
30
32
|
const rgbaColor = (0, _converters.hexToRgba)(hexColor);
|
|
@@ -147,55 +149,66 @@ const adjustHexColorHue = function adjustHexColorHue(hexColor) {
|
|
|
147
149
|
};
|
|
148
150
|
return hslToHex(adjustedHue);
|
|
149
151
|
};
|
|
150
|
-
|
|
152
|
+
|
|
153
|
+
//Sort emissions by scope
|
|
154
|
+
//Calculate total tons for emissions
|
|
155
|
+
|
|
156
|
+
//define colors for scopes
|
|
157
|
+
//use branding colors OR theme colors
|
|
158
|
+
//if branding colors: Primary = scope 1, modifedPrimary = scope 2, secondary = scope 3
|
|
159
|
+
|
|
160
|
+
//build projected scope categories/colors
|
|
161
|
+
//Build a function to lighten colors for projections
|
|
162
|
+
|
|
163
|
+
const buildScopesArrayWithColors = (emissions, branding) => {
|
|
164
|
+
const colorizeScopesArray = (scopesArray, colorsArray) => scopesArray.map((scopeObj, idx) => _objectSpread(_objectSpread({}, scopeObj), {}, {
|
|
165
|
+
color: colorsArray[idx]
|
|
166
|
+
}));
|
|
167
|
+
const scopesArray = [1, 2, 3].map(scope => {
|
|
168
|
+
const scopeEmissions = (0, _emissionsCalcs.filterEmissionsByScope)(emissions, scope);
|
|
169
|
+
const totalTonsCo2e = (0, _otherHelpers.sumTonsCo2e)(scopeEmissions);
|
|
170
|
+
return {
|
|
171
|
+
scope,
|
|
172
|
+
subcategory: "scope".concat(scope),
|
|
173
|
+
name: "Scope ".concat(scope),
|
|
174
|
+
emissions: scopeEmissions,
|
|
175
|
+
totalTonsCo2e,
|
|
176
|
+
icon: /*#__PURE__*/_react.default.createElement(_material.Typography, {
|
|
177
|
+
variant: "h6"
|
|
178
|
+
}, scope)
|
|
179
|
+
};
|
|
180
|
+
});
|
|
181
|
+
if (!branding) {
|
|
182
|
+
const colorsArray = _subcategories.scopesList.map(_ref => {
|
|
183
|
+
var _mainTheme$palette$co;
|
|
184
|
+
let {
|
|
185
|
+
color
|
|
186
|
+
} = _ref;
|
|
187
|
+
return (_mainTheme$palette$co = _themes.default.palette[color]) === null || _mainTheme$palette$co === void 0 ? void 0 : _mainTheme$palette$co.main;
|
|
188
|
+
});
|
|
189
|
+
return colorizeScopesArray(scopesArray, colorsArray);
|
|
190
|
+
}
|
|
191
|
+
const {
|
|
192
|
+
primaryColor,
|
|
193
|
+
secondaryColor
|
|
194
|
+
} = branding;
|
|
195
|
+
if (!primaryColor || !secondaryColor) {
|
|
196
|
+
return scopesArray;
|
|
197
|
+
}
|
|
198
|
+
const sortedScopes = scopesArray.sort((a, b) => b.totalTonsCo2e - a.totalTonsCo2e);
|
|
199
|
+
const adjustedPrimaryColor = adjustHexColorHue(primaryColor);
|
|
200
|
+
const colorsArray = [primaryColor, secondaryColor, adjustedPrimaryColor];
|
|
201
|
+
return colorizeScopesArray(sortedScopes, colorsArray).sort((a, b) => a.scope - b.scope);
|
|
202
|
+
};
|
|
203
|
+
const ReportSummaryBlock = _ref2 => {
|
|
151
204
|
let {
|
|
152
205
|
emissions,
|
|
153
206
|
interval,
|
|
154
207
|
branding
|
|
155
|
-
} =
|
|
156
|
-
const buildScopesArrayWithColors = () => {
|
|
157
|
-
const colorizeScopesArray = (scopesArray, colorsArray) => scopesArray.map((scopeObj, idx) => _objectSpread(_objectSpread({}, scopeObj), {}, {
|
|
158
|
-
color: colorsArray[idx]
|
|
159
|
-
}));
|
|
160
|
-
const scopesArray = [1, 2, 3].map(scope => {
|
|
161
|
-
const scopeEmissions = (0, _emissionsCalcs.filterEmissionsByScope)(emissions, scope);
|
|
162
|
-
const totalTonsCo2e = (0, _otherHelpers.sumTonsCo2e)(scopeEmissions);
|
|
163
|
-
return {
|
|
164
|
-
scope,
|
|
165
|
-
subcategory: "scope".concat(scope),
|
|
166
|
-
name: "Scope ".concat(scope),
|
|
167
|
-
emissions: scopeEmissions,
|
|
168
|
-
totalTonsCo2e,
|
|
169
|
-
icon: /*#__PURE__*/_react.default.createElement(_material.Typography, {
|
|
170
|
-
variant: "h6"
|
|
171
|
-
}, scope)
|
|
172
|
-
};
|
|
173
|
-
});
|
|
174
|
-
if (!branding) {
|
|
175
|
-
const colorsArray = _subcategories.scopesList.map(_ref2 => {
|
|
176
|
-
var _mainTheme$palette$co;
|
|
177
|
-
let {
|
|
178
|
-
color
|
|
179
|
-
} = _ref2;
|
|
180
|
-
return (_mainTheme$palette$co = _themes.default.palette[color]) === null || _mainTheme$palette$co === void 0 ? void 0 : _mainTheme$palette$co.main;
|
|
181
|
-
});
|
|
182
|
-
return colorizeScopesArray(scopesArray, colorsArray);
|
|
183
|
-
}
|
|
184
|
-
const {
|
|
185
|
-
primaryColor,
|
|
186
|
-
secondaryColor
|
|
187
|
-
} = branding;
|
|
188
|
-
if (!primaryColor || !secondaryColor) {
|
|
189
|
-
return scopesArray;
|
|
190
|
-
}
|
|
191
|
-
const sortedScopes = scopesArray.sort((a, b) => b.totalTonsCo2e - a.totalTonsCo2e);
|
|
192
|
-
const adjustedPrimaryColor = adjustHexColorHue(primaryColor);
|
|
193
|
-
const colorsArray = [primaryColor, secondaryColor, adjustedPrimaryColor];
|
|
194
|
-
return colorizeScopesArray(sortedScopes, colorsArray).sort((a, b) => a.scope - b.scope);
|
|
195
|
-
};
|
|
208
|
+
} = _ref2;
|
|
196
209
|
const scopesWithColors = buildScopesArrayWithColors();
|
|
197
210
|
const chartScopes = branding ? scopesWithColors : null;
|
|
198
|
-
return /*#__PURE__*/_react.default.createElement(
|
|
211
|
+
return /*#__PURE__*/_react.default.createElement(ReportGraphContentLayout, {
|
|
199
212
|
scopes: chartScopes,
|
|
200
213
|
contentTitle: (0, _otherHelpers.buildEmissionsSummarySentence)({
|
|
201
214
|
label: "Total Emissions",
|
|
@@ -203,7 +216,7 @@ const ReportSummaryBlock = _ref => {
|
|
|
203
216
|
}),
|
|
204
217
|
interval: interval,
|
|
205
218
|
emissions: emissions,
|
|
206
|
-
contentRows: [/*#__PURE__*/_react.default.createElement(
|
|
219
|
+
contentRows: [/*#__PURE__*/_react.default.createElement(EmissionsPieChart, {
|
|
207
220
|
dataArray: emissions,
|
|
208
221
|
viewMode: "scopes",
|
|
209
222
|
scopes: chartScopes
|
|
@@ -215,7 +228,7 @@ const ReportSummaryBlock = _ref => {
|
|
|
215
228
|
emissions,
|
|
216
229
|
color
|
|
217
230
|
} = _ref3;
|
|
218
|
-
return /*#__PURE__*/_react.default.createElement(
|
|
231
|
+
return /*#__PURE__*/_react.default.createElement(EmissionsSummarySentence, {
|
|
219
232
|
key: "summary-sentence-".concat(idx),
|
|
220
233
|
label: "Total Scope ".concat(scope),
|
|
221
234
|
emissions: emissions,
|
package/dist/index.js
CHANGED
|
@@ -51,6 +51,12 @@ Object.defineProperty(exports, "EmissionsReductionGraph", {
|
|
|
51
51
|
return _EmissionsReductionGraph.default;
|
|
52
52
|
}
|
|
53
53
|
});
|
|
54
|
+
Object.defineProperty(exports, "EmissionsSummarySentence", {
|
|
55
|
+
enumerable: true,
|
|
56
|
+
get: function get() {
|
|
57
|
+
return _EmissionsSummarySentence.default;
|
|
58
|
+
}
|
|
59
|
+
});
|
|
54
60
|
Object.defineProperty(exports, "EmissionsSummaryTable", {
|
|
55
61
|
enumerable: true,
|
|
56
62
|
get: function get() {
|
|
@@ -136,4 +142,5 @@ var _useChartWarningLabels = _interopRequireDefault(require("./components/useCha
|
|
|
136
142
|
var _EmissionsSummaryTable = _interopRequireDefault(require("./components/EmissionsSummaryTable"));
|
|
137
143
|
var _ReportSummaryBlock = _interopRequireDefault(require("./components/ReportSummaryBlock"));
|
|
138
144
|
var _ReportGraphContentLayout = _interopRequireDefault(require("./components/ReportGraphContentLayout"));
|
|
145
|
+
var _EmissionsSummarySentence = _interopRequireDefault(require("./components/EmissionsSummarySentence"));
|
|
139
146
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
package/package.json
CHANGED
|
@@ -1,29 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aclymatepackages/modules",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.17",
|
|
4
4
|
"description": "Aclymate modules",
|
|
5
5
|
"author": "William Loopesko",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"@aclymatepackages/array-immutability-helpers": "^1.0.0",
|
|
9
9
|
"@aclymatepackages/atoms": "^1.0.10",
|
|
10
|
-
"@aclymatepackages/chart-helpers": "^1.0.
|
|
11
|
-
"@aclymatepackages/constants": "^1.0.0",
|
|
10
|
+
"@aclymatepackages/chart-helpers": "^1.0.10",
|
|
12
11
|
"@aclymatepackages/converters": "^1.0.0",
|
|
13
|
-
"@aclymatepackages/date-helpers": "^1.0.0",
|
|
14
12
|
"@aclymatepackages/emissions-calcs": "^1.1.1",
|
|
15
13
|
"@aclymatepackages/fetch-aclymate-api": "^1.0.0",
|
|
16
14
|
"@aclymatepackages/formatters": "^1.0.0",
|
|
17
15
|
"@aclymatepackages/lists": "^1.0.0",
|
|
18
16
|
"@aclymatepackages/multi-part-form": "1.0.1",
|
|
19
|
-
"@aclymatepackages/other-helpers": "^1.0.
|
|
17
|
+
"@aclymatepackages/other-helpers": "^1.0.3",
|
|
20
18
|
"@aclymatepackages/reg-exp": "^1.0.0",
|
|
21
19
|
"@aclymatepackages/themes": "^1.0.0",
|
|
22
20
|
"@babel/preset-react": "^7.16.7",
|
|
23
21
|
"@emotion/react": "^11.11.1",
|
|
24
22
|
"@emotion/styled": "^11.11.0",
|
|
25
23
|
"@fortawesome/react-fontawesome": "^0.1.18",
|
|
26
|
-
"@mui/icons-material": "^5.11.16",
|
|
27
24
|
"@mui/lab": "^5.0.0-alpha.134",
|
|
28
25
|
"@mui/material": "^5.13.6",
|
|
29
26
|
"@stripe/react-stripe-js": "^2.1.0",
|
|
@@ -32,7 +29,6 @@
|
|
|
32
29
|
"dayjs": "^1.11.7",
|
|
33
30
|
"npm": "^8.19.4",
|
|
34
31
|
"peopledatalabs": "^5.0.4",
|
|
35
|
-
"react-cookie": "^6.1.0",
|
|
36
32
|
"react-countup": "^4.4.0",
|
|
37
33
|
"recharts": "^2.10.4",
|
|
38
34
|
"typewriter-effect": "^2.18.2"
|
|
@@ -14,15 +14,9 @@ import {
|
|
|
14
14
|
Tooltip as ChartTooltip,
|
|
15
15
|
} from "recharts";
|
|
16
16
|
|
|
17
|
-
import { Grid,
|
|
17
|
+
import { Grid, Box, useTheme } from "@mui/material";
|
|
18
18
|
|
|
19
19
|
import { formatDecimal } from "@aclymatepackages/formatters";
|
|
20
|
-
import {
|
|
21
|
-
findInclusiveDateDifference,
|
|
22
|
-
findYearFirstDate,
|
|
23
|
-
findQuarterDate,
|
|
24
|
-
} from "@aclymatepackages/date-helpers";
|
|
25
|
-
import { DAYS_PER_YEAR } from "@aclymatepackages/constants";
|
|
26
20
|
import { sumTonsCo2e } from "@aclymatepackages/other-helpers";
|
|
27
21
|
|
|
28
22
|
import EmissionsCustomTooltip from "./EmissionsCustomTooltip";
|
|
@@ -31,7 +25,6 @@ import useChartWarningLabels from "./useChartWarningLabels";
|
|
|
31
25
|
import {
|
|
32
26
|
buildScopesRealDataObj,
|
|
33
27
|
buildSubcategoriesDataObj,
|
|
34
|
-
sumEmissionsTonsBySubcategory,
|
|
35
28
|
buildEmissionGroupData,
|
|
36
29
|
} from "@aclymatepackages/chart-helpers";
|
|
37
30
|
import {
|
|
@@ -41,223 +34,16 @@ import {
|
|
|
41
34
|
|
|
42
35
|
dayjs.extend(dayOfYear);
|
|
43
36
|
|
|
44
|
-
const DAYS_IN_QUARTER = DAYS_PER_YEAR / 4;
|
|
45
|
-
|
|
46
37
|
const findObjectValuesSum = (object) =>
|
|
47
38
|
Object.values(object).reduce((sum, value) => sum + value, 0);
|
|
48
39
|
|
|
49
|
-
const
|
|
50
|
-
if (period === "quarter") {
|
|
51
|
-
return findQuarterDate(label);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
if (period === "year") {
|
|
55
|
-
return findYearFirstDate(label);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return dayjs(label, "MM-YY");
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
const isDateFirstDateOfPeriod = (date, period) => {
|
|
62
|
-
if (period === "quarter") {
|
|
63
|
-
const quarterFirstDate = findQuarterDate(date);
|
|
64
|
-
return dayjs(date).isSame(quarterFirstDate, "day");
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (period === "year") {
|
|
68
|
-
const yearFirstDate = findYearFirstDate(date);
|
|
69
|
-
return dayjs(date).isSame(yearFirstDate, "day");
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return dayjs(date).date() === 1;
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
const findIsEstimatedFirstDateLabel = ({
|
|
76
|
-
startDate,
|
|
77
|
-
earliestEmissionDate,
|
|
78
|
-
label,
|
|
79
|
-
period,
|
|
80
|
-
}) => {
|
|
81
|
-
const labelDate = findLabelDate(period, label);
|
|
82
|
-
const labelStartDateDifference = findInclusiveDateDifference(
|
|
83
|
-
labelDate,
|
|
84
|
-
startDate,
|
|
85
|
-
period
|
|
86
|
-
);
|
|
87
|
-
const labelDateIsFirstOfPeriod = isDateFirstDateOfPeriod(
|
|
88
|
-
earliestEmissionDate,
|
|
89
|
-
period
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
return labelStartDateDifference === 1 && !labelDateIsFirstOfPeriod;
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
const findIsFirstPeriodEstimated = (chartLabelsArray, period) =>
|
|
96
|
-
!chartLabelsArray.reduce(
|
|
97
|
-
(acc, label) => acc && !findIsEstimatedFirstDateLabel({ label, period }),
|
|
98
|
-
true
|
|
99
|
-
);
|
|
100
|
-
|
|
101
|
-
const findIsDataProjected = (latestEmissionDate) => {
|
|
102
|
-
if (!dayjs(latestEmissionDate).isSame(dayjs(), "month")) {
|
|
103
|
-
return false;
|
|
104
|
-
}
|
|
105
|
-
return dayjs(latestEmissionDate).date() !== dayjs().daysInMonth();
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
const findProjectedSubcategoryValueFromEmissions =
|
|
109
|
-
({ emissions, projectionMultiplier }) =>
|
|
110
|
-
(subcategory) => {
|
|
111
|
-
const recurringSubcategoryEmissionsSum = sumEmissionsTonsBySubcategory(
|
|
112
|
-
emissions,
|
|
113
|
-
subcategory
|
|
114
|
-
);
|
|
115
|
-
|
|
116
|
-
return projectionMultiplier * recurringSubcategoryEmissionsSum;
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
const buildSubcategoriesProjectionObj = (emissions, projectionMultiplier) => {
|
|
120
|
-
const findProjectedSubcategoryValue =
|
|
121
|
-
findProjectedSubcategoryValueFromEmissions({
|
|
122
|
-
emissions,
|
|
123
|
-
projectionMultiplier,
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
return {
|
|
127
|
-
"commuting-auto_projected": findProjectedSubcategoryValue("commuting-auto"),
|
|
128
|
-
"home-office_projected": findProjectedSubcategoryValue("home-office"),
|
|
129
|
-
utilities_projected: findProjectedSubcategoryValue("utilities"),
|
|
130
|
-
};
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
const buildScopesProjectionObj = (emissions, projectionMultiplier) => {
|
|
134
|
-
const findProjectedSubcategoryValue =
|
|
135
|
-
findProjectedSubcategoryValueFromEmissions({
|
|
136
|
-
emissions,
|
|
137
|
-
projectionMultiplier,
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
const projectedCommutingEmissionsTons =
|
|
141
|
-
findProjectedSubcategoryValue("commuting-auto");
|
|
142
|
-
const projectedHomeOfficeEmissionsTons =
|
|
143
|
-
findProjectedSubcategoryValue("homeOffice");
|
|
144
|
-
const projectedElectricityEmissionsTons =
|
|
145
|
-
findProjectedSubcategoryValue("electricity");
|
|
146
|
-
const projectedGasEmissionsTons = findProjectedSubcategoryValue("gas");
|
|
147
|
-
|
|
148
|
-
return {
|
|
149
|
-
scope1_projected: projectedGasEmissionsTons,
|
|
150
|
-
scope2_projected: projectedElectricityEmissionsTons,
|
|
151
|
-
scope3_projected:
|
|
152
|
-
projectedHomeOfficeEmissionsTons + projectedCommutingEmissionsTons,
|
|
153
|
-
};
|
|
154
|
-
};
|
|
155
|
-
|
|
156
|
-
const buildGroupedChartData = ({
|
|
157
|
-
startDate = "",
|
|
158
|
-
period,
|
|
159
|
-
isDataProjected,
|
|
160
|
-
isFirstPeriodEstimated,
|
|
161
|
-
groupedEmissions,
|
|
162
|
-
buildProjectionObj,
|
|
163
|
-
buildRealDataObj,
|
|
164
|
-
showProjection,
|
|
165
|
-
}) => {
|
|
166
|
-
const findPeriodPosition = (idx) => {
|
|
167
|
-
if (!idx) {
|
|
168
|
-
return "first";
|
|
169
|
-
}
|
|
170
|
-
if (idx === groupedEmissions.length - 1) {
|
|
171
|
-
return "last";
|
|
172
|
-
}
|
|
173
|
-
return "middle";
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
const forwardProjectionPeriodFraction = (period) => {
|
|
177
|
-
if (period === "month") {
|
|
178
|
-
const daysInMonth = dayjs().daysInMonth();
|
|
179
|
-
return dayjs().date() / daysInMonth;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
if (period === "quarter") {
|
|
183
|
-
const firstDayInQuarter = findQuarterDate(dayjs());
|
|
184
|
-
const currentDaysIntoQuarter = dayjs().diff(firstDayInQuarter, "day");
|
|
185
|
-
return currentDaysIntoQuarter / DAYS_IN_QUARTER;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
const currentDaysIntoYear = dayjs().dayOfYear();
|
|
189
|
-
return currentDaysIntoYear / DAYS_PER_YEAR;
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
const backwardsProjectionPeriodFraction = (period) => {
|
|
193
|
-
const formattedStartDate = dayjs(startDate);
|
|
194
|
-
if (period === "month") {
|
|
195
|
-
const daysInMonth = formattedStartDate.daysInMonth();
|
|
196
|
-
const daysFromEndOfMonth = daysInMonth - formattedStartDate.date();
|
|
197
|
-
return daysFromEndOfMonth / daysInMonth;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
if (period === "quarter") {
|
|
201
|
-
const lastDateInQuarter = findQuarterDate(startDate, false);
|
|
202
|
-
const daysFromEndOfQuarter =
|
|
203
|
-
Math.abs(formattedStartDate.diff(lastDateInQuarter, "day")) + 1;
|
|
204
|
-
return daysFromEndOfQuarter / DAYS_IN_QUARTER;
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
const daysFromEndOfYear = Math.abs(
|
|
208
|
-
formattedStartDate.diff(
|
|
209
|
-
dayjs(new Date(formattedStartDate.year(), 12, 31)),
|
|
210
|
-
"day"
|
|
211
|
-
)
|
|
212
|
-
);
|
|
213
|
-
|
|
214
|
-
return daysFromEndOfYear / DAYS_PER_YEAR;
|
|
215
|
-
};
|
|
216
|
-
|
|
217
|
-
const findPeriodProjectionMultiplier = ({ period, position }) => {
|
|
218
|
-
if (
|
|
219
|
-
!showProjection ||
|
|
220
|
-
position === "middle" ||
|
|
221
|
-
(position === "first" && !isFirstPeriodEstimated) ||
|
|
222
|
-
(position === "last" && !isDataProjected)
|
|
223
|
-
) {
|
|
224
|
-
return 0;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
//TODO: -UPDATE: this projection function doesn't take into account closed offices or terminated employee, so we probably need to rethink it
|
|
228
|
-
const projectionFraction =
|
|
229
|
-
position === "first"
|
|
230
|
-
? backwardsProjectionPeriodFraction(period)
|
|
231
|
-
: forwardProjectionPeriodFraction(period);
|
|
232
|
-
|
|
233
|
-
return 1 / projectionFraction - 1;
|
|
234
|
-
};
|
|
235
|
-
|
|
40
|
+
const buildGroupedChartData = ({ groupedEmissions, buildRealDataObj }) => {
|
|
236
41
|
return groupedEmissions.map((emissionsArray, idx) => {
|
|
237
|
-
const position = findPeriodPosition(idx, groupedEmissions);
|
|
238
|
-
const projectionMultiplier = findPeriodProjectionMultiplier({
|
|
239
|
-
startDate,
|
|
240
|
-
position,
|
|
241
|
-
period,
|
|
242
|
-
isDataProjected,
|
|
243
|
-
isFirstPeriodEstimated,
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
const projectedCategoriesObj = buildProjectionObj(
|
|
247
|
-
emissionsArray,
|
|
248
|
-
projectionMultiplier
|
|
249
|
-
);
|
|
250
|
-
|
|
251
42
|
const subcategoriesObj = buildRealDataObj(
|
|
252
43
|
emissionsArray,
|
|
253
44
|
allSubcategoriesWithOther
|
|
254
45
|
);
|
|
255
46
|
|
|
256
|
-
const chartCategoriesObj = {
|
|
257
|
-
...projectedCategoriesObj,
|
|
258
|
-
...subcategoriesObj,
|
|
259
|
-
};
|
|
260
|
-
|
|
261
47
|
const buildWarningObj = () => {
|
|
262
48
|
const singleEmissionWarning = emissionsArray.find(
|
|
263
49
|
({ warning }) => !!warning
|
|
@@ -272,12 +58,11 @@ const buildGroupedChartData = ({
|
|
|
272
58
|
};
|
|
273
59
|
|
|
274
60
|
return {
|
|
275
|
-
...
|
|
61
|
+
...subcategoriesObj,
|
|
276
62
|
warning: buildWarningObj(),
|
|
277
63
|
id: `emissions-chart-group-${idx}`,
|
|
278
64
|
emissionsSumTons: sumTonsCo2e(emissionsArray),
|
|
279
|
-
totalEmissionsSumTons: findObjectValuesSum(
|
|
280
|
-
projectedEmissionsSumTons: findObjectValuesSum(projectedCategoriesObj),
|
|
65
|
+
totalEmissionsSumTons: findObjectValuesSum(subcategoriesObj),
|
|
281
66
|
};
|
|
282
67
|
});
|
|
283
68
|
};
|
|
@@ -403,7 +188,6 @@ const EmissionsChart = ({
|
|
|
403
188
|
graphPeriod,
|
|
404
189
|
chartRef,
|
|
405
190
|
showTrendline,
|
|
406
|
-
showProjection,
|
|
407
191
|
displayUnit,
|
|
408
192
|
unitConverter,
|
|
409
193
|
aspect,
|
|
@@ -412,27 +196,14 @@ const EmissionsChart = ({
|
|
|
412
196
|
startDate,
|
|
413
197
|
convertCarbonUnits,
|
|
414
198
|
displayUnitLabel,
|
|
415
|
-
|
|
199
|
+
branding,
|
|
416
200
|
}) => {
|
|
417
201
|
const {
|
|
418
202
|
chartLabelsArray,
|
|
419
|
-
latestEmissionDate,
|
|
420
203
|
scopesArray,
|
|
421
204
|
subcategoriesArray,
|
|
422
|
-
period,
|
|
423
205
|
groupedEmissions,
|
|
424
|
-
} = buildEmissionGroupData(emissions, graphPeriod, startDate,
|
|
425
|
-
|
|
426
|
-
const isDataProjected = findIsDataProjected(latestEmissionDate);
|
|
427
|
-
const isFirstPeriodEstimated = findIsFirstPeriodEstimated(
|
|
428
|
-
chartLabelsArray,
|
|
429
|
-
graphPeriod
|
|
430
|
-
);
|
|
431
|
-
|
|
432
|
-
const buildProjectionObj =
|
|
433
|
-
viewMode === "subcategories"
|
|
434
|
-
? buildSubcategoriesProjectionObj
|
|
435
|
-
: buildScopesProjectionObj;
|
|
206
|
+
} = buildEmissionGroupData(emissions, graphPeriod, startDate, branding);
|
|
436
207
|
|
|
437
208
|
const buildRealDataObj =
|
|
438
209
|
viewMode === "subcategories"
|
|
@@ -441,26 +212,8 @@ const EmissionsChart = ({
|
|
|
441
212
|
|
|
442
213
|
const buildChartData = () => {
|
|
443
214
|
const preliminaryChartData = buildGroupedChartData({
|
|
444
|
-
startDate,
|
|
445
|
-
period,
|
|
446
|
-
isDataProjected,
|
|
447
|
-
isFirstPeriodEstimated,
|
|
448
215
|
groupedEmissions,
|
|
449
|
-
buildProjectionObj,
|
|
450
216
|
buildRealDataObj,
|
|
451
|
-
showProjection,
|
|
452
|
-
});
|
|
453
|
-
|
|
454
|
-
const formattedLabels = chartLabelsArray.map((label, idx) => {
|
|
455
|
-
if (idx === chartLabelsArray.length - 1 && isDataProjected) {
|
|
456
|
-
return `${label}*`;
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
if (idx || !isFirstPeriodEstimated) {
|
|
460
|
-
return label;
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
return `${label}**`;
|
|
464
217
|
});
|
|
465
218
|
|
|
466
219
|
const convertChartDataObject = (chartDataObj, converter) =>
|
|
@@ -476,7 +229,7 @@ const EmissionsChart = ({
|
|
|
476
229
|
const labelChartData = (chartData) =>
|
|
477
230
|
chartData.map((data, idx) => ({
|
|
478
231
|
...data,
|
|
479
|
-
label:
|
|
232
|
+
label: chartLabelsArray[idx],
|
|
480
233
|
}));
|
|
481
234
|
|
|
482
235
|
if (isPercentageChart) {
|
|
@@ -545,34 +298,6 @@ const EmissionsChart = ({
|
|
|
545
298
|
showTooltip={showTooltip}
|
|
546
299
|
/>
|
|
547
300
|
</Grid>
|
|
548
|
-
{(isDataProjected || isFirstPeriodEstimated) && (
|
|
549
|
-
<Grid item container justifyContent="flex-end">
|
|
550
|
-
<Grid item>
|
|
551
|
-
{isDataProjected && showProjection && (
|
|
552
|
-
<Typography
|
|
553
|
-
variant="caption"
|
|
554
|
-
color="textSecondary"
|
|
555
|
-
display="block"
|
|
556
|
-
align="right"
|
|
557
|
-
>
|
|
558
|
-
*Data in the most recent period is projected since this period
|
|
559
|
-
isn't complete yet.
|
|
560
|
-
</Typography>
|
|
561
|
-
)}
|
|
562
|
-
{isFirstPeriodEstimated && showProjection && (
|
|
563
|
-
<Typography
|
|
564
|
-
variant="caption"
|
|
565
|
-
color="textSecondary"
|
|
566
|
-
display="block"
|
|
567
|
-
align="right"
|
|
568
|
-
>
|
|
569
|
-
**Data in the first period is estimated since your start date is
|
|
570
|
-
in the middle of this period.
|
|
571
|
-
</Typography>
|
|
572
|
-
)}
|
|
573
|
-
</Grid>
|
|
574
|
-
</Grid>
|
|
575
|
-
)}
|
|
576
301
|
</Grid>
|
|
577
302
|
);
|
|
578
303
|
};
|
|
@@ -15,7 +15,7 @@ import { formatDecimal } from "@aclymatepackages/formatters";
|
|
|
15
15
|
import { sumTonsCo2e } from "@aclymatepackages/other-helpers";
|
|
16
16
|
import {
|
|
17
17
|
buildSubcategoriesArray,
|
|
18
|
-
|
|
18
|
+
buildScopesWithColors,
|
|
19
19
|
} from "@aclymatepackages/subcategories";
|
|
20
20
|
|
|
21
21
|
const PieChartCustomTooltip = ({ payload: passedPayload }) => {
|
|
@@ -49,10 +49,10 @@ const EmissionsPieChart = ({
|
|
|
49
49
|
dataArray: emissions,
|
|
50
50
|
viewMode = "subcategories",
|
|
51
51
|
pieChartRef,
|
|
52
|
-
|
|
52
|
+
branding,
|
|
53
53
|
}) => {
|
|
54
54
|
const subcategoriesArray = buildSubcategoriesArray(emissions);
|
|
55
|
-
const scopesArray =
|
|
55
|
+
const scopesArray = buildScopesWithColors(branding);
|
|
56
56
|
|
|
57
57
|
const emissionsSum = sumTonsCo2e(emissions);
|
|
58
58
|
|
|
@@ -2,10 +2,6 @@ import React from "react";
|
|
|
2
2
|
|
|
3
3
|
import { Typography } from "@mui/material";
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
EmissionsPieChart,
|
|
7
|
-
ReportGraphContentLayout,
|
|
8
|
-
} from "@aclymatepackages/modules";
|
|
9
5
|
import {
|
|
10
6
|
buildEmissionsSummarySentence,
|
|
11
7
|
sumTonsCo2e,
|
|
@@ -15,7 +11,9 @@ import { hexToRgba } from "@aclymatepackages/converters";
|
|
|
15
11
|
import mainTheme from "@aclymatepackages/themes";
|
|
16
12
|
import { scopesList } from "@aclymatepackages/subcategories";
|
|
17
13
|
|
|
18
|
-
import
|
|
14
|
+
// import ReportGraphContentLayout from "./ReportGraphContentLayout";
|
|
15
|
+
// import EmissionsPieChart from "./EmissionsPieChart";
|
|
16
|
+
// import EmissionsSummarySentence from "./EmissionsSummarySentence";
|
|
19
17
|
|
|
20
18
|
const adjustHexColorHue = (hexColor, hueChange = 20) => {
|
|
21
19
|
const rgbaColor = hexToRgba(hexColor);
|
|
@@ -135,51 +133,61 @@ const adjustHexColorHue = (hexColor, hueChange = 20) => {
|
|
|
135
133
|
return hslToHex(adjustedHue);
|
|
136
134
|
};
|
|
137
135
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
const colorizeScopesArray = (scopesArray, colorsArray) =>
|
|
141
|
-
scopesArray.map((scopeObj, idx) => ({
|
|
142
|
-
...scopeObj,
|
|
143
|
-
color: colorsArray[idx],
|
|
144
|
-
}));
|
|
145
|
-
|
|
146
|
-
const scopesArray = [1, 2, 3].map((scope) => {
|
|
147
|
-
const scopeEmissions = filterEmissionsByScope(emissions, scope);
|
|
148
|
-
const totalTonsCo2e = sumTonsCo2e(scopeEmissions);
|
|
149
|
-
return {
|
|
150
|
-
scope,
|
|
151
|
-
subcategory: `scope${scope}`,
|
|
152
|
-
name: `Scope ${scope}`,
|
|
153
|
-
emissions: scopeEmissions,
|
|
154
|
-
totalTonsCo2e,
|
|
155
|
-
icon: <Typography variant="h6">{scope}</Typography>,
|
|
156
|
-
};
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
if (!branding) {
|
|
160
|
-
const colorsArray = scopesList.map(
|
|
161
|
-
({ color }) => mainTheme.palette[color]?.main
|
|
162
|
-
);
|
|
163
|
-
|
|
164
|
-
return colorizeScopesArray(scopesArray, colorsArray);
|
|
165
|
-
}
|
|
136
|
+
//Sort emissions by scope
|
|
137
|
+
//Calculate total tons for emissions
|
|
166
138
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
}
|
|
139
|
+
//define colors for scopes
|
|
140
|
+
//use branding colors OR theme colors
|
|
141
|
+
//if branding colors: Primary = scope 1, modifedPrimary = scope 2, secondary = scope 3
|
|
171
142
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
143
|
+
//build projected scope categories/colors
|
|
144
|
+
//Build a function to lighten colors for projections
|
|
145
|
+
|
|
146
|
+
const buildScopesArrayWithColors = (emissions, branding) => {
|
|
147
|
+
const colorizeScopesArray = (scopesArray, colorsArray) =>
|
|
148
|
+
scopesArray.map((scopeObj, idx) => ({
|
|
149
|
+
...scopeObj,
|
|
150
|
+
color: colorsArray[idx],
|
|
151
|
+
}));
|
|
152
|
+
|
|
153
|
+
const scopesArray = [1, 2, 3].map((scope) => {
|
|
154
|
+
const scopeEmissions = filterEmissionsByScope(emissions, scope);
|
|
155
|
+
const totalTonsCo2e = sumTonsCo2e(scopeEmissions);
|
|
156
|
+
return {
|
|
157
|
+
scope,
|
|
158
|
+
subcategory: `scope${scope}`,
|
|
159
|
+
name: `Scope ${scope}`,
|
|
160
|
+
emissions: scopeEmissions,
|
|
161
|
+
totalTonsCo2e,
|
|
162
|
+
icon: <Typography variant="h6">{scope}</Typography>,
|
|
163
|
+
};
|
|
164
|
+
});
|
|
176
165
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
(
|
|
166
|
+
if (!branding) {
|
|
167
|
+
const colorsArray = scopesList.map(
|
|
168
|
+
({ color }) => mainTheme.palette[color]?.main
|
|
180
169
|
);
|
|
181
|
-
};
|
|
182
170
|
|
|
171
|
+
return colorizeScopesArray(scopesArray, colorsArray);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const { primaryColor, secondaryColor } = branding;
|
|
175
|
+
if (!primaryColor || !secondaryColor) {
|
|
176
|
+
return scopesArray;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const sortedScopes = scopesArray.sort(
|
|
180
|
+
(a, b) => b.totalTonsCo2e - a.totalTonsCo2e
|
|
181
|
+
);
|
|
182
|
+
const adjustedPrimaryColor = adjustHexColorHue(primaryColor);
|
|
183
|
+
|
|
184
|
+
const colorsArray = [primaryColor, secondaryColor, adjustedPrimaryColor];
|
|
185
|
+
return colorizeScopesArray(sortedScopes, colorsArray).sort(
|
|
186
|
+
(a, b) => a.scope - b.scope
|
|
187
|
+
);
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
const ReportSummaryBlock = ({ emissions, interval, branding }) => {
|
|
183
191
|
const scopesWithColors = buildScopesArrayWithColors();
|
|
184
192
|
|
|
185
193
|
const chartScopes = branding ? scopesWithColors : null;
|
package/src/index.js
CHANGED
|
@@ -17,6 +17,7 @@ import useChartWarningLabels from "./components/useChartWarningLabels";
|
|
|
17
17
|
import EmissionsSummaryTable from "./components/EmissionsSummaryTable";
|
|
18
18
|
import ReportSummaryBlock from "./components/ReportSummaryBlock";
|
|
19
19
|
import ReportGraphContentLayout from "./components/ReportGraphContentLayout";
|
|
20
|
+
import EmissionsSummarySentence from "./components/EmissionsSummarySentence";
|
|
20
21
|
|
|
21
22
|
export {
|
|
22
23
|
FootprintVideo,
|
|
@@ -38,4 +39,5 @@ export {
|
|
|
38
39
|
EmissionsSummaryTable,
|
|
39
40
|
ReportSummaryBlock,
|
|
40
41
|
ReportGraphContentLayout,
|
|
42
|
+
EmissionsSummarySentence,
|
|
41
43
|
};
|