fix(site): even y-axis ticks on system charts (#2466)

This commit is contained in:
Sven van Ginkel
2026-09-28 18:14:47 +02:00
committed by GitHub
parent b684ac9910
commit ad215788ed
9 changed files with 21 additions and 29 deletions

View File

@@ -6,6 +6,7 @@ import {
ChartLegendContent,
ChartTooltip,
ChartTooltipContent,
fixedDomainTicks,
xAxis,
} from "@/components/ui/chart"
import { chartMargin, cn, formatShortDate } from "@/lib/utils"
@@ -143,6 +144,7 @@ export default function AreaChartDefault({
className="tracking-tighter"
width={yAxisWidth}
domain={domain ?? [0, max ?? "auto"]}
ticks={fixedDomainTicks(domain ?? [0, max ?? "auto"])}
tickFormatter={(value, index) => updateYAxisWidth(tickFormatter(value, index))}
tickLine={false}
axisLine={false}

View File

@@ -6,6 +6,7 @@ import {
ChartLegendContent,
ChartTooltip,
ChartTooltipContent,
fixedDomainTicks,
xAxis,
} from "@/components/ui/chart"
import { chartMargin, cn, formatShortDate } from "@/lib/utils"
@@ -186,6 +187,7 @@ export default function LineChartDefault({
className="tracking-tighter"
width={yAxisWidth}
domain={domain ?? [0, max ?? "auto"]}
ticks={fixedDomainTicks(domain ?? [0, max ?? "auto"])}
tickFormatter={(value, index) => updateYAxisWidth(tickFormatter(value, index))}
tickLine={false}
axisLine={false}
@@ -199,6 +201,7 @@ export default function LineChartDefault({
className="tracking-tighter"
width={rightAxisWidth}
domain={domain2 ?? [0, max2 ?? "auto"]}
ticks={fixedDomainTicks(domain2 ?? [0, max2 ?? "auto"])}
tickFormatter={tickFormatter2 ?? tickFormatter}
tickLine={false}
axisLine={false}

View File

@@ -4,7 +4,6 @@ import { useContainerDataPoints } from "@/components/charts/hooks"
import { decimalString, toFixedFloat } from "@/lib/utils"
import type { ChartConfig } from "@/components/ui/chart"
import type { ChartData } from "@/types"
import { pinnedAxisDomain } from "@/components/ui/chart"
import CpuCoresSheet from "../cpu-sheet"
import { ChartCard, FilterBar, SelectAvgMax } from "../chart-card"
import { dockerOrPodman } from "../chart-data"
@@ -52,7 +51,6 @@ export function CpuChart({
]}
tickFormatter={(val) => `${toFixedFloat(val, 2)}%`}
contentFormatter={({ value }) => `${decimalString(value)}%`}
domain={pinnedAxisDomain()}
/>
</ChartCard>
)
@@ -87,7 +85,6 @@ export function ContainerCpuChart({
dataPoints={dataPoints}
tickFormatter={(val) => `${toFixedFloat(val, 2)}%`}
contentFormatter={({ value }) => `${decimalString(value)}%`}
domain={pinnedAxisDomain()}
showTotal={true}
reverseStackOrder={true}
filter={filter}

View File

@@ -4,7 +4,6 @@ import { decimalString, formatBytes, toFixedFloat } from "@/lib/utils"
import type { SystemStatsRecord } from "@/types"
import { ChartCard, SelectAvgMax } from "../chart-card"
import { Unit } from "@/lib/enums"
import { pinnedAxisDomain } from "@/components/ui/chart"
import DiskIoSheet from "../disk-io-sheet"
import type { SystemData } from "../use-system-data"
import { useStore } from "@nanostores/react"
@@ -194,7 +193,6 @@ export function DiskIOChart({ systemData, extraFsName }: { systemData: SystemDat
<AreaChartDefault
chartData={chartData}
maxToggled={showMax}
// domain={pinnedAxisDomain(true)}
showTotal={true}
dataPoints={[
{
@@ -250,7 +248,6 @@ export function DiskUtilizationChart({ systemData, extraFsName }: { systemData:
>
<AreaChartDefault
chartData={chartData}
domain={pinnedAxisDomain()}
tickFormatter={(val) => `${toFixedFloat(val, 2)}%`}
contentFormatter={({ value }) => `${decimalString(value)}%`}
maxToggled={showMax}

View File

@@ -7,7 +7,6 @@ import type { ChartData, SystemStatsRecord } from "@/types"
import { ChartCard, FilterBar, SelectAvgMax } from "../chart-card"
import { dockerOrPodman } from "../chart-data"
import { decimalString, formatBytes, toFixedFloat } from "@/lib/utils"
import { pinnedAxisDomain } from "@/components/ui/chart"
export function MemoryChart({
chartData,
@@ -114,7 +113,6 @@ export function ContainerMemoryChart({
const { value, unit } = formatBytes(item.value, false, Unit.Bytes, true)
return `${decimalString(value)} ${unit}`
}}
domain={pinnedAxisDomain()}
showTotal={true}
reverseStackOrder={true}
filter={filter}

View File

@@ -5,7 +5,6 @@ import { useContainerDataPoints } from "@/components/charts/hooks"
import { $userSettings } from "@/lib/stores"
import { decimalString, formatBytes, toFixedFloat } from "@/lib/utils"
import type { ChartConfig } from "@/components/ui/chart"
import { pinnedAxisDomain } from "@/components/ui/chart"
import type { ChartData, SystemStatsRecord } from "@/types"
import { Separator } from "@/components/ui/separator"
import NetworkSheet from "../network-sheet"
@@ -171,7 +170,6 @@ export function ContainerNetworkChart({
return `${toFixedFloat(value, value >= 10 ? 0 : 1)} ${unit}`
}}
contentFormatter={contentFormatter}
domain={pinnedAxisDomain()}
showTotal={true}
reverseStackOrder={true}
filter={filter}

View File

@@ -195,7 +195,7 @@ export default memo(function CpuCoresSheet({
opacity: 0.35,
},
]}
tickFormatter={(val) => `${val}%`}
tickFormatter={(val) => `${toFixedFloat(val, 2)}%`}
contentFormatter={({ value }) => `${value}%`}
/>
</ChartCard>

View File

@@ -12,7 +12,6 @@ import { decimalString, formatBytes, toFixedFloat } from "@/lib/utils"
import { ChartCard, SelectAvgMax } from "@/components/routes/system/chart-card"
import type { SystemData } from "@/components/routes/system/use-system-data"
import { diskDataFns, DiskUtilizationChart } from "./charts/disk-charts"
import { pinnedAxisDomain } from "@/components/ui/chart"
export default memo(function DiskIOSheet({
systemData,
@@ -129,7 +128,6 @@ export default memo(function DiskIOSheet({
maxToggled={showMax}
chartProps={chartProps}
showTotal={true}
domain={pinnedAxisDomain()}
itemSorter={(a, b) => a.order - b.order}
reverseStackOrder={true}
dataPoints={[
@@ -176,7 +174,6 @@ export default memo(function DiskIOSheet({
>
<AreaChartDefault
chartData={chartData}
domain={pinnedAxisDomain()}
tickFormatter={(val) => `${toFixedFloat(val, 2)}%`}
contentFormatter={({ value }) => `${decimalString(value)}%`}
maxToggled={showMax}
@@ -216,7 +213,6 @@ export default memo(function DiskIOSheet({
>
<AreaChartDefault
chartData={chartData}
domain={pinnedAxisDomain()}
tickFormatter={(val) => `${toFixedFloat(val, 2)}`}
contentFormatter={({ value }) => decimalString(value, value < 10 ? 3 : 2)}
maxToggled={showMax}
@@ -248,7 +244,6 @@ export default memo(function DiskIOSheet({
>
<AreaChartDefault
chartData={chartData}
domain={pinnedAxisDomain()}
tickFormatter={(val) => `${toFixedFloat(val, 2)} ms`}
contentFormatter={({ value }) => `${decimalString(value)} ms`}
maxToggled={showMax}

View File

@@ -474,17 +474,19 @@ export {
// ChartStyle,
}
export function pinnedAxisDomain(): AxisDomain {
return [
0,
(dataMax: number) => {
if (dataMax > 10) {
return Math.round(dataMax)
}
if (dataMax > 1) {
return Math.round(dataMax / 0.1) * 0.1
}
return dataMax
},
]
const roundFloat = (value: number) => Number(value.toPrecision(12))
/**
* Four equal intervals for a fixed [0, max] domain (e.g. total memory or disk size), with max as the top tick.
* Recharts stops one full step before max, which leaves a large gap below the top tick.
*/
export function fixedDomainTicks(domain?: AxisDomain): number[] | undefined {
if (!Array.isArray(domain)) {
return undefined
}
const [min, max] = domain
if (min !== 0 || typeof max !== "number" || !(max > 0) || !Number.isFinite(max)) {
return undefined
}
return [0, 1, 2, 3, 4].map((i) => roundFloat((max * i) / 4))
}