diff --git a/README.md b/README.md
index 05c77d09..eef84229 100644
--- a/README.md
+++ b/README.md
@@ -1,38 +1,143 @@
-# Latkit
+
+
+
-[](https://github.com/lukelowry/latkit/actions/workflows/ci.yml)
+latkit
-Columnar data drawn as vertices, edges, lines, and areas on the GPU: networks on a plane, a map, or
-a globe, plots of sampled fields, and block diagrams, from a scene and named data. One Rust crate
-draws them, in the browser through the npm package and natively through the CLI.
+
+ Networks, maps, plots, and diagrams of millions of rows, drawn on the GPU:
+ in the browser with WebGPU, and as pictures and video from the command line.
+
-| Part | Use |
-| --------------------------------- | ------------------------------------------------------------------------------------------ |
-| [`latkit`](crates/latkit) | The library: data, expressions, scenes, views, pictures, and video |
-| [npm `latkit`](npm) | The library in the browser, its scenes as JSON with generated types |
-| [`latkit-cli`](crates/latkit-cli) | Scenes of JSON or binary data rendered to images and videos |
-| [Examples](npm/examples) | Every feature on a page, and the browser gate that drives them |
-| [Benchmark](benchmark) | Each scenario's phases up its sizes, held to committed work and times |
-| [Docs](docs) | How-tos for the npm package and the CLI, on [Read the Docs](https://latkit.readthedocs.io) |
+
+
+
+
+
+
+
+
+
-The `@latkit/*` TypeScript packages, a lighter alternative without WebAssembly, are maintained on
-the [`npm/js`](https://github.com/lukelowry/latkit/tree/npm/js) branch.
+## Install
+
+```sh
+npm install latkit # in the browser
+cargo install latkit-cli # on the command line: pictures and video
+cargo add latkit # in Rust
+```
+
+## In the browser
```ts
-import { loadLatkit, Patch, type Scene } from 'latkit';
+import { loadLatkit, Patch, field, type Scene } from 'latkit';
const { Data, Gpu } = await loadLatkit();
-const gpu = await Gpu.create();
-const data = new Data('grid').apply(new Patch().replace('Bus', [1, 2], { x: [0, 30], y: [0, 20] }));
+const data = new Data('grid').apply(
+ new Patch().replace('Bus', [101, 102], { x: [0, 30], y: [0, 20], kv: [230, 115] }),
+);
const scene: Scene = {
space: 'plane',
- marks: [{ vertices: { of: ['grid', 'Bus'], position: ['x', 'y'], radius: 6 } }],
+ marks: [
+ {
+ vertices: {
+ of: ['grid', 'Bus'],
+ position: ['x', 'y'],
+ radius: 6,
+ color: field('kv').colormap('viridis'),
+ },
+ },
+ ],
};
+
+const gpu = await Gpu.create();
const view = gpu.view(scene);
gpu.canvas(document.querySelector('canvas')!).show([view]);
view.setData(data);
+view.fit();
+```
+
+Scenes, expressions, and patches are plain data, typed from latkit's schema: `latkit/core` builds
+them without loading WebAssembly, in a worker or on a server.
+
+## On the command line
+
+The same scene and data, as JSON, render to a picture, or with `--frames` to video:
+
+```sh
+latkit render scene.json --data grid.json --output grid.png
+latkit render scene.json --data grid.json --frames frames.jsonl --fps 60 --output grid.mp4
```
+
+scene.json and grid.json
+
+`scene.json`
+
+```json
+{
+ "space": "plane",
+ "marks": [
+ {
+ "vertices": {
+ "of": ["grid", "Bus"],
+ "position": ["x", "y"],
+ "radius": 6,
+ "color": { "colormap": "viridis", "value": { "field": "kv" } }
+ }
+ }
+ ]
+}
+```
+
+`grid.json`
+
+```json
+{
+ "name": "grid",
+ "patch": [
+ {
+ "replace": {
+ "table": "Bus",
+ "ids": [101, 102],
+ "fields": { "x": [0, 30], "y": [0, 20], "kv": [230, 115] }
+ }
+ }
+ ]
+}
+```
+
+
+
+## Gallery
+
+
+
+
+
+
+
+
+
+
+
+ From the example pages and the command-line examples, with Torus Silk and Golden Bloom rendered using the published latkit-cli and npm latkit 0.2.0 releases.
+
+
+## Repository
+
+| Part | What it is |
+| --------------------------------- | -------------------------------------------------------------- |
+| [`latkit`](crates/latkit) | The Rust library: data, expressions, scenes, views, and video |
+| [npm `latkit`](npm) | The library in the browser, with types for every scene |
+| [`latkit-cli`](crates/latkit-cli) | Pictures and video of scenes, from JSON or binary data |
+| [Examples](npm/examples) | Every feature on a page, and the browser gate that drives them |
+| [Benchmark](benchmark) | Every scenario's phases up its sizes, held to committed work |
+| [Docs](docs) | The guides, on [Read the Docs](https://latkit.readthedocs.io) |
+
+The `@latkit/*` TypeScript packages, a lighter alternative without WebAssembly, are maintained on
+the [`npm/js`](https://github.com/lukelowry/latkit/tree/npm/js) branch.
+
## Develop
Requires Rust (pinned in `rust-toolchain.toml`), Node.js 24, and pnpm 10.30.
diff --git a/docs/images/diagram.webp b/docs/images/diagram.webp
new file mode 100644
index 00000000..f14c7f75
Binary files /dev/null and b/docs/images/diagram.webp differ
diff --git a/docs/images/golden-bloom.png b/docs/images/golden-bloom.png
new file mode 100644
index 00000000..7221d745
Binary files /dev/null and b/docs/images/golden-bloom.png differ
diff --git a/docs/images/helios.webp b/docs/images/helios.webp
new file mode 100644
index 00000000..b7ea6334
Binary files /dev/null and b/docs/images/helios.webp differ
diff --git a/docs/images/hero.webp b/docs/images/hero.webp
new file mode 100644
index 00000000..41f709fd
Binary files /dev/null and b/docs/images/hero.webp differ
diff --git a/docs/images/linked-views.webp b/docs/images/linked-views.webp
new file mode 100644
index 00000000..1ed6f051
Binary files /dev/null and b/docs/images/linked-views.webp differ
diff --git a/docs/images/power-flow.webp b/docs/images/power-flow.webp
new file mode 100644
index 00000000..32198166
Binary files /dev/null and b/docs/images/power-flow.webp differ
diff --git a/docs/images/torus-silk.png b/docs/images/torus-silk.png
new file mode 100644
index 00000000..553e096e
Binary files /dev/null and b/docs/images/torus-silk.png differ