From af4c05e69270bdaf1eaf5d423378843590b2ed8b Mon Sep 17 00:00:00 2001 From: Henry Dollman Date: Tue, 3 Sep 2024 16:49:12 -0400 Subject: [PATCH] standardize chart values to two decimals --- .../site/src/components/charts/bandwidth-chart.tsx | 3 ++- .../src/components/charts/container-cpu-chart.tsx | 10 ++++++++-- .../src/components/charts/container-mem-chart.tsx | 9 ++++++++- .../src/components/charts/container-net-chart.tsx | 5 +++-- beszel/site/src/components/charts/cpu-chart.tsx | 4 ++-- beszel/site/src/components/charts/disk-chart.tsx | 4 ++-- beszel/site/src/components/charts/disk-io-chart.tsx | 3 ++- .../src/components/charts/extra-fs-disk-chart.tsx | 4 ++-- .../components/charts/extra-fs-disk-io-chart.tsx | 3 ++- beszel/site/src/components/charts/mem-chart.tsx | 11 +++++++++-- beszel/site/src/components/charts/swap-chart.tsx | 3 ++- .../src/components/charts/temperature-chart.tsx | 3 ++- beszel/site/src/components/ui/chart.tsx | 2 +- beszel/site/src/lib/utils.ts | 13 +++++++++++++ 14 files changed, 58 insertions(+), 19 deletions(-) diff --git a/beszel/site/src/components/charts/bandwidth-chart.tsx b/beszel/site/src/components/charts/bandwidth-chart.tsx index 51c0754..fa06a85 100644 --- a/beszel/site/src/components/charts/bandwidth-chart.tsx +++ b/beszel/site/src/components/charts/bandwidth-chart.tsx @@ -6,6 +6,7 @@ import { cn, formatShortDate, toFixedWithoutTrailingZeros, + twoDecimalString, useYaxisWidth, } from '@/lib/utils' // import Spinner from '../spinner' @@ -72,8 +73,8 @@ export default function BandwidthChart({ animationDuration={150} content={ formatShortDate(data[0].payload.created)} + contentFormatter={(item) => twoDecimalString(item.value) + ' MB/s'} indicator="line" /> } diff --git a/beszel/site/src/components/charts/container-cpu-chart.tsx b/beszel/site/src/components/charts/container-cpu-chart.tsx index 5569584..8b2ce60 100644 --- a/beszel/site/src/components/charts/container-cpu-chart.tsx +++ b/beszel/site/src/components/charts/container-cpu-chart.tsx @@ -6,7 +6,7 @@ import { ChartTooltipContent, } from '@/components/ui/chart' import { useMemo, useRef } from 'react' -import { chartTimeData, cn, formatShortDate, useYaxisWidth } from '@/lib/utils' +import { chartTimeData, cn, formatShortDate, twoDecimalString, useYaxisWidth } from '@/lib/utils' // import Spinner from '../spinner' import { useStore } from '@nanostores/react' import { $chartTime, $containerFilter } from '@/lib/stores' @@ -110,7 +110,13 @@ export default function ContainerCpuChart({ labelFormatter={(_, data) => formatShortDate(data[0].payload.time)} // @ts-ignore itemSorter={(a, b) => b.value - a.value} - content={} + content={ + twoDecimalString(item.value) + '%'} + indicator="line" + /> + } /> {Object.keys(chartConfig).map((key) => { const filtered = filter && !key.includes(filter) diff --git a/beszel/site/src/components/charts/container-mem-chart.tsx b/beszel/site/src/components/charts/container-mem-chart.tsx index ca482d4..0657784 100644 --- a/beszel/site/src/components/charts/container-mem-chart.tsx +++ b/beszel/site/src/components/charts/container-mem-chart.tsx @@ -11,6 +11,7 @@ import { cn, formatShortDate, toFixedWithoutTrailingZeros, + twoDecimalString, useYaxisWidth, } from '@/lib/utils' // import Spinner from '../spinner' @@ -115,7 +116,13 @@ export default function ContainerMemChart({ labelFormatter={(_, data) => formatShortDate(data[0].payload.time)} // @ts-ignore itemSorter={(a, b) => b.value - a.value} - content={} + content={ + twoDecimalString(item.value) + ' MB'} + indicator="line" + /> + } /> {Object.keys(chartConfig).map((key) => { const filtered = filter && !key.includes(filter) diff --git a/beszel/site/src/components/charts/container-net-chart.tsx b/beszel/site/src/components/charts/container-net-chart.tsx index 0aebfce..c4fbde0 100644 --- a/beszel/site/src/components/charts/container-net-chart.tsx +++ b/beszel/site/src/components/charts/container-net-chart.tsx @@ -11,6 +11,7 @@ import { cn, formatShortDate, toFixedWithoutTrailingZeros, + twoDecimalString, useYaxisWidth, } from '@/lib/utils' // import Spinner from '../spinner' @@ -125,10 +126,10 @@ export default function ContainerCpuChart({ const received = item?.payload?.[key][1] ?? 0 return ( - {received.toLocaleString()} MB/s + {twoDecimalString(received)} MB/s rx - {sent.toLocaleString()} MB/s tx + {twoDecimalString(sent)} MB/s tx ) } catch (e) { diff --git a/beszel/site/src/components/charts/cpu-chart.tsx b/beszel/site/src/components/charts/cpu-chart.tsx index a5f4d41..e3e8d80 100644 --- a/beszel/site/src/components/charts/cpu-chart.tsx +++ b/beszel/site/src/components/charts/cpu-chart.tsx @@ -1,7 +1,7 @@ import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from 'recharts' import { ChartContainer, ChartTooltip, ChartTooltipContent } from '@/components/ui/chart' -import { chartTimeData, cn, formatShortDate, useYaxisWidth } from '@/lib/utils' +import { chartTimeData, cn, formatShortDate, twoDecimalString, useYaxisWidth } from '@/lib/utils' // import Spinner from '../spinner' import { useStore } from '@nanostores/react' import { $chartTime } from '@/lib/stores' @@ -60,8 +60,8 @@ export default function CpuChart({ animationDuration={150} content={ formatShortDate(data[0].payload.created)} + contentFormatter={(item) => twoDecimalString(item.value) + '%'} indicator="line" /> } diff --git a/beszel/site/src/components/charts/disk-chart.tsx b/beszel/site/src/components/charts/disk-chart.tsx index 705a5e4..e418891 100644 --- a/beszel/site/src/components/charts/disk-chart.tsx +++ b/beszel/site/src/components/charts/disk-chart.tsx @@ -1,7 +1,7 @@ import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from 'recharts' import { ChartContainer, ChartTooltip, ChartTooltipContent } from '@/components/ui/chart' -import { chartTimeData, cn, formatShortDate, useYaxisWidth } from '@/lib/utils' +import { chartTimeData, cn, formatShortDate, twoDecimalString, useYaxisWidth } from '@/lib/utils' import { useMemo, useRef } from 'react' // import Spinner from '../spinner' import { useStore } from '@nanostores/react' @@ -71,8 +71,8 @@ export default function DiskChart({ animationDuration={150} content={ formatShortDate(data[0].payload.created)} + contentFormatter={(item) => twoDecimalString(item.value) + ' GB'} indicator="line" /> } diff --git a/beszel/site/src/components/charts/disk-io-chart.tsx b/beszel/site/src/components/charts/disk-io-chart.tsx index a270247..81258a6 100644 --- a/beszel/site/src/components/charts/disk-io-chart.tsx +++ b/beszel/site/src/components/charts/disk-io-chart.tsx @@ -6,6 +6,7 @@ import { cn, formatShortDate, toFixedWithoutTrailingZeros, + twoDecimalString, useYaxisWidth, } from '@/lib/utils' // import Spinner from '../spinner' @@ -76,8 +77,8 @@ export default function DiskIoChart({ animationDuration={150} content={ formatShortDate(data[0].payload.created)} + contentFormatter={(item) => twoDecimalString(item.value) + ' MB/s'} indicator="line" /> } diff --git a/beszel/site/src/components/charts/extra-fs-disk-chart.tsx b/beszel/site/src/components/charts/extra-fs-disk-chart.tsx index e1df44d..4e44385 100644 --- a/beszel/site/src/components/charts/extra-fs-disk-chart.tsx +++ b/beszel/site/src/components/charts/extra-fs-disk-chart.tsx @@ -1,7 +1,7 @@ import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from 'recharts' import { ChartContainer, ChartTooltip, ChartTooltipContent } from '@/components/ui/chart' -import { chartTimeData, cn, formatShortDate, useYaxisWidth } from '@/lib/utils' +import { chartTimeData, cn, formatShortDate, twoDecimalString, useYaxisWidth } from '@/lib/utils' import { useMemo, useRef } from 'react' // import Spinner from '../spinner' import { useStore } from '@nanostores/react' @@ -70,8 +70,8 @@ export default function ExFsDiskChart({ animationDuration={150} content={ formatShortDate(data[0].payload.created)} + contentFormatter={(item) => twoDecimalString(item.value) + ' GB'} indicator="line" /> } diff --git a/beszel/site/src/components/charts/extra-fs-disk-io-chart.tsx b/beszel/site/src/components/charts/extra-fs-disk-io-chart.tsx index 8dc99ff..4264f1c 100644 --- a/beszel/site/src/components/charts/extra-fs-disk-io-chart.tsx +++ b/beszel/site/src/components/charts/extra-fs-disk-io-chart.tsx @@ -6,6 +6,7 @@ import { cn, formatShortDate, toFixedWithoutTrailingZeros, + twoDecimalString, useYaxisWidth, } from '@/lib/utils' // import Spinner from '../spinner' @@ -78,8 +79,8 @@ export default function ExFsDiskIoChart({ animationDuration={150} content={ formatShortDate(data[0].payload.created)} + contentFormatter={(item) => twoDecimalString(item.value) + ' MB/s'} indicator="line" /> } diff --git a/beszel/site/src/components/charts/mem-chart.tsx b/beszel/site/src/components/charts/mem-chart.tsx index 9458f4f..bb2107f 100644 --- a/beszel/site/src/components/charts/mem-chart.tsx +++ b/beszel/site/src/components/charts/mem-chart.tsx @@ -1,7 +1,14 @@ import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from 'recharts' import { ChartContainer, ChartTooltip, ChartTooltipContent } from '@/components/ui/chart' -import { chartTimeData, cn, formatShortDate, toFixedFloat, useYaxisWidth } from '@/lib/utils' +import { + chartTimeData, + cn, + formatShortDate, + toFixedFloat, + twoDecimalString, + useYaxisWidth, +} from '@/lib/utils' import { useMemo, useRef } from 'react' // import Spinner from '../spinner' import { useStore } from '@nanostores/react' @@ -71,10 +78,10 @@ export default function MemChart({ animationDuration={150} content={ a.name.localeCompare(b.name)} labelFormatter={(_, data) => formatShortDate(data[0].payload.created)} + contentFormatter={(item) => twoDecimalString(item.value) + ' GB'} indicator="line" /> } diff --git a/beszel/site/src/components/charts/swap-chart.tsx b/beszel/site/src/components/charts/swap-chart.tsx index 398427e..06d260d 100644 --- a/beszel/site/src/components/charts/swap-chart.tsx +++ b/beszel/site/src/components/charts/swap-chart.tsx @@ -6,6 +6,7 @@ import { cn, formatShortDate, toFixedWithoutTrailingZeros, + twoDecimalString, useYaxisWidth, } from '@/lib/utils' // import Spinner from '../spinner' @@ -61,8 +62,8 @@ export default function SwapChart({ animationDuration={150} content={ formatShortDate(data[0].payload.created)} + contentFormatter={(item) => twoDecimalString(item.value) + ' GB'} indicator="line" /> } diff --git a/beszel/site/src/components/charts/temperature-chart.tsx b/beszel/site/src/components/charts/temperature-chart.tsx index ba86e05..e656cd8 100644 --- a/beszel/site/src/components/charts/temperature-chart.tsx +++ b/beszel/site/src/components/charts/temperature-chart.tsx @@ -12,6 +12,7 @@ import { cn, formatShortDate, toFixedWithoutTrailingZeros, + twoDecimalString, useYaxisWidth, } from '@/lib/utils' import { useStore } from '@nanostores/react' @@ -102,8 +103,8 @@ export default function TemperatureChart({ itemSorter={(a, b) => b.value - a.value} content={ formatShortDate(data[0].payload.created)} + contentFormatter={(item) => twoDecimalString(item.value) + ' °C'} indicator="line" /> } diff --git a/beszel/site/src/components/ui/chart.tsx b/beszel/site/src/components/ui/chart.tsx index fdcb8ee..db94800 100644 --- a/beszel/site/src/components/ui/chart.tsx +++ b/beszel/site/src/components/ui/chart.tsx @@ -234,7 +234,7 @@ const ChartTooltipContent = React.forwardRef< {item.value !== undefined && ( - + {content && typeof content === 'function' ? content(item, key) : item.value.toLocaleString() + (unit ? unit : '')} diff --git a/beszel/site/src/lib/utils.ts b/beszel/site/src/lib/utils.ts index c2f15bc..0431379 100644 --- a/beszel/site/src/lib/utils.ts +++ b/beszel/site/src/lib/utils.ts @@ -239,6 +239,19 @@ export function toFixedFloat(num: number, digits: number) { return parseFloat(num.toFixed(digits)) } +let twoDecimalFormatter: Intl.NumberFormat +/** Format number to two decimal places */ +export function twoDecimalString(num: number) { + if (!twoDecimalFormatter) { + twoDecimalFormatter = new Intl.NumberFormat(undefined, { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + }) + } + // Return a function that formats numbers using the saved formatter + return twoDecimalFormatter.format(num) +} + /** Get value from local storage */ function getStorageValue(key: string, defaultValue: any) { const saved = localStorage?.getItem(key)