# 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`](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 `Facet`s: 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`](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):
```rust
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 `Msg`s:
```rust
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:
```rust
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 `Msg`s:
```rust
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`
```rust
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 `PreviewTable`s.
Selecting a table and turning on the auto-chart, both directly and headlessly:
```rust
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.