metacubexd/src/pages/Overview.tsx

136 lines
3.8 KiB
TypeScript
Raw Normal View History

2023-09-01 23:57:58 +08:00
import { useI18n } from '@solid-primitives/i18n'
import { makeTimer } from '@solid-primitives/timer'
import type { ApexOptions } from 'apexcharts'
2023-08-24 04:20:53 +08:00
import byteSize from 'byte-size'
import { merge } from 'lodash'
2023-08-24 04:20:53 +08:00
import { SolidApexCharts } from 'solid-apexcharts'
import {
JSX,
ParentComponent,
2023-09-17 03:15:14 +08:00
batch,
children,
createEffect,
createMemo,
createSignal,
} from 'solid-js'
import { CHART_MAX_XAXIS, DEFAULT_CHART_OPTIONS } from '~/constants'
2023-09-08 13:39:51 +08:00
import { latestConnectionMsg, useWsRequest } from '~/signals'
2023-08-24 04:20:53 +08:00
const TrafficWidget: ParentComponent<{ label: JSX.Element }> = (props) => (
<div class="stat flex-1 place-items-center">
<div class="stat-title text-primary-content">{props.label}</div>
<div class="stat-value text-2xl text-primary-content lg:text-3xl">
{children(() => props.children)()}
</div>
</div>
)
export default () => {
2023-09-01 23:57:58 +08:00
const [t] = useI18n()
2023-09-02 00:15:19 +08:00
2023-08-24 04:20:53 +08:00
const [traffics, setTraffics] = createSignal<{ down: number; up: number }[]>(
[],
)
const [memories, setMemories] = createSignal<number[]>([])
// https://github.com/apexcharts/apexcharts.js/blob/main/samples/source/line/realtime.xml
// TODO: needs a better way
makeTimer(
() => {
2023-09-17 03:15:14 +08:00
batch(() => {
setTraffics((traffics) => traffics.slice(-CHART_MAX_XAXIS))
setMemories((memo) => memo.slice(-CHART_MAX_XAXIS))
})
},
// we shrink the chart data array size down every minute to prevent memory leaks
60 * 1000,
setInterval,
)
2023-09-06 19:33:07 +08:00
const traffic = useWsRequest<{ down: number; up: number }>('traffic')
2023-08-24 04:20:53 +08:00
createEffect(() => {
const t = traffic()
if (t) setTraffics((traffics) => [...traffics, t])
2023-08-24 04:20:53 +08:00
})
const trafficChartOptions = createMemo<ApexOptions>(() =>
merge({ title: { text: t('traffic') } }, DEFAULT_CHART_OPTIONS),
)
2023-08-24 04:20:53 +08:00
const trafficChartSeries = createMemo(() => [
{
2023-09-02 00:15:19 +08:00
name: t('down'),
2023-08-24 04:20:53 +08:00
data: traffics().map((t) => t.down),
},
{
2023-09-02 00:15:19 +08:00
name: t('up'),
2023-08-24 04:20:53 +08:00
data: traffics().map((t) => t.up),
},
])
2023-09-06 19:33:07 +08:00
const memory = useWsRequest<{ inuse: number }>('memory')
2023-08-24 04:20:53 +08:00
createEffect(() => {
2023-09-06 19:33:07 +08:00
const m = memory()?.inuse
2023-08-24 04:20:53 +08:00
if (m) setMemories((memories) => [...memories, m])
2023-08-24 04:20:53 +08:00
})
const memoryChartOptions = createMemo<ApexOptions>(() =>
merge({ title: { text: t('memory') } }, DEFAULT_CHART_OPTIONS),
)
2023-08-24 04:20:53 +08:00
const memoryChartSeries = createMemo(() => [
{ name: t('memory'), data: memories() },
])
2023-08-24 04:20:53 +08:00
return (
<div class="flex flex-col gap-2">
<div class="stats stats-vertical w-full grid-cols-2 bg-primary shadow lg:stats-horizontal lg:flex">
2023-09-02 00:15:19 +08:00
<TrafficWidget label={t('upload')}>
{byteSize(traffic()?.up || 0).toString()}/s
</TrafficWidget>
2023-09-02 00:15:19 +08:00
<TrafficWidget label={t('download')}>
{byteSize(traffic()?.down || 0).toString()}/s
</TrafficWidget>
2023-09-02 00:15:19 +08:00
<TrafficWidget label={t('uploadTotal')}>
2023-09-08 13:39:51 +08:00
{byteSize(latestConnectionMsg()?.uploadTotal || 0).toString()}
</TrafficWidget>
2023-09-02 00:15:19 +08:00
<TrafficWidget label={t('downloadTotal')}>
2023-09-08 13:39:51 +08:00
{byteSize(latestConnectionMsg()?.downloadTotal || 0).toString()}
</TrafficWidget>
2023-09-02 00:15:19 +08:00
<TrafficWidget label={t('activeConnections')}>
{latestConnectionMsg()?.connections?.length || 0}
</TrafficWidget>
2023-09-02 00:15:19 +08:00
<TrafficWidget label={t('memoryUsage')}>
2023-09-06 19:33:07 +08:00
{byteSize(memory()?.inuse || 0).toString()}
</TrafficWidget>
2023-08-24 04:20:53 +08:00
</div>
<div class="rounded-box flex flex-col gap-2 bg-base-300 py-4 lg:flex-row">
<div class="flex-1">
2023-09-02 13:50:24 +08:00
<SolidApexCharts
type="area"
options={trafficChartOptions()}
series={trafficChartSeries()}
/>
</div>
<div class="flex-1">
2023-09-02 13:50:24 +08:00
<SolidApexCharts
type="line"
options={memoryChartOptions()}
series={memoryChartSeries()}
/>
</div>
2023-08-24 04:20:53 +08:00
</div>
</div>
)
}