Ranked list A top-N is a table that has given up sorting. The rank is the finding, so the bar is drawn inside the row rather than beside it, and the tail is named instead of being silently dropped. Tokens this needs: --card, --card-foreground, --muted-foreground, --border, --status-warn, --chart-1 The status, chart, scale, state and direction names are an extension, not a rename. shadcn has --destructive and five --chart-* and nothing else in this territory. ──────────────────────────────────────────────────────────────────────── // RankedList.tsx ──────────────────────────────────────────────────────────────────────── export type Ranked = { name: string; value: number }; /** * Sort descending, cut at N, and account for the cut. The list takes the * top rows plus two numbers the query already knows, the total and the * cardinality, so it can draw the "other" row every leaderboard omits. Without * that row a heavy tail and a flat one look the same. */ export function RankedList({ measure, window, top, total, cardinality, noun, onSelect }: { /** What the rows are ranked by, in the viewer's units. "Errors". */ measure: string; /** The window the ranking covers. Top five over an hour is not the top * five at any moment in it, so the window is required, not a caption. */ window: string; /** The rows above the cut. Sorted here, ties broken by name so the order * never jitters between refreshes. */ top: Ranked[]; /** Sum of the measure across every item, above and below the cut. */ total: number; /** How many items the dimension has. The other row carries the count. */ cardinality: number; /** What an item is called: "endpoints", "tenants", "queries". */ noun: string; onSelect?: (name: string) => void; }) { const rows = [...top].sort((a, b) => b.value - a.value || a.name.localeCompare(b.name)); const above = rows.reduce((n, r) => n + r.value, 0); const other = { value: total - above, count: cardinality - rows.length }; const pct = (v: number) => `${Math.round((v / total) * 100)}%`; // Bars are scaled to the top row, so the lead's size is the first thing read. const bar = (v: number) => ({ width: `${(v / rows[0].value) * 70}px` }); return (