import { makeTimer } from '@solid-primitives/timer' import type { ApexOptions } from 'apexcharts' import byteSize from 'byte-size' import { merge } from 'lodash' import { SolidApexCharts } from 'solid-apexcharts' import { JSX, ParentComponent, batch, children, createEffect, createMemo, createSignal, } from 'solid-js' import { CHART_MAX_XAXIS, DEFAULT_CHART_OPTIONS } from '~/constants' import { useI18n } from '~/i18n' import { latestConnectionMsg, useWsRequest } from '~/signals' const TrafficWidget: ParentComponent<{ label: JSX.Element }> = (props) => (
{props.label}
{children(() => props.children)()}
) export default () => { const [t] = useI18n() const [traffics, setTraffics] = createSignal<{ down: number; up: number }[]>( [], ) const [memories, setMemories] = createSignal([]) // https://github.com/apexcharts/apexcharts.js/blob/main/samples/source/line/realtime.xml // TODO: needs a better way makeTimer( () => { 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, ) const traffic = useWsRequest<{ down: number; up: number }>('traffic') createEffect(() => { const t = traffic() if (t) setTraffics((traffics) => [...traffics, t]) }) const trafficChartOptions = createMemo(() => merge({ title: { text: t('traffic') } }, DEFAULT_CHART_OPTIONS), ) const trafficChartSeries = createMemo(() => [ { name: t('down'), data: traffics().map((t) => t.down), }, { name: t('up'), data: traffics().map((t) => t.up), }, ]) const memory = useWsRequest<{ inuse: number }>('memory') createEffect(() => { const m = memory()?.inuse if (m) setMemories((memories) => [...memories, m]) }) const memoryChartOptions = createMemo(() => merge({ title: { text: t('memory') } }, DEFAULT_CHART_OPTIONS), ) const memoryChartSeries = createMemo(() => [ { name: t('memory'), data: memories() }, ]) return (
{byteSize(traffic()?.up || 0).toString()}/s {byteSize(traffic()?.down || 0).toString()}/s {byteSize(latestConnectionMsg()?.uploadTotal || 0).toString()} {byteSize(latestConnectionMsg()?.downloadTotal || 0).toString()} {latestConnectionMsg()?.connections?.length || 0} {byteSize(memory()?.inuse || 0).toString()}
) }