Serverpuls: deutsche Zeitachse und Legende im Diagramm
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
16f3150ff1
commit
57f235dd36
3 files changed
+60
-3
No files matched your search
@@ -1,5 +1,6 @@
|
||||
import { useEffect, useRef } from 'react'
|
||||
import uPlot from 'uplot'
|
||||
import { formatAxisTick, formatLegendTime } from '../../lib/serverpulsFormat'
|
||||
import 'uplot/dist/uPlot.min.css'
|
||||
|
||||
/**
|
||||
@@ -23,7 +24,12 @@ export default function Chart({ data, series, height = 280, yFmt, yRange }) {
|
||||
legend: { live: true },
|
||||
scales: { y: { range: yr || ((u, min, max) => [Math.min(0, min), max === min ? min + 1 : max + (max - min) * 0.08]) } },
|
||||
axes: [
|
||||
{ stroke: '#9aa7b4', grid: { stroke: 'rgba(255,255,255,0.06)' }, ticks: { stroke: 'rgba(255,255,255,0.1)' } },
|
||||
{
|
||||
stroke: '#9aa7b4',
|
||||
grid: { stroke: 'rgba(255,255,255,0.06)' },
|
||||
ticks: { stroke: 'rgba(255,255,255,0.1)' },
|
||||
values: (u, splits, axisIdx, foundSpace, foundIncr) => splits.map((t) => formatAxisTick(t, foundIncr)),
|
||||
},
|
||||
{
|
||||
stroke: '#9aa7b4',
|
||||
grid: { stroke: 'rgba(255,255,255,0.06)' },
|
||||
@@ -33,7 +39,7 @@ export default function Chart({ data, series, height = 280, yFmt, yRange }) {
|
||||
},
|
||||
],
|
||||
series: [
|
||||
{},
|
||||
{ label: 'Zeit', value: (u, v) => formatLegendTime(v) },
|
||||
...s.map((x) => ({
|
||||
label: x.label,
|
||||
stroke: x.color || '#10b981',
|
||||
|
||||
@@ -56,3 +56,36 @@ export function formatNumber(v, digits = 2) {
|
||||
if (v === null || v === undefined) return '–'
|
||||
return nf(digits).format(v)
|
||||
}
|
||||
|
||||
// --- Zeitachsen (Europe/Berlin, de-DE) ---
|
||||
const TZ = 'Europe/Berlin'
|
||||
const dtf = (opts) => new Intl.DateTimeFormat('de-DE', { timeZone: TZ, ...opts })
|
||||
const F = {
|
||||
time: dtf({ hour: '2-digit', minute: '2-digit', hourCycle: 'h23' }),
|
||||
day: dtf({ day: '2-digit', month: '2-digit' }),
|
||||
month: dtf({ month: 'short', year: 'numeric' }),
|
||||
year: dtf({ year: 'numeric' }),
|
||||
legend: dtf({ day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit', hourCycle: 'h23' }),
|
||||
}
|
||||
|
||||
// Welches Format passt zu einem Tick-Abstand (Sekunden)?
|
||||
export function axisTimeKind(incrSec) {
|
||||
if (incrSec < 86400) return 'time'
|
||||
if (incrSec < 86400 * 28) return 'day'
|
||||
if (incrSec < 86400 * 360) return 'month'
|
||||
return 'year'
|
||||
}
|
||||
|
||||
// Tick (Sekunden) -> Text. Bei Tagesgrenzen innerhalb von Sub-Tages-Achsen das Datum zeigen.
|
||||
export function formatAxisTick(sec, incrSec) {
|
||||
const kind = axisTimeKind(incrSec)
|
||||
const d = new Date(sec * 1000)
|
||||
if (kind === 'time' && F.time.format(d) === '00:00') return F.day.format(d)
|
||||
return F[kind].format(d)
|
||||
}
|
||||
|
||||
// Legende: "30.09.2026, 11:20"
|
||||
export function formatLegendTime(sec) {
|
||||
if (sec === null || sec === undefined) return '–'
|
||||
return F.legend.format(new Date(sec * 1000))
|
||||
}
|
||||
Reference in new issue
Block a user