refactor: Reduce bundle size (#1575)
* async load cornerstoneWADOImageLoader chunk * Lazy initializing of CornerstoneWADIImageLoader - delayed till Viewer creation * Async loading of react-vtkjs-viewport * withCornerstone HOC to wrap routes requiring CornerstoneWADOImageLoader initiazation * removed dead code in comments * initWeWorkers is no more. Remove al its references. Co-authored-by: kedar.netelixir <kedar.choudhary@netelixir.com> Co-authored-by: Danny Brown <danny.ri.brown@gmail.com>
This commit is contained in:
parent
e09a3d2e93
commit
81dcbe294d
@ -1,5 +1,5 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { getImageData, loadImageData } from 'react-vtkjs-viewport';
|
import { getReactVtkjsViewport } from './utils/getReactVtkjsViewport';
|
||||||
import ConnectedVTKViewport from './ConnectedVTKViewport';
|
import ConnectedVTKViewport from './ConnectedVTKViewport';
|
||||||
import LoadingIndicator from './LoadingIndicator.js';
|
import LoadingIndicator from './LoadingIndicator.js';
|
||||||
import OHIF from '@ohif/core';
|
import OHIF from '@ohif/core';
|
||||||
@ -69,7 +69,7 @@ class OHIFVTKViewport extends Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
onScroll: () => {},
|
onScroll: () => { },
|
||||||
};
|
};
|
||||||
|
|
||||||
static id = 'OHIFVTKViewport';
|
static id = 'OHIFVTKViewport';
|
||||||
@ -133,7 +133,8 @@ class OHIFVTKViewport extends Component {
|
|||||||
displaySetInstanceUID,
|
displaySetInstanceUID,
|
||||||
SOPClassUID,
|
SOPClassUID,
|
||||||
SOPInstanceUID,
|
SOPInstanceUID,
|
||||||
frameIndex
|
frameIndex,
|
||||||
|
reactVtkjsViewport
|
||||||
) => {
|
) => {
|
||||||
const stack = OHIFVTKViewport.getCornerstoneStack(
|
const stack = OHIFVTKViewport.getCornerstoneStack(
|
||||||
studies,
|
studies,
|
||||||
@ -144,7 +145,10 @@ class OHIFVTKViewport extends Component {
|
|||||||
frameIndex
|
frameIndex
|
||||||
);
|
);
|
||||||
|
|
||||||
const imageDataObject = getImageData(stack.imageIds, displaySetInstanceUID);
|
const imageDataObject = reactVtkjsViewport.getImageData(
|
||||||
|
stack.imageIds,
|
||||||
|
displaySetInstanceUID
|
||||||
|
);
|
||||||
let labelmapDataObject;
|
let labelmapDataObject;
|
||||||
let labelmapColorLUT;
|
let labelmapColorLUT;
|
||||||
|
|
||||||
@ -257,7 +261,9 @@ class OHIFVTKViewport extends Component {
|
|||||||
return volumeActor;
|
return volumeActor;
|
||||||
}
|
}
|
||||||
|
|
||||||
setStateFromProps() {
|
async setStateFromProps() {
|
||||||
|
const reactVtkjsViewport = await getReactVtkjsViewport();
|
||||||
|
|
||||||
const { studies, displaySet } = this.props.viewportData;
|
const { studies, displaySet } = this.props.viewportData;
|
||||||
const {
|
const {
|
||||||
StudyInstanceUID,
|
StudyInstanceUID,
|
||||||
@ -295,8 +301,10 @@ class OHIFVTKViewport extends Component {
|
|||||||
studies,
|
studies,
|
||||||
StudyInstanceUID,
|
StudyInstanceUID,
|
||||||
displaySetInstanceUID,
|
displaySetInstanceUID,
|
||||||
|
sopClassUIDs[0],
|
||||||
SOPInstanceUID,
|
SOPInstanceUID,
|
||||||
frameIndex
|
frameIndex,
|
||||||
|
reactVtkjsViewport
|
||||||
);
|
);
|
||||||
|
|
||||||
this.imageDataObject = imageDataObject;
|
this.imageDataObject = imageDataObject;
|
||||||
@ -317,7 +325,7 @@ class OHIFVTKViewport extends Component {
|
|||||||
dataDetails,
|
dataDetails,
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
this.loadProgressively(imageDataObject);
|
this.loadProgressively(imageDataObject, reactVtkjsViewport);
|
||||||
|
|
||||||
// TODO: There must be a better way to do this.
|
// TODO: There must be a better way to do this.
|
||||||
// We do this so that if all the data is available the react-vtkjs-viewport
|
// We do this so that if all the data is available the react-vtkjs-viewport
|
||||||
@ -335,26 +343,26 @@ class OHIFVTKViewport extends Component {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
async componentDidMount() {
|
||||||
this.setStateFromProps();
|
await this.setStateFromProps();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevProps) {
|
async componentDidUpdate(prevProps) {
|
||||||
const { displaySet } = this.props.viewportData;
|
const { displaySet } = this.props.viewportData;
|
||||||
const prevDisplaySet = prevProps.viewportData.displaySet;
|
const prevDisplaySet = prevProps.viewportData.displaySet;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
displaySet.displaySetInstanceUID !==
|
displaySet.displaySetInstanceUID !==
|
||||||
prevDisplaySet.displaySetInstanceUID ||
|
prevDisplaySet.displaySetInstanceUID ||
|
||||||
displaySet.SOPInstanceUID !== prevDisplaySet.SOPInstanceUID ||
|
displaySet.SOPInstanceUID !== prevDisplaySet.SOPInstanceUID ||
|
||||||
displaySet.frameIndex !== prevDisplaySet.frameIndex
|
displaySet.frameIndex !== prevDisplaySet.frameIndex
|
||||||
) {
|
) {
|
||||||
this.setStateFromProps();
|
await this.setStateFromProps();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loadProgressively(imageDataObject) {
|
loadProgressively(imageDataObject, reactVtkjsViewport) {
|
||||||
loadImageData(imageDataObject);
|
reactVtkjsViewport.loadImageData(imageDataObject);
|
||||||
|
|
||||||
const { isLoading, insertPixelDataPromises } = imageDataObject;
|
const { isLoading, insertPixelDataPromises } = imageDataObject;
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,16 @@
|
|||||||
import React, { useEffect, useCallback } from 'react';
|
import React, { useEffect, useCallback } from 'react';
|
||||||
import { View2D } from 'react-vtkjs-viewport';
|
// import { View2D } from 'react-vtkjs-viewport';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import asyncComponent from './asyncComponent.js';
|
||||||
|
import { getReactVtkjsViewport } from './utils/getReactVtkjsViewport';
|
||||||
|
|
||||||
import './VTKViewport.css';
|
import './VTKViewport.css';
|
||||||
|
|
||||||
|
const View2D = asyncComponent(async () => {
|
||||||
|
const reactVtkjsViewport = await getReactVtkjsViewport();
|
||||||
|
return { default: reactVtkjsViewport.View2D };
|
||||||
|
});
|
||||||
|
|
||||||
const VTKViewport = props => {
|
const VTKViewport = props => {
|
||||||
const style = { width: '100%', height: '100%', position: 'relative' };
|
const style = { width: '100%', height: '100%', position: 'relative' };
|
||||||
|
|
||||||
@ -52,7 +59,7 @@ VTKViewport.propTypes = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
VTKViewport.defaultProps = {
|
VTKViewport.defaultProps = {
|
||||||
onScroll: () => {},
|
onScroll: () => { },
|
||||||
};
|
};
|
||||||
|
|
||||||
export default VTKViewport;
|
export default VTKViewport;
|
||||||
|
|||||||
@ -1,10 +1,5 @@
|
|||||||
import throttle from 'lodash.throttle';
|
import throttle from 'lodash.throttle';
|
||||||
import {
|
import { getReactVtkjsViewport } from './utils/getReactVtkjsViewport';
|
||||||
vtkInteractorStyleMPRCrosshairs,
|
|
||||||
vtkInteractorStyleMPRWindowLevel,
|
|
||||||
vtkInteractorStyleMPRRotate,
|
|
||||||
vtkSVGCrosshairsWidget,
|
|
||||||
} from 'react-vtkjs-viewport';
|
|
||||||
|
|
||||||
import setMPRLayout from './utils/setMPRLayout.js';
|
import setMPRLayout from './utils/setMPRLayout.js';
|
||||||
import setViewportToVTK from './utils/setViewportToVTK.js';
|
import setViewportToVTK from './utils/setViewportToVTK.js';
|
||||||
@ -124,16 +119,18 @@ const commandsModule = ({ commandsManager }) => {
|
|||||||
|
|
||||||
_setView(api, [0, 1, 0], [0, 0, 1]);
|
_setView(api, [0, 1, 0], [0, 0, 1]);
|
||||||
},
|
},
|
||||||
enableRotateTool: () => {
|
enableRotateTool: async () => {
|
||||||
|
const reactVtkjsViewport = await getReactVtkjsViewport();
|
||||||
apis.forEach(api => {
|
apis.forEach(api => {
|
||||||
const istyle = vtkInteractorStyleMPRRotate.newInstance();
|
const istyle = reactVtkjsViewport.vtkInteractorStyleMPRRotate.newInstance();
|
||||||
|
|
||||||
api.setInteractorStyle({ istyle });
|
api.setInteractorStyle({ istyle });
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
enableCrosshairsTool: () => {
|
enableCrosshairsTool: async () => {
|
||||||
|
const reactVtkjsViewport = await getReactVtkjsViewport();
|
||||||
apis.forEach((api, apiIndex) => {
|
apis.forEach((api, apiIndex) => {
|
||||||
const istyle = vtkInteractorStyleMPRCrosshairs.newInstance();
|
const istyle = reactVtkjsViewport.vtkInteractorStyleMPRCrosshairs.newInstance();
|
||||||
|
|
||||||
api.setInteractorStyle({
|
api.setInteractorStyle({
|
||||||
istyle,
|
istyle,
|
||||||
@ -141,7 +138,7 @@ const commandsModule = ({ commandsManager }) => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
enableLevelTool: () => {
|
enableLevelTool: async () => {
|
||||||
function updateVOI(apis, windowWidth, windowCenter) {
|
function updateVOI(apis, windowWidth, windowCenter) {
|
||||||
apis.forEach(api => {
|
apis.forEach(api => {
|
||||||
api.updateVOI(windowWidth, windowCenter);
|
api.updateVOI(windowWidth, windowCenter);
|
||||||
@ -162,8 +159,9 @@ const commandsModule = ({ commandsManager }) => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const reactVtkjsViewport = await getReactVtkjsViewport();
|
||||||
apis.forEach(api => {
|
apis.forEach(api => {
|
||||||
const istyle = vtkInteractorStyleMPRWindowLevel.newInstance();
|
const istyle = reactVtkjsViewport.vtkInteractorStyleMPRWindowLevel.newInstance();
|
||||||
|
|
||||||
api.setInteractorStyle({ istyle, callbacks });
|
api.setInteractorStyle({ istyle, callbacks });
|
||||||
});
|
});
|
||||||
@ -260,14 +258,15 @@ const commandsModule = ({ commandsManager }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add widgets and set default interactorStyle of each viewport.
|
// Add widgets and set default interactorStyle of each viewport.
|
||||||
|
const reactVtkjsViewport = await getReactVtkjsViewport();
|
||||||
apis.forEach((api, apiIndex) => {
|
apis.forEach((api, apiIndex) => {
|
||||||
api.addSVGWidget(
|
api.addSVGWidget(
|
||||||
vtkSVGCrosshairsWidget.newInstance(),
|
reactVtkjsViewport.vtkSVGCrosshairsWidget.newInstance(),
|
||||||
'crosshairsWidget'
|
'crosshairsWidget'
|
||||||
);
|
);
|
||||||
|
|
||||||
const uid = api.uid;
|
const uid = api.uid;
|
||||||
const istyle = vtkInteractorStyleMPRCrosshairs.newInstance();
|
const istyle = reactVtkjsViewport.vtkInteractorStyleMPRCrosshairs.newInstance();
|
||||||
|
|
||||||
api.setInteractorStyle({
|
api.setInteractorStyle({
|
||||||
istyle,
|
istyle,
|
||||||
|
|||||||
5
extensions/vtk/src/utils/getReactVtkjsViewport.js
Normal file
5
extensions/vtk/src/utils/getReactVtkjsViewport.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export function getReactVtkjsViewport() {
|
||||||
|
return import(
|
||||||
|
/* webpackChunkName: "ReactVtkjsViewport" */ 'react-vtkjs-viewport'
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1,10 +1,10 @@
|
|||||||
import cornerstone from 'cornerstone-core';
|
import cornerstone from 'cornerstone-core';
|
||||||
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
|
|
||||||
import {
|
import {
|
||||||
clearStudyLoadingProgress,
|
clearStudyLoadingProgress,
|
||||||
setStudyLoadingProgress,
|
setStudyLoadingProgress,
|
||||||
} from '../redux/actions';
|
} from '../redux/actions';
|
||||||
import StackManager from '../utils/StackManager';
|
import StackManager from '../utils/StackManager';
|
||||||
|
import { getCornerstoneWADOImageLoader } from '../utils/cornerstoneWADOImageLoader';
|
||||||
|
|
||||||
class BaseLoadingListener {
|
class BaseLoadingListener {
|
||||||
constructor(stack, options = {}) {
|
constructor(stack, options = {}) {
|
||||||
@ -103,7 +103,8 @@ class DICOMFileLoadingListener extends BaseLoadingListener {
|
|||||||
this._checkCachedData();
|
this._checkCachedData();
|
||||||
}
|
}
|
||||||
|
|
||||||
_checkCachedData() {
|
async _checkCachedData() {
|
||||||
|
const cornerstoneWADOImageLoader = await getCornerstoneWADOImageLoader();
|
||||||
const dataSet = cornerstoneWADOImageLoader.wadouri.dataSetCacheManager.get(
|
const dataSet = cornerstoneWADOImageLoader.wadouri.dataSetCacheManager.get(
|
||||||
this._dataSetUrl
|
this._dataSetUrl
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import DICOMWeb from '../../../DICOMWeb';
|
import DICOMWeb from '../../../DICOMWeb';
|
||||||
import metadataProvider from '../../../classes/MetadataProvider';
|
import metadataProvider from '../../../classes/MetadataProvider';
|
||||||
import getWADORSImageId from '../../../utils/getWADORSImageId';
|
import getWADORSImageId from '../../../utils/getWADORSImageId';
|
||||||
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
|
|
||||||
import getReferencedSeriesSequence from './getReferencedSeriesSequence';
|
import getReferencedSeriesSequence from './getReferencedSeriesSequence';
|
||||||
|
import { getCornerstoneWADOImageLoader } from '../../../utils/cornerstoneWADOImageLoader';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a plain JS object that describes a study (a study descriptor object)
|
* Create a plain JS object that describes a study (a study descriptor object)
|
||||||
@ -160,6 +160,7 @@ async function makeSOPInstance(server, study, instance) {
|
|||||||
|
|
||||||
const wadoRSMetadata = Object.assign(instance);
|
const wadoRSMetadata = Object.assign(instance);
|
||||||
|
|
||||||
|
const cornerstoneWADOImageLoader = await getCornerstoneWADOImageLoader();
|
||||||
if (sopInstance.NumberOfFrames) {
|
if (sopInstance.NumberOfFrames) {
|
||||||
for (let i = 0; i < sopInstance.NumberOfFrames; i++) {
|
for (let i = 0; i < sopInstance.NumberOfFrames; i++) {
|
||||||
const wadorsImageId = getWADORSImageId(sopInstance, i);
|
const wadorsImageId = getWADORSImageId(sopInstance, i);
|
||||||
|
|||||||
5
platform/core/src/utils/cornerstoneWADOImageLoader.js
Normal file
5
platform/core/src/utils/cornerstoneWADOImageLoader.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export function getCornerstoneWADOImageLoader() {
|
||||||
|
return import(
|
||||||
|
/* webpackChunkName: "CornerstoneWADOImageLoader" */ 'cornerstone-wado-image-loader'
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
import cornerstone from 'cornerstone-core';
|
import cornerstone from 'cornerstone-core';
|
||||||
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
|
|
||||||
import { api } from 'dicomweb-client';
|
import { api } from 'dicomweb-client';
|
||||||
import DICOMWeb from '../DICOMWeb';
|
import DICOMWeb from '../DICOMWeb';
|
||||||
|
import { getCornerstoneWADOImageLoader } from './cornerstoneWADOImageLoader';
|
||||||
|
|
||||||
const getImageId = imageObj => {
|
const getImageId = imageObj => {
|
||||||
if (!imageObj) {
|
if (!imageObj) {
|
||||||
@ -86,7 +86,7 @@ const getImageLoaderType = imageId => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class DicomLoaderService {
|
class DicomLoaderService {
|
||||||
getLocalData(dataset, studies) {
|
async getLocalData(dataset, studies) {
|
||||||
if (dataset && dataset.localFile) {
|
if (dataset && dataset.localFile) {
|
||||||
// Use referenced imageInstance
|
// Use referenced imageInstance
|
||||||
const imageInstance = getImageInstance(dataset);
|
const imageInstance = getImageInstance(dataset);
|
||||||
@ -98,6 +98,7 @@ class DicomLoaderService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!someInvalidStrings(imageId)) {
|
if (!someInvalidStrings(imageId)) {
|
||||||
|
const cornerstoneWADOImageLoader = await getCornerstoneWADOImageLoader();
|
||||||
return cornerstoneWADOImageLoader.wadouri.loadFileRequest(imageId);
|
return cornerstoneWADOImageLoader.wadouri.loadFileRequest(imageId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -176,16 +177,16 @@ class DicomLoaderService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*getLoaderIterator(dataset, studies) {
|
async *getLoaderIterator(dataset, studies) {
|
||||||
yield this.getLocalData(dataset, studies);
|
yield await this.getLocalData(dataset, studies);
|
||||||
yield this.getDataByImageType(dataset);
|
yield this.getDataByImageType(dataset);
|
||||||
yield this.getDataByDatasetType(dataset);
|
yield this.getDataByDatasetType(dataset);
|
||||||
}
|
}
|
||||||
|
|
||||||
findDicomDataPromise(dataset, studies) {
|
async findDicomDataPromise(dataset, studies) {
|
||||||
const loaderIterator = this.getLoaderIterator(dataset, studies);
|
const loaderIterator = this.getLoaderIterator(dataset, studies);
|
||||||
// it returns first valid retriever method.
|
// it returns first valid retriever method.
|
||||||
for (const loader of loaderIterator) {
|
for await (const loader of loaderIterator) {
|
||||||
if (loader) {
|
if (loader) {
|
||||||
return loader;
|
return loader;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,10 +34,7 @@ import i18n from '@ohif/i18n';
|
|||||||
import './config';
|
import './config';
|
||||||
|
|
||||||
/** Utils */
|
/** Utils */
|
||||||
import {
|
import { getUserManagerForOpenIdConnectClient } from './utils/index.js';
|
||||||
getUserManagerForOpenIdConnectClient,
|
|
||||||
initWebWorkers,
|
|
||||||
} from './utils/index.js';
|
|
||||||
|
|
||||||
/** Extensions */
|
/** Extensions */
|
||||||
import { GenericViewerCommands, MeasurementsPanel } from './appExtensions';
|
import { GenericViewerCommands, MeasurementsPanel } from './appExtensions';
|
||||||
@ -140,7 +137,6 @@ class App extends Component {
|
|||||||
*/
|
*/
|
||||||
_initHotkeys(appConfigHotkeys);
|
_initHotkeys(appConfigHotkeys);
|
||||||
_initServers(servers);
|
_initServers(servers);
|
||||||
initWebWorkers();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|||||||
@ -1,7 +1,4 @@
|
|||||||
import OHIF from '@ohif/core';
|
|
||||||
import cornerstone from 'cornerstone-core';
|
import cornerstone from 'cornerstone-core';
|
||||||
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
|
|
||||||
import dicomParser from 'dicom-parser';
|
|
||||||
import version from './version.js';
|
import version from './version.js';
|
||||||
|
|
||||||
let homepage;
|
let homepage;
|
||||||
@ -15,31 +12,4 @@ window.info = {
|
|||||||
homepage,
|
homepage,
|
||||||
};
|
};
|
||||||
|
|
||||||
// For debugging
|
|
||||||
//if (process.env.node_env === 'development') {
|
|
||||||
window.cornerstone = cornerstone;
|
window.cornerstone = cornerstone;
|
||||||
window.cornerstoneWADOImageLoader = cornerstoneWADOImageLoader;
|
|
||||||
//}
|
|
||||||
|
|
||||||
cornerstoneWADOImageLoader.external.cornerstone = cornerstone;
|
|
||||||
cornerstoneWADOImageLoader.external.dicomParser = dicomParser;
|
|
||||||
|
|
||||||
OHIF.user.getAccessToken = () => {
|
|
||||||
// TODO: Get the Redux store from somewhere else
|
|
||||||
const state = window.store.getState();
|
|
||||||
if (!state.oidc || !state.oidc.user) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return state.oidc.user.access_token;
|
|
||||||
};
|
|
||||||
|
|
||||||
cornerstoneWADOImageLoader.configure({
|
|
||||||
beforeSend: function(xhr) {
|
|
||||||
const headers = OHIF.DICOMWeb.getAuthorizationHeader();
|
|
||||||
|
|
||||||
if (headers.Authorization) {
|
|
||||||
xhr.setRequestHeader('Authorization', headers.Authorization);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import FileLoaderService from './localFileLoaders/fileLoaderService';
|
|||||||
const processFile = async file => {
|
const processFile = async file => {
|
||||||
try {
|
try {
|
||||||
const fileLoaderService = new FileLoaderService(file);
|
const fileLoaderService = new FileLoaderService(file);
|
||||||
const imageId = fileLoaderService.addFile(file);
|
const imageId = await fileLoaderService.addFile(file);
|
||||||
const image = await fileLoaderService.loadFile(file, imageId);
|
const image = await fileLoaderService.loadFile(file, imageId);
|
||||||
const dataset = await fileLoaderService.getDataset(image, imageId);
|
const dataset = await fileLoaderService.getDataset(image, imageId);
|
||||||
const studies = await fileLoaderService.getStudies(dataset, imageId);
|
const studies = await fileLoaderService.getStudies(dataset, imageId);
|
||||||
|
|||||||
@ -1,13 +1,14 @@
|
|||||||
import * as dcmjs from 'dcmjs';
|
import * as dcmjs from 'dcmjs';
|
||||||
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
|
|
||||||
import FileLoader from './fileLoader';
|
import FileLoader from './fileLoader';
|
||||||
import OHIF from '@ohif/core';
|
import OHIF from '@ohif/core';
|
||||||
|
import { getCornerstoneWADOImageLoader } from '../../utils/cornerstoneWADOImageLoader';
|
||||||
|
|
||||||
const metadataProvider = OHIF.cornerstone.metadataProvider;
|
const metadataProvider = OHIF.cornerstone.metadataProvider;
|
||||||
|
|
||||||
const DICOMFileLoader = new (class extends FileLoader {
|
const DICOMFileLoader = new (class extends FileLoader {
|
||||||
fileType = 'application/dicom';
|
fileType = 'application/dicom';
|
||||||
loadFile(file, imageId) {
|
async loadFile(file, imageId) {
|
||||||
|
const cornerstoneWADOImageLoader = await getCornerstoneWADOImageLoader();
|
||||||
return cornerstoneWADOImageLoader.wadouri.loadFileRequest(imageId);
|
return cornerstoneWADOImageLoader.wadouri.loadFileRequest(imageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
|
|
||||||
import FileLoader from './fileLoader';
|
import FileLoader from './fileLoader';
|
||||||
import PDFFileLoader from './pdfFileLoader';
|
import PDFFileLoader from './pdfFileLoader';
|
||||||
import DICOMFileLoader from './dicomFileLoader';
|
import DICOMFileLoader from './dicomFileLoader';
|
||||||
|
import { getCornerstoneWADOImageLoader } from '../../utils/cornerstoneWADOImageLoader';
|
||||||
|
|
||||||
class FileLoaderService extends FileLoader {
|
class FileLoaderService extends FileLoader {
|
||||||
fileType;
|
fileType;
|
||||||
@ -53,7 +53,8 @@ class FileLoaderService extends FileLoader {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
addFile(file) {
|
async addFile(file) {
|
||||||
|
const cornerstoneWADOImageLoader = await getCornerstoneWADOImageLoader();
|
||||||
return cornerstoneWADOImageLoader.wadouri.fileManager.add(file);
|
return cornerstoneWADOImageLoader.wadouri.fileManager.add(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
|
|
||||||
import FileLoader from './fileLoader';
|
import FileLoader from './fileLoader';
|
||||||
|
import { getCornerstoneWADOImageLoader } from '../../utils/cornerstoneWADOImageLoader';
|
||||||
|
|
||||||
const PDFFileLoader = new (class extends FileLoader {
|
const PDFFileLoader = new (class extends FileLoader {
|
||||||
fileType = 'application/pdf';
|
fileType = 'application/pdf';
|
||||||
loadFile(file, imageId) {
|
async loadFile(file, imageId) {
|
||||||
|
const cornerstoneWADOImageLoader = await getCornerstoneWADOImageLoader();
|
||||||
return cornerstoneWADOImageLoader.wadouri.loadFileRequest(imageId);
|
return cornerstoneWADOImageLoader.wadouri.loadFileRequest(imageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import asyncComponent from '../components/AsyncComponent.js';
|
import asyncComponent from '../components/AsyncComponent.js';
|
||||||
|
import { withCornerstone } from '../utils/cornerstoneWADOImageLoader';
|
||||||
|
|
||||||
import OHIF from '@ohif/core';
|
import OHIF from '@ohif/core';
|
||||||
const { urlUtil: UrlUtil } = OHIF.utils;
|
const { urlUtil: UrlUtil } = OHIF.utils;
|
||||||
@ -9,8 +10,10 @@ const IHEInvokeImageDisplay = asyncComponent(() =>
|
|||||||
/* webpackChunkName: "IHEInvokeImageDisplay" */ './IHEInvokeImageDisplay.js'
|
/* webpackChunkName: "IHEInvokeImageDisplay" */ './IHEInvokeImageDisplay.js'
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
const ViewerRouting = asyncComponent(() =>
|
const ViewerRouting = withCornerstone(
|
||||||
import(/* webpackChunkName: "ViewerRouting" */ './ViewerRouting.js')
|
asyncComponent(() =>
|
||||||
|
import(/* webpackChunkName: "ViewerRouting" */ './ViewerRouting.js')
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
const StudyListRouting = asyncComponent(() =>
|
const StudyListRouting = asyncComponent(() =>
|
||||||
@ -18,12 +21,18 @@ const StudyListRouting = asyncComponent(() =>
|
|||||||
/* webpackChunkName: "StudyListRouting" */ '../studylist/StudyListRouting.js'
|
/* webpackChunkName: "StudyListRouting" */ '../studylist/StudyListRouting.js'
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
const StandaloneRouting = asyncComponent(() =>
|
const StandaloneRouting = withCornerstone(
|
||||||
import(/* webpackChunkName: "ConnectedStandaloneRouting" */ '../connectedComponents/ConnectedStandaloneRouting.js')
|
asyncComponent(() =>
|
||||||
|
import(
|
||||||
|
/* webpackChunkName: "ConnectedStandaloneRouting" */ '../connectedComponents/ConnectedStandaloneRouting.js'
|
||||||
|
)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
const ViewerLocalFileData = asyncComponent(() =>
|
const ViewerLocalFileData = withCornerstone(
|
||||||
import(
|
asyncComponent(() =>
|
||||||
/* webpackChunkName: "ViewerLocalFileData" */ '../connectedComponents/ViewerLocalFileData.js'
|
import(
|
||||||
|
/* webpackChunkName: "ViewerLocalFileData" */ '../connectedComponents/ViewerLocalFileData.js'
|
||||||
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
79
platform/viewer/src/utils/cornerstoneWADOImageLoader.js
Normal file
79
platform/viewer/src/utils/cornerstoneWADOImageLoader.js
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
import OHIF from '@ohif/core';
|
||||||
|
import cornerstone from 'cornerstone-core';
|
||||||
|
import dicomParser from 'dicom-parser';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
export function getCornerstoneWADOImageLoader() {
|
||||||
|
return import(
|
||||||
|
/* webpackChunkName: "CornerstoneWADOImageLoader" */ 'cornerstone-wado-image-loader'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let initialized = false;
|
||||||
|
export async function initCornerstoneWADOImageLoader() {
|
||||||
|
if (initialized) return;
|
||||||
|
const cornerstoneWADOImageLoader = await getCornerstoneWADOImageLoader();
|
||||||
|
// For debugging
|
||||||
|
//if (process.env.node_env === 'development') {
|
||||||
|
window.cornerstoneWADOImageLoader = cornerstoneWADOImageLoader;
|
||||||
|
//}
|
||||||
|
|
||||||
|
cornerstoneWADOImageLoader.external.cornerstone = cornerstone;
|
||||||
|
cornerstoneWADOImageLoader.external.dicomParser = dicomParser;
|
||||||
|
|
||||||
|
OHIF.user.getAccessToken = () => {
|
||||||
|
// TODO: Get the Redux store from somewhere else
|
||||||
|
const state = window.store.getState();
|
||||||
|
if (!state.oidc || !state.oidc.user) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return state.oidc.user.accesstoken;
|
||||||
|
};
|
||||||
|
|
||||||
|
cornerstoneWADOImageLoader.configure({
|
||||||
|
beforeSend: function (xhr) {
|
||||||
|
const headers = OHIF.DICOMWeb.getAuthorizationHeader();
|
||||||
|
|
||||||
|
if (headers.Authorization) {
|
||||||
|
xhr.setRequestHeader('Authorization', headers.Authorization);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
maxWebWorkers: Math.max(navigator.hardwareConcurrency - 1, 1),
|
||||||
|
startWebWorkersOnDemand: true,
|
||||||
|
taskConfiguration: {
|
||||||
|
decodeTask: {
|
||||||
|
initializeCodecsOnStartup: false,
|
||||||
|
usePDFJS: false,
|
||||||
|
strict: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
cornerstoneWADOImageLoader.webWorkerManager.initialize(config);
|
||||||
|
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function withCornerstone(Component) {
|
||||||
|
// eslint-disable-next-line react/display-name
|
||||||
|
return props => {
|
||||||
|
const [
|
||||||
|
cornerstoneWADOImageLoaderInitialized,
|
||||||
|
setCornerstoneWADOImageLoaderInitialized,
|
||||||
|
] = React.useState(false);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
initCornerstoneWADOImageLoader().then(() =>
|
||||||
|
setCornerstoneWADOImageLoaderInitialized(true)
|
||||||
|
);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
if (!cornerstoneWADOImageLoaderInitialized) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return <Component {...props} />;
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -1,4 +1,3 @@
|
|||||||
import getUserManagerForOpenIdConnectClient from './getUserManagerForOpenIdConnectClient.js';
|
import getUserManagerForOpenIdConnectClient from './getUserManagerForOpenIdConnectClient.js';
|
||||||
import initWebWorkers from './initWebWorkers.js';
|
|
||||||
|
|
||||||
export { getUserManagerForOpenIdConnectClient, initWebWorkers };
|
export { getUserManagerForOpenIdConnectClient };
|
||||||
|
|||||||
@ -5,7 +5,7 @@ describe('utils', () => {
|
|||||||
const utilExports = Object.keys(utils).sort();
|
const utilExports = Object.keys(utils).sort();
|
||||||
|
|
||||||
expect(utilExports).toEqual(
|
expect(utilExports).toEqual(
|
||||||
['getUserManagerForOpenIdConnectClient', 'initWebWorkers'].sort()
|
['getUserManagerForOpenIdConnectClient'].sort()
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,22 +0,0 @@
|
|||||||
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
|
|
||||||
|
|
||||||
let initialized = false;
|
|
||||||
|
|
||||||
export default function initWebWorkers() {
|
|
||||||
const config = {
|
|
||||||
maxWebWorkers: Math.max(navigator.hardwareConcurrency - 1, 1),
|
|
||||||
startWebWorkersOnDemand: true,
|
|
||||||
taskConfiguration: {
|
|
||||||
decodeTask: {
|
|
||||||
initializeCodecsOnStartup: false,
|
|
||||||
usePDFJS: false,
|
|
||||||
strict: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!initialized) {
|
|
||||||
cornerstoneWADOImageLoader.webWorkerManager.initialize(config);
|
|
||||||
initialized = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
import initWebWorkers from './initWebWorkers.js';
|
|
||||||
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
|
|
||||||
|
|
||||||
describe('initWebWorkers', () => {
|
|
||||||
it("initializes cornerstoneWADOImageLoader's web workers", () => {
|
|
||||||
initWebWorkers();
|
|
||||||
|
|
||||||
expect(
|
|
||||||
cornerstoneWADOImageLoader.webWorkerManager.initialize
|
|
||||||
).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('initWebWorkers', () => {
|
|
||||||
it("initializes cornerstoneWADOImageLoader's web workers only once", () => {
|
|
||||||
initWebWorkers();
|
|
||||||
initWebWorkers();
|
|
||||||
|
|
||||||
expect(
|
|
||||||
cornerstoneWADOImageLoader.webWorkerManager.initialize
|
|
||||||
).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
Loading…
Reference in New Issue
Block a user