Reading the report¶
The HTML report is a single offline file: the chart library, the styles, the front-end script, and the analysis payload are all inlined, so it works from a file:// URL with no network access.

The metric selector¶
Top right, Rank & color by drives everything below it. Changing it re-colors the treemap, re-ranks the bar chart, and re-sorts the hotspot table at once.
| Option | What it surfaces |
|---|---|
| Maintainability index | Overall module health (default). |
| Max cyclomatic | The single worst function in each module. |
| Total cyclomatic | Modules that are heavy overall. |
| Max cognitive | The single hardest function to follow. |
| Total cognitive | Modules that are collectively hard to follow. |
| Lines of code | Where the bulk of the code sits. |
The default is maintainability index. A project with no MI data anywhere (a pure TypeScript repo, say) opens on Max cyclomatic instead, so the first view is never an all-grey treemap.
Stat cards¶
A row of headline numbers: modules, functions, total lines of code, average maintainability with its A/B/C grade, and a count of functions over each configured threshold. The threshold cards are the ones to watch; they are the report's to-do list, sized.
The average maintainability is a plain mean over modules that have one, not SLOC-weighted; hover it for the grade boundaries.
Treemap¶
The package/module tree as nested tiles.
- Tile size = lines of code. A big tile is a lot of code, not necessarily bad code.
- Tile color = the selected metric, on a green → amber → red ramp. Greener is better.
- Click a package to zoom into it; a breadcrumb at the top left walks back out.
- Click a module to open its functions in the drill-down panel below.
Depth¶
The depth control (1 / 2 / 3 / All) caps how many levels of nesting render at once, so a deep tree stays readable. The starting value comes from treemap-depth in your config (default 2); 0 there means "All".
How color is scaled¶
Each node is colored by where its value falls between the minimum and maximum across the project, so the ramp is relative: it points you at the outliers in this project, and it is no grade. The worst module in a clean project still shows red.
Packages and modules are scaled separately, since a package's totals dwarf any single module's.
Nodes with no data for the selected metric are grey and sort last. A module with no measurable functions is "unknown", not "perfect".
Color accessibility¶
The ramp's luminance rises toward the bad end, so the worst tiles are also the brightest. A textual better → worse legend sits under the treemap, and every number the color encodes is also in the hotspot table. A fully colorblind-safe palette is a planned option.
Top modules / packages¶
A horizontal bar chart of the fifteen worst entries by the selected metric. The modules / packages dropdown in its heading switches the unit.
The packages view is the one that catches architectural problems: a package split into twenty small, individually innocuous modules never appears in a module ranking, while its aggregate does.
Click a bar to drill into it.
Hotspots table¶
Every module (or package) as a row, sorted worst-first by the selected metric, with the active column highlighted:
| Column | Meaning |
|---|---|
| Module / Package | Path, with a colored dot repeating the badness. |
| LOC | Source lines of code. |
| MI | Maintainability index (blank for non-Python). |
| Max CC | Highest cyclomatic among the functions. |
| Total CC | Sum of cyclomatic over the functions. |
| Max Cog | Highest cognitive score (blank for non-Python). |
| Total Cog | Sum of cognitive scores. |
| Fns | Number of functions. |
Rows with no value for the current metric sink to the bottom. Click a row to drill in.
Function detail¶
Clicking a module tile, a bar, or a table row opens that module's functions, worst first, with the top one expanded.
Each function shows:
- A CC badge (cyclomatic, matching
mccabeand Ruff's C901) and a Cog badge (cognitive, SonarSource), colored on the same ramp relative to the project's function range. - Its name and starting line.
- Its source, unless the report was generated with
--no-source. - A hint when it is over a threshold: "Cyclomatic 22 > 15 — consider extracting" or "Cognitive 19 > 15 — hard to follow".
Selecting a module also re-roots the treemap onto its package, so the two panels stay in step.
Circular imports¶
Modules that import each other, shown as a ⇄ b ⇄ c chains, largest cycle first. The panel reads "none detected" when the graph is acyclic.
This is static, AST-based, and Python only: no code is imported or executed. Only module-level imports count; imports inside functions and under if TYPE_CHECKING: are ignored, because neither causes an import-time cycle. See Metrics for exactly what is followed.
A workflow that works¶
- Open on Total cognitive, unit set to packages. That is the "where is the mass of difficulty" view.
- Switch the unit to modules to find which files in the worst package carry it.
- Switch to Max cognitive and drill into the top module. The first function is already expanded, and it is usually the one to extract.
- Check the Functions over Cog stat card as a running count. Check the circular-imports panel for structural knots that per-function numbers do not show.