Toolbench

Charts and graphs

Every chart and graph a tool can return, and what each one needs from the data.

Charts

TypeScript
{ kind: "series", chart: {    title: "Wait time against utilisation",    x: { label: "Utilisation", min: 0, max: 1, format: "fixed2" },    y: { label: "Wait", unit: "ms", format: "compact" },    series: [      { name: "M/M/1", shape: "line", points: [{ x: 0.1, y: 11 }, { x: 0.5, y: 100 }] },      { name: "Simulated", shape: "line", axis: "right", points: [/* ... */] },    ],    annotations: [{ x: 0.8, label: "knee" }],}}

Heatmaps and pies

Two more chart kinds, from contract version 4, each its own output kind and its own lazily loaded chunk, so a page fetches the code for the kinds it draws and no others. Declare them in kinds.

TypeScript
{ kind: "heatmap", heatmap: {    xLabel: "Hour", yLabel: "Day", label: "Packet loss", unit: "%",    x: ["00:00", "02:00", /* ... */], y: ["Mon", "Tue", /* ... */],    values: [[0.2, 0.3, /* ... */], /* one row per y */],   // null for a cell with no value    scale: "sequential",                                   // or "diverging", with midpoint}} { kind: "pie", pie: {    label: "One voice stream, 48 kb/s", unit: "kb/s",    slices: [{ label: "Opus audio", value: 32 }, { label: "Headers", value: 16 }],    donut: true, total: "48 kb/s",}}

Radar charts, treemaps and Venn diagrams

Three more kinds, each its own output and its own chunk, from contract version 4:

TypeScript
{ kind: "radar", radar: { label, axes: [{ label: "Latency" }, /* ... */], series: [{ label: "Fibre", values: [9, /* ... */] }] } }{ kind: "treemap", treemap: { label, unit, root: { label: "All", children: [{ label: "Media", children: [/* ... */] }] } } }{ kind: "venn", venn: { label, sets: [{ label: "Web", size: 100 }, { label: "Mobile", size: 100 }], overlaps: [{ sets: [0, 1], size: 50 }] } }

See it live: every chart kind

Graphs

Contract version 7 ("sdk": 7) adds graph: you say what is connected, and the runtime decides where everything goes. tools/build-order is the example.

TypeScript
{ kind: "graph", graph: {    label: "Package dependencies",          // the figure's name, and the table's caption    direction: "BT",                        // LR (default), RL, TB or BT    nodes: [{ id: "core", badge: "1" }, { id: "http", badge: "2" }, { id: "app", badge: "3" }],    edges: [{ from: "core", to: "http" }, { from: "http", to: "app", label: "uses" }],    highlight: ["core", "http", "app"],     // a path to emphasise, as node ids in order} }

What you choose, with its default:

What the runtime does for you, so you do not have to:

The structural rules hold in your fixtures as well as on the page: ids are unique, every edge, port, group, lane and highlighted node names something that exists, groups do not nest in a circle, and a group's members share one lane. A case whose output breaks one fails, because the runtime would list that graph rather than draw it. Nothing about size is refused unless you say so: limits: { nodes: 200 } makes a larger graph a table and a sentence saying why.

See it live: graph layouts and families