Skip to content

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 report: stat cards, treemap, top-modules bar chart, and the function drill-down

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 mccabe and 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

  1. Open on Total cognitive, unit set to packages. That is the "where is the mass of difficulty" view.
  2. Switch the unit to modules to find which files in the worst package carry it.
  3. Switch to Max cognitive and drill into the top module. The first function is already expanded, and it is usually the one to extract.
  4. 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.