Goal
Add legend support as a conditional overlay pane, implemented on top of a shared multi-diagram narration/view model rather than a legend-specific tab.
Why
The viewer is moving toward one implementation for multi-diagram narration with multiple visual grammars layered on top of it. Legend should fit inside that model instead of becoming a one-off surface.
Today the only practical way to show a legend is to embed it inside the main D2 graph, which pollutes layout and affects pan/zoom/highlight behavior. A separate legend tab is better than that, but it is still too narrow a primitive if the viewer also needs drill-down, tabs/links, and linked sub-diagrams.
Product Direction
- one underlying story model should support multiple diagrams/views
- authors should be able to source views from separate
.d2 files and from named/inline diagram definitions
left/right remains the global narrative progression
up/down becomes view-depth navigation: drill into a child view or return to a parent view
- drill targets may come from a step, a selected element, or both depending on the final API shape
- step pills should support author-defined labels so the same primitive can render as numbered steps or tab-like labels
- each view may carry its own narration/content
- legend should not be a separate full-screen view by default; it should be a conditional overlay pane with minimized, open, and expanded states
- legend interactions may be synchronized with the main canvas in both directions: clicking legend items can focus diagram elements, and selecting diagram elements can focus related legend items
Scope
- align legend work with reusable
view / diagram primitives in the story schema and viewer runtime
- avoid introducing a legend-only tab/view abstraction that does not generalize
- define how legend pane state coexists with global step state and active view state
- preserve backwards compatibility for single-diagram stories
- keep the authoring API YAML-first, logical, and comfortable for humans to write by hand
Non-goals
- auto-generating the legend in this ticket by default
- redesigning the entire viewer layout in one pass
- forcing a single visual grammar for multi-diagram narration
- migrating all examples immediately
Authoring Principles
- the YAML story should remain the source of truth and stay easy to read/edit manually
- the API should expose a small set of logical primitives rather than UI-specific knobs
- the same targeting model should support drill-down, tabs/links, and legend sync instead of inventing separate mechanisms for each
- authors should not need to think in DOM terms or viewer implementation details
Acceptance Criteria
- a legend can exist outside the main graph layout and does not affect D2 layout, pan/zoom, or highlight computation for the active diagram
- the legend supports overlay pane states: minimized, open, and expanded
- opening, closing, or expanding the legend does not break current step state or active view state
- the implementation path reuses shared multi-diagram/view primitives rather than a legend-only special case
- the design supports synchronized legend-to-diagram and diagram-to-legend focus behavior, even if some sync modes land incrementally
- existing single-diagram stories continue to work unchanged without new required config
- browser-based interactive/visual auditing is part of validation
Design / Ownership Notes
- story/schema implications live in the parser, types, and adapter layers
- multi-view state and legend pane behavior live in the viewer runtime and HTML template
- this ticket now assumes legend is part of a broader multi-diagram narration architecture rather than an isolated tab feature
- this issue should stay aligned with any future epic/foundation tickets for multi-diagram narration
Validation Plan
- add parser/unit tests for any new optional view/legend configuration
- add viewer tests for backwards compatibility and legend pane state handling
- run a browser audit covering legend minimized/open/expanded states, click synchronization, step navigation before/after legend interactions, and no graph-layout contamination
Open Items
- decide the exact YAML shape for multi-source diagrams while preserving author comfort
- decide how much parent context remains visible during drill-down: full replace vs anchored context
- decide whether step-local drill targets, element-local drill targets, or both are in v1
- break the broader multi-diagram narration effort into foundation + follow-up tickets/epic
Goal
Add legend support as a conditional overlay pane, implemented on top of a shared multi-diagram narration/view model rather than a legend-specific tab.
Why
The viewer is moving toward one implementation for multi-diagram narration with multiple visual grammars layered on top of it. Legend should fit inside that model instead of becoming a one-off surface.
Today the only practical way to show a legend is to embed it inside the main D2 graph, which pollutes layout and affects pan/zoom/highlight behavior. A separate legend tab is better than that, but it is still too narrow a primitive if the viewer also needs drill-down, tabs/links, and linked sub-diagrams.
Product Direction
.d2files and from named/inline diagram definitionsleft/rightremains the global narrative progressionup/downbecomes view-depth navigation: drill into a child view or return to a parent viewScope
view/diagramprimitives in the story schema and viewer runtimeNon-goals
Authoring Principles
Acceptance Criteria
Design / Ownership Notes
Validation Plan
Open Items