Skip to content

Commit

Permalink
Session UI: better cost y axis dimensions (#16975)
Browse files Browse the repository at this point in the history
  • Loading branch information
naltatis authored Oct 30, 2024
1 parent 7b933f2 commit d7eeced
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 8 deletions.
4 changes: 3 additions & 1 deletion assets/js/components/Sessions/CostHistoryChart.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down Expand Up @@ -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,
},
Expand Down
46 changes: 39 additions & 7 deletions assets/js/views/Sessions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand All @@ -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"
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit d7eeced

Please sign in to comment.