import { LitElement, html, css } from "lit";
import { customElement, property } from "lit/decorators.js";
import debug from "debug";
const log = debug("process");
const remap = (x: number, lo: number, hi: number, outLo: number, outHi: number) => {
return outLo + (outHi - outLo) * Math.max(0, Math.min(1, (x - lo) / (hi - lo)));
};
@customElement("stats-process")
export class StatsProcess extends LitElement {
@property() dataTime: number = 0; // millis at last data change
@property() cpu: number = 12; // process_cpu_seconds_total
@property() mem: number = 50000000; // process_resident_memory_bytes
w = 64;
h = 64;
revs = 0;
prev = 0;
ctx?: CanvasRenderingContext2D;
firstUpdated(c: Map<string, any>) {
super.firstUpdated(c);
// inspired by https://codepen.io/qiruiyin/pen/qOopQx
this.initCanvas(this.shadowRoot!.firstElementChild as HTMLCanvasElement);
this.prev = Date.now() / 1000;
var animate = () => {
requestAnimationFrame(animate);
this.redraw();
};
animate();
}
initCanvas(canvas: HTMLCanvasElement) {
var ctx = canvas.getContext("2d")!;
canvas.width = this.w;
canvas.height = this.h;
}
redraw() {
if (!this.ctx) return;
const now = Date.now() / 1000;
const ctx = this.ctx;
ctx.beginPath();
// wrong type of fade- never goes to 0
ctx.fillStyle = "#00000003";
ctx.fillRect(0, 0, this.w, this.h);
// if (!this.data || this.data.time < now - 2) {
// return;
// }
const dt = now - this.prev;
this.prev = now;
const size = remap(this.mem / 1024 / 1024, /*in*/ 20, 600, /*out*/ 3, 30);
this.revs += dt * remap(this.cpu, /*in*/ 0, 100, /*out*/ 4, 120);
const rad = remap(size, /*in*/ 3, 30, /*out*/ 14, 5);
var x = this.w / 2 + rad * Math.cos(this.revs / 6.28),
y = this.h / 2 + rad * Math.sin(this.revs / 6.28);
ctx.save();
ctx.beginPath();
ctx.fillStyle = "hsl(194, 100%, 42%)";
ctx.arc(x, y, size, 0, 2 * Math.PI);
ctx.fill();
ctx.restore();
}
updated(changedProperties: Map<string, any>) {
if (changedProperties.has("dataTime")) {
this.shadowRoot!.firstElementChild!.setAttribute("title", `cpu ${this.cpu}% mem ${this.mem}MB`);
}
}
static styles = [
css`
:host {
display: inline-block;
width: 64px;
height: 64px;
}
`,
];
render() {
return html`<canvas></canvas>`;
}
}