1import { useEffect, useRef } from "react";
2import { colormapTable, getColormap, type Range } from "@plate-dyn/core";
4export function Colorbar({
5 range,
6 colormap,
7 unit,
8 scale = 1,
9 height = 200,
10}: {
11 range: Range;
12 colormap: string;
13 unit?: string;
14 scale?: number;
15 height?: number;
16}) {
17 const ref = useRef<HTMLCanvasElement>(null);
18 useEffect(() => {
19 const c = ref.current;
20 if (!c) return;
21 const ctx = c.getContext("2d");
22 if (!ctx) return;
23 const table = colormapTable(getColormap(colormap));
24 const h = 256;
25 c.width = 1;
26 c.height = h;
27 const img = ctx.createImageData(1, h);
28 for (let k = 0; k < h; k++) {
29 const t = 255 - k;
30 img.data[4 * k] = table[3 * t];
31 img.data[4 * k + 1] = table[3 * t + 1];
32 img.data[4 * k + 2] = table[3 * t + 2];
33 img.data[4 * k + 3] = 255;
34 }
35 ctx.putImageData(img, 0, 0);
36 }, [colormap]);
37 return (
38 <div className="pl-colorbar" style={{ height }}>
39 <span>{fmt(range.max * scale)}</span>
40 <canvas ref={ref} />
41 <span>
42 {fmt(range.min * scale)} {unit}
43 </span>
44 </div>
45 );
46}
48export function fmt(x: number): string {
49 if (x === 0) return "0";
50 const a = Math.abs(x);
51 if (a >= 1e4 || a < 1e-2) return x.toExponential(2);
52 return x.toPrecision(3);
53}