/* global React */ // Realistic SVG trend chart with ISO 10816-3 reference bands function TrendChart({ data, thresholds = { warn: 4.5, alarm: 7.1 }, unit = "mm/s", height = 260, showBands = true }) { const width = 880; const padL = 44, padR = 16, padT = 16, padB = 28; const innerW = width - padL - padR; const innerH = height - padT - padB; const values = data.map(d => d.value); const maxY = Math.max(Math.max(...values, thresholds.alarm * 1.15), 10); const minY = 0; const xStep = innerW / (data.length - 1); const yScale = (v) => padT + innerH - ((v - minY) / (maxY - minY)) * innerH; const xScale = (i) => padL + i * xStep; const linePath = data.map((d, i) => `${i === 0 ? "M" : "L"}${xScale(i).toFixed(1)},${yScale(d.value).toFixed(1)}`).join(" "); const areaPath = `${linePath} L${xScale(data.length - 1).toFixed(1)},${yScale(0)} L${xScale(0).toFixed(1)},${yScale(0)} Z`; const yTicks = [0, maxY * 0.25, maxY * 0.5, maxY * 0.75, maxY]; const last = data[data.length - 1]; const lastStatus = last.value > thresholds.alarm ? "alarm" : last.value > thresholds.warn ? "warn" : "ok"; return ( {/* Reference bands */} {showBands && ( <> )} {/* Y gridlines */} {yTicks.map((t, i) => ( {t.toFixed(1)} ))} {/* Threshold lines */} ISO B/C · {thresholds.warn.toFixed(1)} ISO C/D · {thresholds.alarm.toFixed(1)} {/* Area + line */} {/* Dots */} {data.map((d, i) => { const s = d.value > thresholds.alarm ? "var(--alarm)" : d.value > thresholds.warn ? "var(--warn)" : "var(--ok)"; const isLast = i === data.length - 1; return ( ); })} {/* Last value callout */} OSTATNI {last.value.toFixed(2)} {unit} {lastStatus === "alarm" ? "ALM" : lastStatus === "warn" ? "WRN" : "OK"} {/* X axis — every 5th label */} {data.map((d, i) => i % 6 === 0 && ( {d.date.slice(5)} ))} {/* Baseline */} ); } Object.assign(window, { TrendChart });