Backend endpoint makes it easier consume for graph.

New endpoint has the data aggregated so we don't need to do as much in
js.
Also added simple year select when we have data spanning multiple years.
This commit is contained in:
2021-02-18 23:11:48 +01:00
parent d9de155174
commit 7234c2fbba

View File

@@ -2,89 +2,47 @@
<div class="chart">
<canvas ref="purchase-chart" width="100" height="50"></canvas>
<div ref="chartjsLegend" class="chartjsLegend"></div>
<div class="year-select" v-if="years.length">
<button
class="vin-button small"
v-for="year in years"
:class="{ active: yearSelected == year }"
@click="yearFilterClicked(year)"
>
{{ year }}
</button>
</div>
</div>
</template>
<script>
import Chartjs from "chart.js";
import { chartPurchaseByColor } from "@/api";
export default {
data() {
return {
lotteries: [],
years: [],
yearSelected: undefined,
chart: undefined
};
},
async mounted() {
let canvas = this.$refs["purchase-chart"].getContext("2d");
let response = await chartPurchaseByColor();
let labels = [];
let blue = {
label: "Blå",
borderColor: "#57d2fb",
backgroundColor: "#d4f2fe",
borderWidth: 2,
data: []
};
let yellow = {
label: "Gul",
borderColor: "#ffde5d",
backgroundColor: "#fff6d6",
borderWidth: 2,
data: []
};
let red = {
label: "Rød",
borderColor: "#ef5878",
backgroundColor: "#fbd7de",
borderWidth: 2,
data: []
};
let green = {
label: "Grønn",
borderColor: "#10e783",
backgroundColor: "#c8f9df",
borderWidth: 2,
data: []
this.lotteries = await this.chartPurchaseByColor();
if (this.lotteries?.length) this.years = [...new Set(this.lotteries.map(lot => lot.date.slice(0, 4)))];
const dataset = this.calculateChartDatapoints();
let chartData = {
labels: dataset.labels,
datasets: [dataset.blue, dataset.green, dataset.red, dataset.yellow]
};
if (response.length == 1) {
labels.push("");
blue.data.push(0);
yellow.data.push(0);
red.data.push(0);
green.data.push(0);
}
let highestNumber = 0;
for (let i = 0; i < response.length; i++) {
let thisDate = response[i];
let dateObject = new Date(thisDate.date);
labels.push(this.getPrettierDateString(dateObject));
blue.data.push(thisDate.blue);
yellow.data.push(thisDate.yellow);
red.data.push(thisDate.red);
green.data.push(thisDate.green);
if (thisDate.blue > highestNumber) {
highestNumber = thisDate.blue;
}
if (thisDate.yellow > highestNumber) {
highestNumber = thisDate.yellow;
}
if (thisDate.green > highestNumber) {
highestNumber = thisDate.green;
}
if (thisDate.red > highestNumber) {
highestNumber = thisDate.red;
}
}
let datasets = [blue, yellow, green, red];
let chartdata = {
labels: labels,
datasets: datasets
};
let chart = new Chart(canvas, {
this.chart = new Chart(canvas, {
type: "line",
data: chartdata,
data: chartData,
options: {
maintainAspectRatio: false,
animation: {
@@ -110,8 +68,7 @@ export default {
yAxes: [
{
ticks: {
beginAtZero: true,
suggestedMax: highestNumber + 5
beginAtZero: true
}
}
]
@@ -120,10 +77,82 @@ export default {
});
},
methods: {
async yearFilterClicked(year) {
this.yearSelected = this.yearSelected === year ? null : year;
this.lotteries = await this.chartPurchaseByColor();
const dataset = this.calculateChartDatapoints();
let chartData = {
labels: dataset.labels,
datasets: [dataset.blue, dataset.green, dataset.red, dataset.yellow]
};
this.chart.data = chartData;
this.chart.update();
},
setupDataset() {
let blue = {
label: "Blå",
borderColor: "#57d2fb",
backgroundColor: "#d4f2fe",
borderWidth: 2,
data: []
};
let yellow = {
label: "Gul",
borderColor: "#ffde5d",
backgroundColor: "#fff6d6",
borderWidth: 2,
data: []
};
let red = {
label: "Rød",
borderColor: "#ef5878",
backgroundColor: "#fbd7de",
borderWidth: 2,
data: []
};
let green = {
label: "Grønn",
borderColor: "#10e783",
backgroundColor: "#c8f9df",
borderWidth: 2,
data: []
};
return {
labels: [""],
blue,
green,
red,
yellow
};
},
calculateChartDatapoints() {
let dataset = this.setupDataset();
this.lotteries.map(lottery => {
const date = new Date(lottery.date);
dataset.labels.push(this.getPrettierDateString(date));
dataset.blue.data.push(lottery.blue);
dataset.green.data.push(lottery.green);
dataset.red.data.push(lottery.red);
dataset.yellow.data.push(lottery.yellow);
});
return dataset;
},
chartPurchaseByColor() {
const url = new URL("/api/lotteries", window.location);
if (this.yearSelected != null) url.searchParams.set("year", this.yearSelected);
return fetch(url.href)
.then(resp => resp.json())
.then(response => response.lotteries);
},
getPrettierDateString(date) {
return `${this.pad(date.getDate())}.${this.pad(
date.getMonth() + 1
)}.${this.pad(date.getYear() - 100)}`;
return `${this.pad(date.getDate())}.${this.pad(date.getMonth() + 1)}.${this.pad(date.getYear() - 100)}`;
},
pad(num) {
if (num < 10) {
@@ -136,11 +165,19 @@ export default {
</script>
<style lang="scss" scoped>
@import "../styles/media-queries.scss";
@import "@/styles/media-queries.scss";
.chart {
height: 40vh;
max-height: 500px;
width: 100%;
}
.year-select {
margin-top: 1rem;
button:not(:first-of-type) {
margin-left: 0.5rem;
}
}
</style>