Data Bindings And Loading
Generic viewports separate loading, binding, viewport navigation, and render appearance.
The viewport asks its DataProvider to load a logical data id. The loaded data
is passed to the selected render path, and the render path returns a
ViewportDataBinding. The binding contains the mounted runtime rendering plus
callbacks for view state, data presentation, rendering, resize, and cleanup.
Data Provider
A data provider converts an application-level data id into loaded data. For planar viewports this may resolve image ids, volumes, acquisition orientation, metadata, and the internally selected effective render path. The loaded object describes the data; it does not own viewport navigation.
Viewport Data Binding
A binding represents one mounted data/render-path pair. It has a role:
sourcedefines the active view used by the viewport.overlaydraws additional data aligned to the source.
Bindings receive applyViewState(viewState) whenever the viewport navigation
state changes. This replaces the older updateCamera() language because the
binding is applying viewport state, not owning camera truth.
The viewport keeps bindings keyed by display set id. That means tools and application code can update a single mounted display set without reaching into actors or mapper objects:
viewport.setDisplaySetPresentation(petDataId, {
visible: false,
});
viewport.render();
reference is an optional semantic relationship on registered data. It is used
when a binding renders something derived from another object, such as a
segmentation labelmap, volume, image, geometry, or another data id. It is not an
actor id and it is not used as runtime actor identity.
utilities.genericViewportDataSetMetadataProvider.add(labelmapDataId, {
kind: 'planar',
imageIds: labelmapImageIds,
reference: {
kind: 'segmentation',
segmentationId,
representationUID,
labelmapId,
},
});
Presentation Split
Viewport state and data presentation have different ownership:
viewStateis local viewport navigation and layout state.DataPresentationis per-binding appearance such as VOI, opacity, colormap, interpolation, visibility, or playback presentation.
This split lets one viewport pan, zoom, rotate, and navigate once while multiple bindings render with their own appearance settings.
Segmentation Bindings
Labelmap segmentations use the same binding model. The segmentation display
tool creates or resolves labelmap data, registers it as planar data, and mounts
it as an overlay binding. When useSliceRendering is enabled, compatible
volume labelmaps render through the slice/image overlay path instead of the
legacy volume-labelmap actor path.
await segmentation.addLabelmapRepresentationToViewportMap({
[viewportId]: [
{
segmentationId,
config: {
useSliceRendering: true,
},
},
],
});
Internally, that representation maps to overlay data:
await viewport.addDisplaySet(labelmapDataId, {
orientation: viewport.getViewState().orientation,
role: 'overlay',
});
The segmentation remains owned by the tools segmentation state. The viewport only owns the mounted overlay binding used to render it.
Loading Flow
The typical flow is:
- The viewport infers the render path from dataset shape, orientation, and rendering configuration.
- The viewport calls
dataProvider.load(dataId, options)with that internal decision. - The render path resolver selects the runtime path for the loaded data.
- The render path mounts runtime resources and returns a binding.
- The viewport stores the binding with its data id and role.
- The viewport pushes current
viewStateand data presentation into the binding. - The binding projects that state into renderer commands during render or resize.
The viewport remains the owner of navigation state throughout this flow.