From e011b04af8297aebe5c310e0febda723cbe6af79 Mon Sep 17 00:00:00 2001 From: Cathryn Lavery <50469282+cathrynlavery@users.noreply.github.com> Date: Wed, 19 Aug 2026 20:02:02 -0700 Subject: [PATCH] fix(treemap): verify every cell share (#124) * fix(treemap): verify every cell's area, including cells too small to label Closes #89. The area check derived its basis from in-cell labels, so a cell with no label was excluded from it. That is precisely the sliver -- the cell a 4px grid distorts most, and the one that shipped 24% undersized during review of #87. On current main, widening Oceania from 16px to 24px, a 50% area distortion, still reports OK. Every cell now declares `data-share`, its percentage of the whole, and the verifier checks all of them against it. Cells without it are reported rather than skipped: a treemap whose cells cannot be parsed is not a passing treemap, it is an unchecked one, and answering OK to it is the defect. The label and the metadata are also cross-checked, because two statements of one fact is a new way for the picture to lie while the gate stays green. Adversarial tests gain the oversized and undersized unlabelled sliver (both pass on current main and fail here), a fail-closed case for missing metadata, and a label/metadata divergence case. SKILL.md `metadata.version` said 2.4 against 2.5.0 manifests. The manifests are bumped by a script and that field is hand-maintained, so nothing read both numbers and nothing could notice. verify-plugin-package now asserts it tracks the manifest MAJOR.MINOR. The package test's fixture gains the field with it -- a SKILL.md without one is not a valid package, and a fixture missing it would only prove the gate can be tripped by its own test data. The examples regained the `PARTS ROUNDED, MAY NOT SUM` disclosure the type reference requires: displayed parts round up to 8.10B against a stated 8.09B. It was dropped when the examples were rebuilt around the legend block. The anti-pattern list, which still forbade outright what the honest-data rule permits once disclosed, now agrees with it. Also nudges the info mark onto the label row of its neighbours rather than the vertical centre of its own cell, so the bottom row reads as one row. Co-Authored-By: Claude Fable 5 * fix(treemap): reject ambiguous share metadata --------- Co-authored-by: 0xDarkMatter <0xDarkMatter@users.noreply.github.com> Co-authored-by: Claude Fable 5 --- .claude-plugin/plugin.json | 2 +- .codex-plugin/plugin.json | 2 +- .factory-plugin/plugin.json | 2 +- docs/screenshots/manifest.json | 4 +- docs/screenshots/treemap.png | Bin 79087 -> 81363 bytes scripts/test-plugin-package.py | 50 ++++- scripts/test-verify-treemap.py | 133 +++++++++++++ scripts/verify-plugin-package.py | 78 ++++++++ scripts/verify-treemap.py | 188 +++++++++++++----- .../assets/example-treemap-dark.html | 18 +- .../assets/example-treemap-full.html | 18 +- .../assets/example-treemap.html | 18 +- .../diagram-design/references/type-treemap.md | 14 +- 13 files changed, 442 insertions(+), 85 deletions(-) diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index c3f063b..aefef2d 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "diagram-design", "description": "Create branded architecture, IT current-state, flowchart, sequence, state machine, ER/data model, timeline, swimlane, quadrant, radar/spider, loop/flywheel, nested, tree, org chart, layer stack, Venn, pyramid/funnel, treemap, bar, line, Gantt and scatter charts, high-level, process, medallion, data flow, DP integration, DP security matrix, sankey, fishbone, Wardley map, kanban, user journey, deployment, dependency graph, UML class, story map, or database schema diagrams as standalone HTML/SVG/PNG. Redraw .drawio/.drawio.png/.drawio.svg or Mermaid .mmd sources at a chosen size/detail; onboard brand tokens from a website; add semantic patterns, callouts, accessible motion, or sketchy/hand-drawn styling.", - "version": "2.5.16", + "version": "2.5.17", "author": { "name": "Cathryn Lavery", "url": "https://github.com/cathrynlavery" diff --git a/.codex-plugin/plugin.json b/.codex-plugin/plugin.json index 93cdbac..7a7fb4d 100644 --- a/.codex-plugin/plugin.json +++ b/.codex-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "diagram-design", "description": "Create branded architecture, IT current-state, flowchart, sequence, state machine, ER/data model, timeline, swimlane, quadrant, radar/spider, loop/flywheel, nested, tree, org chart, layer stack, Venn, pyramid/funnel, treemap, bar, line, Gantt and scatter charts, high-level, process, medallion, data flow, DP integration, DP security matrix, sankey, fishbone, Wardley map, kanban, user journey, deployment, dependency graph, UML class, story map, or database schema diagrams as standalone HTML/SVG/PNG. Redraw .drawio/.drawio.png/.drawio.svg or Mermaid .mmd sources at a chosen size/detail; onboard brand tokens from a website; add semantic patterns, callouts, accessible motion, or sketchy/hand-drawn styling.", - "version": "2.5.16", + "version": "2.5.17", "author": { "name": "Cathryn Lavery", "url": "https://github.com/cathrynlavery" diff --git a/.factory-plugin/plugin.json b/.factory-plugin/plugin.json index c3f063b..aefef2d 100644 --- a/.factory-plugin/plugin.json +++ b/.factory-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "diagram-design", "description": "Create branded architecture, IT current-state, flowchart, sequence, state machine, ER/data model, timeline, swimlane, quadrant, radar/spider, loop/flywheel, nested, tree, org chart, layer stack, Venn, pyramid/funnel, treemap, bar, line, Gantt and scatter charts, high-level, process, medallion, data flow, DP integration, DP security matrix, sankey, fishbone, Wardley map, kanban, user journey, deployment, dependency graph, UML class, story map, or database schema diagrams as standalone HTML/SVG/PNG. Redraw .drawio/.drawio.png/.drawio.svg or Mermaid .mmd sources at a chosen size/detail; onboard brand tokens from a website; add semantic patterns, callouts, accessible motion, or sketchy/hand-drawn styling.", - "version": "2.5.16", + "version": "2.5.17", "author": { "name": "Cathryn Lavery", "url": "https://github.com/cathrynlavery" diff --git a/docs/screenshots/manifest.json b/docs/screenshots/manifest.json index a377a32..d98fa57 100644 --- a/docs/screenshots/manifest.json +++ b/docs/screenshots/manifest.json @@ -177,8 +177,8 @@ "slug": "treemap", "source": "skills/diagram-design/assets/example-treemap.html", "screenshot": "docs/screenshots/treemap.png", - "source_sha256": "41e11b175c5c2e77716b1193c28ae9e02bde755283d8624628d1f1c9e9a78a4e", - "screenshot_sha256": "b9e2b356e444bd75284130e31e71a7c6c5c1bd880fca066083bd9de87cca9372", + "source_sha256": "e7014bd22d5bc1a5b173747caca0dc6d2916cec5a3038d2b953187e45245e1b4", + "screenshot_sha256": "780ceae4760ecaf02cda02d1783e578b40900c8ac9e6f7f9eead8c95cc75fb7a", "width": 2400, "height": 1202 }, diff --git a/docs/screenshots/treemap.png b/docs/screenshots/treemap.png index f73a712f9e27bc8348550ad4b972b0c1c6702dd4..852321a6a4def85aefd9fa444ab86a404f07f923 100644 GIT binary patch delta 52345 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

=w6({)k|*EI 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 TLGS;EDtqxv<7vT@S0DZl4QyNL diff --git a/scripts/test-plugin-package.py b/scripts/test-plugin-package.py index 66eeeea..3e3f0c1 100755 --- a/scripts/test-plugin-package.py +++ b/scripts/test-plugin-package.py @@ -92,14 +92,28 @@ def seed_package( ], }, ) - skill = root / "skills" / PLUGIN_NAME / "SKILL.md" - skill.parent.mkdir(parents=True, exist_ok=True) - skill.write_text(f"---\nname: {PLUGIN_NAME}\n---\n", encoding="utf-8") + write_skill(root, version) command = root / "commands" / "export-diagram.md" command.parent.mkdir(parents=True, exist_ok=True) command.write_text("Export the diagram.\n", encoding="utf-8") +def write_skill(root: Path, version: str) -> None: + """Fixture SKILL.md, whose metadata.version tracks the manifest MAJOR.MINOR. + + The verifier gates that relationship, so a fixture that omits it is not a + valid package and would only prove the gate can be tripped by its own + test data. + """ + skill = root / "skills" / PLUGIN_NAME / "SKILL.md" + skill.parent.mkdir(parents=True, exist_ok=True) + minor = ".".join(version.split(".")[:2]) + skill.write_text( + f'---\nname: {PLUGIN_NAME}\nmetadata:\n version: "{minor}"\n---\n', + encoding="utf-8", + ) + + @contextmanager def package_repo(include_factory: bool = True) -> Iterator[Path]: with tempfile.TemporaryDirectory() as scratch: @@ -130,6 +144,10 @@ def set_versions( payload = json.loads((root / relative).read_text(encoding="utf-8")) payload["version"] = version write_json(root / relative, payload) + # Keep the fixture's SKILL.md in step with the Claude manifest, so these + # cases exercise the version rules they are about rather than tripping the + # metadata-drift gate every time. + write_skill(root, claude) def set_existing_versions(root: Path, version: str) -> None: @@ -261,6 +279,32 @@ def test_verifier() -> None: "could not read", ) + with package_repo() as root: + set_versions(root, "1.2.4", "1.2.4") + skill = root / "skills" / PLUGIN_NAME / "SKILL.md" + skill.write_text( + f'---\nname: {PLUGIN_NAME}\n---\n\nExample only:\nversion: "1.2"\n', + encoding="utf-8", + ) + expect_failure( + "version line outside frontmatter", + VERIFY.verify_package(root, "HEAD"), + "frontmatter has no metadata.version", + ) + + with package_repo() as root: + set_versions(root, "1.2.4", "1.2.4") + skill = root / "skills" / PLUGIN_NAME / "SKILL.md" + skill.write_text( + f'---\nname: {PLUGIN_NAME}\nversion: "1.2"\nmetadata:\n owner: test\n---\n', + encoding="utf-8", + ) + expect_failure( + "version outside metadata mapping", + VERIFY.verify_package(root, "HEAD"), + "frontmatter has no metadata.version", + ) + def test_bumper() -> None: cases = (("patch", "1.2.4"), ("minor", "1.3.0"), ("major", "2.0.0")) diff --git a/scripts/test-verify-treemap.py b/scripts/test-verify-treemap.py index c523045..064a972 100644 --- a/scripts/test-verify-treemap.py +++ b/scripts/test-verify-treemap.py @@ -263,6 +263,139 @@ def main() -> int: else: print("OK: an unlabelled sliver does not disable the area check") + # 6. The unlabelled sliver, both directions. This is the gap issue #89 + # reported: with the basis derived from in-cell labels, the one cell + # carrying no label was the one cell nothing verified — and it is the + # cell a 4px grid distorts most. Both rects of the pair move, because + # a mask and a body at different sizes are two cells, not one. + for label, width, direction in (("oversized", "24", "larger"), ("undersized", "8", "smaller")): + mutated = source.replace( + '100 values are not shares of a + # whole even though float() accepts them. + for label, value in ( + ("non-numeric", "unknown"), + ("zero", "0"), + ("negative", "-1"), + ("non-finite-nan", "NaN"), + ("non-finite-infinity", "Infinity"), + ("over-100", "101"), + ): + invalid = source.replace('data-share="59.04"', f'data-share="{value}"', 1) + if invalid == source: + failures.append(f"could not build the {label}-share fixture") + continue + code, output = run(write(directory, f"share-{label}.html", invalid)) + if code == 0: + failures.append(f"{label} data-share was accepted") + elif "invalid share metadata" not in output: + failures.append(f"{label} share lacked a metadata finding: {output.strip()}") + else: + print(f"OK: {label} data-share fails closed") + + # 10. The mask/body pair is one logical cell. If both copies state a + # share, they must agree; retaining whichever rect was parsed first + # silently discards contradictory source data. + asia_mask = '' + conflicting = source.replace( + asia_mask, + asia_mask.replace(' fill=', ' data-share="42" fill='), + 1, + ) + if conflicting == source: + failures.append("could not build the conflicting-twin fixture") + else: + code, output = run(write(directory, "conflicting-twins.html", conflicting)) + if code == 0: + failures.append("conflicting duplicate data-share values were accepted") + elif "conflicting data-share" not in output: + failures.append(f"conflicting twins lacked the right finding: {output.strip()}") + else: + print("OK: conflicting mask/body shares are rejected") + + asia_body = ( + '' + ) + triplicated = source.replace(asia_body, f"{asia_body}\n {asia_body}", 1) + if triplicated == source: + failures.append("could not build the triplicated-cell fixture") + else: + code, output = run(write(directory, "triplicated-cell.html", triplicated)) + if code == 0: + failures.append("a triplicated logical cell was silently deduplicated") + elif "duplicate rects" not in output: + failures.append(f"triplicated cell lacked the right finding: {output.strip()}") + else: + print("OK: extra duplicate cell rects are rejected") + + # 11. The shares describe one whole, so a plausible individual number + # cannot hide an incomplete or over-counted set. + incomplete_total = source.replace('data-share="59.04"', 'data-share="50"', 1) + code, output = run(write(directory, "incomplete-share-total.html", incomplete_total)) + if code == 0: + failures.append("data-share values that do not total the whole were accepted") + elif "not approximately 100%" not in output: + failures.append(f"bad share total lacked the right finding: {output.strip()}") + else: + print("OK: shares must total approximately 100%") + + # 12. A treemap with too few parseable cells is unchecked, not clean. + unparsable = source.replace(' rx="2"', ' rx="3"') + code, output = run(write(directory, "too-few-cells.html", unparsable)) + if code == 0: + failures.append("a treemap with no parseable cells was accepted") + elif "expected at least 3 parseable treemap cells" not in output: + failures.append(f"too-few-cells fixture lacked the right finding: {output.strip()}") + else: + print("OK: too few parseable cells fails closed") + for failure in failures: print(f"FAIL: {failure}") if failures: diff --git a/scripts/verify-plugin-package.py b/scripts/verify-plugin-package.py index 8290901..4695317 100755 --- a/scripts/verify-plugin-package.py +++ b/scripts/verify-plugin-package.py @@ -280,6 +280,83 @@ def verify_codex_skill_path(root: Path, codex_manifest: dict[str, Any], errors: errors.append(f"Codex skills path does not contain {PLUGIN_NAME}/SKILL.md") +def parse_frontmatter_metadata_version(text: str) -> str | None: + """Return exactly one direct ``metadata.version`` from YAML frontmatter. + + This intentionally does not search the Markdown body: examples and prose + are allowed to mention ``version:``, but they cannot validate package + metadata. The small parser is limited to the mapping shape this skill owns + and rejects duplicate or nested version keys instead of guessing. + """ + lines = text.splitlines() + if not lines or lines[0].strip() != "---": + return None + try: + closing = next( + index for index in range(1, len(lines)) if lines[index].strip() == "---" + ) + except StopIteration: + return None + + frontmatter = lines[1:closing] + metadata_rows = [ + index + for index, line in enumerate(frontmatter) + if re.fullmatch(r"metadata:\s*(?:#.*)?", line) + ] + if len(metadata_rows) != 1: + return None + + start = metadata_rows[0] + 1 + block: list[str] = [] + for line in frontmatter[start:]: + if line and not line[0].isspace(): + break + block.append(line) + + content = [line for line in block if line.strip() and not line.lstrip().startswith("#")] + if not content: + return None + direct_indent = min(len(line) - len(line.lstrip()) for line in content) + versions: list[str] = [] + for line in content: + indent = len(line) - len(line.lstrip()) + if indent != direct_indent: + continue + match = re.fullmatch( + r"\s*version:\s*(?:\"([^\"]+)\"|'([^']+)'|([0-9]+(?:\.[0-9]+)*))\s*(?:#.*)?", + line, + ) + if match is not None: + versions.append(next(value for value in match.groups() if value is not None)) + return versions[0] if len(versions) == 1 else None + + +def verify_skill_metadata_version(root: Path, manifests: dict[str, dict[str, Any]], errors: list[str]) -> None: + """SKILL.md's metadata version must track the manifests' MAJOR.MINOR. + + The manifests are bumped by a script; SKILL.md's `metadata.version` is + hand-maintained, so a minor release drifts silently - 2.4 sat against + 2.5.0 manifests until a post-merge sweep caught it. Nothing else reads + both numbers, so nothing else can notice. + """ + skill = root / "skills" / PLUGIN_NAME / "SKILL.md" + if not skill.is_file(): + errors.append(f"missing {skill.relative_to(root).as_posix()}") + return + declared = parse_frontmatter_metadata_version(skill.read_text(encoding="utf-8")) + if declared is None: + errors.append("SKILL.md frontmatter has no metadata.version") + return + manifest_version = str(manifests["Claude"].get("version", "")) + expected = ".".join(manifest_version.split(".")[:2]) + if declared != expected: + errors.append( + f"SKILL.md metadata.version {declared!r} must track the manifest " + f"MAJOR.MINOR {expected!r} (manifests are at {manifest_version})" + ) + + def verify_package(root: Path, base_ref: str) -> list[str]: errors: list[str] = [] manifests: dict[str, dict[str, Any]] = {} @@ -291,6 +368,7 @@ def verify_package(root: Path, base_ref: str) -> list[str]: if len(manifests) == len(MANIFEST_PATHS): verify_versions(root, base_ref, manifests, errors) verify_manifest_identity(manifests, errors) + verify_skill_metadata_version(root, manifests, errors) verify_codex_skill_path(root, manifests["Codex"], errors) verify_marketplaces(root, errors) return errors diff --git a/scripts/verify-treemap.py b/scripts/verify-treemap.py index 4085009..33b0e04 100644 --- a/scripts/verify-treemap.py +++ b/scripts/verify-treemap.py @@ -38,6 +38,7 @@ from __future__ import annotations import argparse import html +import math import re import sys import unicodedata @@ -46,13 +47,7 @@ from pathlib import Path ROOT = Path(__file__).resolve().parent.parent ASSET_DIR = ROOT / "skills/diagram-design/assets" -CELL_RE = re.compile( - r"]*?" - r'\bx="(?P-?[\d.]+)"\s+y="(?P-?[\d.]+)"\s+' - r'width="(?P[\d.]+)"\s+height="(?P[\d.]+)"[^>]*?' - r'rx="2"', - re.IGNORECASE, -) +CELL_RE = re.compile(r'[^>]*\brx="2"[^>]*?)/?>', re.IGNORECASE) TEXT_RE = re.compile(r"[^>]*)>(?P.*?)", re.IGNORECASE | re.DOTALL) CIRCLE_RE = re.compile(r"[^>]*)/?>", re.IGNORECASE) ATTR_RE = re.compile(r'(?P[\w:-]+)="(?P[^"]*)"') @@ -87,10 +82,26 @@ MARKER_EPSILON = 0.01 class Box: - __slots__ = ("x", "y", "w", "h", "offset") + __slots__ = ( + "x", + "y", + "w", + "h", + "offset", + "share", + "share_errors", + "rect_count", + ) - def __init__(self, x: float, y: float, w: float, h: float, offset: int = 0) -> None: + def __init__( + self, x: float, y: float, w: float, h: float, offset: int = 0, share: float | None = None + ) -> None: self.x, self.y, self.w, self.h, self.offset = x, y, w, h, offset + # Declared share of the whole, from data-share. None means the cell + # never stated one, which for a treemap is itself a finding. + self.share = share + self.share_errors: list[str] = [] + self.rect_count = 1 @property def right(self) -> float: @@ -137,25 +148,64 @@ def estimated_advance(text: str, mono: bool) -> float: def parse_cells(source: str) -> list[Box]: - """Deduped cell rects. Each cell is painted twice: paper mask, then body.""" + """Deduped cell rects. Each cell is painted twice: paper mask, then body. + + `data-share` may sit on either rect of the pair, so the declared share is + merged across duplicates rather than read off whichever came first. + """ seen: list[Box] = [] for m in CELL_RE.finditer(source): - box = Box( - float(m.group("x")), - float(m.group("y")), - float(m.group("w")), - float(m.group("h")), - m.start(), - ) + attrs = {a.group("name"): a.group("value") for a in ATTR_RE.finditer(m.group("attrs"))} + try: + box = Box( + float(attrs["x"]), + float(attrs["y"]), + float(attrs["width"]), + float(attrs["height"]), + m.start(), + ) + except (KeyError, ValueError): + continue + if "data-share" in attrs: + raw_share = attrs["data-share"] + try: + parsed_share = float(raw_share) + except ValueError: + box.share_errors.append(f"data-share {raw_share!r} is not numeric") + else: + if not math.isfinite(parsed_share): + box.share_errors.append(f"data-share {raw_share!r} is not finite") + elif not 0 < parsed_share <= 100: + box.share_errors.append( + f"data-share {raw_share!r} must be greater than 0 and at most 100" + ) + else: + box.share = parsed_share if box.area < CELL_MIN_AREA or box.w > CELL_MAX_W or box.h > CELL_MAX_H: continue - if any( - abs(s.x - box.x) < 0.01 - and abs(s.y - box.y) < 0.01 - and abs(s.w - box.w) < 0.01 - and abs(s.h - box.h) < 0.01 - for s in seen - ): + twin = next( + ( + s + for s in seen + if abs(s.x - box.x) < 0.01 + and abs(s.y - box.y) < 0.01 + and abs(s.w - box.w) < 0.01 + and abs(s.h - box.h) < 0.01 + ), + None, + ) + if twin is not None: + twin.rect_count += 1 + twin.share_errors.extend(box.share_errors) + if twin.share is not None and box.share is not None and not math.isclose( + twin.share, box.share, rel_tol=0.0, abs_tol=1e-9 + ): + twin.share_errors.append( + f"duplicate rects declare conflicting data-share values " + f"{twin.share:g} and {box.share:g}" + ) + if twin.share is None: + twin.share = box.share continue seen.append(box) return seen @@ -223,7 +273,10 @@ def check(path: Path) -> list[str]: source = path.read_text(encoding="utf-8") cells = parse_cells(source) if len(cells) < 3: - return [] + return [ + f"{path.name}: expected at least 3 parseable treemap cells, found {len(cells)} — " + "the area contract cannot be verified" + ] findings: list[str] = [] labels: dict[int, list[str]] = {index: [] for index in range(len(cells))} @@ -306,31 +359,70 @@ def check(path: Path) -> list[str]: "drop the marker and identify the sliver in the legend" ) - claims = {index: parse_claim(" ".join(texts)) for index, texts in labels.items()} - # Only compare on a basis every cell states, so the shares share a - # denominator. Percentages win when present: they are the claim itself. - percentages = {i: p for i, (p, _) in claims.items() if p} - magnitudes = {i: v for i, (_, v) in claims.items() if v} - known = percentages if len(percentages) >= len(magnitudes) else magnitudes + # Every cell is checked against its OWN declared share, so the cell most + # likely to be wrong is not the one exempt from checking. Deriving the + # basis from in-cell labels instead leaves an unlabelled sliver - exactly + # the cell a 4px grid distorts most - verified by nothing at all. + for cell in cells: + for error in cell.share_errors: + findings.append( + f"{path.name}:{line_of(source, cell.offset)}: cell {cell.w:g}x{cell.h:g} " + f"has invalid share metadata: {error}" + ) + if cell.rect_count > 2: + findings.append( + f"{path.name}:{line_of(source, cell.offset)}: cell {cell.w:g}x{cell.h:g} " + f"is painted by {cell.rect_count} duplicate rects — expected at most a mask/body pair" + ) - # Normalise both sides over the labelled cells only. A sliver too small to - # label is legal - it keeps its honest area and is named in the source line - # - and it must not switch this check off for the cells that do carry a - # claim, which is what comparing against the full drawn area would do. - if len(known) >= 3: - drawn_total = sum(cells[index].area for index in known) - value_total = sum(known.values()) - for index, value in sorted(known.items()): - cell = cells[index] - area_share = cell.area / drawn_total * 100 - value_share = value / value_total * 100 - relative = (area_share - value_share) / value_share * 100 - if abs(relative) > AREA_TOLERANCE: + undeclared = [cell for cell in cells if cell.share is None and not cell.share_errors] + if undeclared: + # Fail closed. A treemap whose cells cannot be parsed is not a passing + # treemap; it is an unchecked one, and saying "OK" to it is the bug. + for cell in undeclared: + findings.append( + f"{path.name}:{line_of(source, cell.offset)}: cell {cell.w:g}x{cell.h:g} " + f"has no data-share, so its area is unverifiable — every treemap cell " + f"must declare its share of the whole, including cells too small to label" + ) + return findings + + drawn_total = sum(cell.area for cell in cells) + if any(cell.share_errors for cell in cells): + return findings + + share_total = sum(cell.share for cell in cells if cell.share is not None) + if not 99.0 <= share_total <= 101.0: + findings.append( + f"{path.name}: data-share values total {share_total:g}%, not approximately 100% — " + "every cell must declare its share of the same whole" + ) + return findings + + for index, cell in enumerate(cells): + assert cell.share is not None + area_share = cell.area / drawn_total * 100 + declared = cell.share / share_total * 100 + relative = (area_share - declared) / declared * 100 + if abs(relative) > AREA_TOLERANCE: + findings.append( + f"{path.name}:{line_of(source, cell.offset)}: cell {cell.w:g}x{cell.h:g} " + f"draws {area_share:.2f}% of the area but declares {declared:.2f}% — " + f"{relative:+.1f}% relative. Area is the only encoding; resize the cell" + ) + continue + + # A label and the metadata are two statements of one fact. Let them + # disagree and the picture lies while the gate stays green. + percentage, _ = parse_claim(" ".join(labels[index])) + if percentage is not None and declared > 0: + drift = abs(percentage - declared) + # 1pp covers honest rounding of a displayed integer percentage. + if drift > 1.0: findings.append( - f"{path.name}:{line_of(source, cell.offset)}: cell " - f"{cell.w:g}x{cell.h:g} labelled {' '.join(labels[index])[:30]!r} draws " - f"{area_share:.2f}% of the area for a {value_share:.2f}% value — " - f"{relative:+.1f}% relative. Area is the only encoding; resize the cell" + f"{path.name}:{line_of(source, cell.offset)}: cell {cell.w:g}x{cell.h:g} " + f"is labelled {percentage:g}% but declares {declared:.2f}% — " + f"the label and data-share must state the same fact" ) return findings diff --git a/skills/diagram-design/assets/example-treemap-dark.html b/skills/diagram-design/assets/example-treemap-dark.html index defd637..e72cf0a 100644 --- a/skills/diagram-design/assets/example-treemap-dark.html +++ b/skills/diagram-design/assets/example-treemap-dark.html @@ -49,31 +49,31 @@ - + Asia 4.78B · 59% of world - + Africa 1.48B · 18% - + Europe 0.75B · 9% - + North America 0.61B · 8% - + South America 0.43B · 5% @@ -83,14 +83,14 @@ legend: a treemap must not silently omit a part of the whole it claims to show, but it need not label what it cannot label well. --> - - - i + + + i LEGEND - AREA = POPULATION · OUR WORLD IN DATA CONTINENTS (UN WPP) · MID-2023 · 8.09B TOTAL + AREA = POPULATION · OUR WORLD IN DATA CONTINENTS (UN WPP) · MID-2023 · 8.09B TOTAL · PARTS ROUNDED, MAY NOT SUM Asia · the focal share diff --git a/skills/diagram-design/assets/example-treemap-full.html b/skills/diagram-design/assets/example-treemap-full.html index bd1e5f8..1cf2209 100644 --- a/skills/diagram-design/assets/example-treemap-full.html +++ b/skills/diagram-design/assets/example-treemap-full.html @@ -57,31 +57,31 @@ - + Asia 4.78B · 59% of world - + Africa 1.48B · 18% - + Europe 0.75B · 9% - + North America 0.61B · 8% - + South America 0.43B · 5% @@ -91,14 +91,14 @@ legend: a treemap must not silently omit a part of the whole it claims to show, but it need not label what it cannot label well. --> - - - i + + + i LEGEND - AREA = POPULATION · OUR WORLD IN DATA CONTINENTS (UN WPP) · MID-2023 · 8.09B TOTAL + AREA = POPULATION · OUR WORLD IN DATA CONTINENTS (UN WPP) · MID-2023 · 8.09B TOTAL · PARTS ROUNDED, MAY NOT SUM Asia · the focal share diff --git a/skills/diagram-design/assets/example-treemap.html b/skills/diagram-design/assets/example-treemap.html index d66da13..e0d1ee1 100644 --- a/skills/diagram-design/assets/example-treemap.html +++ b/skills/diagram-design/assets/example-treemap.html @@ -49,31 +49,31 @@ - + Asia 4.78B · 59% of world - + Africa 1.48B · 18% - + Europe 0.75B · 9% - + North America 0.61B · 8% - + South America 0.43B · 5% @@ -83,14 +83,14 @@ legend: a treemap must not silently omit a part of the whole it claims to show, but it need not label what it cannot label well. --> - - - i + + + i LEGEND - AREA = POPULATION · OUR WORLD IN DATA CONTINENTS (UN WPP) · MID-2023 · 8.09B TOTAL + AREA = POPULATION · OUR WORLD IN DATA CONTINENTS (UN WPP) · MID-2023 · 8.09B TOTAL · PARTS ROUNDED, MAY NOT SUM Asia · the focal share diff --git a/skills/diagram-design/references/type-treemap.md b/skills/diagram-design/references/type-treemap.md index 8c885c1..e6ddf7d 100644 --- a/skills/diagram-design/references/type-treemap.md +++ b/skills/diagram-design/references/type-treemap.md @@ -21,13 +21,23 @@ Not for: ranked lists where exact values matter more than proportion (use a **ba - **Contrast:** compute the ceiling against the token you actually ship. The 9px value line is `muted`, not `ink`, and `muted` needs a lighter cell than `ink` does: measured against the composited fill, the top of the ramp can go to **0.16 on light paper and 0.14 on dark** before it drops under 4.5:1. (`ink` would tolerate 0.20 — which is exactly the number you will write down if you check the wrong token.) A mid-tone fill — solid accent, or 50% ink — fails against both light and dark text; use the tint-plus-stroke pattern instead. The source line takes `muted` too: `soft` measures 3.48:1 on paper and never reaches AA anywhere on this ramp. - **Legend:** the house block (rule, `LEGEND`, keys), naming the focal cell, the direction of the ink ramp, and any cell carrying an info mark. The source line rides the same row as `LEGEND`, right-aligned in mono 8px, stating what area encodes plus the dataset and its date. +### Declaring the share + +**Every cell carries `data-share` — including cells too small to label.** It is the cell's percentage of the whole, and it is what makes the area checkable: + +```svg + +``` + +Without it, a verifier has to infer the intended share from the text inside the cell, which quietly exempts the one cell that has no text — and that is the sliver, the cell the 4px grid distorts most. A shipped treemap once had its smallest cell drawn 50% oversized with every gate green for exactly this reason. `scripts/verify-treemap.py` now fails closed on any cell without it, and cross-checks `data-share` against the percentage the label prints, because a label and the metadata are two statements of one fact. + ### Cell element pattern ```svg - + NAME VALUE · SHARE ``` @@ -43,7 +53,7 @@ Watch the smallest cell hardest: it is the one that grid snapping and gutters di ## Anti-patterns - More than 8 cells without an "Other" bucket (unlabelable slivers). -- Cells that do not sum to the stated whole, or a percentage column that doesn't total 100. +- A stated total the cells contradict by more than display rounding — or rounding that is never disclosed. Rounded parts that miss the total by a hair are honest once the source line says so; silently printing figures that don't reconcile is not. - Stripe layout instead of squarified — defeats area comparison. - Rainbow fills: one hue per cell destroys the rank reading and the one-accent rule. - Nesting more than two levels deep in a static diagram; a second level needs a heavier border and its own label tier, and a third is unreadable without interaction.