Temporal Projection View Widget Roadmap
TemporalProjectionViewWidget Development Roadmap
This document tracks remaining development tasks for the Temporal Projection View Widget. For documentation of completed features and current architecture, see the main developer documentation.
Completed Work Summary
The following features are complete and documented in index.qmd:
Widget skeleton: EditorState pattern, registration, state/view/properties factories
State management:
TemporalProjectionViewStatewithHorizontalAxisState,VerticalAxisStatecomposition;TemporalProjectionViewStateDataserializable struct withrfl::jsonDual rendering pipeline:
SceneRendererfor point glyphs,BatchLineRendererfor selectable linesData key management: Add/remove multiple
PointDataandLineDatakeys via properties panelSpatial mapping:
SpatialMapper::mapAllPoints()for flattening all time frames;buildLineBatchFromLineData()for line segmentsAuto-fit bounds: Bounding box computation from actual data with 2% margin, zoom/pan reset on bounds change
Axis system:
HorizontalAxisWidget(X) andVerticalAxisWidget(Y) with bidirectional sync, including the “silent update” patternInteraction: Separated X/Y zoom, pan via shared
PlotInteractionHelpersPoint selection: Ctrl+Click toggle via
SceneHitTester::queryQuadTree()with 10px toleranceLine selection: Ctrl+Click drag intersection stroke via shared
LineSelectionHelpers, GPU compute shader and CPU intersector backendsSelection state:
std::unordered_set<EntityId>with preservation across scene rebuildsRendering controls: Point size and line width spinboxes in properties panel
Selection mode toggle: None / Point / Line combo box in properties panel
DataManager observer: Combo box population and cleanup in destructor
State serialization: Full round-trip JSON via
rfl::jsonRegistration wiring:
timePositionSelected→EditorRegistry::setCurrentTime()connectionLine style customization:
LineStyleData(color, thickness, alpha) viaLineStyleState/LineStyleControls— global single style, replaces hardcoded redPolygon selection: Dual-mode selection (Point/Line/Polygon) via combo box; Enter to close polygon, Backspace to undo vertex, Escape to cancel; uses shared
PolygonInteractionControllerandselectPointsInPolygon()fromCorePlotting/Selection/; polygon preview viaPreviewRenderer; additive selection (adds to existing)Group integration: Right-click context menu via
GroupContextMenuHandlerfor “Add to Group”, “Create New Group”, “Remove from Group”; integrated withEntityRegistry; selection instructions via sharedSelectionInstructionshelpersGroup-based coloring:
color_by_grouptoggle in properties panel;applyGroupColorsToScene()applies group colors to point glyphs with priority (selected → group → default);GroupManagersignal connections trigger scene rebuild on group changes
Not yet implemented: double-click time navigation, subgroup visibility filtering, per-key rendering options described below.
Phase 7: Subgroup Visibility Filtering
Status: Not started. Depends on Phase 5 (group integration) and Phase 6 (group coloring).
Goal: Allow the user to selectively show/hide points and lines by their group membership, enabling focused analysis of specific subgroups.
7.1 Visibility State
Extend state with a visibility filter:
struct TemporalProjectionViewStateData {
// ... existing fields ...
// Groups to show. Empty means "show all".
std::vector<std::string> visible_groups;
bool show_ungrouped = true; ///< Show entities not in any group
};7.2 Visibility Filtering During Scene Build
In rebuildScene(), before building the scene, filter entities:
For points:
- After
SpatialMapper::mapAllPoints(), iterateMappedElementobjects - For each element, check if its
EntityIdbelongs to a visible group - Only include matching elements in the
SceneBuilder::addGlyphs()call
For lines:
- After building
LineBatchData, setvisibility_mask[i] = 0for lines whoseEntityIddoes not belong to a visible group - Upload the filtered visibility mask to
BatchLineStore
The BatchLineRenderer already respects the visibility mask, so no rendering changes are needed for lines.
7.3 Properties Panel Controls
Add a “Visibility” collapsible section:
- Group checklist — checkbox per group (checked = visible)
- “Show ungrouped” checkbox — toggle visibility of entities not in any group
- “Show All” / “Hide All” buttons — convenience toggles
7.4 Signal Flow
User toggles group visibility checkbox
↓
State updates visible_groups
↓
stateChanged() emitted
↓
rebuildScene() filters by visibility
↓
Filtered scene rendered
Phase 8: Per-Key Rendering Options
Status: Not started. Currently rendering options (point size, line width, color) are global.
Goal: Allow per-data-key rendering customization, so different PointData and LineData keys can have distinct visual styles.
8.1 Per-Key Options in State
Replace global options with per-key option maps:
struct TemporalProjectionViewStateData {
// ... existing fields ...
// Replace flat point_size/line_width with per-key options:
std::map<std::string, PointGlyphOptions> point_options; // key → glyph options
std::map<std::string, LineRenderOptions> line_options; // key → line options
};Keys not present in the map use default PointGlyphOptions / LineRenderOptions.
8.2 Properties Panel
Replace the current flat spinboxes with a per-key options table, similar to LinePlotWidget’s per-series options table:
- Point data table — add columns for glyph type, size, color
- Line data table — add columns for color, width, alpha
8.3 Rendering Update
In rebuildScene(), look up per-key options when building glyph styles and line colors:
for (auto const & pb : point_batches) {
auto opts = lookupPointOptions(pb.key, _state->pointOptions());
CorePlotting::GlyphStyle style;
style.glyph_type = toRenderableGlyphType(opts.glyph_type);
style.size = opts.glyph_size;
style.color = hexToGlmVec4(opts.hex_color, opts.alpha);
builder.addGlyphs("points_" + pb.key, pb.mapped, style);
}Dependency Graph
Phase 3: Double-Click Time Navigation
│
│ (all independent of each other, can be done in any order)
│
Phase 4: Polygon Selection
└── uses: PolygonInteractionController (already implemented)
└── needs: CorePlotting::Selection::selectPointsInPolygon (new)
│
Phase 5: Selection → Group Integration
├── depends on: Phase 4 (polygon selection adds to selection set)
│ (but can start with click/stroke selection only)
└── depends on: Plots/Common/GroupManagementPanel
(shared with LinePlotWidget, ScatterPlotWidget)
│
Phase 6: Group-Based Coloring
└── depends on: Phase 5 (group membership required)
│
Phase 7: Subgroup Visibility Filtering
└── depends on: Phase 5 (group membership required)
│
Phase 8: Per-Key Rendering Options
└── depends on: Phase 2 (glyph/line options defined)
Phases 1–3 are independent and can be implemented in any order. Phase 4 (polygon selection) is independent of 1–3 but provides the most natural multi-select workflow. Phase 5 (group integration) can begin with existing click/stroke selection but benefits from Phase 4. Phases 6 and 7 both depend on Phase 5 but are independent of each other. Phase 8 extends Phases 1 and 2 to per-key granularity.
Design Decisions
Per-key vs. global rendering options: Phase 2 started with global options (simpler, now complete), extended to per-key options in Phase 8 to avoid premature complexity.
Polygon interaction: Uses the existing
PolygonInteractionControllerfromCorePlotting/Interaction/. This shared controller handles click-based polygon creation, vertex drag modification, cursor preview, and auto-close detection. Only a newselectPointsInPolygon()utility is needed for the ray-casting containment test.
Open Questions
Group color conflict resolution: When an entity belongs to multiple groups, which group’s color takes priority? Options: first group alphabetically, most recently assigned, or a blended color. First-match is simplest.
Visibility filtering performance: For very large datasets, should visibility filtering happen at the data-gathering stage (skip loading invisible entities entirely) or at the rendering stage (set visibility mask to 0)? The mask approach is simpler and sufficient for moderate dataset sizes.
MaskData support: The state struct has a comment noting “mask_data_keys deferred due to CPU contour extraction performance”. If GPU-based contour extraction becomes available,
MaskDatarendering could be added as a future phase.
See Also
- TemporalProjectionViewWidget Documentation — Full architecture and feature documentation
- Plot Widget Guide — Shared architecture, axis types, DataManager integration
- LinePlotWidget Roadmap — Group integration pattern (Phase 1), feature coloring (Phase 3)
- ScatterPlotWidget Roadmap — Polygon selection (Phase 3), glyph customization (Phase 4)
- EventPlotWidget Roadmap — Glyph options (Phase 3), TensorData feature coloring (Phase 5)