Files @ 04ed5d134973
Branch filter:

Location: light9/light9/web/homepage/StatsProcess.ts

drewp@bigasterisk.com
WIP draw prom metrics on homepage
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>`;
  }
}