wykres z gap
This commit is contained in:
18
app.py
18
app.py
@@ -205,6 +205,7 @@ def get_timeseries(phase_id):
|
||||
datetime.fromisoformat(end_param.replace("Z", "+00:00"))
|
||||
except Exception:
|
||||
return api_error(400, "bad_datetime", "start/end must be ISO 8601")
|
||||
|
||||
time_filter = f"time >= '{start_param}' AND time <= '{end_param}'"
|
||||
interval = config.DEFAULT_INTERVAL
|
||||
else:
|
||||
@@ -213,6 +214,7 @@ def get_timeseries(phase_id):
|
||||
parse_range(clean_range)
|
||||
except Exception:
|
||||
return api_error(400, "bad_range", "range must be like 24h or 7d")
|
||||
|
||||
time_filter = f"time > now() - {clean_range}"
|
||||
interval = config.TIME_RANGES.get(range_param, {}).get("interval", config.DEFAULT_INTERVAL)
|
||||
|
||||
@@ -221,17 +223,21 @@ def get_timeseries(phase_id):
|
||||
FROM "{config.MEASUREMENT}"
|
||||
WHERE "entity_id" = '{entity_id}'
|
||||
AND {time_filter}
|
||||
GROUP BY time({interval}) fill(none)
|
||||
GROUP BY time({interval}) fill(null)
|
||||
'''
|
||||
|
||||
client = get_influx_client()
|
||||
try:
|
||||
result = client.query(query)
|
||||
data = [
|
||||
{"time": p["time"], "voltage": round(p["voltage"], 2)}
|
||||
for p in result.get_points()
|
||||
if p.get("voltage") is not None
|
||||
]
|
||||
data = []
|
||||
for p in result.get_points():
|
||||
v = p.get("voltage")
|
||||
data.append(
|
||||
{
|
||||
"time": p["time"],
|
||||
"voltage": (round(float(v), 2) if v is not None else None),
|
||||
}
|
||||
)
|
||||
return jsonify(data)
|
||||
except Exception as e:
|
||||
app.logger.error(f"Timeseries Error: {e} | Query: {query}")
|
||||
|
||||
@@ -82,7 +82,7 @@ window.setupMainChart = function setupMainChart() {
|
||||
legend: {
|
||||
labels: {
|
||||
color: '#c9d1d9',
|
||||
filter: (item) => !['Zanik', 'Powrot', 'Awaria'].some(word => item.text.includes(word))
|
||||
filter: (item) => !['Zanik', 'Powrot', 'Awaria', 'Brak danych'].some(word => item.text.includes(word))
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
|
||||
@@ -1,35 +1,73 @@
|
||||
window.processPhaseData = function processPhaseData(id, data) {
|
||||
const lineData = [];
|
||||
const outagePoints = [];
|
||||
const recoveryPoints = [];
|
||||
const outageLineData = [];
|
||||
|
||||
const gapBars = [];
|
||||
const outageBars = [];
|
||||
|
||||
let wasOutage = false;
|
||||
|
||||
const Y_TOP = 255;
|
||||
const GAP_BAR_VALUE = Y_TOP;
|
||||
const OUT_BAR_VALUE = Y_TOP;
|
||||
|
||||
data.forEach(p => {
|
||||
const v = p.voltage;
|
||||
const t = new Date(p.time);
|
||||
|
||||
if (v < 180 && v !== null) {
|
||||
const pOut = { x: t, y: 195, realV: v };
|
||||
outagePoints.push(pOut);
|
||||
outageLineData.push(pOut);
|
||||
if (v === null || v === undefined) {
|
||||
lineData.push({ x: t, y: null });
|
||||
outageLineData.push({ x: t, y: null });
|
||||
gapBars.push({ x: t, y: GAP_BAR_VALUE });
|
||||
return;
|
||||
}
|
||||
|
||||
if (v < 180) {
|
||||
outageBars.push({ x: t, y: OUT_BAR_VALUE });
|
||||
|
||||
lineData.push({ x: t, y: null });
|
||||
outageLineData.push({ x: t, y: 195, realV: v });
|
||||
|
||||
wasOutage = true;
|
||||
} else {
|
||||
if (wasOutage) {
|
||||
const pRec = { x: t, y: v, realV: v };
|
||||
recoveryPoints.push(pRec);
|
||||
outageLineData.push(pRec);
|
||||
wasOutage = false;
|
||||
} else {
|
||||
outageLineData.push({ x: t, y: null });
|
||||
}
|
||||
lineData.push({ x: t, y: v });
|
||||
return;
|
||||
}
|
||||
|
||||
if (wasOutage) {
|
||||
const pRec = { x: t, y: v, realV: v };
|
||||
recoveryPoints.push(pRec);
|
||||
outageLineData.push(pRec);
|
||||
wasOutage = false;
|
||||
} else {
|
||||
outageLineData.push({ x: t, y: null });
|
||||
}
|
||||
|
||||
lineData.push({ x: t, y: v });
|
||||
});
|
||||
|
||||
return {
|
||||
gapDataset: gapBars.length ? {
|
||||
type: 'bar',
|
||||
label: 'Brak danych ' + window.phasesConfig[id].label,
|
||||
data: gapBars,
|
||||
backgroundColor: 'rgba(160,160,160,0.14)',
|
||||
borderWidth: 0,
|
||||
barPercentage: 1.0,
|
||||
categoryPercentage: 1.0,
|
||||
order: -50
|
||||
} : null,
|
||||
|
||||
outageShadeDataset: outageBars.length ? {
|
||||
type: 'bar',
|
||||
label: 'Zanik ' + window.phasesConfig[id].label,
|
||||
data: outageBars,
|
||||
backgroundColor: 'rgba(255,0,0,0.10)',
|
||||
borderWidth: 0,
|
||||
barPercentage: 1.0,
|
||||
categoryPercentage: 1.0,
|
||||
order: -40
|
||||
} : null,
|
||||
|
||||
lineDataset: {
|
||||
label: window.phasesConfig[id].label,
|
||||
data: lineData,
|
||||
@@ -38,8 +76,10 @@ window.processPhaseData = function processPhaseData(id, data) {
|
||||
tension: 0.1,
|
||||
borderWidth: 2,
|
||||
spanGaps: false,
|
||||
pointRadius: 0
|
||||
pointRadius: 0,
|
||||
order: 0
|
||||
},
|
||||
|
||||
outageLine: {
|
||||
label: 'Awaria ' + window.phasesConfig[id].label,
|
||||
data: outageLineData,
|
||||
@@ -49,18 +89,10 @@ window.processPhaseData = function processPhaseData(id, data) {
|
||||
pointRadius: 0,
|
||||
fill: false,
|
||||
spanGaps: false,
|
||||
showLine: true
|
||||
showLine: true,
|
||||
order: 1
|
||||
},
|
||||
outageDataset: outagePoints.length ? {
|
||||
label: 'Zanik ' + window.phasesConfig[id].label,
|
||||
data: outagePoints,
|
||||
type: 'scatter',
|
||||
pointRadius: 4,
|
||||
pointBackgroundColor: '#ff0000',
|
||||
pointBorderColor: '#fff',
|
||||
pointBorderWidth: 1,
|
||||
z: 99
|
||||
} : null,
|
||||
|
||||
recoveryDataset: recoveryPoints.length ? {
|
||||
label: 'Powrot ' + window.phasesConfig[id].label,
|
||||
data: recoveryPoints,
|
||||
@@ -69,7 +101,8 @@ window.processPhaseData = function processPhaseData(id, data) {
|
||||
pointBackgroundColor: '#3fb950',
|
||||
pointBorderColor: '#fff',
|
||||
pointBorderWidth: 1,
|
||||
z: 99
|
||||
z: 99,
|
||||
order: 11
|
||||
} : null
|
||||
};
|
||||
};
|
||||
@@ -89,6 +122,11 @@ window.reloadDataForRange = async function reloadDataForRange(min, max, rangeNam
|
||||
try {
|
||||
const raw = await fetch(`/api/timeseries/${id}?${urlParams}`).then(r => r.json());
|
||||
const proc = window.processPhaseData(id, raw);
|
||||
|
||||
if (proc.gapDataset) newDatasets.push(proc.gapDataset);
|
||||
if (proc.outageShadeDataset) newDatasets.push(proc.outageShadeDataset);
|
||||
|
||||
|
||||
newDatasets.push(proc.lineDataset);
|
||||
if (proc.outageLine) newDatasets.push(proc.outageLine);
|
||||
if (proc.outageDataset) newDatasets.push(proc.outageDataset);
|
||||
|
||||
Reference in New Issue
Block a user