From 6e867a0fae77f9502fab5c86497ada7b3b00287f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Z=C3=ADpek?= Date: Sun, 14 Aug 2022 12:46:15 +0200 Subject: [PATCH] More configuration --- client/js/index.js | 166 +++++++++++++++++++++++++++++++++------------ 1 file changed, 121 insertions(+), 45 deletions(-) diff --git a/client/js/index.js b/client/js/index.js index a2d0cc0..2091645 100644 --- a/client/js/index.js +++ b/client/js/index.js @@ -20,7 +20,7 @@ function load() { fetch("/api/sensors") .then((r) => r.json()) .then((sensors) => { - $sensorsContainer.innerHTML = '' + $sensorsContainer.innerHTML = ""; sensorComponents = sensors.map((sensor) => createSensor(sensor)); sensorComponents.forEach((component) => @@ -74,10 +74,28 @@ function renderConfig({ sensor, onSave, shown }) { +
+ + +
+
+
+ + +
+
+ + +
@@ -91,27 +109,58 @@ function renderConfig({ sensor, onSave, shown }) { ); } -const CURRENT_FILTERS = { - interval: "week", - refresh: "1s", - customFrom: new Date().toISOString(), - customTo: new Date().toISOString(), -}; +const CURRENT_FILTERS = loadFilters(); -function refreshAll() { - sensorComponents.forEach(c => c.refreshValues()) +function loadFilters() { + const params = new URLSearchParams(location.search.replace(/^\?/, "")); + + return { + interval: params.get("interval") || "week", + refresh: "1s", + customFrom: params.get("from") || new Date().toISOString(), + customTo: params.get("to") || new Date().toISOString(), + }; } -let isCustomSelected = false -let lastIntervalSelected = 'week' +function saveFilters() { + const values = { + interval: CURRENT_FILTERS.interval, + }; + + if (CURRENT_FILTERS.interval === "custom") { + values.from = CURRENT_FILTERS.customFrom.toISOString(); + values.to = CURRENT_FILTERS.customTo.toISOString(); + } + + const url = new URL(location.href); + const params = new URLSearchParams(values); + + url.search = params.toString(); + + history.replaceState(null, null, url.toString()); +} + +function refreshAll() { + sensorComponents.forEach((c) => c.refreshValues()); +} + +let lastIntervalSelected = CURRENT_FILTERS.interval; function splitDateTime(v) { - const d = new Date(v) + const d = new Date(v); - const date = d.getFullYear() + '-' + (d.getMonth() + 1).toString().padStart(2, '0') + '-' + d.getDate().toString().padStart(2, '0') - const time = d.getHours().toString().padStart(2, '0') + ':' + d.getMinutes().toString().padStart(2, '0') + const date = + d.getFullYear() + + "-" + + (d.getMonth() + 1).toString().padStart(2, "0") + + "-" + + d.getDate().toString().padStart(2, "0"); + const time = + d.getHours().toString().padStart(2, "0") + + ":" + + d.getMinutes().toString().padStart(2, "0"); - return [date, time] + return [date, time]; } function renderFilters() { @@ -128,23 +177,26 @@ function renderFilters() { CURRENT_FILTERS.customFrom = from.toISOString(); CURRENT_FILTERS.customTo = to.toISOString(); } else { - CURRENT_FILTERS.customFrom = new Date(`${data.fromDate} ${data.fromTime}`) - CURRENT_FILTERS.customTo = new Date(`${data.toDate} ${data.toTime}`) + CURRENT_FILTERS.customFrom = new Date( + `${data.fromDate} ${data.fromTime}` + ); + CURRENT_FILTERS.customTo = new Date(`${data.toDate} ${data.toTime}`); } - refreshAll() - renderFilters() + refreshAll(); + renderFilters(); + saveFilters(); }; const handleIntervalChange = (e) => { - lastIntervalSelected = e.target.value + lastIntervalSelected = e.target.value; - renderFilters() - } + renderFilters(); + }; - const customFrom = splitDateTime(CURRENT_FILTERS.customFrom) - const customTo = splitDateTime(CURRENT_FILTERS.customTo) - const isCustomSelected = lastIntervalSelected === 'custom' + const customFrom = splitDateTime(CURRENT_FILTERS.customFrom); + const customTo = splitDateTime(CURRENT_FILTERS.customTo); + const isCustomSelected = lastIntervalSelected === "custom"; render( $filters, @@ -153,7 +205,11 @@ function renderFilters() {
- @@ -162,22 +218,32 @@ function renderFilters() {
- ${isCustomSelected ? html` -
- -
- - -
-
-
- -
- - -
-
- ` : undefined} + ${isCustomSelected + ? html` +
+ +
+ + +
+
+
+ +
+ + +
+
+ ` + : undefined}
@@ -246,20 +312,30 @@ function createSensor(sensor) { const renderBody = (range, values) => { const { from, to } = range; + const minValue = parseFloat(sensor.config.min); + const maxValue = parseFloat(sensor.config.max); + const customRange = !isNaN(minValue) && !isNaN(maxValue); Plotly.newPlot( body, [ { - type: "lines", + ...(sensor.config.graphType === 'line' && { type: 'scatter', mode: 'lines' }), + ...(sensor.config.graphType === 'points' && { type: 'scatter', mode: 'markers' }), + ...(sensor.config.graphType === 'lineAndPoints' && { type: 'scatter', mode: 'lines+markers' }), + ...(sensor.config.graphType === 'bar' && { type: 'bar' }), x: values.map((v) => new Date(v.timestamp * 1000)), y: values.map((v) => v.value), }, ], { xaxis: { range: [from, to], type: "date" }, + yaxis: { + ...(customRange && { range: [minValue, maxValue] }), + ...(sensor.config.unit && { ticksuffix: ` ${sensor.config.unit}` }), + }, margin: { - l: 50, + l: 70, r: 20, b: 60, t: 20, @@ -302,7 +378,7 @@ function createSensor(sensor) { return { container, - refreshValues + refreshValues, }; }