mirror of
https://github.com/fankes/beszel.git
synced 2025-10-19 01:39:34 +08:00
standardize chart values to two decimals
This commit is contained in:
@@ -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={
|
||||
<ChartTooltipContent
|
||||
unit=" MB/s"
|
||||
labelFormatter={(_, data) => formatShortDate(data[0].payload.created)}
|
||||
contentFormatter={(item) => twoDecimalString(item.value) + ' MB/s'}
|
||||
indicator="line"
|
||||
/>
|
||||
}
|
||||
|
@@ -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={<ChartTooltipContent filter={filter} unit="%" indicator="line" />}
|
||||
content={
|
||||
<ChartTooltipContent
|
||||
filter={filter}
|
||||
contentFormatter={(item) => twoDecimalString(item.value) + '%'}
|
||||
indicator="line"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
{Object.keys(chartConfig).map((key) => {
|
||||
const filtered = filter && !key.includes(filter)
|
||||
|
@@ -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={<ChartTooltipContent filter={filter} unit=" MB" indicator="line" />}
|
||||
content={
|
||||
<ChartTooltipContent
|
||||
filter={filter}
|
||||
contentFormatter={(item) => twoDecimalString(item.value) + ' MB'}
|
||||
indicator="line"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
{Object.keys(chartConfig).map((key) => {
|
||||
const filtered = filter && !key.includes(filter)
|
||||
|
@@ -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 (
|
||||
<span className="flex">
|
||||
{received.toLocaleString()} MB/s
|
||||
{twoDecimalString(received)} MB/s
|
||||
<span className="opacity-70 ml-0.5"> rx </span>
|
||||
<Separator orientation="vertical" className="h-3 mx-1.5 bg-primary/40" />
|
||||
{sent.toLocaleString()} MB/s<span className="opacity-70 ml-0.5"> tx</span>
|
||||
{twoDecimalString(sent)} MB/s<span className="opacity-70 ml-0.5"> tx</span>
|
||||
</span>
|
||||
)
|
||||
} catch (e) {
|
||||
|
@@ -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={
|
||||
<ChartTooltipContent
|
||||
unit="%"
|
||||
labelFormatter={(_, data) => formatShortDate(data[0].payload.created)}
|
||||
contentFormatter={(item) => twoDecimalString(item.value) + '%'}
|
||||
indicator="line"
|
||||
/>
|
||||
}
|
||||
|
@@ -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={
|
||||
<ChartTooltipContent
|
||||
unit=" GB"
|
||||
labelFormatter={(_, data) => formatShortDate(data[0].payload.created)}
|
||||
contentFormatter={(item) => twoDecimalString(item.value) + ' GB'}
|
||||
indicator="line"
|
||||
/>
|
||||
}
|
||||
|
@@ -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={
|
||||
<ChartTooltipContent
|
||||
unit=" MB/s"
|
||||
labelFormatter={(_, data) => formatShortDate(data[0].payload.created)}
|
||||
contentFormatter={(item) => twoDecimalString(item.value) + ' MB/s'}
|
||||
indicator="line"
|
||||
/>
|
||||
}
|
||||
|
@@ -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={
|
||||
<ChartTooltipContent
|
||||
unit=" GB"
|
||||
labelFormatter={(_, data) => formatShortDate(data[0].payload.created)}
|
||||
contentFormatter={(item) => twoDecimalString(item.value) + ' GB'}
|
||||
indicator="line"
|
||||
/>
|
||||
}
|
||||
|
@@ -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={
|
||||
<ChartTooltipContent
|
||||
unit=" MB/s"
|
||||
labelFormatter={(_, data) => formatShortDate(data[0].payload.created)}
|
||||
contentFormatter={(item) => twoDecimalString(item.value) + ' MB/s'}
|
||||
indicator="line"
|
||||
/>
|
||||
}
|
||||
|
@@ -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={
|
||||
<ChartTooltipContent
|
||||
unit=" GB"
|
||||
// @ts-ignore
|
||||
itemSorter={(a, b) => a.name.localeCompare(b.name)}
|
||||
labelFormatter={(_, data) => formatShortDate(data[0].payload.created)}
|
||||
contentFormatter={(item) => twoDecimalString(item.value) + ' GB'}
|
||||
indicator="line"
|
||||
/>
|
||||
}
|
||||
|
@@ -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={
|
||||
<ChartTooltipContent
|
||||
unit=" GB"
|
||||
labelFormatter={(_, data) => formatShortDate(data[0].payload.created)}
|
||||
contentFormatter={(item) => twoDecimalString(item.value) + ' GB'}
|
||||
indicator="line"
|
||||
/>
|
||||
}
|
||||
|
@@ -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={
|
||||
<ChartTooltipContent
|
||||
unit=" °C"
|
||||
labelFormatter={(_, data) => formatShortDate(data[0].payload.created)}
|
||||
contentFormatter={(item) => twoDecimalString(item.value) + ' °C'}
|
||||
indicator="line"
|
||||
/>
|
||||
}
|
||||
|
@@ -234,7 +234,7 @@ const ChartTooltipContent = React.forwardRef<
|
||||
</span>
|
||||
</div>
|
||||
{item.value !== undefined && (
|
||||
<span className="font-mono font-medium tabular-nums text-foreground">
|
||||
<span className="font-medium tabular-nums text-foreground">
|
||||
{content && typeof content === 'function'
|
||||
? content(item, key)
|
||||
: item.value.toLocaleString() + (unit ? unit : '')}
|
||||
|
@@ -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)
|
||||
|
Reference in New Issue
Block a user