OHIF-285/OHIF-274: Fix default hanging of display sets into the ViewportGrid (#1917)

* OHIF-285/OHIF-274: Fix default hanging of display sets into the ViewportGrid

Co-authored-by: James A. Petts <jamesapetts@gmail.com>
This commit is contained in:
Erik ZieglerandJames A. Petts authored and GitHub committed 2020-07-24 12:51:57 +02:00
1 parent 9df57e7f7f
commit 55cf9f2306
33 files changed
+548 -208

No files matched your search

@@ -42,7 +42,7 @@ function createDicomWebApi(dicomWebConfig) {
wadoRoot,
enableStudyLazyLoad,
supportsFuzzyMatching,
supportsWildcard
supportsWildcard,
} = dicomWebConfig;
const qidoConfig = {
@@ -63,9 +63,12 @@ function createDicomWebApi(dicomWebConfig) {
query: {
studies: {
mapParams: mapParams.bind(),
search: async function (origParams) {
search: async function(origParams) {
const { studyInstanceUid, seriesInstanceUid, ...mappedParams } =
mapParams(origParams, { supportsFuzzyMatching, supportsWildcard }) || {};
mapParams(origParams, {
supportsFuzzyMatching,
supportsWildcard,
}) || {};
const results = await qidoSearch(
qidoDicomWebClient,
@@ -80,7 +83,7 @@ function createDicomWebApi(dicomWebConfig) {
},
series: {
// mapParams: mapParams.bind(),
search: async function (studyInstanceUid) {
search: async function(studyInstanceUid) {
const results = await seriesInStudy(
qidoDicomWebClient,
studyInstanceUid
@@ -133,7 +136,8 @@ function createDicomWebApi(dicomWebConfig) {
);
studyPromises.forEach(studyPromise => {
studyPromise.then(seriesPromises => {
studyPromise.then(data => {
const { seriesPromises } = data;
seriesPromises.forEach(seriesPromise => {
seriesPromise.then(instances => {
storeInstances(instances);
@@ -178,7 +182,10 @@ function createDicomWebApi(dicomWebConfig) {
}
// Get Series
const seriesPromises = await retrieveStudyMetadata(
const {
seriesSummaryMetadata,
seriesPromises,
} = await retrieveStudyMetadata(
wadoDicomWebClient,
StudyInstanceUID,
enableStudyLazyLoad
@@ -191,6 +198,8 @@ function createDicomWebApi(dicomWebConfig) {
DicomMetadataStore.addInstances(naturalizedInstances);
}
DicomMetadataStore.addSeriesMetadata(seriesSummaryMetadata);
seriesPromises.forEach(async seriesPromise => {
const instances = await seriesPromise;
storeInstances(instances);
@@ -29,9 +29,12 @@ async function RetrieveMetadata(
studyInstanceUid,
filters
);
const studyMetadata = retrieveMetadataLoader.execLoad();
const { preLoadData, promises } = await retrieveMetadataLoader.execLoad();
return studyMetadata;
return {
seriesSummaryMetadata: preLoadData,
seriesPromises: promises,
};
}
export default RetrieveMetadata;
@@ -1,15 +1,9 @@
import dcmjs from 'dcmjs';
import { studies } from '@ohif/core';
import RetrieveMetadataLoader from './retrieveMetadataLoader';
//import { sortStudySeries, sortingCriteria } from '../../sortStudy';
import getSeriesInfo from './utils/getSeriesInfo';
/**
* Map seriesList to an array of seriesInstanceUid
* @param {Arrays} seriesList list of Series Instance UIDs
* @returns {Arrays} A list of Series Instance UIDs
*/
function mapStudySeries(seriesList) {
return seriesList.map(series => getSeriesInfo(series).seriesInstanceUid);
}
const { sortStudySeries, sortingCriteria } = studies;
/**
* Creates an immutable series loader object which loads each series sequentially using the iterator interface
@@ -33,7 +27,6 @@ function makeSeriesAsyncLoader(
studyInstanceUID,
seriesInstanceUID,
});
// return { studyInstanceUID, seriesInstanceUID, sopInstances };
},
});
}
@@ -73,56 +66,42 @@ export default class RetrieveMetadataLoaderAsync extends RetrieveMetadataLoader
const preLoaders = this.getPreLoaders();
const result = await this.runLoaders(preLoaders);
// const seriesSorted = sortStudySeries(
// result,
// sortingCriteria.seriesSortCriteria.seriesInfoSortingCriteria
// );
const { naturalizeDataset } = dcmjs.data.DicomMetaDictionary;
const naturalized = result.map(naturalizeDataset);
//const seriesInstanceUidsMap = mapStudySeries(seriesSorted);
const seriesInstanceUidsMap = mapStudySeries(result);
return seriesInstanceUidsMap;
return sortStudySeries(
naturalized,
sortingCriteria.seriesSortCriteria.seriesInfoSortingCriteria
);
}
async load(preLoadData) {
const { client, studyInstanceUID } = this;
const seriesInstanceUIDs = preLoadData.map(s => s.SeriesInstanceUID);
const seriesAsyncLoader = makeSeriesAsyncLoader(
client,
studyInstanceUID,
preLoadData
seriesInstanceUIDs
);
// const firstSeries = await seriesAsyncLoader.next();
// return {
// sopInstances: firstSeries.sopInstances,
// asyncLoader: seriesAsyncLoader,
// };
const promises = [];
while (seriesAsyncLoader.hasNext()) {
promises.push(seriesAsyncLoader.next());
}
return promises;
// if (asyncLoader.hasNext()) {
return {
preLoadData,
promises,
};
}
async posLoad(promises) {
return promises;
// const { client } = this;
// const { sopInstances, asyncLoader } = loadData;
// const study = await createStudyFromSOPInstanceList(server, sopInstances);
// if (asyncLoader.hasNext()) {
// attachSeriesLoader(server, study, asyncLoader);
// }
// return study;
async posLoad({ preLoadData, promises }) {
return {
preLoadData,
promises,
};
}
}
@@ -1,25 +0,0 @@
import { DICOMWeb } from '@ohif/core';
// import isLowPriorityModality from '../utils/isLowPriorityModality';
const INFO = Symbol('INFO');
/**
* Creates an object with processed series information and saves its reference
* inside the series object itself.
* @param {Object} series The raw series object
* @returns {Object} object containing some useful info from given series
*/
export default function getSeriesInfo(series) {
let info = series[INFO];
if (!info) {
const modality = DICOMWeb.getString(series['00080060'], '').toUpperCase();
info = Object.freeze({
modality,
// isLowPriority: isLowPriorityModality(modality), // TODO -> We should do this in the series list level, not here.
seriesInstanceUid: DICOMWeb.getString(series['0020000E']),
seriesNumber: DICOMWeb.getNumber(series['00200011'], 0) || 0,
});
series[INFO] = info;
}
return info;
}
+29 -8
View File
@@ -54,7 +54,11 @@ function ViewerLayout({
};
};
const defaultTool = { icon: 'tool-more-menu', label: 'More', isActive: false };
const defaultTool = {
icon: 'tool-more-menu',
label: 'More',
isActive: false,
};
const [toolbars, setToolbars] = useState({ primary: [], secondary: [] });
const [activeTool, setActiveTool] = useState(defaultTool);
@@ -63,7 +67,12 @@ function ViewerLayout({
};
const onPrimaryClickHandler = (evt, btn) => {
if (btn.props && btn.props.commands && evt.value && btn.props.commands[evt.value]) {
if (
btn.props &&
btn.props.commands &&
evt.value &&
btn.props.commands[evt.value]
) {
const { commandName, commandOptions } = btn.props.commands[evt.value];
commandsManager.runCommand(commandName, commandOptions);
}
@@ -75,8 +84,13 @@ function ViewerLayout({
() => {
console.warn('~~~ TOOL BAR MODIFIED EVENT CAUGHT');
const updatedToolbars = {
primary: ToolBarService.getButtonSection('primary', { onClick: onPrimaryClickHandler, setActiveTool: setActiveToolHandler }),
secondary: ToolBarService.getButtonSection('secondary', { setActiveTool: setActiveToolHandler }),
primary: ToolBarService.getButtonSection('primary', {
onClick: onPrimaryClickHandler,
setActiveTool: setActiveToolHandler,
}),
secondary: ToolBarService.getButtonSection('secondary', {
setActiveTool: setActiveToolHandler,
}),
};
setToolbars(updatedToolbars);
}
@@ -94,18 +108,25 @@ function ViewerLayout({
<Header>
<ErrorBoundary context="Primary Toolbar">
<div className="relative flex justify-center">
{toolbars.primary.map(toolDef => {
{toolbars.primary.map((toolDef, index) => {
const isNested = Array.isArray(toolDef);
if (!isNested) {
const { id, Component, componentProps } = toolDef;
return <Component key={id} id={id} {...componentProps} />;
} else {
return (
<NestedMenu isActive={activeTool.isActive} icon={activeTool.icon} label={activeTool.label}>
<NestedMenu
key={index}
isActive={activeTool.isActive}
icon={activeTool.icon}
label={activeTool.label}
>
<div className="flex">
{toolDef.map(x => {
const { id, Component, componentProps } = x;
return <Component key={id} id={id} {...componentProps} />;
return (
<Component key={id} id={id} {...componentProps} />
);
})}
</div>
</NestedMenu>
@@ -174,7 +195,7 @@ ViewerLayout.propTypes = {
leftPanels: PropTypes.array,
rightPanels: PropTypes.array,
/** Responsible for rendering our grid of viewports; provided by consuming application */
children: PropTypes.oneOfType(PropTypes.node, PropTypes.func).isRequired,
children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired,
};
ViewerLayout.defaultProps = {