dot na zanikach
This commit is contained in:
@@ -41,30 +41,50 @@ function initMonitor(phases, defaultRange) {
|
||||
if (ctxChart) {
|
||||
voltageChart = new Chart(ctxChart, {
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: Object.keys(phasesConfig).map(id => ({
|
||||
label: phasesConfig[id].label,
|
||||
data: [],
|
||||
borderColor: phasesConfig[id].color,
|
||||
backgroundColor: phasesConfig[id].color + '20',
|
||||
tension: 0.3,
|
||||
pointRadius: 0,
|
||||
borderWidth: 2
|
||||
}))
|
||||
},
|
||||
data: { datasets: [] },
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
scales: {
|
||||
x: {
|
||||
type: 'time',
|
||||
time: {
|
||||
displayFormats: { hour: 'HH:mm', minute: 'HH:mm' },
|
||||
tooltipFormat: 'HH:mm'
|
||||
},
|
||||
time: { displayFormats: { hour: 'HH:mm', minute: 'HH:mm' }, tooltipFormat: 'HH:mm' },
|
||||
grid: { color: '#2d3139' }
|
||||
},
|
||||
y: { min: 190, max: 270, grid: { color: '#2d3139' }, ticks: { stepSize: 10 } }
|
||||
y: {
|
||||
beginAtZero: false,
|
||||
suggestedMin: 210,
|
||||
suggestedMax: 255,
|
||||
grid: { color: '#2d3139' },
|
||||
ticks: { stepSize: 5, color: '#c9d1d9' }
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
legend: {
|
||||
labels: {
|
||||
color: '#c9d1d9',
|
||||
filter: function(item) {
|
||||
return !item.text.includes('Zanik') && !item.text.includes('Powrot');
|
||||
}
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: function(context) {
|
||||
if (context.dataset.label.includes('Zanik')) {
|
||||
return 'ZANIK: ' + context.raw.realV.toFixed(1) + 'V';
|
||||
}
|
||||
if (context.dataset.label.includes('Powrot')) {
|
||||
return 'POWROT: ' + context.raw.realV.toFixed(1) + 'V';
|
||||
}
|
||||
let label = context.dataset.label || '';
|
||||
if (context.parsed.y !== null) {
|
||||
label += ': ' + context.parsed.y.toFixed(1) + 'V';
|
||||
}
|
||||
return label;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -74,15 +94,18 @@ function initMonitor(phases, defaultRange) {
|
||||
Object.keys(phasesConfig).forEach(id => {
|
||||
const val = data['phase' + id];
|
||||
const textElement = document.getElementById('value' + id);
|
||||
if (val !== undefined && val !== null && val !== 0) {
|
||||
if (val !== undefined && val !== null) {
|
||||
const numVal = parseFloat(val);
|
||||
if (textElement) textElement.textContent = numVal.toFixed(1) + 'V';
|
||||
if (textElement) {
|
||||
textElement.textContent = numVal.toFixed(1) + 'V';
|
||||
textElement.style.color = numVal < 200 ? '#dc3545' : '#fff';
|
||||
}
|
||||
updateGaugeUI(id, numVal);
|
||||
}
|
||||
});
|
||||
if (data.timestamp) {
|
||||
const date = new Date(data.timestamp);
|
||||
document.getElementById('lastUpdate').textContent = 'Odczyt: ' + date.toLocaleTimeString('pl-PL', {hour: '2-digit', minute:'2-digit', second:'2-digit', hour12: false});
|
||||
document.getElementById('lastUpdate').textContent = 'Odczyt: ' + date.toLocaleTimeString('pl-PL', {hour12: false});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -105,12 +128,74 @@ window.changeTimeRange = async function(range) {
|
||||
document.querySelectorAll('.time-btn').forEach(btn => btn.classList.remove('active'));
|
||||
const activeBtn = document.querySelector(`[data-range="${range}"]`);
|
||||
if (activeBtn) activeBtn.classList.add('active');
|
||||
|
||||
if (!voltageChart) return;
|
||||
for (let i = 1; i <= Object.keys(phasesConfig).length; i++) {
|
||||
const phaseIds = Object.keys(phasesConfig);
|
||||
voltageChart.data.datasets = [];
|
||||
|
||||
for (let id of phaseIds) {
|
||||
try {
|
||||
const response = await fetch(`/api/timeseries/${i}?range=${range}`);
|
||||
const response = await fetch(`/api/timeseries/${id}?range=${range}`);
|
||||
const data = await response.json();
|
||||
voltageChart.data.datasets[i-1].data = data.map(d => ({ x: new Date(d.time), y: d.voltage }));
|
||||
const lineData = [];
|
||||
const outagePoints = [];
|
||||
const recoveryPoints = [];
|
||||
let wasOutage = false;
|
||||
|
||||
data.forEach(p => {
|
||||
const v = p.voltage;
|
||||
const t = new Date(p.time);
|
||||
const minY = voltageChart.scales.y.min || 190;
|
||||
|
||||
if (v < 200 && v !== null) {
|
||||
outagePoints.push({ x: t, y: minY + 0.5, realV: v });
|
||||
lineData.push({ x: t, y: null });
|
||||
wasOutage = true;
|
||||
} else {
|
||||
if (wasOutage) {
|
||||
recoveryPoints.push({ x: t, y: v, realV: v });
|
||||
wasOutage = false;
|
||||
}
|
||||
lineData.push({ x: t, y: v });
|
||||
}
|
||||
});
|
||||
|
||||
voltageChart.data.datasets.push({
|
||||
label: phasesConfig[id].label,
|
||||
data: lineData,
|
||||
borderColor: phasesConfig[id].color,
|
||||
backgroundColor: phasesConfig[id].color + '15',
|
||||
tension: 0,
|
||||
borderWidth: 2,
|
||||
spanGaps: false,
|
||||
pointRadius: 0
|
||||
});
|
||||
|
||||
if (outagePoints.length > 0) {
|
||||
voltageChart.data.datasets.push({
|
||||
label: 'Zanik ' + phasesConfig[id].label,
|
||||
data: outagePoints,
|
||||
type: 'scatter',
|
||||
pointRadius: 5,
|
||||
pointBackgroundColor: '#ff0000ff',
|
||||
pointBorderColor: phasesConfig[id].color,
|
||||
pointBorderWidth: 2,
|
||||
z: 999
|
||||
});
|
||||
}
|
||||
|
||||
if (recoveryPoints.length > 0) {
|
||||
voltageChart.data.datasets.push({
|
||||
label: 'Powrot ' + phasesConfig[id].label,
|
||||
data: recoveryPoints,
|
||||
type: 'scatter',
|
||||
pointRadius: 5,
|
||||
pointBackgroundColor: '#3fb99aff',
|
||||
pointBorderColor: '#ffffff',
|
||||
pointBorderWidth: 2,
|
||||
z: 999
|
||||
});
|
||||
}
|
||||
} catch (e) { console.error(e); }
|
||||
}
|
||||
voltageChart.update();
|
||||
|
||||
Reference in New Issue
Block a user