realtime current stats heatbar

This commit is contained in:
mbecker20
2023-01-09 07:47:00 +00:00
parent 6acbc19c6a
commit b41486fb20
3 changed files with 133 additions and 8 deletions

View File

@@ -0,0 +1,66 @@
import {
Component,
createSignal,
For,
JSX,
onCleanup,
onMount,
} from "solid-js";
import Flex from "./layout/Flex";
const BAR_GAP = 4;
const BLUE: [number, number, number] = [24, 78, 159];
const RED: [number, number, number] = [149, 46, 35];
const HeatBar: Component<{
total: number;
filled: number;
containerClass?: string;
containerStyle?: JSX.CSSProperties;
barHeight?: string;
}> = (p) => {
let el: HTMLDivElement;
const [width, setWidth] = createSignal<number>();
const handleResize = () => {
if (el) {
setWidth((el.clientWidth - (p.total - 1) * BAR_GAP) / p.total);
}
};
onMount(() => handleResize());
addEventListener("resize", handleResize);
onCleanup(() => {
removeEventListener("resize", handleResize);
});
return (
<Flex ref={el!} gap={`${BAR_GAP}px`} class={p.containerClass} style={p.containerStyle}>
<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",
}}
/>
)}
</For>
</Flex>
);
};
export default HeatBar;
function blendColors(
[r1, g1, b1]: [number, number, number],
[r2, b2, g2]: [number, number, number],
perc: number /* 0-1 */
) {
const r = Math.floor(r1 + (r2 - r1) * perc);
const g = Math.floor(g1 + (g2 - g1) * perc);
const b = Math.floor(b1 + (b2 - b1) * perc);
return `rgb(${r},${g},${b})`;
}

View File

@@ -1,11 +1,20 @@
import { Params, useParams } from "@solidjs/router";
import ReconnectingWebSocket from "reconnecting-websocket";
import { Component, createEffect, createSignal, Setter } from "solid-js";
import {
Component,
createEffect,
createSignal,
onCleanup,
Setter,
Show,
} from "solid-js";
import { client, URL } from "../..";
import { SystemStats } from "../../types";
import { generateQuery } from "../../util/helpers";
import { combineClasses, generateQuery } from "../../util/helpers";
import HeatBar from "../shared/HeatBar";
import Flex from "../shared/layout/Flex";
import Grid from "../shared/layout/Grid";
import Loading from "../shared/loading/Loading";
import s from "./stats.module.scss";
const CurrentStats: Component<{}> = (p) => {
@@ -21,12 +30,54 @@ const CurrentStats: Component<{}> = (p) => {
})
.then(setStats);
});
const mem_perc = () => {
return (100 * stats()!.mem_used_gb) / stats()!.mem_total_gb;
};
const disk_perc = () => {
return (100 * stats()!.disk.used_gb) / stats()!.disk.total_gb;
};
return (
<Grid class={s.Content}>
<Flex>
<div>cpu:</div>
<h2>{}</h2>
</Flex>
<Grid class={s.Content} placeItems="start center">
<Show when={stats()} fallback={<Loading type="three-dot" />}>
<Grid class={s.HeatBars} placeItems="center start">
<h1>cpu:</h1>
<HeatBar
containerClass="card shadow"
containerStyle={{ width: "60vw", "min-width": "300px" }}
filled={Math.floor(stats()!.cpu_perc)}
total={100}
/>
<h1>{stats()!.cpu_perc.toFixed(1)}%</h1>
<h1>mem:</h1>
<HeatBar
containerClass="card shadow"
containerStyle={{ width: "60vw", "min-width": "300px" }}
filled={Math.floor(mem_perc())}
total={100}
/>
<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
</div>
</Grid>
<h1>disk:</h1>
<HeatBar
containerClass="card shadow"
containerStyle={{ width: "60vw", "min-width": "300px" }}
filled={Math.floor(disk_perc())}
total={100}
/>
<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
</div>
</Grid>
</Grid>
</Show>
</Grid>
);
};
@@ -53,7 +104,7 @@ function useStatsWs(params: Params, setStats: Setter<SystemStats>) {
return;
}
const stats = JSON.parse(data) as SystemStats;
console.log(stats);
// console.log(stats);
setStats(stats);
});
ws.addEventListener("close", () => {
@@ -61,6 +112,10 @@ function useStatsWs(params: Params, setStats: Setter<SystemStats>) {
// clearInterval(int);
setOpen(false);
});
onCleanup(() => {
console.log("closing stats ws");
ws.close();
});
return {
open,
};

View File

@@ -12,4 +12,8 @@
width: 100%;
height: fit-content;
box-sizing: border-box;
}
.HeatBars {
grid-template-columns: repeat(3, auto);
}