Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/facett

.nornir/dataview-guide.md

dataview — Iceberg / warehouse browsing — guide

Class: guide · audience: a techie wiring one of the three dataview components into a host, or driving one from a test. The what is in dataview-design.md. This file is the workflow.

f0 — picking the right component (the whole workflow)

Three questions decide which of the three components you want:

  1. Do you need to scrub a single table's history (time-travel)? → facett-icebergview::IcebergView (f1).
  2. Do you need several tables/graphs visible at once, as a dashboard? → facett-warehousedeck::WarehouseDeck (f2).
  3. Do you need a simple "pick one table from a list, see its rows or an auto-chart" browser? → facett-table::warehouse::WarehouseTableView (f3).

All three are Facets: build one, Box::new(it) into a FacetDeck, and you get the palette picker and headless testability for free — the same pattern as grid-guide.md f0.

f1 — driving IcebergView

Build it from a host-read scan per snapshot (order doesn't matter — it sorts newest-first for you):

use facett_icebergview::{IcebergView, Snapshot, SnapshotMeta};

let view = IcebergView::new(
    "🧊 Tables",
    "Person",
    vec![
        Snapshot::new(SnapshotMeta::new(100, 1_000, 2), batches_v1),
        Snapshot::new(SnapshotMeta::new(200, 2_000, 3), batches_v2),
    ],
).with_page_size(500);

Time-travel and paging, both as direct calls and as headless Msgs:

view.select_snapshot(100);   // by stable Iceberg snapshot id
view.set_page(1);
view.current_id();           // Some(100)
view.snapshot_metas();       // newest-first, for a custom picker UI

// Headless, through the Elm seam:
use facett_core::harness;
use facett_icebergview::Msg;
let state = harness::snapshot(&mut view, [Msg::SelectSnapshot(200), Msg::NextPage]);
assert_eq!(state.current, Some(200));

When new snapshots accrue (a live feed), call set_snapshots again with the full updated list — it re-sorts, re-selects the newest, and rebuilds the grid. Read view.state_json() for the exact keys a headless assertion or a mega-matrix run should check: table, snapshots, current, total_rows, page, page_size, page_count, columns, visible_rows.

f2 — building a WarehouseDeck wall

Start from the registry so table→view-kind mapping is one line per table:

use facett_warehousedeck::{WarehouseDeck, WarehouseRegistry, PaneData, GraphSpec, ChartSpec};

let registry = WarehouseRegistry::default_nordisk();
let mut deck = WarehouseDeck::new("🏢 Warehouse").with_cols(3);

// For each table your host scanned, look up its kind and add the matching pane:
match registry.kind_for("bench_runs") {
    Some(_) => { deck.add_for("bench runs", "bench_runs", PaneData::Grid(scanned_batches)); }
    None => {}
}
// Join-derived panes (a call graph from two tables) are added directly, no registry lookup:
deck.add_for("call graph", "call_edges", PaneData::Graph(GraphSpec::new(nodes, edges)));

Drive the layout / focus from a toolbar or headlessly — both routes go through the same Msgs:

use facett_core::harness;
use facett_warehousedeck::{Msg, DeckLayout};

deck.set_layout(DeckLayout::Focus);          // direct call
harness::drive(&mut deck, [Msg::DrillInto("call graph".into())]);  // headless
assert_eq!(deck.selected(), Some("call graph"));

Reading deck.state_json()["deck"]["trace"]["ran"] after a headless render is the way to assert every expected pane actually drew (each entry is deck.wall:<pane title>), which is the strongest signal for "the dashboard came up correctly" in a test.

f3 — driving WarehouseTableView

use facett_table::warehouse::{WarehouseTableView, PreviewTable};

let view = WarehouseTableView::new("Warehouse")
    .with_table("bench_runs", PreviewTable::new(
        vec!["bench".into(), "ms".into()],
        vec![vec!["xml_parse".into(), "12.4".into()], vec!["json_parse".into(), "8.1".into()]],
    ))
    .with_table("repos", PreviewTable::new(
        vec!["name".into(), "lang".into()],
        vec![vec!["nornir".into(), "rust".into()]],
    ));

WarehouseTableView::local() / ::remote() seed two demo tables with no host attached — reach for these when you just need something on screen (a smoke test, a storybook) rather than hand-rolling PreviewTables.

Selecting a table and turning on the auto-chart, both directly and headlessly:

view.select("bench_runs");                       // direct call, by stable name
use facett_core::harness;
use facett_table::warehouse::Msg;
harness::drive(&mut view, [Msg::SetChart(true)]); // defaults value/label columns for you

A live feed that grows a table each tick calls set_table(name, updated_preview) — it replaces an existing table's rows in place (selection preserved) or appends a new one. state_json() exposes tables, selected, chart (on/value_col/ label_col), and preview (loaded, columns, rows as a count, numeric_columns) for whatever's currently selected.