/ concept-collection / turing-sphere
Sign in
concept-collection / turing-sphere
36 lines · 1.2 KBBlameHistoryRaw
1import type { ColormapFunc } from './colormaps.ts';
3/** Vertical colorbar drawn on a small canvas, with min/max labels. */
4export class Colorbar {
5 #canvas: HTMLCanvasElement;
6 #minLabel: HTMLElement;
7 #maxLabel: HTMLElement;
9 constructor(container: HTMLElement) {
10 container.classList.add('colorbar');
11 this.#maxLabel = document.createElement('div');
12 this.#maxLabel.className = 'colorbar-label';
13 this.#canvas = document.createElement('canvas');
14 this.#canvas.width = 12;
15 this.#canvas.height = 160;
16 this.#minLabel = document.createElement('div');
17 this.#minLabel.className = 'colorbar-label';
18 container.append(this.#maxLabel, this.#canvas, this.#minLabel);
19 }
21 update(cmap: ColormapFunc, vmin: number, vmax: number): void {
22 const ctx = this.#canvas.getContext('2d');
23 if (!ctx) return;
24 const h = this.#canvas.height;
25 for (let y = 0; y < h; y++) {
26 const t = 1 - y / (h - 1);
27 const [r, g, b] = cmap(t);
28 ctx.fillStyle = `rgb(${r},${g},${b})`;
29 ctx.fillRect(0, y, this.#canvas.width, 1);
30 }
31 const fmt = (v: number) =>
32 Number.isFinite(v) ? v.toPrecision(3).replace(/\.?0+$/, '') : '—';
33 this.#maxLabel.textContent = fmt(vmax);
34 this.#minLabel.textContent = fmt(vmin);
35 }
moveopenescclose