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 [thumbnailImageSrcMap, setThumbnailImageSrcMap] = useState({});
// Listen for measurement service "adds" (really shouldn't be added until cornerstone-tools "complete")
// const {
// MEASUREMENT_ADDED,
// MEASUREMENT_UPDATED,
// } = measurementService.EVENTS;
// TODO: Listen for measurement service "adds" (really shouldn't be added until cornerstone-tools "complete")
useEffect(() => {
const { unsubscribe } = MeasurementService.subscribe(
MeasurementService.EVENTS.MEASUREMENT_ADDED,
@ -58,11 +53,7 @@ function PanelStudyBrowserTracking({
);
return unsubscribe;
}, []);
// TODO: REPLACE ME
useEffect(() => {
}, [sendTrackedMeasurementsEvent]);
}, [MeasurementService, sendTrackedMeasurementsEvent]);
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 cornerstone from 'cornerstone-core';
import CornerstoneViewport from 'react-cornerstone-viewport';
@ -7,6 +7,11 @@ import { ViewportActionBar } from '@ohif/ui';
import debounce from 'lodash.debounce';
import throttle from 'lodash.throttle';
// const [
// trackedMeasurements,
// sendTrackedMeasurementsEvent,
// ] = useTrackedMeasurements();
// const cine = viewportSpecificData.cine;
@ -15,78 +20,22 @@ import throttle from 'lodash.throttle';
const { StackManager } = OHIF.utils;
class OHIFCornerstoneViewport extends Component {
state = {
viewportData: null,
};
static defaultProps = {
customProps: {},
};
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()');
}
function OHIFCornerstoneViewport({
children,
dataSource,
displaySet,
viewportIndex,
}) {
const [viewportData, setViewportData] = useState(null);
// TODO: Still needed? Better way than import `OHIF` and destructure?
// Why is this managed by `core`?
static destroy() {
console.log('OHIFCornerstoneViewport destroy()');
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,
useEffect(() => {
return () => {
StackManager.clearStacks();
};
}, []);
return viewportData;
};
setStateFromProps() {
const { displaySet } = this.props;
useEffect(() => {
const {
StudyInstanceUID,
displaySetInstanceUID,
@ -103,112 +52,149 @@ class OHIFCornerstoneViewport extends Component {
);
}
this.getViewportData(displaySet).then(viewportData => {
this.setState({
viewportData,
});
_getViewportData(dataSource, displaySet).then(viewportData => {
setViewportData({ ...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() {
this.setStateFromProps();
}
// 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', displaySet)
// const seriesMeta = DicomMetadataStore.getSeries(this.props.displaySet.StudyInstanceUID, '');
// console.log(seriesMeta);
componentDidUpdate(prevProps) {
const { displaySet } = this.props;
const prevDisplaySet = prevProps.displaySet;
const { Modality, SeriesDate, SeriesDescription, SeriesNumber } = displaySet;
const {
PatientID,
PatientName,
PatientSex,
PatientAge,
SliceThickness,
} = displaySet.images[0];
if (
displaySet.displaySetInstanceUID !==
prevDisplaySet.displaySetInstanceUID ||
displaySet.SOPInstanceUID !== prevDisplaySet.SOPInstanceUID ||
displaySet.frameIndex !== prevDisplaySet.frameIndex
) {
this.setStateFromProps();
}
}
render() {
let childrenWithProps = null;
if (!this.state.viewportData) {
return null;
}
const { viewportIndex } = this.props;
const {
imageIds,
currentImageIdIndex,
// If this comes from the instance, would be a better default
// `FrameTime` in the instance
// frameRate = 0,
} = this.state.viewportData.stack;
// TODO: Does it make more sense to use Context?
if (this.props.children && this.props.children.length) {
childrenWithProps = this.props.children.map((child, index) => {
return (
child &&
React.cloneElement(child, {
viewportIndex: this.props.viewportIndex,
key: index,
})
);
});
}
// 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}
</>
);
}
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;