Add treemap explorer view for physical block visualization#8613
Add treemap explorer view for physical block visualization#8613robert3005 wants to merge 15 commits into
Conversation
Add a new top-level "Treemap" view to the file explorer that visualises the file's physical blocks as a zoomable, pannable treemap. Layouts subdivide the canvas first; flat layouts subdivide further into their array-encoding buffers, so the deepest tiles are the physical blocks. Tiles are sized by byte footprint, coloured by encoding, and shaded with a WinDirStat-style cushion gradient. - BlockTreemap: SVG treemap rendered in screen space with wheel-zoom, drag-pan, zoom-to-fit on double-click, zoom buttons, hover tooltip with physical stats, and click-to-select that lazily expands array encodings. Selection/hover sync through SelectionContext so the tree and map stay in lock-step. - physicalStats: shared helper for physical properties (data/metadata bytes, % of file, bytes/row density, segment/buffer counts). - TreemapExplorer: composes the map with an encoding legend, a metadata + physical-statistics sidebar, and the shared data-sample preview. - FileHeader/App/MainArea: Explorer | Treemap view switcher; TreePanel, file map and data preview stay shared between views. - Storybook stories for the explorer plus orders/wide/heavy-chunk fixtures. Signed-off-by: Robert <robert@spiraldb.com>
…th theme Document the treemap explorer in the README with rendered screenshots (overview, hover-with-stats, and many-chunks views). To render the screenshots from Storybook, supply the theme via a global preview decorator so components using `useTheme` render in stories and follow the Storybook theme toolbar. Export `ThemeContext` to enable this, mirroring the existing `SelectionContext` export. Signed-off-by: Robert <robert@spiraldb.com>
Replace the WinDirStat-style saturated, cushion-shaded tiles with the translucent, dtype-coloured treatment used by the detail treemap and swimlane: flat tint fills (0.06 container / 0.18 leaf / 0.4 selected), thin app borders, Geist Mono fg/dim labels, and the standard dtype legend. The hover tooltip now uses the shared swimlane tooltip card (name + dtype badge + stat grid). Zoom, pan, selection sync, and physical statistics are unchanged. Signed-off-by: Robert <robert@spiraldb.com>
The app is dark by default (matching explore.vortex.dev), so default the TreemapExplorer story to the dark theme and refresh the README screenshots in dark. The treemap already renders in dark via the shared theme tokens (#1a1a1e surface, #e4e4e8 text, #2cb9d1 accent); this just makes the preview and docs reflect the production default. Signed-off-by: Robert <robert@spiraldb.com>
Nested container labels (e.g. customer → id, amount → data, status → values) rendered as plain text one padding-band apart and visually collided. Give each container a tinted header bar in its padding band, coloured by its dtype, so nested parent names read as a stacked staircase of title strips instead of overlapping. Labels sit within their own bar; the bytes line stays leaf-only. Signed-off-by: Robert <robert@spiraldb.com>
Replace the per-container header bars with a single sticky breadcrumb overlaid on the treemap: only leaf blocks are labelled inline, and the hovered block's full path (e.g. "status / values") is shown pinned to the corner. This is simpler than reserving a labelled padding band per nesting level and removes parent-name overlaps by construction, since parent names are never stacked inline. Leaf name + bytes labels and all interactions are unchanged. Signed-off-by: Robert <robert@spiraldb.com>
Replace the overlay breadcrumb with sticky header bars. Each container layout draws a title strip in its padding band; when the container scrolls above the top of the view, its strip pins just below its parent's, so ancestor strips stack into the current path as you pan and zoom. Strips are coloured by dtype, highlight on hover/selection, and sit in their natural band at rest. Leaf name and bytes labels are unchanged. Signed-off-by: Robert <robert@spiraldb.com>
A pinned (stuck) sticky header bar was translucent, so content scrolling underneath bled through it. Draw an opaque surface base beneath the dtype tint once a bar is stuck, so it reads as solid and the children sit cleanly below it. In-band (non-stuck) strips keep their light tint. Signed-off-by: Robert <robert@spiraldb.com>
The header bars were piling up on top of each other (and on leaf labels) at the top of the map because `.paddingTop(18)` was being overridden: d3's `.paddingOuter(1)` also sets the top pad and was called after it, collapsing the band to 1px. Set `paddingTop` last so each container gets a real 18px band, and lay out PAD_TOP taller with an upward shift so the root's own band doesn't leave a top margin. Strips now sit in their own bands with no overlap. Signed-off-by: Robert <robert@spiraldb.com>
Replace the nested treemap (and its per-container header strips, the source of the overlapping labels) with a drill-down box: the box shows the current layout's child blocks one level deep, each a single labelled tile sized by its subtree bytes. A header bar at the top is the current path — click a block to drill in, click a path segment to drill back out. Because every visible tile is one level deep, labels never collide. Hover still drives the tooltip, sidebar, and data sample; selection stays in sync with the tree panel. Drops the pan/zoom transform and sticky-header machinery. Signed-off-by: Robert <robert@spiraldb.com>
The one-level drill view hid the blocks (a dominant field was just one big empty tile). Render the full nested tree down to the leaves again so every physical block is visible, but label only leaf blocks — parent names come from a single path header at the top, which shows the path to the block under the cursor (e.g. "root / amount / data / [4]"). Because containers carry no inline label, nothing overlaps. Click a block to select it (flat blocks expand in place to reveal their buffers); click a path segment to focus that subtree. Signed-off-by: Robert <robert@spiraldb.com>
… header Move each layout's name back onto its own block: container layouts label their header band (which their children never occupy, so labels cannot collide) and leaves label their body with name + bytes. Drop the top path header. The full nested tree still renders down to the leaves so every physical block is visible, coloured by dtype; hover drives the tooltip/sidebar and click selects (flat blocks expand in place). Relies on the corrected header band (paddingTop set after paddingOuter) so nested names stack cleanly without overlap. Signed-off-by: Robert <robert@spiraldb.com>
6f08e27 to
2bde076
Compare
Merging this PR will not alter performance
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ❌ | Simulation | slice_empty_vortex |
339.4 ns | 397.8 ns | -14.66% |
| ⚡ | Simulation | bitwise_not_vortex_buffer_mut[128] |
244.4 ns | 215.3 ns | +13.55% |
| ⚡ | Simulation | bitwise_not_vortex_buffer_mut[1024] |
304.7 ns | 275.6 ns | +10.58% |
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing claude/stoic-brown-5pzm5s (a6a3616) with develop (bf2be52)
Footnotes
-
4 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩
Replace the simpler TreemapPane with the richer BlockTreemap as the detail panel's "Treemap" tab, rooted at the selected node and rendering every physical block down to the leaves with local per-layout labels (container header bands + leaf bodies). Single-click highlights a block; double-click selects it, which re-roots the tab there (zoom in) — zoom back out via the detail-panel breadcrumb. Remove the standalone top-level Treemap view and its Explorer|Treemap header toggle (TreemapExplorer, MainArea/FileHeader/App view plumbing), and drop the old TreemapPane. Add a BlockTreemap story (root, zoomed field, heavy chunks). Signed-off-by: Robert <robert@spiraldb.com>
…k to zoom Single-clicking a block now selects it — highlighting it and scrolling the tree panel to it — instead of only highlighting locally. To keep select separate from zoom, the Treemap tab now roots at the whole file with its own internal drill state: double-click zooms into a block (re-root) and an "↑" control zooms back out, while selection just highlights and syncs the tree/sidebar/preview. Signed-off-by: Robert <robert@spiraldb.com>
Selecting a node in the tree panel now re-roots (zooms) the treemap at it. The map distinguishes selections it made itself (single-click highlight, which must not re-zoom) from external selections (tree panel, breadcrumb) via a ref, and only the latter drive the zoom. Double-click and the "↑" control still adjust the zoom directly. Signed-off-by: Robert <robert@spiraldb.com>
Rationale for this change
This PR adds a new Treemap view to the explorer that visualizes the physical layout of blocks in a Vortex file. The treemap renders every encoded block down to the leaves, sized by byte footprint and colored by dtype, providing insight into file structure, chunk distribution, and encoding density. This complements the existing swimlane explorer which focuses on logical structure.
The treemap view:
What changes are included in this PR?
New components:
BlockTreemap.tsx: Core treemap rendering using D3 hierarchy and squarified treemap layout. Handles hit testing, hover/selection, and tooltip display.TreemapExplorer.tsx: Top-level view combining the treemap with a dtype legend and metadata sidebar.physicalStats.ts: Utilities for computing physical statistics (data bytes, metadata, density, row counts) aggregated over subtrees.Modified components:
FileHeader.tsx: Added view switcher buttons ("Explorer" / "Treemap") to toggle between the detail panel and treemap views.MainArea.tsx: Refactored to accept aviewprop and conditionally render either the detail panel or treemap explorer.ExplorerShell.tsx: Updated to manage view state and pass it through the component tree.App.tsx: Updated to manage and pass the view state.Documentation & stories:
TreemapExplorer.stories.tsx: Added Storybook stories demonstrating the treemap with three datasets (orders, wide columns, heavy chunks).README.md: Added section documenting the treemap explorer with screenshots and usage notes.Theme context:
ThemeContext.tsx: ExportedThemeContextfor use in Storybook preview configuration..storybook/preview.ts: Updated to wrap stories withThemeContextso theme switching works in Storybook.What APIs are changed? Are there any user-facing changes?
User-facing changes:
Component API changes:
FileHeadernow requiresviewandonViewChangepropsMainAreanow requires aviewpropExplorerViewtype exported fromMainAreato indicate the two view modesNo breaking changes to public APIs outside the explorer shell.
https://claude.ai/code/session_01AgSCUYWJ7tJmrtUGkgEV4A