refactor: consolidate fixedFloat funcs + remove trailing zeroes from y axis

This commit is contained in:
henrygd
2025-07-15 21:46:41 -04:00
parent d4fd19522b
commit 49ae424698
8 changed files with 23 additions and 50 deletions

View File

@@ -1,15 +1,7 @@
import { Area, AreaChart, CartesianGrid, YAxis } from "recharts" import { Area, AreaChart, CartesianGrid, YAxis } from "recharts"
import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent, xAxis } from "@/components/ui/chart" import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent, xAxis } from "@/components/ui/chart"
import { memo, useMemo } from "react" import { memo, useMemo } from "react"
import { import { useYAxisWidth, cn, formatShortDate, chartMargin, toFixedFloat, formatBytes, decimalString } from "@/lib/utils"
useYAxisWidth,
cn,
formatShortDate,
chartMargin,
toFixedWithoutTrailingZeros,
formatBytes,
decimalString,
} from "@/lib/utils"
// import Spinner from '../spinner' // import Spinner from '../spinner'
import { useStore } from "@nanostores/react" import { useStore } from "@nanostores/react"
import { $containerFilter, $userSettings } from "@/lib/stores" import { $containerFilter, $userSettings } from "@/lib/stores"
@@ -84,14 +76,14 @@ export default memo(function ContainerChart({
// tick formatter // tick formatter
if (chartType === ChartType.CPU) { if (chartType === ChartType.CPU) {
obj.tickFormatter = (value) => { obj.tickFormatter = (value) => {
const val = toFixedWithoutTrailingZeros(value, 2) + unit const val = toFixedFloat(value, 2) + unit
return updateYAxisWidth(val) return updateYAxisWidth(val)
} }
} else { } else {
const chartUnit = isNetChart ? userSettings.unitNet : Unit.Bytes const chartUnit = isNetChart ? userSettings.unitNet : Unit.Bytes
obj.tickFormatter = (val) => { obj.tickFormatter = (val) => {
const { value, unit } = formatBytes(val, isNetChart, chartUnit, true) const { value, unit } = formatBytes(val, isNetChart, chartUnit, true)
return updateYAxisWidth(decimalString(value, value >= 10 ? 0 : 1) + " " + unit) return updateYAxisWidth(toFixedFloat(value, value >= 10 ? 0 : 1) + " " + unit)
} }
} }
// tooltip formatter // tooltip formatter

View File

@@ -1,6 +1,6 @@
import { Area, AreaChart, CartesianGrid, YAxis } from "recharts" import { Area, AreaChart, CartesianGrid, YAxis } from "recharts"
import { ChartContainer, ChartTooltip, ChartTooltipContent, xAxis } from "@/components/ui/chart" import { ChartContainer, ChartTooltip, ChartTooltipContent, xAxis } from "@/components/ui/chart"
import { useYAxisWidth, cn, formatShortDate, decimalString, chartMargin, formatBytes } from "@/lib/utils" import { useYAxisWidth, cn, formatShortDate, decimalString, chartMargin, formatBytes, toFixedFloat } from "@/lib/utils"
import { ChartData } from "@/types" import { ChartData } from "@/types"
import { memo } from "react" import { memo } from "react"
import { useLingui } from "@lingui/react/macro" import { useLingui } from "@lingui/react/macro"
@@ -48,7 +48,7 @@ export default memo(function DiskChart({
axisLine={false} axisLine={false}
tickFormatter={(val) => { tickFormatter={(val) => {
const { value, unit } = formatBytes(val * 1024, false, Unit.Bytes, true) const { value, unit } = formatBytes(val * 1024, false, Unit.Bytes, true)
return updateYAxisWidth(decimalString(value, value >= 10 ? 0 : 1) + " " + unit) return updateYAxisWidth(toFixedFloat(value, value >= 10 ? 0 : 1) + " " + unit)
}} }}
/> />
{xAxis(chartData)} {xAxis(chartData)}

View File

@@ -8,14 +8,7 @@ import {
ChartTooltipContent, ChartTooltipContent,
xAxis, xAxis,
} from "@/components/ui/chart" } from "@/components/ui/chart"
import { import { useYAxisWidth, cn, formatShortDate, toFixedFloat, decimalString, chartMargin } from "@/lib/utils"
useYAxisWidth,
cn,
formatShortDate,
toFixedWithoutTrailingZeros,
decimalString,
chartMargin,
} from "@/lib/utils"
import { ChartData } from "@/types" import { ChartData } from "@/types"
import { memo, useMemo } from "react" import { memo, useMemo } from "react"
@@ -72,7 +65,7 @@ export default memo(function GpuPowerChart({ chartData }: { chartData: ChartData
domain={[0, "auto"]} domain={[0, "auto"]}
width={yAxisWidth} width={yAxisWidth}
tickFormatter={(value) => { tickFormatter={(value) => {
const val = toFixedWithoutTrailingZeros(value, 2) const val = toFixedFloat(value, 2)
return updateYAxisWidth(val + "W") return updateYAxisWidth(val + "W")
}} }}
tickLine={false} tickLine={false}

View File

@@ -1,6 +1,6 @@
import { Area, AreaChart, CartesianGrid, YAxis } from "recharts" import { Area, AreaChart, CartesianGrid, YAxis } from "recharts"
import { ChartContainer, ChartTooltip, ChartTooltipContent, xAxis } from "@/components/ui/chart" import { ChartContainer, ChartTooltip, ChartTooltipContent, xAxis } from "@/components/ui/chart"
import { useYAxisWidth, cn, toFixedFloat, decimalString, formatShortDate, chartMargin, formatBytes } from "@/lib/utils" import { useYAxisWidth, cn, decimalString, formatShortDate, chartMargin, formatBytes, toFixedFloat } from "@/lib/utils"
import { memo } from "react" import { memo } from "react"
import { ChartData } from "@/types" import { ChartData } from "@/types"
import { useLingui } from "@lingui/react/macro" import { useLingui } from "@lingui/react/macro"
@@ -41,7 +41,7 @@ export default memo(function MemChart({ chartData }: { chartData: ChartData }) {
axisLine={false} axisLine={false}
tickFormatter={(value) => { tickFormatter={(value) => {
const { value: convertedValue, unit } = formatBytes(value * 1024, false, Unit.Bytes, true) const { value: convertedValue, unit } = formatBytes(value * 1024, false, Unit.Bytes, true)
return updateYAxisWidth(decimalString(convertedValue, value >= 10 ? 0 : 1) + " " + unit) return updateYAxisWidth(toFixedFloat(convertedValue, value >= 10 ? 0 : 1) + " " + unit)
}} }}
/> />
)} )}

View File

@@ -2,15 +2,7 @@ import { t } from "@lingui/core/macro"
import { Area, AreaChart, CartesianGrid, YAxis } from "recharts" import { Area, AreaChart, CartesianGrid, YAxis } from "recharts"
import { ChartContainer, ChartTooltip, ChartTooltipContent, xAxis } from "@/components/ui/chart" import { ChartContainer, ChartTooltip, ChartTooltipContent, xAxis } from "@/components/ui/chart"
import { import { useYAxisWidth, cn, formatShortDate, decimalString, chartMargin, formatBytes, toFixedFloat } from "@/lib/utils"
useYAxisWidth,
cn,
formatShortDate,
toFixedWithoutTrailingZeros,
decimalString,
chartMargin,
formatBytes,
} from "@/lib/utils"
import { ChartData } from "@/types" import { ChartData } from "@/types"
import { memo } from "react" import { memo } from "react"
import { $userSettings } from "@/lib/stores" import { $userSettings } from "@/lib/stores"
@@ -37,13 +29,13 @@ export default memo(function SwapChart({ chartData }: { chartData: ChartData })
direction="ltr" direction="ltr"
orientation={chartData.orientation} orientation={chartData.orientation}
className="tracking-tighter" className="tracking-tighter"
domain={[0, () => toFixedWithoutTrailingZeros(chartData.systemStats.at(-1)?.stats.s ?? 0.04, 2)]} domain={[0, () => toFixedFloat(chartData.systemStats.at(-1)?.stats.s ?? 0.04, 2)]}
width={yAxisWidth} width={yAxisWidth}
tickLine={false} tickLine={false}
axisLine={false} axisLine={false}
tickFormatter={(value) => { tickFormatter={(value) => {
const { value: convertedValue, unit } = formatBytes(value * 1024, false, userSettings.unitDisk, true) const { value: convertedValue, unit } = formatBytes(value * 1024, false, userSettings.unitDisk, true)
return updateYAxisWidth(decimalString(convertedValue, value >= 10 ? 0 : 1) + " " + unit) return updateYAxisWidth(toFixedFloat(convertedValue, value >= 10 ? 0 : 1) + " " + unit)
}} }}
/> />
{xAxis(chartData)} {xAxis(chartData)}

View File

@@ -12,7 +12,7 @@ import {
useYAxisWidth, useYAxisWidth,
cn, cn,
formatShortDate, formatShortDate,
toFixedWithoutTrailingZeros, toFixedFloat,
chartMargin, chartMargin,
formatTemperature, formatTemperature,
decimalString, decimalString,
@@ -76,7 +76,7 @@ export default memo(function TemperatureChart({ chartData }: { chartData: ChartD
width={yAxisWidth} width={yAxisWidth}
tickFormatter={(val) => { tickFormatter={(val) => {
const { value, unit } = formatTemperature(val, userSettings.unitTemp) const { value, unit } = formatTemperature(val, userSettings.unitTemp)
return updateYAxisWidth(toFixedWithoutTrailingZeros(value, 2) + " " + unit) return updateYAxisWidth(toFixedFloat(value, 2) + " " + unit)
}} }}
tickLine={false} tickLine={false}
axisLine={false} axisLine={false}

View File

@@ -26,7 +26,7 @@ import {
getHostDisplayValue, getHostDisplayValue,
getPbTimestamp, getPbTimestamp,
listen, listen,
toFixedWithoutTrailingZeros, toFixedFloat,
useLocalStorage, useLocalStorage,
} from "@/lib/utils" } from "@/lib/utils"
import { Separator } from "../ui/separator" import { Separator } from "../ui/separator"
@@ -478,7 +478,7 @@ export default function SystemDetail({ name }: { name: string }) {
chartData={chartData} chartData={chartData}
chartName="CPU Usage" chartName="CPU Usage"
maxToggled={maxValues} maxToggled={maxValues}
tickFormatter={(val) => toFixedWithoutTrailingZeros(val, 2) + "%"} tickFormatter={(val) => toFixedFloat(val, 2) + "%"}
contentFormatter={({ value }) => decimalString(value) + "%"} contentFormatter={({ value }) => decimalString(value) + "%"}
/> />
</ChartCard> </ChartCard>
@@ -533,7 +533,7 @@ export default function SystemDetail({ name }: { name: string }) {
maxToggled={maxValues} maxToggled={maxValues}
tickFormatter={(val) => { tickFormatter={(val) => {
const { value, unit } = formatBytes(val, true, userSettings.unitDisk, true) const { value, unit } = formatBytes(val, true, userSettings.unitDisk, true)
return decimalString(value, value >= 10 ? 0 : 1) + " " + unit return toFixedFloat(value, value >= 10 ? 0 : 1) + " " + unit
}} }}
contentFormatter={({ value }) => { contentFormatter={({ value }) => {
const { value: convertedValue, unit } = formatBytes(value, true, userSettings.unitDisk, true) const { value: convertedValue, unit } = formatBytes(value, true, userSettings.unitDisk, true)
@@ -555,8 +555,7 @@ export default function SystemDetail({ name }: { name: string }) {
maxToggled={maxValues} maxToggled={maxValues}
tickFormatter={(val) => { tickFormatter={(val) => {
let { value, unit } = formatBytes(val, true, userSettings.unitNet, true) let { value, unit } = formatBytes(val, true, userSettings.unitNet, true)
// value = value >= 10 ? Math.ceil(value) : value return toFixedFloat(value, value >= 10 ? 0 : 1) + " " + unit
return decimalString(value, value >= 10 ? 0 : 1) + " " + unit
}} }}
contentFormatter={({ value }) => { contentFormatter={({ value }) => {
const { value: convertedValue, unit } = formatBytes(value, true, userSettings.unitNet, true) const { value: convertedValue, unit } = formatBytes(value, true, userSettings.unitNet, true)
@@ -638,7 +637,7 @@ export default function SystemDetail({ name }: { name: string }) {
<AreaChartDefault <AreaChartDefault
chartData={chartData} chartData={chartData}
chartName={`g.${id}.u`} chartName={`g.${id}.u`}
tickFormatter={(val) => toFixedWithoutTrailingZeros(val, 2) + "%"} tickFormatter={(val) => toFixedFloat(val, 2) + "%"}
contentFormatter={({ value }) => decimalString(value) + "%"} contentFormatter={({ value }) => decimalString(value) + "%"}
/> />
</ChartCard> </ChartCard>
@@ -654,7 +653,7 @@ export default function SystemDetail({ name }: { name: string }) {
max={gpu.mt} max={gpu.mt}
tickFormatter={(val) => { tickFormatter={(val) => {
const { value, unit } = formatBytes(val, false, Unit.Bytes, true) const { value, unit } = formatBytes(val, false, Unit.Bytes, true)
return decimalString(value, value >= 10 ? 0 : 1) + " " + unit return toFixedFloat(value, value >= 10 ? 0 : 1) + " " + unit
}} }}
contentFormatter={({ value }) => { contentFormatter={({ value }) => {
const { value: convertedValue, unit } = formatBytes(value, false, Unit.Bytes, true) const { value: convertedValue, unit } = formatBytes(value, false, Unit.Bytes, true)
@@ -699,7 +698,7 @@ export default function SystemDetail({ name }: { name: string }) {
maxToggled={maxValues} maxToggled={maxValues}
tickFormatter={(val) => { tickFormatter={(val) => {
const { value, unit } = formatBytes(val, true, userSettings.unitDisk, true) const { value, unit } = formatBytes(val, true, userSettings.unitDisk, true)
return decimalString(value, value >= 10 ? 0 : 1) + " " + unit return toFixedFloat(value, value >= 10 ? 0 : 1) + " " + unit
}} }}
contentFormatter={({ value }) => { contentFormatter={({ value }) => {
const { value: convertedValue, unit } = formatBytes(value, true, userSettings.unitDisk, true) const { value: convertedValue, unit } = formatBytes(value, true, userSettings.unitDisk, true)

View File

@@ -226,16 +226,13 @@ export function useYAxisWidth() {
return { yAxisWidth, updateYAxisWidth } return { yAxisWidth, updateYAxisWidth }
} }
export function toFixedWithoutTrailingZeros(num: number, digits: number) { /** Format number to x decimal places, without trailing zeros */
return parseFloat(num.toFixed(digits)).toString()
}
export function toFixedFloat(num: number, digits: number) { export function toFixedFloat(num: number, digits: number) {
return parseFloat((digits === 0 ? Math.ceil(num) : num).toFixed(digits)) return parseFloat((digits === 0 ? Math.ceil(num) : num).toFixed(digits))
} }
let decimalFormatters: Map<number, Intl.NumberFormat> = new Map() let decimalFormatters: Map<number, Intl.NumberFormat> = new Map()
/** Format number to x decimal places */ /** Format number to x decimal places, maintaining trailing zeros */
export function decimalString(num: number, digits = 2) { export function decimalString(num: number, digits = 2) {
if (digits === 0) { if (digits === 0) {
return Math.ceil(num).toString() return Math.ceil(num).toString()