mirror of
https://github.com/henrygd/beszel.git
synced 2025-12-17 18:56:17 +01:00
Adds display unit preference (#938)
* Adds temperature unit preference * add unit preferences for networking * adds options for MB/s and bps. * supports disk throughput unit preferences
This commit is contained in:
@@ -9,11 +9,15 @@ import {
|
||||
toFixedWithoutTrailingZeros,
|
||||
decimalString,
|
||||
chartMargin,
|
||||
convertNetworkSpeed,
|
||||
convertDiskSpeed,
|
||||
} from "@/lib/utils"
|
||||
// import Spinner from '../spinner'
|
||||
import { ChartData } from "@/types"
|
||||
import { memo, useMemo } from "react"
|
||||
import { useLingui } from "@lingui/react/macro"
|
||||
import { useStore } from "@nanostores/react"
|
||||
import { $userSettings } from "@/lib/stores"
|
||||
|
||||
/** [label, key, color, opacity] */
|
||||
type DataKeys = [string, string, number, number]
|
||||
@@ -47,11 +51,26 @@ export default memo(function AreaChartDefault({
|
||||
}) {
|
||||
const { yAxisWidth, updateYAxisWidth } = useYAxisWidth()
|
||||
const { i18n } = useLingui()
|
||||
const userSettings = useStore($userSettings)
|
||||
|
||||
const { chartTime } = chartData
|
||||
|
||||
const showMax = chartTime !== "1h" && maxToggled
|
||||
|
||||
// Determine if this is a network chart or disk chart and adjust unit accordingly
|
||||
const isNetworkChart = chartName === "bw"
|
||||
const isDiskChart = chartName === "dio" || chartName.startsWith("efs")
|
||||
const displayUnit = useMemo(() => {
|
||||
if (isNetworkChart) {
|
||||
const { symbol } = convertNetworkSpeed(1, userSettings.networkUnit)
|
||||
return symbol
|
||||
} else if (isDiskChart) {
|
||||
const { symbol } = convertDiskSpeed(1, userSettings.diskUnit)
|
||||
return symbol
|
||||
}
|
||||
return unit
|
||||
}, [isNetworkChart, isDiskChart, userSettings.networkUnit, userSettings.diskUnit, unit])
|
||||
|
||||
const dataKeys: DataKeys[] = useMemo(() => {
|
||||
// [label, key, color, opacity]
|
||||
if (chartName === "CPU Usage") {
|
||||
@@ -102,8 +121,14 @@ export default memo(function AreaChartDefault({
|
||||
let val: string
|
||||
if (tickFormatter) {
|
||||
val = tickFormatter(value)
|
||||
} else if (isNetworkChart) {
|
||||
const { value: convertedValue, symbol } = convertNetworkSpeed(value, userSettings.networkUnit)
|
||||
val = toFixedWithoutTrailingZeros(convertedValue, 2) + symbol
|
||||
} else if (isDiskChart) {
|
||||
const { value: convertedValue, symbol } = convertDiskSpeed(value, userSettings.diskUnit)
|
||||
val = toFixedWithoutTrailingZeros(convertedValue, 2) + symbol
|
||||
} else {
|
||||
val = toFixedWithoutTrailingZeros(value, 2) + unit
|
||||
val = toFixedWithoutTrailingZeros(value, 2) + displayUnit
|
||||
}
|
||||
return updateYAxisWidth(val)
|
||||
}}
|
||||
@@ -120,8 +145,14 @@ export default memo(function AreaChartDefault({
|
||||
contentFormatter={({ value }) => {
|
||||
if (contentFormatter) {
|
||||
return contentFormatter(value)
|
||||
} else if (isNetworkChart) {
|
||||
const { display } = convertNetworkSpeed(value, userSettings.networkUnit)
|
||||
return display
|
||||
} else if (isDiskChart) {
|
||||
const { display } = convertDiskSpeed(value, userSettings.diskUnit)
|
||||
return display
|
||||
}
|
||||
return decimalString(value) + unit
|
||||
return decimalString(value) + displayUnit
|
||||
}}
|
||||
// indicator="line"
|
||||
/>
|
||||
|
||||
@@ -10,10 +10,11 @@ import {
|
||||
toFixedFloat,
|
||||
getSizeAndUnit,
|
||||
toFixedWithoutTrailingZeros,
|
||||
convertNetworkSpeed,
|
||||
} from "@/lib/utils"
|
||||
// import Spinner from '../spinner'
|
||||
import { useStore } from "@nanostores/react"
|
||||
import { $containerFilter } from "@/lib/stores"
|
||||
import { $containerFilter, $userSettings } from "@/lib/stores"
|
||||
import { ChartData } from "@/types"
|
||||
import { Separator } from "../ui/separator"
|
||||
import { ChartType } from "@/lib/enums"
|
||||
@@ -30,6 +31,7 @@ export default memo(function ContainerChart({
|
||||
unit?: string
|
||||
}) {
|
||||
const filter = useStore($containerFilter)
|
||||
const userSettings = useStore($userSettings)
|
||||
const { yAxisWidth, updateYAxisWidth } = useYAxisWidth()
|
||||
|
||||
const { containerData } = chartData
|
||||
@@ -87,10 +89,15 @@ export default memo(function ContainerChart({
|
||||
const val = toFixedWithoutTrailingZeros(value, 2) + unit
|
||||
return updateYAxisWidth(val)
|
||||
}
|
||||
} else if (isNetChart) {
|
||||
obj.tickFormatter = (value) => {
|
||||
const { value: convertedValue, symbol } = convertNetworkSpeed(value, userSettings.networkUnit)
|
||||
return updateYAxisWidth(`${toFixedFloat(convertedValue, 2)}${symbol}`)
|
||||
}
|
||||
} else {
|
||||
obj.tickFormatter = (value) => {
|
||||
const { v, u } = getSizeAndUnit(value, false)
|
||||
return updateYAxisWidth(`${toFixedFloat(v, 2)}${u}${isNetChart ? "/s" : ""}`)
|
||||
return updateYAxisWidth(`${toFixedFloat(v, 2)}${u}`)
|
||||
}
|
||||
}
|
||||
// tooltip formatter
|
||||
@@ -99,12 +106,14 @@ export default memo(function ContainerChart({
|
||||
try {
|
||||
const sent = item?.payload?.[key]?.ns ?? 0
|
||||
const received = item?.payload?.[key]?.nr ?? 0
|
||||
const { display: receivedDisplay } = convertNetworkSpeed(received, userSettings.networkUnit)
|
||||
const { display: sentDisplay } = convertNetworkSpeed(sent, userSettings.networkUnit)
|
||||
return (
|
||||
<span className="flex">
|
||||
{decimalString(received)} MB/s
|
||||
{receivedDisplay}
|
||||
<span className="opacity-70 ms-0.5"> rx </span>
|
||||
<Separator orientation="vertical" className="h-3 mx-1.5 bg-primary/40" />
|
||||
{decimalString(sent)} MB/s
|
||||
{sentDisplay}
|
||||
<span className="opacity-70 ms-0.5"> tx</span>
|
||||
</span>
|
||||
)
|
||||
|
||||
@@ -15,14 +15,16 @@ import {
|
||||
toFixedWithoutTrailingZeros,
|
||||
decimalString,
|
||||
chartMargin,
|
||||
convertTemperature,
|
||||
} from "@/lib/utils"
|
||||
import { ChartData } from "@/types"
|
||||
import { memo, useMemo } from "react"
|
||||
import { $temperatureFilter } from "@/lib/stores"
|
||||
import { $temperatureFilter, $userSettings } from "@/lib/stores"
|
||||
import { useStore } from "@nanostores/react"
|
||||
|
||||
export default memo(function TemperatureChart({ chartData }: { chartData: ChartData }) {
|
||||
const filter = useStore($temperatureFilter)
|
||||
const userSettings = useStore($userSettings)
|
||||
const { yAxisWidth, updateYAxisWidth } = useYAxisWidth()
|
||||
|
||||
if (chartData.systemStats.length === 0) {
|
||||
@@ -36,13 +38,17 @@ export default memo(function TemperatureChart({ chartData }: { chartData: ChartD
|
||||
colors: Record<string, string>
|
||||
}
|
||||
const tempSums = {} as Record<string, number>
|
||||
const unit = userSettings.temperatureUnit || "celsius"
|
||||
|
||||
for (let data of chartData.systemStats) {
|
||||
let newData = { created: data.created } as Record<string, number | string>
|
||||
let keys = Object.keys(data.stats?.t ?? {})
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
let key = keys[i]
|
||||
newData[key] = data.stats.t![key]
|
||||
tempSums[key] = (tempSums[key] ?? 0) + newData[key]
|
||||
const celsiusTemp = data.stats.t![key]
|
||||
const { value } = convertTemperature(celsiusTemp, unit)
|
||||
newData[key] = value
|
||||
tempSums[key] = (tempSums[key] ?? 0) + value
|
||||
}
|
||||
newChartData.data.push(newData)
|
||||
}
|
||||
@@ -51,7 +57,7 @@ export default memo(function TemperatureChart({ chartData }: { chartData: ChartD
|
||||
newChartData.colors[key] = `hsl(${((keys.indexOf(key) * 360) / keys.length) % 360}, 60%, 55%)`
|
||||
}
|
||||
return newChartData
|
||||
}, [chartData])
|
||||
}, [chartData, userSettings.temperatureUnit])
|
||||
|
||||
const colors = Object.keys(newChartData.colors)
|
||||
|
||||
@@ -74,7 +80,8 @@ export default memo(function TemperatureChart({ chartData }: { chartData: ChartD
|
||||
width={yAxisWidth}
|
||||
tickFormatter={(value) => {
|
||||
const val = toFixedWithoutTrailingZeros(value, 2)
|
||||
return updateYAxisWidth(val + " °C")
|
||||
const { symbol } = convertTemperature(0, userSettings.temperatureUnit || "celsius")
|
||||
return updateYAxisWidth(val + " " + symbol)
|
||||
}}
|
||||
tickLine={false}
|
||||
axisLine={false}
|
||||
@@ -88,7 +95,10 @@ export default memo(function TemperatureChart({ chartData }: { chartData: ChartD
|
||||
content={
|
||||
<ChartTooltipContent
|
||||
labelFormatter={(_, data) => formatShortDate(data[0].payload.created)}
|
||||
contentFormatter={(item) => decimalString(item.value) + " °C"}
|
||||
contentFormatter={(item) => {
|
||||
const { symbol } = convertTemperature(0, userSettings.temperatureUnit || "celsius")
|
||||
return decimalString(item.value) + " " + symbol
|
||||
}}
|
||||
filter={filter}
|
||||
/>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user