mirror of
https://github.com/badlogic/heissepreise.git
synced 2024-06-23 17:05:53 +02:00
Improve responsiveness of input box via timeout delay, add date range to chart, add sum and sum by store charting to main page.
This commit is contained in:
parent
08103a4c95
commit
6449ec971a
|
@ -26,6 +26,10 @@
|
|||
<label><input type="checkbox" id="sumstores" checked> Preissumme pro Kette</label>
|
||||
<label><input type="checkbox" id="todayonly"> Nur heutige Preise</label>
|
||||
</div>
|
||||
<div>
|
||||
<label>Von <input id="start" type="date"></label>
|
||||
<label>Bis <input id="end"type="date"></label>
|
||||
</div>
|
||||
<hr>
|
||||
<input id="filter" type="text" style="max-width: 800px; width: 100%; margin-bottom: 1em;" placeholder="Filtern...">
|
||||
<div class="filters" id="filters-store">
|
||||
|
|
25
site/cart.js
25
site/cart.js
|
@ -67,6 +67,10 @@ async function load() {
|
|||
document.querySelector("#sum").addEventListener("change", () => updateCharts(canvasDom, filter(cart.items)));
|
||||
document.querySelector("#sumstores").addEventListener("change", () => updateCharts(canvasDom, filter(cart.items)));
|
||||
document.querySelector("#todayonly").addEventListener("change", () => updateCharts(canvasDom, filter(cart.items)));
|
||||
document.querySelector("#start").addEventListener("change", () => updateCharts(canvasDom, filter(cart.items)));
|
||||
document.querySelector("#end").addEventListener("change", () => updateCharts(canvasDom, filter(cart.items)));
|
||||
document.querySelector("#start").value = getOldestDate(cart.items);
|
||||
document.querySelector("#end").value = currentDate();
|
||||
|
||||
const filtersStore = document.querySelector("#filters-store");
|
||||
filtersStore.innerHTML = STORE_KEYS.map(store => `<label><input id="${store}" type="checkbox" checked="true">${stores[store].name}</label>`).join(" ");
|
||||
|
@ -103,6 +107,8 @@ function showSearch(cart, items) {
|
|||
cell.children[0].addEventListener("click", () => {
|
||||
cart.items.push(item);
|
||||
shoppingCarts.save();
|
||||
document.querySelector("#start").value = getOldestDate(cart.items);
|
||||
document.querySelector("#end").value = currentDate();
|
||||
showCart(cart);
|
||||
});
|
||||
itemDom.appendChild(cell);
|
||||
|
@ -111,7 +117,22 @@ function showSearch(cart, items) {
|
|||
}
|
||||
|
||||
function updateCharts(canvasDom, items) {
|
||||
showCharts(canvasDom, items, document.querySelector("#sum").checked, document.querySelector("#sumstores").checked, document.querySelector("#todayonly").checked);
|
||||
let startDate = document.querySelector("#start").value;
|
||||
let endDate = document.querySelector("#end").value;
|
||||
if (start > endDate) {
|
||||
let tmp = start;
|
||||
start = endDate;
|
||||
endDate = tmp;
|
||||
}
|
||||
showCharts(
|
||||
canvasDom,
|
||||
items,
|
||||
document.querySelector("#sum").checked,
|
||||
document.querySelector("#sumstores").checked,
|
||||
document.querySelector("#todayonly").checked,
|
||||
startDate,
|
||||
endDate
|
||||
);
|
||||
}
|
||||
|
||||
function showCart(cart) {
|
||||
|
@ -156,6 +177,8 @@ function showCart(cart) {
|
|||
cell.children[1].addEventListener("click", () => {
|
||||
cart.items.splice(idx, 1);
|
||||
shoppingCarts.save();
|
||||
document.querySelector("#start").value = getOldestDate(cart.items);
|
||||
document.querySelector("#end").value = currentDate();
|
||||
showCart(cart)
|
||||
});
|
||||
|
||||
|
|
|
@ -17,7 +17,18 @@
|
|||
<a href="changes.html">Tagespreisänderungen</a>
|
||||
<a href="carts.html">Warenkörbe</a>
|
||||
</div>
|
||||
<canvas id="chart" style="display: none;"></canvas>
|
||||
<div id="chart" class="column hide" style="width: 80%">
|
||||
<canvas></canvas>
|
||||
<div class="filters" style="margin-top: 1em;">
|
||||
<label><input type="checkbox" id="sum"> Preissumme Gesamt</label>
|
||||
<label><input type="checkbox" id="sumstores"> Preissumme pro Kette</label>
|
||||
<label><input type="checkbox" id="todayonly"> Nur heutige Preise</label>
|
||||
</div>
|
||||
<div>
|
||||
<label>Von <input id="start" type="date"></label>
|
||||
<label>Bis <input id="end"type="date"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div id="search" class="column">
|
||||
</div>
|
||||
</div>
|
||||
|
|
59
site/main.js
59
site/main.js
|
@ -1,10 +1,41 @@
|
|||
function updateCharts(canvasDom, items) {
|
||||
const now =performance.now();
|
||||
const sum = document.querySelector("#sum").checked;
|
||||
const sumStores = document.querySelector("#sumstores").checked;
|
||||
const todayOnly = document.querySelector("#todayonly").checked;
|
||||
let startDate = document.querySelector("#start").value;
|
||||
let endDate = document.querySelector("#end").value;
|
||||
if (start > endDate) {
|
||||
let tmp = start;
|
||||
start = endDate;
|
||||
endDate = tmp;
|
||||
}
|
||||
showCharts(canvasDom, items, sum, sumStores, todayOnly, startDate, endDate);
|
||||
console.log("Updating charts took: " + (performance.now() - now) / 1000 + " seconds");
|
||||
}
|
||||
async function load() {
|
||||
const items = await loadItems();
|
||||
const chartDom = document.querySelector("#chart");
|
||||
const canvasDom = chartDom.querySelector("canvas");
|
||||
let lastHits = null;
|
||||
document.querySelector("#sum").addEventListener("change", () => updateCharts(canvasDom, lastHits));
|
||||
document.querySelector("#sumstores").addEventListener("change", () => updateCharts(canvasDom, lastHits));
|
||||
document.querySelector("#todayonly").addEventListener("change", () => updateCharts(canvasDom, lastHits));
|
||||
document.querySelector("#start").addEventListener("change", () => updateCharts(canvasDom, lastHits));
|
||||
document.querySelector("#end").addEventListener("change", () => updateCharts(canvasDom, lastHits));
|
||||
document.querySelector("#start").value = getOldestDate(items);
|
||||
document.querySelector("#end").value = currentDate();
|
||||
|
||||
newSearchComponent(document.querySelector("#search"), items,
|
||||
(hits) => {
|
||||
items.forEach(item => item.chart = false);
|
||||
showChart(chartDom, []);
|
||||
if (hits.length > 0) {
|
||||
chartDom.classList.remove("hide");
|
||||
} else {
|
||||
chartDom.classList.add("hide");
|
||||
}
|
||||
updateCharts(canvasDom, hits);
|
||||
lastHits = hits;
|
||||
return hits;
|
||||
},
|
||||
null,
|
||||
|
@ -19,28 +50,16 @@ async function load() {
|
|||
})
|
||||
return header;
|
||||
}, (item, itemDom, items, setQuery) => {
|
||||
const chartCheckbox = dom("input");
|
||||
const checked = (getQueryParameter("c") ?? []).includes(`${item.store}:${item.id}`);
|
||||
chartCheckbox.setAttribute("type", "checkbox");
|
||||
chartCheckbox.checked = checked;
|
||||
item.chart = checked;
|
||||
chartCheckbox.setAttribute("data-id", `${item.store}:${item.id}`);
|
||||
const cell = dom("td", "");
|
||||
cell.appendChild(chartCheckbox);
|
||||
const checked = item.chart = (getQueryParameter("c") ?? []).includes(`${item.store}:${item.id}`);
|
||||
const dataId = item.store + ":" + item.id;
|
||||
const cell = dom("td", `<input type="checkbox" ${checked ? "checked" : ""} data-id="${dataId}">`);
|
||||
itemDom.appendChild(cell);
|
||||
const handleClick = (eventShouldSetQuery = false) =>{
|
||||
item.chart = chartCheckbox.checked;
|
||||
const data = [];
|
||||
items.forEach(i => { if (i.chart) data.push(i) });
|
||||
if (data.length == 0) {
|
||||
chartDom.style.display = "none";
|
||||
} else {
|
||||
chartDom.style.display = "block";
|
||||
showChart(chartDom, data);
|
||||
}
|
||||
item.chart = cell.children[0].checked;
|
||||
updateCharts(canvasDom, lastHits)
|
||||
!!eventShouldSetQuery && setQuery();
|
||||
}
|
||||
chartCheckbox.addEventListener("click", handleClick);
|
||||
cell.children[0].addEventListener("click", handleClick);
|
||||
checked && handleClick();
|
||||
return itemDom;
|
||||
});
|
||||
|
@ -49,7 +68,7 @@ async function load() {
|
|||
document.querySelector("input").value = query;
|
||||
const inputEvent = new Event('input', {
|
||||
bubbles: true,
|
||||
cancelable: true
|
||||
cancelable: false
|
||||
});
|
||||
document.querySelector("input").dispatchEvent(inputEvent);
|
||||
}
|
||||
|
|
|
@ -486,7 +486,7 @@ function newSearchComponent(parentElement, items, searched, filter, headerModifi
|
|||
|
||||
now = performance.now();
|
||||
let num = 0;
|
||||
let limit = isMobile() ? 500 : 2000;
|
||||
let limit = 500; // isMobile() ? 500 : 2000;
|
||||
hits.every(hit => {
|
||||
let itemDom = itemToDOM(hit);
|
||||
if (itemDomModifier) itemDom = itemDomModifier(hit, itemDom, hits, setQuery);
|
||||
|
@ -499,19 +499,23 @@ function newSearchComponent(parentElement, items, searched, filter, headerModifi
|
|||
lastHits = hits;
|
||||
}
|
||||
|
||||
let timeoutId;
|
||||
searchInput.addEventListener("input", (event) => {
|
||||
const query = searchInput.value.trim();
|
||||
if (query == 0) {
|
||||
minPrice.value = 0;
|
||||
maxPrice.value = 100;
|
||||
}
|
||||
if (query?.charAt(0) == "!") {
|
||||
parentElement.querySelectorAll(".filters").forEach(f => f.style.display = "none");
|
||||
} else {
|
||||
parentElement.querySelectorAll(".filters").forEach(f => f.style.display = "block");
|
||||
}
|
||||
setQuery();
|
||||
search(searchInput.value);
|
||||
clearTimeout(timeoutId);
|
||||
timeoutId = setTimeout(() => {
|
||||
const query = searchInput.value.trim();
|
||||
if (query == 0) {
|
||||
minPrice.value = 0;
|
||||
maxPrice.value = 100;
|
||||
}
|
||||
if (query?.charAt(0) == "!") {
|
||||
parentElement.querySelectorAll(".filters").forEach(f => f.style.display = "none");
|
||||
} else {
|
||||
parentElement.querySelectorAll(".filters").forEach(f => f.style.display = "block");
|
||||
}
|
||||
setQuery();
|
||||
search(searchInput.value);
|
||||
}, 50);
|
||||
});
|
||||
budgetBrands.addEventListener("change", () => search(searchInput.value));
|
||||
bio.addEventListener("change", () => search(searchInput.value));
|
||||
|
@ -587,13 +591,21 @@ function showChart(canvasDom, items, chartType) {
|
|||
document.documentElement.scrollTop = scrollTop;
|
||||
}
|
||||
|
||||
function showCharts(canvasDom, items, sum, sumStores, todayOnly) {
|
||||
function getOldestDate(items) {
|
||||
let oldestDate = "9999-01-01";
|
||||
for (item of items) {
|
||||
if (oldestDate > item.dateOldest) oldestDate = item.dateOldest;
|
||||
}
|
||||
return oldestDate;
|
||||
}
|
||||
|
||||
function showCharts(canvasDom, items, sum, sumStores, todayOnly, startDate, endDate) {
|
||||
let itemsToShow = [];
|
||||
|
||||
if (sum && items.length > 0) {
|
||||
itemsToShow.push({
|
||||
name: "Preissumme Warenkorb",
|
||||
priceHistory: calculateOverallPriceChanges(items, todayOnly)
|
||||
priceHistory: calculateOverallPriceChanges(items, todayOnly, startDate, endDate)
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -603,20 +615,27 @@ function showCharts(canvasDom, items, sum, sumStores, todayOnly) {
|
|||
if (storeItems.length > 0) {
|
||||
itemsToShow.push({
|
||||
name: "Preissumme " + store,
|
||||
priceHistory: calculateOverallPriceChanges(storeItems, todayOnly)
|
||||
priceHistory: calculateOverallPriceChanges(storeItems, todayOnly, startDate, endDate)
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
items.forEach((item) => {
|
||||
if (item.chart) itemsToShow.push({ name: item.store + " " + item.name, priceHistory: todayOnly ? [{date: currentDate(), price: item.price}] : item.priceHistory});
|
||||
if (item.chart) {
|
||||
itemsToShow.push({
|
||||
name: item.store + " " + item.name,
|
||||
priceHistory: todayOnly ?
|
||||
[{ date: currentDate(), price: item.price }] :
|
||||
item.priceHistory.filter(price => price.date >= startDate && price.date <= endDate)
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
showChart(canvasDom, itemsToShow, todayOnly ? "bar" : "line");
|
||||
}
|
||||
|
||||
function calculateOverallPriceChanges(items, todayOnly) {
|
||||
function calculateOverallPriceChanges(items, todayOnly, startDate, endDate) {
|
||||
if (items.length == 0) return { dates: [], changes: [] };
|
||||
|
||||
if (todayOnly) {
|
||||
|
@ -626,8 +645,9 @@ function calculateOverallPriceChanges(items, todayOnly) {
|
|||
}
|
||||
|
||||
const allDates = items.flatMap(product => product.priceHistory.map(item => item.date));
|
||||
const uniqueDates = [...new Set(allDates)];
|
||||
let uniqueDates = [...new Set(allDates)];
|
||||
uniqueDates.sort();
|
||||
uniqueDates = uniqueDates.filter(date => date >= startDate && date <= endDate);
|
||||
|
||||
const allPrices = items.map(product => {
|
||||
let price = null;
|
||||
|
|
Loading…
Reference in New Issue
Block a user