This commit is contained in:
henrygd
2026-04-26 17:19:15 -04:00
parent af49ebf2df
commit f830665984
8 changed files with 113 additions and 91 deletions

View File

@@ -1,6 +1,6 @@
import type { CellContext, Column, ColumnDef } from "@tanstack/react-table"
import { Button } from "@/components/ui/button"
import { cn, decimalString, hourWithSeconds } from "@/lib/utils"
import { cn, formatMicroseconds, hourWithSeconds } from "@/lib/utils"
import {
GlobeIcon,
TimerIcon,
@@ -290,9 +290,9 @@ export function getProbeColumns(
}
const responseTimeThresholds = {
http: { warning: 800, critical: 3000 },
tcp: { warning: 500, critical: 2000 },
icmp: { warning: 100, critical: 500 },
http: { warning: 800_000, critical: 3_000_000 },
tcp: { warning: 500_000, critical: 2_000_000 },
icmp: { warning: 100_000, critical: 500_000 },
}
function responseTimeCell(cell: CellContext<NetworkProbeRecord, unknown>) {
@@ -317,7 +317,7 @@ function responseTimeCell(cell: CellContext<NetworkProbeRecord, unknown>) {
return (
<span className="ms-1.5 tabular-nums flex gap-2 items-center">
<span className={cn("shrink-0 size-2 rounded-full", color)} />
{decimalString(responseTime, responseTime < 100 ? 2 : 1).toLocaleString()}ms
{formatMicroseconds(responseTime)}
</span>
)
}

View File

@@ -1,6 +1,6 @@
import LineChartDefault from "@/components/charts/line-chart"
import type { DataPoint } from "@/components/charts/line-chart"
import { toFixedFloat, decimalString } from "@/lib/utils"
import { decimalString, formatMicroseconds, toFixedFloat } from "@/lib/utils"
import { useLingui } from "@lingui/react/macro"
import { ChartCard, FilterBar } from "../chart-card"
import type { ChartData, NetworkProbeRecord, NetworkProbeStatsRecord } from "@/types"
@@ -116,13 +116,13 @@ export function ResponseChart({ probeStats, grid, probes, chartData, empty }: Pr
empty={empty}
valueIndex={0}
title={t`Response`}
description={t`Average response time (ms)`}
tickFormatter={(value) => `${toFixedFloat(value, value >= 10 ? 0 : 1)} ms`}
description={t`Average response time`}
tickFormatter={(value) => formatMicroseconds(value, false)}
contentFormatter={({ value }) => {
if (typeof value !== "number") {
return value
}
return `${decimalString(value, 2)} ms`
return formatMicroseconds(value)
}}
/>
)

View File

@@ -199,6 +199,26 @@ export function decimalString(num: number, digits = 2) {
return formatter.format(num)
}
export function formatMicroseconds(microseconds: number, showDigits = true): string {
if (!Number.isFinite(microseconds)) {
return "-"
}
if (microseconds < 1000) {
return `${microseconds}μs`
}
if (microseconds < 1_000_000) {
const milliseconds = microseconds / 1000
const digits = milliseconds >= 10 ? 1 : 2
return `${decimalString(milliseconds, showDigits ? digits : 0)}ms`
}
const seconds = microseconds / 1_000_000
const digits = seconds >= 10 ? 1 : 2
return `${decimalString(seconds, showDigits ? digits : 0)}s`
}
/** Get value from local or session storage */
function getStorageValue(key: string, defaultValue: unknown, storageInterface: Storage = localStorage) {
const saved = storageInterface?.getItem(key)

View File

@@ -563,15 +563,15 @@ export interface NetworkProbeRecord {
}
/**
* 0: avg 1 minute response in ms
* 0: avg 1 minute response in microseconds
*
* 1: avg response over 1 hour in ms
* 1: avg response over 1 hour in microseconds
*
* 2: min response over the last hour in ms
* 2: min response over the last hour in microseconds
*
* 3: max response over the last hour in ms
* 3: max response over the last hour in microseconds
*
* 4: packet loss in %
* 4: packet loss over 1 hour in %
*/
type ProbeResult = number[]