From 765abfd5721636cd612c12af39ad8ceca4119c78 Mon Sep 17 00:00:00 2001 From: Erik Ziegler Date: Sat, 1 Dec 2018 12:27:36 -0500 Subject: [PATCH] wip on react transition 6 --- .../CornerstoneViewport.js | 38 ++++++---- .../ViewportOrientationMarkers.js | 72 +++++++++++++++++-- .../ViewportOrientationMarkers.styl | 13 ++-- .../lib/classes/StudyLoadingListener.js | 4 +- .../lib/classes/metadata/StudyMetadata.js | 20 ++---- 5 files changed, 105 insertions(+), 42 deletions(-) diff --git a/Packages/ohif-viewerbase/client/components/viewer/CornerstoneViewport/CornerstoneViewport.js b/Packages/ohif-viewerbase/client/components/viewer/CornerstoneViewport/CornerstoneViewport.js index 09015d8ea..084ed8d7f 100644 --- a/Packages/ohif-viewerbase/client/components/viewer/CornerstoneViewport/CornerstoneViewport.js +++ b/Packages/ohif-viewerbase/client/components/viewer/CornerstoneViewport/CornerstoneViewport.js @@ -38,29 +38,36 @@ function initializeTools(tools) { }); } -const scrollToIndex = cornerstoneTools.import('util/scrollToIndex'); - -class CornerstoneViewport extends Component { - constructor(props) { - super(props); - - const { displaySetInstanceUid, studyInstanceUid } = this.props.viewportData; +function getCornerstoneStack(viewportData) { + const { displaySetInstanceUid, studyInstanceUid } = viewportData; // Create shortcut to displaySet const study = OHIF.viewer.Studies.findBy({ studyInstanceUid }); const displaySet = study.displaySets.find(set => { - return set.displaySetInstanceUid === displaySetInstanceUid; + return set.displaySetInstanceUid === displaySetInstanceUid; }); // Get stack from Stack Manager const stack = StackManager.findOrCreateStack(study, displaySet); stack.currentImageIdIndex = 0; + return stack +} + + +const scrollToIndex = cornerstoneTools.import('util/scrollToIndex'); + +class CornerstoneViewport extends Component { + constructor(props) { + super(props); + + const stack = getCornerstoneStack(this.props.viewportData) + // TODO: Allow viewport as a prop this.state = { stack, - displaySetInstanceUid, + displaySetInstanceUid: this.props.viewportData.displaySetInstanceUid, imageId: stack.imageIds[0], viewportHeight: '100%', isLoading: false,//true, @@ -138,7 +145,10 @@ class CornerstoneViewport extends Component { imageId={this.state.imageId} numImagesLoaded={this.state.numImagesLoaded} /> - +
Please drag a stack here to view images. @@ -425,13 +435,12 @@ class CornerstoneViewport extends Component { // Get stack from Stack Manager const stack = StackManager.findOrCreateStack(study, displaySet); - const stackData = cornerstoneTools.getToolState(this.element, 'stack'); let currentStack = stackData && stackData.data[0]; if (!currentStack) { currentStack = { - currentImageIdIndex: currentImageIdIndex, + currentImageIdIndex, imageIds: stack.imageIds }; @@ -443,7 +452,7 @@ class CornerstoneViewport extends Component { currentStack.imageIds = stack.imageIds; } - const imageId = currentStack.imageIds[currentStack.currentImageIdIndex]; + const imageId = currentStack.imageIds[currentImageIdIndex]; this.setState({ displaySetInstanceUid, @@ -452,6 +461,7 @@ class CornerstoneViewport extends Component { imageId }); + cornerstoneTools.stackPrefetch.disable(this.element); cornerstone.loadAndCacheImage(imageId).then(image => { try { cornerstone.getEnabledElement(this.element); @@ -461,7 +471,6 @@ class CornerstoneViewport extends Component { return; } - const viewport = cornerstone.getDefaultViewportForImage(this.element, image); // Workaround for Cornerstone issue #304 @@ -472,7 +481,6 @@ class CornerstoneViewport extends Component { cornerstone.displayImage(this.element, image, viewport); - cornerstoneTools.stackPrefetch.disable(this.element); cornerstoneTools.stackPrefetch.enable(this.element); }); } diff --git a/Packages/ohif-viewerbase/client/components/viewer/ViewportOrientationMarkers/ViewportOrientationMarkers.js b/Packages/ohif-viewerbase/client/components/viewer/ViewportOrientationMarkers/ViewportOrientationMarkers.js index 6240b9f0b..60f77ca85 100644 --- a/Packages/ohif-viewerbase/client/components/viewer/ViewportOrientationMarkers/ViewportOrientationMarkers.js +++ b/Packages/ohif-viewerbase/client/components/viewer/ViewportOrientationMarkers/ViewportOrientationMarkers.js @@ -1,19 +1,83 @@ import { Component } from 'react'; import React from 'react'; -//import PropTypes from 'prop-types'; +import PropTypes from 'prop-types'; import './ViewportOrientationMarkers.styl'; +/** + * Computes the orientation labels on a Cornerstone-enabled Viewport element + * when the viewport settings change (e.g. when a horizontal flip or a rotation occurs) + * + * @param imageId The Cornerstone ImageId + * @param viewport The current viewport + */ +export function getOrientationMarkers(imageId, viewport) { + const imagePlane = cornerstone.metaData.get('imagePlane', imageId); + if (!imagePlane || !imagePlane.rowCosines || !imagePlane.columnCosines) { + return; + } + + const rowString = cornerstoneTools.orientation.getOrientationString(imagePlane.rowCosines); + const columnString = cornerstoneTools.orientation.getOrientationString(imagePlane.columnCosines); + const oppositeRowString = cornerstoneTools.orientation.invertOrientationString(rowString); + const oppositeColumnString = cornerstoneTools.orientation.invertOrientationString(columnString); + + const markers = { + top: oppositeColumnString, + left: oppositeRowString + }; + + // If any vertical or horizontal flips are applied, change the orientation strings ahead of + // the rotation applications + if (viewport.vflip) { + markers.top = cornerstoneTools.orientation.invertOrientationString(markers.top); + } + + if (viewport.hflip) { + markers.left = cornerstoneTools.orientation.invertOrientationString(markers.left); + } + + // Swap the labels accordingly if the viewport has been rotated + // This could be done in a more complex way for intermediate rotation values (e.g. 45 degrees) + if (viewport.rotation === 90 || viewport.rotation === -270) { + return { + top: markers.left, + left: cornerstoneTools.orientation.invertOrientationString(markers.top) + }; + } else if (viewport.rotation === -90 || viewport.rotation === 270) { + return { + top: cornerstoneTools.orientation.invertOrientationString(markers.left), + left: markers.top + }; + } else if (viewport.rotation === 180 || viewport.rotation === -180) { + return { + top: cornerstoneTools.orientation.invertOrientationString(markers.top), + left: cornerstoneTools.orientation.invertOrientationString(markers.left) + }; + } + + return markers; +} + class ViewportOrientationMarkers extends Component { render() { + const { imageId, viewport } = this.props; + const markers = getOrientationMarkers(imageId, viewport); return ( -
-
+
+
+ {markers.top}
-
+
+ {markers.left}
); } }; +ViewportOrientationMarkers.propTypes = { + imageId: PropTypes.string.isRequired, + viewport: PropTypes.object.isRequired +}; + export default ViewportOrientationMarkers; diff --git a/Packages/ohif-viewerbase/client/components/viewer/ViewportOrientationMarkers/ViewportOrientationMarkers.styl b/Packages/ohif-viewerbase/client/components/viewer/ViewportOrientationMarkers/ViewportOrientationMarkers.styl index 740449286..cf6dc5a2d 100644 --- a/Packages/ohif-viewerbase/client/components/viewer/ViewportOrientationMarkers/ViewportOrientationMarkers.styl +++ b/Packages/ohif-viewerbase/client/components/viewer/ViewportOrientationMarkers/ViewportOrientationMarkers.styl @@ -1,18 +1,17 @@ -.viewportOrientationMarkers +.ViewportOrientationMarkers pointer-events: none // Necessary for click-through to cornerstone element below - + font-size: 15px color: rgb(204, 204, 204) line-height: 18px - .orientationMarker + .orientation-marker position: absolute - .topMid + .top-mid top: 5px left: 50% - - .leftMid + + .left-mid top: 47% left: 5px - \ No newline at end of file diff --git a/Packages/ohif-viewerbase/client/lib/classes/StudyLoadingListener.js b/Packages/ohif-viewerbase/client/lib/classes/StudyLoadingListener.js index f5a840cfe..961312ae8 100644 --- a/Packages/ohif-viewerbase/client/lib/classes/StudyLoadingListener.js +++ b/Packages/ohif-viewerbase/client/lib/classes/StudyLoadingListener.js @@ -347,9 +347,7 @@ class StudyLoadingListener { return; } - for (let i = 0; i < studies.length; i++) { - this.addStudy(studies[i]); - } + studies.forEach(study => this.addStudy(study)); } clear() { diff --git a/Packages/ohif-viewerbase/client/lib/classes/metadata/StudyMetadata.js b/Packages/ohif-viewerbase/client/lib/classes/metadata/StudyMetadata.js index ea2d82c88..b04c58172 100644 --- a/Packages/ohif-viewerbase/client/lib/classes/metadata/StudyMetadata.js +++ b/Packages/ohif-viewerbase/client/lib/classes/metadata/StudyMetadata.js @@ -244,20 +244,18 @@ export class StudyMetadata extends Metadata { } /** - * It sorts the series based on display sets order. Each series must be an instance + * It sorts the series based on display sets order. Each series must be an instance * of SeriesMetadata and each display sets must be an instance of ImageSet. - * Useful example of usage: - * Study data provided by backend does not sort series at all and client-side + * Useful example of usage: + * Study data provided by backend does not sort series at all and client-side * needs series sorted by the same criteria used for sorting display sets. */ sortSeriesByDisplaySets() { - // Object for mapping display sets' index by seriesInstanceUid const displaySetsMapping = {}; // Loop through each display set to create the mapping this.forEachDisplaySet( (displaySet, index) => { - if (!(displaySet instanceof ImageSet)) { throw new OHIFError(`StudyMetadata::sortSeriesByDisplaySets display set at index ${index} is not an instance of ImageSet`); } @@ -271,8 +269,7 @@ export class StudyMetadata extends Metadata { // Clone of actual series const actualSeries = this.getSeries(); - actualSeries.forEach( (series, index) => { - + actualSeries.forEach((series, index) => { if (!(series instanceof SeriesMetadata)) { throw new OHIFError(`StudyMetadata::sortSeriesByDisplaySets series at index ${index} is not an instance of SeriesMetadata`); } @@ -343,7 +340,7 @@ export class StudyMetadata extends Metadata { * The callback is passed two arguments: instance (a InstanceMetadata instance) and index (the integer * index of the instance within the current series) * @param {function} callback The callback function which will be invoked for each instance instance. - * @returns {Object} Result object containing series (SeriesMetadata) and instance (InstanceMetadata) + * @returns {Object} Result object containing series (SeriesMetadata) and instance (InstanceMetadata) * objects or an empty object if not found. */ findSeriesAndInstanceByInstance(callback) { @@ -371,7 +368,7 @@ export class StudyMetadata extends Metadata { /** * Find series by instance using the supplied callback as criteria. The callback is passed - * two arguments: instance (a InstanceMetadata instance) and index (the integer index of + * two arguments: instance (a InstanceMetadata instance) and index (the integer index of * the instance within its series) * @param {function} callback The callback function which will be invoked for each instance. * @returns {SeriesMetadata|undefined} If a series is found based on callback criteria it @@ -385,7 +382,7 @@ export class StudyMetadata extends Metadata { /** * Find an instance using the supplied callback as criteria. The callback is passed - * two arguments: instance (a InstanceMetadata instance) and index (the integer index of + * two arguments: instance (a InstanceMetadata instance) and index (the integer index of * the instance within its series) * @param {function} callback The callback function which will be invoked for each instance. * @returns {InstanceMetadata|undefined} If an instance is found based on callback criteria it @@ -396,7 +393,4 @@ export class StudyMetadata extends Metadata { return result.instance; } - - - }