Module: Viewport
Overview​
Viewports consume a displaySet and display/allow the user to interact with data.
An extension can register a Viewport Module by defining a getViewportModule
method that returns a React component. Currently, we use viewport components to
add support for:
- 2D Medical Image Viewing (cornerstone ext.)
- Structured Reports as SR (DICOM SR ext.)
- Encapsulated PDFs as PDFs (DICOM pdf ext.)
The general pattern is that a mode can define which Viewport to use for which
specific SOPClassHandlerUID, so if you want to fork just a single Viewport
component for a specialized mode, this is possible.
// displaySet, viewportIndex, dataSource
const getViewportModule = () => {
const wrappedViewport = props => {
return (
<ExampleViewport
{...props}
onEvent={data => {
commandsManager.runCommand('commandName', data);
}}
/>
);
};
return [{ name: 'example', component: wrappedViewport }];
};
Example Viewport Component​
A simplified version of the tracked OHIFCornerstoneViewport is shown below, which
creates a cornerstone viewport:
Not in OHIF version 3.1 we use displaySets in the props which is new compared to
the previous version (3.0) which uses displaySet. This is due to the fact that
we are moving to a new data model that can render fused images in a single viewport.
function TrackedCornerstoneViewport({
children,
dataSource,
displaySets,
viewportIndex,
servicesManager,
extensionManager,
commandsManager,
}) {
return (
<div className="viewport-wrapper">
/** Resize Detector */
<ReactResizeDetector
handleWidth
handleHeight
skipOnMount={true} // Todo: make these configurable
refreshMode={'debounce'}
refreshRate={100}
onResize={onResize}
targetRef={elementRef.current}
/>
/** Div For displaying image */
<div
className="cornerstone-viewport-element"
style={{ height: '100%', width: '100%' }}
onContextMenu={e => e.preventDefault()}
onMouseDown={e => e.preventDefault()}
ref={elementRef}
></div>
</div>
);
}
@ohif/viewer​
Viewport components are managed by the ViewportGrid Component. Which Viewport
component is used depends on:
- Hanging Protocols
- The Layout Configuration
- Registered SopClassHandlers
