Init 2
This commit is contained in:
1 parent
ce00c4c671
commit
bdb9b72fac
66 files changed
+9553
-1547
No files matched your search
@@ -0,0 +1,84 @@
|
||||
import type { PingProbe, Server } from "@/lib/data"
|
||||
|
||||
/** Длина ряда на графике дашборда (ось времени). */
|
||||
export const DASH_LATENCY_POINTS = 60
|
||||
|
||||
/** Растягивает/сэмплирует ряд до `targetLen` (линейная интерполяция по индексам). */
|
||||
export function padSeriesToLength(values: number[], targetLen: number): number[] {
|
||||
if (targetLen <= 0) return []
|
||||
if (values.length === 0) return Array(targetLen).fill(0)
|
||||
if (values.length === targetLen) return [...values]
|
||||
if (values.length > targetLen) return values.slice(values.length - targetLen)
|
||||
if (values.length === 1) return Array(targetLen).fill(values[0] ?? 0)
|
||||
const out: number[] = []
|
||||
for (let i = 0; i < targetLen; i++) {
|
||||
const t = (i / (targetLen - 1)) * (values.length - 1)
|
||||
const j = Math.floor(t)
|
||||
const f = t - j
|
||||
const a = values[j] ?? 0
|
||||
const b = values[Math.min(j + 1, values.length - 1)] ?? a
|
||||
out.push(Math.round(a + f * (b - a)))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
export interface DashboardLatencyChartInput {
|
||||
series: Record<string, number[]>
|
||||
labels: Record<string, string>
|
||||
}
|
||||
|
||||
/**
|
||||
* Средний RTT по всем включённым пробам с одного источника (srcServerId).
|
||||
* Ключ серии — стабильный id вида `src-<numericId>`; подпись — площадка или имя сервера.
|
||||
* Ограничение числа линий — чтобы график оставался читаемым.
|
||||
*/
|
||||
export function buildLatencySeriesByProbeSource(
|
||||
probes: PingProbe[],
|
||||
servers: Server[],
|
||||
opts?: { maxServers?: number; points?: number },
|
||||
): DashboardLatencyChartInput {
|
||||
const maxServers = opts?.maxServers ?? 8
|
||||
const points = opts?.points ?? DASH_LATENCY_POINTS
|
||||
|
||||
const bySrv = new Map<string, PingProbe[]>()
|
||||
for (const p of probes) {
|
||||
if (!p.enabled || !p.series?.length) continue
|
||||
const sid = p.srcServerId
|
||||
if (!bySrv.has(sid)) bySrv.set(sid, [])
|
||||
bySrv.get(sid)!.push(p)
|
||||
}
|
||||
|
||||
const sortedIds = [...bySrv.keys()].sort((a, b) => {
|
||||
const na = servers.find((s) => s.id === a)?.name ?? a
|
||||
const nb = servers.find((s) => s.id === b)?.name ?? b
|
||||
return na.localeCompare(nb, "ru")
|
||||
}).slice(0, maxServers)
|
||||
|
||||
const series: Record<string, number[]> = {}
|
||||
const labels: Record<string, string> = {}
|
||||
|
||||
for (const sid of sortedIds) {
|
||||
const plist = bySrv.get(sid)!
|
||||
const innerLen = plist.reduce((m, p) => Math.max(m, p.series.length), 0)
|
||||
if (innerLen === 0) continue
|
||||
|
||||
const averaged = Array.from({ length: innerLen }, (_, i) => {
|
||||
const vals = plist
|
||||
.map((p) => p.series[i])
|
||||
.filter((v): v is number => typeof v === "number" && Number.isFinite(v))
|
||||
if (!vals.length) return 0
|
||||
return Math.round(vals.reduce((x, y) => x + y, 0) / vals.length)
|
||||
})
|
||||
|
||||
const key = `src-${sid}`
|
||||
series[key] = padSeriesToLength(averaged, points)
|
||||
const srv = servers.find((s) => s.id === sid)
|
||||
const site = srv?.site?.trim()
|
||||
labels[key] =
|
||||
site && site !== "—"
|
||||
? site.slice(0, 16)
|
||||
: (srv?.name ?? `#${sid}`).slice(0, 16)
|
||||
}
|
||||
|
||||
return { series, labels }
|
||||
}
|
||||
Reference in new issue
Block a user