Integrate Study Prefetcher and Study Loading Listener
This commit is contained in:
parent
8962f957d8
commit
3954c32441
16
OHIFViewer-react/.eslintrc
Normal file
16
OHIFViewer-react/.eslintrc
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"extends": [
|
||||||
|
"react-app",
|
||||||
|
"eslint:recommended",
|
||||||
|
"plugin:react/recommended"
|
||||||
|
],
|
||||||
|
"parser": "babel-eslint",
|
||||||
|
"env": {
|
||||||
|
"jest": true
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"react": {
|
||||||
|
"version": "detect",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
@ -13,12 +13,12 @@
|
|||||||
"hammerjs": "^2.0.8",
|
"hammerjs": "^2.0.8",
|
||||||
"lodash.debounce": "^4.0.8",
|
"lodash.debounce": "^4.0.8",
|
||||||
"moment": "^2.22.2",
|
"moment": "^2.22.2",
|
||||||
"ohif-core": "^0.1.3",
|
"ohif-core": "^0.1.4",
|
||||||
"oidc-client": "^1.6.1",
|
"oidc-client": "^1.6.1",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
"query-string": "^6.2.0",
|
"query-string": "^6.2.0",
|
||||||
"react": "^16.4.1",
|
"react": "^16.4.1",
|
||||||
"react-cornerstone-viewport": "^0.1.5",
|
"react-cornerstone-viewport": "^0.1.6",
|
||||||
"react-dom": "^16.4.1",
|
"react-dom": "^16.4.1",
|
||||||
"react-redux": "^6.0.0",
|
"react-redux": "^6.0.0",
|
||||||
"react-router": "^4.3.1",
|
"react-router": "^4.3.1",
|
||||||
|
|||||||
@ -4,13 +4,17 @@ import OHIF from 'ohif-core'
|
|||||||
|
|
||||||
const { setViewportActive } = OHIF.redux.actions;
|
const { setViewportActive } = OHIF.redux.actions;
|
||||||
|
|
||||||
const mapStateToProps = state => {
|
const mapStateToProps = (state, ownProps) => {
|
||||||
const activeButton = state.tools.buttons.find(tool => tool.active === true);
|
const activeButton = state.tools.buttons.find(tool => tool.active === true);
|
||||||
|
|
||||||
|
// If this is the active viewport, enable prefetching.
|
||||||
|
const enableStackPrefetch = ownProps.viewportData.viewportIndex === state.viewports.activeViewportIndex;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
layout: state.viewports.layout,
|
layout: state.viewports.layout,
|
||||||
activeViewportIndex: state.viewports.activeViewportIndex,
|
activeViewportIndex: state.viewports.activeViewportIndex,
|
||||||
activeTool: activeButton && activeButton.command
|
activeTool: activeButton && activeButton.command,
|
||||||
|
enableStackPrefetch
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,8 @@ import FlexboxLayout from './FlexboxLayout';
|
|||||||
const mapStateToProps = state => {
|
const mapStateToProps = state => {
|
||||||
return {
|
return {
|
||||||
leftSidebarOpen: state.ui.leftSidebarOpen,
|
leftSidebarOpen: state.ui.leftSidebarOpen,
|
||||||
rightSidebarOpen: state.ui.rightSidebarOpen
|
rightSidebarOpen: state.ui.rightSidebarOpen,
|
||||||
|
stackLoadingData: state.loading
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -63,23 +63,60 @@ const loadError = function(error, studyInstanceUid, displaySetInstanceUid) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class FlexboxLayout extends Component {
|
class FlexboxLayout extends Component {
|
||||||
constructor(props) {
|
static propTypes = {
|
||||||
super(props);
|
studies: PropTypes.array.isRequired,
|
||||||
|
leftSidebarOpen: PropTypes.bool.isRequired,
|
||||||
this.state = {
|
rightSidebarOpen: PropTypes.bool.isRequired,
|
||||||
studiesForBrowser: this.getStudiesForBrowser(),
|
stackLoadingData: PropTypes.object// { lastUpdated, progress }
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getStudiesForBrowser = this.getStudiesForBrowser.bind(this);
|
state = {
|
||||||
this.getThumbnailsFromImageIds = this.getThumbnailsFromImageIds.bind(this);
|
studiesForBrowser: []
|
||||||
}
|
};
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.getThumbnailsFromImageIds();
|
const studiesForBrowser = this.getStudiesForBrowser();
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
studiesForBrowser
|
||||||
|
});
|
||||||
|
|
||||||
|
this.getThumbnailsFromImageIds(studiesForBrowser);
|
||||||
}
|
}
|
||||||
|
|
||||||
getThumbnailsFromImageIds() {
|
componentDidUpdate(prevProps) {
|
||||||
this.state.studiesForBrowser.forEach(function (study) {
|
const { stackLoadingData } = this.props;
|
||||||
|
|
||||||
|
// If we know that the stack loading progress details have changed,
|
||||||
|
// we can try to update the component state so that the thumbnail
|
||||||
|
// progress bar is updated
|
||||||
|
if (stackLoadingData.lastUpdated !== prevProps.stackLoadingData.lastUpdated) {
|
||||||
|
const stackLoadingProgressMap = stackLoadingData.progress;
|
||||||
|
const studiesForBrowser = this.state.studiesForBrowser;
|
||||||
|
|
||||||
|
studiesForBrowser.forEach(study => {
|
||||||
|
study.thumbnails.forEach(data => {
|
||||||
|
const { displaySetInstanceUid } = data
|
||||||
|
const stackId = `StackProgress:${displaySetInstanceUid}`;
|
||||||
|
const stackProgressData = stackLoadingProgressMap[stackId];
|
||||||
|
|
||||||
|
let stackPercentComplete = 0;
|
||||||
|
if (stackProgressData) {
|
||||||
|
stackPercentComplete = stackProgressData.percentComplete;
|
||||||
|
}
|
||||||
|
|
||||||
|
data.stackPercentComplete = stackPercentComplete;
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
studiesForBrowser
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getThumbnailsFromImageIds = (studiesForBrowser) => {
|
||||||
|
studiesForBrowser.forEach(function (study) {
|
||||||
const { studyInstanceUid } = study;
|
const { studyInstanceUid } = study;
|
||||||
|
|
||||||
study.thumbnails.forEach(function (displaySet) {
|
study.thumbnails.forEach(function (displaySet) {
|
||||||
@ -96,8 +133,9 @@ class FlexboxLayout extends Component {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getStudiesForBrowser() {
|
getStudiesForBrowser = () => {
|
||||||
const { studies } = this.props;
|
const { studies, stackLoadingData } = this.props;
|
||||||
|
const stackLoadingProgressMap = stackLoadingData.progress;
|
||||||
|
|
||||||
// TODO[react]:
|
// TODO[react]:
|
||||||
// - Add sorting of display sets
|
// - Add sorting of display sets
|
||||||
@ -109,10 +147,18 @@ class FlexboxLayout extends Component {
|
|||||||
const { studyInstanceUid } = study;
|
const { studyInstanceUid } = study;
|
||||||
|
|
||||||
const thumbnails = study.displaySets.map((displaySet) => {
|
const thumbnails = study.displaySets.map((displaySet) => {
|
||||||
const active = false;
|
|
||||||
const stackPercentComplete = 0;
|
|
||||||
const { displaySetInstanceUid, seriesDescription, seriesNumber, instanceNumber, numImageFrames } = displaySet;
|
const { displaySetInstanceUid, seriesDescription, seriesNumber, instanceNumber, numImageFrames } = displaySet;
|
||||||
|
const active = false;
|
||||||
|
const stackId = `StackProgress:${displaySetInstanceUid}`;
|
||||||
|
const stackProgressData = stackLoadingProgressMap[stackId];
|
||||||
|
|
||||||
|
let stackPercentComplete = 0;
|
||||||
|
if (stackProgressData) {
|
||||||
|
stackPercentComplete = stackProgressData.percentComplete;
|
||||||
|
}
|
||||||
|
|
||||||
const imageId = displaySet.images[0].getImageId();
|
const imageId = displaySet.images[0].getImageId();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
imageSrc: '',
|
imageSrc: '',
|
||||||
imageId,
|
imageId,
|
||||||
@ -160,10 +206,4 @@ class FlexboxLayout extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FlexboxLayout.propTypes = {
|
|
||||||
studies: PropTypes.array.isRequired,
|
|
||||||
leftSidebarOpen: PropTypes.bool.isRequired,
|
|
||||||
rightSidebarOpen: PropTypes.bool.isRequired,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default FlexboxLayout;
|
export default FlexboxLayout;
|
||||||
|
|||||||
@ -7,16 +7,13 @@ import cornerstoneMath from "cornerstone-math";
|
|||||||
import { OHIF } from 'ohif-core';
|
import { OHIF } from 'ohif-core';
|
||||||
import ConnectedCornerstoneViewport from './ConnectedCornerstoneViewport.js';
|
import ConnectedCornerstoneViewport from './ConnectedCornerstoneViewport.js';
|
||||||
import ConnectedLayoutManager from './ConnectedLayoutManager.js';
|
import ConnectedLayoutManager from './ConnectedLayoutManager.js';
|
||||||
import StackManager from '../lib/StackManager.js';
|
|
||||||
import './ViewerMain.css';
|
import './ViewerMain.css';
|
||||||
|
|
||||||
// Attempt to fix weird undefined dep issue
|
// Attempt to fix weird undefined dep issue
|
||||||
cornerstoneTools.external.cornerstoneMath = cornerstoneMath;
|
cornerstoneTools.external.cornerstoneMath = cornerstoneMath;
|
||||||
|
|
||||||
//const { StudyLoadingListener, StudyPrefetcher, ResizeViewportManager } = OHIF.classes;
|
const { StudyLoadingListener, StudyPrefetcher } = OHIF.classes;
|
||||||
|
const { StackManager } = OHIF.utils;
|
||||||
|
|
||||||
//window.ResizeViewportManager = window.ResizeViewportManager || new ResizeViewportManager();
|
|
||||||
|
|
||||||
function getCornerstoneStack(studies, viewportData) {
|
function getCornerstoneStack(studies, viewportData) {
|
||||||
const {
|
const {
|
||||||
@ -36,35 +33,21 @@ function getCornerstoneStack(studies, viewportData) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ViewerMain extends Component {
|
class ViewerMain extends Component {
|
||||||
constructor(props) {
|
state = {
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
displaySets: [],
|
displaySets: [],
|
||||||
viewportData: [],
|
viewportData: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getCornerstoneViewport = this.getCornerstoneViewport.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
// Attach the Window resize listener
|
|
||||||
// Don't use jQuery here. "window.onresize" will always be null
|
|
||||||
// If its necessary, check all the code for window.onresize getter
|
|
||||||
// and change it to jQuery._data(window, 'events')['resize'].
|
|
||||||
// Otherwise this function will be probably overrided.
|
|
||||||
// See cineDialog instance.setResizeHandler function
|
|
||||||
//window.addEventListener('resize', window.ResizeViewportManager.getResizeHandler());
|
|
||||||
|
|
||||||
// Add beforeUnload event handler to check for unsaved changes
|
// Add beforeUnload event handler to check for unsaved changes
|
||||||
//window.addEventListener('beforeunload', unloadHandlers.beforeUnload);
|
//window.addEventListener('beforeunload', unloadHandlers.beforeUnload);
|
||||||
|
|
||||||
const { studies } = this.props;
|
const { studies } = this.props;
|
||||||
//this.studyPrefetcher = StudyPrefetcher.getInstance();
|
this.studyPrefetcher = StudyPrefetcher.getInstance(cornerstone, cornerstoneTools);
|
||||||
//this.studyPrefetcher.setStudies(studies);
|
this.studyPrefetcher.setStudies(studies);
|
||||||
//this.studyLoadingListener = StudyLoadingListener.getInstance();
|
this.studyLoadingListener = StudyLoadingListener.getInstance(cornerstone);
|
||||||
//this.studyLoadingListener.clear();
|
this.studyLoadingListener.clear();
|
||||||
//this.studyLoadingListener.addStudies(studies);
|
this.studyLoadingListener.addStudies(studies);
|
||||||
|
|
||||||
// Get all the display sets for the viewer studies
|
// Get all the display sets for the viewer studies
|
||||||
const displaySets = [];
|
const displaySets = [];
|
||||||
@ -84,7 +67,7 @@ class ViewerMain extends Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getCornerstoneViewport(data, index) {
|
getCornerstoneViewport = (data, index) => {
|
||||||
// Clone the stack here so we don't mutate it later
|
// Clone the stack here so we don't mutate it later
|
||||||
const stack = Object.assign({}, getCornerstoneStack(this.props.studies, data));
|
const stack = Object.assign({}, getCornerstoneStack(this.props.studies, data));
|
||||||
stack.currentImageIdIndex = 0;
|
stack.currentImageIdIndex = 0;
|
||||||
@ -130,9 +113,6 @@ class ViewerMain extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
// Remove the Window resize listener
|
|
||||||
//window.removeEventListener('resize', window.ResizeViewportManager.getResizeHandler());
|
|
||||||
|
|
||||||
// Remove beforeUnload event handler...
|
// Remove beforeUnload event handler...
|
||||||
//window.removeEventListener('beforeunload', unloadHandlers.beforeUnload);
|
//window.removeEventListener('beforeunload', unloadHandlers.beforeUnload);
|
||||||
|
|
||||||
@ -140,13 +120,13 @@ class ViewerMain extends Component {
|
|||||||
OHIF.viewer.updateImageSynchronizer.destroy();
|
OHIF.viewer.updateImageSynchronizer.destroy();
|
||||||
|
|
||||||
// Stop prefetching when we close the viewer
|
// Stop prefetching when we close the viewer
|
||||||
//this.studyPrefetcher.destroy();
|
this.studyPrefetcher.destroy();
|
||||||
|
|
||||||
// Destroy stack loading listeners when we close the viewer
|
// Destroy stack loading listeners when we close the viewer
|
||||||
//this.studyLoadingListener.clear();
|
this.studyLoadingListener.clear();
|
||||||
|
|
||||||
// Clear references to all stacks in the StackManager
|
// Clear references to all stacks in the StackManager
|
||||||
//OHIF.viewerbase.stackManager.clearStacks();
|
StackManager.clearStacks();
|
||||||
|
|
||||||
// @TypeSafeStudies
|
// @TypeSafeStudies
|
||||||
// Clears OHIF.viewer.Studies collection
|
// Clears OHIF.viewer.Studies collection
|
||||||
|
|||||||
@ -3,7 +3,8 @@ import PropTypes from "prop-types";
|
|||||||
import qs from 'query-string'
|
import qs from 'query-string'
|
||||||
import Viewer from "./Viewer/Viewer";
|
import Viewer from "./Viewer/Viewer";
|
||||||
import OHIF from 'ohif-core';
|
import OHIF from 'ohif-core';
|
||||||
import createDisplaySets from "./lib/createDisplaySets";
|
|
||||||
|
const { createDisplaySets } = OHIF.utils;
|
||||||
|
|
||||||
function parseQueryAndFetchStudies(query) {
|
function parseQueryAndFetchStudies(query) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|||||||
@ -10,6 +10,8 @@ import ConnectedFlexboxLayout from '../FlexboxLayout/ConnectedFlexboxLayout.js';
|
|||||||
import ConnectedToolbarRow from "../FlexboxLayout/ConnectedToolbarRow";
|
import ConnectedToolbarRow from "../FlexboxLayout/ConnectedToolbarRow";
|
||||||
import './Viewer.css';
|
import './Viewer.css';
|
||||||
|
|
||||||
|
const { StackManager } = OHIF.utils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inits OHIF Hanging Protocol's onReady.
|
* Inits OHIF Hanging Protocol's onReady.
|
||||||
* It waits for OHIF Hanging Protocol to be ready to instantiate the ProtocolEngine
|
* It waits for OHIF Hanging Protocol to be ready to instantiate the ProtocolEngine
|
||||||
@ -65,13 +67,17 @@ OHIF.viewer.functionList = {
|
|||||||
// Create the synchronizer used to update reference lines
|
// Create the synchronizer used to update reference lines
|
||||||
OHIF.viewer.updateImageSynchronizer = new cornerstoneTools.Synchronizer('cornerstonenewimage', cornerstoneTools.updateImageSynchronizer);
|
OHIF.viewer.updateImageSynchronizer = new cornerstoneTools.Synchronizer('cornerstonenewimage', cornerstoneTools.updateImageSynchronizer);
|
||||||
|
|
||||||
OHIF.viewer.metadataProvider = new OHIF.cornerstone.MetadataProvider();
|
|
||||||
|
|
||||||
// Metadata configuration
|
// Metadata configuration
|
||||||
const metadataProvider = OHIF.viewer.metadataProvider;
|
const metadataProvider = new OHIF.cornerstone.MetadataProvider();
|
||||||
cornerstone.metaData.addProvider(metadataProvider.provider.bind(metadataProvider));
|
cornerstone.metaData.addProvider(metadataProvider.provider.bind(metadataProvider));
|
||||||
|
|
||||||
|
StackManager.setMetadataProvider(metadataProvider);
|
||||||
|
|
||||||
class Viewer extends Component {
|
class Viewer extends Component {
|
||||||
|
static propTypes = {
|
||||||
|
studies: PropTypes.array
|
||||||
|
};
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
@ -97,8 +103,5 @@ class Viewer extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Viewer.propTypes = {
|
|
||||||
studies: PropTypes.array
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Viewer;
|
export default Viewer;
|
||||||
|
|||||||
@ -2,7 +2,8 @@ import React, {Component} from "react";
|
|||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
import OHIF from 'ohif-core';
|
import OHIF from 'ohif-core';
|
||||||
import Viewer from "./Viewer/Viewer.js";
|
import Viewer from "./Viewer/Viewer.js";
|
||||||
import createDisplaySets from './lib/createDisplaySets.js';
|
|
||||||
|
const { createDisplaySets } = OHIF.utils;
|
||||||
|
|
||||||
class ViewerFromStudyData extends Component {
|
class ViewerFromStudyData extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
|||||||
@ -9,8 +9,6 @@ import sha from './sha.js';
|
|||||||
import version from './version.js';
|
import version from './version.js';
|
||||||
import { homepage } from '../package.json';
|
import { homepage } from '../package.json';
|
||||||
|
|
||||||
console.warn('cornerstoneMath');
|
|
||||||
console.warn(cornerstoneMath)
|
|
||||||
window.info = {
|
window.info = {
|
||||||
sha,
|
sha,
|
||||||
version,
|
version,
|
||||||
@ -20,6 +18,7 @@ window.info = {
|
|||||||
// For debugging
|
// For debugging
|
||||||
window.cornerstone = cornerstone;
|
window.cornerstone = cornerstone;
|
||||||
window.cornerstoneTools = cornerstoneTools;
|
window.cornerstoneTools = cornerstoneTools;
|
||||||
|
window.cornerstoneWADOImageLoader = cornerstoneWADOImageLoader;
|
||||||
|
|
||||||
cornerstoneTools.external.cornerstone = cornerstone;
|
cornerstoneTools.external.cornerstone = cornerstone;
|
||||||
cornerstoneTools.external.Hammer = Hammer;
|
cornerstoneTools.external.Hammer = Hammer;
|
||||||
@ -29,6 +28,10 @@ cornerstoneTools.init();
|
|||||||
cornerstoneWADOImageLoader.external.cornerstone = cornerstone;
|
cornerstoneWADOImageLoader.external.cornerstone = cornerstone;
|
||||||
cornerstoneWADOImageLoader.external.dicomParser = dicomParser;
|
cornerstoneWADOImageLoader.external.dicomParser = dicomParser;
|
||||||
|
|
||||||
|
OHIF.external.cornerstone = cornerstone;
|
||||||
|
OHIF.external.cornerstoneTools = cornerstoneTools;
|
||||||
|
OHIF.external.cornerstoneWADOImageLoader = cornerstoneWADOImageLoader;
|
||||||
|
|
||||||
// TODO: Is there a better way to guess ROOT_URL?
|
// TODO: Is there a better way to guess ROOT_URL?
|
||||||
let ROOT_URL = homepage;
|
let ROOT_URL = homepage;
|
||||||
|
|
||||||
|
|||||||
@ -99,12 +99,12 @@ const servers = {
|
|||||||
//"wadoUriRoot": "http://localhost:8080/dcm4chee-arc/aets/DCM4CHEE/wado",
|
//"wadoUriRoot": "http://localhost:8080/dcm4chee-arc/aets/DCM4CHEE/wado",
|
||||||
//"qidoRoot": "http://localhost:8080/dcm4chee-arc/aets/DCM4CHEE/rs",
|
//"qidoRoot": "http://localhost:8080/dcm4chee-arc/aets/DCM4CHEE/rs",
|
||||||
//"wadoRoot": "http://localhost:8080/dcm4chee-arc/aets/DCM4CHEE/rs",
|
//"wadoRoot": "http://localhost:8080/dcm4chee-arc/aets/DCM4CHEE/rs",
|
||||||
"wadoUriRoot": "https://dcm4che.ohif.club/dcm4chee-arc/aets/DCM4CHEE/wado",
|
//"wadoUriRoot": "https://dcm4che.ohif.club/dcm4chee-arc/aets/DCM4CHEE/wado",
|
||||||
"qidoRoot": "https://dcm4che.ohif.club/dcm4chee-arc/aets/DCM4CHEE/rs",
|
//"qidoRoot": "https://dcm4che.ohif.club/dcm4chee-arc/aets/DCM4CHEE/rs",
|
||||||
"wadoRoot": "https://dcm4che.ohif.club/dcm4chee-arc/aets/DCM4CHEE/rs",
|
//"wadoRoot": "https://dcm4che.ohif.club/dcm4chee-arc/aets/DCM4CHEE/rs",
|
||||||
//"wadoUriRoot": "https://cancer.crowds-cure.org/dcm4chee-arc/aets/DCM4CHEE/wado",
|
"wadoUriRoot": "https://cancer.crowds-cure.org/dcm4chee-arc/aets/DCM4CHEE/wado",
|
||||||
//"qidoRoot": "https://cancer.crowds-cure.org/dcm4chee-arc/aets/DCM4CHEE/rs",
|
"qidoRoot": "https://cancer.crowds-cure.org/dcm4chee-arc/aets/DCM4CHEE/rs",
|
||||||
//"wadoRoot": "https://cancer.crowds-cure.org/dcm4chee-arc/aets/DCM4CHEE/rs",
|
"wadoRoot": "https://cancer.crowds-cure.org/dcm4chee-arc/aets/DCM4CHEE/rs",
|
||||||
"qidoSupportsIncludeField": true,
|
"qidoSupportsIncludeField": true,
|
||||||
"imageRendering": "wadors",
|
"imageRendering": "wadors",
|
||||||
"thumbnailRendering": "wadors",
|
"thumbnailRendering": "wadors",
|
||||||
@ -114,7 +114,7 @@ const servers = {
|
|||||||
"logResponses": false,
|
"logResponses": false,
|
||||||
"logTiming": true,
|
"logTiming": true,
|
||||||
//"auth": "admin:admin"
|
//"auth": "admin:admin"
|
||||||
"auth": "cloud:healthcare"
|
//"auth": "cloud:healthcare"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@ -1,151 +0,0 @@
|
|||||||
import OHIF from 'ohif-core';
|
|
||||||
import { getImageId } from './getImageId';
|
|
||||||
|
|
||||||
let stackMap = {};
|
|
||||||
let configuration = {};
|
|
||||||
const stackUpdatedCallbacks = [];
|
|
||||||
|
|
||||||
const { OHIFError } = OHIF.classes;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loop through the current series and add metadata to the
|
|
||||||
* Cornerstone meta data provider. This will be used to fill information
|
|
||||||
* into the viewport overlays, and to calculate reference lines and orientation markers
|
|
||||||
* @param {Object} stackMap stackMap object
|
|
||||||
* @param {Object} study Study object
|
|
||||||
* @param {Object} displaySet The set of images to make the stack from
|
|
||||||
* @return {Array} Array with image IDs
|
|
||||||
*/
|
|
||||||
function createAndAddStack(stackMap, study, displaySet) {
|
|
||||||
const metadataProvider = OHIF.viewer.metadataProvider;
|
|
||||||
const numImages = displaySet.images.length;
|
|
||||||
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 numberOfFrames = image.numberOfFrames;
|
|
||||||
if (numberOfFrames > 1) {
|
|
||||||
OHIF.log.info('Multiframe image detected');
|
|
||||||
for (let i = 0; i < numberOfFrames; i++) {
|
|
||||||
metaData.frameNumber = i;
|
|
||||||
imageId = getImageId(image, i);
|
|
||||||
imageIds.push(imageId);
|
|
||||||
metadataProvider.addMetadata(imageId, metaData);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
metaData.frameNumber = 1;
|
|
||||||
imageId = getImageId(image);
|
|
||||||
imageIds.push(imageId);
|
|
||||||
metadataProvider.addMetadata(imageId, metaData);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const stack = {
|
|
||||||
displaySetInstanceUid: displaySet.displaySetInstanceUid,
|
|
||||||
imageIds,
|
|
||||||
frameRate: displaySet.frameRate,
|
|
||||||
isClip: displaySet.isClip
|
|
||||||
};
|
|
||||||
|
|
||||||
stackMap[displaySet.displaySetInstanceUid] = stack;
|
|
||||||
|
|
||||||
return stack;
|
|
||||||
}
|
|
||||||
|
|
||||||
configuration = {
|
|
||||||
createAndAddStack
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This object contains all the functions needed for interacting with the stack manager.
|
|
||||||
* Generally, findStack is the only function used. If you want to know when new stacks
|
|
||||||
* come in, you can register a callback with addStackUpdatedCallback.
|
|
||||||
*/
|
|
||||||
const StackManager = {
|
|
||||||
/**
|
|
||||||
* Removes all current stacks
|
|
||||||
*/
|
|
||||||
clearStacks() {
|
|
||||||
stackMap = {};
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
* @return {Array} Array with image IDs
|
|
||||||
*/
|
|
||||||
makeAndAddStack(study, displaySet) {
|
|
||||||
return configuration.createAndAddStack(stackMap, study, displaySet, stackUpdatedCallbacks);
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Find a stack from the currently created stacks.
|
|
||||||
* @param displaySetInstanceUid The UID of the stack to find.
|
|
||||||
* @returns {*} undefined if not found, otherwise the stack object is returned.
|
|
||||||
*/
|
|
||||||
findStack(displaySetInstanceUid) {
|
|
||||||
return stackMap[displaySetInstanceUid];
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
* @return {Array} Array with image IDs
|
|
||||||
*/
|
|
||||||
findOrCreateStack(study, displaySet) {
|
|
||||||
let stack = this.findStack(displaySet.displaySetInstanceUid);
|
|
||||||
|
|
||||||
if (!stack || !stack.imageIds) {
|
|
||||||
stack = this.makeAndAddStack(study, displaySet);
|
|
||||||
}
|
|
||||||
|
|
||||||
return stack;
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Gets the underlying map of displaySetInstanceUid to stack object.
|
|
||||||
* WARNING: Do not change this object. It directly affects the manager.
|
|
||||||
* @returns {{}} map of displaySetInstanceUid -> stack.
|
|
||||||
*/
|
|
||||||
getAllStacks() {
|
|
||||||
return stackMap;
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Adds in a callback to be called on a stack being added / updated.
|
|
||||||
* @param callback must accept at minimum one argument,
|
|
||||||
* which is the stack that was added / updated.
|
|
||||||
*/
|
|
||||||
addStackUpdatedCallback(callback) {
|
|
||||||
if (typeof callback !== 'function') {
|
|
||||||
throw new OHIFError('callback must be provided as a function');
|
|
||||||
}
|
|
||||||
stackUpdatedCallbacks.push(callback);
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Return configuration
|
|
||||||
*/
|
|
||||||
getConfiguration() {
|
|
||||||
return configuration;
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Set configuration, in order to provide compatibility
|
|
||||||
* with other systems by overriding this functions
|
|
||||||
* @param {Object} config object with functions to be overrided
|
|
||||||
*
|
|
||||||
* For now, only makeAndAddStack can be overrided
|
|
||||||
*/
|
|
||||||
setConfiguration(config) {
|
|
||||||
configuration = config;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export { StackManager };
|
|
||||||
export default StackManager;
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
import OHIF from 'ohif-core';
|
|
||||||
import { sortingManager } from './sortingManager.js';
|
|
||||||
import { updateMetaDataManager } from './updateMetaDataManager.js';
|
|
||||||
|
|
||||||
// TODO: Move to react-viewerbase
|
|
||||||
export default function createDisplaySets(studies) {
|
|
||||||
// Define the OHIF.viewer.data global object
|
|
||||||
// TODO: Save all data that is currently in OHIF.viewer in redux instead
|
|
||||||
//OHIF.viewer.data = OHIF.viewer.data || {};
|
|
||||||
|
|
||||||
// @TypeSafeStudies
|
|
||||||
// Clears OHIF.viewer.Studies collection
|
|
||||||
//OHIF.viewer.Studies.removeAll();
|
|
||||||
|
|
||||||
// @TypeSafeStudies
|
|
||||||
// Clears OHIF.viewer.StudyMetadataList collection
|
|
||||||
//OHIF.viewer.StudyMetadataList.removeAll();
|
|
||||||
|
|
||||||
//OHIF.viewer.data.studyInstanceUids = [];
|
|
||||||
|
|
||||||
const updatedStudies = studies.map(study => {
|
|
||||||
const studyMetadata = new OHIF.metadata.OHIFStudyMetadata(study, study.studyInstanceUid);
|
|
||||||
let displaySets = study.displaySets;
|
|
||||||
|
|
||||||
if (!study.displaySets) {
|
|
||||||
displaySets = sortingManager.getDisplaySets(studyMetadata);
|
|
||||||
study.displaySets = displaySets;
|
|
||||||
}
|
|
||||||
|
|
||||||
studyMetadata.setDisplaySets(displaySets);
|
|
||||||
|
|
||||||
study.selected = true;
|
|
||||||
//OHIF.viewer.Studies.insert(study);
|
|
||||||
//OHIF.viewer.StudyMetadataList.insert(studyMetadata);
|
|
||||||
//OHIF.viewer.data.studyInstanceUids.push(study.studyInstanceUid);
|
|
||||||
|
|
||||||
// Updates WADO-RS metaDataManager
|
|
||||||
updateMetaDataManager(study);
|
|
||||||
|
|
||||||
return study;
|
|
||||||
});
|
|
||||||
|
|
||||||
return updatedStudies;
|
|
||||||
}
|
|
||||||
@ -1,128 +0,0 @@
|
|||||||
import OHIF from 'ohif-core';
|
|
||||||
import { isImage } from './isImage';
|
|
||||||
|
|
||||||
const { ImageSet } = OHIF.classes;
|
|
||||||
|
|
||||||
const isMultiFrame = instance => {
|
|
||||||
// NumberOfFrames (0028,0008)
|
|
||||||
return instance.getRawValue('x00280008') > 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
const makeDisplaySet = (series, instances) => {
|
|
||||||
const instance = instances[0];
|
|
||||||
|
|
||||||
const imageSet = new ImageSet(instances);
|
|
||||||
const seriesData = series.getData();
|
|
||||||
|
|
||||||
// set appropriate attributes to image set...
|
|
||||||
imageSet.setAttributes({
|
|
||||||
displaySetInstanceUid: imageSet.uid, // create a local alias for the imageSet UID
|
|
||||||
seriesDate: seriesData.seriesDate,
|
|
||||||
seriesTime: seriesData.seriesTime,
|
|
||||||
seriesInstanceUid: series.getSeriesInstanceUID(),
|
|
||||||
seriesNumber: instance.getRawValue('x00200011'),
|
|
||||||
seriesDescription: instance.getRawValue('x0008103e'),
|
|
||||||
numImageFrames: instances.length,
|
|
||||||
frameRate: instance.getRawValue('x00181063'),
|
|
||||||
modality: instance.getRawValue('x00080060'),
|
|
||||||
isMultiFrame: isMultiFrame(instance)
|
|
||||||
});
|
|
||||||
|
|
||||||
// Sort the images in this series if needed
|
|
||||||
const shallSort = true//!OHIF.utils.ObjectPath.get(Meteor, 'settings.public.ui.sortSeriesByIncomingOrder');
|
|
||||||
if (shallSort) {
|
|
||||||
imageSet.sortBy((a, b) => {
|
|
||||||
// Sort by InstanceNumber (0020,0013)
|
|
||||||
return (parseInt(a.getRawValue('x00200013', 0)) || 0) - (parseInt(b.getRawValue('x00200013', 0)) || 0);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Include the first image instance number (after sorted)
|
|
||||||
imageSet.setAttribute('instanceNumber', imageSet.getImage(0).getRawValue('x00200013'));
|
|
||||||
|
|
||||||
return imageSet;
|
|
||||||
};
|
|
||||||
|
|
||||||
const isSingleImageModality = modality => {
|
|
||||||
return (modality === 'CR' ||
|
|
||||||
modality === 'MG' ||
|
|
||||||
modality === 'DX');
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a set of series to be placed in the Study Metadata
|
|
||||||
* The series that appear in the Study Metadata must represent
|
|
||||||
* imaging modalities.
|
|
||||||
*
|
|
||||||
* Furthermore, for drag/drop functionality,
|
|
||||||
* it is easiest if the stack objects also contain information about
|
|
||||||
* which study they are linked to.
|
|
||||||
*
|
|
||||||
* @param study The study instance metadata to be used
|
|
||||||
* @returns {Array} An array of series to be placed in the Study Metadata
|
|
||||||
*/
|
|
||||||
const createStacks = study => {
|
|
||||||
// Define an empty array of display sets
|
|
||||||
const displaySets = [];
|
|
||||||
|
|
||||||
if (!study || !study.getSeriesCount()) {
|
|
||||||
return displaySets;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loop through the series (SeriesMetadata)
|
|
||||||
study.forEachSeries(series => {
|
|
||||||
// If the series has no instances, skip it
|
|
||||||
if (!series.getInstanceCount()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Search through the instances (InstanceMedatada object) of this series
|
|
||||||
// Split Multi-frame instances and Single-image modalities
|
|
||||||
// into their own specific display sets. Place the rest of each
|
|
||||||
// series into another display set.
|
|
||||||
const stackableInstances = [];
|
|
||||||
series.forEachInstance(instance => {
|
|
||||||
// All imaging modalities must have a valid value for sopClassUid (x00080016) or rows (x00280010)
|
|
||||||
if (!isImage(instance.getRawValue('x00080016')) && !instance.getRawValue('x00280010')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let displaySet;
|
|
||||||
if (isMultiFrame(instance)) {
|
|
||||||
displaySet = makeDisplaySet(series, [ instance ]);
|
|
||||||
displaySet.setAttributes({
|
|
||||||
isClip: true,
|
|
||||||
studyInstanceUid: study.getStudyInstanceUID(), // Include the study instance Uid for drag/drop purposes
|
|
||||||
numImageFrames: instance.getRawValue('x00280008'), // Override the default value of instances.length
|
|
||||||
instanceNumber: instance.getRawValue('x00200013'), // Include the instance number
|
|
||||||
acquisitionDatetime: instance.getRawValue('x0008002a') // Include the acquisition datetime
|
|
||||||
});
|
|
||||||
displaySets.push(displaySet);
|
|
||||||
} else if (isSingleImageModality(instance.modality)) {
|
|
||||||
displaySet = makeDisplaySet(series, [ instance ]);
|
|
||||||
displaySet.setAttributes({
|
|
||||||
studyInstanceUid: study.getStudyInstanceUID(), // Include the study instance Uid
|
|
||||||
instanceNumber: instance.getRawValue('x00200013'), // Include the instance number
|
|
||||||
acquisitionDatetime: instance.getRawValue('x0008002a') // Include the acquisition datetime
|
|
||||||
});
|
|
||||||
displaySets.push(displaySet);
|
|
||||||
} else {
|
|
||||||
stackableInstances.push(instance);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (stackableInstances.length) {
|
|
||||||
const displaySet = makeDisplaySet(series, stackableInstances);
|
|
||||||
displaySet.setAttribute('studyInstanceUid', study.getStudyInstanceUID());
|
|
||||||
displaySets.push(displaySet);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return displaySets;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Expose "createStacks"...
|
|
||||||
*/
|
|
||||||
|
|
||||||
export { createStacks };
|
|
||||||
@ -1,51 +0,0 @@
|
|||||||
import { getWADORSImageId } from './getWADORSImageId';
|
|
||||||
|
|
||||||
// https://stackoverflow.com/a/6021027/3895126
|
|
||||||
function updateQueryStringParameter(uri, key, value) {
|
|
||||||
const regex = new RegExp('([?&])' + key + '=.*?(&|$)', 'i');
|
|
||||||
const separator = uri.indexOf('?') !== -1 ? '&' : '?';
|
|
||||||
if (uri.match(regex)) {
|
|
||||||
return uri.replace(regex, '$1' + key + '=' + value + '$2');
|
|
||||||
} else {
|
|
||||||
return uri + separator + key + '=' + value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Obtain an imageId for Cornerstone from an image instance
|
|
||||||
*
|
|
||||||
* @param instance
|
|
||||||
* @param frame
|
|
||||||
* @param thumbnail
|
|
||||||
* @returns {string} The imageId to be used by Cornerstone
|
|
||||||
*/
|
|
||||||
export function getImageId(instance, frame, thumbnail=false) {
|
|
||||||
if (!instance) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof instance.getImageId === 'function') {
|
|
||||||
return instance.getImageId();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (instance.url) {
|
|
||||||
if (frame !== undefined) {
|
|
||||||
instance.url = updateQueryStringParameter(instance.url, 'frame', frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
return instance.url;
|
|
||||||
}
|
|
||||||
|
|
||||||
const renderingAttr = thumbnail ? 'thumbnailRendering' : 'imageRendering';
|
|
||||||
|
|
||||||
if (!instance[renderingAttr] || instance[renderingAttr] === 'wadouri' || !instance.wadorsuri) {
|
|
||||||
let imageId = 'dicomweb:' + instance.wadouri;
|
|
||||||
if (frame !== undefined) {
|
|
||||||
imageId += '&frame=' + frame;
|
|
||||||
}
|
|
||||||
|
|
||||||
return imageId;
|
|
||||||
} else {
|
|
||||||
return getWADORSImageId(instance, frame, thumbnail); // WADO-RS Retrieve Frame
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
function getWADORSImageUrl(instance, frame) {
|
|
||||||
let wadorsuri = instance.wadorsuri;
|
|
||||||
|
|
||||||
if (!wadorsuri) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We need to sum 1 because WADO-RS frame number is 1-based
|
|
||||||
frame = (frame || 0) + 1;
|
|
||||||
|
|
||||||
// Replaces /frame/1 by /frame/{frame}
|
|
||||||
wadorsuri = wadorsuri.replace(/(%2Fframes%2F)(\d+)/, `$1${frame}`);
|
|
||||||
|
|
||||||
return wadorsuri;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Obtain an imageId for Cornerstone based on the WADO-RS scheme
|
|
||||||
*
|
|
||||||
* @param {object} instanceMetada metadata object (InstanceMetadata)
|
|
||||||
* @returns {string} The imageId to be used by Cornerstone
|
|
||||||
*/
|
|
||||||
export function getWADORSImageId(instance, frame) {
|
|
||||||
const uri = getWADORSImageUrl(instance, frame);
|
|
||||||
|
|
||||||
if (!uri) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return `wadors:${uri}`;
|
|
||||||
}
|
|
||||||
@ -1,61 +0,0 @@
|
|||||||
import { sopClassDictionary } from './sopClassDictionary';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether dicom files with specified SOP Class UID have image data
|
|
||||||
* @param {string} sopClassUid - SOP Class UID to be checked
|
|
||||||
* @returns {boolean} - true if it has image data
|
|
||||||
*/
|
|
||||||
export function isImage(sopClassUid) {
|
|
||||||
if (sopClassUid === sopClassDictionary.ComputedRadiographyImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.DigitalXRayImageStorageForPresentation
|
|
||||||
|| sopClassUid === sopClassDictionary.DigitalXRayImageStorageForProcessing
|
|
||||||
|| sopClassUid === sopClassDictionary.DigitalMammographyXRayImageStorageForPresentation
|
|
||||||
|| sopClassUid === sopClassDictionary.DigitalMammographyXRayImageStorageForProcessing
|
|
||||||
|| sopClassUid === sopClassDictionary.DigitalIntraOralXRayImageStorageForPresentation
|
|
||||||
|| sopClassUid === sopClassDictionary.DigitalIntraOralXRayImageStorageForProcessing
|
|
||||||
|| sopClassUid === sopClassDictionary.CTImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.EnhancedCTImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.LegacyConvertedEnhancedCTImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.UltrasoundMultiframeImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.MRImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.EnhancedMRImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.EnhancedMRColorImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.LegacyConvertedEnhancedMRImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.UltrasoundImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.SecondaryCaptureImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.MultiframeSingleBitSecondaryCaptureImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.MultiframeGrayscaleByteSecondaryCaptureImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.MultiframeGrayscaleWordSecondaryCaptureImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.MultiframeTrueColorSecondaryCaptureImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.XRayAngiographicImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.EnhancedXAImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.XRayRadiofluoroscopicImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.EnhancedXRFImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.XRay3DAngiographicImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.XRay3DCraniofacialImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.BreastTomosynthesisImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.BreastProjectionXRayImageStorageForPresentation
|
|
||||||
|| sopClassUid === sopClassDictionary.BreastProjectionXRayImageStorageForProcessing
|
|
||||||
|| sopClassUid === sopClassDictionary.IntravascularOpticalCoherenceTomographyImageStorageForPresentation
|
|
||||||
|| sopClassUid === sopClassDictionary.IntravascularOpticalCoherenceTomographyImageStorageForProcessing
|
|
||||||
|| sopClassUid === sopClassDictionary.NuclearMedicineImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.VLEndoscopicImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.VideoEndoscopicImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.VLMicroscopicImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.VideoMicroscopicImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.VLSlideCoordinatesMicroscopicImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.VLPhotographicImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.VideoPhotographicImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.OphthalmicPhotography8BitImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.OphthalmicPhotography16BitImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.OphthalmicTomographyImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.VLWholeSlideMicroscopyImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.PositronEmissionTomographyImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.EnhancedPETImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.LegacyConvertedEnhancedPETImageStorage
|
|
||||||
|| sopClassUid === sopClassDictionary.RTImageStorage) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
@ -1,116 +0,0 @@
|
|||||||
// TODO: Deprecate since we have the same thing in dcmjs?
|
|
||||||
export const sopClassDictionary = {
|
|
||||||
ComputedRadiographyImageStorage: "1.2.840.10008.5.1.4.1.1.1",
|
|
||||||
DigitalXRayImageStorageForPresentation: "1.2.840.10008.5.1.4.1.1.1.1",
|
|
||||||
DigitalXRayImageStorageForProcessing: "1.2.840.10008.5.1.4.1.1.1.1.1",
|
|
||||||
DigitalMammographyXRayImageStorageForPresentation: "1.2.840.10008.5.1.4.1.1.1.2",
|
|
||||||
DigitalMammographyXRayImageStorageForProcessing: "1.2.840.10008.5.1.4.1.1.1.2.1",
|
|
||||||
DigitalIntraOralXRayImageStorageForPresentation: "1.2.840.10008.5.1.4.1.1.1.3",
|
|
||||||
DigitalIntraOralXRayImageStorageForProcessing: "1.2.840.10008.5.1.4.1.1.1.3.1",
|
|
||||||
CTImageStorage: "1.2.840.10008.5.1.4.1.1.2",
|
|
||||||
EnhancedCTImageStorage: "1.2.840.10008.5.1.4.1.1.2.1",
|
|
||||||
LegacyConvertedEnhancedCTImageStorage: "1.2.840.10008.5.1.4.1.1.2.2",
|
|
||||||
UltrasoundMultiframeImageStorage: "1.2.840.10008.5.1.4.1.1.3.1",
|
|
||||||
MRImageStorage: "1.2.840.10008.5.1.4.1.1.4",
|
|
||||||
EnhancedMRImageStorage: "1.2.840.10008.5.1.4.1.1.4.1",
|
|
||||||
MRSpectroscopyStorage: "1.2.840.10008.5.1.4.1.1.4.2",
|
|
||||||
EnhancedMRColorImageStorage: "1.2.840.10008.5.1.4.1.1.4.3",
|
|
||||||
LegacyConvertedEnhancedMRImageStorage: "1.2.840.10008.5.1.4.1.1.4.4",
|
|
||||||
UltrasoundImageStorage: "1.2.840.10008.5.1.4.1.1.6.1",
|
|
||||||
EnhancedUSVolumeStorage: "1.2.840.10008.5.1.4.1.1.6.2",
|
|
||||||
SecondaryCaptureImageStorage: "1.2.840.10008.5.1.4.1.1.7",
|
|
||||||
MultiframeSingleBitSecondaryCaptureImageStorage: "1.2.840.10008.5.1.4.1.1.7.1",
|
|
||||||
MultiframeGrayscaleByteSecondaryCaptureImageStorage: "1.2.840.10008.5.1.4.1.1.7.2",
|
|
||||||
MultiframeGrayscaleWordSecondaryCaptureImageStorage: "1.2.840.10008.5.1.4.1.1.7.3",
|
|
||||||
MultiframeTrueColorSecondaryCaptureImageStorage: "1.2.840.10008.5.1.4.1.1.7.4",
|
|
||||||
Sop12LeadECGWaveformStorage: "1.2.840.10008.5.1.4.1.1.9.1.1",
|
|
||||||
GeneralECGWaveformStorage: "1.2.840.10008.5.1.4.1.1.9.1.2",
|
|
||||||
AmbulatoryECGWaveformStorage: "1.2.840.10008.5.1.4.1.1.9.1.3",
|
|
||||||
HemodynamicWaveformStorage: "1.2.840.10008.5.1.4.1.1.9.2.1",
|
|
||||||
CardiacElectrophysiologyWaveformStorage: "1.2.840.10008.5.1.4.1.1.9.3.1",
|
|
||||||
BasicVoiceAudioWaveformStorage: "1.2.840.10008.5.1.4.1.1.9.4.1",
|
|
||||||
GeneralAudioWaveformStorage: "1.2.840.10008.5.1.4.1.1.9.4.2",
|
|
||||||
ArterialPulseWaveformStorage: "1.2.840.10008.5.1.4.1.1.9.5.1",
|
|
||||||
RespiratoryWaveformStorage: "1.2.840.10008.5.1.4.1.1.9.6.1",
|
|
||||||
GrayscaleSoftcopyPresentationStateStorage: "1.2.840.10008.5.1.4.1.1.11.1",
|
|
||||||
ColorSoftcopyPresentationStateStorage: "1.2.840.10008.5.1.4.1.1.11.2",
|
|
||||||
PseudoColorSoftcopyPresentationStateStorage: "1.2.840.10008.5.1.4.1.1.11.3",
|
|
||||||
BlendingSoftcopyPresentationStateStorage: "1.2.840.10008.5.1.4.1.1.11.4",
|
|
||||||
XAXRFGrayscaleSoftcopyPresentationStateStorage: "1.2.840.10008.5.1.4.1.1.11.5",
|
|
||||||
XRayAngiographicImageStorage: "1.2.840.10008.5.1.4.1.1.12.1",
|
|
||||||
EnhancedXAImageStorage: "1.2.840.10008.5.1.4.1.1.12.1.1",
|
|
||||||
XRayRadiofluoroscopicImageStorage: "1.2.840.10008.5.1.4.1.1.12.2",
|
|
||||||
EnhancedXRFImageStorage: "1.2.840.10008.5.1.4.1.1.12.2.1",
|
|
||||||
XRay3DAngiographicImageStorage: "1.2.840.10008.5.1.4.1.1.13.1.1",
|
|
||||||
XRay3DCraniofacialImageStorage: "1.2.840.10008.5.1.4.1.1.13.1.2",
|
|
||||||
BreastTomosynthesisImageStorage: "1.2.840.10008.5.1.4.1.1.13.1.3",
|
|
||||||
BreastProjectionXRayImageStorageForPresentation: "1.2.840.10008.5.1.4.1.1.13.1.4",
|
|
||||||
BreastProjectionXRayImageStorageForProcessing: "1.2.840.10008.5.1.4.1.1.13.1.5",
|
|
||||||
IntravascularOpticalCoherenceTomographyImageStorageForPresentation: "1.2.840.10008.5.1.4.1.1.14.1",
|
|
||||||
IntravascularOpticalCoherenceTomographyImageStorageForProcessing: "1.2.840.10008.5.1.4.1.1.14.2",
|
|
||||||
NuclearMedicineImageStorage: "1.2.840.10008.5.1.4.1.1.20",
|
|
||||||
RawDataStorage: "1.2.840.10008.5.1.4.1.1.66",
|
|
||||||
SpatialRegistrationStorage: "1.2.840.10008.5.1.4.1.1.66.1",
|
|
||||||
SpatialFiducialsStorage: "1.2.840.10008.5.1.4.1.1.66.2",
|
|
||||||
DeformableSpatialRegistrationStorage: "1.2.840.10008.5.1.4.1.1.66.3",
|
|
||||||
SegmentationStorage: "1.2.840.10008.5.1.4.1.1.66.4",
|
|
||||||
SurfaceSegmentationStorage: "1.2.840.10008.5.1.4.1.1.66.5",
|
|
||||||
RealWorldValueMappingStorage: "1.2.840.10008.5.1.4.1.1.67",
|
|
||||||
SurfaceScanMeshStorage: "1.2.840.10008.5.1.4.1.1.68.1",
|
|
||||||
SurfaceScanPointCloudStorage: "1.2.840.10008.5.1.4.1.1.68.2",
|
|
||||||
VLEndoscopicImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.1",
|
|
||||||
VideoEndoscopicImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.1.1",
|
|
||||||
VLMicroscopicImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.2",
|
|
||||||
VideoMicroscopicImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.2.1",
|
|
||||||
VLSlideCoordinatesMicroscopicImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.3",
|
|
||||||
VLPhotographicImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.4",
|
|
||||||
VideoPhotographicImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.4.1",
|
|
||||||
OphthalmicPhotography8BitImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.5.1",
|
|
||||||
OphthalmicPhotography16BitImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.5.2",
|
|
||||||
StereometricRelationshipStorage: "1.2.840.10008.5.1.4.1.1.77.1.5.3",
|
|
||||||
OphthalmicTomographyImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.5.4",
|
|
||||||
VLWholeSlideMicroscopyImageStorage: "1.2.840.10008.5.1.4.1.1.77.1.6",
|
|
||||||
LensometryMeasurementsStorage: "1.2.840.10008.5.1.4.1.1.78.1",
|
|
||||||
AutorefractionMeasurementsStorage: "1.2.840.10008.5.1.4.1.1.78.2",
|
|
||||||
KeratometryMeasurementsStorage: "1.2.840.10008.5.1.4.1.1.78.3",
|
|
||||||
SubjectiveRefractionMeasurementsStorage: "1.2.840.10008.5.1.4.1.1.78.4",
|
|
||||||
VisualAcuityMeasurementsStorage: "1.2.840.10008.5.1.4.1.1.78.5",
|
|
||||||
SpectaclePrescriptionReportStorage: "1.2.840.10008.5.1.4.1.1.78.6",
|
|
||||||
OphthalmicAxialMeasurementsStorage: "1.2.840.10008.5.1.4.1.1.78.7",
|
|
||||||
IntraocularLensCalculationsStorage: "1.2.840.10008.5.1.4.1.1.78.8",
|
|
||||||
MacularGridThicknessandVolumeReport: "1.2.840.10008.5.1.4.1.1.79.1",
|
|
||||||
OphthalmicVisualFieldStaticPerimetryMeasurementsStorage: "1.2.840.10008.5.1.4.1.1.80.1",
|
|
||||||
OphthalmicThicknessMapStorage: "1.2.840.10008.5.1.4.1.1.81.1",
|
|
||||||
CornealTopographyMapStorage: "1.2.840.10008.5.1.4.1.1.82.1",
|
|
||||||
BasicTextSR: "1.2.840.10008.5.1.4.1.1.88.11",
|
|
||||||
EnhancedSR: "1.2.840.10008.5.1.4.1.1.88.22",
|
|
||||||
ComprehensiveSR: "1.2.840.10008.5.1.4.1.1.88.33",
|
|
||||||
Comprehensive3DSR: "1.2.840.10008.5.1.4.1.1.88.34",
|
|
||||||
ProcedureLog: "1.2.840.10008.5.1.4.1.1.88.40",
|
|
||||||
MammographyCADSR: "1.2.840.10008.5.1.4.1.1.88.50",
|
|
||||||
KeyObjectSelection: "1.2.840.10008.5.1.4.1.1.88.59",
|
|
||||||
ChestCADSR: "1.2.840.10008.5.1.4.1.1.88.65",
|
|
||||||
XRayRadiationDoseSR: "1.2.840.10008.5.1.4.1.1.88.67",
|
|
||||||
RadiopharmaceuticalRadiationDoseSR: "1.2.840.10008.5.1.4.1.1.88.68",
|
|
||||||
ColonCADSR: "1.2.840.10008.5.1.4.1.1.88.69",
|
|
||||||
ImplantationPlanSRDocumentStorage: "1.2.840.10008.5.1.4.1.1.88.70",
|
|
||||||
EncapsulatedPDFStorage: "1.2.840.10008.5.1.4.1.1.104.1",
|
|
||||||
EncapsulatedCDAStorage: "1.2.840.10008.5.1.4.1.1.104.2",
|
|
||||||
PositronEmissionTomographyImageStorage: "1.2.840.10008.5.1.4.1.1.128",
|
|
||||||
EnhancedPETImageStorage: "1.2.840.10008.5.1.4.1.1.130",
|
|
||||||
LegacyConvertedEnhancedPETImageStorage: "1.2.840.10008.5.1.4.1.1.128.1",
|
|
||||||
BasicStructuredDisplayStorage: "1.2.840.10008.5.1.4.1.1.131",
|
|
||||||
RTImageStorage: "1.2.840.10008.5.1.4.1.1.481.1",
|
|
||||||
RTDoseStorage: "1.2.840.10008.5.1.4.1.1.481.2",
|
|
||||||
RTStructureSetStorage: "1.2.840.10008.5.1.4.1.1.481.3",
|
|
||||||
RTBeamsTreatmentRecordStorage: "1.2.840.10008.5.1.4.1.1.481.4",
|
|
||||||
RTPlanStorage: "1.2.840.10008.5.1.4.1.1.481.5",
|
|
||||||
RTBrachyTreatmentRecordStorage: "1.2.840.10008.5.1.4.1.1.481.6",
|
|
||||||
RTTreatmentSummaryRecordStorage: "1.2.840.10008.5.1.4.1.1.481.7",
|
|
||||||
RTIonPlanStorage: "1.2.840.10008.5.1.4.1.1.481.8",
|
|
||||||
RTIonBeamsTreatmentRecordStorage: "1.2.840.10008.5.1.4.1.1.481.9",
|
|
||||||
RTBeamsDeliveryInstructionStorage: "1.2.840.10008.5.1.4.34.7",
|
|
||||||
GenericImplantTemplateStorage: "1.2.840.10008.5.1.4.43.1",
|
|
||||||
ImplantAssemblyTemplateStorage: "1.2.840.10008.5.1.4.44.1",
|
|
||||||
ImplantTemplateGroupStorage: "1.2.840.10008.5.1.4.45.1"
|
|
||||||
};
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
import { createStacks } from './createStacks';
|
|
||||||
|
|
||||||
const getDisplaySets = (studyMetadata, seriesNumber, iteratorFunction) => {
|
|
||||||
const iteratorFn = typeof iteratorFunction !== 'function' ? createStacks : iteratorFunction;
|
|
||||||
|
|
||||||
return iteratorFn(studyMetadata, seriesNumber);
|
|
||||||
};
|
|
||||||
|
|
||||||
const sortingManager = {
|
|
||||||
getDisplaySets
|
|
||||||
};
|
|
||||||
|
|
||||||
export { sortingManager };
|
|
||||||
@ -1,88 +0,0 @@
|
|||||||
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
|
|
||||||
import OHIF from 'ohif-core';
|
|
||||||
import { getWADORSImageId } from './getWADORSImageId';
|
|
||||||
|
|
||||||
function getRadiopharmaceuticalInfoMetaData(instance) {
|
|
||||||
const radiopharmaceuticalInfo = instance.radiopharmaceuticalInfo;
|
|
||||||
|
|
||||||
if ((instance.modality !== 'PT') || !radiopharmaceuticalInfo) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const { WadoRsMetaDataBuilder } = OHIF.metadata;
|
|
||||||
|
|
||||||
return new WadoRsMetaDataBuilder()
|
|
||||||
.addTag('00181072', radiopharmaceuticalInfo.radiopharmaceuticalStartTime)
|
|
||||||
.addTag('00181074', radiopharmaceuticalInfo.radionuclideTotalDose)
|
|
||||||
.addTag('00181075', radiopharmaceuticalInfo.radionuclideHalfLife)
|
|
||||||
.toJSON();
|
|
||||||
}
|
|
||||||
|
|
||||||
const getWadoRsInstanceMetaData = (study, series, instance) => {
|
|
||||||
const { WadoRsMetaDataBuilder } = OHIF.metadata;
|
|
||||||
return new WadoRsMetaDataBuilder()
|
|
||||||
.addTag('00080016', instance.sopClassUid)
|
|
||||||
.addTag('00080018', instance.sopInstanceUid)
|
|
||||||
.addTag('00080021', series.seriesDate)
|
|
||||||
.addTag('00080031', series.seriesTime)
|
|
||||||
.addTag('00080060', instance.modality)
|
|
||||||
.addTag('00101010', study.patientAge)
|
|
||||||
.addTag('00101020', study.patientSize)
|
|
||||||
.addTag('00101030', study.patientWeight)
|
|
||||||
.addTag('00180050', instance.sliceThickness)
|
|
||||||
.addTag('0020000e', series.seriesInstanceUid)
|
|
||||||
.addTag('00200011', series.seriesNumber)
|
|
||||||
.addTag('0020000d', study.studyInstanceUid)
|
|
||||||
.addTag('00200013', instance.instanceNumber)
|
|
||||||
.addTag('00200032', instance.imagePositionPatient, true)
|
|
||||||
.addTag('00200037', instance.imageOrientationPatient, true)
|
|
||||||
.addTag('00200052', instance.frameOfReferenceUID)
|
|
||||||
.addTag('00201041', instance.sliceLocation)
|
|
||||||
.addTag('00280002', instance.samplesPerPixel)
|
|
||||||
.addTag('00280004', instance.photometricInterpretation)
|
|
||||||
.addTag('00280006', instance.planarConfiguration)
|
|
||||||
.addTag('00280010', instance.rows)
|
|
||||||
.addTag('00280011', instance.columns)
|
|
||||||
.addTag('00280030', instance.pixelSpacing, true)
|
|
||||||
.addTag('00280034', instance.pixelAspectRatio, true)
|
|
||||||
.addTag('00280100', instance.bitsAllocated)
|
|
||||||
.addTag('00280101', instance.bitsStored)
|
|
||||||
.addTag('00280102', instance.highBit)
|
|
||||||
.addTag('00280103', instance.pixelRepresentation)
|
|
||||||
.addTag('00280106', instance.smallestPixelValue)
|
|
||||||
.addTag('00280107', instance.largestPixelValue)
|
|
||||||
.addTag('00281050', instance.windowCenter, true)
|
|
||||||
.addTag('00281051', instance.windowWidth, true)
|
|
||||||
.addTag('00281052', instance.rescaleIntercept)
|
|
||||||
.addTag('00281053', instance.rescaleSlope)
|
|
||||||
.addTag('00281054', instance.rescaleType)
|
|
||||||
.addTag('00281101', instance.redPaletteColorLookupTableDescriptor)
|
|
||||||
.addTag('00281102', instance.greenPaletteColorLookupTableDescriptor)
|
|
||||||
.addTag('00281103', instance.bluePaletteColorLookupTableDescriptor)
|
|
||||||
.addTag('00281201', instance.redPaletteColorLookupTableData)
|
|
||||||
.addTag('00281202', instance.greenPaletteColorLookupTableData)
|
|
||||||
.addTag('00281203', instance.bluePaletteColorLookupTableData)
|
|
||||||
.addTag('00540016', getRadiopharmaceuticalInfoMetaData(instance))
|
|
||||||
.toJSON();
|
|
||||||
};
|
|
||||||
|
|
||||||
export function updateMetaDataManager(study) {
|
|
||||||
study.seriesList.forEach(series => {
|
|
||||||
series.instances.forEach(instance => {
|
|
||||||
// Cache just images that are going to be loaded via WADO-RS
|
|
||||||
if ((instance.imageRendering !== 'wadors') && (instance.thumbnailRendering !== 'wadors')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const metaData = getWadoRsInstanceMetaData(study, series, instance);
|
|
||||||
const numberOfFrames = instance.numberOfFrames || 1;
|
|
||||||
|
|
||||||
// We can share the same metaData with all frames because it doesn't have
|
|
||||||
// any frame specific data, such as frameNumber, pixelData, offset, etc.
|
|
||||||
// WADO-RS frame number is 1-based
|
|
||||||
for (let frameNumber = 0; frameNumber < numberOfFrames; frameNumber++) {
|
|
||||||
const imageId = getWADORSImageId(instance, frameNumber);
|
|
||||||
cornerstoneWADOImageLoader.wadors.metaDataManager.add(imageId, metaData);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@ -36,4 +36,17 @@
|
|||||||
--text-secondary-color: #91b9cd;
|
--text-secondary-color: #91b9cd;
|
||||||
--large-numbers-color: #6fbde2;
|
--large-numbers-color: #6fbde2;
|
||||||
--text-disabled-color: #878787;
|
--text-disabled-color: #878787;
|
||||||
|
|
||||||
|
--input-background-color: #2c363f;
|
||||||
|
--input-placeholder-color: #d3d3d3;
|
||||||
|
|
||||||
|
--table-hover-color: #2c363f;
|
||||||
|
--table-text-primary-color: #ffffff;
|
||||||
|
--table-text-secondary-color: #91b9cd;
|
||||||
|
|
||||||
|
--large-numbers-color:#6FBDE2;
|
||||||
|
|
||||||
|
--state-error: #FFCCCC;
|
||||||
|
--state-error-border: #FFCCCC;
|
||||||
|
--state-error-text: #FFCCCC;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2519,14 +2519,6 @@ cornerstone-math@0.1.7, cornerstone-math@^0.1.7:
|
|||||||
resolved "https://registry.yarnpkg.com/cornerstone-math/-/cornerstone-math-0.1.7.tgz#7c55536f02e7221b05fc49a4c780bb82c234ce39"
|
resolved "https://registry.yarnpkg.com/cornerstone-math/-/cornerstone-math-0.1.7.tgz#7c55536f02e7221b05fc49a4c780bb82c234ce39"
|
||||||
integrity sha512-svsDSoqLNFM9niCV2AtV2DNmRkYztT1v80lVdbA5hkgdGdpWg5/h2On794zbqBK+aI3hNOHufERDsI4wdXGknA==
|
integrity sha512-svsDSoqLNFM9niCV2AtV2DNmRkYztT1v80lVdbA5hkgdGdpWg5/h2On794zbqBK+aI3hNOHufERDsI4wdXGknA==
|
||||||
|
|
||||||
cornerstone-tools@3.0.0-b.1471:
|
|
||||||
version "3.0.0-b.1471"
|
|
||||||
resolved "https://registry.yarnpkg.com/cornerstone-tools/-/cornerstone-tools-3.0.0-b.1471.tgz#9bbfd6e21ec6acfbc7b497ff16fe897a03cac899"
|
|
||||||
integrity sha512-XyNOH0ptfZBAW0xghnhyVVc9PqteBRH9OUiLcBoVQSh1GvY0lsmGZURUF/5a4VbnfmXaFuV1niAkODP1zP7mbA==
|
|
||||||
dependencies:
|
|
||||||
"@babel/runtime" "7.1.2"
|
|
||||||
cornerstone-math "^0.1.7"
|
|
||||||
|
|
||||||
cornerstone-tools@3.0.0-b.1512:
|
cornerstone-tools@3.0.0-b.1512:
|
||||||
version "3.0.0-b.1512"
|
version "3.0.0-b.1512"
|
||||||
resolved "https://registry.yarnpkg.com/cornerstone-tools/-/cornerstone-tools-3.0.0-b.1512.tgz#64e60709b7b638c08d201313a5748aa6f5145337"
|
resolved "https://registry.yarnpkg.com/cornerstone-tools/-/cornerstone-tools-3.0.0-b.1512.tgz#64e60709b7b638c08d201313a5748aa6f5145337"
|
||||||
@ -8317,17 +8309,11 @@ react-bootstrap-modal@^4.2.0:
|
|||||||
react-overlays "^0.8.0"
|
react-overlays "^0.8.0"
|
||||||
react-transition-group "^2.0.0"
|
react-transition-group "^2.0.0"
|
||||||
|
|
||||||
react-cornerstone-viewport@^0.1.4:
|
react-cornerstone-viewport@^0.1.5:
|
||||||
version "0.1.4"
|
version "0.1.5"
|
||||||
resolved "https://registry.yarnpkg.com/react-cornerstone-viewport/-/react-cornerstone-viewport-0.1.4.tgz#6e1e1e31cbfca28617d4aebddd591f3a13206382"
|
resolved "https://registry.yarnpkg.com/react-cornerstone-viewport/-/react-cornerstone-viewport-0.1.5.tgz#64809bcba4942710c1cd7dddd63ab14cb682b31f"
|
||||||
integrity sha512-bowfkjKR/hdg+2nEQy2BJejjKIsudiedJrMKehygK2f0SI17w2FC8r8QJPysdykfwz1WuBouOlA0JJtfHzk+CQ==
|
integrity sha512-ANSjQvYOc533k055j4/sV+SrOgmLoEI7ssQ6MiHn5j3E3po30ooUYMWc56fsDxEH/lxFt5VtcFyHYgJdI4RHig==
|
||||||
dependencies:
|
dependencies:
|
||||||
cornerstone-core "2.2.8"
|
|
||||||
cornerstone-math "0.1.7"
|
|
||||||
cornerstone-tools "3.0.0-b.1471"
|
|
||||||
cornerstone-wado-image-loader "2.2.3"
|
|
||||||
dicom-parser "1.8.3"
|
|
||||||
hammerjs "^2.0.8"
|
|
||||||
lodash.debounce "^4.0.8"
|
lodash.debounce "^4.0.8"
|
||||||
moment "^2.23.0"
|
moment "^2.23.0"
|
||||||
stylus "^0.54.5"
|
stylus "^0.54.5"
|
||||||
@ -8521,10 +8507,10 @@ react-transition-group@^2.0.0, react-transition-group@^2.2.0:
|
|||||||
prop-types "^15.6.2"
|
prop-types "^15.6.2"
|
||||||
react-lifecycles-compat "^3.0.4"
|
react-lifecycles-compat "^3.0.4"
|
||||||
|
|
||||||
react-viewerbase@^0.1.9:
|
react-viewerbase@^0.1.10:
|
||||||
version "0.1.9"
|
version "0.1.10"
|
||||||
resolved "https://registry.yarnpkg.com/react-viewerbase/-/react-viewerbase-0.1.9.tgz#9d6930cc22149dd34bbf5d088218f86a804f0260"
|
resolved "https://registry.yarnpkg.com/react-viewerbase/-/react-viewerbase-0.1.10.tgz#7b5d2d9adcea20174a863c0291eca6a728d8da6a"
|
||||||
integrity sha512-0wpEATJxdZAUT8dqUJa4Q0FSv7Zo+HLh969uDXx+x9ZtlZi2JgsU8Hb97D4ump16LHfg6OG5uQqJPcQzrDGWYA==
|
integrity sha512-I6f6n3wgGD9aHyMTta9CIae3BXWk6TTmeAmqaYrfR+uSTfnjBsARmaj2FKtnusGLc2XCZlsSKUQRHSVL6NH3Kg==
|
||||||
dependencies:
|
dependencies:
|
||||||
classnames "^2.2.6"
|
classnames "^2.2.6"
|
||||||
react-bootstrap-modal "^4.2.0"
|
react-bootstrap-modal "^4.2.0"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user