current stats page

This commit is contained in:
mbecker20
2023-01-10 02:56:22 +00:00
parent b41486fb20
commit 662df40aaf
8 changed files with 457 additions and 298 deletions
+2 -2
View File
@@ -38,7 +38,7 @@
"scope": "typescriptreact,javascriptreact",
"prefix": "provider",
"body": [
"import { Component, createContext, useContext } from \"solid-js\";",
"import { ParentComponent, createContext, useContext } from \"solid-js\";",
"",
"const value = () => {",
"\treturn {};",
@@ -48,7 +48,7 @@
"",
"const context = createContext<Value>();",
"",
"export const Provider: Component<{}> = (p) => {",
"export const Provider: ParentComponent<{}> = (p) => {",
"\treturn (",
"\t\t<context.Provider value={value()}>",
"\t\t\t{p.children}",
+15 -6
View File
@@ -18,6 +18,7 @@ const HeatBar: Component<{
containerClass?: string;
containerStyle?: JSX.CSSProperties;
barHeight?: string;
onClick?: () => void;
}> = (p) => {
let el: HTMLDivElement;
const [width, setWidth] = createSignal<number>();
@@ -32,18 +33,26 @@ const HeatBar: Component<{
removeEventListener("resize", handleResize);
});
return (
<Flex ref={el!} gap={`${BAR_GAP}px`} class={p.containerClass} style={p.containerStyle}>
<Flex
ref={el!}
gap={`${BAR_GAP}px`}
class={p.containerClass}
style={{
cursor: p.onClick && "pointer",
...p.containerStyle,
}}
onClick={p.onClick}
>
<For each={[...Array(p.total).keys()]}>
{(index) => (
<div
style={{
height: p.barHeight || "2rem",
width: `${width()!}px`,
"background-color": index <= p.filled ? blendColors(
BLUE,
RED,
index / p.total
) : "transparent",
"background-color":
index <= p.filled
? blendColors(BLUE, RED, index / p.total)
: "transparent",
}}
/>
)}
@@ -26,9 +26,12 @@ type LineDataPoint = {
};
const LightweightChart: Component<{
style?: JSX.CSSProperties;
class?: string;
lines?: () => LinesData[];
class?: string;
style?: JSX.CSSProperties;
width?: string;
height?: string;
disableScroll?: boolean
}> = (p) => {
let el: HTMLDivElement;
const [chart, setChart] = createSignal<IChartApi>();
@@ -49,8 +52,8 @@ const LightweightChart: Component<{
vertLines: { color: "#3f454d" },
},
timeScale: { timeVisible: true },
// handleScroll: false,
// handleScale: false,
handleScroll: p.disableScroll ? false : true,
handleScale: p.disableScroll ? false : true,
});
chart.timeScale().fitContent();
setChart(chart);
@@ -64,11 +67,12 @@ const LightweightChart: Component<{
const series = chart()!.addLineSeries({
color: line.color,
title: line.title,
priceLineVisible: line.priceLineVisible || false
priceLineVisible: line.priceLineVisible || false,
});
series.setData(line.line as any);
return series;
});
chart()!.timeScale().fitContent();
lineSeries = series;
}
});
@@ -86,7 +90,11 @@ const LightweightChart: Component<{
<div
ref={el!}
class={p.class}
style={{ width: "100%", height: "100%", ...p.style }}
style={{
width: p.width || "100%",
height: p.height || "100%",
...p.style,
}}
/>
);
};
+359
View File
@@ -0,0 +1,359 @@
import { Accessor, Component, createSignal, For, Show } from "solid-js";
import { SystemStats, SystemStatsRecord } from "../../types";
import {
convertTsMsToLocalUnixTsInSecs,
get_to_one_sec_divisor,
} from "../../util/helpers";
import Flex from "../shared/layout/Flex";
import Grid from "../shared/layout/Grid";
import LightweightChart from "../shared/LightweightChart";
import s from "./stats.module.scss";
export const COLORS = {
blue: "#184e9f",
orange: "#ac5c36",
purple: "#5A0B4D",
green: "#41764c",
red: "#952E23",
};
const CHART_HEIGHT = "200px";
const SMALL_CHART_HEIGHT = "150px";
export const CpuChart: Component<{
stats: Accessor<(SystemStatsRecord | SystemStats)[] | undefined>;
small?: boolean;
disableScroll?: boolean;
}> = (p) => {
const line = () => {
return p.stats()?.map((s) => {
return {
time: convertTsMsToLocalUnixTsInSecs(
(s as SystemStatsRecord).ts || (s as SystemStats).refresh_ts
),
value: s.cpu_perc,
};
});
};
return (
<Show when={line()}>
<Grid
gap="0"
class="card shadow"
style={{
height: "fit-content",
width: "100%",
"box-sizing": "border-box",
"padding-bottom": "0.2rem",
}}
>
<Show when={!p.small}>
<h2>cpu</h2>
</Show>
<LightweightChart
class={s.LightweightChart}
height={p.small ? SMALL_CHART_HEIGHT : CHART_HEIGHT}
lines={() => [{ title: "%", color: COLORS.blue, line: line()! }]}
disableScroll={p.disableScroll}
/>
</Grid>
</Show>
);
};
export const MemChart: Component<{
stats: Accessor<(SystemStatsRecord | SystemStats)[] | undefined>;
small?: boolean;
disableScroll?: boolean;
}> = (p) => {
const line = () => {
return p.stats()?.map((s) => {
return {
time: convertTsMsToLocalUnixTsInSecs(
(s as SystemStatsRecord).ts || (s as SystemStats).refresh_ts
),
value: (100 * s.mem_used_gb) / s.mem_total_gb,
};
});
};
return (
<Show when={line()}>
<Grid
gap="0"
class="card shadow"
style={{
height: "fit-content",
width: "100%",
"box-sizing": "border-box",
"padding-bottom": "0.2rem",
}}
>
<Show when={!p.small}>
<h2>memory</h2>
</Show>
<LightweightChart
class={s.LightweightChart}
height={p.small ? SMALL_CHART_HEIGHT : CHART_HEIGHT}
lines={() => [{ title: "mem %", color: COLORS.blue, line: line()! }]}
disableScroll={p.disableScroll}
/>
</Grid>
</Show>
);
};
export const DiskChart: Component<{
stats: Accessor<(SystemStatsRecord | SystemStats)[] | undefined>;
small?: boolean;
disableScroll?: boolean;
}> = (p) => {
const line = () => {
return p.stats()?.map((s) => {
return {
time: convertTsMsToLocalUnixTsInSecs(
(s as SystemStatsRecord).ts || (s as SystemStats).refresh_ts
),
value: (100 * s.disk.used_gb) / s.disk.total_gb,
};
});
};
return (
<Show when={line()}>
<Grid
gap="0"
class="card shadow"
style={{
height: "fit-content",
width: "100%",
"box-sizing": "border-box",
"padding-bottom": "0.2rem",
}}
>
<Show when={!p.small}>
<h2>disk</h2>
</Show>
<LightweightChart
class={s.LightweightChart}
height={p.small ? SMALL_CHART_HEIGHT : CHART_HEIGHT}
lines={() => [{ title: "disk %", color: "#184e9f", line: line()! }]}
disableScroll={p.disableScroll}
/>
</Grid>
</Show>
);
};
export const NetworkIoCharts: Component<{
stats: Accessor<(SystemStatsRecord | SystemStats)[] | undefined>;
small?: boolean;
disableScroll?: boolean;
}> = (p) => {
const recv_line = () => {
return p.stats()?.map((s) => {
return {
time: convertTsMsToLocalUnixTsInSecs(
(s as SystemStatsRecord).ts || (s as SystemStats).refresh_ts
),
value:
s.networks?.length || 0 > 0
? s.networks!.map((n) => n.recieved_kb).reduce((p, c) => p + c) /
get_to_one_sec_divisor(s.polling_rate)!
: 0,
};
});
};
const trans_line = () => {
return p.stats()?.map((s) => {
return {
time: convertTsMsToLocalUnixTsInSecs(
(s as SystemStatsRecord).ts || (s as SystemStats).refresh_ts
),
value:
s.networks?.length || 0 > 0
? s.networks!.map((n) => n.transmitted_kb).reduce((p, c) => p + c) /
get_to_one_sec_divisor(s.polling_rate)!
: 0,
};
});
};
return (
<Show when={recv_line()}>
<Grid
gap="0"
class="card shadow"
style={{
height: "fit-content",
width: "100%",
"box-sizing": "border-box",
"padding-bottom": "0.2rem",
}}
>
<Show when={!p.small}>
<h2>network sent kb/s</h2>
</Show>
<LightweightChart
class={s.LightweightChart}
height={p.small ? SMALL_CHART_HEIGHT : CHART_HEIGHT}
lines={() => [
{ title: "sent kb/s", color: "#184e9f", line: trans_line()! },
]}
/>
</Grid>
<Grid
gap="0"
class="card shadow"
style={{
height: "fit-content",
width: "100%",
"box-sizing": "border-box",
"padding-bottom": "0.2rem",
}}
>
<Show when={!p.small}>
<h2>network received kb/s</h2>
</Show>
<LightweightChart
class={s.LightweightChart}
height={p.small ? SMALL_CHART_HEIGHT : CHART_HEIGHT}
lines={() => [
{ title: "recv kb/s", color: "#184e9f", line: recv_line()! },
]}
disableScroll={p.disableScroll}
/>
</Grid>
</Show>
);
};
export const DiskIoCharts: Component<{
stats: Accessor<(SystemStatsRecord | SystemStats)[] | undefined>;
small?: boolean;
disableScroll?: boolean;
}> = (p) => {
const read_line = () => {
return p.stats()?.map((s) => {
return {
time: convertTsMsToLocalUnixTsInSecs(
(s as SystemStatsRecord).ts || (s as SystemStats).refresh_ts
),
value:
s.disk.disks?.length || 0 > 0
? s.disk.read_kb / get_to_one_sec_divisor(s.polling_rate)!
: 0,
};
});
};
const write_line = () => {
return p.stats()?.map((s) => {
return {
time: convertTsMsToLocalUnixTsInSecs(
(s as SystemStatsRecord).ts || (s as SystemStats).refresh_ts
),
value:
s.disk.disks?.length || 0 > 0
? s.disk.write_kb / get_to_one_sec_divisor(s.polling_rate)!
: 0,
};
});
};
return (
<Show when={read_line()}>
<Grid
gap="0"
class="card shadow"
style={{
height: "fit-content",
width: "100%",
"box-sizing": "border-box",
"padding-bottom": "0.2rem",
}}
>
<Show when={!p.small}>
<h2>disk read kb/s</h2>
</Show>
<LightweightChart
class={s.LightweightChart}
height={p.small ? SMALL_CHART_HEIGHT : CHART_HEIGHT}
lines={() => [
{ title: "kb/s", color: "#184e9f", line: read_line()! },
]}
/>
</Grid>
<Grid
gap="0"
class="card shadow"
style={{
height: "fit-content",
width: "100%",
"box-sizing": "border-box",
"padding-bottom": "0.2rem",
}}
>
<h2>disk write kb/s</h2>
<LightweightChart
class={s.LightweightChart}
height={p.small ? SMALL_CHART_HEIGHT : CHART_HEIGHT}
lines={() => [
{ title: "kb/s", color: "#184e9f", line: write_line()! },
]}
disableScroll={p.disableScroll}
/>
</Grid>
</Show>
);
};
export const TempuratureChart: Component<{
stats: Accessor<(SystemStatsRecord | SystemStats)[] | undefined>;
small?: boolean;
disableScroll?: boolean;
}> = (p) => {
// const [selected, setSelected] = createSignal(p.stats()![p.stats()!.length - 1].components![0].label);
const labels = () => {
return p.stats()![p.stats()!.length - 1].components!.map((c) => c.label);
};
const line = (component: string) => {
return p.stats()?.map((s) => {
const temp = s.components!.find((c) => c.label === component)?.temp;
return {
time: convertTsMsToLocalUnixTsInSecs(
(s as SystemStatsRecord).ts || (s as SystemStats).refresh_ts
),
value: temp || 0,
};
});
};
return (
<For each={labels()}>
{(label) => (
<Grid
gap="0"
class="card shadow"
style={{
height: "fit-content",
width: "100%",
"box-sizing": "border-box",
"padding-bottom": "0.2rem",
}}
>
<Flex alignItems="center" justifyContent="space-between">
<h2>{label}</h2>
{/* <Selector
selected={selected()}
items={labels()}
onSelect={setSelected}
/> */}
</Flex>
<LightweightChart
class={s.LightweightChart}
height={p.small ? SMALL_CHART_HEIGHT : CHART_HEIGHT}
lines={() => [
{ title: "temp", color: "#184e9f", line: line(label)! },
]}
disableScroll={p.disableScroll}
/>
</Grid>
)}
</For>
);
};
+60 -15
View File
@@ -8,18 +8,32 @@ import {
Setter,
Show,
} from "solid-js";
import { createStore } from "solid-js/store";
import { client, URL } from "../..";
import { SystemStats } from "../../types";
import { combineClasses, generateQuery } from "../../util/helpers";
import { generateQuery } from "../../util/helpers";
import { useLocalStorage } from "../../util/hooks";
import HeatBar from "../shared/HeatBar";
import Flex from "../shared/layout/Flex";
import Grid from "../shared/layout/Grid";
import Loading from "../shared/loading/Loading";
import { CpuChart, DiskChart, MemChart } from "./Charts";
import s from "./stats.module.scss";
const CurrentStats: Component<{}> = (p) => {
const params = useParams();
const [stats, setStats] = createSignal<SystemStats>();
const [showCpuGraph, setShowCpuGraph] = useLocalStorage(
false,
"current-stats-cpu-graph-v1"
);
const [showMemGraph, setShowMemGraph] = useLocalStorage(
false,
"current-stats-mem-graph-v1"
);
const [showDiskGraph, setShowDiskGraph] = useLocalStorage(
false,
"current-stats-disk-graph-v1"
);
const [stats, setStats] = createSignal<SystemStats[]>([]);
const open = useStatsWs(params, setStats);
createEffect(() => {
client
@@ -28,54 +42,82 @@ const CurrentStats: Component<{}> = (p) => {
components: true,
processes: true,
})
.then(setStats);
.then((stats) => setStats([stats]));
});
const mem_perc = () => {
return (100 * stats()!.mem_used_gb) / stats()!.mem_total_gb;
return (
(100 * stats()[stats()!.length - 1].mem_used_gb) /
stats()![stats().length - 1].mem_total_gb
);
};
const disk_perc = () => {
return (100 * stats()!.disk.used_gb) / stats()!.disk.total_gb;
return (
(100 * stats()[stats().length - 1].disk.used_gb) /
stats()![stats().length - 1].disk.total_gb
);
};
return (
<Grid class={s.Content} placeItems="start center">
<Show when={stats()} fallback={<Loading type="three-dot" />}>
<Show when={stats().length > 0} fallback={<Loading type="three-dot" />}>
<Grid class={s.HeatBars} placeItems="center start">
<div />
<h1>basic</h1>
<div />
<h1>cpu:</h1>
<HeatBar
containerClass="card shadow"
containerStyle={{ width: "60vw", "min-width": "300px" }}
filled={Math.floor(stats()!.cpu_perc)}
filled={Math.floor(stats()[stats().length - 1].cpu_perc)}
total={100}
onClick={() => setShowCpuGraph((curr) => !curr)}
/>
<h1>{stats()!.cpu_perc.toFixed(1)}%</h1>
<h1>{stats()[stats().length - 1].cpu_perc.toFixed(1)}%</h1>
<Show when={showCpuGraph()}>
<div />
<CpuChart stats={stats} small disableScroll />
<div />
</Show>
<h1>mem:</h1>
<HeatBar
containerClass="card shadow"
containerStyle={{ width: "60vw", "min-width": "300px" }}
filled={Math.floor(mem_perc())}
total={100}
onClick={() => setShowMemGraph((curr) => !curr)}
/>
<Grid gap="0">
<h1>{mem_perc().toFixed(1)}%</h1>
<div style={{ opacity: 0.7 }}>
{stats()!.mem_used_gb.toFixed()}GB of{" "}
{stats()!.mem_total_gb.toFixed()}GB
{stats()[stats().length - 1].mem_used_gb.toFixed()}GB of{" "}
{stats()[stats().length - 1].mem_total_gb.toFixed()}GB
</div>
</Grid>
<Show when={showMemGraph()}>
<div />
<MemChart stats={stats} small disableScroll />
<div />
</Show>
<h1>disk:</h1>
<HeatBar
containerClass="card shadow"
containerStyle={{ width: "60vw", "min-width": "300px" }}
filled={Math.floor(disk_perc())}
total={100}
onClick={() => setShowDiskGraph(curr => !curr)}
/>
<Grid gap="0">
<h1>{disk_perc().toFixed(1)}%</h1>
<div style={{ opacity: 0.7 }}>
{stats()!.disk.used_gb.toFixed()}GB of{" "}
{stats()!.disk.total_gb.toFixed()}GB
{stats()[stats().length - 1].disk.used_gb.toFixed()}GB of{" "}
{stats()[stats().length - 1].disk.total_gb.toFixed()}GB
</div>
</Grid>
<Show when={showDiskGraph()}>
<div />
<DiskChart stats={stats} small disableScroll />
<div />
</Show>
</Grid>
</Show>
</Grid>
@@ -84,7 +126,7 @@ const CurrentStats: Component<{}> = (p) => {
export default CurrentStats;
function useStatsWs(params: Params, setStats: Setter<SystemStats>) {
function useStatsWs(params: Params, setStats: Setter<SystemStats[]>) {
const ws = new ReconnectingWebSocket(
`${URL.replace("http", "ws")}/ws/stats/${params.id}${generateQuery({
networks: "true",
@@ -105,7 +147,10 @@ function useStatsWs(params: Params, setStats: Setter<SystemStats>) {
}
const stats = JSON.parse(data) as SystemStats;
// console.log(stats);
setStats(stats);
setStats((stats_arr) => [
...(stats_arr.length > 200 ? stats_arr.slice(1) : stats_arr),
stats,
]);
});
ws.addEventListener("close", () => {
console.log("stats connection closed");
@@ -1,15 +1,14 @@
import { useParams } from "@solidjs/router";
import { Accessor, Component, createEffect, createSignal, For, Match, Show, Switch } from "solid-js";
import { Component, createEffect, createSignal, Match, Show, Switch } from "solid-js";
import { client } from "../..";
import { SystemStatsRecord, Timelength } from "../../types";
import { convertTsMsToLocalUnixTsInSecs, get_to_one_sec_divisor } from "../../util/helpers";
import { useLocalStorage } from "../../util/hooks";
import Icon from "../shared/Icon";
import Flex from "../shared/layout/Flex";
import Grid from "../shared/layout/Grid";
import LightweightChart from "../shared/LightweightChart";
import Loading from "../shared/loading/Loading";
import Selector from "../shared/menu/Selector";
import { CpuChart, DiskChart, DiskIoCharts, MemChart, NetworkIoCharts, TempuratureChart } from "./Charts";
import s from "./stats.module.scss";
const TIMELENGTHS = [
@@ -22,13 +21,7 @@ const TIMELENGTHS = [
Timelength.OneDay,
];
const COLORS = {
blue: "#184e9f",
orange: "#ac5c36",
purple: "#5A0B4D",
green: "#41764c",
red: "#952E23",
};
const VIEWS = [
"basic",
@@ -58,7 +51,7 @@ const HistoricalStats: Component<{}> = (p) => {
});
return (
<Grid class={s.Content}>
<Flex alignItems="center">
<Flex alignItems="center" justifyContent="center">
<Flex class="card light shadow" alignItems="center">
<button
class="darkgrey"
@@ -115,8 +108,8 @@ const HistoricalStats: Component<{}> = (p) => {
</Match>
<Match when={view() === "i / o"}>
<Grid class={s.Charts}>
<DiskIoCharts stats={stats} />
<NetworkIoCharts stats={stats} />
<DiskIoCharts stats={stats} />
</Grid>
</Match>
<Match when={view() === "temp"}>
@@ -130,259 +123,4 @@ const HistoricalStats: Component<{}> = (p) => {
);
};
const CpuChart: Component<{
stats: Accessor<SystemStatsRecord[] | undefined>;
}> = (p) => {
const line = () => {
return p.stats()?.map((s) => {
return {
time: convertTsMsToLocalUnixTsInSecs(s.ts),
value: s.cpu_perc,
};
});
};
return (
<Show when={line()}>
<Grid gap="0" class="card shadow" style={{ height: "fit-content" }}>
<h2>cpu</h2>
<LightweightChart
class={s.LightweightChart}
style={{ height: "200px" }}
lines={() => [{ title: "%", color: COLORS.blue, line: line()! }]}
/>
</Grid>
</Show>
);
};
const MemChart: Component<{
stats: Accessor<SystemStatsRecord[] | undefined>;
}> = (p) => {
const [selected, setSelected] = createSignal("%");
const line = () => {
return p.stats()?.map((s) => {
return {
time: convertTsMsToLocalUnixTsInSecs(s.ts),
value:
selected() === "%"
? (100 * s.mem_used_gb) / s.mem_total_gb
: s.mem_used_gb,
};
});
};
return (
<Show when={line()}>
<Grid gap="0" class="card shadow" style={{ height: "fit-content" }}>
<Flex alignItems="center" justifyContent="space-between">
<h2>memory</h2>
{/* <Selector
selected={selected()}
items={["%", "GB"]}
onSelect={setSelected}
/> */}
</Flex>
<LightweightChart
class={s.LightweightChart}
style={{ height: "200px" }}
lines={() => [{ title: selected(), color: COLORS.blue, line: line()! }]}
/>
</Grid>
</Show>
);
};
const DiskChart: Component<{
stats: Accessor<SystemStatsRecord[] | undefined>;
}> = (p) => {
const [selected, setSelected] = createSignal("%");
const line = () => {
return p.stats()?.map((s) => {
return {
time: convertTsMsToLocalUnixTsInSecs(s.ts),
value:
selected() === "%"
? (100 * s.disk.used_gb) / s.disk.total_gb
: s.disk.used_gb,
};
});
};
return (
<Show when={line()}>
<Grid gap="0" class="card shadow" style={{ height: "fit-content" }}>
<Flex alignItems="center" justifyContent="space-between">
<h2>disk</h2>
{/* <Selector
selected={selected()}
items={["%", "GB"]}
onSelect={setSelected}
/> */}
</Flex>
<LightweightChart
class={s.LightweightChart}
style={{ height: "200px" }}
lines={() => [{ title: selected(), color: "#184e9f", line: line()! }]}
/>
</Grid>
</Show>
);
};
const NetworkIoCharts: Component<{
stats: Accessor<SystemStatsRecord[] | undefined>;
}> = (p) => {
const recv_line = () => {
return p.stats()?.map((s) => {
return {
time: convertTsMsToLocalUnixTsInSecs(s.ts),
value:
s.networks?.length || 0 > 0
? s.networks!.map((n) => n.recieved_kb).reduce((p, c) => p + c) /
get_to_one_sec_divisor(s.polling_rate)!
: 0,
};
});
};
const trans_line = () => {
return p.stats()?.map((s) => {
return {
time: convertTsMsToLocalUnixTsInSecs(s.ts),
value:
s.networks?.length || 0 > 0
? s.networks!.map((n) => n.transmitted_kb).reduce((p, c) => p + c) /
get_to_one_sec_divisor(s.polling_rate)!
: 0,
};
});
};
return (
<Show when={recv_line()}>
<Grid gap="0" class="card shadow" style={{ height: "fit-content" }}>
<Flex alignItems="center" justifyContent="space-between">
<h2>network sent kb/s</h2>
</Flex>
<LightweightChart
class={s.LightweightChart}
style={{ height: "200px" }}
lines={() => [
{ title: "kb/s", color: "#184e9f", line: trans_line()! },
]}
/>
</Grid>
<Grid gap="0" class="card shadow" style={{ height: "fit-content" }}>
<Flex alignItems="center" justifyContent="space-between">
<h2>network received kb/s</h2>
</Flex>
<LightweightChart
class={s.LightweightChart}
style={{ height: "200px" }}
lines={() => [
{ title: "kb/s", color: "#184e9f", line: recv_line()! },
]}
/>
</Grid>
</Show>
);
};
const DiskIoCharts: Component<{
stats: Accessor<SystemStatsRecord[] | undefined>;
}> = (p) => {
const read_line = () => {
return p.stats()?.map((s) => {
return {
time: convertTsMsToLocalUnixTsInSecs(s.ts),
value:
s.disk.disks?.length || 0 > 0
? s.disk.read_kb /
get_to_one_sec_divisor(s.polling_rate)!
: 0,
};
});
};
const write_line = () => {
return p.stats()?.map((s) => {
return {
time: convertTsMsToLocalUnixTsInSecs(s.ts),
value:
s.disk.disks?.length || 0 > 0
? s.disk.write_kb / get_to_one_sec_divisor(s.polling_rate)!
: 0,
};
});
};
return (
<Show when={read_line()}>
<Grid gap="0" class="card shadow" style={{ height: "fit-content" }}>
<Flex alignItems="center" justifyContent="space-between">
<h2>disk read kb/s</h2>
</Flex>
<LightweightChart
class={s.LightweightChart}
style={{ height: "200px" }}
lines={() => [
{ title: "kb/s", color: "#184e9f", line: read_line()! },
]}
/>
</Grid>
<Grid gap="0" class="card shadow" style={{ height: "fit-content" }}>
<Flex alignItems="center" justifyContent="space-between">
<h2>disk write kb/s</h2>
</Flex>
<LightweightChart
class={s.LightweightChart}
style={{ height: "200px" }}
lines={() => [
{ title: "kb/s", color: "#184e9f", line: write_line()! },
]}
/>
</Grid>
</Show>
);
};
const TempuratureChart: Component<{
stats: Accessor<SystemStatsRecord[] | undefined>;
}> = (p) => {
// const [selected, setSelected] = createSignal(p.stats()![p.stats()!.length - 1].components![0].label);
const labels = () => {
return p.stats()![p.stats()!.length - 1].components!.map((c) => c.label);
};
const line = (component: string) => {
return p.stats()?.map((s) => {
const temp = s.components!.find((c) => c.label === component)?.temp;
return {
time: convertTsMsToLocalUnixTsInSecs(s.ts),
value: temp || 0,
};
});
};
return (
<For each={labels()}>
{(label) => (
<Grid
gap="0"
class="card shadow"
style={{ height: "fit-content" }}
>
<Flex alignItems="center" justifyContent="space-between">
<h2>{label}</h2>
{/* <Selector
selected={selected()}
items={labels()}
onSelect={setSelected}
/> */}
</Flex>
<LightweightChart
class={s.LightweightChart}
style={{ height: "200px" }}
lines={() => [
{ title: "temp", color: "#184e9f", line: line(label)! },
]}
/>
</Grid>
)}
</For>
);
};
export default HistoricalStats;
+1 -1
View File
@@ -18,7 +18,7 @@ const Stats: Component<{}> = (p) => {
const [view, setView] = useLocalStorage("current", "stats-view-v1");
return (
<Grid class={s.Content}>
<Flex alignItems="center">
<Flex alignItems="center" justifyContent="space-between">
<Header />
<Selector
targetClass="grey"
@@ -1,7 +1,7 @@
@use "../../style/colors.scss" as c;
.Charts {
grid-template-columns: repeat(auto-fit, minmax(520px, 1fr));
grid-template-columns: repeat(auto-fit, minmax(600px, 1fr));
}
.LightweightChart {