---
name: bargraph_component
description: Composant bargraph de remplissage de subnet (v0.15) — invariants et décisions non-évidentes
metadata:
  type: project
---

Le bargraph de subnet (`public/assets/js/subnet-bargraph.js`, intégré dans `subnet.php`,
inspiré de la vue Patch d'Avolites Titan) a des invariants non-évidents à respecter :

- **layoutSegments doit garantir Σ widthPct = 100 %**, y compris dans le cas saturé où les
  planchers 5px seuls dépassent 100 % (barre étroite + beaucoup de micro-blocs — atteignable
  sur un /23 dense dans une fenêtre étroite). Une mise à l'échelle uniforme finale (planchers
  sacrifiés) garantit ça. Sans elle, la barre déborde son conteneur. Régression testée dans
  `subnet-bargraph.test.html` (« saturated floors »).
- **Fixtures /23** : un /23 = 512 adresses, **510 utilisables** (`total`), lastUsable =
  192.168.3.254 (3232236542). Piège : ne PAS utiliser 1534/3232237566 (ça décrit un /21, pas
  un /23). Le PHP de subnet.php calcule correctement depuis le CIDR ; seules les fixtures
  écrites à la main sont à surveiller.
- **Couleur = type d'occupation IP**, jamais le groupe : réservation (bleu), pool dynamique
  (ambre), pool short-lease (violet). Fusion des blocs **par type** (pas par groupe, sinon
  illisible sur subnets à groupes random) ; les groupes sont listés dans l'infobulle.
- **Seul `group_name`** (donnée utilisateur) atteint l'infobulle et il est échappé
  (`escapeHtml`). hostname/description/mac ne sont jamais rendus dans l'infobulle.
- Le filtre de sub.php comprend une **syntaxe de range** (`parseRange`) : `a.b.c.d-a.b.c.d`
  ou forme courte `30-80` (octets de fin, préfixe réseau du subnet complété à gauche).
  **Piège** : chaque borne doit commencer par un chiffre — la forme à point initial
  `.1-.100` n'est PAS reconnue (tombe en recherche sous-chaîne). Un clic sur un bloc
  réservation injecte le range en forme complète.

Spec : `docs/superpowers/specs/2026-07-14-subnet-bargraph-design.md`.
Plan : `docs/superpowers/plans/2026-07-14-subnet-bargraph.md`.
