From 858ac79eacb9843210a5b4daaa8c60e80fc7081b Mon Sep 17 00:00:00 2001 From: ianmuchyri Date: Mon, 11 Mar 2024 14:18:32 +0300 Subject: [PATCH 1/3] add fetch data functionality to line chart Signed-off-by: ianmuchyri --- ui/web/static/js/charts.js | 96 +++++++++++++++++++-- ui/web/templates/charts/linechartmodal.html | 9 +- 2 files changed, 96 insertions(+), 9 deletions(-) diff --git a/ui/web/static/js/charts.js b/ui/web/static/js/charts.js index ec4381593..a45f36213 100644 --- a/ui/web/static/js/charts.js +++ b/ui/web/static/js/charts.js @@ -799,18 +799,19 @@ class TimeSeriesLineChart extends Echart { left: 'center', show: true }, + tooltip: { + trigger: 'axis', + }, xAxis: { type: 'category', - data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], name: '${this.chartData.xAxisLabel}', - nameLocation: 'middle', - nameGap: 35 + min: '${new Date(this.chartData.startTime)}', + max: '${new Date(this.chartData.stopTime)}', }, yAxis: { type: 'value', name: '${this.chartData.yAxisLabel}', nameLocation: 'middle', - nameGap: 35 }, legend: { show: true, @@ -818,10 +819,10 @@ class TimeSeriesLineChart extends Echart { }, series: [ { - data: [150, 230, 224, 218, 135, 147, 260], + data: [], type: 'line', lineStyle: { - width: '${this.chartData.lineWidth}', + width: ${this.chartData.lineWidth}, type: 'solid', color: '${this.chartData.lineColor}' }, @@ -830,7 +831,88 @@ class TimeSeriesLineChart extends Echart { ] }; - lineChart.setOption(option);`; + lineChart.setOption(option); + var chartdata = { + channel:'${this.chartData.channel}', + publisher:'${this.chartData.thing}', + name:'${this.chartData.valueName}', + from:${this.chartData.startTime}, + to:${this.chartData.stopTime}, + aggregation:'${this.chartData.aggregationType}', + limit:100, + interval:'${this.chartData.updateInterval}', + }; + getData(lineChart,chartdata); + + async function getData(linechart,chartData) { + try { + const response = await fetch( + "/data?channel=" + chartData.channel + + "&publisher=" + chartData.publisher + + "&name=" + chartData.name + + "&from=" + chartData.from + + "&to=" + chartData.to + + "&aggregation=" + chartData.aggregation + + "&limit=" + chartData.limit + + "&interval=" + chartData.interval, + ); + if (response.ok) { + const data = await response.json(); + const xAxisArray = []; + const yAxisArray = []; + let currentTimestamp = chartData.from; + let previousTimestamp; + const endTimestamp = chartData.to; + const intervalNum = 3600; + while (currentTimestamp <= endTimestamp) { + let messageIndex = data.messages.length - 1; + let isempty= true; + while (messageIndex >= 0 && (data.messages[messageIndex].time) >= previousTimestamp) { + const item = data.messages[messageIndex]; + if ((item.time) <= currentTimestamp) { + const date = new Date(item.time); + xAxisArray.push(date.toLocaleTimeString()); + yAxisArray.push(item.value); + isempty=false; + } + messageIndex--; + } + if (isempty) { + const date = new Date(currentTimestamp); + xAxisArray.push(date.toLocaleTimeString()); + yAxisArray.push("-"); + } + previousTimestamp = currentTimestamp; + currentTimestamp += intervalNum * 1e3; + } + linechart.setOption({ + xAxis: { + data: xAxisArray, + }, + series: [ + { + data: yAxisArray, + }, + ], + }); + } else { + // Handle errors + console.error("HTTP request failed with status:", response.status); + } + + // Poll again after a couple of seconds + setTimeout(function () { + getData(linechart, chartData); + }, 20000); + } catch (error) { + // Handle fetch or other errors + console.error("Error:", error); + // Retry after a couple of seconds + setTimeout(function () { + getData(linechart, chartData); + }, 20000); + } + }`; } } diff --git a/ui/web/templates/charts/linechartmodal.html b/ui/web/templates/charts/linechartmodal.html index 1b1fcf95e..18304484d 100644 --- a/ui/web/templates/charts/linechartmodal.html +++ b/ui/web/templates/charts/linechartmodal.html @@ -241,10 +241,15 @@ } // Create an object to store the form data - let chartData = {}; + const chartData = {}; let formData = new FormData(form); for (var pair of formData.entries()) { - chartData[pair[0]] = pair[1]; + if (pair[0] === "startTime" || pair[0] === "stopTime") { + const inputDate = new Date(pair[1]); + chartData[pair[0]] = inputDate.getTime(); + } else { + chartData[pair[0]] = pair[1]; + } } if (chartData.stopTime <= chartData.startTime) { From f17fcc0ceaa6a5eacb8b7e578bbc1f163a9dfd7f Mon Sep 17 00:00:00 2001 From: ianmuchyri Date: Wed, 13 Mar 2024 12:32:10 +0300 Subject: [PATCH 2/3] make aggregation not required Signed-off-by: ianmuchyri --- ui/web/static/js/charts.js | 5 --- ui/web/templates/charts/linechartmodal.html | 46 ++++++++++++++------- 2 files changed, 31 insertions(+), 20 deletions(-) diff --git a/ui/web/static/js/charts.js b/ui/web/static/js/charts.js index a45f36213..1ce041097 100644 --- a/ui/web/static/js/charts.js +++ b/ui/web/static/js/charts.js @@ -899,11 +899,6 @@ class TimeSeriesLineChart extends Echart { // Handle errors console.error("HTTP request failed with status:", response.status); } - - // Poll again after a couple of seconds - setTimeout(function () { - getData(linechart, chartData); - }, 20000); } catch (error) { // Handle fetch or other errors console.error("Error:", error); diff --git a/ui/web/templates/charts/linechartmodal.html b/ui/web/templates/charts/linechartmodal.html index 18304484d..63f2df966 100644 --- a/ui/web/templates/charts/linechartmodal.html +++ b/ui/web/templates/charts/linechartmodal.html @@ -122,6 +122,17 @@ required /> +
+ + +
Time Series Line Chart name="updateInterval" id="update-interval" placeholder="Enter the update interval, eg. 5s, 10m, 1h, 1d" - required /> -
Please enter a valid interval
-
-
- - +
Please enter a valid interval
@@ -252,14 +251,31 @@ } } + if (chartData.aggregationType != "") { + const updateInterval = form.querySelector("#update-interval"); + if (chartData.updateInterval === "") { + form.querySelector(".invalid-interval").innerHTML = "Please enter an Interval"; + updateInterval.classList.remove("was-validated"); + updateInterval.classList.add("is-invalid"); + return; + } else { + form.querySelector(".invalid-interval").innerHTML = ""; + updateInterval.classList.remove("is-invalid"); + updateInterval.classList.add("was-validated"); + } + } + const invalidTimeFeedback = form.querySelector(".invalid-time"); + const invalidTimeInput = form.querySelector("#stop-time"); if (chartData.stopTime <= chartData.startTime) { - const invalidTimeFeedback = form.querySelector(".invalid-time"); invalidTimeFeedback.innerHTML = "Stop time should be greater than start time"; invalidTimeFeedback.style.color = "red"; - const invalidTimeInput = form.querySelector("#stop-time"); invalidTimeInput.classList.remove("was-validated"); invalidTimeInput.classList.add("is-invalid"); return; + } else { + invalidTimeFeedback.innerHTML = ""; + invalidTimeInput.classList.remove("is-invalid"); + invalidTimeInput.classList.add("was-validated"); } var widgetID = "lineChart-" + Date.now(); From 3a2d756d718da80422b8201a0a62a2456ec10709 Mon Sep 17 00:00:00 2001 From: ianmuchyri Date: Wed, 13 Mar 2024 12:42:29 +0300 Subject: [PATCH 3/3] add path prefix Signed-off-by: ianmuchyri --- ui/web/static/js/charts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/web/static/js/charts.js b/ui/web/static/js/charts.js index 1ce041097..2b55ad992 100644 --- a/ui/web/static/js/charts.js +++ b/ui/web/static/js/charts.js @@ -847,7 +847,7 @@ class TimeSeriesLineChart extends Echart { async function getData(linechart,chartData) { try { const response = await fetch( - "/data?channel=" + chartData.channel + + "${pathPrefix}/data?channel=" + chartData.channel + "&publisher=" + chartData.publisher + "&name=" + chartData.name + "&from=" + chartData.from +