OHIF-26: StudyLoadingListener :: wadors
This commit is contained in:
parent
de98fb7800
commit
f299eb60e0
@ -117,12 +117,16 @@ Template.viewer.onCreated(() => {
|
|||||||
OHIF.viewer.data.studyInstanceUids = [];
|
OHIF.viewer.data.studyInstanceUids = [];
|
||||||
instance.data.studies.forEach(study => {
|
instance.data.studies.forEach(study => {
|
||||||
const studyMetadata = new OHIF.metadata.StudyMetadata(study, study.studyInstanceUid);
|
const studyMetadata = new OHIF.metadata.StudyMetadata(study, study.studyInstanceUid);
|
||||||
const displaySets = OHIF.viewerbase.sortingManager.getDisplaySets(studyMetadata);
|
let displaySets = study.displaySets;
|
||||||
|
|
||||||
|
if(!displaySets) {
|
||||||
|
displaySets = OHIF.viewerbase.sortingManager.getDisplaySets(studyMetadata);
|
||||||
|
study.displaySets = displaySets;
|
||||||
|
}
|
||||||
|
|
||||||
studyMetadata.setDisplaySets(displaySets);
|
studyMetadata.setDisplaySets(displaySets);
|
||||||
|
|
||||||
study.selected = true;
|
study.selected = true;
|
||||||
study.displaySets = displaySets;
|
|
||||||
OHIF.viewer.Studies.insert(study);
|
OHIF.viewer.Studies.insert(study);
|
||||||
OHIF.viewer.StudyMetadataList.insert(studyMetadata);
|
OHIF.viewer.StudyMetadataList.insert(studyMetadata);
|
||||||
OHIF.viewer.data.studyInstanceUids.push(study.studyInstanceUid);
|
OHIF.viewer.data.studyInstanceUids.push(study.studyInstanceUid);
|
||||||
|
|||||||
@ -111,5 +111,16 @@ Template.imageThumbnail.helpers({
|
|||||||
if (percentComplete && percentComplete !== 100) {
|
if (percentComplete && percentComplete !== 100) {
|
||||||
return percentComplete + '%';
|
return percentComplete + '%';
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Return how much the displaySet has already been loaded (%)
|
||||||
|
stackPercentComplete() {
|
||||||
|
const instance = Template.instance();
|
||||||
|
const stack = instance.data.thumbnail.stack;
|
||||||
|
const displaySetInstanceUid = stack.displaySetInstanceUid;
|
||||||
|
const progress = Session.get('DisplaySetProgress:' + displaySetInstanceUid);
|
||||||
|
const percentComplete = parseFloat(progress ? progress.percentComplete : 0) * 100;
|
||||||
|
|
||||||
|
return percentComplete.toFixed(2);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -56,11 +56,7 @@ const loadDisplaySetIntoViewport = (data, templateData) => {
|
|||||||
const displaySet = data.displaySet;
|
const displaySet = data.displaySet;
|
||||||
|
|
||||||
// Get stack from Stack Manager
|
// Get stack from Stack Manager
|
||||||
let stack = StackManager.findStack(displaySet.displaySetInstanceUid);
|
let stack = StackManager.findOrCreateStack(data.study, displaySet);
|
||||||
// Make sure if the stack is already loaded in the stack manager, otherwise create it
|
|
||||||
if (!stack || !stack.imageIds) {
|
|
||||||
stack = StackManager.makeAndAddStack(data.study, displaySet);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If is a clip, updates the global FPS for cine dialog
|
// If is a clip, updates the global FPS for cine dialog
|
||||||
if (stack.isClip && stack.frameRate > 0) {
|
if (stack.isClip && stack.frameRate > 0) {
|
||||||
|
|||||||
@ -37,6 +37,9 @@ Template.viewerMain.onRendered(() => {
|
|||||||
const parentElement = instance.$('#layoutManagerTarget').get(0);
|
const parentElement = instance.$('#layoutManagerTarget').get(0);
|
||||||
const studyPrefetcher = StudyPrefetcher.getInstance();
|
const studyPrefetcher = StudyPrefetcher.getInstance();
|
||||||
|
|
||||||
|
OHIF.viewerbase.studyLoadingListener.clear();
|
||||||
|
OHIF.viewerbase.studyLoadingListener.addStudies(studies);
|
||||||
|
|
||||||
OHIF.viewerbase.layoutManager = new LayoutManager(parentElement, studies);
|
OHIF.viewerbase.layoutManager = new LayoutManager(parentElement, studies);
|
||||||
studyPrefetcher.setStudies(studies);
|
studyPrefetcher.setStudies(studies);
|
||||||
|
|
||||||
|
|||||||
@ -157,6 +157,10 @@ Viewerbase.createStacks = createStacks;
|
|||||||
import { StackManager } from './lib/StackManager';
|
import { StackManager } from './lib/StackManager';
|
||||||
Viewerbase.stackManager = StackManager;
|
Viewerbase.stackManager = StackManager;
|
||||||
|
|
||||||
|
// studyLoadingListener
|
||||||
|
import { studyLoadingListener } from './lib/studyLoadingListener';
|
||||||
|
Viewerbase.studyLoadingListener = studyLoadingListener;
|
||||||
|
|
||||||
// toolManager
|
// toolManager
|
||||||
import { toolManager } from './lib/toolManager';
|
import { toolManager } from './lib/toolManager';
|
||||||
Viewerbase.toolManager = toolManager;
|
Viewerbase.toolManager = toolManager;
|
||||||
|
|||||||
@ -93,6 +93,21 @@ const StackManager = {
|
|||||||
findStack(displaySetInstanceUid) {
|
findStack(displaySetInstanceUid) {
|
||||||
return stackMap[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.
|
* Gets the underlying map of displaySetInstanceUid to stack object.
|
||||||
* WARNING: Do not change this object. It directly affects the manager.
|
* WARNING: Do not change this object. It directly affects the manager.
|
||||||
|
|||||||
184
Packages/ohif-viewerbase/client/lib/studyLoadingListener.js
Normal file
184
Packages/ohif-viewerbase/client/lib/studyLoadingListener.js
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
import { $ } from 'meteor/jquery';
|
||||||
|
import { Session } from 'meteor/session';
|
||||||
|
|
||||||
|
class BaseLoadingListener {
|
||||||
|
constructor(stack) {
|
||||||
|
this.id = BaseLoadingListener.getNewId();
|
||||||
|
this.stack = stack;
|
||||||
|
this.startListening();
|
||||||
|
}
|
||||||
|
|
||||||
|
_getProgressSessionId() {
|
||||||
|
const displaySetInstanceUid = this.stack.displaySetInstanceUid;
|
||||||
|
return 'DisplaySetProgress:' + displaySetInstanceUid;
|
||||||
|
}
|
||||||
|
|
||||||
|
_clearSession() {
|
||||||
|
const progressSessionId = this._getProgressSessionId();
|
||||||
|
Session.set(progressSessionId, undefined)
|
||||||
|
delete Session.keys.progressSessionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
this.stopListening();
|
||||||
|
this._clearSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
static getNewId() {
|
||||||
|
const timeSlice = (new Date()).getTime().toString().slice(-8);
|
||||||
|
const randomNumber = parseInt(Math.random() * 1000000000000);
|
||||||
|
|
||||||
|
return timeSlice.toString() + randomNumber.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DICOMFileLoadingListener extends BaseLoadingListener {
|
||||||
|
constructor(stack) {
|
||||||
|
super(stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class StackLoadingListener extends BaseLoadingListener {
|
||||||
|
constructor(stack) {
|
||||||
|
super(stack);
|
||||||
|
this.remainingImageIds = stack.imageIds.slice();
|
||||||
|
this.loadedImageIds = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
getImageLoadedEventName() {
|
||||||
|
return 'CornerstoneImageLoaded.' + this.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
getImageCachePromiseRemoveEventName() {
|
||||||
|
return 'CornerstoneImageCachePromiseRemoved.' + this.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
startListening() {
|
||||||
|
const imageLoadedEventName = this.getImageLoadedEventName();
|
||||||
|
const imageCachePromiseRemovedEventName = this.getImageCachePromiseRemoveEventName();
|
||||||
|
|
||||||
|
this.stopListening();
|
||||||
|
|
||||||
|
$(cornerstone).on(imageLoadedEventName, (e, eventData) => {
|
||||||
|
this._imageLoadedEventHandle(e, eventData);
|
||||||
|
});
|
||||||
|
|
||||||
|
$(cornerstone).on(imageCachePromiseRemovedEventName, (e, eventData) => {
|
||||||
|
this._imageCachePromiseRemovedEventHandle(e, eventData);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
stopListening() {
|
||||||
|
const imageLoadedEventName = this.getImageLoadedEventName();
|
||||||
|
const imageCachePromiseRemovedEventName = this.getImageCachePromiseRemoveEventName();
|
||||||
|
|
||||||
|
$(cornerstone).off(imageLoadedEventName);
|
||||||
|
$(cornerstone).off(imageCachePromiseRemovedEventName);
|
||||||
|
}
|
||||||
|
|
||||||
|
_hasImageId(imageId) {
|
||||||
|
return this.stack.imageIds.indexOf(imageId) !== -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
_moveImageId(imageId, srcImageIds, dstImageIds) {
|
||||||
|
const imageIdIndex = srcImageIds.indexOf(imageId);
|
||||||
|
|
||||||
|
if(imageIdIndex === -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dstImageIds.push(imageId);
|
||||||
|
srcImageIds.splice(imageIdIndex, 1);
|
||||||
|
this._triggerProgress();
|
||||||
|
}
|
||||||
|
|
||||||
|
_imageLoadedEventHandle(e, eventData) {
|
||||||
|
const imageId = eventData.image.imageId;
|
||||||
|
this._moveImageId(imageId, this.remainingImageIds, this.loadedImageIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
_imageCachePromiseRemovedEventHandle(e, eventData) {
|
||||||
|
const imageId = eventData.imageId;
|
||||||
|
this._moveImageId(imageId, this.loadedImageIds, this.remainingImageIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
_triggerProgress() {
|
||||||
|
const loadedImagesCount = this.loadedImageIds.length;
|
||||||
|
const remainingImagesCount = this.remainingImageIds.length;
|
||||||
|
const totalImagesCount = loadedImagesCount + remainingImagesCount;
|
||||||
|
const percentComplete = loadedImagesCount / (totalImagesCount);
|
||||||
|
const progressSessionId = this._getProgressSessionId();
|
||||||
|
|
||||||
|
Session.set(progressSessionId, {
|
||||||
|
totalImagesCount,
|
||||||
|
loadedImagesCount,
|
||||||
|
remainingImagesCount,
|
||||||
|
percentComplete
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class StudyLoadingListener {
|
||||||
|
constructor() {
|
||||||
|
this.listeners = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
addStack(stack) {
|
||||||
|
const displaySetInstanceUid = stack.displaySetInstanceUid;
|
||||||
|
|
||||||
|
if (!this.listeners[displaySetInstanceUid]) {
|
||||||
|
listener = this._createListener(stack);
|
||||||
|
if (listener) {
|
||||||
|
this.listeners[displaySetInstanceUid] = listener;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addStudy(study) {
|
||||||
|
study.displaySets.forEach(displaySet => {
|
||||||
|
const stack = OHIF.viewerbase.stackManager.findOrCreateStack(study, displaySet);
|
||||||
|
this.addStack(stack);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
addStudies(studies) {
|
||||||
|
if(!studies || !studies.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(let i = 0; i < studies.length; i++) {
|
||||||
|
this.addStudy(studies[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
const displaySetInstanceUids = Object.keys(this.listeners);
|
||||||
|
const length = displaySetInstanceUids.length;
|
||||||
|
|
||||||
|
for(let i = 0; i < length; i++) {
|
||||||
|
const displaySetInstanceUid = displaySetInstanceUids[i];
|
||||||
|
const displaySet = this.listeners[displaySetInstanceUid]
|
||||||
|
displaySet.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.listener = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
_createListener(stack) {
|
||||||
|
const schema = this._getSchema(stack);
|
||||||
|
|
||||||
|
if(schema === 'wadors') {
|
||||||
|
return new StackLoadingListener(stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_getSchema(stack) {
|
||||||
|
const imageId = stack.imageIds[0];
|
||||||
|
const colonIndex = imageId.indexOf(":");
|
||||||
|
return imageId.substring(0, colonIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const studyLoadingListener = new StudyLoadingListener();
|
||||||
|
|
||||||
|
export { studyLoadingListener };
|
||||||
Loading…
Reference in New Issue
Block a user