Skip to content

Commit 1b1f637

Browse files
Maschganaltatis
andauthored
chore: Typescript: Rewrite Sessions (#21047)
Co-authored-by: Michael Geers <[email protected]>
1 parent b1d0ceb commit 1b1f637

20 files changed

+534
-377
lines changed

assets/js/components/Sessions/AvgCostGroupedChart.vue

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,33 +9,38 @@
99
</div>
1010
</template>
1111

12-
<script>
12+
<script lang="ts">
1313
import { PolarArea } from "vue-chartjs";
14-
import { RadialLinearScale, ArcElement, Legend, Tooltip } from "chart.js";
15-
import { registerChartComponents, commonOptions, tooltipLabelColor } from "./chartConfig";
14+
import { RadialLinearScale, ArcElement, Legend, Tooltip, type TooltipItem } from "chart.js";
15+
import { registerChartComponents, commonOptions, tooltipLabelColor } from "./chartConfig.ts";
1616
import formatter from "@/mixins/formatter";
1717
import colors, { dimColor } from "@/colors";
18-
import { TYPES, GROUPS } from "./types";
1918
import LegendList from "./LegendList.vue";
19+
import { defineComponent, type PropType } from "vue";
20+
import type { CURRENCY } from "@/types/evcc";
21+
import { TYPES, GROUPS, type Session } from "./types.ts";
2022
2123
registerChartComponents([RadialLinearScale, ArcElement, Legend, Tooltip]);
2224
23-
export default {
25+
export default defineComponent({
2426
name: "AvgCostGroupedChart",
2527
components: { PolarArea, LegendList },
2628
mixins: [formatter],
2729
props: {
28-
sessions: { type: Array, default: () => [] },
29-
currency: { type: String, default: "EUR" },
30-
groupBy: { type: String, default: GROUPS.LOADPOINT },
30+
sessions: { type: Array as PropType<Session[]>, default: () => [] },
31+
currency: { type: String as PropType<CURRENCY>, default: "EUR" },
32+
groupBy: {
33+
type: String as PropType<Exclude<GROUPS, GROUPS.NONE>>,
34+
default: GROUPS.LOADPOINT,
35+
},
3136
colorMappings: { type: Object, default: () => ({ loadpoint: {}, vehicle: {} }) },
3237
suggestedMax: { type: Number, default: 0 },
33-
costType: { type: String, default: TYPES.PRICE },
38+
costType: { type: String as PropType<TYPES>, default: TYPES.PRICE },
3439
},
3540
computed: {
3641
chartData() {
3742
console.log(`update ${this.costType} grouped data`);
38-
const aggregatedData = {};
43+
const aggregatedData: Record<string, { energy: number; cost: number }> = {};
3944
4045
this.sessions.forEach((session) => {
4146
const groupKey = session[this.groupBy];
@@ -45,10 +50,10 @@ export default {
4550
const chargedEnergy = session.chargedEnergy;
4651
if (this.costType === TYPES.CO2) {
4752
aggregatedData[groupKey].energy += chargedEnergy;
48-
aggregatedData[groupKey].cost += session.co2PerKWh * chargedEnergy;
53+
aggregatedData[groupKey].cost += (session.co2PerKWh || 0) * chargedEnergy;
4954
} else if (this.costType === TYPES.PRICE) {
5055
aggregatedData[groupKey].energy += chargedEnergy;
51-
aggregatedData[groupKey].cost += session.price;
56+
aggregatedData[groupKey].cost += session.price || 0;
5257
}
5358
});
5459
@@ -85,7 +90,7 @@ export default {
8590
aspectRatio: 1,
8691
borderRadius: 8,
8792
borderWidth: 3,
88-
color: colors.text,
93+
color: colors.text || "",
8994
spacing: 0,
9095
radius: "100%",
9196
plugins: {
@@ -96,45 +101,47 @@ export default {
96101
position: "topBottomCenter",
97102
callbacks: {
98103
title: () => null,
99-
label: (tooltipItem) => {
100-
const { label, raw = 0 } = tooltipItem;
104+
label: (tooltipItem: TooltipItem<"polarArea">) => {
105+
const { label, dataset, dataIndex } = tooltipItem;
106+
const d = dataset.data[dataIndex];
107+
101108
return (
102109
label +
103110
": " +
104111
(this.costType === TYPES.CO2
105-
? this.fmtCo2Long(raw)
106-
: this.fmtPricePerKWh(raw, this.currency))
112+
? this.fmtCo2Long(d)
113+
: this.fmtPricePerKWh(d, this.currency))
107114
);
108115
},
109116
labelColor: tooltipLabelColor(true),
110117
},
111-
},
118+
} as any,
112119
},
113120
scales: {
114121
r: {
115122
suggestedMin: 0,
116123
suggestedMax: this.suggestedMax,
117124
beginAtZero: false,
118125
ticks: {
119-
color: colors.muted,
120-
backdropColor: colors.background,
126+
color: colors.muted || "",
127+
backdropColor: colors.background || "",
121128
font: { size: 10 },
122129
callback: this.formatValue,
123130
maxTicksLimit: 6,
124131
},
125132
angleLines: { display: false },
126-
grid: { color: colors.border },
127-
},
133+
grid: { color: colors.border || "" },
134+
} as any,
128135
},
129136
};
130137
},
131138
},
132139
methods: {
133-
formatValue(value) {
140+
formatValue(value: number) {
134141
return this.costType === TYPES.CO2
135142
? this.fmtCo2Medium(value)
136143
: this.fmtPricePerKWh(value, this.currency);
137144
},
138145
},
139-
};
146+
});
140147
</script>

assets/js/components/Sessions/CostGroupedChart.vue

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,42 +9,55 @@
99
</div>
1010
</template>
1111

12-
<script>
12+
<script lang="ts">
1313
import { Doughnut } from "vue-chartjs";
14-
import { DoughnutController, ArcElement, LinearScale, Legend, Tooltip } from "chart.js";
14+
import {
15+
DoughnutController,
16+
ArcElement,
17+
LinearScale,
18+
Legend,
19+
Tooltip,
20+
type TooltipItem,
21+
} from "chart.js";
1522
import LegendList from "./LegendList.vue";
1623
import { registerChartComponents, commonOptions, tooltipLabelColor } from "./chartConfig";
1724
import formatter from "@/mixins/formatter";
1825
import colors from "@/colors";
19-
import { TYPES, GROUPS } from "./types";
26+
import { TYPES, GROUPS, type Session } from "./types";
27+
import { defineComponent, type PropType } from "vue";
28+
import { CURRENCY } from "@/types/evcc";
2029
2130
registerChartComponents([DoughnutController, ArcElement, LinearScale, Legend, Tooltip]);
2231
23-
export default {
32+
export default defineComponent({
2433
name: "CostGroupedChart",
2534
components: { Doughnut, LegendList },
2635
mixins: [formatter],
2736
props: {
28-
sessions: { type: Array, default: () => [] },
29-
groupBy: { type: String, default: GROUPS.LOADPOINT },
37+
sessions: { type: Array as PropType<Session[]>, default: () => [] },
38+
groupBy: {
39+
type: String as PropType<Exclude<GROUPS, GROUPS.NONE>>,
40+
default: GROUPS.LOADPOINT,
41+
},
3042
colorMappings: { type: Object, default: () => ({ loadpoint: {}, vehicle: {} }) },
31-
currency: { type: String, default: "EUR" },
32-
costType: { type: String, default: TYPES.PRICE },
43+
currency: { type: String as PropType<CURRENCY>, default: CURRENCY.EUR },
44+
costType: { type: String as PropType<TYPES>, default: TYPES.PRICE },
3345
},
3446
computed: {
3547
chartData() {
3648
console.log(`update ${this.costType} grouped data`);
37-
const aggregatedData = {};
49+
const aggregatedData: Record<string, number> = {};
3850
3951
this.sessions.forEach((session) => {
4052
const groupKey = session[this.groupBy];
4153
if (!aggregatedData[groupKey]) {
4254
aggregatedData[groupKey] = 0;
4355
}
4456
if (this.costType === TYPES.PRICE) {
45-
aggregatedData[groupKey] += session.price;
57+
aggregatedData[groupKey] += session.price || 0;
4658
} else if (this.costType === TYPES.CO2) {
47-
aggregatedData[groupKey] += session.co2PerKWh * session.chargedEnergy;
59+
aggregatedData[groupKey] +=
60+
(session.co2PerKWh || 0) * (session.chargedEnergy || 0);
4861
}
4962
});
5063
@@ -60,7 +73,7 @@ export default {
6073
},
6174
legends() {
6275
const total = this.chartData.datasets[0].data.reduce((acc, curr) => acc + curr, 0);
63-
const fmtShare = (value) => this.fmtPercentage((100 / total) * value, 1);
76+
const fmtShare = (value: number) => this.fmtPercentage((100 / total) * value, 1);
6477
return this.chartData.labels.map((label, index) => ({
6578
label: label,
6679
color: this.chartData.datasets[0].backgroundColor[index],
@@ -76,9 +89,9 @@ export default {
7689
locale: this.$i18n?.locale,
7790
aspectRatio: 1,
7891
borderRadius: 10,
79-
color: colors.text,
92+
color: colors.text || "",
8093
borderWidth: 3,
81-
borderColor: colors.background,
94+
borderColor: colors.background || "",
8295
cutout: "70%",
8396
radius: "95%",
8497
animation: { duration: 250 },
@@ -89,21 +102,24 @@ export default {
89102
axis: "r",
90103
position: "center",
91104
callbacks: {
92-
label: (tooltipItem) => this.formatValue(tooltipItem.raw || 0),
105+
label: (tooltipItem: TooltipItem<"doughnut">) =>
106+
this.formatValue(
107+
tooltipItem.dataset.data[tooltipItem.dataIndex] || 0
108+
),
93109
labelColor: tooltipLabelColor(false),
94110
},
95111
},
96112
},
97-
};
113+
} as any;
98114
},
99115
},
100116
methods: {
101-
formatValue(value) {
117+
formatValue(value: number) {
102118
if (this.costType === TYPES.PRICE) {
103119
return this.fmtMoney(value, this.currency, true, true);
104120
}
105121
return this.fmtGrams(value);
106122
},
107123
},
108-
};
124+
});
109125
</script>

0 commit comments

Comments
 (0)