dataview — Iceberg / warehouse browsing — design
Class:
design· Function axis:f0(the whole) +f1snapshot time-travel (facett-icebergview) ·f2the multi-pane warehouse wall (facett-warehousedeck) ·f3the single-table picker + auto chart (facett-table::warehouse). Strict: this file states only the shape as built — every claim points at a realfile:linein the named crate'ssrc/. The workflow isdataview-guide.md.
f0 — the whole
"dataview" is not one crate; it's three composable facett components that browse lakehouse/warehouse data at three different granularities, each an independent Facet a host can drop into a deck on its own:
| component | crate | shows |
IcebergView |
facett-icebergview |
one Iceberg table's history — a snapshot picker over a paged row grid |
WarehouseDeck |
facett-warehousedeck |
many tables/graphs at once — a wall of panes (3D graphs, grids, charts) |
WarehouseTableView |
facett-table::warehouse |
one warehouse, many tables — a left-hand table picker + a striped grid or auto bar-chart |
All three take data, not a catalog handle: none of them depend on iceberg/skade/nornir (facett-icebergview/src/lib.rs:1-7, facett-warehousedeck/src/lib.rs:14-18, facett-table/src/warehouse.rs:6-10). A host (korp / nornir-viz) reads its Iceberg/warehouse source and hands in already-materialized Arrow batches or PreviewTables; each component implements facett_core::Elm/Facet the same way as facett-grid (a serializable Model, a Msg enum, a pure view), so every one drops into a FacetDeck and is robot-testable through facett_core::harness.
IcebergView's row grid is built from facett_table::Table (facett-icebergview/src/lib.rs:54, :166), not facett-grid — see grid-design.md for the boundary between the two table components.
f1 — snapshot time-travel (facett-icebergview)
IcebergView (facett-icebergview/src/lib.rs:153-167) pairs, per Iceberg snapshot, a SnapshotMeta { id, timestamp_ms, rows } (lib.rs:62-69) with its materialized Vec<RecordBatch> (Snapshot, lib.rs:82-95). IcebergState (lib.rs:138-150) is the observable Model: the table name, every snapshot's meta newest-first, the selected snapshot's id (FC-5 — a stable id, never the picker's volatile index), and the paging window (page/page_size). IcebergView::new and set_snapshots (lib.rs:173-190, :232-239) call split_sorted (lib.rs:194-205), which sorts by timestamp_ms descending (ties broken by the larger id) and selects the newest by default.
Msg (lib.rs:107-120): SelectSnapshot(id) (time-travel by stable id, resets to page 0), SetPage/NextPage/PrevPage/SetPageSize. update (lib.rs:312-343) is the single mutation path; unknown ids and out-of-range pages are clamped, never panic. Every transition calls rebuild_grid (lib.rs:345-349), which calls build_grid (lib.rs:355-391): it slices the selected snapshot's batches to the [page*page_size, …) window — walking batch-by-batch so a page can span a batch boundary (lib.rs:370-389) — and maps each windowed batch to string rows via facett_arrow::table_from_batch (lib.rs:380), filling a facett_table::Table. Effect is uninhabited (lib.rs:129): every frame is handed in already materialized, so time-travel only re-slices in-memory data — no I/O happens inside this crate.
view (lib.rs:400-494) paints a ComboBox snapshot picker (newest marked ▲, each entry showing #id · t=…ms · N rows, lib.rs:421-442), a pager (lib.rs:448-460), and renders the current page by delegating to the inner Table::ui (lib.rs:468). state_json (lib.rs:537-554, form-3 macro invocation lib.rs:536) publishes table, snapshots (newest-first), current, total_rows, page, page_size, page_count, columns, visible_rows. copy_payload (lib.rs:498-507) delegates to the inner grid's own CopySource, so Ctrl-C copies the visible page as a TSV rectangle.
f2 — the multi-pane warehouse wall (facett-warehousedeck)
WarehouseDeck (facett-warehousedeck/src/lib.rs:361-367) composes an arbitrary number of panes — Graph3D · Grid · PlotView · Table — inside a facett_core::FacetDeck held in a RefCell (lib.rs:366, not serializable, so it lives outside the Model). ViewKind (lib.rs:70-79) names the four pane shapes; PaneData (lib.rs:130-140) is what a host hands per pane (Graph(GraphSpec) / Grid(Vec<RecordBatch>) / Chart(ChartSpec) / Blob { text }). WarehouseRegistry (lib.rs:157-250) maps a table name to the ViewKind it should render as; WarehouseRegistry::default_nordisk (lib.rs:195-249) is the concrete mapping for the nornir/modgunn warehouse (e.g. call_edges → Graph3D, bench_runs → Grid, release_events → Chart).
WarehouseDeck::add (lib.rs:409-450) builds the matching widget from PaneData — a Graph3D::new(...) for graphs (lib.rs:418-423), a Grid via build_grid (concatenating batches with arrow_select::concat::concat_batches, lib.rs:684-691) for grids, a PlotView::line/bars for charts (lib.rs:431-434), a one-column Table for blobs (lib.rs:436-445) — records a PaneInfo (lib.rs:274-288, the stable-id title + per-kind counts), and pushes the boxed Facet into the deck.
WarehouseModel (lib.rs:296-310) is the observable Model: title, layout (DeckLayout::Wall/Focus, lib.rs:253-269), cols (wall column count, clamped 1..=6), panes: Vec<PaneInfo>, and selected (the focused pane's stable id — its PaneInfo::title, FC-5). Msg (lib.rs:317-341) covers layout switching, the column stepper (IncCols/DecCols/SetCols), pane selection/drill-in (SelectPane/DrillInto, both keyed on the stable title), BackToWall, and FocusNext/FocusPrev (wrapping cycle, step_focus, lib.rs:551-564). update (lib.rs:524-547) is the sole mutation path; DrillInto both selects a pane and switches to Focus layout in one message (lib.rs:536-541).
view (lib.rs:635-679) renders the toolbar (lib.rs:569-627, layout toggle + column stepper + a pane navigator) then, in Wall layout, calls FacetDeck::wall_ui(ui, cols) so every pane paints simultaneously (lib.rs:641); in Focus layout it syncs the child deck's active tab to the Model's selected before drawing, then reconciles a live tab click back into a Msg::SelectPane so live and headless stay identical (lib.rs:645-658). state_json (lib.rs:722-747, form-3) folds in pane_count, graph3d_count/grid_count/chart_count/blob_count, the panes array, and the composed child deck's own state_json under the deck key (whose trace.ran lists deck.wall:<title> for every pane that actually drew).
f3 — the single-table picker + auto chart (facett-table::warehouse)
WarehouseTableView (facett-table/src/warehouse.rs:125-134) is a left-panel table picker over a Vec<(String, PreviewTable)>; PreviewTable (warehouse.rs:35-43) is just named columns + stringified rows. Its col_is_numeric (warehouse.rs:48-61) — at least half of a column's non-empty cells parse as f64, and at least one does — decides which columns numeric_columns (warehouse.rs:64-66) offers as chartable.
WarehouseState (warehouse.rs:76-89) is the observable Model: the loaded tables in picker order, the selected table's name (FC-5, not the picker's volatile index), and the chart controls (chart: bool, chart_val, chart_label column indices). Msg (warehouse.rs:104-115): Select(name), SetChart(bool), SetChartValue/SetChartLabel. update (warehouse.rs:204-235): selecting a table clears stale chart-column choices (warehouse.rs:206-212); turning chart mode on defaults the value column to the first numeric column and the label column to the first non-numeric column (warehouse.rs:216-228).
view (warehouse.rs:297-431) paints an egui::Panel::left table list (warehouse.rs:300-313) and a central panel that, for the selected table, shows either the striped grid or — when the "📊 chart" checkbox is on and the table has a numeric column — a hand-painted horizontal bar chart with value/label ComboBox pickers (warehouse.rs:341-…). state_json_impl (warehouse.rs:436-454, wired in via form-3 custom_state_json at warehouse.rs:484) publishes title, tables (names), table_count, selected, chart (on/value_col/ label_col), and preview (loaded, columns, rows as a count, numeric_columns) for the selected table.