← Cycles
Qmap · c4

semantic-zoom

archivedcreated 2026-03-23· last activity 2026-08-15

New in this cycle: Google-Maps-style semantic zoom — Company → Teams → Apps by clicking

Summary

Exploring hierarchical decomposition and semantic zoom—how the visualization changes at different abstraction levels, from company-wide aggregates down to individual actors.


Core Concept

Like Google Maps, the level of detail changes with scale:

Zoom LevelAbstractionWhat's Shown
GlobalCompany-wideAggregated traffic flows between companies
RegionalTeam-levelTeams as containers, inter-team flows
LocalIndividual actorsApps, services, databases with detailed flows

Key insight: The "inside" doesn't need to fit the "outside"—this is semantic space, not physical space. A team cube can expand to reveal 50 apps that take up more space than the original cube.


Nested Actors

Composite Pattern

Actor (base)
├── LeafActor (app, service, database, vendor)
└── CompositeActor (team, company, region...)
    └── children: Actor[]  ← can be leaves OR other composites

Visual States

StateRepresentation
CollapsedSimplified cube with label + child count badge
ExpandedBoundary outline containing positioned children
LeafFull detail mesh (dodecahedron, prism, etc. from c2)

Container Fracturing

When drilling into a composite:

  1. Siblings fade/mute (context preserved but de-emphasized)
  2. Target cube "fractures" or splits
  3. Children emerge and settle into positions
  4. Flows re-route from aggregate to detailed endpoints

Flow Transformation

Flows adapt to the current zoom level:

  • Collapsed view: Single thick line Engineering ←→ Vendor
  • Expanded view: Line fans out to actual connections (api → Vendor, auth → Vendor)

Aggregate flows "unpack" when their source/target expands.


Layout Agent

A positioning system that handles spatial arrangement dynamically.

Triggers & Responses

TriggerAction
Composite expandsPosition children within expanded space
Composite collapsesAnimate children back into cube
Sibling expandsShift/compress to make room
Actor added/removedReflow affected region
Window resizeRescale/reposition as needed

Algorithm Options

Force-Directed Family

AlgorithmDescriptionBest For
Spring-EmbedderNodes repel, edges act as springsGeneral networks, organic feel
ForceAtlas2GPU-accelerated, smooth clusteringLarge dense graphs (10-10k nodes)
Kamada-KawaiPreserves graph-theoretic distanceRelationship distances
Fruchterman-ReingoldAttractive + repulsive with coolingAesthetic drawing

Hierarchical/Layered

AlgorithmDescriptionBest For
SugiyamaNodes in layers, minimize edge crossingsDirected flows, org charts
Reingold-TilfordTree-specific, top-downPure hierarchies
Radial/TwopiConcentric circles from rootDependency chains

Space-Filling

AlgorithmDescriptionBest For
TreemapNested rectangles, area = weightProportions in hierarchy
VoronoiEach node claims surrounding spaceTerritory/zone boundaries
Circle PackingNested circles containing childrenHierarchical containment

Hybrid strategy:

  1. Force-directed for positioning siblings (organic, handles unknown cardinality)
  2. Hierarchical constraints to keep children within parent bounds
  3. Semantic zoom to swap representations at threshold
  4. Animation choreography for sequenced transitions

Semantic Zoom Techniques

From ZUI research:

TechniqueDescription
Level of Refinement (LOR)Quick sketches at LOR 0, full detail at higher levels
Pixel-threshold cullingObjects < 1px hidden; tree traversal stops early
Structure transformationObjects change shape/detail/presence, not just scale

References

Relationship to Other Cycles

  • c1.border-grouping: Zones may become composite actors; ForceClustering strategy is relevant
  • c2.entity-meshes: Leaf actors use these meshes; composites need new container representation
  • c3.data-flows: Flows must support aggregation/disaggregation based on zoom level

Progress

  • Test harness: HTML page with zoom radio buttons
  • Test data: Hierarchical structure (1 Company → 12 Teams → ~166 Apps)
  • Basic zoom level rendering (cubes at each level)
  • ContainerRug class: flat labeled planes for parent context
  • Grid layout for actors within containers
  • Nested rugs at Apps level (company + team rugs)
  • Design composite actor data model
  • Implement CompositeActor class extending BaseMesh
  • Collapsed state rendering (cube + badge)
  • Expand/collapse animation
  • Layout agent prototype (force-directed with containment)
  • Flow aggregation logic
  • Semantic zoom thresholds
  • Sibling muting on drill-down

Test Data Distribution

TeamApp Count
Platform18
Payments12
Identity8
Search15
Analytics22
Mobile10
Infrastructure24
Data14
Frontend9
Backend16
DevOps7
Security11

Total: ~166 apps


Open Questions

  1. What triggers zoom level change? Camera distance? User click? Both?
  2. Should expansion be animated or instant with fade?
  3. How deep can nesting go before UX degrades?
  4. How do zones (c1) and composite actors interact?

Lessons Learned

Scene Object Cleanup (Three.js + Vue)

Problem: Objects weren't being removed when switching zoom levels, even though tracking arrays were cleared.

Root cause: Relying on tracking arrays (renderedCubes, renderedRugs) to stay in sync with the actual Three.js scene is fragile. The removeObject helper from ExperimentBase wasn't reliably removing objects.

Solution: Clear directly from the scene, not from tracking arrays:

function clearScene() {
  const scene = sceneManager.value?.getScene();
  if (!scene) return;

  // Copy children array before modifying
  const toRemove = [...scene.children].filter(obj => {
    // Keep lights, cameras, grid helpers
    if (obj.isLight || obj.isCamera || obj.isGridHelper) return false;
    return obj.isMesh || obj.isGroup;
  });

  toRemove.forEach(obj => {
    scene.remove(obj);
    // Dispose recursively...
  });
}

Key patterns:

  1. Copy scene.children before iterating ([...scene.children])
  2. Use Three.js type checks: obj.isMesh, obj.isGroup, obj.isLight, obj.isGridHelper
  3. Dispose geometry and materials recursively via obj.traverse()
  4. Don't trust wrapper functions—go straight to the scene when debugging

Visual record

5 captures — heroes, page slices, and full-page renders. Click to view.

Company level — the whole org as one block
Company level — the whole org as one block
Teams level after drilling in
Teams level after drilling in
Apps level — the full decomposition
Apps level — the full decomposition
A team expanded at app level (honest ceiling: 4 click-driven states)
A team expanded at app level (honest ceiling: 4 click-driven states)
c4 legacy

Artifacts

/experiments/c4.semantic-zoom/ (local dev)

Qpoint Brand Style Guide