Files @ 4556eebe5d73
Branch filter:

Location: light9/web/metrics/StatsProcess.ts

drewp@bigasterisk.com
topdir reorgs; let pdm have its src/ dir; separate vite area from light9/
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 {
  // inspired by https://codepen.io/qiruiyin/pen/qOopQx
  @property() cpu = 0; // process_cpu_seconds_total
  @property() mem = 0; // process_resident_memory_bytes

  w = 64;
  h = 64;
  revs = 0;
  prev = 0;
  canvas?: HTMLCanvasElement;
  ctx?: CanvasRenderingContext2D;
  connectedCallback() {
    super.connectedCallback();
    this.initCanvas(this.shadowRoot!.firstElementChild as HTMLCanvasElement);
    this.prev = Date.now() / 1000;

    var animate = () => {
      requestAnimationFrame(animate);
      this.redraw();
    };
    animate();
  }
  initCanvas(canvas: HTMLCanvasElement) {
    if (!canvas) {
      return;
    }
    this.canvas = canvas;
    this.ctx = this.canvas.getContext("2d")!;

    this.canvas.width = this.w;
    this.canvas.height = this.h;
  }
  redraw() {
    if (!this.ctx) {
      this.initCanvas(this.shadowRoot!.firstElementChild as HTMLCanvasElement);
    }
    if (!this.ctx) return;

    this.canvas!.setAttribute("title", 
    `cpu ${new Number(this.cpu).toPrecision(3)}% mem ${new Number(this.mem).toPrecision(3)}MB`);

    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);
    const dt = now - this.prev;
    this.prev = now;

    const size = remap(this.mem.valueOf() / 1024 / 1024, /*in*/ 20, 80, /*out*/ 3, 30);
    this.revs += dt * remap(this.cpu.valueOf(), /*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();
  }

  static styles = [
    css`
      :host {
        display: inline-block;
        width: 64px;
        height: 64px;
      }
    `,
  ];

  render() {
    return html`<canvas></canvas>`;
  }
}