Improved charting.

This commit is contained in:
Mario Zechner 2023-06-14 04:06:25 +02:00
parent 38a11e0e79
commit 64350d27f6

View File

@ -2,7 +2,9 @@ const { STORE_KEYS } = require("../model/stores");
const { today, log, deltaTime } = require("../js/misc"); const { today, log, deltaTime } = require("../js/misc");
const { View } = require("./view"); const { View } = require("./view");
require("./custom-checkbox"); require("./custom-checkbox");
const moment = require("moment");
const { Chart, registerables } = require("chart.js"); const { Chart, registerables } = require("chart.js");
require("chartjs-adapter-moment");
Chart.register(...registerables); Chart.register(...registerables);
class ItemsChart extends View { class ItemsChart extends View {
@ -84,7 +86,11 @@ class ItemsChart extends View {
canvasDom.classList.remove("hidden"); canvasDom.classList.remove("hidden");
} }
const allDates = items.flatMap((item) => item.priceHistory.map((price) => price.date)); const startDate = this.elements.startDate.value;
const endDate = this.elements.endDate.value;
const allDates = items.flatMap((item) =>
item.priceHistory.filter((price) => price.date >= startDate && price.date <= endDate).map((price) => price.date)
);
const uniqueDates = [...new Set(allDates)]; const uniqueDates = [...new Set(allDates)];
uniqueDates.sort(); uniqueDates.sort();
@ -92,22 +98,54 @@ class ItemsChart extends View {
let price = null; let price = null;
const prices = uniqueDates.map((date) => { const prices = uniqueDates.map((date) => {
const priceObj = item.priceHistory.find((item) => item.date === date); const priceObj = item.priceHistory.find((item) => item.date === date);
if (!price && priceObj) price = priceObj.price; if (!price && priceObj) price = priceObj;
return priceObj ? priceObj.price : null; return priceObj;
}); });
const firstIndex = item.priceHistory.indexOf(price);
for (let i = 0; i < prices.length; i++) { for (let i = 0; i < prices.length; i++) {
if (prices[i] == null) { if (prices[i] == null) {
if (i == 0) {
if (firstIndex < item.priceHistory.length - 1) {
price = item.priceHistory[firstIndex + 1];
prices[i] = price; prices[i] = price;
}
} else {
prices[i] = price;
}
} else { } else {
price = prices[i]; price = prices[i];
} }
} }
return { const dedupPrices = [];
prices.forEach((price, index) => {
if (price == null) return;
if (dedupPrices.length == 0) {
dedupPrices.push({ price: price.price, date: uniqueDates[index] });
} else {
const lastPrice = dedupPrices[dedupPrices.length - 1];
if (lastPrice.date == price.date && lastPrice.price == price.price) return;
dedupPrices.push({ price: price.price, date: uniqueDates[index] });
}
});
const dataset = {
label: (item.store ? item.store + " " : "") + item.name, label: (item.store ? item.store + " " : "") + item.name,
data: prices, data: dedupPrices.map((price, index) => {
return {
x: moment(price.date),
y: price.price,
}; };
}),
// stepped: "before"
};
const data = dataset.data;
for (let i = 0; i < data.length; i++) {}
return dataset;
}); });
const ctx = canvasDom.getContext("2d"); const ctx = canvasDom.getContext("2d");
@ -119,13 +157,28 @@ class ItemsChart extends View {
canvasDom.lastChart = new Chart(ctx, { canvasDom.lastChart = new Chart(ctx, {
type: chartType ? chartType : "line", type: chartType ? chartType : "line",
data: { data: {
labels: uniqueDates,
datasets: datasets, datasets: datasets,
}, },
options: { options: {
responsive: true, responsive: true,
aspectRation: 16 / 9, aspectRation: 16 / 9,
scales: { scales: {
x: {
type: "time",
adapters: {
date: moment,
},
time: {
unit: "day",
displayFormats: {
day: "YYYY-MM-D",
},
},
title: {
display: true,
text: "Date",
},
},
y: { y: {
title: { title: {
display: true, display: true,
@ -169,12 +222,11 @@ class ItemsChart extends View {
items.forEach((item) => { items.forEach((item) => {
if (item.chart) { if (item.chart) {
itemsToShow.push({ const chartItem = {
name: item.store + " " + item.name, name: item.store + " " + item.name,
priceHistory: onlyToday priceHistory: onlyToday ? [{ date: today(), price: item.price }] : item.priceHistory,
? [{ date: today(), price: item.price }] };
: item.priceHistory.filter((price) => price.date >= startDate && price.date <= endDate), itemsToShow.push(chartItem);
});
} }
}); });