OHIFCornerstoneComponent from class component to function component

This commit is contained in:
dannyrb 2020-05-27 23:09:06 -04:00
parent 1c45d643ac
commit 05a0bdc55b
2 changed files with 158 additions and 181 deletions

View File

@ -32,12 +32,7 @@ function PanelStudyBrowserTracking({
const [displaySets, setDisplaySets] = useState([]); const [displaySets, setDisplaySets] = useState([]);
const [thumbnailImageSrcMap, setThumbnailImageSrcMap] = useState({}); const [thumbnailImageSrcMap, setThumbnailImageSrcMap] = useState({});
// Listen for measurement service "adds" (really shouldn't be added until cornerstone-tools "complete") // TODO: Listen for measurement service "adds" (really shouldn't be added until cornerstone-tools "complete")
// const {
// MEASUREMENT_ADDED,
// MEASUREMENT_UPDATED,
// } = measurementService.EVENTS;
useEffect(() => { useEffect(() => {
const { unsubscribe } = MeasurementService.subscribe( const { unsubscribe } = MeasurementService.subscribe(
MeasurementService.EVENTS.MEASUREMENT_ADDED, MeasurementService.EVENTS.MEASUREMENT_ADDED,
@ -58,11 +53,7 @@ function PanelStudyBrowserTracking({
); );
return unsubscribe; return unsubscribe;
}, []); }, [MeasurementService, sendTrackedMeasurementsEvent]);
// TODO: REPLACE ME
useEffect(() => {
}, [sendTrackedMeasurementsEvent]);
const { trackedStudy, trackedSeries } = trackedMeasurements.context; const { trackedStudy, trackedSeries } = trackedMeasurements.context;

View File

@ -1,4 +1,4 @@
import React, { Component } from 'react'; import React, { useEffect, useState } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import cornerstone from 'cornerstone-core'; import cornerstone from 'cornerstone-core';
import CornerstoneViewport from 'react-cornerstone-viewport'; import CornerstoneViewport from 'react-cornerstone-viewport';
@ -7,6 +7,11 @@ import { ViewportActionBar } from '@ohif/ui';
import debounce from 'lodash.debounce'; import debounce from 'lodash.debounce';
import throttle from 'lodash.throttle'; import throttle from 'lodash.throttle';
// const [
// trackedMeasurements,
// sendTrackedMeasurementsEvent,
// ] = useTrackedMeasurements();
// const cine = viewportSpecificData.cine; // const cine = viewportSpecificData.cine;
@ -15,78 +20,22 @@ import throttle from 'lodash.throttle';
const { StackManager } = OHIF.utils; const { StackManager } = OHIF.utils;
class OHIFCornerstoneViewport extends Component { function OHIFCornerstoneViewport({
state = { children,
viewportData: null, dataSource,
}; displaySet,
viewportIndex,
static defaultProps = { }) {
customProps: {}, const [viewportData, setViewportData] = useState(null);
};
static propTypes = {
displaySet: PropTypes.object,
viewportIndex: PropTypes.number,
dataSource: PropTypes.object,
children: PropTypes.node,
customProps: PropTypes.object,
};
static name = 'OHIFCornerstoneViewport';
static init() {
console.log('OHIFCornerstoneViewport init()');
}
// TODO: Still needed? Better way than import `OHIF` and destructure? // TODO: Still needed? Better way than import `OHIF` and destructure?
// Why is this managed by `core`? // Why is this managed by `core`?
static destroy() { useEffect(() => {
console.log('OHIFCornerstoneViewport destroy()'); return () => {
StackManager.clearStacks(); StackManager.clearStacks();
}
/**
* Obtain the CornerstoneTools Stack for the specified display set.
*
* @param {Object} displaySet
* @param {Object} dataSource
* @return {Object} CornerstoneTools Stack
*/
static getCornerstoneStack(displaySet, dataSource) {
const { frameIndex } = displaySet;
// Get stack from Stack Manager
const storedStack = StackManager.findOrCreateStack(displaySet, dataSource);
// Clone the stack here so we don't mutate it
const stack = Object.assign({}, storedStack);
stack.currentImageIdIndex = frameIndex;
return stack;
}
getViewportData = async displaySet => {
let viewportData;
const { dataSource } = this.props;
const stack = OHIFCornerstoneViewport.getCornerstoneStack(
displaySet,
dataSource
);
viewportData = {
StudyInstanceUID: displaySet.StudyInstanceUID,
displaySetInstanceUID: displaySet.displaySetInstanceUID,
stack,
}; };
}, []);
return viewportData; useEffect(() => {
};
setStateFromProps() {
const { displaySet } = this.props;
const { const {
StudyInstanceUID, StudyInstanceUID,
displaySetInstanceUID, displaySetInstanceUID,
@ -103,112 +52,149 @@ class OHIFCornerstoneViewport extends Component {
); );
} }
this.getViewportData(displaySet).then(viewportData => { _getViewportData(dataSource, displaySet).then(viewportData => {
this.setState({ setViewportData({ ...viewportData });
viewportData, });
}); }, [
displaySet,
displaySet.StudyInstanceUID,
displaySet.displaySetInstanceUID,
displaySet.frameIndex,
]);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
let childrenWithProps = null;
if (!viewportData) {
return null;
}
const {
imageIds,
currentImageIdIndex,
// If this comes from the instance, would be a better default
// `FrameTime` in the instance
// frameRate = 0,
} = viewportData.stack;
// TODO: Does it make more sense to use Context?
if (children && children.length) {
childrenWithProps = children.map((child, index) => {
return (
child &&
React.cloneElement(child, {
viewportIndex,
key: index,
})
);
}); });
} }
componentDidMount() { // We have...
this.setStateFromProps(); // StudyInstanceUid, DisplaySetInstanceUid
} // Use displaySetInstanceUid --> SeriesInstanceUid
// Get meta for series, map to actionBar
// const displaySet = DisplaySetService.getDisplaySetByUID(
// dSet.displaySetInstanceUID
// );
// TODO: This display contains the meta for all instances.
// That can't be right...
console.log('DISPLAYSET', displaySet)
// const seriesMeta = DicomMetadataStore.getSeries(this.props.displaySet.StudyInstanceUID, '');
// console.log(seriesMeta);
componentDidUpdate(prevProps) { const { Modality, SeriesDate, SeriesDescription, SeriesNumber } = displaySet;
const { displaySet } = this.props; const {
const prevDisplaySet = prevProps.displaySet; PatientID,
PatientName,
PatientSex,
PatientAge,
SliceThickness,
} = displaySet.images[0];
if ( return (
displaySet.displaySetInstanceUID !== <>
prevDisplaySet.displaySetInstanceUID || <ViewportActionBar
displaySet.SOPInstanceUID !== prevDisplaySet.SOPInstanceUID || onSeriesChange={direction => alert(`Series ${direction}`)}
displaySet.frameIndex !== prevDisplaySet.frameIndex studyData={{
) { label: '',
this.setStateFromProps(); isTracked: false,
} isLocked: false,
} studyDate: SeriesDate, // TODO: This is series date. Is that ok?
currentSeries: SeriesNumber,
render() { seriesDescription: SeriesDescription,
let childrenWithProps = null; modality: Modality,
patientInformation: {
if (!this.state.viewportData) { patientName: PatientName ? PatientName.Alphabetic || '' : '',
return null; patientSex: PatientSex || '',
} patientAge: PatientAge || '',
const { viewportIndex } = this.props; MRN: PatientID || '',
const { thickness: `${SliceThickness}mm`,
imageIds, spacing: '',
currentImageIdIndex, scanner: '',
// If this comes from the instance, would be a better default },
// `FrameTime` in the instance }}
// frameRate = 0, />
} = this.state.viewportData.stack; <CornerstoneViewport
viewportIndex={viewportIndex}
// TODO: Does it make more sense to use Context? imageIds={imageIds}
if (this.props.children && this.props.children.length) { imageIdIndex={currentImageIdIndex}
childrenWithProps = this.props.children.map((child, index) => { // TODO: ViewportGrid Context?
return ( isActive={true} // todo
child && isStackPrefetchEnabled={true} // todo
React.cloneElement(child, { isPlaying={false}
viewportIndex: this.props.viewportIndex, frameRate={24}
key: index, />
}) {childrenWithProps}
); </>
}); );
}
// We have...
// StudyInstanceUid, DisplaySetInstanceUid
// Use displaySetInstanceUid --> SeriesInstanceUid
// Get meta for series, map to actionBar
// const displaySet = DisplaySetService.getDisplaySetByUID(
// dSet.displaySetInstanceUID
// );
// TODO: This display contains the meta for all instances.
// That can't be right...
console.log('DISPLAYSET', this.props.displaySet)
const seriesMeta = DicomMetadataStore.getSeries(this.props.displaySet.StudyInstanceUID, '');
console.log(seriesMeta);
const { Modality, SeriesDate, SeriesDescription, SeriesNumber } = this.props.displaySet;
const { PatientID, PatientName, PatientSex, PatientAge, SliceThickness, } = this.props.displaySet.images[0];
return (
<>
<ViewportActionBar
onSeriesChange={direction => alert(`Series ${direction}`)}
studyData={{
label: '',
isTracked: false,
isLocked: false,
studyDate: SeriesDate, // TODO: This is series date. Is that ok?
currentSeries: SeriesNumber,
seriesDescription: SeriesDescription,
modality: Modality,
patientInformation: {
patientName: PatientName ? PatientName.Alphabetic || '' : '',
patientSex: PatientSex || '',
patientAge: PatientAge || '',
MRN: PatientID || '',
thickness: `${SliceThickness}mm`,
spacing: '',
scanner: '',
},
}}
/>
<CornerstoneViewport
viewportIndex={viewportIndex}
imageIds={imageIds}
imageIdIndex={currentImageIdIndex}
// TODO: ViewportGrid Context?
isActive={true} // todo
isStackPrefetchEnabled={true} // todo
isPlaying={false}
frameRate={24}
/>
{childrenWithProps}
</>
);
}
} }
OHIFCornerstoneViewport.propTypes = {
displaySet: PropTypes.object.isRequired,
viewportIndex: PropTypes.number.isRequired,
dataSource: PropTypes.object,
children: PropTypes.node,
customProps: PropTypes.object,
};
OHIFCornerstoneViewport.defaultProps = {
customProps: {},
};
/**
* Obtain the CornerstoneTools Stack for the specified display set.
*
* @param {Object} displaySet
* @param {Object} dataSource
* @return {Object} CornerstoneTools Stack
*/
function _getCornerstoneStack(displaySet, dataSource) {
const { frameIndex } = displaySet;
// Get stack from Stack Manager
const storedStack = StackManager.findOrCreateStack(displaySet, dataSource);
// Clone the stack here so we don't mutate it
const stack = Object.assign({}, storedStack);
stack.currentImageIdIndex = frameIndex;
return stack;
}
async function _getViewportData(dataSource, displaySet) {
let viewportData;
const stack = _getCornerstoneStack(displaySet, dataSource);
viewportData = {
StudyInstanceUID: displaySet.StudyInstanceUID,
displaySetInstanceUID: displaySet.displaySetInstanceUID,
stack,
};
return viewportData;
};
export default OHIFCornerstoneViewport; export default OHIFCornerstoneViewport;