[OHIF 284] - JumpToMeasurement + prevent layout change on scroll Prevent layout change on scroll (#1889)
* No more setting on debounce, jumpToMeasurement service set up. * Fix bug causing a race condition sometimes if you click super fast. * Optimise rendering of Tracking viewport slightly. * element => targetElement * Remove complete TODO * Respond to reviewer comments. * Fix e2e workflow. * Fix regression that removed highlighting on jump to. * Make sure jump to works from panel as well as viewport. * Fix typo and remove debugger. Co-authored-by: Danny Brown <danny.ri.brown@gmail.com>
This commit is contained in:
parent
4985fbf5a6
commit
a4f286feee
@ -35,7 +35,7 @@
|
|||||||
"cornerstone-math": "^0.1.8",
|
"cornerstone-math": "^0.1.8",
|
||||||
"cornerstone-tools": "4.18.1",
|
"cornerstone-tools": "4.18.1",
|
||||||
"cornerstone-wado-image-loader": "^3.1.2",
|
"cornerstone-wado-image-loader": "^3.1.2",
|
||||||
"dcmjs": "0.16.0",
|
"dcmjs": "0.16.1",
|
||||||
"dicom-parser": "^1.8.3",
|
"dicom-parser": "^1.8.3",
|
||||||
"hammerjs": "^2.0.8",
|
"hammerjs": "^2.0.8",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
|
|||||||
@ -83,8 +83,6 @@ const commandsModule = ({ servicesManager }) => {
|
|||||||
const enabledElement = _getActiveViewportsEnabledElement();
|
const enabledElement = _getActiveViewportsEnabledElement();
|
||||||
|
|
||||||
if (enabledElement) {
|
if (enabledElement) {
|
||||||
debugger;
|
|
||||||
|
|
||||||
const cancelActiveManipulatorsForElement = cornerstoneTools.getModule(
|
const cancelActiveManipulatorsForElement = cornerstoneTools.getModule(
|
||||||
'manipulatorState'
|
'manipulatorState'
|
||||||
).setters.cancelActiveManipulatorsForElement;
|
).setters.cancelActiveManipulatorsForElement;
|
||||||
@ -284,32 +282,6 @@ const commandsModule = ({ servicesManager }) => {
|
|||||||
cornerstone.setViewport(enabledElement, viewport);
|
cornerstone.setViewport(enabledElement, viewport);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
jumpToImage: ({
|
|
||||||
StudyInstanceUID,
|
|
||||||
SOPInstanceUID,
|
|
||||||
imageIndex,
|
|
||||||
activeViewportIndex,
|
|
||||||
}) => {
|
|
||||||
const study = studyMetadataManager.get(StudyInstanceUID);
|
|
||||||
|
|
||||||
const displaySet = study.findDisplaySet(ds => {
|
|
||||||
return (
|
|
||||||
ds.images &&
|
|
||||||
ds.images.find(i => i.getSOPInstanceUID() === SOPInstanceUID)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
displaySet.SOPInstanceUID = SOPInstanceUID;
|
|
||||||
displaySet.imageIndex = imageIndex;
|
|
||||||
|
|
||||||
window.store.dispatch(
|
|
||||||
setViewportSpecificData(activeViewportIndex, displaySet)
|
|
||||||
);
|
|
||||||
|
|
||||||
cornerstone.getEnabledElements().forEach(enabledElement => {
|
|
||||||
cornerstone.updateImage(enabledElement.element);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const definitions = {
|
const definitions = {
|
||||||
|
|||||||
@ -18,7 +18,11 @@ import { setEnabledElement } from './state';
|
|||||||
* @param {Object|Array} configuration.csToolsConfig
|
* @param {Object|Array} configuration.csToolsConfig
|
||||||
*/
|
*/
|
||||||
export default function init({ servicesManager, configuration }) {
|
export default function init({ servicesManager, configuration }) {
|
||||||
const { UIDialogService, MeasurementService } = servicesManager.services;
|
const {
|
||||||
|
UIDialogService,
|
||||||
|
MeasurementService,
|
||||||
|
DisplaySetService,
|
||||||
|
} = servicesManager.services;
|
||||||
|
|
||||||
const callInputDialog = (data, event, callback) => {
|
const callInputDialog = (data, event, callback) => {
|
||||||
if (UIDialogService) {
|
if (UIDialogService) {
|
||||||
@ -137,7 +141,7 @@ export default function init({ servicesManager, configuration }) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
/* Measurement Service */
|
/* Measurement Service */
|
||||||
_connectToolsToMeasurementService(MeasurementService);
|
_connectToolsToMeasurementService(MeasurementService, DisplaySetService);
|
||||||
|
|
||||||
/* Add extension tools configuration here. */
|
/* Add extension tools configuration here. */
|
||||||
const internalToolsConfig = {
|
const internalToolsConfig = {
|
||||||
@ -220,21 +224,21 @@ export default function init({ servicesManager, configuration }) {
|
|||||||
csTools.setToolEnabled('Overlay', {});
|
csTools.setToolEnabled('Overlay', {});
|
||||||
}
|
}
|
||||||
|
|
||||||
const _initMeasurementService = measurementService => {
|
const _initMeasurementService = (MeasurementService, DisplaySetService) => {
|
||||||
/* Initialization */
|
/* Initialization */
|
||||||
const {
|
const {
|
||||||
Length,
|
Length,
|
||||||
Bidirectional,
|
Bidirectional,
|
||||||
EllipticalRoi,
|
EllipticalRoi,
|
||||||
ArrowAnnotate,
|
ArrowAnnotate,
|
||||||
} = measurementServiceMappingsFactory(measurementService);
|
} = measurementServiceMappingsFactory(MeasurementService, DisplaySetService);
|
||||||
const csToolsVer4MeasurementSource = measurementService.createSource(
|
const csToolsVer4MeasurementSource = MeasurementService.createSource(
|
||||||
'CornerstoneTools',
|
'CornerstoneTools',
|
||||||
'4'
|
'4'
|
||||||
);
|
);
|
||||||
|
|
||||||
/* Mappings */
|
/* Mappings */
|
||||||
measurementService.addMapping(
|
MeasurementService.addMapping(
|
||||||
csToolsVer4MeasurementSource,
|
csToolsVer4MeasurementSource,
|
||||||
'Length',
|
'Length',
|
||||||
Length.matchingCriteria,
|
Length.matchingCriteria,
|
||||||
@ -242,7 +246,7 @@ const _initMeasurementService = measurementService => {
|
|||||||
Length.toMeasurement
|
Length.toMeasurement
|
||||||
);
|
);
|
||||||
|
|
||||||
measurementService.addMapping(
|
MeasurementService.addMapping(
|
||||||
csToolsVer4MeasurementSource,
|
csToolsVer4MeasurementSource,
|
||||||
'Bidirectional',
|
'Bidirectional',
|
||||||
Bidirectional.matchingCriteria,
|
Bidirectional.matchingCriteria,
|
||||||
@ -250,7 +254,7 @@ const _initMeasurementService = measurementService => {
|
|||||||
Bidirectional.toMeasurement
|
Bidirectional.toMeasurement
|
||||||
);
|
);
|
||||||
|
|
||||||
measurementService.addMapping(
|
MeasurementService.addMapping(
|
||||||
csToolsVer4MeasurementSource,
|
csToolsVer4MeasurementSource,
|
||||||
'EllipticalRoi',
|
'EllipticalRoi',
|
||||||
EllipticalRoi.matchingCriteria,
|
EllipticalRoi.matchingCriteria,
|
||||||
@ -258,7 +262,7 @@ const _initMeasurementService = measurementService => {
|
|||||||
EllipticalRoi.toMeasurement
|
EllipticalRoi.toMeasurement
|
||||||
);
|
);
|
||||||
|
|
||||||
measurementService.addMapping(
|
MeasurementService.addMapping(
|
||||||
csToolsVer4MeasurementSource,
|
csToolsVer4MeasurementSource,
|
||||||
'ArrowAnnotate',
|
'ArrowAnnotate',
|
||||||
ArrowAnnotate.matchingCriteria,
|
ArrowAnnotate.matchingCriteria,
|
||||||
@ -269,12 +273,16 @@ const _initMeasurementService = measurementService => {
|
|||||||
return csToolsVer4MeasurementSource;
|
return csToolsVer4MeasurementSource;
|
||||||
};
|
};
|
||||||
|
|
||||||
const _connectToolsToMeasurementService = measurementService => {
|
const _connectToolsToMeasurementService = (
|
||||||
|
MeasurementService,
|
||||||
|
DisplaySetService
|
||||||
|
) => {
|
||||||
const csToolsVer4MeasurementSource = _initMeasurementService(
|
const csToolsVer4MeasurementSource = _initMeasurementService(
|
||||||
measurementService
|
MeasurementService,
|
||||||
|
DisplaySetService
|
||||||
);
|
);
|
||||||
_connectMeasurementServiceToTools(
|
_connectMeasurementServiceToTools(
|
||||||
measurementService,
|
MeasurementService,
|
||||||
csToolsVer4MeasurementSource
|
csToolsVer4MeasurementSource
|
||||||
);
|
);
|
||||||
const { addOrUpdate, remove } = csToolsVer4MeasurementSource;
|
const { addOrUpdate, remove } = csToolsVer4MeasurementSource;
|
||||||
@ -330,9 +338,9 @@ const _connectToolsToMeasurementService = measurementService => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const { MEASUREMENTS_CLEARED } = measurementService.EVENTS;
|
const { MEASUREMENTS_CLEARED } = MeasurementService.EVENTS;
|
||||||
|
|
||||||
measurementService.subscribe(MEASUREMENTS_CLEARED, () => {
|
MeasurementService.subscribe(MEASUREMENTS_CLEARED, () => {
|
||||||
cornerstoneTools.globalImageIdSpecificToolStateManager.restoreToolState(
|
cornerstoneTools.globalImageIdSpecificToolStateManager.restoreToolState(
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
@ -350,16 +358,16 @@ const _connectToolsToMeasurementService = measurementService => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const _connectMeasurementServiceToTools = (
|
const _connectMeasurementServiceToTools = (
|
||||||
measurementService,
|
MeasurementService,
|
||||||
measurementSource
|
measurementSource
|
||||||
) => {
|
) => {
|
||||||
const {
|
const {
|
||||||
MEASUREMENTS_CLEARED,
|
MEASUREMENTS_CLEARED,
|
||||||
MEASUREMENT_REMOVED,
|
MEASUREMENT_REMOVED,
|
||||||
} = measurementService.EVENTS;
|
} = MeasurementService.EVENTS;
|
||||||
const sourceId = measurementSource.id;
|
const sourceId = measurementSource.id;
|
||||||
|
|
||||||
measurementService.subscribe(MEASUREMENTS_CLEARED, () => {
|
MeasurementService.subscribe(MEASUREMENTS_CLEARED, () => {
|
||||||
cornerstoneTools.globalImageIdSpecificToolStateManager.restoreToolState({});
|
cornerstoneTools.globalImageIdSpecificToolStateManager.restoreToolState({});
|
||||||
cornerstone.getEnabledElements().forEach(enabledElement => {
|
cornerstone.getEnabledElements().forEach(enabledElement => {
|
||||||
cornerstone.updateImage(enabledElement.element);
|
cornerstone.updateImage(enabledElement.element);
|
||||||
@ -367,7 +375,7 @@ const _connectMeasurementServiceToTools = (
|
|||||||
});
|
});
|
||||||
|
|
||||||
/* TODO: Remove per measurement
|
/* TODO: Remove per measurement
|
||||||
measurementService.subscribe(MEASUREMENT_REMOVED,
|
MeasurementService.subscribe(MEASUREMENT_REMOVED,
|
||||||
({ source, measurement }) => {
|
({ source, measurement }) => {
|
||||||
if ([sourceId].includes(source.id)) {
|
if ([sourceId].includes(source.id)) {
|
||||||
// const annotation = getAnnotation('Length', measurement.id);
|
// const annotation = getAnnotation('Length', measurement.id);
|
||||||
@ -380,9 +388,9 @@ const _connectMeasurementServiceToTools = (
|
|||||||
// const {
|
// const {
|
||||||
// MEASUREMENT_ADDED,
|
// MEASUREMENT_ADDED,
|
||||||
// MEASUREMENT_UPDATED,
|
// MEASUREMENT_UPDATED,
|
||||||
// } = measurementService.EVENTS;
|
// } = MeasurementService.EVENTS;
|
||||||
|
|
||||||
// measurementService.subscribe(
|
// MeasurementService.subscribe(
|
||||||
// MEASUREMENT_ADDED,
|
// MEASUREMENT_ADDED,
|
||||||
// ({ source, measurement }) => {
|
// ({ source, measurement }) => {
|
||||||
// if (![sourceId].includes(source.id)) {
|
// if (![sourceId].includes(source.id)) {
|
||||||
@ -397,7 +405,7 @@ const _connectMeasurementServiceToTools = (
|
|||||||
// }
|
// }
|
||||||
// );
|
// );
|
||||||
|
|
||||||
// measurementService.subscribe(
|
// MeasurementService.subscribe(
|
||||||
// MEASUREMENT_UPDATED,
|
// MEASUREMENT_UPDATED,
|
||||||
// ({ source, measurement }) => {
|
// ({ source, measurement }) => {
|
||||||
// if (![sourceId].includes(source.id)) {
|
// if (![sourceId].includes(source.id)) {
|
||||||
|
|||||||
@ -6,7 +6,11 @@ const ArrowAnnotate = {
|
|||||||
toAnnotation: (measurement, definition) => {
|
toAnnotation: (measurement, definition) => {
|
||||||
// TODO -> Implement when this is needed.
|
// TODO -> Implement when this is needed.
|
||||||
},
|
},
|
||||||
toMeasurement: (csToolsAnnotation, getValueTypeFromToolType) => {
|
toMeasurement: (
|
||||||
|
csToolsAnnotation,
|
||||||
|
DisplaySetService,
|
||||||
|
getValueTypeFromToolType
|
||||||
|
) => {
|
||||||
const { element, measurementData } = csToolsAnnotation;
|
const { element, measurementData } = csToolsAnnotation;
|
||||||
const tool =
|
const tool =
|
||||||
csToolsAnnotation.toolType ||
|
csToolsAnnotation.toolType ||
|
||||||
@ -26,6 +30,11 @@ const ArrowAnnotate = {
|
|||||||
StudyInstanceUID,
|
StudyInstanceUID,
|
||||||
} = getSOPInstanceAttributes(element);
|
} = getSOPInstanceAttributes(element);
|
||||||
|
|
||||||
|
const displaySet = DisplaySetService.getDisplaySetForSOPInstanceUID(
|
||||||
|
SOPInstanceUID,
|
||||||
|
SeriesInstanceUID
|
||||||
|
);
|
||||||
|
|
||||||
const points = [];
|
const points = [];
|
||||||
points.push(measurementData.handles);
|
points.push(measurementData.handles);
|
||||||
|
|
||||||
@ -35,6 +44,7 @@ const ArrowAnnotate = {
|
|||||||
FrameOfReferenceUID,
|
FrameOfReferenceUID,
|
||||||
referenceSeriesUID: SeriesInstanceUID,
|
referenceSeriesUID: SeriesInstanceUID,
|
||||||
referenceStudyUID: StudyInstanceUID,
|
referenceStudyUID: StudyInstanceUID,
|
||||||
|
displaySetInstanceUID: displaySet.displaySetInstanceUID,
|
||||||
label: measurementData.text,
|
label: measurementData.text,
|
||||||
description: measurementData.description,
|
description: measurementData.description,
|
||||||
unit: measurementData.unit,
|
unit: measurementData.unit,
|
||||||
|
|||||||
@ -5,7 +5,11 @@ const Bidirectional = {
|
|||||||
toAnnotation: (measurement, definition) => {
|
toAnnotation: (measurement, definition) => {
|
||||||
// TODO -> Implement when this is needed.
|
// TODO -> Implement when this is needed.
|
||||||
},
|
},
|
||||||
toMeasurement: (csToolsAnnotation, getValueTypeFromToolType) => {
|
toMeasurement: (
|
||||||
|
csToolsAnnotation,
|
||||||
|
DisplaySetService,
|
||||||
|
getValueTypeFromToolType
|
||||||
|
) => {
|
||||||
const { element, measurementData } = csToolsAnnotation;
|
const { element, measurementData } = csToolsAnnotation;
|
||||||
const tool =
|
const tool =
|
||||||
csToolsAnnotation.toolType ||
|
csToolsAnnotation.toolType ||
|
||||||
@ -25,6 +29,11 @@ const Bidirectional = {
|
|||||||
StudyInstanceUID,
|
StudyInstanceUID,
|
||||||
} = getSOPInstanceAttributes(element);
|
} = getSOPInstanceAttributes(element);
|
||||||
|
|
||||||
|
const displaySet = DisplaySetService.getDisplaySetForSOPInstanceUID(
|
||||||
|
SOPInstanceUID,
|
||||||
|
SeriesInstanceUID
|
||||||
|
);
|
||||||
|
|
||||||
const { handles } = measurementData;
|
const { handles } = measurementData;
|
||||||
|
|
||||||
const longAxis = [handles.start, handles.end];
|
const longAxis = [handles.start, handles.end];
|
||||||
@ -36,6 +45,7 @@ const Bidirectional = {
|
|||||||
FrameOfReferenceUID,
|
FrameOfReferenceUID,
|
||||||
referenceSeriesUID: SeriesInstanceUID,
|
referenceSeriesUID: SeriesInstanceUID,
|
||||||
referenceStudyUID: StudyInstanceUID,
|
referenceStudyUID: StudyInstanceUID,
|
||||||
|
displaySetInstanceUID: displaySet.displaySetInstanceUID,
|
||||||
label: measurementData.text,
|
label: measurementData.text,
|
||||||
description: measurementData.description,
|
description: measurementData.description,
|
||||||
unit: measurementData.unit,
|
unit: measurementData.unit,
|
||||||
|
|||||||
@ -5,7 +5,11 @@ const EllipticalRoi = {
|
|||||||
toAnnotation: (measurement, definition) => {
|
toAnnotation: (measurement, definition) => {
|
||||||
// TODO -> Implement when this is needed.
|
// TODO -> Implement when this is needed.
|
||||||
},
|
},
|
||||||
toMeasurement: (csToolsAnnotation, getValueTypeFromToolType) => {
|
toMeasurement: (
|
||||||
|
csToolsAnnotation,
|
||||||
|
DisplaySetService,
|
||||||
|
getValueTypeFromToolType
|
||||||
|
) => {
|
||||||
const { element, measurementData } = csToolsAnnotation;
|
const { element, measurementData } = csToolsAnnotation;
|
||||||
const tool =
|
const tool =
|
||||||
csToolsAnnotation.toolType ||
|
csToolsAnnotation.toolType ||
|
||||||
@ -25,6 +29,11 @@ const EllipticalRoi = {
|
|||||||
StudyInstanceUID,
|
StudyInstanceUID,
|
||||||
} = getSOPInstanceAttributes(element);
|
} = getSOPInstanceAttributes(element);
|
||||||
|
|
||||||
|
const displaySet = DisplaySetService.getDisplaySetForSOPInstanceUID(
|
||||||
|
SOPInstanceUID,
|
||||||
|
SeriesInstanceUID
|
||||||
|
);
|
||||||
|
|
||||||
const { start, end } = measurementData.handles;
|
const { start, end } = measurementData.handles;
|
||||||
|
|
||||||
const halfXLength = Math.abs(start.x - end.x) / 2;
|
const halfXLength = Math.abs(start.x - end.x) / 2;
|
||||||
@ -58,6 +67,7 @@ const EllipticalRoi = {
|
|||||||
FrameOfReferenceUID,
|
FrameOfReferenceUID,
|
||||||
referenceSeriesUID: SeriesInstanceUID,
|
referenceSeriesUID: SeriesInstanceUID,
|
||||||
referenceStudyUID: StudyInstanceUID,
|
referenceStudyUID: StudyInstanceUID,
|
||||||
|
displaySetInstanceUID: displaySet.displaySetInstanceUID,
|
||||||
label: measurementData.text,
|
label: measurementData.text,
|
||||||
description: measurementData.description,
|
description: measurementData.description,
|
||||||
unit: measurementData.unit,
|
unit: measurementData.unit,
|
||||||
|
|||||||
@ -37,7 +37,11 @@ const Length = {
|
|||||||
* @param {Object} cornerstone Cornerstone event data
|
* @param {Object} cornerstone Cornerstone event data
|
||||||
* @return {Measurement} Measurement instance
|
* @return {Measurement} Measurement instance
|
||||||
*/
|
*/
|
||||||
toMeasurement: (csToolsAnnotation, getValueTypeFromToolType) => {
|
toMeasurement: (
|
||||||
|
csToolsAnnotation,
|
||||||
|
DisplaySetService,
|
||||||
|
getValueTypeFromToolType
|
||||||
|
) => {
|
||||||
const { element, measurementData } = csToolsAnnotation;
|
const { element, measurementData } = csToolsAnnotation;
|
||||||
const tool =
|
const tool =
|
||||||
csToolsAnnotation.toolType ||
|
csToolsAnnotation.toolType ||
|
||||||
@ -57,12 +61,18 @@ const Length = {
|
|||||||
StudyInstanceUID,
|
StudyInstanceUID,
|
||||||
} = getSOPInstanceAttributes(element);
|
} = getSOPInstanceAttributes(element);
|
||||||
|
|
||||||
|
const displaySet = DisplaySetService.getDisplaySetForSOPInstanceUID(
|
||||||
|
SOPInstanceUID,
|
||||||
|
SeriesInstanceUID
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: measurementData.id,
|
id: measurementData.id,
|
||||||
SOPInstanceUID: SOPInstanceUID,
|
SOPInstanceUID: SOPInstanceUID,
|
||||||
FrameOfReferenceUID,
|
FrameOfReferenceUID,
|
||||||
referenceSeriesUID: SeriesInstanceUID,
|
referenceSeriesUID: SeriesInstanceUID,
|
||||||
referenceStudyUID: StudyInstanceUID,
|
referenceStudyUID: StudyInstanceUID,
|
||||||
|
displaySetInstanceUID: displaySet.displaySetInstanceUID,
|
||||||
label: measurementData.text,
|
label: measurementData.text,
|
||||||
description: measurementData.description,
|
description: measurementData.description,
|
||||||
unit: measurementData.unit,
|
unit: measurementData.unit,
|
||||||
|
|||||||
@ -3,7 +3,10 @@ import Bidirectional from './Bidirectional';
|
|||||||
import ArrowAnnotate from './ArrowAnnotate';
|
import ArrowAnnotate from './ArrowAnnotate';
|
||||||
import EllipticalRoi from './EllipticalRoi';
|
import EllipticalRoi from './EllipticalRoi';
|
||||||
|
|
||||||
const measurementServiceMappingsFactory = measurementService => {
|
const measurementServiceMappingsFactory = (
|
||||||
|
MeasurementService,
|
||||||
|
DisplaySetService
|
||||||
|
) => {
|
||||||
/**
|
/**
|
||||||
* Maps measurement service format object to cornerstone annotation object.
|
* Maps measurement service format object to cornerstone annotation object.
|
||||||
*
|
*
|
||||||
@ -18,7 +21,7 @@ const measurementServiceMappingsFactory = measurementService => {
|
|||||||
ELLIPSE,
|
ELLIPSE,
|
||||||
POINT,
|
POINT,
|
||||||
BIDIRECTIONAL,
|
BIDIRECTIONAL,
|
||||||
} = measurementService.VALUE_TYPES;
|
} = MeasurementService.VALUE_TYPES;
|
||||||
|
|
||||||
// TODO -> I get why this was attemped, but its not nearly flexible enough.
|
// TODO -> I get why this was attemped, but its not nearly flexible enough.
|
||||||
// A single measurement may have an ellipse + a bidirectional measurement, for instances.
|
// A single measurement may have an ellipse + a bidirectional measurement, for instances.
|
||||||
@ -37,10 +40,14 @@ const measurementServiceMappingsFactory = measurementService => {
|
|||||||
Length: {
|
Length: {
|
||||||
toAnnotation: Length.toAnnotation,
|
toAnnotation: Length.toAnnotation,
|
||||||
toMeasurement: csToolsAnnotation =>
|
toMeasurement: csToolsAnnotation =>
|
||||||
Length.toMeasurement(csToolsAnnotation, _getValueTypeFromToolType),
|
Length.toMeasurement(
|
||||||
|
csToolsAnnotation,
|
||||||
|
DisplaySetService,
|
||||||
|
_getValueTypeFromToolType
|
||||||
|
),
|
||||||
matchingCriteria: [
|
matchingCriteria: [
|
||||||
{
|
{
|
||||||
valueType: measurementService.VALUE_TYPES.POLYLINE,
|
valueType: MeasurementService.VALUE_TYPES.POLYLINE,
|
||||||
points: 2,
|
points: 2,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -50,17 +57,18 @@ const measurementServiceMappingsFactory = measurementService => {
|
|||||||
toMeasurement: csToolsAnnotation =>
|
toMeasurement: csToolsAnnotation =>
|
||||||
Bidirectional.toMeasurement(
|
Bidirectional.toMeasurement(
|
||||||
csToolsAnnotation,
|
csToolsAnnotation,
|
||||||
|
DisplaySetService,
|
||||||
_getValueTypeFromToolType
|
_getValueTypeFromToolType
|
||||||
),
|
),
|
||||||
matchingCriteria: [
|
matchingCriteria: [
|
||||||
// TODO -> We should eventually do something like shortAxis + longAxis,
|
// TODO -> We should eventually do something like shortAxis + longAxis,
|
||||||
// But its still a little unclear how these automatic interpretations will work.
|
// But its still a little unclear how these automatic interpretations will work.
|
||||||
{
|
{
|
||||||
valueType: measurementService.VALUE_TYPES.POLYLINE,
|
valueType: MeasurementService.VALUE_TYPES.POLYLINE,
|
||||||
points: 2,
|
points: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
valueType: measurementService.VALUE_TYPES.POLYLINE,
|
valueType: MeasurementService.VALUE_TYPES.POLYLINE,
|
||||||
points: 2,
|
points: 2,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -70,11 +78,12 @@ const measurementServiceMappingsFactory = measurementService => {
|
|||||||
toMeasurement: csToolsAnnotation =>
|
toMeasurement: csToolsAnnotation =>
|
||||||
ArrowAnnotate.toMeasurement(
|
ArrowAnnotate.toMeasurement(
|
||||||
csToolsAnnotation,
|
csToolsAnnotation,
|
||||||
|
DisplaySetService,
|
||||||
_getValueTypeFromToolType
|
_getValueTypeFromToolType
|
||||||
),
|
),
|
||||||
matchingCriteria: [
|
matchingCriteria: [
|
||||||
{
|
{
|
||||||
valueType: measurementService.VALUE_TYPES.POINT,
|
valueType: MeasurementService.VALUE_TYPES.POINT,
|
||||||
points: 1,
|
points: 1,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -84,11 +93,12 @@ const measurementServiceMappingsFactory = measurementService => {
|
|||||||
toMeasurement: csToolsAnnotation =>
|
toMeasurement: csToolsAnnotation =>
|
||||||
EllipticalRoi.toMeasurement(
|
EllipticalRoi.toMeasurement(
|
||||||
csToolsAnnotation,
|
csToolsAnnotation,
|
||||||
|
DisplaySetService,
|
||||||
_getValueTypeFromToolType
|
_getValueTypeFromToolType
|
||||||
),
|
),
|
||||||
matchingCriteria: [
|
matchingCriteria: [
|
||||||
{
|
{
|
||||||
valueType: measurementService.VALUE_TYPES.ELLIPSE,
|
valueType: MeasurementService.VALUE_TYPES.ELLIPSE,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
@ -34,7 +34,7 @@
|
|||||||
"react": "^16.13.1",
|
"react": "^16.13.1",
|
||||||
"react-dom": "^16.13.1",
|
"react-dom": "^16.13.1",
|
||||||
"webpack": "^4.0.0",
|
"webpack": "^4.0.0",
|
||||||
"dcmjs": "0.16.0"
|
"dcmjs": "0.16.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "7.7.6"
|
"@babel/runtime": "7.7.6"
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@ohif/core": "^0.50.0",
|
"@ohif/core": "^0.50.0",
|
||||||
"dcmjs": "0.16.0",
|
"dcmjs": "0.16.1",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
"react": "^16.11.0",
|
"react": "^16.11.0",
|
||||||
"react-dom": "^16.11.0"
|
"react-dom": "^16.11.0"
|
||||||
|
|||||||
@ -31,7 +31,7 @@
|
|||||||
"@ohif/core": "^0.50.0",
|
"@ohif/core": "^0.50.0",
|
||||||
"cornerstone-core": "^2.2.8",
|
"cornerstone-core": "^2.2.8",
|
||||||
"cornerstone-tools": "4.18.1",
|
"cornerstone-tools": "4.18.1",
|
||||||
"dcmjs": "0.16.0",
|
"dcmjs": "0.16.1",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
"react": "^16.8.6",
|
"react": "^16.8.6",
|
||||||
"react-dom": "^16.8.6"
|
"react-dom": "^16.8.6"
|
||||||
|
|||||||
@ -31,7 +31,7 @@
|
|||||||
"@ohif/core": "^0.50.0",
|
"@ohif/core": "^0.50.0",
|
||||||
"cornerstone-core": "^2.2.8",
|
"cornerstone-core": "^2.2.8",
|
||||||
"cornerstone-tools": "4.18.1",
|
"cornerstone-tools": "4.18.1",
|
||||||
"dcmjs": "0.16.0",
|
"dcmjs": "0.16.1",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
"react": "^16.8.6",
|
"react": "^16.8.6",
|
||||||
"react-dom": "^16.8.6"
|
"react-dom": "^16.8.6"
|
||||||
|
|||||||
@ -35,7 +35,7 @@
|
|||||||
"cornerstone-math": "^0.1.8",
|
"cornerstone-math": "^0.1.8",
|
||||||
"cornerstone-tools": "4.18.1",
|
"cornerstone-tools": "4.18.1",
|
||||||
"cornerstone-wado-image-loader": "^3.1.2",
|
"cornerstone-wado-image-loader": "^3.1.2",
|
||||||
"dcmjs": "0.16.0",
|
"dcmjs": "0.16.1",
|
||||||
"dicom-parser": "^1.8.3",
|
"dicom-parser": "^1.8.3",
|
||||||
"hammerjs": "^2.0.8",
|
"hammerjs": "^2.0.8",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
|
|||||||
@ -372,6 +372,7 @@ function OHIFCornerstoneSRViewport({
|
|||||||
const toMeasurementSchema = getToolStateToCornerstoneMeasurementSchema(
|
const toMeasurementSchema = getToolStateToCornerstoneMeasurementSchema(
|
||||||
toolType,
|
toolType,
|
||||||
MeasurementService,
|
MeasurementService,
|
||||||
|
DisplaySetService,
|
||||||
imageId
|
imageId
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -436,8 +437,8 @@ function OHIFCornerstoneSRViewport({
|
|||||||
spacing:
|
spacing:
|
||||||
PixelSpacing && PixelSpacing.length
|
PixelSpacing && PixelSpacing.length
|
||||||
? `${PixelSpacing[0].toFixed(2)}mm x ${PixelSpacing[1].toFixed(
|
? `${PixelSpacing[0].toFixed(2)}mm x ${PixelSpacing[1].toFixed(
|
||||||
2
|
2
|
||||||
)}mm`
|
)}mm`
|
||||||
: '',
|
: '',
|
||||||
scanner: ManufacturerModelName || '',
|
scanner: ManufacturerModelName || '',
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
export default function getToolStateToCornerstoneMeasurementSchema(
|
export default function getToolStateToCornerstoneMeasurementSchema(
|
||||||
toolType,
|
toolType,
|
||||||
MeasurementService,
|
MeasurementService,
|
||||||
|
DisplaySetService,
|
||||||
imageId
|
imageId
|
||||||
) {
|
) {
|
||||||
const _getValueTypeFromToolType = toolType => {
|
const _getValueTypeFromToolType = toolType => {
|
||||||
@ -28,20 +29,45 @@ export default function getToolStateToCornerstoneMeasurementSchema(
|
|||||||
switch (toolType) {
|
switch (toolType) {
|
||||||
case 'Length':
|
case 'Length':
|
||||||
return measurementData =>
|
return measurementData =>
|
||||||
Length(measurementData, imageId, _getValueTypeFromToolType);
|
Length(
|
||||||
|
measurementData,
|
||||||
|
imageId,
|
||||||
|
DisplaySetService,
|
||||||
|
_getValueTypeFromToolType
|
||||||
|
);
|
||||||
case 'Bidirectional':
|
case 'Bidirectional':
|
||||||
return measurementData =>
|
return measurementData =>
|
||||||
Bidirectional(measurementData, imageId, _getValueTypeFromToolType);
|
Bidirectional(
|
||||||
|
measurementData,
|
||||||
|
imageId,
|
||||||
|
DisplaySetService,
|
||||||
|
_getValueTypeFromToolType
|
||||||
|
);
|
||||||
case 'EllipticalRoi':
|
case 'EllipticalRoi':
|
||||||
return measurementData =>
|
return measurementData =>
|
||||||
EllipticalRoi(measurementData, imageId, _getValueTypeFromToolType);
|
EllipticalRoi(
|
||||||
|
measurementData,
|
||||||
|
imageId,
|
||||||
|
DisplaySetService,
|
||||||
|
_getValueTypeFromToolType
|
||||||
|
);
|
||||||
case 'ArrowAnnotate':
|
case 'ArrowAnnotate':
|
||||||
return measurementData =>
|
return measurementData =>
|
||||||
ArrowAnnotate(measurementData, imageId, _getValueTypeFromToolType);
|
ArrowAnnotate(
|
||||||
|
measurementData,
|
||||||
|
imageId,
|
||||||
|
DisplaySetService,
|
||||||
|
_getValueTypeFromToolType
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Length(measurementData, imageId, _getValueTypeFromToolType) {
|
function Length(
|
||||||
|
measurementData,
|
||||||
|
imageId,
|
||||||
|
DisplaySetService,
|
||||||
|
_getValueTypeFromToolType
|
||||||
|
) {
|
||||||
const tool = measurementData.toolType || measurementData.toolName;
|
const tool = measurementData.toolType || measurementData.toolName;
|
||||||
const instance = cornerstone.metaData.get('instance', imageId);
|
const instance = cornerstone.metaData.get('instance', imageId);
|
||||||
const {
|
const {
|
||||||
@ -51,6 +77,12 @@ function Length(measurementData, imageId, _getValueTypeFromToolType) {
|
|||||||
StudyInstanceUID,
|
StudyInstanceUID,
|
||||||
} = instance;
|
} = instance;
|
||||||
|
|
||||||
|
const displaySetInstanceUID = _getDisplaySetInstanceUID(
|
||||||
|
DisplaySetService,
|
||||||
|
SeriesInstanceUID,
|
||||||
|
SOPInstanceUID
|
||||||
|
);
|
||||||
|
|
||||||
const { handles, label } = measurementData;
|
const { handles, label } = measurementData;
|
||||||
|
|
||||||
const points = [];
|
const points = [];
|
||||||
@ -69,7 +101,7 @@ function Length(measurementData, imageId, _getValueTypeFromToolType) {
|
|||||||
FrameOfReferenceUID,
|
FrameOfReferenceUID,
|
||||||
referenceSeriesUID: SeriesInstanceUID,
|
referenceSeriesUID: SeriesInstanceUID,
|
||||||
referenceStudyUID: StudyInstanceUID,
|
referenceStudyUID: StudyInstanceUID,
|
||||||
label: measurementData.text,
|
displaySetInstanceUID,
|
||||||
description: measurementData.description,
|
description: measurementData.description,
|
||||||
unit: measurementData.unit,
|
unit: measurementData.unit,
|
||||||
length: measurementData.length,
|
length: measurementData.length,
|
||||||
@ -79,7 +111,12 @@ function Length(measurementData, imageId, _getValueTypeFromToolType) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function Bidirectional(measurementData, imageId, _getValueTypeFromToolType) {
|
function Bidirectional(
|
||||||
|
measurementData,
|
||||||
|
imageId,
|
||||||
|
DisplaySetService,
|
||||||
|
_getValueTypeFromToolType
|
||||||
|
) {
|
||||||
const tool = measurementData.toolType || measurementData.toolName;
|
const tool = measurementData.toolType || measurementData.toolName;
|
||||||
const instance = cornerstone.metaData.get('instance', imageId);
|
const instance = cornerstone.metaData.get('instance', imageId);
|
||||||
const {
|
const {
|
||||||
@ -88,6 +125,11 @@ function Bidirectional(measurementData, imageId, _getValueTypeFromToolType) {
|
|||||||
SeriesInstanceUID,
|
SeriesInstanceUID,
|
||||||
StudyInstanceUID,
|
StudyInstanceUID,
|
||||||
} = instance;
|
} = instance;
|
||||||
|
const displaySetInstanceUID = _getDisplaySetInstanceUID(
|
||||||
|
DisplaySetService,
|
||||||
|
SeriesInstanceUID,
|
||||||
|
SOPInstanceUID
|
||||||
|
);
|
||||||
|
|
||||||
const { handles, label } = measurementData;
|
const { handles, label } = measurementData;
|
||||||
|
|
||||||
@ -100,7 +142,7 @@ function Bidirectional(measurementData, imageId, _getValueTypeFromToolType) {
|
|||||||
FrameOfReferenceUID,
|
FrameOfReferenceUID,
|
||||||
referenceSeriesUID: SeriesInstanceUID,
|
referenceSeriesUID: SeriesInstanceUID,
|
||||||
referenceStudyUID: StudyInstanceUID,
|
referenceStudyUID: StudyInstanceUID,
|
||||||
label: measurementData.text,
|
displaySetInstanceUID,
|
||||||
description: measurementData.description,
|
description: measurementData.description,
|
||||||
unit: measurementData.unit,
|
unit: measurementData.unit,
|
||||||
shortestDiameter: measurementData.shortestDiameter,
|
shortestDiameter: measurementData.shortestDiameter,
|
||||||
@ -111,7 +153,12 @@ function Bidirectional(measurementData, imageId, _getValueTypeFromToolType) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function EllipticalRoi(measurementData, imageId, _getValueTypeFromToolType) {
|
function EllipticalRoi(
|
||||||
|
measurementData,
|
||||||
|
imageId,
|
||||||
|
DisplaySetService,
|
||||||
|
_getValueTypeFromToolType
|
||||||
|
) {
|
||||||
const tool = measurementData.toolType || measurementData.toolName;
|
const tool = measurementData.toolType || measurementData.toolName;
|
||||||
const instance = cornerstone.metaData.get('instance', imageId);
|
const instance = cornerstone.metaData.get('instance', imageId);
|
||||||
const {
|
const {
|
||||||
@ -121,6 +168,11 @@ function EllipticalRoi(measurementData, imageId, _getValueTypeFromToolType) {
|
|||||||
StudyInstanceUID,
|
StudyInstanceUID,
|
||||||
} = instance;
|
} = instance;
|
||||||
|
|
||||||
|
const displaySetInstanceUID = _getDisplaySetInstanceUID(
|
||||||
|
DisplaySetService,
|
||||||
|
SeriesInstanceUID,
|
||||||
|
SOPInstanceUID
|
||||||
|
);
|
||||||
const { handles, label } = measurementData;
|
const { handles, label } = measurementData;
|
||||||
const { start, end } = handles;
|
const { start, end } = handles;
|
||||||
|
|
||||||
@ -155,7 +207,7 @@ function EllipticalRoi(measurementData, imageId, _getValueTypeFromToolType) {
|
|||||||
FrameOfReferenceUID,
|
FrameOfReferenceUID,
|
||||||
referenceSeriesUID: SeriesInstanceUID,
|
referenceSeriesUID: SeriesInstanceUID,
|
||||||
referenceStudyUID: StudyInstanceUID,
|
referenceStudyUID: StudyInstanceUID,
|
||||||
label: measurementData.text,
|
displaySetInstanceUID,
|
||||||
description: measurementData.description,
|
description: measurementData.description,
|
||||||
unit: measurementData.unit,
|
unit: measurementData.unit,
|
||||||
area:
|
area:
|
||||||
@ -168,7 +220,12 @@ function EllipticalRoi(measurementData, imageId, _getValueTypeFromToolType) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function ArrowAnnotate(measurementData, imageId, _getValueTypeFromToolType) {
|
function ArrowAnnotate(
|
||||||
|
measurementData,
|
||||||
|
imageId,
|
||||||
|
DisplaySetService,
|
||||||
|
_getValueTypeFromToolType
|
||||||
|
) {
|
||||||
const tool = measurementData.toolType || measurementData.toolName;
|
const tool = measurementData.toolType || measurementData.toolName;
|
||||||
const instance = cornerstone.metaData.get('instance', imageId);
|
const instance = cornerstone.metaData.get('instance', imageId);
|
||||||
const {
|
const {
|
||||||
@ -178,6 +235,12 @@ function ArrowAnnotate(measurementData, imageId, _getValueTypeFromToolType) {
|
|||||||
StudyInstanceUID,
|
StudyInstanceUID,
|
||||||
} = instance;
|
} = instance;
|
||||||
|
|
||||||
|
const displaySetInstanceUID = _getDisplaySetInstanceUID(
|
||||||
|
DisplaySetService,
|
||||||
|
SeriesInstanceUID,
|
||||||
|
SOPInstanceUID
|
||||||
|
);
|
||||||
|
|
||||||
const { handles } = measurementData;
|
const { handles } = measurementData;
|
||||||
|
|
||||||
const points = [];
|
const points = [];
|
||||||
@ -196,12 +259,25 @@ function ArrowAnnotate(measurementData, imageId, _getValueTypeFromToolType) {
|
|||||||
FrameOfReferenceUID,
|
FrameOfReferenceUID,
|
||||||
referenceSeriesUID: SeriesInstanceUID,
|
referenceSeriesUID: SeriesInstanceUID,
|
||||||
referenceStudyUID: StudyInstanceUID,
|
referenceStudyUID: StudyInstanceUID,
|
||||||
|
displaySetInstanceUID,
|
||||||
label: measurementData.text,
|
label: measurementData.text,
|
||||||
description: measurementData.description,
|
description: measurementData.description,
|
||||||
unit: measurementData.unit,
|
unit: measurementData.unit,
|
||||||
text: measurementData.text,
|
text: measurementData.text,
|
||||||
type: _getValueTypeFromToolType(tool),
|
type: _getValueTypeFromToolType(tool),
|
||||||
points,
|
points,
|
||||||
label,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _getDisplaySetInstanceUID(
|
||||||
|
DisplaySetService,
|
||||||
|
SeriesInstanceUID,
|
||||||
|
SOPInstanceUID
|
||||||
|
) {
|
||||||
|
const displaySet = DisplaySetService.getDisplaySetForSOPInstanceUID(
|
||||||
|
SOPInstanceUID,
|
||||||
|
SeriesInstanceUID
|
||||||
|
);
|
||||||
|
|
||||||
|
return displaySet.displaySetInstanceUID;
|
||||||
|
}
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@ohif/core": "^0.50.0",
|
"@ohif/core": "^0.50.0",
|
||||||
"cornerstone-tools": "4.18.1",
|
"cornerstone-tools": "4.18.1",
|
||||||
"dcmjs": "0.16.0",
|
"dcmjs": "0.16.1",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
"react": "^16.13.1",
|
"react": "^16.13.1",
|
||||||
"react-dom": "^16.13.1",
|
"react-dom": "^16.13.1",
|
||||||
|
|||||||
@ -161,29 +161,7 @@ function PanelMeasurementTableTracking({ servicesManager, extensionManager }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const jumpToImage = ({ id, isActive }) => {
|
const jumpToImage = ({ id, isActive }) => {
|
||||||
const measurement = MeasurementService.getMeasurement(id);
|
MeasurementService.jumpToMeasurement(viewportGrid.activeViewportIndex, id);
|
||||||
const { referenceSeriesUID, SOPInstanceUID } = measurement;
|
|
||||||
|
|
||||||
setCornerstoneMeasurementActive(measurement);
|
|
||||||
|
|
||||||
const displaySets = DisplaySetService.getDisplaySetsForSeries(
|
|
||||||
referenceSeriesUID
|
|
||||||
);
|
|
||||||
const displaySet = displaySets.find(ds => {
|
|
||||||
return (
|
|
||||||
ds.images && ds.images.some(i => i.SOPInstanceUID === SOPInstanceUID)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
const imageIndex = displaySet.images
|
|
||||||
.map(i => i.SOPInstanceUID)
|
|
||||||
.indexOf(SOPInstanceUID);
|
|
||||||
|
|
||||||
viewportGridService.setDisplaysetForViewport({
|
|
||||||
viewportIndex: viewportGrid.activeViewportIndex,
|
|
||||||
displaySetInstanceUID: displaySet.displaySetInstanceUID,
|
|
||||||
imageIndex,
|
|
||||||
});
|
|
||||||
|
|
||||||
onMeasurementItemClickHandler({ id, isActive });
|
onMeasurementItemClickHandler({ id, isActive });
|
||||||
};
|
};
|
||||||
|
|||||||
@ -16,6 +16,7 @@ import ViewportOverlay from './ViewportOverlay';
|
|||||||
import ViewportLoadingIndicator from './ViewportLoadingIndicator';
|
import ViewportLoadingIndicator from './ViewportLoadingIndicator';
|
||||||
import setCornerstoneMeasurementActive from '../_shared/setCornerstoneMeasurementActive';
|
import setCornerstoneMeasurementActive from '../_shared/setCornerstoneMeasurementActive';
|
||||||
|
|
||||||
|
const scrollToIndex = cornerstoneTools.importInternal('util/scrollToIndex');
|
||||||
const { formatDate } = utils;
|
const { formatDate } = utils;
|
||||||
|
|
||||||
// TODO -> Get this list from the list of tracked measurements.
|
// TODO -> Get this list from the list of tracked measurements.
|
||||||
@ -47,12 +48,13 @@ function TrackedCornerstoneViewport({
|
|||||||
viewportIndex,
|
viewportIndex,
|
||||||
servicesManager,
|
servicesManager,
|
||||||
}) {
|
}) {
|
||||||
const { ToolBarService, DisplaySetService } = servicesManager.services;
|
const {
|
||||||
|
ToolBarService,
|
||||||
|
DisplaySetService,
|
||||||
|
MeasurementService,
|
||||||
|
} = servicesManager.services;
|
||||||
const [trackedMeasurements] = useTrackedMeasurements();
|
const [trackedMeasurements] = useTrackedMeasurements();
|
||||||
const [
|
const [{ activeViewportIndex, viewports }] = useViewportGrid();
|
||||||
{ activeViewportIndex, viewports },
|
|
||||||
viewportGridService,
|
|
||||||
] = useViewportGrid();
|
|
||||||
// viewportIndex, onSubmit
|
// viewportIndex, onSubmit
|
||||||
const [viewportDialogState, viewportDialogApi] = useViewportDialog();
|
const [viewportDialogState, viewportDialogApi] = useViewportDialog();
|
||||||
const [viewportData, setViewportData] = useState(null);
|
const [viewportData, setViewportData] = useState(null);
|
||||||
@ -69,6 +71,28 @@ function TrackedCornerstoneViewport({
|
|||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const unsubcribeFromJumpToMeasurementEvents = _subscribeToJumpToMeasurementEvents(
|
||||||
|
MeasurementService,
|
||||||
|
DisplaySetService,
|
||||||
|
element,
|
||||||
|
viewportIndex,
|
||||||
|
displaySet.displaySetInstanceUID
|
||||||
|
);
|
||||||
|
|
||||||
|
_checkForCachedJumpToMeasurementEvents(
|
||||||
|
MeasurementService,
|
||||||
|
DisplaySetService,
|
||||||
|
element,
|
||||||
|
viewportIndex,
|
||||||
|
displaySet.displaySetInstanceUID
|
||||||
|
);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
unsubcribeFromJumpToMeasurementEvents();
|
||||||
|
};
|
||||||
|
}, [element, displaySet]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!element) {
|
if (!element) {
|
||||||
return;
|
return;
|
||||||
@ -167,13 +191,6 @@ function TrackedCornerstoneViewport({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* This grabs `imageIndex from first matching
|
|
||||||
* We actually want whichever is at our `viewportIndex`
|
|
||||||
*/
|
|
||||||
const { imageIndex } = viewports[viewportIndex];
|
|
||||||
displaySet.imageIndex = imageIndex;
|
|
||||||
|
|
||||||
_getViewportData(dataSource, displaySet).then(setViewportData);
|
_getViewportData(dataSource, displaySet).then(setViewportData);
|
||||||
}, [dataSource, displaySet, viewports, viewportIndex]);
|
}, [dataSource, displaySet, viewports, viewportIndex]);
|
||||||
|
|
||||||
@ -275,19 +292,10 @@ function TrackedCornerstoneViewport({
|
|||||||
|
|
||||||
setCornerstoneMeasurementActive(measurement);
|
setCornerstoneMeasurementActive(measurement);
|
||||||
|
|
||||||
const {
|
MeasurementService.jumpToMeasurement(
|
||||||
displaySetInstanceUID,
|
|
||||||
imageIndex,
|
|
||||||
} = _getViewportDataFromTrackedMeasurementId(
|
|
||||||
measurement,
|
|
||||||
DisplaySetService
|
|
||||||
);
|
|
||||||
|
|
||||||
viewportGridService.setDisplaysetForViewport({
|
|
||||||
viewportIndex,
|
viewportIndex,
|
||||||
displaySetInstanceUID,
|
newTrackedMeasurementId
|
||||||
imageIndex,
|
);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const showNavArrows = isTracked && viewportIndex === activeViewportIndex;
|
const showNavArrows = isTracked && viewportIndex === activeViewportIndex;
|
||||||
@ -336,14 +344,6 @@ function TrackedCornerstoneViewport({
|
|||||||
viewportIndex={viewportIndex}
|
viewportIndex={viewportIndex}
|
||||||
imageIds={imageIds}
|
imageIds={imageIds}
|
||||||
imageIdIndex={currentImageIdIndex}
|
imageIdIndex={currentImageIdIndex}
|
||||||
onNewImageDebounceTime={700}
|
|
||||||
onNewImageDebounced={({ currentImageIdIndex }) => {
|
|
||||||
viewportGridService.setDisplaysetForViewport({
|
|
||||||
viewportIndex: activeViewportIndex,
|
|
||||||
displaySetInstanceUID: displaySet.displaySetInstanceUID,
|
|
||||||
imageIndex: currentImageIdIndex,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
// Sync resize throttle w/ sidepanel animation duration to prevent
|
// Sync resize throttle w/ sidepanel animation duration to prevent
|
||||||
// seizure inducing strobe blinking effect
|
// seizure inducing strobe blinking effect
|
||||||
resizeRefreshRateMs={150}
|
resizeRefreshRateMs={150}
|
||||||
@ -402,16 +402,12 @@ const _viewportLabels = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'];
|
|||||||
* @return {Object} CornerstoneTools Stack
|
* @return {Object} CornerstoneTools Stack
|
||||||
*/
|
*/
|
||||||
function _getCornerstoneStack(displaySet, dataSource) {
|
function _getCornerstoneStack(displaySet, dataSource) {
|
||||||
const { imageIndex } = displaySet;
|
|
||||||
|
|
||||||
// Get stack from Stack Manager
|
// Get stack from Stack Manager
|
||||||
const storedStack = StackManager.findOrCreateStack(displaySet, dataSource);
|
const storedStack = StackManager.findOrCreateStack(displaySet, dataSource);
|
||||||
|
|
||||||
// Clone the stack here so we don't mutate it
|
// Clone the stack here so we don't mutate it
|
||||||
const stack = Object.assign({}, storedStack);
|
const stack = Object.assign({}, storedStack);
|
||||||
|
|
||||||
stack.currentImageIdIndex = imageIndex;
|
|
||||||
|
|
||||||
return stack;
|
return stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -498,26 +494,111 @@ function _getNextMeasurementId(
|
|||||||
return newTrackedMeasurementId;
|
return newTrackedMeasurementId;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _getViewportDataFromTrackedMeasurementId(
|
function _subscribeToJumpToMeasurementEvents(
|
||||||
|
MeasurementService,
|
||||||
|
DisplaySetService,
|
||||||
|
element,
|
||||||
|
viewportIndex,
|
||||||
|
displaySetInstanceUID
|
||||||
|
) {
|
||||||
|
const { unsubscribe } = MeasurementService.subscribe(
|
||||||
|
MeasurementService.EVENTS.JUMP_TO_MEASUREMENT,
|
||||||
|
({ viewportIndex: jumpToMeasurementViewportIndex, measurement }) => {
|
||||||
|
// check if the correct viewport index.
|
||||||
|
if (viewportIndex !== jumpToMeasurementViewportIndex) {
|
||||||
|
// Event for a different viewport.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (measurement.displaySetInstanceUID !== displaySetInstanceUID) {
|
||||||
|
// Not for this displaySet.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_jumpToMeasurement(
|
||||||
|
measurement,
|
||||||
|
element,
|
||||||
|
viewportIndex,
|
||||||
|
MeasurementService,
|
||||||
|
DisplaySetService
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return unsubscribe;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _checkForCachedJumpToMeasurementEvents(
|
||||||
|
MeasurementService,
|
||||||
|
DisplaySetService,
|
||||||
|
element,
|
||||||
|
viewportIndex,
|
||||||
|
displaySetInstanceUID
|
||||||
|
) {
|
||||||
|
// Check if there is a queued jumpToMeasurement event
|
||||||
|
const measurementIdToJumpTo = MeasurementService.getJumpToMeasurement(
|
||||||
|
viewportIndex
|
||||||
|
);
|
||||||
|
|
||||||
|
if (measurementIdToJumpTo && element) {
|
||||||
|
// Jump to measurement if the measurement exists
|
||||||
|
const measurement = MeasurementService.getMeasurement(
|
||||||
|
measurementIdToJumpTo
|
||||||
|
);
|
||||||
|
|
||||||
|
if (measurement.displaySetInstanceUID === displaySetInstanceUID) {
|
||||||
|
_jumpToMeasurement(
|
||||||
|
measurement,
|
||||||
|
element,
|
||||||
|
viewportIndex,
|
||||||
|
MeasurementService,
|
||||||
|
DisplaySetService
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _jumpToMeasurement(
|
||||||
measurement,
|
measurement,
|
||||||
|
targetElement,
|
||||||
|
viewportIndex,
|
||||||
|
MeasurementService,
|
||||||
DisplaySetService
|
DisplaySetService
|
||||||
) {
|
) {
|
||||||
const { referenceSeriesUID: SeriesInstanceUID, SOPInstanceUID } = measurement;
|
const { displaySetInstanceUID, SOPInstanceUID } = measurement;
|
||||||
|
|
||||||
const activeDisplaySets = DisplaySetService.getActiveDisplaySets();
|
const referencedDisplaySet = DisplaySetService.getDisplaySetByUID(
|
||||||
|
displaySetInstanceUID
|
||||||
const displaySet = activeDisplaySets.find(
|
|
||||||
ds => ds.SeriesInstanceUID === SeriesInstanceUID
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const imageIndex = displaySet.images.findIndex(
|
const imageIndex = referencedDisplaySet.images.findIndex(
|
||||||
image => image.SOPInstanceUID === SOPInstanceUID
|
i => i.SOPInstanceUID === SOPInstanceUID
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
setCornerstoneMeasurementActive(measurement);
|
||||||
imageIndex,
|
|
||||||
displaySetInstanceUID: displaySet.displaySetInstanceUID,
|
if (targetElement !== null) {
|
||||||
};
|
const enabledElement = cornerstone.getEnabledElement(targetElement);
|
||||||
|
|
||||||
|
if (enabledElement.image) {
|
||||||
|
// Wait for the image to update or we get a race condition when the element has only just been enabled.
|
||||||
|
const scrollToHandler = evt => {
|
||||||
|
scrollToIndex(targetElement, imageIndex);
|
||||||
|
targetElement.removeEventListener(
|
||||||
|
'cornerstoneimagerendered',
|
||||||
|
scrollToHandler
|
||||||
|
);
|
||||||
|
};
|
||||||
|
targetElement.addEventListener(
|
||||||
|
'cornerstoneimagerendered',
|
||||||
|
scrollToHandler
|
||||||
|
);
|
||||||
|
cornerstone.updateImage(targetElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Jump to measurement consumed, remove.
|
||||||
|
MeasurementService.removeJumpToMeasurement(viewportIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default TrackedCornerstoneViewport;
|
export default TrackedCornerstoneViewport;
|
||||||
|
|||||||
@ -33,7 +33,7 @@
|
|||||||
"@ohif/ui": "^2.0.0",
|
"@ohif/ui": "^2.0.0",
|
||||||
"cornerstone-core": "^2.3.0",
|
"cornerstone-core": "^2.3.0",
|
||||||
"cornerstone-wado-image-loader": "^3.1.2",
|
"cornerstone-wado-image-loader": "^3.1.2",
|
||||||
"dcmjs": "0.16.0",
|
"dcmjs": "0.16.1",
|
||||||
"dicom-parser": "^1.8.3",
|
"dicom-parser": "^1.8.3",
|
||||||
"i18next": "^17.0.3",
|
"i18next": "^17.0.3",
|
||||||
"i18next-browser-languagedetector": "^3.0.1",
|
"i18next-browser-languagedetector": "^3.0.1",
|
||||||
|
|||||||
@ -38,7 +38,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "7.7.6",
|
"@babel/runtime": "7.7.6",
|
||||||
"ajv": "^6.10.0",
|
"ajv": "^6.10.0",
|
||||||
"dcmjs": "0.16.0",
|
"dcmjs": "0.16.1",
|
||||||
"dicomweb-client": "^0.6.0",
|
"dicomweb-client": "^0.6.0",
|
||||||
"immer": "6.0.2",
|
"immer": "6.0.2",
|
||||||
"isomorphic-base64": "^1.0.2",
|
"isomorphic-base64": "^1.0.2",
|
||||||
|
|||||||
@ -46,6 +46,20 @@ export default class DisplaySetService {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
getDisplaySetForSOPInstanceUID(SOPInstanceUID, SeriesInstanceUID) {
|
||||||
|
const displaySets = SeriesInstanceUID
|
||||||
|
? this.getDisplaySetsForSeries(SeriesInstanceUID)
|
||||||
|
: this.getDisplaySetCache();
|
||||||
|
|
||||||
|
const displaySet = displaySets.find(ds => {
|
||||||
|
return (
|
||||||
|
ds.images && ds.images.some(i => i.SOPInstanceUID === SOPInstanceUID)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return displaySet;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} displaySetInstanceUID
|
* @param {string} displaySetInstanceUID
|
||||||
* @returns {object} displaySet
|
* @returns {object} displaySet
|
||||||
|
|||||||
@ -53,6 +53,7 @@ const EVENTS = {
|
|||||||
MEASUREMENT_ADDED: 'event::measurement_added',
|
MEASUREMENT_ADDED: 'event::measurement_added',
|
||||||
MEASUREMENT_REMOVED: 'event::measurement_removed',
|
MEASUREMENT_REMOVED: 'event::measurement_removed',
|
||||||
MEASUREMENTS_CLEARED: 'event::measurements_cleared',
|
MEASUREMENTS_CLEARED: 'event::measurements_cleared',
|
||||||
|
JUMP_TO_MEASUREMENT: 'event:jump_to_measurement',
|
||||||
};
|
};
|
||||||
|
|
||||||
const VALUE_TYPES = {
|
const VALUE_TYPES = {
|
||||||
@ -70,6 +71,7 @@ class MeasurementService {
|
|||||||
this.mappings = {};
|
this.mappings = {};
|
||||||
this.measurements = {};
|
this.measurements = {};
|
||||||
this.listeners = {};
|
this.listeners = {};
|
||||||
|
this._jumpToMeasurementCache = {};
|
||||||
Object.defineProperty(this, 'EVENTS', {
|
Object.defineProperty(this, 'EVENTS', {
|
||||||
value: EVENTS,
|
value: EVENTS,
|
||||||
writable: false,
|
writable: false,
|
||||||
@ -498,6 +500,40 @@ class MeasurementService {
|
|||||||
this._broadcastChange(this.EVENTS.MEASUREMENTS_CLEARED);
|
this._broadcastChange(this.EVENTS.MEASUREMENTS_CLEARED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jumpToMeasurement(viewportIndex, id) {
|
||||||
|
const measurement = this.measurements[id];
|
||||||
|
|
||||||
|
if (!measurement) {
|
||||||
|
log.warn(`No id provided, or unable to find measurement by id.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._addJumpToMeasurement(viewportIndex, id);
|
||||||
|
|
||||||
|
const eventName = this.EVENTS.JUMP_TO_MEASUREMENT;
|
||||||
|
|
||||||
|
const hasListeners = Object.keys(this.listeners).length > 0;
|
||||||
|
const hasCallbacks = Array.isArray(this.listeners[eventName]);
|
||||||
|
|
||||||
|
if (hasListeners && hasCallbacks) {
|
||||||
|
this.listeners[eventName].forEach(listener => {
|
||||||
|
listener.callback({ viewportIndex, measurement });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_addJumpToMeasurement(viewportIndex, id) {
|
||||||
|
this._jumpToMeasurementCache[viewportIndex] = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
getJumpToMeasurement(viewportIndex) {
|
||||||
|
return this._jumpToMeasurementCache[viewportIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
removeJumpToMeasurement(viewportIndex) {
|
||||||
|
delete this._jumpToMeasurementCache[viewportIndex];
|
||||||
|
}
|
||||||
|
|
||||||
_getMappingByMeasurementSource(measurementId, definition) {
|
_getMappingByMeasurementSource(measurementId, definition) {
|
||||||
const measurement = this.getMeasurement(measurementId);
|
const measurement = this.getMeasurement(measurementId);
|
||||||
if (this._isValidSource(measurement.source)) {
|
if (this._isValidSource(measurement.source)) {
|
||||||
|
|||||||
@ -27,14 +27,10 @@ export function ViewportGridProvider({ children, service }) {
|
|||||||
return { ...state, ...{ activeViewportIndex: action.payload } };
|
return { ...state, ...{ activeViewportIndex: action.payload } };
|
||||||
}
|
}
|
||||||
case 'SET_DISPLAYSET_FOR_VIEWPORT': {
|
case 'SET_DISPLAYSET_FOR_VIEWPORT': {
|
||||||
const {
|
const { viewportIndex, displaySetInstanceUID } = action.payload;
|
||||||
viewportIndex,
|
|
||||||
displaySetInstanceUID,
|
|
||||||
imageIndex,
|
|
||||||
} = action.payload;
|
|
||||||
const viewports = state.viewports.slice();
|
const viewports = state.viewports.slice();
|
||||||
|
|
||||||
viewports[viewportIndex] = { displaySetInstanceUID, imageIndex };
|
viewports[viewportIndex] = { displaySetInstanceUID };
|
||||||
|
|
||||||
return { ...state, ...{ viewports }, cachedLayout: null };
|
return { ...state, ...{ viewports }, cachedLayout: null };
|
||||||
}
|
}
|
||||||
@ -63,7 +59,7 @@ export function ViewportGridProvider({ children, service }) {
|
|||||||
numCols: 1,
|
numCols: 1,
|
||||||
numRows: 1,
|
numRows: 1,
|
||||||
activeViewportIndex: 0,
|
activeViewportIndex: 0,
|
||||||
viewports: [{ displaySetInstanceUID: null, imageIndex: null }],
|
viewports: [{ displaySetInstanceUID: null }],
|
||||||
cachedLayout: null,
|
cachedLayout: null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -96,13 +92,12 @@ export function ViewportGridProvider({ children, service }) {
|
|||||||
[dispatch]
|
[dispatch]
|
||||||
);
|
);
|
||||||
const setDisplaysetForViewport = useCallback(
|
const setDisplaysetForViewport = useCallback(
|
||||||
({ viewportIndex, displaySetInstanceUID, imageIndex }) =>
|
({ viewportIndex, displaySetInstanceUID }) =>
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'SET_DISPLAYSET_FOR_VIEWPORT',
|
type: 'SET_DISPLAYSET_FOR_VIEWPORT',
|
||||||
payload: {
|
payload: {
|
||||||
viewportIndex,
|
viewportIndex,
|
||||||
displaySetInstanceUID,
|
displaySetInstanceUID,
|
||||||
imageIndex,
|
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
[dispatch]
|
[dispatch]
|
||||||
|
|||||||
@ -70,7 +70,7 @@
|
|||||||
"cornerstone-math": "^0.1.8",
|
"cornerstone-math": "^0.1.8",
|
||||||
"cornerstone-tools": "4.18.1",
|
"cornerstone-tools": "4.18.1",
|
||||||
"cornerstone-wado-image-loader": "^3.1.2",
|
"cornerstone-wado-image-loader": "^3.1.2",
|
||||||
"dcmjs": "0.16.0",
|
"dcmjs": "0.16.1",
|
||||||
"dicom-parser": "^1.8.3",
|
"dicom-parser": "^1.8.3",
|
||||||
"dicomweb-client": "^0.4.4",
|
"dicomweb-client": "^0.4.4",
|
||||||
"dotenv-webpack": "^1.7.0",
|
"dotenv-webpack": "^1.7.0",
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* CSS Grid Reference: http://grid.malven.co/
|
* CSS Grid Reference: http://grid.malven.co/
|
||||||
*/
|
*/
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect, useCallback } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { ViewportGrid, ViewportPane, useViewportGrid } from '@ohif/ui';
|
import { ViewportGrid, ViewportPane, useViewportGrid } from '@ohif/ui';
|
||||||
import EmptyViewport from './EmptyViewport';
|
import EmptyViewport from './EmptyViewport';
|
||||||
@ -11,13 +11,18 @@ import classNames from 'classnames';
|
|||||||
|
|
||||||
function ViewerViewportGrid(props) {
|
function ViewerViewportGrid(props) {
|
||||||
const { servicesManager, viewportComponents, dataSource } = props;
|
const { servicesManager, viewportComponents, dataSource } = props;
|
||||||
const [
|
const [viewportGrid, viewportGridService] = useViewportGrid();
|
||||||
{ numCols, numRows, activeViewportIndex, viewports, cachedLayout },
|
|
||||||
viewportGridService,
|
const {
|
||||||
] = useViewportGrid();
|
numCols,
|
||||||
|
numRows,
|
||||||
|
activeViewportIndex,
|
||||||
|
viewports,
|
||||||
|
cachedLayout,
|
||||||
|
} = viewportGrid;
|
||||||
|
|
||||||
// TODO -> Need some way of selecting which displaySets hit the viewports.
|
// TODO -> Need some way of selecting which displaySets hit the viewports.
|
||||||
const { DisplaySetService } = servicesManager.services;
|
const { DisplaySetService, MeasurementService } = servicesManager.services;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const { unsubscribe } = DisplaySetService.subscribe(
|
const { unsubscribe } = DisplaySetService.subscribe(
|
||||||
@ -40,30 +45,56 @@ function ViewerViewportGrid(props) {
|
|||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// TODO -> Make a HangingProtocolService
|
useEffect(() => {
|
||||||
const HangingProtocolService = displaySets => {
|
const { unsubscribe } = MeasurementService.subscribe(
|
||||||
let displaySetInstanceUID;
|
MeasurementService.EVENTS.JUMP_TO_MEASUREMENT,
|
||||||
|
({ viewportIndex, measurement }) => {
|
||||||
|
const referencedDisplaySetInstanceUID =
|
||||||
|
measurement.displaySetInstanceUID;
|
||||||
|
|
||||||
// Fallback
|
// If the viewport does not contain the displaySet, then hang that displaySet.
|
||||||
if (!displaySets || !displaySets.length) {
|
if (
|
||||||
const displaySet = DisplaySetService.activeDisplaySets[0];
|
viewports[viewportIndex].displaySetInstanceUID !==
|
||||||
displaySetInstanceUID = displaySet.displaySetInstanceUID;
|
referencedDisplaySetInstanceUID
|
||||||
} else {
|
) {
|
||||||
const displaySet = displaySets[0];
|
viewportGridService.setDisplaysetForViewport({
|
||||||
displaySetInstanceUID = displaySet.displaySetInstanceUID;
|
viewportIndex,
|
||||||
}
|
displaySetInstanceUID: referencedDisplaySetInstanceUID,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return () => {
|
||||||
numRows: 1,
|
unsubscribe();
|
||||||
numCols: 1,
|
|
||||||
activeViewportIndex: 0,
|
|
||||||
viewports: [
|
|
||||||
{
|
|
||||||
displaySetInstanceUID,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
};
|
}, [viewports]);
|
||||||
|
|
||||||
|
// TODO -> Make a HangingProtocolService
|
||||||
|
// Commented out whilst not in use to avoid pointlessly regenerating this function.
|
||||||
|
// const HangingProtocolService = displaySets => {
|
||||||
|
// let displaySetInstanceUID;
|
||||||
|
|
||||||
|
// // Fallback
|
||||||
|
// if (!displaySets || !displaySets.length) {
|
||||||
|
// const displaySet = DisplaySetService.activeDisplaySets[0];
|
||||||
|
// displaySetInstanceUID = displaySet.displaySetInstanceUID;
|
||||||
|
// } else {
|
||||||
|
// const displaySet = displaySets[0];
|
||||||
|
// displaySetInstanceUID = displaySet.displaySetInstanceUID;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return {
|
||||||
|
// numRows: 1,
|
||||||
|
// numCols: 1,
|
||||||
|
// activeViewportIndex: 0,
|
||||||
|
// viewports: [
|
||||||
|
// {
|
||||||
|
// displaySetInstanceUID,
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
// };
|
||||||
|
// };
|
||||||
|
|
||||||
const onDoubleClick = viewportIndex => {
|
const onDoubleClick = viewportIndex => {
|
||||||
// TODO -> Disabled for now.
|
// TODO -> Disabled for now.
|
||||||
|
|||||||
@ -7364,10 +7364,10 @@ dateformat@^3.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae"
|
resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae"
|
||||||
integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==
|
integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==
|
||||||
|
|
||||||
dcmjs@0.16.0:
|
dcmjs@0.16.1:
|
||||||
version "0.16.0"
|
version "0.16.1"
|
||||||
resolved "https://registry.yarnpkg.com/dcmjs/-/dcmjs-0.16.0.tgz#714755d006c3a49cf65ef13e627ff7a23151d35a"
|
resolved "https://registry.yarnpkg.com/dcmjs/-/dcmjs-0.16.1.tgz#76bc61cbdf2c58a2f54990080729ca2d7ee19543"
|
||||||
integrity sha512-41nY3Isg5i5FoSd1s67aUgUHi146r+fb8JuiRvDsxvm7MEkkdjIzMYMtxjsrVwKRW1xRH+x34nxbV9+8cc7WQw==
|
integrity sha512-t6vsKi5QXzwX1fwnHY2hdU99FfyzmK8aO0OSBDH6XvJNrBp2A6HpoVWbucybOy8eStIPDqs4v0FGP/m39cTCRA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/polyfill" "^7.8.3"
|
"@babel/polyfill" "^7.8.3"
|
||||||
"@babel/runtime" "^7.8.4"
|
"@babel/runtime" "^7.8.4"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user