Session UI: better cost y axis dimensions (#16975)
This commit is contained in:
parent
7b933f2ed2
commit
d7eeced5b1
2 changed files with 42 additions and 8 deletions
|
|
@ -47,6 +47,7 @@ export default {
|
|||
period: { type: String, default: PERIODS.TOTAL },
|
||||
currency: { type: String, default: "EUR" },
|
||||
colorMappings: { type: Object, default: () => ({ loadpoint: {}, vehicle: {} }) },
|
||||
suggestedMaxAvgCost: { type: Number, default: 0 },
|
||||
suggestedMaxCost: { type: Number, default: 0 },
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -313,12 +314,13 @@ export default {
|
|||
color: colors.muted,
|
||||
maxTicksLimit: 6,
|
||||
},
|
||||
suggestedMax: this.suggestedMaxCost,
|
||||
min: 0,
|
||||
},
|
||||
y1: {
|
||||
position: "left",
|
||||
border: { display: false },
|
||||
suggestedMax: this.suggestedMaxCost,
|
||||
suggestedMax: this.suggestedMaxAvgCost,
|
||||
grid: {
|
||||
drawOnChartArea: false,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@
|
|||
:cost-type="activeType"
|
||||
:currency="currency"
|
||||
:period="period"
|
||||
:suggested-max-avg-cost="suggestedMaxAvgCost"
|
||||
:suggested-max-cost="suggestedMaxCost"
|
||||
/>
|
||||
<div v-if="showExtraCharts" class="row align-items-start">
|
||||
|
|
@ -118,7 +119,7 @@
|
|||
v-else
|
||||
:sessions="currentTypeSessions"
|
||||
:color-mappings="colorMappings"
|
||||
:suggested-max-price="suggestedMaxCost"
|
||||
:suggested-max-price="suggestedMaxAvgCost"
|
||||
:group-by="selectedGroup"
|
||||
:cost-type="activeType"
|
||||
:currency="currency"
|
||||
|
|
@ -594,17 +595,42 @@ export default {
|
|||
|
||||
return (isGrouped && hasMultipleEntries) || (isSolar && isNotMonth && !isGrouped);
|
||||
},
|
||||
suggestedMaxPrice() {
|
||||
// returns the 90th percentile of all prices
|
||||
suggestedMaxAvgPrice() {
|
||||
// returns the 98th percentile of avg prices for all sessions
|
||||
const sessionsWithPrice = this.sessions.filter((s) => s.pricePerKWh !== null);
|
||||
const prices = sessionsWithPrice.map((s) => s.pricePerKWh);
|
||||
return this.percentile(prices, 90);
|
||||
return this.percentile(prices, 98);
|
||||
},
|
||||
suggestedMaxCo2() {
|
||||
// returns the 90th percentile of all co2 emissions
|
||||
suggestedMaxAvgCo2() {
|
||||
// returns the 98th percentile of avg co2 emissions for all sessions
|
||||
const sessionsWithCo2 = this.sessions.filter((s) => s.co2PerKWh !== null);
|
||||
const co2 = sessionsWithCo2.map((s) => s.co2PerKWh);
|
||||
return this.percentile(co2, 90);
|
||||
return this.percentile(co2, 98);
|
||||
},
|
||||
suggestedMaxAvgCost() {
|
||||
return this.activeType === TYPES.PRICE
|
||||
? this.suggestedMaxAvgPrice
|
||||
: this.suggestedMaxAvgCo2;
|
||||
},
|
||||
suggestedMaxCo2() {
|
||||
// returns the 98th percentile of total co2 emissions by time period
|
||||
const sessionsWithCo2 = this.sessions.filter((s) => s.co2PerKWh !== null);
|
||||
const co2Map = sessionsWithCo2.reduce((acc, s) => {
|
||||
const key = this.dateToPeriodKey(new Date(s.created));
|
||||
acc[key] = (acc[key] || 0) + s.co2PerKWh * s.chargedEnergy;
|
||||
return acc;
|
||||
}, {});
|
||||
return Math.max(this.percentile(Object.values(co2Map), 98), 5); // 5kg default
|
||||
},
|
||||
suggestedMaxPrice() {
|
||||
// returns the 98th percentile of total price by time period
|
||||
const sessionsWithPrice = this.sessions.filter((s) => s.price !== null);
|
||||
const priceMap = sessionsWithPrice.reduce((acc, s) => {
|
||||
const key = this.dateToPeriodKey(new Date(s.created));
|
||||
acc[key] = (acc[key] || 0) + s.price;
|
||||
return acc;
|
||||
}, {});
|
||||
return Math.max(this.percentile(Object.values(priceMap), 98), 1); // 1 CURRENCY default
|
||||
},
|
||||
suggestedMaxCost() {
|
||||
return this.activeType === TYPES.PRICE ? this.suggestedMaxPrice : this.suggestedMaxCo2;
|
||||
|
|
@ -636,6 +662,12 @@ export default {
|
|||
}
|
||||
this.$router.push({ query: { ...this.$route.query, period, month, year } });
|
||||
},
|
||||
dateToPeriodKey(date) {
|
||||
const options = { year: "numeric", month: "numeric", day: "numeric" };
|
||||
if (this.period === PERIODS.YEAR) options.day = undefined;
|
||||
if (this.period === PERIODS.TOTAL) options.month = undefined;
|
||||
return date.toLocaleDateString(undefined, options);
|
||||
},
|
||||
async loadSessions() {
|
||||
const response = await api.get("sessions");
|
||||
// ensure sessions are sorted by created date
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue