initial test + libraries

This commit is contained in:
l_samenv
2024-09-13 11:45:06 +02:00
parent 9105a5cb41
commit 05a77ce2f4
9 changed files with 279 additions and 96 deletions

View File

@ -41,9 +41,14 @@
<script src="externalFiles/eventsource.js"></script>
<!-- <script src="externalFiles/d3.min.js"></script> -->
<script src="externalFiles/swiper-bundle.min.js"></script>
<script src="externalFiles/Chart.bundle.min.js"></script>
<!-- <script src="externalFiles/Chart.bundle.min.js"></script> -->
<script src="externalFiles/chart.umd.min.js"></script>
<script src="externalFiles/luxon.min.js"></script>
<script src="externalFiles/chartjs-adapter-luxon.umd.min.js"></script>
<script src="externalFiles/hammer.js"></script>
<script src="externalFiles/chartjs-zoom.js"></script>
<script src="externalFiles/chartjs-plugin-zoom.min.js"></script>
<!-- <script src="externalFiles/chartjs-zoom.js"></script> -->
<script src="jsFiles/SEAWebClientLocalStorage.js"></script>
<script src="jsFiles/SEAWebClientResponsivity.js"></script>
<script src="jsFiles/SEAWebClientSwiper.js"></script>

File diff suppressed because one or more lines are too long

20
client/externalFiles/chart.umd.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,7 @@
/*!
* chartjs-adapter-luxon v1.3.1
* https://www.chartjs.org
* (c) 2023 chartjs-adapter-luxon Contributors
* Released under the MIT license
*/
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(require("chart.js"),require("luxon")):"function"==typeof define&&define.amd?define(["chart.js","luxon"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).Chart,e.luxon)}(this,(function(e,t){"use strict";const n={datetime:t.DateTime.DATETIME_MED_WITH_SECONDS,millisecond:"h:mm:ss.SSS a",second:t.DateTime.TIME_WITH_SECONDS,minute:t.DateTime.TIME_SIMPLE,hour:{hour:"numeric"},day:{day:"numeric",month:"short"},week:"DD",month:{month:"short",year:"numeric"},quarter:"'Q'q - yyyy",year:{year:"numeric"}};e._adapters._date.override({_id:"luxon",_create:function(e){return t.DateTime.fromMillis(e,this.options)},init(e){this.options.locale||(this.options.locale=e.locale)},formats:function(){return n},parse:function(e,n){const i=this.options,r=typeof e;return null===e||"undefined"===r?null:("number"===r?e=this._create(e):"string"===r?e="string"==typeof n?t.DateTime.fromFormat(e,n,i):t.DateTime.fromISO(e,i):e instanceof Date?e=t.DateTime.fromJSDate(e,i):"object"!==r||e instanceof t.DateTime||(e=t.DateTime.fromObject(e,i)),e.isValid?e.valueOf():null)},format:function(e,t){const n=this._create(e);return"string"==typeof t?n.toFormat(t):n.toLocaleString(t)},add:function(e,t,n){const i={};return i[n]=t,this._create(e).plus(i).valueOf()},diff:function(e,t,n){return this._create(e).diff(this._create(t)).as(n).valueOf()},startOf:function(e,t,n){if("isoWeek"===t){n=Math.trunc(Math.min(Math.max(0,n),6));const t=this._create(e);return t.minus({days:(t.weekday-n+7)%7}).startOf("day").valueOf()}return t?this._create(e).startOf(t).valueOf():e},endOf:function(e,t){return this._create(e).endOf(t).valueOf()}})}));

File diff suppressed because one or more lines are too long

1
client/externalFiles/luxon.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -601,8 +601,8 @@ let graphs = (function (){
* @returns If the minimun y-value of all the curves of the charts is greater than the maximum y-value (same)
*/
function autoScale(chart) {
axis = chart.options.scales.yAxes[0];
tax = chart.options.scales.xAxes[0].ticks;
axis = chart.options.scales.y;
tax = chart.options.scales.x.ticks;
datasets = chart.data.datasets;
let max = -1e99;
let min = 1e99;
@ -788,7 +788,7 @@ let graphs = (function (){
* @returns When data is received (no need to autoScale and update as it is done in reloadData)
*/
function checkReload(graph){
let tk = graph.chart.options.scales.xAxes[0].ticks;
let tk = graph.chart.options.scales.x.ticks;
let xmin = tk.min, xmax = tk.max;
/*
if (xmax < now()-100000) { // was 100000 = 100sec
@ -830,9 +830,9 @@ let graphs = (function (){
function zoomCallback(graph){
let tk, min, max;
if (currentZoomMode == 'y') {
tk = graph.chart.options.scales.yAxes[0].ticks;
tk = graph.chart.options.scales.y.ticks;
} else {
tk = graph.chart.options.scales.xAxes[0].ticks;
tk = graph.chart.options.scales.x.ticks;
}
min = tk.min;
max = tk.max;
@ -924,7 +924,7 @@ let graphs = (function (){
* @param {*} graph - The graph for which the function has to be called
*/
function panCallback(graph){
let tk = graph.chart.options.scales.xAxes[0].ticks;
let tk = graph.chart.options.scales.x.ticks;
let xmin = tk.min, xmax = tk.max;
if (liveMode && xmax < lastTime) setLiveMode(false);
setMinMax(xmin,xmax);
@ -1363,29 +1363,33 @@ function Graph(gindex, container, x_label, y_label, tag, scaleType = "linear"){
parent.appendChild(canvas);
let ctx = canvas.getContext("2d");
let self = this;
chart = new Chart(ctx, {
type: 'scatter',
options: {
responsive: true,
maintainAspectRatio: false,
animation:{duration:0},
scales: {
yAxes: [{ticks: {
beginAtZero: false,
chart = new Chart(ctx,
{
type: 'scatter',
options: {
responsive: true,
maintainAspectRatio: false,
animation:{duration:0},
scales: {
y:{
beginAtZero: false,
ticks:{
mirror: true,
padding: -10,
//workaround for proper number format
callback: function(label, index, labels) {
if(index == 0 || index == labels.length-1)
return "";
return strFormat(label);
}
},
gridLines:{drawTicks:false},
scaleLabel: false, // {display: true, labelString: y_label},
grid:{drawTicks:false},
title: false, //Former scaleLabel
type: scaleType,
position: 'right',
afterBuildTicks: function(axis, ticks) {
afterBuildTicks: function({chart}) {
let axis = chart.scales.y
let ticks = axis.ticks
if (scaleType == "logarithmic" && ticks.length <= 4) {
y1 = ticks[0];
y0 = ticks.slice(-1)[0];
@ -1405,77 +1409,206 @@ function Graph(gindex, container, x_label, y_label, tag, scaleType = "linear"){
}
return ticks
},
}],
xAxes: [{
scaleLabel: false,//{display: true, labelString: x_label},
type: 'time',
time: {
displayFormats: {'millisecond': 'HH:mm:ss.SSS', 'second': 'HH:mm:ss', 'minute': 'HH:mm','hour': 'dd HH:mm', 'day': 'dd MMM DD', 'week': 'MMM DD', 'month': 'MMM DD'},
},
ticks: { padding: -20,
callback: function(label, index, labels) {
let l = labels.length - 1;
if (index == 0 || index == l) return "";
if (index == 1 || index == l - 1) {
// skip first and / or last label, if too close to the end
let minstep = 0.05 * (labels[l].value - labels[0].value);
if (index == 1) {
if (labels[1].value - labels[0].value < minstep) return "";
} else {
if (labels[l].value - labels[l-1].value < minstep) return "";
}
x:{
title: false, // former scaleLabel
type: 'time',
time: {
displayFormats: {'millisecond': 'HH:mm:ss.SSS', 'second': 'HH:mm:ss', 'minute': 'HH:mm','hour': 'dd HH:mm', 'day': 'dd MMM DD', 'week': 'MMM DD', 'month': 'MMM DD'},
},
ticks: {
padding: -20,
// LABEL = TIMESTAMP
// callback: function(label, index, labels) {
// let l = labels.length - 1;
// if (index == 0 || index == l) return "";
// if (index == 1 || index == l - 1) {
// // skip first and / or last label, if too close to the end
// let minstep = 0.05 * (labels[l].value - labels[0].value);
// if (index == 1) {
// if (labels[1].value - labels[0].value < minstep) return "";
// } else {
// if (labels[l].value - labels[l-1].value < minstep) return "";
// }
// }
// hourofday = /\S+ (\d+:00)/.exec(label);
// if (hourofday && hourofday[1] != '00:00') {
// return hourofday[1];
// }
// return label;
// }
},
afterBuildTicks: function({chart}) {
let axis = chart.scales.x
let ticks = axis.ticks
if (!ticks || ticks.length <= 2) return ticks;
first = ticks[0].value;
step = ticks[1].value - first;
offset = (first - axis._adapter.startOf(first, 'day')) % step;
let start = 0;
if (ticks[0].value - offset < axis.min) start = 1;
let v = axis.min;
result = [{value: v, major: false}];
for (tick of ticks.slice(start)) {
v = tick.value - offset;
result.push({value: v, major: false});
}
hourofday = /\S+ (\d+:00)/.exec(label);
if (hourofday && hourofday[1] != '00:00') {
return hourofday[1];
}
return label;
v += step;
if (v < axis.max) result.push({value:v, major: false});
result.push({value: axis.max, major: false});
return result;
},
grid:{drawTicks:false},
}
},
plugins:{
tooltip: false,
legend: false,
zoom:{
pan: {
enabled: true,
mode: 'xy',
speed: 10,
threshold: 10,
onPan: function({chart}) { graphs.panCallback(chart.graph);},
onPanComplete: function({chart}){graphs.updateAuto();},
},
zoom: {
wheel:{
enabled: true
},
pinch:{
enabled: true
},
mode: isTouchDevice ? 'xy': 'x',
speed: 0.1,
sensitivity: 1,
onZoom: function({chart}) { graphs.zoomCallback(chart.graph);},
onZoomComplete: function({chart}){graphs.onZoomCompleteCallback()},
}
},
afterBuildTicks: function(axis, ticks) {
if (!ticks || ticks.length <= 2) return ticks;
first = ticks[0].value;
step = ticks[1].value - first;
offset = (first - axis._adapter.startOf(first, 'day')) % step;
let start = 0;
if (ticks[0].value - offset < axis.min) start = 1;
let v = axis.min;
result = [{value: v, major: false}];
for (tick of ticks.slice(start)) {
v = tick.value - offset;
result.push({value: v, major: false});
}
v += step;
if (v < axis.max) result.push({value:v, major: false});
result.push({value: axis.max, major: false});
return result;
},
gridLines:{drawTicks:false},
}],
},
tooltips: false,
legend: false,
pan: {
enabled: true,
mode: 'xy',
speed: 10,
threshold: 10,
onPan: function({chart}) { graphs.panCallback(chart.graph);},
//onPanComplete: function({chart}){graphs.checkReload(chart.graph);redraw()},
onPanComplete: function({chart}){graphs.updateAuto();},
},
zoom: {
enabled: true,
drag: false,
mode: isTouchDevice ? 'xy': 'x',
speed: 0.1,
sensitivity: 1,
onZoom: function({chart}) { graphs.zoomCallback(chart.graph);},
//onZoomComplete: function({chart}){graphs.checkReload(chart.graph);redraw()},
onZoomComplete: function({chart}){graphs.onZoomCompleteCallback()},
}
}
}
}
});
)
// chart = new Chart(ctx, {
// type: 'scatter',
// options: {
// responsive: true,
// maintainAspectRatio: false,
// animation:{duration:0},
// scales: {
// yAxes: [{ticks: {
// beginAtZero: false,
// mirror: true,
// padding: -10,
// //workaround for proper number format
// callback: function(label, index, labels) {
// if(index == 0 || index == labels.length-1)
// return "";
// return strFormat(label);
// }
// },
// gridLines:{drawTicks:false},
// scaleLabel: false, // {display: true, labelString: y_label},
// type: scaleType,
// position: 'right',
// afterBuildTicks: function(axis, ticks) {
// if (scaleType == "logarithmic" && ticks.length <= 4) {
// y1 = ticks[0];
// y0 = ticks.slice(-1)[0];
// span = y1 - y0;
// step = Math.abs(span * 0.3).toExponential(0);
// if (step[0] > '5') {
// step = '5' + step.substr(1);
// } else if (step[0] > '2') {
// step = '2' + step.substr(1);
// }
// step = Number.parseFloat(step);
// ticks = [y1];
// for (let yt = Math.ceil(y1 / step) * step; yt > y0; yt -= step) {
// ticks.push(yt);
// }
// ticks.push(y0);
// }
// return ticks
// },
// }],
// xAxes: [{
// scaleLabel: false,//{display: true, labelString: x_label},
// type: 'time',
// time: {
// displayFormats: {'millisecond': 'HH:mm:ss.SSS', 'second': 'HH:mm:ss', 'minute': 'HH:mm','hour': 'dd HH:mm', 'day': 'dd MMM DD', 'week': 'MMM DD', 'month': 'MMM DD'},
// },
// ticks: { padding: -20,
// callback: function(label, index, labels) {
// let l = labels.length - 1;
// if (index == 0 || index == l) return "";
// if (index == 1 || index == l - 1) {
// // skip first and / or last label, if too close to the end
// let minstep = 0.05 * (labels[l].value - labels[0].value);
// if (index == 1) {
// if (labels[1].value - labels[0].value < minstep) return "";
// } else {
// if (labels[l].value - labels[l-1].value < minstep) return "";
// }
// }
// hourofday = /\S+ (\d+:00)/.exec(label);
// if (hourofday && hourofday[1] != '00:00') {
// return hourofday[1];
// }
// return label;
// }
// },
// afterBuildTicks: function(axis, ticks) {
// if (!ticks || ticks.length <= 2) return ticks;
// first = ticks[0].value;
// step = ticks[1].value - first;
// offset = (first - axis._adapter.startOf(first, 'day')) % step;
// let start = 0;
// if (ticks[0].value - offset < axis.min) start = 1;
// let v = axis.min;
// result = [{value: v, major: false}];
// for (tick of ticks.slice(start)) {
// v = tick.value - offset;
// result.push({value: v, major: false});
// }
// v += step;
// if (v < axis.max) result.push({value:v, major: false});
// result.push({value: axis.max, major: false});
// return result;
// },
// gridLines:{drawTicks:false},
// }],
// },
// tooltips: false,
// legend: false,
// pan: {
// enabled: true,
// mode: 'xy',
// speed: 10,
// threshold: 10,
// onPan: function({chart}) { graphs.panCallback(chart.graph);},
// //onPanComplete: function({chart}){graphs.checkReload(chart.graph);redraw()},
// onPanComplete: function({chart}){graphs.updateAuto();},
// },
// zoom: {
// enabled: true,
// drag: false,
// mode: isTouchDevice ? 'xy': 'x',
// speed: 0.1,
// sensitivity: 1,
// onZoom: function({chart}) { graphs.zoomCallback(chart.graph);},
// //onZoomComplete: function({chart}){graphs.checkReload(chart.graph);redraw()},
// onZoomComplete: function({chart}){graphs.onZoomCompleteCallback()},
// }
// }
// });
//console.log('create legend')
let legend = document.createElement('div');
@ -1802,8 +1935,11 @@ function Graph(gindex, container, x_label, y_label, tag, scaleType = "linear"){
* @param {number} max - The maximum timestamp in milliseconds of the viewing window
*/
function setMinMax(min, max){
let ax = chart.options.scales.xAxes[0];
let ay = chart.options.scales.yAxes[0];
let ax = chart.options.scales.x;
ax = chart.scales.x
console.log(chart)
let ay = chart.options.scales.y;
ay = chart.scales.y
// clamp X-span
let span = max - min;
let half = 0;
@ -1844,8 +1980,11 @@ function Graph(gindex, container, x_label, y_label, tag, scaleType = "linear"){
}
mainstep *= info[1];
}
ax.time.unit = info[0];
ax.time.stepSize = Math.round(step / mainstep);
ax["time"] = {"unit":info[0]}
// ax["time"] = {"unit":info[0]}
// ax.time.unit = info[0];
ax.time["stepSize"] = Math.round(step / mainstep);
//ax.ticks.unit = ax.time.unit;
//ax.ticks.stepSize =ax.time.stepSize;
//console.log('INFO', step, mainstep, info, ax, ax.time);
@ -1873,7 +2012,7 @@ function Graph(gindex, container, x_label, y_label, tag, scaleType = "linear"){
* Called when log button in the legend is clicked
*/
function toggleAxesType(){
setAxesType((chart.options.scales.yAxes[0].type=== 'linear') ? 'logarithmic' : 'linear');
setAxesType((chart.options.scales.y.type=== 'linear') ? 'logarithmic' : 'linear');
}
/**
@ -1887,7 +2026,7 @@ function Graph(gindex, container, x_label, y_label, tag, scaleType = "linear"){
}else{
linlog.innerHTML = "<strong>&#9746;</strong> log";
}
chart.options.scales.yAxes[0].type = type;
chart.options.scales.y.type = type;
chart.options.animation.duration = 800;
if (autoScaleFlag) graphs.autoScale(chart);
update();
@ -1905,8 +2044,8 @@ function Graph(gindex, container, x_label, y_label, tag, scaleType = "linear"){
let y = null;
for(let j = 0; j < chart.getDatasetMeta(i).data.length; j++){
let dp = chart.getDatasetMeta(i).data[j];
if (dp._model.x >= x) break;
y = chart.data.datasets[i].data[dp._index].y;
if (dp.x >= x) break; //_model does not exist anymore, properties are defined directly on elements
y = chart.data.datasets[i].data[dp.$context.index].y; // $context not mentionned in ChartJS doc, seen with console.log
}
valueElm = legendvalues[chart.data.datasets[i].key];
if (labelMinWidth == 0) {

View File

@ -76,7 +76,7 @@ new Settings()
.treat("showConsole", "sc", to_bool, true)
.treat("showOverview", "so", to_bool, true)
.treat("showGraphics", "sg", to_bool, true) // false)
.treat("hideRightPart", "hr", to_bool, false) //used to completely disable the right part
.treat("hideRightPart", "hr", to_bool, true) //used to completely disable the right part
.treat("wideGraphs", "wg", to_bool, false) //used to toggle the size of the graphs part
.treat("showAsync", "sa", to_bool, false)

View File

@ -151,6 +151,9 @@ class InfluxGraph:
{"type":"accept-graph", "live": bool} : a dict with its "accept-graph" type and a "live" value telling if the server could change its visualization mode to live
"""
logging.info("UPD GRAPH %d", self.livemode)
# DISABLE LIVE UPDATE FOR THE MOMENT
self.livemode = self.HISTORICAL
return dict(type='accept-graph', live=False)
if self.livemode == self.HISTORICAL:
return dict(type='accept-graph', live=False)
else: