Skip to content

Treemap depth and a SpaceSniffer style - #5

Merged
gitRasheed merged 4 commits into
mainfrom
treemap-drilldown
Nov 1, 2026
Merged

gitRasheed merged 4 commits into
mainfrom
treemap-drilldown

Conversation

@gitRasheed

Copy link
Copy Markdown
Owner

Closes #2.

Summary

  • Settings → Treemap style: Default (unchanged) or SpaceSniffer. Settings → Treemap depth: All, 1, 2 or a custom number.
  • With a depth cap, deeper folders draw as closed, labelled blocks. In SpaceSniffer style a click opens a folder in place and folds the previous one; in Default a click zooms as before. Zooming anywhere folds back to the cap.
  • Wheel, double-click, Backspace and breadcrumbs work the same in both styles and match main.
  • Hovering outlines the folder the hovered block sits in.
  • Fixes the clippy chunks_exact lint on current stable in its own commit.
  • Includes Li3age's first commit from Treemap legibility: floors, plates, seams, labels and depth #4 with their authorship. The next commit replaces its fit-based layout so the default stays as it was.

Why

#2 asked for less noise and SpaceSniffer-style drill-down without changing the default. Depth and click behaviour are separate settings so each does one thing.

Selection, view and open folder are three separate pieces of state, and they only flow one way. The selection is a cursor and only highlights. Only commands move the view: map clicks, wheel, keys, breadcrumbs and the sidebar. Moving the view clears the open folder. An earlier version let the selection decide what was open, which made arrowing through the sidebar open and zoom the map. QDirStat, WinDirStat and WizTree also link the selection between the list and the map and only zoom on explicit commands.

Design notes

  • Core: TreemapOptions.reveal keeps one node visible past max_depth; TreemapRect.expanded says whether a directory's children were laid out. Tests pin that revealing only adds rects.
  • IPC: get_treemap takes an args struct; name is sent only for folded folders under a depth cap.
  • Esc does nothing in the treemap. Every menu and dialog already uses it.

Review

Reviewed with GPT-6 Astra and GPT-6.1 Sol through opencode over five rounds.

Taken:

  • Esc closed the context menu and folded the map at the same time (Astra, Sol). Removed Esc from the treemap.
  • Server-side expanded flag instead of inferring folded folders from rect order (Sol).
  • Export lost its custom depth when the menu closed (Astra).
  • A click at depth All left an older open folder in place, which came back when a cap was set (Astra). Changing depth, filter or hide-system now clears the open folder.
  • The parent-folder hover frame vanished when hovering the selected block (Astra).

Rejected:

  • Split the record.rs hunk out (Sol). It is already its own commit.
  • Outline the whole view when hovering a top-level block (Astra). The view is the parent; a frame around everything is noise.

Several earlier findings (wheel opening and folding, selection-driven reveal races) went away when the design changed to the model above.

Validation

  • cargo fmt, cargo clippy --workspace --all-targets -D warnings, cargo test --workspace (Windows)
  • clippy 1.99 on the portable crates (Linux)
  • npm lint, format:check, build
  • Eye test in npm run dev on Windows

Thanks to @Li3age for the issue and the SpaceSniffer pointer.

gitRasheed and others added 4 commits September 23, 2026 19:07
Percentages divided by the filtered total, so with a type filter active a
row could read above 100%. They now divide by the sum of the displayed rows,
and emptiness is judged from those rows too. The active ext: list normalizes
dots and case the way the Rust parser does, so shift-clicking .pdf while
ext:.PDF is active removes it instead of adding a duplicate.
Current stable clippy rejects chunks_exact with a constant size.
A treemap that draws every file it can subdivide is a mosaic: on a real
drive most of the pixels are specks too small to identify, and finding out
what any of them is costs a hover, one block at a time. That is the whole of
the "visual overload" complaint, and no depth setting fixes it — the setting
the issue asked for decides how much of the tree is drawn, not whether what
is drawn can be read.

Three changes, all in the layout:

Culling is by side, not area. `min_area_px: 3.0` accepted a 40×0.1 sliver
because 4 px² cleared the floor; `min_side_px` requires both dimensions, so
what survives is something a person can actually see. Culled children keep
eating their share of the parent, as before — that contract is what makes
the parent's area honest, and the test that pinned it still does.

A directory reserves a strip at the top of its interior for its label, and
its children tile what is left. The strip is taken from the *children's*
frame and never from the directory's own rect: that rect has to stay a
function of its own frame alone, or a depth cap that stops recursion early
would shift the rects that survive it, and the UI switches depth live. The
test that pins that prefix property runs with a strip on.

Depth became adaptive. A directory subdivides only while its interior can
still hold a legible child — padding, strip and padding again come out of
every level, so a branch runs out of room and stops on its own. Big folders
go deep because they have the pixels; small ones stay a plate. max_depth is
now only an upper bound on top of that, which leaves room for the explicit
depth preference to land on top of it without fighting it.

The rect carries the text too. Names come from `tree.name(id)` at the
DTO boundary rather than through `TreemapRect`, which stays `Copy` and
geometry-only for the layout's own tests; one string per visible rect is
also far cheaper than the round trip per node it would otherwise take to
label a block.
Settings gets Treemap style (Default or SpaceSniffer) and Treemap depth
(All, 1, 2 or custom). Default with All is the old treemap. This replaces the fit-based layout
from the previous commit, so the default stays as it was.

With a depth cap, folders below the cap draw as closed, labelled blocks.
In SpaceSniffer style a click opens a folder in place and folds the one
opened before; Default still zooms. Changing the view folds everything
back to the cap. A clicked folder whose contents are too small to draw
zooms instead of opening to nothing. SpaceSniffer has no All, since a map
with every level drawn has nothing to open; it reads a stored All as 1 so
switching back to Default restores it.

The layout takes one node to keep open past the cap and reports which
folders had their children drawn, so the UI never infers that from rect
order. Opening a folder only adds rects; nothing already drawn moves.

Hovering outlines the folder the block sits in. The Export menu shares
the depth picker.
@gitRasheed
gitRasheed merged commit 6672003 into main Nov 1, 2026
3 checks passed
@gitRasheed
gitRasheed deleted the treemap-drilldown branch November 1, 2026 22:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature request: configurable default expand depth (or remember expand state) to avoid visual overload

2 participants