[IDC-1670] Better display of derived datasets in side panel. (#1962)
* WIP
* WIP
* WIP
* WIP
* Working click on seg.
* Load SEG if not loaded and set active.
* RTSTRUCT
* feat: 🎸 Display SEG and RTSTRUCT in side panel
* Throw error if dataset not available.
* Add delay in microscopy viewer e2e test.
* Add delay in microscopy viewer e2e test.
This commit is contained in:
parent
b7ab88b0f1
commit
f8fc31bcac
@ -1,5 +1,6 @@
|
|||||||
import { MODULE_TYPES, utils, DICOMWeb } from '@ohif/core';
|
import { MODULE_TYPES, utils, DICOMWeb } from '@ohif/core';
|
||||||
import loadRTStruct from './loadRTStruct';
|
import loadRTStruct from './loadRTStruct';
|
||||||
|
import getSourceDisplaySet from './getSourceDisplaySet';
|
||||||
|
|
||||||
import id from './id';
|
import id from './id';
|
||||||
|
|
||||||
@ -67,6 +68,10 @@ const OHIFDicomRTStructSopClassHandler = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rtStructDisplaySet.getSourceDisplaySet = function(studies) {
|
||||||
|
return getSourceDisplaySet(studies, rtStructDisplaySet);
|
||||||
|
};
|
||||||
|
|
||||||
rtStructDisplaySet.load = function(referencedDisplaySet, studies) {
|
rtStructDisplaySet.load = function(referencedDisplaySet, studies) {
|
||||||
return loadRTStruct(
|
return loadRTStruct(
|
||||||
rtStructDisplaySet,
|
rtStructDisplaySet,
|
||||||
|
|||||||
@ -242,7 +242,7 @@ const RTPanel = ({
|
|||||||
key={SeriesInstanceUID}
|
key={SeriesInstanceUID}
|
||||||
title={metadata.StructureSetLabel}
|
title={metadata.StructureSetLabel}
|
||||||
loading={!isLoaded || !loadedSet}
|
loading={!isLoaded || !loadedSet}
|
||||||
visible={isLoaded && loadedSet.visible}
|
visible={isLoaded && loadedSet && loadedSet.visible}
|
||||||
hideVisibleButton={!isLoaded}
|
hideVisibleButton={!isLoaded}
|
||||||
expanded={
|
expanded={
|
||||||
isLoaded &&
|
isLoaded &&
|
||||||
|
|||||||
38
extensions/dicom-rt/src/getSourceDisplaySet.js
Normal file
38
extensions/dicom-rt/src/getSourceDisplaySet.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
export default function getSourceDisplaySet(studies, rtStructDisplaySet) {
|
||||||
|
const referencedDisplaySet = _getReferencedDisplaySet(
|
||||||
|
rtStructDisplaySet,
|
||||||
|
studies
|
||||||
|
);
|
||||||
|
|
||||||
|
rtStructDisplaySet.load(referencedDisplaySet, studies);
|
||||||
|
|
||||||
|
return referencedDisplaySet;
|
||||||
|
}
|
||||||
|
|
||||||
|
const _getReferencedDisplaySet = (rtStructDisplaySet, studies) => {
|
||||||
|
let allDisplaySets = [];
|
||||||
|
|
||||||
|
studies.forEach(study => {
|
||||||
|
allDisplaySets = allDisplaySets.concat(study.displaySets);
|
||||||
|
});
|
||||||
|
|
||||||
|
const otherDisplaySets = allDisplaySets.filter(
|
||||||
|
ds => ds.displaySetInstanceUID !== rtStructDisplaySet.displaySetInstanceUID
|
||||||
|
);
|
||||||
|
|
||||||
|
const ReferencedSeriesSequence = Array.isArray(
|
||||||
|
rtStructDisplaySet.metadata.ReferencedSeriesSequence
|
||||||
|
)
|
||||||
|
? rtStructDisplaySet.metadata.ReferencedSeriesSequence
|
||||||
|
: [rtStructDisplaySet.metadata.ReferencedSeriesSequence];
|
||||||
|
|
||||||
|
const referencedSeriesInstanceUIDs = ReferencedSeriesSequence.map(
|
||||||
|
ReferencedSeries => ReferencedSeries.SeriesInstanceUID
|
||||||
|
);
|
||||||
|
|
||||||
|
const referencedDisplaySet = otherDisplaySets.find(ds =>
|
||||||
|
referencedSeriesInstanceUIDs.includes(ds.SeriesInstanceUID)
|
||||||
|
);
|
||||||
|
|
||||||
|
return referencedDisplaySet;
|
||||||
|
};
|
||||||
@ -6,6 +6,9 @@ import moment from 'moment';
|
|||||||
import { utils, log } from '@ohif/core';
|
import { utils, log } from '@ohif/core';
|
||||||
import { ScrollableArea, TableList, Icon } from '@ohif/ui';
|
import { ScrollableArea, TableList, Icon } from '@ohif/ui';
|
||||||
|
|
||||||
|
import setActiveLabelmap from '../../utils/setActiveLabelMap';
|
||||||
|
import refreshViewports from '../../utils/refreshViewports';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
BrushColorSelector,
|
BrushColorSelector,
|
||||||
BrushRadius,
|
BrushRadius,
|
||||||
@ -19,12 +22,6 @@ import SegmentationSettings from '../SegmentationSettings/SegmentationSettings';
|
|||||||
|
|
||||||
const { studyMetadataManager } = utils;
|
const { studyMetadataManager } = utils;
|
||||||
|
|
||||||
const refreshViewport = () => {
|
|
||||||
cornerstone.getEnabledElements().forEach(enabledElement => {
|
|
||||||
cornerstone.updateImage(enabledElement.element);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SegmentationPanel component
|
* SegmentationPanel component
|
||||||
*
|
*
|
||||||
@ -68,8 +65,7 @@ const SegmentationPanel = ({
|
|||||||
*/
|
*/
|
||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
brushRadius: DEFAULT_BRUSH_RADIUS,
|
brushRadius: DEFAULT_BRUSH_RADIUS,
|
||||||
brushColor:
|
brushColor: 'rgba(221, 85, 85, 1)',
|
||||||
'rgba(221, 85, 85, 1)',
|
|
||||||
selectedSegment: null,
|
selectedSegment: null,
|
||||||
selectedSegmentation: null,
|
selectedSegmentation: null,
|
||||||
showSegmentationSettings: false,
|
showSegmentationSettings: false,
|
||||||
@ -78,7 +74,7 @@ const SegmentationPanel = ({
|
|||||||
segmentList: [],
|
segmentList: [],
|
||||||
cachedSegmentsProperties: [],
|
cachedSegmentsProperties: [],
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
isDisabled: true
|
isDisabled: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -112,7 +108,10 @@ const SegmentationPanel = ({
|
|||||||
* allows us to easily watch the module or the segmentations loading process in any other component
|
* allows us to easily watch the module or the segmentations loading process in any other component
|
||||||
* without subscribing to external events.
|
* without subscribing to external events.
|
||||||
*/
|
*/
|
||||||
document.addEventListener('extensiondicomsegmentationsegloaded', refreshSegmentations);
|
document.addEventListener(
|
||||||
|
'extensiondicomsegmentationsegloaded',
|
||||||
|
refreshSegmentations
|
||||||
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These are specific to each element;
|
* These are specific to each element;
|
||||||
@ -127,7 +126,10 @@ const SegmentationPanel = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
document.removeEventListener('extensiondicomsegmentationsegloaded', refreshSegmentations);
|
document.removeEventListener(
|
||||||
|
'extensiondicomsegmentationsegloaded',
|
||||||
|
refreshSegmentations
|
||||||
|
);
|
||||||
cornerstoneTools.store.state.enabledElements.forEach(enabledElement =>
|
cornerstoneTools.store.state.enabledElements.forEach(enabledElement =>
|
||||||
enabledElement.removeEventListener(
|
enabledElement.removeEventListener(
|
||||||
'cornerstonetoolslabelmapmodified',
|
'cornerstonetoolslabelmapmodified',
|
||||||
@ -169,26 +171,29 @@ const SegmentationPanel = ({
|
|||||||
selectedSegmentation: brushStackState.activeLabelmapIndex,
|
selectedSegmentation: brushStackState.activeLabelmapIndex,
|
||||||
labelmapList,
|
labelmapList,
|
||||||
segmentList,
|
segmentList,
|
||||||
isDisabled
|
isDisabled,
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
setState(state => ({
|
setState(state => ({
|
||||||
...state,
|
...state,
|
||||||
labelmapList: [],
|
labelmapList: [],
|
||||||
segmentList: [],
|
segmentList: [],
|
||||||
isDisabled
|
isDisabled,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [
|
}, [viewports, activeIndex, state.isLoading]);
|
||||||
viewports,
|
|
||||||
activeIndex,
|
|
||||||
state.isLoading
|
|
||||||
]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
refreshSegmentations();
|
refreshSegmentations();
|
||||||
}, [viewports, activeIndex, isOpen, state.selectedSegmentation, activeContexts, state.isLoading]);
|
}, [
|
||||||
|
viewports,
|
||||||
|
activeIndex,
|
||||||
|
isOpen,
|
||||||
|
state.selectedSegmentation,
|
||||||
|
activeContexts,
|
||||||
|
state.isLoading,
|
||||||
|
]);
|
||||||
|
|
||||||
/* Handle open/closed panel behaviour */
|
/* Handle open/closed panel behaviour */
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -223,12 +228,10 @@ const SegmentationPanel = ({
|
|||||||
title: displayDescription,
|
title: displayDescription,
|
||||||
description: displayDate,
|
description: displayDate,
|
||||||
onClick: async () => {
|
onClick: async () => {
|
||||||
const activatedLabelmapIndex = await _setActiveLabelmap(
|
const activatedLabelmapIndex = await setActiveLabelmap(
|
||||||
activeViewport,
|
activeViewport,
|
||||||
studies,
|
studies,
|
||||||
displaySet,
|
displaySet,
|
||||||
firstImageId,
|
|
||||||
brushStackState.activeLabelmapIndex,
|
|
||||||
() => onSelectedSegmentationChange(),
|
() => onSelectedSegmentationChange(),
|
||||||
onDisplaySetLoadFailure
|
onDisplaySetLoadFailure
|
||||||
);
|
);
|
||||||
@ -376,9 +379,13 @@ const SegmentationPanel = ({
|
|||||||
return !segmentsHidden[segmentIndex];
|
return !segmentsHidden[segmentIndex];
|
||||||
};
|
};
|
||||||
|
|
||||||
const cachedSegmentProperties = state.cachedSegmentsProperties[segmentNumber];
|
const cachedSegmentProperties =
|
||||||
|
state.cachedSegmentsProperties[segmentNumber];
|
||||||
let visible = isSegmentVisible();
|
let visible = isSegmentVisible();
|
||||||
if (cachedSegmentProperties && cachedSegmentProperties.visible !== visible) {
|
if (
|
||||||
|
cachedSegmentProperties &&
|
||||||
|
cachedSegmentProperties.visible !== visible
|
||||||
|
) {
|
||||||
toggleSegmentVisibility();
|
toggleSegmentVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -406,8 +413,10 @@ const SegmentationPanel = ({
|
|||||||
onSegmentVisibilityChange(segmentNumber, newVisibility);
|
onSegmentVisibilityChange(segmentNumber, newVisibility);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateCachedSegmentsProperties(segmentNumber, { visible: newVisibility });
|
updateCachedSegmentsProperties(segmentNumber, {
|
||||||
refreshViewport();
|
visible: newVisibility,
|
||||||
|
});
|
||||||
|
refreshViewports();
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@ -429,10 +438,9 @@ const SegmentationPanel = ({
|
|||||||
const segmentsProperties = state.cachedSegmentsProperties;
|
const segmentsProperties = state.cachedSegmentsProperties;
|
||||||
const segmentProperties = state.cachedSegmentsProperties[segmentNumber];
|
const segmentProperties = state.cachedSegmentsProperties[segmentNumber];
|
||||||
|
|
||||||
segmentsProperties[segmentNumber] =
|
segmentsProperties[segmentNumber] = segmentProperties
|
||||||
segmentProperties ?
|
? { ...segmentProperties, ...properties }
|
||||||
{ ...segmentProperties, ...properties } :
|
: properties;
|
||||||
properties;
|
|
||||||
|
|
||||||
updateState('cachedSegmentsProperties', segmentsProperties);
|
updateState('cachedSegmentsProperties', segmentsProperties);
|
||||||
};
|
};
|
||||||
@ -499,10 +507,13 @@ const SegmentationPanel = ({
|
|||||||
configuration.fillAlphaInactive = newConfiguration.fillAlphaInactive;
|
configuration.fillAlphaInactive = newConfiguration.fillAlphaInactive;
|
||||||
configuration.outlineAlphaInactive = newConfiguration.outlineAlphaInactive;
|
configuration.outlineAlphaInactive = newConfiguration.outlineAlphaInactive;
|
||||||
onConfigurationChange(newConfiguration);
|
onConfigurationChange(newConfiguration);
|
||||||
refreshViewport();
|
refreshViewports();
|
||||||
};
|
};
|
||||||
|
|
||||||
const disabledConfigurationFields = ['outlineAlpha', 'shouldRenderInactiveLabelmaps'];
|
const disabledConfigurationFields = [
|
||||||
|
'outlineAlpha',
|
||||||
|
'shouldRenderInactiveLabelmaps',
|
||||||
|
];
|
||||||
if (state.showSegmentationSettings) {
|
if (state.showSegmentationSettings) {
|
||||||
return (
|
return (
|
||||||
<SegmentationSettings
|
<SegmentationSettings
|
||||||
@ -514,7 +525,10 @@ const SegmentationPanel = ({
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<div className={`dcmseg-segmentation-panel ${state.isDisabled && 'disabled'}`}>
|
<div
|
||||||
|
className={`dcmseg-segmentation-panel ${state.isDisabled &&
|
||||||
|
'disabled'}`}
|
||||||
|
>
|
||||||
<Icon
|
<Icon
|
||||||
className="cog-icon"
|
className="cog-icon"
|
||||||
name="cog"
|
name="cog"
|
||||||
@ -613,57 +627,6 @@ const _getReferencedSegDisplaysets = (StudyInstanceUID, SeriesInstanceUID) => {
|
|||||||
return referencedDisplaysets;
|
return referencedDisplaysets;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param {*} viewportSpecificData
|
|
||||||
* @param {*} studies
|
|
||||||
* @param {*} displaySet
|
|
||||||
* @param {*} firstImageId
|
|
||||||
* @param {*} activeLabelmapIndex
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
const _setActiveLabelmap = async (
|
|
||||||
viewportSpecificData,
|
|
||||||
studies,
|
|
||||||
displaySet,
|
|
||||||
firstImageId,
|
|
||||||
activeLabelmapIndex,
|
|
||||||
callback = () => { },
|
|
||||||
onDisplaySetLoadFailure
|
|
||||||
) => {
|
|
||||||
if (displaySet.labelmapIndex === activeLabelmapIndex) {
|
|
||||||
log.warn(`${activeLabelmapIndex} is already the active labelmap`);
|
|
||||||
return displaySet.labelmapIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!displaySet.isLoaded) {
|
|
||||||
// What props does this expect `viewportSpecificData` to have?
|
|
||||||
// TODO: Should this return the `labelmapIndex`?
|
|
||||||
|
|
||||||
const loadPromise = displaySet.load(viewportSpecificData, studies);
|
|
||||||
|
|
||||||
loadPromise.catch(error => {
|
|
||||||
onDisplaySetLoadFailure(error);
|
|
||||||
|
|
||||||
// Return old index.
|
|
||||||
return activeLabelmapIndex;
|
|
||||||
});
|
|
||||||
|
|
||||||
await loadPromise;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { state } = cornerstoneTools.getModule('segmentation');
|
|
||||||
const brushStackState = state.series[firstImageId];
|
|
||||||
brushStackState.activeLabelmapIndex = displaySet.labelmapIndex;
|
|
||||||
|
|
||||||
refreshViewport();
|
|
||||||
|
|
||||||
callback();
|
|
||||||
|
|
||||||
return displaySet.labelmapIndex;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {*} firstImageId
|
* @param {*} firstImageId
|
||||||
@ -683,7 +646,7 @@ const _setActiveSegment = (firstImageId, segmentIndex, activeSegmentIndex) => {
|
|||||||
brushStackState.labelmaps3D[brushStackState.activeLabelmapIndex];
|
brushStackState.labelmaps3D[brushStackState.activeLabelmapIndex];
|
||||||
labelmap3D.activeSegmentIndex = segmentIndex;
|
labelmap3D.activeSegmentIndex = segmentIndex;
|
||||||
|
|
||||||
refreshViewport();
|
refreshViewports();
|
||||||
|
|
||||||
return segmentIndex;
|
return segmentIndex;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { MODULE_TYPES, utils } from '@ohif/core';
|
import { MODULE_TYPES, utils } from '@ohif/core';
|
||||||
import loadSegmentation from './loadSegmentation';
|
import loadSegmentation from './loadSegmentation';
|
||||||
|
import getSourceDisplaySet from './getSourceDisplaySet';
|
||||||
|
|
||||||
// TODO: Should probably use dcmjs for this
|
// TODO: Should probably use dcmjs for this
|
||||||
const SOP_CLASS_UIDS = {
|
const SOP_CLASS_UIDS = {
|
||||||
@ -54,6 +55,10 @@ export default function getSopClassHandlerModule({ servicesManager }) {
|
|||||||
SeriesDescription,
|
SeriesDescription,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
segDisplaySet.getSourceDisplaySet = function(studies) {
|
||||||
|
return getSourceDisplaySet(studies, segDisplaySet);
|
||||||
|
};
|
||||||
|
|
||||||
segDisplaySet.load = function(referencedDisplaySet, studies) {
|
segDisplaySet.load = function(referencedDisplaySet, studies) {
|
||||||
return loadSegmentation(segDisplaySet, referencedDisplaySet, studies);
|
return loadSegmentation(segDisplaySet, referencedDisplaySet, studies);
|
||||||
};
|
};
|
||||||
|
|||||||
37
extensions/dicom-segmentation/src/getSourceDisplaySet.js
Normal file
37
extensions/dicom-segmentation/src/getSourceDisplaySet.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import setActiveLabelmap from './utils/setActiveLabelMap';
|
||||||
|
|
||||||
|
export default function getSourceDisplaySet(studies, segDisplaySet) {
|
||||||
|
const referencedDisplaySet = _getReferencedDisplaySet(segDisplaySet, studies);
|
||||||
|
|
||||||
|
setActiveLabelmap(referencedDisplaySet, studies, segDisplaySet);
|
||||||
|
|
||||||
|
return referencedDisplaySet;
|
||||||
|
}
|
||||||
|
|
||||||
|
const _getReferencedDisplaySet = (segDisplaySet, studies) => {
|
||||||
|
let allDisplaySets = [];
|
||||||
|
|
||||||
|
studies.forEach(study => {
|
||||||
|
allDisplaySets = allDisplaySets.concat(study.displaySets);
|
||||||
|
});
|
||||||
|
|
||||||
|
const otherDisplaySets = allDisplaySets.filter(
|
||||||
|
ds => ds.displaySetInstanceUID !== segDisplaySet.displaySetInstanceUID
|
||||||
|
);
|
||||||
|
|
||||||
|
const ReferencedSeriesSequence = Array.isArray(
|
||||||
|
segDisplaySet.metadata.ReferencedSeriesSequence
|
||||||
|
)
|
||||||
|
? segDisplaySet.metadata.ReferencedSeriesSequence
|
||||||
|
: [segDisplaySet.metadata.ReferencedSeriesSequence];
|
||||||
|
|
||||||
|
const referencedSeriesInstanceUIDs = ReferencedSeriesSequence.map(
|
||||||
|
ReferencedSeries => ReferencedSeries.SeriesInstanceUID
|
||||||
|
);
|
||||||
|
|
||||||
|
const referencedDisplaySet = otherDisplaySets.find(ds =>
|
||||||
|
referencedSeriesInstanceUIDs.includes(ds.SeriesInstanceUID)
|
||||||
|
);
|
||||||
|
|
||||||
|
return referencedDisplaySet;
|
||||||
|
};
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
export default function refreshViewports() {
|
||||||
|
cornerstone.getEnabledElements().forEach(enabledElement => {
|
||||||
|
cornerstone.updateImage(enabledElement.element);
|
||||||
|
});
|
||||||
|
}
|
||||||
67
extensions/dicom-segmentation/src/utils/setActiveLabelMap.js
Normal file
67
extensions/dicom-segmentation/src/utils/setActiveLabelMap.js
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
import { utils, log } from '@ohif/core';
|
||||||
|
import cornerstoneTools from 'cornerstone-tools';
|
||||||
|
import refreshViewports from './refreshViewports';
|
||||||
|
|
||||||
|
const { studyMetadataManager } = utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param {*} viewportSpecificData
|
||||||
|
* @param {*} studies
|
||||||
|
* @param {*} displaySet
|
||||||
|
* @param {*} firstImageId
|
||||||
|
* @param {*} activeLabelmapIndex
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export default async function setActiveLabelmap(
|
||||||
|
referencedDisplaySet,
|
||||||
|
studies,
|
||||||
|
displaySet,
|
||||||
|
callback = () => {},
|
||||||
|
onDisplaySetLoadFailure = err => {
|
||||||
|
throw new Error(err.message);
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
const studyMetadata = studyMetadataManager.get(
|
||||||
|
referencedDisplaySet.StudyInstanceUID
|
||||||
|
);
|
||||||
|
const firstImageId = studyMetadata.getFirstImageId(
|
||||||
|
referencedDisplaySet.displaySetInstanceUID
|
||||||
|
);
|
||||||
|
|
||||||
|
let { state } = cornerstoneTools.getModule('segmentation');
|
||||||
|
|
||||||
|
let brushStackState = state.series[firstImageId];
|
||||||
|
const activeLabelmapIndex = brushStackState
|
||||||
|
? brushStackState.activeLabelmapIndex
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
if (displaySet.labelmapIndex === activeLabelmapIndex) {
|
||||||
|
log.warn(`${activeLabelmapIndex} is already the active labelmap`);
|
||||||
|
return displaySet.labelmapIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!displaySet.isLoaded) {
|
||||||
|
const loadPromise = displaySet.load(referencedDisplaySet, studies);
|
||||||
|
|
||||||
|
loadPromise.catch(error => {
|
||||||
|
onDisplaySetLoadFailure(error);
|
||||||
|
|
||||||
|
// Return old index.
|
||||||
|
return activeLabelmapIndex;
|
||||||
|
});
|
||||||
|
|
||||||
|
await loadPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This might have just been created, so need to use the non-cached value.
|
||||||
|
state = cornerstoneTools.getModule('segmentation').state;
|
||||||
|
brushStackState = state.series[firstImageId];
|
||||||
|
brushStackState.activeLabelmapIndex = displaySet.labelmapIndex;
|
||||||
|
|
||||||
|
refreshViewports();
|
||||||
|
callback();
|
||||||
|
|
||||||
|
return displaySet.labelmapIndex;
|
||||||
|
}
|
||||||
@ -139,9 +139,11 @@ export class StudyMetadata extends Metadata {
|
|||||||
if (displaySet) {
|
if (displaySet) {
|
||||||
displaySet.sopClassModule = true;
|
displaySet.sopClassModule = true;
|
||||||
|
|
||||||
displaySet.isDerived
|
if (displaySet.isDerived) {
|
||||||
? this._addDerivedDisplaySet(displaySet)
|
this._addDerivedDisplaySet(displaySet);
|
||||||
: displaySets.push(displaySet);
|
}
|
||||||
|
|
||||||
|
displaySets.push(displaySet);
|
||||||
|
|
||||||
return displaySets;
|
return displaySets;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,6 +12,8 @@ describe('OHIF Microscopy Extension', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('drags and drop a SM thumbnail into viewport', () => {
|
it('drags and drop a SM thumbnail into viewport', () => {
|
||||||
|
// Waiting for series list to load all displaySets (lots of SRs, before defining which dom element to grab.)
|
||||||
|
cy.wait(3000);
|
||||||
cy.get('[data-cy="thumbnail-list"]')
|
cy.get('[data-cy="thumbnail-list"]')
|
||||||
.contains('SM')
|
.contains('SM')
|
||||||
.drag('.viewport-drop-target');
|
.drag('.viewport-drop-target');
|
||||||
|
|||||||
@ -80,6 +80,7 @@ const ViewportGrid = function(props) {
|
|||||||
// - When updating a panel, ensure that the currently enabled plugin
|
// - When updating a panel, ensure that the currently enabled plugin
|
||||||
// in the viewport is capable of rendering this display set. If not
|
// in the viewport is capable of rendering this display set. If not
|
||||||
// then use the most capable available plugin
|
// then use the most capable available plugin
|
||||||
|
|
||||||
const pluginName =
|
const pluginName =
|
||||||
!layout.plugin && displaySet && displaySet.plugin
|
!layout.plugin && displaySet && displaySet.plugin
|
||||||
? displaySet.plugin
|
? displaySet.plugin
|
||||||
|
|||||||
@ -4,6 +4,8 @@ import { StudyBrowser } from '@ohif/ui';
|
|||||||
import cloneDeep from 'lodash.clonedeep';
|
import cloneDeep from 'lodash.clonedeep';
|
||||||
import findDisplaySetByUID from './findDisplaySetByUID';
|
import findDisplaySetByUID from './findDisplaySetByUID';
|
||||||
|
|
||||||
|
const { studyMetadataManager } = OHIF.utils;
|
||||||
|
|
||||||
const { setActiveViewportSpecificData } = OHIF.redux.actions;
|
const { setActiveViewportSpecificData } = OHIF.redux.actions;
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
@ -39,11 +41,27 @@ const mapStateToProps = (state, ownProps) => {
|
|||||||
const mapDispatchToProps = (dispatch, ownProps) => {
|
const mapDispatchToProps = (dispatch, ownProps) => {
|
||||||
return {
|
return {
|
||||||
onThumbnailClick: displaySetInstanceUID => {
|
onThumbnailClick: displaySetInstanceUID => {
|
||||||
const displaySet = findDisplaySetByUID(
|
let displaySet = findDisplaySetByUID(
|
||||||
ownProps.studyMetadata,
|
ownProps.studyMetadata,
|
||||||
displaySetInstanceUID
|
displaySetInstanceUID
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (displaySet.isDerived) {
|
||||||
|
const { Modality } = displaySet;
|
||||||
|
|
||||||
|
displaySet = displaySet.getSourceDisplaySet(ownProps.studyMetadata);
|
||||||
|
|
||||||
|
if (!displaySet) {
|
||||||
|
throw new Error(
|
||||||
|
`Referenced series for ${Modality} dataset not present.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!displaySet) {
|
||||||
|
throw new Error('Source data not present');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dispatch(setActiveViewportSpecificData(displaySet));
|
dispatch(setActiveViewportSpecificData(displaySet));
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -133,12 +133,23 @@ class ViewerMain extends Component {
|
|||||||
StudyInstanceUID,
|
StudyInstanceUID,
|
||||||
displaySetInstanceUID,
|
displaySetInstanceUID,
|
||||||
}) => {
|
}) => {
|
||||||
const displaySet = this.findDisplaySet(
|
let displaySet = this.findDisplaySet(
|
||||||
this.props.studies,
|
this.props.studies,
|
||||||
StudyInstanceUID,
|
StudyInstanceUID,
|
||||||
displaySetInstanceUID
|
displaySetInstanceUID
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (displaySet.isDerived) {
|
||||||
|
const { Modality } = displaySet;
|
||||||
|
displaySet = displaySet.getSourceDisplaySet(this.props.studies);
|
||||||
|
|
||||||
|
if (!displaySet) {
|
||||||
|
throw new Error(
|
||||||
|
`Referenced series for ${Modality} dataset not present.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.props.setViewportSpecificData(viewportIndex, displaySet);
|
this.props.setViewportSpecificData(viewportIndex, displaySet);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user