Loading devShakib…
Every Flutter charting package will draw a treemap. None lets you drill into a rectangle and walk back out. So I wrote one.
Helm's storage tool shows your disk as a treemap: every folder a rectangle, every rectangle sized by how much space it takes. Click one and you are inside it, looking at its children, with a breadcrumb trail back out. It goes from a 494 GB volume down to a single file.
I drew it by hand. Not because the packages are bad, but because the thing that makes a treemap useful for disk space is the part they do not expose.
Search for a Flutter treemap and you will find several that work. Hand them a list of values, get back a coloured rectangle layout. For a dashboard showing revenue by region, that is the whole job.
A disk browser needs four things beyond that, and each one reaches into the layout rather than sitting on top of it:
Any one of those is a fork of the package. All four means you are writing it anyway, and you would rather own it than fight an abstraction built for a different problem.
The naive treemap slices the rectangle repeatedly along one axis. It is easy and it produces slivers — long thin shapes that are impossible to read, impossible to tap, and misleading, because human eyes judge area badly when the aspect ratio is extreme.
The squarified algorithm keeps rectangles as close to square as it can. The idea is simple enough to hold in your head: sort children largest first, then add them one at a time to the current row while doing so improves the worst aspect ratio in that row. The moment adding one makes the worst ratio worse, close the row, and start a new one in the remaining space.
That is the entire algorithm. Sort descending, accumulate greedily, close the row when the worst ratio stops improving, recurse into the space that is left.
Two implementation notes that cost me time:
Sort descending or the greedy step is meaningless. The whole method assumes you place the biggest item first. Feed it unsorted input and it still produces a layout — a bad one, with no error to tell you why.
Guard against zero. Empty folders, and the remaining space after the last row, both produce zero-width or zero-height rectangles, which turn into divide-by-zero in the ratio computation and NaN in the layout. NaN propagates silently through a layout pass and you get an empty canvas with no exception, which is a genuinely unpleasant thing to debug.
Scanning a 347 GB volume walks several hundred thousand files. Two things keep that from freezing the UI, and neither is about the treemap itself.
Scan off the main isolate. Walking a filesystem is not CPU-heavy so much as relentless — hundreds of thousands of stat calls. Done on the main isolate it blocks the frame loop, and the app appears hung exactly while it is doing the work the user asked for.
Lay out one level at a time. The tree has a million nodes; the screen shows a few dozen rectangles. There is no reason to lay out anything but the current level's children. Diving in is a fresh layout over a smaller subtree, which is why it stays instant no matter how deep you go — the work is bounded by what is visible, not by what exists.
The second point is the one that also solves the label problem. Because you only lay out the visible level, you know each rectangle's real pixel size at paint time, so deciding whether a name fits is a measurement rather than a guess.
The hardest part of Helm's storage tool is not the treemap. It is making the numbers agree with the operating system.
macOS reports purgeable space — snapshots and caches the system will reclaim when it needs to. If you sum file sizes and ignore purgeable, your total disagrees with About This Mac, and when a user sees two numbers they believe the one from Apple. Correctly, too: yours is the one that is wrong.
So the categories have to be disjoint buckets that reconcile to the volume's reported capacity, purgeable included as its own slice rather than quietly dropped or quietly counted as used. A beautiful visualisation of numbers the user does not trust is worth nothing, and trust here is a single comparison against a system dialog they already know.
For a dashboard, no — use a package. For anything where the treemap is the interface rather than a picture of the data, you will end up writing it, because drill-down, hit-testing and adaptive labels all live below the API surface that a general charting package exposes.
The reward is that it is genuinely the fastest way to answer "what is eating my disk". A list of the largest folders makes you read and compare. A treemap makes the answer the biggest thing on screen.
Helm is free and MIT, and the treemap is in lib/tools/storage/ui/widgets/treemap.dart if you want to read it rather than reimplement it: github.com/devShakib015/helm.