mirror of
https://github.com/badlogic/heissepreise.git
synced 2024-06-28 03:16:12 +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="sumstores" checked> Preissumme pro Kette</label>
|
||||||
<label><input type="checkbox" id="todayonly"> Nur heutige Preise</label>
|
<label><input type="checkbox" id="todayonly"> Nur heutige Preise</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<label>Von <input id="start" type="date"></label>
|
||||||
|
<label>Bis <input id="end"type="date"></label>
|
||||||
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<input id="filter" type="text" style="max-width: 800px; width: 100%; margin-bottom: 1em;" placeholder="Filtern...">
|
<input id="filter" type="text" style="max-width: 800px; width: 100%; margin-bottom: 1em;" placeholder="Filtern...">
|
||||||
<div class="filters" id="filters-store">
|
<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("#sum").addEventListener("change", () => updateCharts(canvasDom, filter(cart.items)));
|
||||||
document.querySelector("#sumstores").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("#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");
|
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(" ");
|
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", () => {
|
cell.children[0].addEventListener("click", () => {
|
||||||
cart.items.push(item);
|
cart.items.push(item);
|
||||||
shoppingCarts.save();
|
shoppingCarts.save();
|
||||||
|
document.querySelector("#start").value = getOldestDate(cart.items);
|
||||||
|
document.querySelector("#end").value = currentDate();
|
||||||
showCart(cart);
|
showCart(cart);
|
||||||
});
|
});
|
||||||
itemDom.appendChild(cell);
|
itemDom.appendChild(cell);
|
||||||
|
@ -111,7 +117,22 @@ function showSearch(cart, items) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateCharts(canvasDom, 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) {
|
function showCart(cart) {
|
||||||
|
@ -156,6 +177,8 @@ function showCart(cart) {
|
||||||
cell.children[1].addEventListener("click", () => {
|
cell.children[1].addEventListener("click", () => {
|
||||||
cart.items.splice(idx, 1);
|
cart.items.splice(idx, 1);
|
||||||
shoppingCarts.save();
|
shoppingCarts.save();
|
||||||
|
document.querySelector("#start").value = getOldestDate(cart.items);
|
||||||
|
document.querySelector("#end").value = currentDate();
|
||||||
showCart(cart)
|
showCart(cart)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,18 @@
|
||||||
<a href="changes.html">Tagespreisänderungen</a>
|
<a href="changes.html">Tagespreisänderungen</a>
|
||||||
<a href="carts.html">Warenkörbe</a>
|
<a href="carts.html">Warenkörbe</a>
|
||||||
</div>
|
</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 id="search" class="column">
|
||||||
</div>
|
</div>
|
||||||
</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() {
|
async function load() {
|
||||||
const items = await loadItems();
|
const items = await loadItems();
|
||||||
const chartDom = document.querySelector("#chart");
|
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,
|
newSearchComponent(document.querySelector("#search"), items,
|
||||||
(hits) => {
|
(hits) => {
|
||||||
items.forEach(item => item.chart = false);
|
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;
|
return hits;
|
||||||
},
|
},
|
||||||
null,
|
null,
|
||||||
|
@ -19,28 +50,16 @@ async function load() {
|
||||||
})
|
})
|
||||||
return header;
|
return header;
|
||||||
}, (item, itemDom, items, setQuery) => {
|
}, (item, itemDom, items, setQuery) => {
|
||||||
const chartCheckbox = dom("input");
|
const checked = item.chart = (getQueryParameter("c") ?? []).includes(`${item.store}:${item.id}`);
|
||||||
const checked = (getQueryParameter("c") ?? []).includes(`${item.store}:${item.id}`);
|
const dataId = item.store + ":" + item.id;
|
||||||
chartCheckbox.setAttribute("type", "checkbox");
|
const cell = dom("td", `<input type="checkbox" ${checked ? "checked" : ""} data-id="${dataId}">`);
|
||||||
chartCheckbox.checked = checked;
|
|
||||||
item.chart = checked;
|
|
||||||
chartCheckbox.setAttribute("data-id", `${item.store}:${item.id}`);
|
|
||||||
const cell = dom("td", "");
|
|
||||||
cell.appendChild(chartCheckbox);
|
|
||||||
itemDom.appendChild(cell);
|
itemDom.appendChild(cell);
|
||||||
const handleClick = (eventShouldSetQuery = false) =>{
|
const handleClick = (eventShouldSetQuery = false) =>{
|
||||||
item.chart = chartCheckbox.checked;
|
item.chart = cell.children[0].checked;
|
||||||
const data = [];
|
updateCharts(canvasDom, lastHits)
|
||||||
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);
|
|
||||||
}
|
|
||||||
!!eventShouldSetQuery && setQuery();
|
!!eventShouldSetQuery && setQuery();
|
||||||
}
|
}
|
||||||
chartCheckbox.addEventListener("click", handleClick);
|
cell.children[0].addEventListener("click", handleClick);
|
||||||
checked && handleClick();
|
checked && handleClick();
|
||||||
return itemDom;
|
return itemDom;
|
||||||
});
|
});
|
||||||
|
@ -49,7 +68,7 @@ async function load() {
|
||||||
document.querySelector("input").value = query;
|
document.querySelector("input").value = query;
|
||||||
const inputEvent = new Event('input', {
|
const inputEvent = new Event('input', {
|
||||||
bubbles: true,
|
bubbles: true,
|
||||||
cancelable: true
|
cancelable: false
|
||||||
});
|
});
|
||||||
document.querySelector("input").dispatchEvent(inputEvent);
|
document.querySelector("input").dispatchEvent(inputEvent);
|
||||||
}
|
}
|
||||||
|
|
|
@ -486,7 +486,7 @@ function newSearchComponent(parentElement, items, searched, filter, headerModifi
|
||||||
|
|
||||||
now = performance.now();
|
now = performance.now();
|
||||||
let num = 0;
|
let num = 0;
|
||||||
let limit = isMobile() ? 500 : 2000;
|
let limit = 500; // isMobile() ? 500 : 2000;
|
||||||
hits.every(hit => {
|
hits.every(hit => {
|
||||||
let itemDom = itemToDOM(hit);
|
let itemDom = itemToDOM(hit);
|
||||||
if (itemDomModifier) itemDom = itemDomModifier(hit, itemDom, hits, setQuery);
|
if (itemDomModifier) itemDom = itemDomModifier(hit, itemDom, hits, setQuery);
|
||||||
|
@ -499,19 +499,23 @@ function newSearchComponent(parentElement, items, searched, filter, headerModifi
|
||||||
lastHits = hits;
|
lastHits = hits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let timeoutId;
|
||||||
searchInput.addEventListener("input", (event) => {
|
searchInput.addEventListener("input", (event) => {
|
||||||
const query = searchInput.value.trim();
|
clearTimeout(timeoutId);
|
||||||
if (query == 0) {
|
timeoutId = setTimeout(() => {
|
||||||
minPrice.value = 0;
|
const query = searchInput.value.trim();
|
||||||
maxPrice.value = 100;
|
if (query == 0) {
|
||||||
}
|
minPrice.value = 0;
|
||||||
if (query?.charAt(0) == "!") {
|
maxPrice.value = 100;
|
||||||
parentElement.querySelectorAll(".filters").forEach(f => f.style.display = "none");
|
}
|
||||||
} else {
|
if (query?.charAt(0) == "!") {
|
||||||
parentElement.querySelectorAll(".filters").forEach(f => f.style.display = "block");
|
parentElement.querySelectorAll(".filters").forEach(f => f.style.display = "none");
|
||||||
}
|
} else {
|
||||||
setQuery();
|
parentElement.querySelectorAll(".filters").forEach(f => f.style.display = "block");
|
||||||
search(searchInput.value);
|
}
|
||||||
|
setQuery();
|
||||||
|
search(searchInput.value);
|
||||||
|
}, 50);
|
||||||
});
|
});
|
||||||
budgetBrands.addEventListener("change", () => search(searchInput.value));
|
budgetBrands.addEventListener("change", () => search(searchInput.value));
|
||||||
bio.addEventListener("change", () => search(searchInput.value));
|
bio.addEventListener("change", () => search(searchInput.value));
|
||||||
|
@ -587,13 +591,21 @@ function showChart(canvasDom, items, chartType) {
|
||||||
document.documentElement.scrollTop = scrollTop;
|
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 = [];
|
let itemsToShow = [];
|
||||||
|
|
||||||
if (sum && items.length > 0) {
|
if (sum && items.length > 0) {
|
||||||
itemsToShow.push({
|
itemsToShow.push({
|
||||||
name: "Preissumme Warenkorb",
|
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) {
|
if (storeItems.length > 0) {
|
||||||
itemsToShow.push({
|
itemsToShow.push({
|
||||||
name: "Preissumme " + store,
|
name: "Preissumme " + store,
|
||||||
priceHistory: calculateOverallPriceChanges(storeItems, todayOnly)
|
priceHistory: calculateOverallPriceChanges(storeItems, todayOnly, startDate, endDate)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
items.forEach((item) => {
|
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");
|
showChart(canvasDom, itemsToShow, todayOnly ? "bar" : "line");
|
||||||
}
|
}
|
||||||
|
|
||||||
function calculateOverallPriceChanges(items, todayOnly) {
|
function calculateOverallPriceChanges(items, todayOnly, startDate, endDate) {
|
||||||
if (items.length == 0) return { dates: [], changes: [] };
|
if (items.length == 0) return { dates: [], changes: [] };
|
||||||
|
|
||||||
if (todayOnly) {
|
if (todayOnly) {
|
||||||
|
@ -626,8 +645,9 @@ function calculateOverallPriceChanges(items, todayOnly) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const allDates = items.flatMap(product => product.priceHistory.map(item => item.date));
|
const allDates = items.flatMap(product => product.priceHistory.map(item => item.date));
|
||||||
const uniqueDates = [...new Set(allDates)];
|
let uniqueDates = [...new Set(allDates)];
|
||||||
uniqueDates.sort();
|
uniqueDates.sort();
|
||||||
|
uniqueDates = uniqueDates.filter(date => date >= startDate && date <= endDate);
|
||||||
|
|
||||||
const allPrices = items.map(product => {
|
const allPrices = items.map(product => {
|
||||||
let price = null;
|
let price = null;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user