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 map from './map.js'
|
||||||
import * as dt from './datetime.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
|
// global constants
|
||||||
const Stuttgart = [48.779, 9.16]
|
const Stuttgart = [48.779, 9.16]
|
||||||
const MAXROWS_IN_TABLE = 1000
|
const MAXROWS_IN_TABLE = 1000
|
||||||
@@ -25,21 +28,49 @@ import * as dt from './datetime.js'
|
|||||||
}
|
}
|
||||||
// END global variables
|
// 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() {
|
async function main() {
|
||||||
// initialise tabs
|
// initialise tabs
|
||||||
let triggerTabList = [].slice.call(document.querySelectorAll('#myTab a'))
|
let triggerTabList = [].slice.call(document.querySelectorAll('.nav-link'))
|
||||||
triggerTabList.forEach(function (triggerEl) {
|
triggerTabList.forEach(function (triggerEl) {
|
||||||
let tabTrigger = new bootstrap.Tab(triggerEl)
|
let tabTrigger = new bootstrap.Tab(triggerEl)
|
||||||
|
|
||||||
triggerEl.addEventListener('click', function (event) {
|
triggerEl.addEventListener('click', function (event) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
tabTrigger.show()
|
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)
|
dt.showDate(true)
|
||||||
// and show date/time every minute
|
// and show date/time every minute
|
||||||
setInterval(() => dt.showDate(false), 1000)
|
setInterval(() => dt.showDate(false), 1000)
|
||||||
@@ -49,7 +80,6 @@ import * as dt from './datetime.js'
|
|||||||
|
|
||||||
// show the map
|
// show the map
|
||||||
map.showMap(params)
|
map.showMap(params)
|
||||||
await map.buildMarkers()
|
|
||||||
}
|
}
|
||||||
main().catch(console.error)
|
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 colorscale = ['#d53e4f', '#fc8d59', '#fee08b', '#e6f598', '#99d594', '#3288bd', '#808080'];
|
||||||
const dba = [100, 80, 60, 40, 20, 0, -999];
|
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))
|
map = L.map('map',{ scrollWheelZoom: false}).setView(params.center, parseInt(params.zoom))
|
||||||
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||||
maxZoom: 19,
|
maxZoom: 19,
|
||||||
@@ -37,7 +37,8 @@ export const showMap = (params) => {
|
|||||||
return div
|
return div
|
||||||
};
|
};
|
||||||
legend.addTo(map)
|
legend.addTo(map)
|
||||||
|
let lastdate = await buildMarkers()
|
||||||
|
showLastDate(lastdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -58,7 +59,7 @@ function calcPolygon(bounds) {
|
|||||||
});
|
});
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
async function plotMap(cid, poly) {
|
async function plotMap(cid, poly) {
|
||||||
// if sensor nbr is give, find coordinates, else use Stuttgart center
|
// if sensor nbr is give, find coordinates, else use Stuttgart center
|
||||||
debug_log('plotMap()');
|
debug_log('plotMap()');
|
||||||
@@ -132,7 +133,7 @@ async function plotMap(cid, poly) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// With all Markers in cluster (markers) calculate the median
|
// With all Markers in cluster (markers) calculate the median
|
||||||
// of the values. With this median fetch the color and return it.
|
// of the values. With this median fetch the color and return it.
|
||||||
@@ -151,7 +152,7 @@ function getMedian(markers) {
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
console.log(markers);
|
// console.log(markers);
|
||||||
let i = 0; // now find the 'offlines' (value == -1)
|
let i = 0; // now find the 'offlines' (value == -1)
|
||||||
for (i = 0; i < markers.length; i++) {
|
for (i = 0; i < markers.length; i++) {
|
||||||
if (markers[i].options.value > 0) {
|
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
|
return getColor(markers[(Math.floor(lang / 2))].options.value); // median is in the middle
|
||||||
} else { // evaen ->
|
} else { // evaen ->
|
||||||
lang = lang / 2; // median is mean of both middle values
|
lang = lang / 2; // median is mean of both middle values
|
||||||
console.log(lang);
|
// console.log(lang);
|
||||||
let wert = (markers[lang - 1].options.value +
|
let wert = (markers[lang - 1].options.value +
|
||||||
markers[lang].options.value) / 2;
|
markers[lang].options.value) / 2;
|
||||||
return getColor(wert);
|
return getColor(wert);
|
||||||
@@ -250,8 +251,7 @@ export async function buildMarkers() {
|
|||||||
markers.addLayer(marker);
|
markers.addLayer(marker);
|
||||||
}
|
}
|
||||||
map.addLayer(markers);
|
map.addLayer(markers);
|
||||||
// ToDo showLastDate(sensors.lastDate);
|
return sensors.lastdate
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onMarkerClick(e, click) {
|
async function onMarkerClick(e, click) {
|
||||||
@@ -299,36 +299,48 @@ async function setCenter(adr) {
|
|||||||
console.log(data);
|
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)
|
let ret = await fetch(url)
|
||||||
.catch(e => {
|
.catch(e => {
|
||||||
console.log(e)
|
console.log(e)
|
||||||
});
|
});
|
||||||
let sensors = await ret.json()
|
let sensors = await ret.json()
|
||||||
|
let actsensors = 0
|
||||||
let url = '/api/getdata';
|
for (let x of sensors.values) {
|
||||||
let ld = moment(dt);
|
if (x.value >= 0) {
|
||||||
let last = ld.subtract(1,'h')
|
actsensors++
|
||||||
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) {
|
document.querySelector('#mapdate').innerText = 'Values from ' + dt.formatISODate(ld).slice(0,-3)
|
||||||
console.log(e)
|
document.querySelector('#actsensors').innerText = `Active sensors: ${actsensors} (registered: ${sensors.count})`
|
||||||
}
|
// $('#actsensors').html(`${erg.count} aktive Sensoren (angemeldet ${allsens})`)
|
||||||
$('#mapdate').html('Werte von ' + ld.format('YYYY-MM-DD HH:mm'));
|
|
||||||
$('#actsensors').html(`${erg.count} aktive Sensoren (angemeldet ${allsens})`)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*/
|
|
||||||
@@ -5,7 +5,6 @@ body {
|
|||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: rgb(146, 154, 146);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
@@ -16,7 +15,6 @@ html {
|
|||||||
margin: auto;
|
margin: auto;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background-color: #e9e9e9;
|
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -27,13 +25,13 @@ a {
|
|||||||
}
|
}
|
||||||
|
|
||||||
header {
|
header {
|
||||||
width: 98%;
|
background-color: lightgray;
|
||||||
margin: auto;
|
|
||||||
}
|
}
|
||||||
header #hline1 {
|
header #hline1 {
|
||||||
width: 98%;
|
margin: 0px 1vw 0px 1vw;
|
||||||
margin: 0px auto 0px;
|
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
overflow: auto;
|
||||||
}
|
}
|
||||||
header #h1name {
|
header #h1name {
|
||||||
font-size: 148%;
|
font-size: 148%;
|
||||||
@@ -47,9 +45,10 @@ header #h1datum {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#fenster {
|
#fenster {
|
||||||
margin-top: 45px;
|
margin-left: 0.5vw;
|
||||||
background: lightgray;
|
background: white;
|
||||||
padding-top: 5px;
|
padding-top: 5px;
|
||||||
|
width: 99vw;
|
||||||
}
|
}
|
||||||
#fenster #navi {
|
#fenster #navi {
|
||||||
float: left;
|
float: left;
|
||||||
@@ -64,10 +63,9 @@ header #h1datum {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#map {
|
#map {
|
||||||
margin-left: 1vw;
|
margin-left: 0.5vw;
|
||||||
margin-top: 5px;
|
|
||||||
width: 98vw;
|
width: 98vw;
|
||||||
height: 66vh;
|
height: 80vh;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
border: solid 1px seagreen;
|
border: solid 1px seagreen;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -83,17 +81,36 @@ header #h1datum {
|
|||||||
text-align: center;
|
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%;
|
font-size: 80%;
|
||||||
width: 95%;
|
width: 98vw;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
padding-bottom: 30px;
|
padding-bottom: 30px;
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
|
height: 50px;
|
||||||
}
|
}
|
||||||
#author #mailadr {
|
footer #author #mailadr {
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
#author #versn {
|
footer #author #versn {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,4 +150,14 @@ header #h1datum {
|
|||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tab-pane {
|
||||||
|
margin-top: 44px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#dlive, #dhour, #dday, #ddaynight, #dlden {
|
||||||
|
width: 98vw;
|
||||||
|
height: 100%;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
/*# sourceMappingURL=style.css.map */
|
/*# 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)
|
$table-stripes: rgb(157, 179, 157)
|
||||||
$fieldset-color: rgb(208, 235, 208)
|
$fieldset-color: rgb(208, 235, 208)
|
||||||
$button-color: darkslategrey
|
$button-color: darkslategrey
|
||||||
|
$header_footer_color: lightgray
|
||||||
$checkboxsize: 1.5
|
$checkboxsize: 1.5
|
||||||
$inboxwidth: 70px
|
$inboxwidth: 70px
|
||||||
|
|
||||||
@@ -15,7 +16,7 @@ body
|
|||||||
margin-left: auto
|
margin-left: auto
|
||||||
margin-right: auto
|
margin-right: auto
|
||||||
height: 100%
|
height: 100%
|
||||||
background-color: $background
|
// background-color: $background
|
||||||
|
|
||||||
html
|
html
|
||||||
height: 100%
|
height: 100%
|
||||||
@@ -24,7 +25,7 @@ html
|
|||||||
margin: auto
|
margin: auto
|
||||||
width: 100%
|
width: 100%
|
||||||
text-align: center
|
text-align: center
|
||||||
background-color: #e9e9e9
|
// background-color: #e9e9e9
|
||||||
margin-top: 5px
|
margin-top: 5px
|
||||||
height: 100%
|
height: 100%
|
||||||
position: relative
|
position: relative
|
||||||
@@ -33,13 +34,13 @@ a
|
|||||||
color: #0000EE
|
color: #0000EE
|
||||||
|
|
||||||
header
|
header
|
||||||
width: 98%
|
background-color: $header_footer_color
|
||||||
margin: auto
|
|
||||||
|
|
||||||
#hline1
|
#hline1
|
||||||
width: 98%
|
margin: 0px 1vw 0px 1vw
|
||||||
margin: 0px auto 0px
|
|
||||||
padding-top: 10px
|
padding-top: 10px
|
||||||
|
padding-bottom: 10px
|
||||||
|
overflow: auto
|
||||||
|
|
||||||
#h1name
|
#h1name
|
||||||
font-size: 148%
|
font-size: 148%
|
||||||
@@ -52,9 +53,10 @@ header
|
|||||||
margin-top: 5px
|
margin-top: 5px
|
||||||
|
|
||||||
#fenster
|
#fenster
|
||||||
margin-top: 45px
|
margin-left: 0.5vw
|
||||||
background: lightgray
|
background: white
|
||||||
padding-top: 5px
|
padding-top: 5px
|
||||||
|
width: 99vw
|
||||||
|
|
||||||
#navi
|
#navi
|
||||||
float: left
|
float: left
|
||||||
@@ -67,10 +69,10 @@ header
|
|||||||
margin-right: 20px
|
margin-right: 20px
|
||||||
|
|
||||||
#map
|
#map
|
||||||
margin-left: 1vw
|
margin-left: 0.5vw
|
||||||
margin-top: 5px
|
// margin-top: 15px
|
||||||
width: 98vw
|
width: 98vw
|
||||||
height: 66vh
|
height: 80vh
|
||||||
border-radius: $corner-radius
|
border-radius: $corner-radius
|
||||||
border: solid 1px $border-color
|
border: solid 1px $border-color
|
||||||
overflow: hidden
|
overflow: hidden
|
||||||
@@ -84,13 +86,29 @@ header
|
|||||||
margin-top: 10px
|
margin-top: 10px
|
||||||
text-align: center
|
text-align: center
|
||||||
|
|
||||||
|
#mapdateactsens
|
||||||
|
width: 98vw
|
||||||
|
font-size: 70%
|
||||||
|
padding: 10px 0 10px 0
|
||||||
|
overflow: auto
|
||||||
|
|
||||||
#author
|
#mapdate, #actsensors
|
||||||
|
width: 33%
|
||||||
|
float: left
|
||||||
|
#actsensors
|
||||||
|
text-align: left
|
||||||
|
margin-left: 1vw
|
||||||
|
|
||||||
|
footer
|
||||||
|
background-color: $header_footer_color
|
||||||
|
|
||||||
|
#author
|
||||||
font-size: 80%
|
font-size: 80%
|
||||||
width: 95%
|
width: 98vw
|
||||||
margin: auto
|
margin: auto
|
||||||
padding-bottom: 30px
|
padding-bottom: 30px
|
||||||
padding-top: 10px
|
padding-top: 10px
|
||||||
|
height: 50px
|
||||||
|
|
||||||
#mailadr
|
#mailadr
|
||||||
float: left
|
float: left
|
||||||
@@ -129,3 +147,10 @@ header
|
|||||||
position: absolute
|
position: absolute
|
||||||
font-size: 24px
|
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')
|
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
|
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')
|
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')
|
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')
|
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')
|
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')
|
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
|
#buttonsRight
|
||||||
button.btn.btn-primary#btnSet(value='set') Settings
|
button.btn.btn-primary#btnSet(value='set') Settings
|
||||||
button.btn.btn-primary#btnHelp(value='help') Info
|
button.btn.btn-primary#btnHelp(value='help') Info
|
||||||
@@ -28,13 +28,16 @@ block content
|
|||||||
.tab-content#thetabs
|
.tab-content#thetabs
|
||||||
.tab-pane.fade.show.active#t_map(role="tabpanel" aria-labelledby="map-tab")
|
.tab-pane.fade.show.active#t_map(role="tabpanel" aria-labelledby="map-tab")
|
||||||
#map MapTAB
|
#map MapTAB
|
||||||
.tab-pane.fade.show.active#t_live(role="tabpanel" aria-labelledby="map-tab")
|
#mapdateactsens
|
||||||
#placeholderNOI1 LiveTAB
|
#actsensors
|
||||||
.tab-pane.fade.show.active#t_houravg(role="tabpanel" aria-labelledby="map-tab")
|
#mapdate
|
||||||
#placeholderNOI2 HourTAB
|
.tab-pane.fade#t_live(role="tabpanel" aria-labelledby="live-tab")
|
||||||
.tab-pane.fade.show.active#t_dayavg(role="tabpanel" aria-labelledby="map-tab")
|
#dlive LiveTAB
|
||||||
#placeholderNOI3 DayTAB
|
.tab-pane.fade#t_houravg(role="tabpanel" aria-labelledby="map-tab")
|
||||||
.tab-pane.fade.show.active#t_daynight(role="tabpanel" aria-labelledby="map-tab")
|
#dhour HourTAB
|
||||||
#placeholderNOI4 DayNightTAB
|
.tab-pane.fade#t_dayavg(role="tabpanel" aria-labelledby="map-tab")
|
||||||
.tab-pane.fade.show.active#t_lden(role="tabpanel" aria-labelledby="map-tab")
|
#dday DayTAB
|
||||||
#placeholderNOI5 LdenTAB
|
.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
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ html
|
|||||||
body
|
body
|
||||||
#wrapper
|
#wrapper
|
||||||
block content
|
block content
|
||||||
|
footer
|
||||||
#author
|
#author
|
||||||
#mailadr
|
#mailadr
|
||||||
a(href="mailto:rexfue@gmail.com") mailto:rexfue@gmail.com
|
a(href="mailto:rexfue@gmail.com") mailto:rexfue@gmail.com
|
||||||
@@ -43,4 +44,5 @@ html
|
|||||||
integrity="sha256-WBkoXOwTeyKclOHuWtc+i2uENFpDZ9YPdf5Hf+D7ewM="
|
integrity="sha256-WBkoXOwTeyKclOHuWtc+i2uENFpDZ9YPdf5Hf+D7ewM="
|
||||||
crossorigin="")
|
crossorigin="")
|
||||||
script(src="/javascripts/leaflet.markercluster.js")
|
script(src="/javascripts/leaflet.markercluster.js")
|
||||||
|
script(src="https://code.highcharts.com/highcharts.js")
|
||||||
script(type="module" src="/javascripts/global.js")
|
script(type="module" src="/javascripts/global.js")
|
||||||
Reference in New Issue
Block a user