import { useState } from "react"; import type { TreeNode } from "./tree"; function fmt(x: number): string { if (Number.isNaN(x)) return "NaN"; if (!Number.isFinite(x)) return x > 0 ? "Inf" : "-Inf"; return Number.isInteger(x) ? String(x) : Number(x.toPrecision(6)).toString(); } // Hard cap on how many values/rows are ever rendered as text, to keep large // arrays (e.g. big surf grids) from freezing the UI. const MAX_RENDER = 5000; const STEP = 1000; function DataValues({ data }: { data: unknown }) { const [limit, setLimit] = useState(200); if (!Array.isArray(data) || data.length === 0) return
No data.
; const isNumber = (e: unknown) => typeof e === "number"; const allNumbers = (data as unknown[]).every(isNumber); const total = data.length; const renderCap = Math.min(total, MAX_RENDER); const shown = Math.min(limit, renderCap); const hasMore = shown < renderCap; const capped = total > MAX_RENDER && shown >= MAX_RENDER; const unit = allNumbers ? "values" : "rows"; let body: string; if (allNumbers) { body = (data as number[]).slice(0, shown).map(fmt).join(", "); } else { body = (data as unknown[]) .slice(0, shown) .map((r, i) => { const text = Array.isArray(r) ? `[${(r as number[]).map(fmt).join(", ")}]` : fmt(r as number); return `${i}: ${text}`; }) .join("\n"); } if (shown < total) body += allNumbers ? ", …" : "\n…"; return ( <>{body}
Select an object in the tree to inspect it.
No properties.
) : (| {p.key} | {p.swatch && ( )} {p.value} |
| shape | {detail.shapeLabel} |
| count | {detail.count} |
| min | {fmt(detail.stats.min)} |
| max | {fmt(detail.stats.max)} |
| mean | {fmt(detail.stats.mean)} |
| NaN | {detail.stats.nan} |