Skip to content

feat: count data visuals separately from decorative elements#111

Merged
jonathan-pap merged 1 commit into
mainfrom
feat/data-visual-count
Jun 4, 2026
Merged

feat: count data visuals separately from decorative elements#111
jonathan-pap merged 1 commit into
mainfrom
feat/data-visual-count

Conversation

@jonathan-pap

Copy link
Copy Markdown
Owner

Summary

Visual counts now reflect what users mean by "visuals" — only data-bound canvas elements (charts, tables, cards, slicers, maps, AI visuals, custom visuals). Decorative shapes, textboxes, images, action buttons, page navigators, and visual groups no longer inflate the totals.

What changed

  • report-scanner: new isDataVisual predicate (denylist of non-data visualType strings) and a per-visual flag on ScannedVisual. Track dataVisualCount per PageMeta and across the whole scan.
  • data-builder: surface PageData.dataVisualCount, allPages entries, and FullData.totals.dataVisuals.
  • md-generator + client: switch the user-facing counters — header KPI, per-page stats, page-index bullets, hidden-page table, Pages table in the data-quality MD — to the data-only count.
  • Kept the raw visualCount as the source for the wireframe (needs every shape to render the layout) and the empty-state check that distinguishes "blank page" from "decorative only".
  • No change to the Sources tab / Sources.md — PhysicalSourceEntry.visualCount was already binding-derived (counts only visuals consuming model fields), so it was already correct.

Why a denylist not a binding check

Considered "count if has bindings" but went with a visualType denylist:

  • Future-proof — an unknown custom visual still counts as data (binding check would have to be perfect to match)
  • Matches user mental model: "I dropped 5 chart placeholders" = 5 visuals, even if fields aren't bound yet
  • Denylist is small and stable: shape, basicShape, textbox, image, actionButton, pageNavigator, bookmarkNavigator, group

Tests

  • New tests/report-scanner.test.ts with a minimal PBIR fixture under tests/fixtures/scanner-pbir/: 1 chart + 1 shape + 1 textbox + 1 image + 1 button + 1 unknown custom visual. Asserts visualCount=6, dataVisualCount=2 (chart + custom), and each ScannedVisual carries the right isDataVisual flag. Plus defensive cases on the predicate (case/whitespace/missing).
  • Updated factory totals in 6 existing test files for the new dataVisuals field.
  • Updated md-tier1.test.ts page-section assertion to read dataVisualCount.
  • Updated render-xss-fuzz.test.ts PageData / allPages fixtures.

375/375 tests green. Browser bundle rebuilt (docs/index.html + baked docs/sample-data.json).

Test plan

  • CI green on Node 18 / 20 / 22.
  • Open docs/index.html locally — confirm the header Visuals KPI drops vs. the previous main (sample has decorative elements on at least one page).
  • Hover the Visuals KPI — tooltip now explains the new semantics.
  • Page card "Visuals" stat reflects data-bound only; "Visuals (N)" section heading matches the list rows.
  • Pages MD doc on a real model — totals + per-page bullets show the data-only number.

"Visuals" counts now mean what users mean — charts, tables, cards,
slicers, maps, AI visuals, and custom visuals. Shapes, textboxes,
images, action buttons, page navigators, and visual groups no longer
inflate the per-page or overall totals.

- report-scanner: add isDataVisual predicate (denylist of non-data
  visualType strings) and a per-visual flag on ScannedVisual; track
  dataVisualCount per PageMeta and across the scan.
- data-builder: surface PageData.dataVisualCount, allPages entries,
  and FullData.totals.dataVisuals.
- md-generator + client: switch the user-facing counters (header KPI,
  per-page stats, page index bullets, hidden-page table, Pages table
  in the data-quality MD) to the data-only count. The raw count
  (visualCount) stays as the source for the wireframe view and the
  empty-state check that distinguishes "blank page" from "decorative
  only".
- PhysicalSourceEntry.visualCount already counts only binding-derived
  visuals, so the Sources tab and Sources.md were already correct.

Tests
- New report-scanner.test.ts with a minimal PBIR fixture: 1 chart +
  1 shape + 1 textbox + 1 image + 1 button + 1 unknown custom visual.
  Asserts visualCount=6, dataVisualCount=2 (chart + custom), and that
  each ScannedVisual is tagged correctly. Plus defensive cases for
  the predicate (case/whitespace/missing visualType).
- Updated factory totals in 6 existing test files to include the new
  dataVisuals field.
- Updated md-tier1 page-section assertion to read dataVisualCount.
- Updated render-xss-fuzz PageData / allPages fixtures.
@jonathan-pap
jonathan-pap merged commit 6f48a19 into main Jun 4, 2026
3 checks passed
@jonathan-pap
jonathan-pap deleted the feat/data-visual-count branch June 4, 2026 10:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant