display viewport.
This commit is contained in:
parent
7c0d93f011
commit
4fc3169fed
@ -1,6 +1,6 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
|
import CornerstoneViewport from 'react-cornerstone-viewport';
|
||||||
import ConnectedCornerstoneViewport from './ConnectedCornerstoneViewport';
|
//import ConnectedCornerstoneViewport from './ConnectedCornerstoneViewport';
|
||||||
import OHIF from '@ohif/core';
|
import OHIF from '@ohif/core';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import cornerstone from 'cornerstone-core';
|
import cornerstone from 'cornerstone-core';
|
||||||
@ -18,9 +18,9 @@ class OHIFCornerstoneViewport extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
studies: PropTypes.object,
|
|
||||||
displaySet: PropTypes.object,
|
displaySet: PropTypes.object,
|
||||||
viewportIndex: PropTypes.number,
|
viewportIndex: PropTypes.number,
|
||||||
|
dataSource: PropTypes.object,
|
||||||
children: PropTypes.node,
|
children: PropTypes.node,
|
||||||
customProps: PropTypes.object,
|
customProps: PropTypes.object,
|
||||||
};
|
};
|
||||||
@ -39,98 +39,57 @@ class OHIFCornerstoneViewport extends Component {
|
|||||||
/**
|
/**
|
||||||
* Obtain the CornerstoneTools Stack for the specified display set.
|
* Obtain the CornerstoneTools Stack for the specified display set.
|
||||||
*
|
*
|
||||||
* @param {Object[]} studies
|
* @param {Object} displaySet
|
||||||
* @param {String} StudyInstanceUID
|
* @param {Object} dataSource
|
||||||
* @param {String} displaySetInstanceUID
|
|
||||||
* @param {String} [SOPInstanceUID]
|
|
||||||
* @param {Number} [frameIndex=1]
|
|
||||||
* @return {Object} CornerstoneTools Stack
|
* @return {Object} CornerstoneTools Stack
|
||||||
*/
|
*/
|
||||||
static getCornerstoneStack(
|
static getCornerstoneStack(displaySet, dataSource) {
|
||||||
studies,
|
const { frameIndex } = displaySet;
|
||||||
StudyInstanceUID,
|
|
||||||
displaySetInstanceUID,
|
|
||||||
SOPInstanceUID,
|
|
||||||
frameIndex = 0
|
|
||||||
) {
|
|
||||||
if (!studies || !studies.length) {
|
|
||||||
throw new Error('Studies not provided.');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!StudyInstanceUID) {
|
|
||||||
throw new Error('StudyInstanceUID not provided.');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!displaySetInstanceUID) {
|
|
||||||
throw new Error('StudyInstanceUID not provided.');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create shortcut to displaySet
|
|
||||||
const study = studies.find(
|
|
||||||
study => study.StudyInstanceUID === StudyInstanceUID
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!study) {
|
|
||||||
throw new Error('Study not found.');
|
|
||||||
}
|
|
||||||
|
|
||||||
const displaySet = study.displaySets.find(set => {
|
|
||||||
return set.displaySetInstanceUID === displaySetInstanceUID;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!displaySet) {
|
|
||||||
throw new Error('Display Set not found.');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get stack from Stack Manager
|
// Get stack from Stack Manager
|
||||||
const storedStack = StackManager.findOrCreateStack(study, displaySet);
|
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 = frameIndex;
|
stack.currentImageIdIndex = frameIndex;
|
||||||
|
|
||||||
if (SOPInstanceUID) {
|
// TODO -> Do we ever use this like this?
|
||||||
const index = stack.imageIds.findIndex(imageId => {
|
// if (SOPInstanceUID) {
|
||||||
const imageIdSOPInstanceUID = cornerstone.metaData.get(
|
// const index = stack.imageIds.findIndex(imageId => {
|
||||||
'SOPInstanceUID',
|
// const imageIdSOPInstanceUID = cornerstone.metaData.get(
|
||||||
imageId
|
// 'SOPInstanceUID',
|
||||||
);
|
// imageId
|
||||||
|
// );
|
||||||
|
|
||||||
return imageIdSOPInstanceUID === SOPInstanceUID;
|
// return imageIdSOPInstanceUID === SOPInstanceUID;
|
||||||
});
|
// });
|
||||||
|
|
||||||
if (index > -1) {
|
// if (index > -1) {
|
||||||
stack.currentImageIdIndex = index;
|
// stack.currentImageIdIndex = index;
|
||||||
} else {
|
// } else {
|
||||||
console.warn(
|
// console.warn(
|
||||||
'SOPInstanceUID provided was not found in specified DisplaySet'
|
// 'SOPInstanceUID provided was not found in specified DisplaySet'
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
return stack;
|
return stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
getViewportData = async (
|
getViewportData = async displaySet => {
|
||||||
studies,
|
|
||||||
StudyInstanceUID,
|
|
||||||
displaySetInstanceUID,
|
|
||||||
SOPInstanceUID,
|
|
||||||
frameIndex
|
|
||||||
) => {
|
|
||||||
let viewportData;
|
let viewportData;
|
||||||
|
|
||||||
|
const { dataSource } = this.props;
|
||||||
|
|
||||||
const stack = OHIFCornerstoneViewport.getCornerstoneStack(
|
const stack = OHIFCornerstoneViewport.getCornerstoneStack(
|
||||||
studies,
|
displaySet,
|
||||||
StudyInstanceUID,
|
dataSource
|
||||||
displaySetInstanceUID,
|
|
||||||
SOPInstanceUID,
|
|
||||||
frameIndex
|
|
||||||
);
|
);
|
||||||
|
|
||||||
viewportData = {
|
viewportData = {
|
||||||
StudyInstanceUID,
|
StudyInstanceUID: displaySet.StudyInstanceUID,
|
||||||
displaySetInstanceUID,
|
displaySetInstanceUID: displaySet.displaySetInstanceUID,
|
||||||
stack,
|
stack,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -138,32 +97,24 @@ class OHIFCornerstoneViewport extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
setStateFromProps() {
|
setStateFromProps() {
|
||||||
const { studies, displaySet } = this.props.viewportData;
|
const { displaySet } = this.props;
|
||||||
const {
|
const {
|
||||||
StudyInstanceUID,
|
StudyInstanceUID,
|
||||||
displaySetInstanceUID,
|
displaySetInstanceUID,
|
||||||
sopClassUIDs,
|
sopClassUids,
|
||||||
SOPInstanceUID,
|
|
||||||
frameIndex,
|
|
||||||
} = displaySet;
|
} = displaySet;
|
||||||
|
|
||||||
if (!StudyInstanceUID || !displaySetInstanceUID) {
|
if (!StudyInstanceUID || !displaySetInstanceUID) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sopClassUIDs && sopClassUIDs.length > 1) {
|
if (sopClassUids && sopClassUids.length > 1) {
|
||||||
console.warn(
|
console.warn(
|
||||||
'More than one SOPClassUID in the same series is not yet supported.'
|
'More than one SOPClassUID in the same series is not yet supported.'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.getViewportData(
|
this.getViewportData(displaySet).then(viewportData => {
|
||||||
studies,
|
|
||||||
StudyInstanceUID,
|
|
||||||
displaySetInstanceUID,
|
|
||||||
SOPInstanceUID,
|
|
||||||
frameIndex
|
|
||||||
).then(viewportData => {
|
|
||||||
this.setState({
|
this.setState({
|
||||||
viewportData,
|
viewportData,
|
||||||
});
|
});
|
||||||
@ -175,8 +126,8 @@ class OHIFCornerstoneViewport extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevProps) {
|
componentDidUpdate(prevProps) {
|
||||||
const { displaySet } = this.props.viewportData;
|
const { displaySet } = this.props;
|
||||||
const prevDisplaySet = prevProps.viewportData.displaySet;
|
const prevDisplaySet = prevProps.displaySet;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
displaySet.displaySetInstanceUID !==
|
displaySet.displaySetInstanceUID !==
|
||||||
@ -232,9 +183,11 @@ class OHIFCornerstoneViewport extends Component {
|
|||||||
700
|
700
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// TODO -> We may still want a wrapped component to define all the measurement api stuff.
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<ConnectedCornerstoneViewport
|
{/* <ConnectedCornerstoneViewport
|
||||||
viewportIndex={viewportIndex}
|
viewportIndex={viewportIndex}
|
||||||
imageIds={imageIds}
|
imageIds={imageIds}
|
||||||
imageIdIndex={currentImageIdIndex}
|
imageIdIndex={currentImageIdIndex}
|
||||||
@ -246,6 +199,16 @@ class OHIFCornerstoneViewport extends Component {
|
|||||||
// onElementEnabled={() => {}}
|
// onElementEnabled={() => {}}
|
||||||
// setViewportActive{() => {}}
|
// setViewportActive{() => {}}
|
||||||
{...this.props.customProps}
|
{...this.props.customProps}
|
||||||
|
/> */}
|
||||||
|
<CornerstoneViewport
|
||||||
|
viewportIndex={viewportIndex}
|
||||||
|
imageIds={imageIds}
|
||||||
|
imageIdIndex={currentImageIdIndex}
|
||||||
|
onNewImage={debouncedNewImageHandler}
|
||||||
|
isActive={true} // todo
|
||||||
|
isStackPrefetchEnabled={true} // todo
|
||||||
|
isPlaying={false}
|
||||||
|
frameRate={24}
|
||||||
/>
|
/>
|
||||||
{childrenWithProps}
|
{childrenWithProps}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -130,9 +130,9 @@ function createDicomWebApi(dicomWebConfig) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
getImageIdsForDisplaySet(displaySetInstanceUid) {
|
getImageIdsForDisplaySet(displaySetInstanceUID) {
|
||||||
const displaySet = displaySetManager.getDisplaySetByUID(
|
const displaySet = displaySetManager.getDisplaySetByUID(
|
||||||
displaySetInstanceUid
|
displaySetInstanceUID
|
||||||
);
|
);
|
||||||
|
|
||||||
const images = displaySet.images;
|
const images = displaySet.images;
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
import React, { useEffect } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { SidePanel, Toolbar } from '@ohif/ui';
|
import { SidePanel, Toolbar } from '@ohif/ui';
|
||||||
//
|
//
|
||||||
import Header from './Header.jsx';
|
import Header from './Header.jsx';
|
||||||
|
import { displaySetManager } from '@ohif/core';
|
||||||
|
|
||||||
function ViewerLayout({
|
function ViewerLayout({
|
||||||
// From Extension Module Params
|
// From Extension Module Params
|
||||||
@ -11,7 +12,8 @@ function ViewerLayout({
|
|||||||
leftPanels,
|
leftPanels,
|
||||||
rightPanels,
|
rightPanels,
|
||||||
toolBarLayout,
|
toolBarLayout,
|
||||||
displaySetInstanceUids,
|
viewports,
|
||||||
|
displaySetInstanceUIDs,
|
||||||
ViewportGrid,
|
ViewportGrid,
|
||||||
}) {
|
}) {
|
||||||
/**
|
/**
|
||||||
@ -28,6 +30,17 @@ function ViewerLayout({
|
|||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
// TODO -> Need some way of selecting which displaySets hit the viewports.
|
||||||
|
const [viewportData, setViewportData] = useState([]);
|
||||||
|
|
||||||
|
console.log(displaySetInstanceUIDs);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setViewportData([
|
||||||
|
displaySetManager.getDisplaySetByUID(displaySetInstanceUIDs[0]),
|
||||||
|
]);
|
||||||
|
}, [displaySetInstanceUIDs]);
|
||||||
|
|
||||||
const getPanelData = id => {
|
const getPanelData = id => {
|
||||||
const entry = extensionManager.getModuleEntry(id);
|
const entry = extensionManager.getModuleEntry(id);
|
||||||
// TODO, not sure why sidepanel content has to be JSX, and not a children prop?
|
// TODO, not sure why sidepanel content has to be JSX, and not a children prop?
|
||||||
@ -42,11 +55,22 @@ function ViewerLayout({
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getViewportComponentData = viewportComponent => {
|
||||||
|
const entry = extensionManager.getModuleEntry(viewportComponent.namespace);
|
||||||
|
|
||||||
|
return {
|
||||||
|
component: entry.component,
|
||||||
|
displaySetsToDisplay: viewportComponent.displaySetsToDisplay,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const leftPanelComponents = leftPanels.map(getPanelData);
|
const leftPanelComponents = leftPanels.map(getPanelData);
|
||||||
const rightPanelComponents = rightPanels.map(getPanelData);
|
const rightPanelComponents = rightPanels.map(getPanelData);
|
||||||
|
|
||||||
console.warn(displaySetInstanceUids);
|
const viewportComponents = viewports.map(getViewportComponentData);
|
||||||
console.warn(toolBarLayout);
|
|
||||||
|
console.log(displaySetInstanceUIDs);
|
||||||
|
console.log(toolBarLayout);
|
||||||
|
|
||||||
const [primaryToolBarLayout, secondaryToolBarLayout] = toolBarLayout;
|
const [primaryToolBarLayout, secondaryToolBarLayout] = toolBarLayout;
|
||||||
|
|
||||||
@ -72,7 +96,10 @@ function ViewerLayout({
|
|||||||
<Toolbar type="secondary" tools={secondaryToolBarLayout.tools} />
|
<Toolbar type="secondary" tools={secondaryToolBarLayout.tools} />
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-1 h-full overflow-hidden bg-black items-center justify-center pb-2 pt-1">
|
<div className="flex flex-1 h-full overflow-hidden bg-black items-center justify-center pb-2 pt-1">
|
||||||
<ViewportGrid />
|
<ViewportGrid
|
||||||
|
viewportData={viewportData}
|
||||||
|
viewportComponents={viewportComponents}
|
||||||
|
/>
|
||||||
{/*
|
{/*
|
||||||
viewportContents={[
|
viewportContents={[
|
||||||
<Viewport
|
<Viewport
|
||||||
@ -152,7 +179,7 @@ ViewerLayout.propTypes = {
|
|||||||
moreTools: PropTypes.array,
|
moreTools: PropTypes.array,
|
||||||
})
|
})
|
||||||
).isRequired,
|
).isRequired,
|
||||||
displaySetInstanceUids: PropTypes.any.isRequired,
|
displaySetInstanceUIDs: PropTypes.any.isRequired,
|
||||||
leftPanels: PropTypes.array,
|
leftPanels: PropTypes.array,
|
||||||
rightPanels: PropTypes.array,
|
rightPanels: PropTypes.array,
|
||||||
/** Responsible for rendering our grid of viewports; provided by consuming application */
|
/** Responsible for rendering our grid of viewports; provided by consuming application */
|
||||||
|
|||||||
@ -40,7 +40,7 @@ function StudyBrowserPanel({ getDataSources, commandsManager }) {
|
|||||||
const seriesTracking = {}; //useSeriesTracking();
|
const seriesTracking = {}; //useSeriesTracking();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!viewModel.displaySetInstanceUids.length) {
|
if (!viewModel.displaySetInstanceUIDs.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ function StudyBrowserPanel({ getDataSources, commandsManager }) {
|
|||||||
|
|
||||||
const { cornerstone, cornerstoneTools } = command.commandFn();
|
const { cornerstone, cornerstoneTools } = command.commandFn();
|
||||||
|
|
||||||
viewModel.displaySetInstanceUids.forEach(uid => {
|
viewModel.displaySetInstanceUIDs.forEach(uid => {
|
||||||
const imageIds = dataSource.getImageIdsForDisplaySet(uid);
|
const imageIds = dataSource.getImageIdsForDisplaySet(uid);
|
||||||
const imageId = imageIds[Math.floor(imageIds.length / 2)];
|
const imageId = imageIds[Math.floor(imageIds.length / 2)];
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ function StudyBrowserPanel({ getDataSources, commandsManager }) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const displaySets = viewModel.displaySetInstanceUids.map(
|
const displaySets = viewModel.displaySetInstanceUIDs.map(
|
||||||
displaySetManager.getDisplaySetByUID
|
displaySetManager.getDisplaySetByUID
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ function StudyBrowserPanel({ getDataSources, commandsManager }) {
|
|||||||
const studiesFromInstanceData = {};
|
const studiesFromInstanceData = {};
|
||||||
displaySets.forEach(ds => {
|
displaySets.forEach(ds => {
|
||||||
const displaySet = {
|
const displaySet = {
|
||||||
displaySetInstanceUid: ds.displaySetInstanceUid,
|
displaySetInstanceUID: ds.displaySetInstanceUID,
|
||||||
description: ds.SeriesDescription,
|
description: ds.SeriesDescription,
|
||||||
seriesNumber: ds.SeriesNumber,
|
seriesNumber: ds.SeriesNumber,
|
||||||
modality: ds.Modality,
|
modality: ds.Modality,
|
||||||
@ -107,7 +107,7 @@ function StudyBrowserPanel({ getDataSources, commandsManager }) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const displaySetViewportData = viewportData.find(
|
const displaySetViewportData = viewportData.find(
|
||||||
a => a.displaySetInstanceUid === ds.displaySetInstanceUid
|
a => a.displaySetInstanceUID === ds.displaySetInstanceUID
|
||||||
);
|
);
|
||||||
|
|
||||||
if (displaySetViewportData) {
|
if (displaySetViewportData) {
|
||||||
@ -192,11 +192,11 @@ function StudyBrowserPanel({ getDataSources, commandsManager }) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return () => (isSubscribed = false);
|
return () => (isSubscribed = false);
|
||||||
}, [viewModel.displaySetInstanceUids]);
|
}, [viewModel.displaySetInstanceUIDs]);
|
||||||
|
|
||||||
studyData.forEach(study => {
|
studyData.forEach(study => {
|
||||||
study.displaySets.forEach(ds => {
|
study.displaySets.forEach(ds => {
|
||||||
ds.imageSrc = thumbnailImageSrcMap.get(ds.displaySetInstanceUid);
|
ds.imageSrc = thumbnailImageSrcMap.get(ds.displaySetInstanceUID);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,7 @@ const makeDisplaySet = instances => {
|
|||||||
|
|
||||||
// set appropriate attributes to image set...
|
// set appropriate attributes to image set...
|
||||||
imageSet.setAttributes({
|
imageSet.setAttributes({
|
||||||
displaySetInstanceUid: imageSet.uid, // create a local alias for the imageSet UID
|
displaySetInstanceUID: imageSet.uid, // create a local alias for the imageSet UID
|
||||||
SeriesDate: instance.SeriesDate,
|
SeriesDate: instance.SeriesDate,
|
||||||
SeriesTime: instance.SeriesTime,
|
SeriesTime: instance.SeriesTime,
|
||||||
SeriesInstanceUID: instance.SeriesInstanceUID,
|
SeriesInstanceUID: instance.SeriesInstanceUID,
|
||||||
|
|||||||
@ -74,8 +74,7 @@ export default function mode({ modeConfiguration }) {
|
|||||||
rightPanels: ['org.ohif.default.panelModule.measure'],
|
rightPanels: ['org.ohif.default.panelModule.measure'],
|
||||||
viewports: [
|
viewports: [
|
||||||
{
|
{
|
||||||
namespace:
|
namespace: 'org.ohif.cornerstone.viewportModule.cornerstone',
|
||||||
'org.ohif.cornerstone.viewportModule.OHIFCornerstoneViewport',
|
|
||||||
displaySetsToDisplay: [
|
displaySetsToDisplay: [
|
||||||
'org.ohif.default.sopClassHandlerModule.stack',
|
'org.ohif.default.sopClassHandlerModule.stack',
|
||||||
],
|
],
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import React, { Component, useContext } from 'react';
|
|||||||
/// TODO MAKE THIS PRETTY DANNY
|
/// TODO MAKE THIS PRETTY DANNY
|
||||||
|
|
||||||
const ViewModelContext = React.createContext({
|
const ViewModelContext = React.createContext({
|
||||||
displaySetInstanceUids: [],
|
displaySetInstanceUIDs: [],
|
||||||
setDisplaySetInstanceUids: () => {},
|
setDisplaySetInstanceUids: () => {},
|
||||||
toolBarLayout: [],
|
toolBarLayout: [],
|
||||||
setToolBarLayout: () => {},
|
setToolBarLayout: () => {},
|
||||||
@ -13,12 +13,12 @@ ViewModelContext.displayName = 'ViewModelContext';
|
|||||||
|
|
||||||
class ViewModelProvider extends Component {
|
class ViewModelProvider extends Component {
|
||||||
state = {
|
state = {
|
||||||
displaySetInstanceUids: [],
|
displaySetInstanceUIDs: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const setDisplaySetInstanceUids = displaySetInstanceUids => {
|
const setDisplaySetInstanceUids = displaySetInstanceUIDs => {
|
||||||
this.setState({ displaySetInstanceUids });
|
this.setState({ displaySetInstanceUIDs });
|
||||||
};
|
};
|
||||||
|
|
||||||
const setToolBarLayout = toolBarLayout => {
|
const setToolBarLayout = toolBarLayout => {
|
||||||
@ -28,7 +28,7 @@ class ViewModelProvider extends Component {
|
|||||||
return (
|
return (
|
||||||
<ViewModelContext.Provider
|
<ViewModelContext.Provider
|
||||||
value={{
|
value={{
|
||||||
displaySetInstanceUids: this.state.displaySetInstanceUids,
|
displaySetInstanceUIDs: this.state.displaySetInstanceUIDs,
|
||||||
setDisplaySetInstanceUids,
|
setDisplaySetInstanceUids,
|
||||||
toolBarLayout: this.state.toolBarLayout,
|
toolBarLayout: this.state.toolBarLayout,
|
||||||
setToolBarLayout,
|
setToolBarLayout,
|
||||||
|
|||||||
@ -8,26 +8,26 @@ class DisplaySetManager {
|
|||||||
this.SOPClassHandlerIds = SOPClassHandlerIds;
|
this.SOPClassHandlerIds = SOPClassHandlerIds;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
displaySetInstanceUids,
|
displaySetInstanceUIDs,
|
||||||
setDisplaySetInstanceUids,
|
setDisplaySetInstanceUids,
|
||||||
} = viewModelContext;
|
} = viewModelContext;
|
||||||
|
|
||||||
this.displaySetInstanceUids = displaySetInstanceUids;
|
this.displaySetInstanceUIDs = displaySetInstanceUIDs;
|
||||||
this.setDisplaySetInstanceUids = setDisplaySetInstanceUids;
|
this.setDisplaySetInstanceUids = setDisplaySetInstanceUids;
|
||||||
|
|
||||||
// Reset displaySetInstanceUids
|
// Reset displaySetInstanceUIDs
|
||||||
this.setDisplaySetInstanceUids([]);
|
this.setDisplaySetInstanceUids([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
_addDisplaySets(displaySets) {
|
_addDisplaySets(displaySets) {
|
||||||
//const displayInstanceUids = [...this.displaySetInstanceUids];
|
//const displayInstanceUids = [...this.displaySetInstanceUIDs];
|
||||||
|
|
||||||
const addedDisplaySetUids = [];
|
const addedDisplaySetUids = [];
|
||||||
|
|
||||||
displaySets.forEach(displaySet => {
|
displaySets.forEach(displaySet => {
|
||||||
this.displaySets.push(displaySet);
|
this.displaySets.push(displaySet);
|
||||||
|
|
||||||
addedDisplaySetUids.push(displaySet.displaySetInstanceUid);
|
addedDisplaySetUids.push(displaySet.displaySetInstanceUID);
|
||||||
});
|
});
|
||||||
|
|
||||||
return addedDisplaySetUids;
|
return addedDisplaySetUids;
|
||||||
@ -39,9 +39,9 @@ class DisplaySetManager {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
getDisplaySetByUID = displaySetInstanceUid => {
|
getDisplaySetByUID = displaySetInstanceUID => {
|
||||||
return this.displaySets.find(
|
return this.displaySets.find(
|
||||||
displaySet => displaySet.displaySetInstanceUid === displaySetInstanceUid
|
displaySet => displaySet.displaySetInstanceUID === displaySetInstanceUID
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ class DisplaySetManager {
|
|||||||
|
|
||||||
if (cachedDisplaySets.length) {
|
if (cachedDisplaySets.length) {
|
||||||
addedDisplaySetUids = cachedDisplaySets.map(
|
addedDisplaySetUids = cachedDisplaySets.map(
|
||||||
displaySet => displaySet.displaySetInstanceUid
|
displaySet => displaySet.displaySetInstanceUID
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
const displaySets = handler.getDisplaySetsFromSeries(instances);
|
const displaySets = handler.getDisplaySetsFromSeries(instances);
|
||||||
@ -79,12 +79,12 @@ class DisplaySetManager {
|
|||||||
addedDisplaySetUids = this._addDisplaySets(displaySets);
|
addedDisplaySetUids = this._addDisplaySets(displaySets);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.displaySetInstanceUids = [
|
this.displaySetInstanceUIDs = [
|
||||||
...addedDisplaySetUids,
|
...addedDisplaySetUids,
|
||||||
...this.displaySetInstanceUids,
|
...this.displaySetInstanceUIDs,
|
||||||
];
|
];
|
||||||
|
|
||||||
this.setDisplaySetInstanceUids(this.displaySetInstanceUids);
|
this.setDisplaySetInstanceUids(this.displaySetInstanceUIDs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -105,9 +105,9 @@ export default class ExtensionManager {
|
|||||||
this._initToolBarModule(extensionModule, extensionId);
|
this._initToolBarModule(extensionModule, extensionId);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MODULE_TYPES.VIEWPORT:
|
||||||
case MODULE_TYPES.PANEL:
|
case MODULE_TYPES.PANEL:
|
||||||
case MODULE_TYPES.SOP_CLASS_HANDLER:
|
case MODULE_TYPES.SOP_CLASS_HANDLER:
|
||||||
case MODULE_TYPES.VIEWPORT:
|
|
||||||
case MODULE_TYPES.CONTEXT:
|
case MODULE_TYPES.CONTEXT:
|
||||||
case MODULE_TYPES.LAYOUT_TEMPLATE:
|
case MODULE_TYPES.LAYOUT_TEMPLATE:
|
||||||
// Default for most extension points,
|
// Default for most extension points,
|
||||||
@ -118,6 +118,7 @@ export default class ExtensionManager {
|
|||||||
`${extensionId}.${moduleType}.${element.name}`
|
`${extensionId}.${moduleType}.${element.name}`
|
||||||
] = element;
|
] = element;
|
||||||
});
|
});
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.modules[moduleType].push({
|
this.modules[moduleType].push({
|
||||||
|
|||||||
@ -11,79 +11,37 @@ const stackUpdatedCallbacks = [];
|
|||||||
* Cornerstone meta data provider. This will be used to fill information
|
* Cornerstone meta data provider. This will be used to fill information
|
||||||
* into the viewport overlays, and to calculate reference lines and orientation markers
|
* into the viewport overlays, and to calculate reference lines and orientation markers
|
||||||
* @param {Object} stackMap stackMap object
|
* @param {Object} stackMap stackMap object
|
||||||
* @param {Object} study Study object
|
|
||||||
* @param {Object} displaySet The set of images to make the stack from
|
* @param {Object} displaySet The set of images to make the stack from
|
||||||
* @return {Array} Array with image IDs
|
* @return {Array} Array with image IDs
|
||||||
*/
|
*/
|
||||||
function createAndAddStack(stackMap, study, displaySet, stackUpdatedCallbacks) {
|
function createAndAddStack(
|
||||||
const images = displaySet.images;
|
stackMap,
|
||||||
|
displaySet,
|
||||||
|
dataSource,
|
||||||
|
stackUpdatedCallbacks
|
||||||
|
) {
|
||||||
|
const {
|
||||||
|
images,
|
||||||
|
displaySetInstanceUID,
|
||||||
|
StudyInstanceUID,
|
||||||
|
frameRate,
|
||||||
|
isClip,
|
||||||
|
} = displaySet;
|
||||||
if (!images) {
|
if (!images) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const numImages = images.length;
|
const imageIds = dataSource.getImageIdsForDisplaySet(displaySetInstanceUID);
|
||||||
const imageIds = [];
|
|
||||||
let imageId;
|
|
||||||
|
|
||||||
displaySet.images.forEach((instance, imageIndex) => {
|
|
||||||
const image = instance.getData();
|
|
||||||
const metaData = {
|
|
||||||
instance: image, // in this context, instance will be the data of the InstanceMetadata object...
|
|
||||||
series: displaySet, // TODO: Check this
|
|
||||||
study,
|
|
||||||
numImages,
|
|
||||||
imageIndex: imageIndex + 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
const naturalizedInstance = instance.getData().metadata;
|
|
||||||
const NumberOfFrames = naturalizedInstance.NumberOfFrames;
|
|
||||||
|
|
||||||
if (NumberOfFrames > 1) {
|
|
||||||
for (let i = 0; i < NumberOfFrames; i++) {
|
|
||||||
metaData.frameNumber = i;
|
|
||||||
imageId = getImageId(image, i);
|
|
||||||
imageIds.push(imageId);
|
|
||||||
|
|
||||||
const {
|
|
||||||
StudyInstanceUID,
|
|
||||||
SeriesInstanceUID,
|
|
||||||
SOPInstanceUID,
|
|
||||||
} = instance.getData().metadata;
|
|
||||||
|
|
||||||
metadataProvider.addImageIdToUIDs(imageId, {
|
|
||||||
StudyInstanceUID,
|
|
||||||
SeriesInstanceUID,
|
|
||||||
SOPInstanceUID,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
metaData.frameNumber = 1;
|
|
||||||
imageId = getImageId(image);
|
|
||||||
imageIds.push(imageId);
|
|
||||||
|
|
||||||
const {
|
|
||||||
StudyInstanceUID,
|
|
||||||
SeriesInstanceUID,
|
|
||||||
SOPInstanceUID,
|
|
||||||
} = naturalizedInstance;
|
|
||||||
|
|
||||||
metadataProvider.addImageIdToUIDs(imageId, {
|
|
||||||
StudyInstanceUID,
|
|
||||||
SeriesInstanceUID,
|
|
||||||
SOPInstanceUID,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const stack = {
|
const stack = {
|
||||||
StudyInstanceUID: study.StudyInstanceUID,
|
StudyInstanceUID,
|
||||||
displaySetInstanceUID: displaySet.displaySetInstanceUID,
|
displaySetInstanceUID,
|
||||||
imageIds,
|
imageIds,
|
||||||
frameRate: displaySet.frameRate,
|
frameRate,
|
||||||
isClip: displaySet.isClip,
|
isClip,
|
||||||
};
|
};
|
||||||
|
|
||||||
stackMap[displaySet.displaySetInstanceUID] = stack;
|
stackMap[displaySetInstanceUID] = stack;
|
||||||
|
|
||||||
return stack;
|
return stack;
|
||||||
}
|
}
|
||||||
@ -106,15 +64,14 @@ const StackManager = {
|
|||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Create a stack from an image set, as well as add in the metadata on a per image bases.
|
* Create a stack from an image set, as well as add in the metadata on a per image bases.
|
||||||
* @param study The study who's metadata will be added
|
|
||||||
* @param displaySet The set of images to make the stack from
|
* @param displaySet The set of images to make the stack from
|
||||||
* @return {Array} Array with image IDs
|
* @return {Array} Array with image IDs
|
||||||
*/
|
*/
|
||||||
makeAndAddStack(study, displaySet) {
|
makeAndAddStack(displaySet, dataSource) {
|
||||||
return configuration.createAndAddStack(
|
return configuration.createAndAddStack(
|
||||||
stackMap,
|
stackMap,
|
||||||
study,
|
|
||||||
displaySet,
|
displaySet,
|
||||||
|
dataSource,
|
||||||
stackUpdatedCallbacks
|
stackUpdatedCallbacks
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -128,15 +85,14 @@ const StackManager = {
|
|||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Find a stack or reate one if it has not been created yet
|
* Find a stack or reate one if it has not been created yet
|
||||||
* @param study The study who's metadata will be added
|
|
||||||
* @param displaySet The set of images to make the stack from
|
* @param displaySet The set of images to make the stack from
|
||||||
* @return {Array} Array with image IDs
|
* @return {Array} Array with image IDs
|
||||||
*/
|
*/
|
||||||
findOrCreateStack(study, displaySet) {
|
findOrCreateStack(displaySet, dataSource) {
|
||||||
let stack = this.findStack(displaySet.displaySetInstanceUID);
|
let stack = this.findStack(displaySet.displaySetInstanceUID);
|
||||||
|
|
||||||
if (!stack || !stack.imageIds) {
|
if (!stack || !stack.imageIds) {
|
||||||
stack = this.makeAndAddStack(study, displaySet);
|
stack = this.makeAndAddStack(displaySet, dataSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
return stack;
|
return stack;
|
||||||
|
|||||||
@ -30,7 +30,7 @@ import studyMetadataManager from './studyMetadataManager';
|
|||||||
* Factory function to load and cache derived display sets.
|
* Factory function to load and cache derived display sets.
|
||||||
*
|
*
|
||||||
* @param {object} referencedDisplaySet Display set
|
* @param {object} referencedDisplaySet Display set
|
||||||
* @param {string} referencedDisplaySet.displaySetInstanceUid Display set instance uid
|
* @param {string} referencedDisplaySet.displaySetInstanceUID Display set instance uid
|
||||||
* @param {string} referencedDisplaySet.seriesDate
|
* @param {string} referencedDisplaySet.seriesDate
|
||||||
* @param {string} referencedDisplaySet.seriesTime
|
* @param {string} referencedDisplaySet.seriesTime
|
||||||
* @param {string} referencedDisplaySet.seriesInstanceUid
|
* @param {string} referencedDisplaySet.seriesInstanceUid
|
||||||
|
|||||||
@ -7,13 +7,13 @@ import { ButtonGroup, Button, StudyItem, ThumbnailList } from '@ohif/ui';
|
|||||||
const buttonClasses = 'text-white text-base border-none bg-black p-2 min-w-18';
|
const buttonClasses = 'text-white text-base border-none bg-black p-2 min-w-18';
|
||||||
const activeButtonClasses = 'bg-primary-main';
|
const activeButtonClasses = 'bg-primary-main';
|
||||||
|
|
||||||
const getInitialActiveTab = (tabs) => {
|
const getInitialActiveTab = tabs => {
|
||||||
return tabs && tabs[0] && tabs[0].name;
|
return tabs && tabs[0] && tabs[0].name;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getTrackedSeries = (displaySets) => {
|
const getTrackedSeries = displaySets => {
|
||||||
let trackedSeries = 0;
|
let trackedSeries = 0;
|
||||||
displaySets.forEach((displaySet) => {
|
displaySets.forEach(displaySet => {
|
||||||
if (displaySet.isTracked) {
|
if (displaySet.isTracked) {
|
||||||
trackedSeries++;
|
trackedSeries++;
|
||||||
}
|
}
|
||||||
@ -28,7 +28,7 @@ const StudyBrowser = ({ tabs, onClickStudy, onClickThumbnail }) => {
|
|||||||
const [thumbnailActive, setThumbnailActive] = useState(null);
|
const [thumbnailActive, setThumbnailActive] = useState(null);
|
||||||
|
|
||||||
const getTabContent = () => {
|
const getTabContent = () => {
|
||||||
const tabData = tabs.find((tab) => tab.name === tabActive);
|
const tabData = tabs.find(tab => tab.name === tabActive);
|
||||||
|
|
||||||
if (!tabData || !tabData.studies || !Array.isArray(tabData.studies)) {
|
if (!tabData || !tabData.studies || !Array.isArray(tabData.studies)) {
|
||||||
return;
|
return;
|
||||||
@ -65,17 +65,16 @@ const StudyBrowser = ({ tabs, onClickStudy, onClickThumbnail }) => {
|
|||||||
<ThumbnailList
|
<ThumbnailList
|
||||||
thumbnails={displaySets}
|
thumbnails={displaySets}
|
||||||
thumbnailActive={thumbnailActive}
|
thumbnailActive={thumbnailActive}
|
||||||
onThumbnailClick={(thumbnailId) => {
|
onThumbnailClick={thumbnailId => {
|
||||||
setThumbnailActive(
|
setThumbnailActive(
|
||||||
thumbnailId === thumbnailActive ? null : thumbnailId
|
thumbnailId === thumbnailActive ? null : thumbnailId
|
||||||
)
|
);
|
||||||
|
|
||||||
if (onClickThumbnail) {
|
if (onClickThumbnail) {
|
||||||
// TODO: what is thumbnailId? Should pass display set instead
|
// TODO: what is thumbnailId? Should pass display set instead
|
||||||
onClickThumbnail(thumbnailId);
|
onClickThumbnail(thumbnailId);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
@ -92,7 +91,7 @@ const StudyBrowser = ({ tabs, onClickStudy, onClickThumbnail }) => {
|
|||||||
color="inherit"
|
color="inherit"
|
||||||
className="border border-secondary-light rounded-md"
|
className="border border-secondary-light rounded-md"
|
||||||
>
|
>
|
||||||
{tabs.map((tab) => {
|
{tabs.map(tab => {
|
||||||
const { name, label } = tab;
|
const { name, label } = tab;
|
||||||
const isActive = tabActive === name;
|
const isActive = tabActive === name;
|
||||||
return (
|
return (
|
||||||
@ -137,7 +136,7 @@ StudyBrowser.propTypes = {
|
|||||||
description: PropTypes.string,
|
description: PropTypes.string,
|
||||||
displaySets: PropTypes.arrayOf(
|
displaySets: PropTypes.arrayOf(
|
||||||
PropTypes.shape({
|
PropTypes.shape({
|
||||||
displaySetInstanceUid: PropTypes.string.isRequired,
|
displaySetInstanceUID: PropTypes.string.isRequired,
|
||||||
imageSrc: PropTypes.string,
|
imageSrc: PropTypes.string,
|
||||||
imageAltText: PropTypes.string,
|
imageAltText: PropTypes.string,
|
||||||
seriesDate: PropTypes.string,
|
seriesDate: PropTypes.string,
|
||||||
|
|||||||
@ -27,7 +27,7 @@ import { StudyBrowser } from '@ohif/ui';
|
|||||||
modalities: 'CT,SR',
|
modalities: 'CT,SR',
|
||||||
displaySets: [
|
displaySets: [
|
||||||
{
|
{
|
||||||
displaySetInstanceUid: 'f69f6asdasd48c-223e-db7f-c4af-b8906641a66e',
|
displaySetInstanceUID: 'f69f6asdasd48c-223e-db7f-c4af-b8906641a66e',
|
||||||
description: 'Multiple line image series description lorem sit',
|
description: 'Multiple line image series description lorem sit',
|
||||||
seriesNumber: 1,
|
seriesNumber: 1,
|
||||||
numInstances: 68,
|
numInstances: 68,
|
||||||
@ -36,7 +36,7 @@ import { StudyBrowser } from '@ohif/ui';
|
|||||||
isTracked: true,
|
isTracked: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displaySetInstanceUid: 'f69f648c-223e-db7f-c4asdasdaf-b8906641a66e',
|
displaySetInstanceUID: 'f69f648c-223e-db7f-c4asdasdaf-b8906641a66e',
|
||||||
description: 'Multiple line image series description lorem sit',
|
description: 'Multiple line image series description lorem sit',
|
||||||
seriesNumber: 1,
|
seriesNumber: 1,
|
||||||
numInstances: 68,
|
numInstances: 68,
|
||||||
@ -44,14 +44,14 @@ import { StudyBrowser } from '@ohif/ui';
|
|||||||
viewportIdentificator: 'B',
|
viewportIdentificator: 'B',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displaySetInstanceUid: 'f69f648c-223e-dasdasdb7f-c4af-b8906641a66e',
|
displaySetInstanceUID: 'f69f648c-223e-dasdasdb7f-c4af-b8906641a66e',
|
||||||
description: 'Multiple line image series description lorem sit',
|
description: 'Multiple line image series description lorem sit',
|
||||||
seriesNumber: 1,
|
seriesNumber: 1,
|
||||||
numInstances: 68,
|
numInstances: 68,
|
||||||
componentType: 'thumbnailTracked',
|
componentType: 'thumbnailTracked',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displaySetInstanceUid: 'f69f648c-223e-db7f-c4afas-b8906asd641a66e',
|
displaySetInstanceUID: 'f69f648c-223e-db7f-c4afas-b8906asd641a66e',
|
||||||
description: 'Multiple line description lorem ipsum dolor sit amet',
|
description: 'Multiple line description lorem ipsum dolor sit amet',
|
||||||
modality: 'SR',
|
modality: 'SR',
|
||||||
componentType: 'thumbnailNoImage',
|
componentType: 'thumbnailNoImage',
|
||||||
@ -67,7 +67,7 @@ import { StudyBrowser } from '@ohif/ui';
|
|||||||
modalities: 'CT',
|
modalities: 'CT',
|
||||||
displaySets: [
|
displaySets: [
|
||||||
{
|
{
|
||||||
displaySetInstanceUid: 'f69f648c-223e-db7f-c4af-b8906641a66e',
|
displaySetInstanceUID: 'f69f648c-223e-db7f-c4af-b8906641a66e',
|
||||||
description: 'Multiple line image series description lorem sit',
|
description: 'Multiple line image series description lorem sit',
|
||||||
seriesNumber: 1,
|
seriesNumber: 1,
|
||||||
numInstances: 68,
|
numInstances: 68,
|
||||||
|
|||||||
@ -8,7 +8,7 @@ const ThumbnailList = ({ thumbnails, thumbnailActive, onThumbnailClick }) => {
|
|||||||
<div className="bg-black py-3">
|
<div className="bg-black py-3">
|
||||||
{thumbnails.map(
|
{thumbnails.map(
|
||||||
({
|
({
|
||||||
displaySetInstanceUid,
|
displaySetInstanceUID,
|
||||||
description,
|
description,
|
||||||
seriesNumber,
|
seriesNumber,
|
||||||
numInstances,
|
numInstances,
|
||||||
@ -20,13 +20,13 @@ const ThumbnailList = ({ thumbnails, thumbnailActive, onThumbnailClick }) => {
|
|||||||
imageSrc,
|
imageSrc,
|
||||||
imageAltText,
|
imageAltText,
|
||||||
}) => {
|
}) => {
|
||||||
const isActive = thumbnailActive === displaySetInstanceUid;
|
const isActive = thumbnailActive === displaySetInstanceUID;
|
||||||
|
|
||||||
switch (componentType) {
|
switch (componentType) {
|
||||||
case 'thumbnail':
|
case 'thumbnail':
|
||||||
return (
|
return (
|
||||||
<Thumbnail
|
<Thumbnail
|
||||||
key={displaySetInstanceUid}
|
key={displaySetInstanceUID}
|
||||||
description={description}
|
description={description}
|
||||||
seriesNumber={seriesNumber}
|
seriesNumber={seriesNumber}
|
||||||
numInstances={numInstances}
|
numInstances={numInstances}
|
||||||
@ -34,23 +34,23 @@ const ThumbnailList = ({ thumbnails, thumbnailActive, onThumbnailClick }) => {
|
|||||||
imageAltText={imageAltText}
|
imageAltText={imageAltText}
|
||||||
viewportIdentificator={viewportIdentificator}
|
viewportIdentificator={viewportIdentificator}
|
||||||
isActive={isActive}
|
isActive={isActive}
|
||||||
onClick={() => onThumbnailClick(displaySetInstanceUid)}
|
onClick={() => onThumbnailClick(displaySetInstanceUID)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
case 'thumbnailNoImage':
|
case 'thumbnailNoImage':
|
||||||
return (
|
return (
|
||||||
<ThumbnailNoImage
|
<ThumbnailNoImage
|
||||||
key={displaySetInstanceUid}
|
key={displaySetInstanceUID}
|
||||||
modality={modality}
|
modality={modality}
|
||||||
seriesDate={seriesDate}
|
seriesDate={seriesDate}
|
||||||
description={description}
|
description={description}
|
||||||
onClick={() => onThumbnailClick(displaySetInstanceUid)}
|
onClick={() => onThumbnailClick(displaySetInstanceUID)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
case 'thumbnailTracked':
|
case 'thumbnailTracked':
|
||||||
return (
|
return (
|
||||||
<ThumbnailTracked
|
<ThumbnailTracked
|
||||||
key={displaySetInstanceUid}
|
key={displaySetInstanceUID}
|
||||||
description={description}
|
description={description}
|
||||||
seriesNumber={seriesNumber}
|
seriesNumber={seriesNumber}
|
||||||
numInstances={numInstances}
|
numInstances={numInstances}
|
||||||
@ -59,7 +59,7 @@ const ThumbnailList = ({ thumbnails, thumbnailActive, onThumbnailClick }) => {
|
|||||||
viewportIdentificator={viewportIdentificator}
|
viewportIdentificator={viewportIdentificator}
|
||||||
isTracked={isTracked}
|
isTracked={isTracked}
|
||||||
isActive={isActive}
|
isActive={isActive}
|
||||||
onClick={() => onThumbnailClick(displaySetInstanceUid)}
|
onClick={() => onThumbnailClick(displaySetInstanceUID)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
default:
|
default:
|
||||||
@ -74,7 +74,7 @@ const ThumbnailList = ({ thumbnails, thumbnailActive, onThumbnailClick }) => {
|
|||||||
ThumbnailList.propTypes = {
|
ThumbnailList.propTypes = {
|
||||||
thumbnails: PropTypes.arrayOf(
|
thumbnails: PropTypes.arrayOf(
|
||||||
PropTypes.shape({
|
PropTypes.shape({
|
||||||
displaySetInstanceUid: PropTypes.string.isRequired,
|
displaySetInstanceUID: PropTypes.string.isRequired,
|
||||||
imageSrc: PropTypes.string,
|
imageSrc: PropTypes.string,
|
||||||
imageAltText: PropTypes.string,
|
imageAltText: PropTypes.string,
|
||||||
seriesDate: PropTypes.string,
|
seriesDate: PropTypes.string,
|
||||||
|
|||||||
@ -6,7 +6,7 @@ const studyWithSR = {
|
|||||||
modalities: 'CT,SR',
|
modalities: 'CT,SR',
|
||||||
displaySets: [
|
displaySets: [
|
||||||
{
|
{
|
||||||
displaySetInstanceUid: 'f69f6asdasd48c-223e-db7f-c4af-b8906641a66e',
|
displaySetInstanceUID: 'f69f6asdasd48c-223e-db7f-c4af-b8906641a66e',
|
||||||
description: 'Multiple line image series description lorem sit',
|
description: 'Multiple line image series description lorem sit',
|
||||||
seriesNumber: 1,
|
seriesNumber: 1,
|
||||||
numInstances: 68,
|
numInstances: 68,
|
||||||
@ -15,7 +15,7 @@ const studyWithSR = {
|
|||||||
isTracked: true,
|
isTracked: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displaySetInstanceUid: 'f69f648c-223e-db7f-c4asdasdaf-b8906641a66e',
|
displaySetInstanceUID: 'f69f648c-223e-db7f-c4asdasdaf-b8906641a66e',
|
||||||
description: 'Multiple line image series description lorem sit',
|
description: 'Multiple line image series description lorem sit',
|
||||||
seriesNumber: 1,
|
seriesNumber: 1,
|
||||||
numInstances: 68,
|
numInstances: 68,
|
||||||
@ -23,14 +23,14 @@ const studyWithSR = {
|
|||||||
viewportIdentificator: 'B',
|
viewportIdentificator: 'B',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displaySetInstanceUid: 'f69f648c-223e-dasdasdb7f-c4af-b8906641a66e',
|
displaySetInstanceUID: 'f69f648c-223e-dasdasdb7f-c4af-b8906641a66e',
|
||||||
description: 'Multiple line image series description lorem sit',
|
description: 'Multiple line image series description lorem sit',
|
||||||
seriesNumber: 1,
|
seriesNumber: 1,
|
||||||
numInstances: 68,
|
numInstances: 68,
|
||||||
componentType: 'thumbnailTracked',
|
componentType: 'thumbnailTracked',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displaySetInstanceUid: 'f69f648c-223e-db7f-c4afas-b8906asd641a66e',
|
displaySetInstanceUID: 'f69f648c-223e-db7f-c4afas-b8906asd641a66e',
|
||||||
description: 'Multiple line description lorem ipsum dolor sit amet',
|
description: 'Multiple line description lorem ipsum dolor sit amet',
|
||||||
modality: 'SR',
|
modality: 'SR',
|
||||||
componentType: 'thumbnailNoImage',
|
componentType: 'thumbnailNoImage',
|
||||||
@ -47,7 +47,7 @@ const studySimple = {
|
|||||||
modalities: 'CT',
|
modalities: 'CT',
|
||||||
displaySets: [
|
displaySets: [
|
||||||
{
|
{
|
||||||
displaySetInstanceUid: 'f69f648c-223e-db7f-c4af-b8906641a66e',
|
displaySetInstanceUID: 'f69f648c-223e-db7f-c4af-b8906641a66e',
|
||||||
description: 'Multiple line image series description lorem sit',
|
description: 'Multiple line image series description lorem sit',
|
||||||
seriesNumber: 1,
|
seriesNumber: 1,
|
||||||
numInstances: 68,
|
numInstances: 68,
|
||||||
|
|||||||
@ -8,7 +8,12 @@ import { ViewportGrid, ViewportPane } from '@ohif/ui';
|
|||||||
// import EmptyViewport from './EmptyViewport.js';
|
// import EmptyViewport from './EmptyViewport.js';
|
||||||
|
|
||||||
function ViewerViewportGrid(props) {
|
function ViewerViewportGrid(props) {
|
||||||
const { activeViewportIndex, displaySets, children } = props;
|
const {
|
||||||
|
activeViewportIndex,
|
||||||
|
viewportData,
|
||||||
|
viewportComponents,
|
||||||
|
dataSource,
|
||||||
|
} = props;
|
||||||
|
|
||||||
// From ViewportGridService and/or ContextProvider
|
// From ViewportGridService and/or ContextProvider
|
||||||
const [viewportGrid, setViewportGrid] = useState({
|
const [viewportGrid, setViewportGrid] = useState({
|
||||||
@ -35,8 +40,20 @@ function ViewerViewportGrid(props) {
|
|||||||
|
|
||||||
const getViewportPanes = () =>
|
const getViewportPanes = () =>
|
||||||
viewportGrid.viewports.map((viewport, viewportIndex) => {
|
viewportGrid.viewports.map((viewport, viewportIndex) => {
|
||||||
const someId = viewport.displaySetId;
|
const displaySet = viewportData[viewportIndex];
|
||||||
// const displaySet = displaySets[someId];
|
|
||||||
|
if (!displaySet) {
|
||||||
|
return (
|
||||||
|
<ViewportPane
|
||||||
|
key={viewportIndex}
|
||||||
|
className="m-1"
|
||||||
|
onDrop={() => {
|
||||||
|
/* setDisplaySet for Viewport */
|
||||||
|
}}
|
||||||
|
isActive={activeViewportIndex === viewportIndex}
|
||||||
|
></ViewportPane>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// if (!displaySet) {
|
// if (!displaySet) {
|
||||||
// // TODO: Empty Viewport
|
// // TODO: Empty Viewport
|
||||||
@ -48,14 +65,12 @@ function ViewerViewportGrid(props) {
|
|||||||
// ? displaySet.plugin
|
// ? displaySet.plugin
|
||||||
// : layout.plugin;
|
// : layout.plugin;
|
||||||
|
|
||||||
// const ViewportComponent = _getViewportComponent(
|
// TODO -> Need way for other viewport e.g. vtk to be used.
|
||||||
// data, // Why do we pass this as `ViewportData`, when that's not really what it is?
|
|
||||||
// viewportIndex,
|
|
||||||
// children,
|
|
||||||
|
|
||||||
// pluginName,
|
const ViewportComponent = _getViewportComponent(
|
||||||
// defaultPluginName
|
displaySet,
|
||||||
// );
|
viewportComponents
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ViewportPane
|
<ViewportPane
|
||||||
@ -66,13 +81,17 @@ function ViewerViewportGrid(props) {
|
|||||||
}}
|
}}
|
||||||
isActive={activeViewportIndex === viewportIndex}
|
isActive={activeViewportIndex === viewportIndex}
|
||||||
>
|
>
|
||||||
{/* {ViewportComponent} */}
|
<ViewportComponent
|
||||||
|
displaySet={displaySet}
|
||||||
|
viewportIndex={viewportIndex}
|
||||||
|
dataSource={dataSource}
|
||||||
|
/>
|
||||||
</ViewportPane>
|
</ViewportPane>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const ViewportPanes = React.useMemo(getViewportPanes, [
|
const ViewportPanes = React.useMemo(getViewportPanes, [
|
||||||
children,
|
viewportComponents,
|
||||||
activeViewportIndex,
|
activeViewportIndex,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -86,16 +105,30 @@ function ViewerViewportGrid(props) {
|
|||||||
ViewerViewportGrid.propTypes = {
|
ViewerViewportGrid.propTypes = {
|
||||||
// viewports: PropTypes.array.isRequired,
|
// viewports: PropTypes.array.isRequired,
|
||||||
activeViewportIndex: PropTypes.number.isRequired,
|
activeViewportIndex: PropTypes.number.isRequired,
|
||||||
children: PropTypes.node,
|
viewportComponents: PropTypes.array.isRequired,
|
||||||
// numRows: PropTypes.number.isRequired,
|
// numRows: PropTypes.number.isRequired,
|
||||||
// numColumns: PropTypes.number.isRequired,
|
// numColumns: PropTypes.number.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
ViewerViewportGrid.defaultProps = {
|
ViewerViewportGrid.defaultProps = {
|
||||||
// viewports: [],
|
|
||||||
// numRows: 1,
|
// numRows: 1,
|
||||||
// numColumns: 1,
|
// numColumns: 1,
|
||||||
|
viewportData: [],
|
||||||
|
viewportComponents: [],
|
||||||
activeViewportIndex: 0,
|
activeViewportIndex: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function _getViewportComponent(displaySet, viewportComponents) {
|
||||||
|
const { SOPClassHandlerId } = displaySet;
|
||||||
|
|
||||||
|
for (let i = 0; i < viewportComponents.length; i++) {
|
||||||
|
if (
|
||||||
|
viewportComponents[i].displaySetsToDisplay.includes(SOPClassHandlerId)
|
||||||
|
) {
|
||||||
|
const { component } = viewportComponents[i];
|
||||||
|
return component;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default ViewerViewportGrid;
|
export default ViewerViewportGrid;
|
||||||
|
|||||||
@ -17,7 +17,7 @@ export default function ModeRoute({
|
|||||||
const {
|
const {
|
||||||
toolBarLayout,
|
toolBarLayout,
|
||||||
setToolBarLayout,
|
setToolBarLayout,
|
||||||
displaySetInstanceUids,
|
displaySetInstanceUIDs,
|
||||||
setDisplaySetInstanceUids,
|
setDisplaySetInstanceUids,
|
||||||
} = useViewModel();
|
} = useViewModel();
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ export default function ModeRoute({
|
|||||||
const createDisplaySets = useCallback(() => {
|
const createDisplaySets = useCallback(() => {
|
||||||
// Add SOPClassHandlers to a new SOPClassManager.
|
// Add SOPClassHandlers to a new SOPClassManager.
|
||||||
displaySetManager.init(extensionManager, sopClassHandlers, {
|
displaySetManager.init(extensionManager, sopClassHandlers, {
|
||||||
displaySetInstanceUids,
|
displaySetInstanceUIDs,
|
||||||
setDisplaySetInstanceUids,
|
setDisplaySetInstanceUids,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ export default function ModeRoute({
|
|||||||
queryParams,
|
queryParams,
|
||||||
displaySetManager.makeDisplaySets
|
displaySetManager.makeDisplaySets
|
||||||
);
|
);
|
||||||
}, [displaySetInstanceUids, location]);
|
}, [displaySetInstanceUIDs, location]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
createDisplaySets();
|
createDisplaySets();
|
||||||
@ -84,6 +84,10 @@ export default function ModeRoute({
|
|||||||
const CombinedContextProvider = ({ children }) =>
|
const CombinedContextProvider = ({ children }) =>
|
||||||
Compose({ components: contextModuleProviders, children });
|
Compose({ components: contextModuleProviders, children });
|
||||||
|
|
||||||
|
function ViewportGridWithDataSource(props) {
|
||||||
|
return ViewportGrid({ ...props, dataSource });
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CombinedContextProvider>
|
<CombinedContextProvider>
|
||||||
{/* TODO: extensionManager is already provided to the extension module.
|
{/* TODO: extensionManager is already provided to the extension module.
|
||||||
@ -92,9 +96,9 @@ export default function ModeRoute({
|
|||||||
<DragAndDropProvider>
|
<DragAndDropProvider>
|
||||||
<LayoutComponent
|
<LayoutComponent
|
||||||
extensionManager={extensionManager}
|
extensionManager={extensionManager}
|
||||||
displaySetInstanceUids={displaySetInstanceUids}
|
displaySetInstanceUIDs={displaySetInstanceUIDs}
|
||||||
toolBarLayout={toolBarLayout}
|
toolBarLayout={toolBarLayout}
|
||||||
ViewportGrid={ViewportGrid}
|
ViewportGrid={ViewportGridWithDataSource}
|
||||||
{...layoutTemplateData.props}
|
{...layoutTemplateData.props}
|
||||||
/>
|
/>
|
||||||
</DragAndDropProvider>
|
</DragAndDropProvider>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user