Live Chart woks
This commit is contained in:
@@ -0,0 +1,265 @@
|
||||
// Show the live data chart
|
||||
import {logit, logerror} from './logit.js'
|
||||
import * as utils from './chart_utilities.js'
|
||||
|
||||
// ******************************************************************
|
||||
// PlotDayLive_Noise
|
||||
// ******************************************************************
|
||||
|
||||
let noise_ymin = 30; // lowest value on y-axis for noise
|
||||
let noise_ymax = 120; // highest value on y-axis for noise
|
||||
let activeTab = 0; // active TAB number
|
||||
let peaklim = 70; // threshold for peak count
|
||||
|
||||
|
||||
export const showLive = (params) => {
|
||||
PlotDayLive_Noise(37833)
|
||||
}
|
||||
|
||||
export const PlotDayLive_Noise = async (sid) => {
|
||||
|
||||
let series1 = []
|
||||
let series2 = []
|
||||
let series3 = []
|
||||
|
||||
// ave the current (actual) values here
|
||||
let aktVal = {}
|
||||
|
||||
// read the data from the server
|
||||
const url = `http://localhost:3004/getsensordata?type=noise&sensorid=${sid}`
|
||||
let ret = await fetch(url)
|
||||
.catch(e => {
|
||||
logerror(e)
|
||||
});
|
||||
let sensors = await ret.json()
|
||||
let lastidx = sensors.count-1
|
||||
// Put values into the arrays
|
||||
let cnt = 0
|
||||
sensors.values.forEach((x) => {
|
||||
let dat = new Date(x.datetime).getTime()
|
||||
series1.push([dat, x.noise_LAeq])
|
||||
series2.push([dat, x.noise_LA_max])
|
||||
series3.push([dat, x.noise_LA_min]) // put data and value into series array
|
||||
})
|
||||
|
||||
if (sensors.values.length != 0) {
|
||||
// Aktuelle Werte speichern
|
||||
aktVal['LAeq'] = sensors.values[lastidx].noise_LAeq
|
||||
aktVal['LAMax'] = sensors.values[lastidx].noise_LA_max
|
||||
aktVal['LAMin'] = sensors.values[lastidx].noise_LA_min
|
||||
|
||||
// InfoTafel füllen
|
||||
let infoTafel =
|
||||
'<table class="infoTafel"><tr >' +
|
||||
'<th colspan="3">Aktuelle Werte</th>' +
|
||||
'</tr><tr>' +
|
||||
'<td>LAeq</td><td>' + (aktVal.LAeq).toFixed(1) + '</td><td>dbA</td>'
|
||||
infoTafel +=
|
||||
'</tr><tr>' +
|
||||
'<td>LAmin</td><td>' + (aktVal.LAMin).toFixed(0) + '</td><td>dbA</td>'
|
||||
infoTafel +=
|
||||
'</tr><tr>' +
|
||||
'<td>LAmax</td><td>' + (aktVal.LAMax).toFixed(0) + '</td><td>dbA</td>'
|
||||
infoTafel +=
|
||||
'</tr></table>' +
|
||||
'</div>'
|
||||
}
|
||||
let txtMeldung = false
|
||||
|
||||
|
||||
// Plot-Options
|
||||
let options = utils.createGlobObtions()
|
||||
|
||||
let series_LAeq = {
|
||||
name: 'LAeq',
|
||||
data: series1,
|
||||
color: utils.colors.eq,
|
||||
yAxis: 0,
|
||||
zIndex: 1,
|
||||
marker: {
|
||||
enabled: false,
|
||||
symbol: 'square',
|
||||
},
|
||||
visible: true,
|
||||
fillColor: {
|
||||
linearGradient: [0, 600, 0, 0],
|
||||
stops: [
|
||||
[0, 'rgb(238,223,236)'],
|
||||
[1, 'rgb(238,223,236)']
|
||||
]
|
||||
},
|
||||
}
|
||||
|
||||
let series_LAMax = {
|
||||
name: 'LAmax',
|
||||
data: series2,
|
||||
color: utils.colors.max,
|
||||
yAxis: 0,
|
||||
zIndex: 0,
|
||||
marker: {
|
||||
enabled: false,
|
||||
symbol: 'square',
|
||||
},
|
||||
visible: true,
|
||||
fillColor: {
|
||||
linearGradient: [0, 600, 0, 0],
|
||||
stops: [
|
||||
[0, 'rgb(255,233,236)'],
|
||||
[1, 'rgb(255,233,236)']
|
||||
]
|
||||
},
|
||||
// fillOpacity: 0.2,
|
||||
}
|
||||
|
||||
let series_LAMin = {
|
||||
name: 'LAmin',
|
||||
data: series3,
|
||||
color: utils.colors.min,
|
||||
yAxis: 0,
|
||||
zIndex: 6,
|
||||
marker: {
|
||||
enabled: false,
|
||||
symbol: 'square',
|
||||
},
|
||||
visible: true,
|
||||
fillColor: {
|
||||
linearGradient: [0, 600, 0, 0],
|
||||
stops: [
|
||||
[0, 'rgb(219,216,217)'],
|
||||
[1, 'rgb(219,216,217)']
|
||||
]
|
||||
},
|
||||
}
|
||||
|
||||
let yAxis_LAeq = { // 1
|
||||
title: {
|
||||
text: 'dbA',
|
||||
style: {
|
||||
color: 'black'
|
||||
}
|
||||
},
|
||||
max: noise_ymax,
|
||||
min: noise_ymin,
|
||||
// opposite: true,
|
||||
tickAmount: 10,
|
||||
useHTML: true,
|
||||
}
|
||||
|
||||
options.series = []
|
||||
options.yAxis = []
|
||||
options.series[0] = series_LAeq
|
||||
options.series[1] = series_LAMin
|
||||
options.title.text = 'Noise level for one day'
|
||||
options.subtitle.useHTML = true
|
||||
options.subtitle.text = '2.5min log. average values <br />  '
|
||||
options.series[2] = series_LAMax
|
||||
// options.yAxis[2] = yAxis_LAMin
|
||||
options.yAxis[0] = yAxis_LAeq
|
||||
// options.yAxis[1] = yAxis_LAMax
|
||||
options.chart.zoomType = 'x'
|
||||
options.chart.type = 'area'
|
||||
options.chart.resetZoomButton= {
|
||||
position: {
|
||||
align: 'left',
|
||||
verticalAlign: 'bottom',
|
||||
x: 20,
|
||||
y: -50,
|
||||
},
|
||||
relativeTo: 'chart'
|
||||
}
|
||||
|
||||
|
||||
let noDataTafel = '<div class="errTafel">' +
|
||||
'Für heute liegen leider keine Daten vor!<br /> Bitte den Sensor überprüfen!\' <br />' +
|
||||
'</div>'
|
||||
|
||||
|
||||
let navy = 20
|
||||
let navbreit = 55
|
||||
let navtxt = ['-24h', '-12h', 'live', '+12h', '+24h']
|
||||
let navtime = [-24, -12, 0, 12, 24]
|
||||
|
||||
let chr = Highcharts.chart('dlive', options, function (chart) {
|
||||
utils.addSensorID2chart(chart, sensors.props, document.getElementById('dlive').offsetWidth)
|
||||
// let breit = $(window).width()
|
||||
// let navx = breit-350
|
||||
// chart.renderer.label(
|
||||
// infoTafel,
|
||||
// breit - 250,
|
||||
// 78, 'rect', 0, 0, true)
|
||||
// .css({
|
||||
// fontSize: '10pt',
|
||||
// color: 'green'
|
||||
// })
|
||||
// .attr({
|
||||
// zIndex: 5,
|
||||
// }).add()
|
||||
// for (let i = 0; i < navtxt.length; i++) {
|
||||
// renderPfeil(i, chart, navx + (i * navbreit), navy, navtxt[i], navtime[i])
|
||||
// }
|
||||
if (txtMeldung == true) {
|
||||
let labeText = ''
|
||||
let errtext = chart.renderer.label(
|
||||
noDataTafel,
|
||||
250,
|
||||
120, 'rect', 0, 0, true)
|
||||
.css({
|
||||
fontSize: '18pt',
|
||||
color: 'red'
|
||||
})
|
||||
.attr({
|
||||
zIndex: 1000,
|
||||
stroke: 'black',
|
||||
'stroke-width': 2,
|
||||
fill: 'white',
|
||||
padding: 10,
|
||||
}).add()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
let butOpts = [
|
||||
{fill: 'lightblue', r: 2},
|
||||
{fill: 'blue', r: 2, style: {color: 'white'}},
|
||||
{fill: 'lightblue', r: 2},
|
||||
{fill: 'lightblue', r: 2}
|
||||
]
|
||||
|
||||
|
||||
function renderPfeil(n, chart, x, y, txt, time) {
|
||||
chart.renderer.button(txt, x, y, null, butOpts[0], butOpts[1], butOpts[2], butOpts[3])
|
||||
.attr({
|
||||
id: 'button' + n,
|
||||
zIndex: 3,
|
||||
width: 30,
|
||||
})
|
||||
.on('click', function () {
|
||||
prevHour(time)
|
||||
})
|
||||
.add()
|
||||
}
|
||||
|
||||
function prevHour(hours) {
|
||||
console.log("Zurück um ", hours, "Stunden")
|
||||
let start
|
||||
if (startDay == "") {
|
||||
start = moment()
|
||||
start.subtract(24, 'h')
|
||||
} else {
|
||||
start = moment(startDay)
|
||||
}
|
||||
let mrk = moment()
|
||||
mrk.subtract(24, 'h')
|
||||
let startDay = ""
|
||||
if (hours < 0) {
|
||||
start.subtract(Math.abs(hours), 'h')
|
||||
startDay = start.format("YYYY-MM-DDTHH:mm:ssZ")
|
||||
} else if (hours > 0) {
|
||||
start.add(hours, 'h')
|
||||
if (!start.isAfter(mrk)) {
|
||||
startDay = start.format("YYYY-MM-DDTHH:mm:ssZ")
|
||||
}
|
||||
}
|
||||
doPlot('live', startDay)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
// Utility routine for plotting the data
|
||||
|
||||
import {DateTime} from './luxon.min.js'
|
||||
export const colors = {'eq': '#0000FF', 'max': '#FF0000', 'min': '#008000', 'peaks': '#DAA520'};
|
||||
|
||||
// Defaults für die Mittelwertbildungen
|
||||
const refreshRate = 5; // Grafik so oft auffrischen (in Minuten)
|
||||
let txtMeldung = false; // falls keine Daten da sind, Text melden
|
||||
const avgTime = 30; // defaul average time für particulate matter
|
||||
let doUpdate = true; // update every 5 min
|
||||
let optSidsArray = []; // Arrray der letzten 5 Einträge
|
||||
let nbrofdaysforavg = 8; // Stundenmittel Anzahl Tagte (default = 5)
|
||||
let nbrofdaysfordaynight = 30; // use 30 days or day/night graphic
|
||||
let stucols = 1; // Anzeige nur Balken (StundenMittel)
|
||||
|
||||
|
||||
export function createGlobObtions() {
|
||||
var globObject = {};
|
||||
|
||||
// Options, die für alle Plots identisch sind
|
||||
globObject = {
|
||||
chart: {
|
||||
height: 600,
|
||||
// width: 1000;
|
||||
spacingRight: 20,
|
||||
spacingLeft: 20,
|
||||
spacingTop: 25,
|
||||
backgroundColor: {
|
||||
linearGradient: [0, 400, 0, 0],
|
||||
stops: [
|
||||
[0, '#eee'],//[0, '#ACD0AA'], //[0, '#A18D99'], // [0, '#886A8B'], // [0, '#F2D0B5'],
|
||||
[1, '#fff']
|
||||
]
|
||||
},
|
||||
type: 'line',
|
||||
borderWidth: '2',
|
||||
events: {
|
||||
selection: function (event) {
|
||||
if (event.xAxis) {
|
||||
doUpdate = false;
|
||||
} else {
|
||||
doUpdate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
title: {
|
||||
// text: 'Feinstaub über 1 Tag',
|
||||
align: 'left',
|
||||
style: {'fontSize': '25px'},
|
||||
useHTML: true,
|
||||
},
|
||||
subtitle: {
|
||||
text: 'Gemessene Werte und ' + avgTime + 'min-gleitende Mittelwerte',
|
||||
align: 'left',
|
||||
},
|
||||
tooltip: {
|
||||
valueDecimals: 1,
|
||||
backgroundColor: 0,
|
||||
borderWidth: 0,
|
||||
borderRadius: 0,
|
||||
useHTML: true,
|
||||
formatter: function () {
|
||||
return '<div style="border: 2px solid ' + this.point.color + '; padding: 3px;">' +
|
||||
DateTime.fromMillis(this.x, {zone: 'utc'}).toFormat('dd.LL HH:mm:ss') + '<br />' +
|
||||
'<span style="color: ' + this.point.color + '">● </span>' +
|
||||
this.series.name + ': <b>' +
|
||||
Highcharts.numberFormat(this.y, 1) +
|
||||
'</b></div>';
|
||||
}
|
||||
},
|
||||
xAxis: {
|
||||
type: 'datetime',
|
||||
title: {
|
||||
text: 'date/time',
|
||||
},
|
||||
gridLineWidth: 2,
|
||||
labels: {
|
||||
formatter: function () {
|
||||
let v = this.axis.defaultLabelFormatter.call(this);
|
||||
if (v.indexOf(':') == -1) {
|
||||
return '<span style="font-weight:bold;color:red">' + v + '<span>';
|
||||
} else {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
enabled: true,
|
||||
layout: 'horizontal',
|
||||
// verticalAlign: 'top',
|
||||
borderWidth: 1,
|
||||
align: 'center',
|
||||
},
|
||||
plotOptions: {
|
||||
series: {
|
||||
animation: false,
|
||||
turboThreshold: 0,
|
||||
marker: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
};
|
||||
return globObject;
|
||||
}
|
||||
|
||||
function calcWeekends(data, isyear) {
|
||||
var weekend = [];
|
||||
var oldDay = 8;
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var mom = moment(data[i].date);
|
||||
if (isyear) {
|
||||
mom = moment(data[i]._id)
|
||||
}
|
||||
var day = mom.day();
|
||||
var st = mom.startOf('day');
|
||||
if (day != oldDay) {
|
||||
if (day == 6) {
|
||||
weekend.push({
|
||||
color: 'rgba(169,235,158,0.4)',
|
||||
from: st.valueOf(),
|
||||
to: st.add(1, 'days').valueOf(),
|
||||
zIndex: 0
|
||||
})
|
||||
} else if (day == 0) {
|
||||
weekend.push({
|
||||
color: 'rgba(169,235,158,0.4)',
|
||||
from: st.valueOf(),
|
||||
to: st.add(1, 'days').valueOf(),
|
||||
zIndex: 0
|
||||
})
|
||||
}
|
||||
oldDay = day;
|
||||
}
|
||||
}
|
||||
return weekend;
|
||||
}
|
||||
|
||||
function calcDays(data, isyear) {
|
||||
var days = [];
|
||||
if (data.length == 0) {
|
||||
return days
|
||||
}
|
||||
var oldday = moment(data[0].date).day();
|
||||
if (isyear) {
|
||||
oldday = moment(data[0]._id).day();
|
||||
}
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var m = moment(data[i].date);
|
||||
if (isyear) {
|
||||
m = moment(data[i]._id);
|
||||
}
|
||||
var tag = m.day()
|
||||
if (tag != oldday) {
|
||||
m.startOf('day');
|
||||
days.push({color: 'lightgray', value: m.valueOf(), width: 1, zIndex: 2});
|
||||
oldday = tag;
|
||||
}
|
||||
}
|
||||
return days;
|
||||
};
|
||||
|
||||
function getIndoor(sensor) {
|
||||
let p = new Promise(function (resolve, reject) {
|
||||
let url = '/api/getdata?data=props&sensorid=' + sensor;
|
||||
$.get(url, (data, err) => {
|
||||
if (err != 'success') {
|
||||
resolve(false)
|
||||
} else {
|
||||
resolve(data.values[0].indoor == 1)
|
||||
}
|
||||
})
|
||||
})
|
||||
return p
|
||||
}
|
||||
|
||||
export async function addSensorID2chart(chart, props, width) {
|
||||
console.log('widht: ',width);
|
||||
let indoor = props.location[0].indoor
|
||||
console.log('indoor: ',indoor)
|
||||
let sens = chart.renderer.label(
|
||||
`Sensor: ${props._id} ${indoor ? ' (indoor)' : ''}`,
|
||||
width / 2 - 100, 65,
|
||||
'text', 0, 0, true)
|
||||
.css({
|
||||
fontSize: '12pt',
|
||||
'font-weight': 'bold',
|
||||
})
|
||||
.attr({
|
||||
zIndex: 5,
|
||||
}).add();
|
||||
}
|
||||
@@ -3,8 +3,11 @@
|
||||
|
||||
import * as map from './map.js'
|
||||
import * as dt from './datetime.js'
|
||||
import {logit} from './logit.js'
|
||||
import * as chart_live from './chart_live.js'
|
||||
|
||||
(async () => {
|
||||
|
||||
(async function () {
|
||||
// global constants
|
||||
const Stuttgart = [48.779, 9.16]
|
||||
const MAXROWS_IN_TABLE = 1000
|
||||
@@ -25,21 +28,49 @@ import * as dt from './datetime.js'
|
||||
}
|
||||
// END global variables
|
||||
|
||||
|
||||
const tabtable = [
|
||||
{id: 'kartentab', func: map.showMap},
|
||||
{id: 'livetab', func: chart_live.showLive},
|
||||
// {id: 'houravgtab', func: chart_houravg.showHouravg},
|
||||
// {id: 'dayavgtab', func: chart_dayavg.showDayavg},
|
||||
// {id: 'daynighttab', func: chart_daynight.showDaynight},
|
||||
// {id: 'ldentab', func: chart_lden.showLden},
|
||||
]
|
||||
|
||||
async function main() {
|
||||
// initialise tabs
|
||||
let triggerTabList = [].slice.call(document.querySelectorAll('#myTab a'))
|
||||
let triggerTabList = [].slice.call(document.querySelectorAll('.nav-link'))
|
||||
triggerTabList.forEach(function (triggerEl) {
|
||||
let tabTrigger = new bootstrap.Tab(triggerEl)
|
||||
|
||||
triggerEl.addEventListener('click', function (event) {
|
||||
event.preventDefault()
|
||||
tabTrigger.show()
|
||||
for(let x of tabtable) {
|
||||
if (x.id === event.currentTarget.id) {
|
||||
x.func(params)
|
||||
}
|
||||
}
|
||||
logit(`tab chaned to ${event.currentTarget.id}`)
|
||||
})
|
||||
})
|
||||
|
||||
// show dat/time at start
|
||||
// var triggerEl = document.querySelector('#tablist a[href="#profile"]')
|
||||
// bootstrap.Tab.getInstance(triggerEl).show() // Select tab by name
|
||||
//
|
||||
// var triggerFirstTabEl = document.querySelector('#tablist li:first-child a')
|
||||
// bootstrap.Tab.getInstance(triggerFirstTabEl).show() // Select first tab
|
||||
|
||||
|
||||
// let nl = document.querySelectorAll('.nav-link')
|
||||
// for (let x of nl) {
|
||||
// x.addEventListener('click', (event) => {
|
||||
// event.preventDefault()
|
||||
// console.log(event)
|
||||
// })
|
||||
// }
|
||||
|
||||
|
||||
dt.showDate(true)
|
||||
// and show date/time every minute
|
||||
setInterval(() => dt.showDate(false), 1000)
|
||||
@@ -49,7 +80,6 @@ import * as dt from './datetime.js'
|
||||
|
||||
// show the map
|
||||
map.showMap(params)
|
||||
await map.buildMarkers()
|
||||
}
|
||||
main().catch(console.error)
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import { DateTime } from './luxon.min.js'
|
||||
|
||||
export function logit(str) {
|
||||
let s = `${DateTime.now().toISO()} => ${str}`;
|
||||
console.log(s);
|
||||
}
|
||||
|
||||
export function logerror(str) {
|
||||
let s = `${DateTime.utc().toISO()} => *** ERROR *** ${str}`;
|
||||
console.log(s);
|
||||
}
|
||||
|
||||
+44
-32
@@ -9,7 +9,7 @@ let popuptext = ''
|
||||
const colorscale = ['#d53e4f', '#fc8d59', '#fee08b', '#e6f598', '#99d594', '#3288bd', '#808080'];
|
||||
const dba = [100, 80, 60, 40, 20, 0, -999];
|
||||
|
||||
export const showMap = (params) => {
|
||||
export const showMap = async (params) => {
|
||||
map = L.map('map',{ scrollWheelZoom: false}).setView(params.center, parseInt(params.zoom))
|
||||
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
maxZoom: 19,
|
||||
@@ -37,7 +37,8 @@ export const showMap = (params) => {
|
||||
return div
|
||||
};
|
||||
legend.addTo(map)
|
||||
|
||||
let lastdate = await buildMarkers()
|
||||
showLastDate(lastdate);
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +59,7 @@ function calcPolygon(bounds) {
|
||||
});
|
||||
;
|
||||
}
|
||||
|
||||
/*
|
||||
async function plotMap(cid, poly) {
|
||||
// if sensor nbr is give, find coordinates, else use Stuttgart center
|
||||
debug_log('plotMap()');
|
||||
@@ -132,7 +133,7 @@ async function plotMap(cid, poly) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
// With all Markers in cluster (markers) calculate the median
|
||||
// of the values. With this median fetch the color and return it.
|
||||
@@ -151,7 +152,7 @@ function getMedian(markers) {
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
console.log(markers);
|
||||
// console.log(markers);
|
||||
let i = 0; // now find the 'offlines' (value == -1)
|
||||
for (i = 0; i < markers.length; i++) {
|
||||
if (markers[i].options.value > 0) {
|
||||
@@ -165,7 +166,7 @@ function getMedian(markers) {
|
||||
return getColor(markers[(Math.floor(lang / 2))].options.value); // median is in the middle
|
||||
} else { // evaen ->
|
||||
lang = lang / 2; // median is mean of both middle values
|
||||
console.log(lang);
|
||||
// console.log(lang);
|
||||
let wert = (markers[lang - 1].options.value +
|
||||
markers[lang].options.value) / 2;
|
||||
return getColor(wert);
|
||||
@@ -250,8 +251,7 @@ export async function buildMarkers() {
|
||||
markers.addLayer(marker);
|
||||
}
|
||||
map.addLayer(markers);
|
||||
// ToDo showLastDate(sensors.lastDate);
|
||||
|
||||
return sensors.lastdate
|
||||
}
|
||||
|
||||
async function onMarkerClick(e, click) {
|
||||
@@ -299,36 +299,48 @@ async function setCenter(adr) {
|
||||
console.log(data);
|
||||
}
|
||||
|
||||
/*
|
||||
// Show the last date below tha map grafics
|
||||
async function showLastDate(dt) {
|
||||
const url = `http://localhost:3004/getproperties?type=noise&box=${bounds.toBBoxString()}`
|
||||
|
||||
// Show the last date below tha map grafics
|
||||
async function showLastDate(ld) {
|
||||
// const url = `http://localhost:3004/getproperties?type=noise&box=${bounds.toBBoxString()}`
|
||||
//
|
||||
// let ret = await fetch(url)
|
||||
// .catch(e => {
|
||||
// console.log(e)
|
||||
// });
|
||||
// let sensors = await ret.json()
|
||||
//
|
||||
// let url = '/api/getdata';
|
||||
// let ld = moment(dt);
|
||||
// let last = ld.subtract(1,'h')
|
||||
// let erg;
|
||||
// let allsens
|
||||
// try {
|
||||
// erg = await $.getJSON(url + `?data=props&last=1900-01-01`);
|
||||
// allsens = erg.count
|
||||
// erg = await $.getJSON(url + `?data=props&last=${last.format('YYYY-MM-DD HH:mm')}`);
|
||||
// if ((erg != undefined) && (erg.values[0].error != undefined)) {
|
||||
// showError(3,erg.values[0].error,aktsensorid);
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// catch(e) {
|
||||
// console.log(e)
|
||||
// }
|
||||
// fetch all sensors
|
||||
const url = `http://localhost:3004/getmapdata?type=noise`
|
||||
let ret = await fetch(url)
|
||||
.catch(e => {
|
||||
console.log(e)
|
||||
});
|
||||
let sensors = await ret.json()
|
||||
|
||||
let url = '/api/getdata';
|
||||
let ld = moment(dt);
|
||||
let last = ld.subtract(1,'h')
|
||||
let erg;
|
||||
let allsens
|
||||
try {
|
||||
erg = await $.getJSON(url + `?data=props&last=1900-01-01`);
|
||||
allsens = erg.count
|
||||
erg = await $.getJSON(url + `?data=props&last=${last.format('YYYY-MM-DD HH:mm')}`);
|
||||
if ((erg != undefined) && (erg.values[0].error != undefined)) {
|
||||
showError(3,erg.values[0].error,aktsensorid);
|
||||
return;
|
||||
let actsensors = 0
|
||||
for (let x of sensors.values) {
|
||||
if (x.value >= 0) {
|
||||
actsensors++
|
||||
}
|
||||
}
|
||||
catch(e) {
|
||||
console.log(e)
|
||||
}
|
||||
$('#mapdate').html('Werte von ' + ld.format('YYYY-MM-DD HH:mm'));
|
||||
$('#actsensors').html(`${erg.count} aktive Sensoren (angemeldet ${allsens})`)
|
||||
document.querySelector('#mapdate').innerText = 'Values from ' + dt.formatISODate(ld).slice(0,-3)
|
||||
document.querySelector('#actsensors').innerText = `Active sensors: ${actsensors} (registered: ${sensors.count})`
|
||||
// $('#actsensors').html(`${erg.count} aktive Sensoren (angemeldet ${allsens})`)
|
||||
}
|
||||
|
||||
*/
|
||||
@@ -5,7 +5,6 @@ body {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
height: 100%;
|
||||
background-color: rgb(146, 154, 146);
|
||||
}
|
||||
|
||||
html {
|
||||
@@ -16,7 +15,6 @@ html {
|
||||
margin: auto;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
background-color: #e9e9e9;
|
||||
margin-top: 5px;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
@@ -27,13 +25,13 @@ a {
|
||||
}
|
||||
|
||||
header {
|
||||
width: 98%;
|
||||
margin: auto;
|
||||
background-color: lightgray;
|
||||
}
|
||||
header #hline1 {
|
||||
width: 98%;
|
||||
margin: 0px auto 0px;
|
||||
margin: 0px 1vw 0px 1vw;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
overflow: auto;
|
||||
}
|
||||
header #h1name {
|
||||
font-size: 148%;
|
||||
@@ -47,9 +45,10 @@ header #h1datum {
|
||||
}
|
||||
|
||||
#fenster {
|
||||
margin-top: 45px;
|
||||
background: lightgray;
|
||||
margin-left: 0.5vw;
|
||||
background: white;
|
||||
padding-top: 5px;
|
||||
width: 99vw;
|
||||
}
|
||||
#fenster #navi {
|
||||
float: left;
|
||||
@@ -64,10 +63,9 @@ header #h1datum {
|
||||
}
|
||||
|
||||
#map {
|
||||
margin-left: 1vw;
|
||||
margin-top: 5px;
|
||||
margin-left: 0.5vw;
|
||||
width: 98vw;
|
||||
height: 66vh;
|
||||
height: 80vh;
|
||||
border-radius: 10px;
|
||||
border: solid 1px seagreen;
|
||||
overflow: hidden;
|
||||
@@ -83,17 +81,36 @@ header #h1datum {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#author {
|
||||
#mapdateactsens {
|
||||
width: 98vw;
|
||||
font-size: 70%;
|
||||
padding: 10px 0 10px 0;
|
||||
overflow: auto;
|
||||
}
|
||||
#mapdateactsens #mapdate, #mapdateactsens #actsensors {
|
||||
width: 33%;
|
||||
float: left;
|
||||
}
|
||||
#mapdateactsens #actsensors {
|
||||
text-align: left;
|
||||
margin-left: 1vw;
|
||||
}
|
||||
|
||||
footer {
|
||||
background-color: lightgray;
|
||||
}
|
||||
footer #author {
|
||||
font-size: 80%;
|
||||
width: 95%;
|
||||
width: 98vw;
|
||||
margin: auto;
|
||||
padding-bottom: 30px;
|
||||
padding-top: 10px;
|
||||
height: 50px;
|
||||
}
|
||||
#author #mailadr {
|
||||
footer #author #mailadr {
|
||||
float: left;
|
||||
}
|
||||
#author #versn {
|
||||
footer #author #versn {
|
||||
float: right;
|
||||
}
|
||||
|
||||
@@ -133,4 +150,14 @@ header #h1datum {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.tab-pane {
|
||||
margin-top: 44px;
|
||||
}
|
||||
|
||||
#dlive, #dhour, #dday, #ddaynight, #dlden {
|
||||
width: 98vw;
|
||||
height: 100%;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=style.css.map */
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"sourceRoot":"","sources":["style.sass"],"names":[],"mappings":"AAUA;EACE;EACA;EACA;EACA;EACA;EACA;EACA,kBAfW;;;AAiBb;EACE;;;AAEF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;;AAEA;EACE;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;;AAEF;EACE;EACA;;;AAEJ;EACE;EACA;EACA;;AAEA;EACE;EACA;;AAEF;EACE;EACA;;AACA;EACE;;;AAEN;EACE;EACA;EACA;EACA;EACA,eAzEc;EA0Ed;EACA;EACA;;AAEA;EACE;EACA;EACA;;AACF;EACE;EACA;;;AAGJ;EACE;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;EACE;;;AAGJ;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA","file":"style.css"}
|
||||
{"version":3,"sourceRoot":"","sources":["style.sass"],"names":[],"mappings":"AAWA;EACE;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;;;AAEF;EACE;EACA;EACA;EAEA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE,kBA7BoB;;AA+BpB;EACE;EACA;EACA;EACA;;AAEF;EACE;EACA;EACA;EACA;;AAEF;EACE;EACA;;;AAEJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAEF;EACE;EACA;;AACA;EACE;;;AAEN;EACE;EAEA;EACA;EACA,eA3Ec;EA4Ed;EACA;EACA;;AAEA;EACE;EACA;EACA;;AACF;EACE;EACA;;;AAEJ;EACE;EACA;EACA;EACA;;AAEA;EACE;EACA;;AACF;EACE;EACA;;;AAEJ;EACE,kBA/FoB;;AAiGpB;EACE;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;AAEF;EACE;;;AAGN;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;EACA;;;AAEF;EACE;EACA;EACA;;;AAEF;EACE;EACA;EACA;EACA;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;;;AAEF;EACE;;;AAEF;EACE;EACA;EACA","file":"style.css"}
|
||||
@@ -5,6 +5,7 @@ $divcolor: rgb(162, 227, 162)
|
||||
$table-stripes: rgb(157, 179, 157)
|
||||
$fieldset-color: rgb(208, 235, 208)
|
||||
$button-color: darkslategrey
|
||||
$header_footer_color: lightgray
|
||||
$checkboxsize: 1.5
|
||||
$inboxwidth: 70px
|
||||
|
||||
@@ -15,7 +16,7 @@ body
|
||||
margin-left: auto
|
||||
margin-right: auto
|
||||
height: 100%
|
||||
background-color: $background
|
||||
// background-color: $background
|
||||
|
||||
html
|
||||
height: 100%
|
||||
@@ -24,7 +25,7 @@ html
|
||||
margin: auto
|
||||
width: 100%
|
||||
text-align: center
|
||||
background-color: #e9e9e9
|
||||
// background-color: #e9e9e9
|
||||
margin-top: 5px
|
||||
height: 100%
|
||||
position: relative
|
||||
@@ -33,13 +34,13 @@ a
|
||||
color: #0000EE
|
||||
|
||||
header
|
||||
width: 98%
|
||||
margin: auto
|
||||
background-color: $header_footer_color
|
||||
|
||||
#hline1
|
||||
width: 98%
|
||||
margin: 0px auto 0px
|
||||
margin: 0px 1vw 0px 1vw
|
||||
padding-top: 10px
|
||||
padding-bottom: 10px
|
||||
overflow: auto
|
||||
|
||||
#h1name
|
||||
font-size: 148%
|
||||
@@ -52,9 +53,10 @@ header
|
||||
margin-top: 5px
|
||||
|
||||
#fenster
|
||||
margin-top: 45px
|
||||
background: lightgray
|
||||
margin-left: 0.5vw
|
||||
background: white
|
||||
padding-top: 5px
|
||||
width: 99vw
|
||||
|
||||
#navi
|
||||
float: left
|
||||
@@ -67,10 +69,10 @@ header
|
||||
margin-right: 20px
|
||||
|
||||
#map
|
||||
margin-left: 1vw
|
||||
margin-top: 5px
|
||||
margin-left: 0.5vw
|
||||
// margin-top: 15px
|
||||
width: 98vw
|
||||
height: 66vh
|
||||
height: 80vh
|
||||
border-radius: $corner-radius
|
||||
border: solid 1px $border-color
|
||||
overflow: hidden
|
||||
@@ -84,19 +86,35 @@ header
|
||||
margin-top: 10px
|
||||
text-align: center
|
||||
|
||||
#mapdateactsens
|
||||
width: 98vw
|
||||
font-size: 70%
|
||||
padding: 10px 0 10px 0
|
||||
overflow: auto
|
||||
|
||||
#author
|
||||
font-size: 80%
|
||||
width: 95%
|
||||
margin: auto
|
||||
padding-bottom: 30px
|
||||
padding-top: 10px
|
||||
|
||||
#mailadr
|
||||
#mapdate, #actsensors
|
||||
width: 33%
|
||||
float: left
|
||||
#actsensors
|
||||
text-align: left
|
||||
margin-left: 1vw
|
||||
|
||||
#versn
|
||||
float: right
|
||||
footer
|
||||
background-color: $header_footer_color
|
||||
|
||||
#author
|
||||
font-size: 80%
|
||||
width: 98vw
|
||||
margin: auto
|
||||
padding-bottom: 30px
|
||||
padding-top: 10px
|
||||
height: 50px
|
||||
|
||||
#mailadr
|
||||
float: left
|
||||
|
||||
#versn
|
||||
float: right
|
||||
|
||||
|
||||
.info
|
||||
@@ -129,3 +147,10 @@ header
|
||||
position: absolute
|
||||
font-size: 24px
|
||||
|
||||
.tab-pane
|
||||
margin-top: 44px
|
||||
|
||||
#dlive, #dhour, #dday, #ddaynight, #dlden
|
||||
width: 98vw
|
||||
height: 100%
|
||||
margin: auto
|
||||
|
||||
+18
-15
@@ -12,15 +12,15 @@ block content
|
||||
li.nav-item(role='presentation')
|
||||
button.nav-link.active#kartentab(data-bs-toggle="tab" data-bs-target="#t_map" type="button" role="tab" aria-controls="map" aria-selected="true") Map
|
||||
li.nav-item(role='presentation')
|
||||
button.nav-link.active#livetab(data-bs-toggle="tab" data-bs-target="#t_live" type="button" role="tab" aria-controls="live" aria-selected="true") Live
|
||||
button.nav-link#livetab(data-bs-toggle="tab" data-bs-target="#t_live" type="button" role="tab" aria-controls="live" aria-selected="true") Live
|
||||
li.nav-item(role='presentation')
|
||||
button.nav-link.active#houravgtab(data-bs-toggle="tab" data-bs-target="#t_houravg" type="button" role="tab" aria-controls="houravg" aria-selected="true") Hour_AVG
|
||||
button.nav-link#houravgtab(data-bs-toggle="tab" data-bs-target="#t_houravg" type="button" role="tab" aria-controls="houravg" aria-selected="true") Hour_AVG
|
||||
li.nav-item(role='presentation')
|
||||
button.nav-link.active#dayavgtab(data-bs-toggle="tab" data-bs-target="#t_dayavg" type="button" role="tab" aria-controls="dayavg" aria-selected="true") Day_AVG
|
||||
button.nav-link#dayavgtab(data-bs-toggle="tab" data-bs-target="#t_dayavg" type="button" role="tab" aria-controls="dayavg" aria-selected="true") Day_AVG
|
||||
li.nav-item(role='presentation')
|
||||
button.nav-link.active#daynightab(data-bs-toggle="tab" data-bs-target="#t_daynight" type="button" role="tab" aria-controls="daynight" aria-selected="true") Day_Night
|
||||
button.nav-link#daynightab(data-bs-toggle="tab" data-bs-target="#t_daynight" type="button" role="tab" aria-controls="daynight" aria-selected="true") Day_Night
|
||||
li.nav-item(role='presentation')
|
||||
button.nav-link.active#ldenab(data-bs-toggle="tab" data-bs-target="#t_lden" type="button" role="tab" aria-controls="lden" aria-selected="true") L<sub>DEN</sub>-Index
|
||||
button.nav-link#ldenab(data-bs-toggle="tab" data-bs-target="#t_lden" type="button" role="tab" aria-controls="lden" aria-selected="true") L<sub>DEN</sub>-Index
|
||||
#buttonsRight
|
||||
button.btn.btn-primary#btnSet(value='set') Settings
|
||||
button.btn.btn-primary#btnHelp(value='help') Info
|
||||
@@ -28,13 +28,16 @@ block content
|
||||
.tab-content#thetabs
|
||||
.tab-pane.fade.show.active#t_map(role="tabpanel" aria-labelledby="map-tab")
|
||||
#map MapTAB
|
||||
.tab-pane.fade.show.active#t_live(role="tabpanel" aria-labelledby="map-tab")
|
||||
#placeholderNOI1 LiveTAB
|
||||
.tab-pane.fade.show.active#t_houravg(role="tabpanel" aria-labelledby="map-tab")
|
||||
#placeholderNOI2 HourTAB
|
||||
.tab-pane.fade.show.active#t_dayavg(role="tabpanel" aria-labelledby="map-tab")
|
||||
#placeholderNOI3 DayTAB
|
||||
.tab-pane.fade.show.active#t_daynight(role="tabpanel" aria-labelledby="map-tab")
|
||||
#placeholderNOI4 DayNightTAB
|
||||
.tab-pane.fade.show.active#t_lden(role="tabpanel" aria-labelledby="map-tab")
|
||||
#placeholderNOI5 LdenTAB
|
||||
#mapdateactsens
|
||||
#actsensors
|
||||
#mapdate
|
||||
.tab-pane.fade#t_live(role="tabpanel" aria-labelledby="live-tab")
|
||||
#dlive LiveTAB
|
||||
.tab-pane.fade#t_houravg(role="tabpanel" aria-labelledby="map-tab")
|
||||
#dhour HourTAB
|
||||
.tab-pane.fade#t_dayavg(role="tabpanel" aria-labelledby="map-tab")
|
||||
#dday DayTAB
|
||||
.tab-pane.fade#t_daynight(role="tabpanel" aria-labelledby="map-tab")
|
||||
#ddaynight DayNightTAB
|
||||
.tab-pane.fade#t_lden(role="tabpanel" aria-labelledby="map-tab")
|
||||
#dlden LdenTAB
|
||||
|
||||
+6
-4
@@ -32,10 +32,11 @@ html
|
||||
body
|
||||
#wrapper
|
||||
block content
|
||||
#author
|
||||
#mailadr
|
||||
a(href="mailto:rexfue@gmail.com") mailto:rexfue@gmail.com
|
||||
#versn
|
||||
footer
|
||||
#author
|
||||
#mailadr
|
||||
a(href="mailto:rexfue@gmail.com") mailto:rexfue@gmail.com
|
||||
#versn
|
||||
script(src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"
|
||||
integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4"
|
||||
crossorigin="anonymous")
|
||||
@@ -43,4 +44,5 @@ html
|
||||
integrity="sha256-WBkoXOwTeyKclOHuWtc+i2uENFpDZ9YPdf5Hf+D7ewM="
|
||||
crossorigin="")
|
||||
script(src="/javascripts/leaflet.markercluster.js")
|
||||
script(src="https://code.highcharts.com/highcharts.js")
|
||||
script(type="module" src="/javascripts/global.js")
|
||||
Reference in New Issue
Block a user