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/app
Viewport components are managed by the ViewportGrid Component. Which Viewport
component is used depends on:
- Hanging Protocols
 - The Layout Configuration
 - Registered SopClassHandlers
 
