Updates to improve reactivity, session storage, logging
This commit is contained in:
parent
9fb5cc2953
commit
a10f149b4b
@ -36,3 +36,4 @@ random
|
|||||||
reactive-var
|
reactive-var
|
||||||
reactive-dict
|
reactive-dict
|
||||||
lesiontracker
|
lesiontracker
|
||||||
|
practicalmeteor:loglevel
|
||||||
|
|||||||
@ -16,6 +16,7 @@ caching-compiler@1.0.0
|
|||||||
caching-html-compiler@1.0.2
|
caching-html-compiler@1.0.2
|
||||||
callback-hook@1.0.4
|
callback-hook@1.0.4
|
||||||
check@1.1.0
|
check@1.1.0
|
||||||
|
coffeescript@1.0.11
|
||||||
cornerstone@0.0.1
|
cornerstone@0.0.1
|
||||||
ddp@1.2.2
|
ddp@1.2.2
|
||||||
ddp-client@1.2.1
|
ddp-client@1.2.1
|
||||||
@ -67,6 +68,8 @@ npm-bcrypt@0.7.8_2
|
|||||||
npm-mongo@1.4.39_1
|
npm-mongo@1.4.39_1
|
||||||
observe-sequence@1.0.7
|
observe-sequence@1.0.7
|
||||||
ordered-dict@1.0.4
|
ordered-dict@1.0.4
|
||||||
|
practicalmeteor:chai@1.9.2_3
|
||||||
|
practicalmeteor:loglevel@1.1.0_3
|
||||||
promise@0.5.1
|
promise@0.5.1
|
||||||
random@1.0.5
|
random@1.0.5
|
||||||
rate-limit@1.0.0
|
rate-limit@1.0.0
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
<template name="viewer">
|
<template name="viewer">
|
||||||
<div id="viewer" class="viewer">
|
<div id="viewer" class="viewer">
|
||||||
{{ >lesionDialog studies=studies activeViewport=activeViewport}}
|
{{ >lesionDialog }}
|
||||||
<div id="upperHalf">
|
<div id="upperHalf">
|
||||||
{{ >hidingPanel studies=studies activeViewport=activeViewport}}
|
{{ >hidingPanel }}
|
||||||
{{ >viewerMain studies=studies activeViewport=activeViewport viewportRows=viewportRows viewportColumns=viewportColumns}}
|
{{ >viewerMain }}
|
||||||
</div>
|
</div>
|
||||||
{{ >lesionTable studies=studies activeViewport=activeViewport viewportRows=viewportRows viewportColumns=viewportColumns}}
|
{{ >lesionTable }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -1,4 +1,6 @@
|
|||||||
function resizeViewports() {
|
function resizeViewports() {
|
||||||
|
log.info("viewer resizeViewports");
|
||||||
|
|
||||||
// Handle resizing of image viewer viewports
|
// Handle resizing of image viewer viewports
|
||||||
// For some reason, this seems to need to be on
|
// For some reason, this seems to need to be on
|
||||||
// another delay, or the resizing won't work properly
|
// another delay, or the resizing won't work properly
|
||||||
@ -15,7 +17,8 @@ function resizeViewports() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Template.viewer.onCreated(function() {
|
Template.viewer.onCreated(function() {
|
||||||
console.log("Image Viewer onCreated");
|
log.info("viewer onCreated");
|
||||||
|
|
||||||
OHIF = {
|
OHIF = {
|
||||||
viewer: {}
|
viewer: {}
|
||||||
};
|
};
|
||||||
@ -55,35 +58,35 @@ Template.viewer.onCreated(function() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.data.activeViewport === undefined) {
|
|
||||||
this.data.activeViewport = new ReactiveVar(0);
|
|
||||||
}
|
|
||||||
if (this.data.viewportRows === undefined) {
|
|
||||||
this.data.viewportRows = new ReactiveVar(1);
|
|
||||||
}
|
|
||||||
if (this.data.viewportColumns === undefined) {
|
|
||||||
this.data.viewportColumns = new ReactiveVar(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
var contentId = this.data.contentId;
|
var contentId = this.data.contentId;
|
||||||
|
|
||||||
// Update the viewer data object
|
if (ViewerData[contentId].loadedSeriesData) {
|
||||||
ViewerData[contentId].viewportColumns = this.data.viewportColumns;
|
log.info('Reloading previous loadedSeriesData');
|
||||||
ViewerData[contentId].viewportRows = this.data.viewportRows;
|
|
||||||
ViewerData[contentId].activeViewport = this.data.activeViewport;
|
OHIF.viewer.loadedSeriesData = ViewerData[contentId].loadedSeriesData;
|
||||||
Session.set('ViewerData', ViewerData);
|
|
||||||
|
|
||||||
if (ViewerData[contentId].viewer) {
|
|
||||||
OHIF.viewer = ViewerData[contentId].viewer;
|
|
||||||
} else {
|
} else {
|
||||||
OHIF.viewer.imageViewerLoadedSeriesDictionary = {};
|
log.info('Setting default ViewerData');
|
||||||
ViewerData[contentId].viewer = OHIF.viewer;
|
OHIF.viewer.loadedSeriesData = {};
|
||||||
|
|
||||||
|
ViewerData[contentId].loadedSeriesData = OHIF.viewer.loadedSeriesData;
|
||||||
|
|
||||||
|
// Update the viewer data object
|
||||||
|
ViewerData[contentId].viewportColumns = 2;
|
||||||
|
ViewerData[contentId].viewportRows = 1;
|
||||||
|
ViewerData[contentId].activeViewport = 0;
|
||||||
|
Session.set('ViewerData', ViewerData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Session.set('activeViewport', ViewerData[contentId].activeViewport || 0);
|
||||||
|
|
||||||
|
Session.set("studies", this.data.studies);
|
||||||
|
|
||||||
OHIF.viewer.updateImageSynchronizer = new cornerstoneTools.Synchronizer("CornerstoneNewImage", cornerstoneTools.updateImageSynchronizer);
|
OHIF.viewer.updateImageSynchronizer = new cornerstoneTools.Synchronizer("CornerstoneNewImage", cornerstoneTools.updateImageSynchronizer);
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.viewer.onDestroyed(function() {
|
Template.viewer.onDestroyed(function() {
|
||||||
|
log.info("onDestroyed");
|
||||||
OHIF.viewer.updateImageSynchronizer.destroy();
|
OHIF.viewer.updateImageSynchronizer.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template name="viewerMain">
|
<template name="viewerMain">
|
||||||
<div class="viewerMain">
|
<div class="viewerMain">
|
||||||
{{ >toolbar toolbarOptions=toolbarOptions activeViewport=activeViewport viewportRows=viewportRows viewportColumns=viewportColumns}}
|
{{ >toolbar toolbarOptions=toolbarOptions }}
|
||||||
{{ >imageViewerViewports studies=studies activeViewport=activeViewport viewportRows=viewportRows viewportColumns=viewportColumns}}
|
{{ >imageViewerViewports }}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -1,7 +1,4 @@
|
|||||||
Template.viewerMain.helpers({
|
Template.viewerMain.helpers({
|
||||||
studies : function() {
|
|
||||||
return this.studies;
|
|
||||||
},
|
|
||||||
'toolbarOptions': function() {
|
'toolbarOptions': function() {
|
||||||
var toolbarOptions = {};
|
var toolbarOptions = {};
|
||||||
|
|
||||||
|
|||||||
3
LesionTracker/client/log.js
Normal file
3
LesionTracker/client/log.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
// Create application logger using loglevel
|
||||||
|
// https://atmospherejs.com/spacejamio/loglevel
|
||||||
|
log = loglevel.createAppLogger('LesionTracker', defaultLevel = 'info');
|
||||||
@ -1,49 +0,0 @@
|
|||||||
Router.configure({
|
|
||||||
layoutTemplate: 'layoutLesionTracker',
|
|
||||||
//loadingTemplate: '',
|
|
||||||
notFoundTemplate: 'notFound'
|
|
||||||
});
|
|
||||||
|
|
||||||
Router.route('/', function () {
|
|
||||||
this.render('worklist', {});
|
|
||||||
});
|
|
||||||
|
|
||||||
tabs = new Meteor.Collection(null);
|
|
||||||
Session.setDefault('ViewerData', {});
|
|
||||||
Session.setDefault('ViewerDataUpdated', Random.id());
|
|
||||||
|
|
||||||
Object.keys(ViewerData).forEach(function(contentId) {
|
|
||||||
var tabData = ViewerData[contentId];
|
|
||||||
var data = {
|
|
||||||
title: tabData.title,
|
|
||||||
contentid: tabData.contentId,
|
|
||||||
};
|
|
||||||
tabs.insert(data);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
Router.route('/viewer/:_id', {
|
|
||||||
layoutTemplate: 'layout',
|
|
||||||
name: 'viewer',
|
|
||||||
onBeforeAction: function() {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
Meteor.call('GetStudyMetadata', this.params._id, function(error, study) {
|
|
||||||
sortStudy(study);
|
|
||||||
|
|
||||||
var title = study.seriesList[0].instances[0].patientName;
|
|
||||||
var contentid = generateUUID();
|
|
||||||
|
|
||||||
var data = {
|
|
||||||
title: title,
|
|
||||||
contentid: contentid,
|
|
||||||
};
|
|
||||||
tabs.insert(data);
|
|
||||||
|
|
||||||
data.studies = [study];
|
|
||||||
|
|
||||||
self.render('worklist');
|
|
||||||
Session.set('OpenNewTabEvent', data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
45
LesionTracker/client/routes.js
Normal file
45
LesionTracker/client/routes.js
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
tabs = new Meteor.Collection(null);
|
||||||
|
Session.setDefault('ViewerData', {});
|
||||||
|
|
||||||
|
// Re-add any tab data saved in the Session
|
||||||
|
Object.keys(ViewerData).forEach(function(contentId) {
|
||||||
|
var tabData = ViewerData[contentId];
|
||||||
|
var data = {
|
||||||
|
title: tabData.title,
|
||||||
|
contentid: tabData.contentid,
|
||||||
|
};
|
||||||
|
tabs.insert(data);
|
||||||
|
});
|
||||||
|
|
||||||
|
Router.configure({
|
||||||
|
layoutTemplate: 'layout',
|
||||||
|
loadingTemplate: 'layout',
|
||||||
|
notFoundTemplate: 'notFound'
|
||||||
|
});
|
||||||
|
|
||||||
|
Router.onBeforeAction('loading');
|
||||||
|
|
||||||
|
Router.route('/', function () {
|
||||||
|
this.render('worklist');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
Router.route('/viewer/:_id', {
|
||||||
|
layoutTemplate: 'layout',
|
||||||
|
name: 'viewer',
|
||||||
|
onBeforeAction: function() {
|
||||||
|
log.info('Router GetStudyMetadata');
|
||||||
|
|
||||||
|
var studyInstanceUid = this.params._id;
|
||||||
|
|
||||||
|
// Check if this study is already loaded in a tab
|
||||||
|
// If it is, stop here so we don't keep adding tabs on hot-code reloads
|
||||||
|
var tab = tabs.find({'studyInstanceUid' : studyInstanceUid}).fetch();
|
||||||
|
if (tab) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.render('worklist');
|
||||||
|
openNewTab(studyInstanceUid);
|
||||||
|
}
|
||||||
|
});
|
||||||
@ -33,3 +33,4 @@ dicomweb
|
|||||||
viewerbase
|
viewerbase
|
||||||
worklist
|
worklist
|
||||||
reactive-var
|
reactive-var
|
||||||
|
practicalmeteor:loglevel
|
||||||
|
|||||||
@ -15,6 +15,7 @@ caching-compiler@1.0.0
|
|||||||
caching-html-compiler@1.0.2
|
caching-html-compiler@1.0.2
|
||||||
callback-hook@1.0.4
|
callback-hook@1.0.4
|
||||||
check@1.1.0
|
check@1.1.0
|
||||||
|
coffeescript@1.0.11
|
||||||
cornerstone@0.0.1
|
cornerstone@0.0.1
|
||||||
ddp@1.2.2
|
ddp@1.2.2
|
||||||
ddp-client@1.2.1
|
ddp-client@1.2.1
|
||||||
@ -64,6 +65,8 @@ npm-bcrypt@0.7.8_2
|
|||||||
npm-mongo@1.4.39_1
|
npm-mongo@1.4.39_1
|
||||||
observe-sequence@1.0.7
|
observe-sequence@1.0.7
|
||||||
ordered-dict@1.0.4
|
ordered-dict@1.0.4
|
||||||
|
practicalmeteor:chai@1.9.2_3
|
||||||
|
practicalmeteor:loglevel@1.1.0_3
|
||||||
promise@0.5.1
|
promise@0.5.1
|
||||||
random@1.0.5
|
random@1.0.5
|
||||||
rate-limit@1.0.0
|
rate-limit@1.0.0
|
||||||
|
|||||||
@ -1,6 +1,9 @@
|
|||||||
<template name="viewer">
|
<template name="viewer">
|
||||||
<div id="viewer">
|
<div id="viewer">
|
||||||
{{> studyBrowser studies=studies activeViewport=activeViewport}}
|
{{> studyBrowser }}
|
||||||
{{> viewerMain studies=studies activeViewport=activeViewport viewportRows=viewportRows viewportColumns=viewportColumns}}
|
<div class='viewerMain'>
|
||||||
|
{{ > toolbar }}
|
||||||
|
{{ > imageViewerViewports }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -1,4 +1,6 @@
|
|||||||
function resizeViewports() {
|
function resizeViewports() {
|
||||||
|
log.info("viewer resizeViewports");
|
||||||
|
|
||||||
// Handle resizing of image viewer viewports
|
// Handle resizing of image viewer viewports
|
||||||
// For some reason, this seems to need to be on
|
// For some reason, this seems to need to be on
|
||||||
// another delay, or the resizing won't work properly
|
// another delay, or the resizing won't work properly
|
||||||
@ -15,7 +17,8 @@ function resizeViewports() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Template.viewer.onCreated(function() {
|
Template.viewer.onCreated(function() {
|
||||||
console.log("Image Viewer onCreated");
|
log.info("viewer onCreated");
|
||||||
|
|
||||||
OHIF = {
|
OHIF = {
|
||||||
viewer: {}
|
viewer: {}
|
||||||
};
|
};
|
||||||
@ -55,35 +58,35 @@ Template.viewer.onCreated(function() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.data.activeViewport === undefined) {
|
|
||||||
this.data.activeViewport = new ReactiveVar(0);
|
|
||||||
}
|
|
||||||
if (this.data.viewportRows === undefined) {
|
|
||||||
this.data.viewportRows = new ReactiveVar(1);
|
|
||||||
}
|
|
||||||
if (this.data.viewportColumns === undefined) {
|
|
||||||
this.data.viewportColumns = new ReactiveVar(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
var contentId = this.data.contentId;
|
var contentId = this.data.contentId;
|
||||||
|
|
||||||
// Update the viewer data object
|
if (ViewerData[contentId].loadedSeriesData) {
|
||||||
ViewerData[contentId].viewportColumns = this.data.viewportColumns;
|
log.info('Reloading previous loadedSeriesData');
|
||||||
ViewerData[contentId].viewportRows = this.data.viewportRows;
|
|
||||||
ViewerData[contentId].activeViewport = this.data.activeViewport;
|
OHIF.viewer.loadedSeriesData = ViewerData[contentId].loadedSeriesData;
|
||||||
Session.set('ViewerData', ViewerData);
|
|
||||||
|
|
||||||
if (ViewerData[contentId].viewer) {
|
|
||||||
OHIF.viewer = ViewerData[contentId].viewer;
|
|
||||||
} else {
|
} else {
|
||||||
OHIF.viewer.imageViewerLoadedSeriesDictionary = {};
|
log.info('Setting default ViewerData');
|
||||||
ViewerData[contentId].viewer = OHIF.viewer;
|
OHIF.viewer.loadedSeriesData = {};
|
||||||
|
|
||||||
|
ViewerData[contentId].loadedSeriesData = OHIF.viewer.loadedSeriesData;
|
||||||
|
|
||||||
|
// Update the viewer data object
|
||||||
|
ViewerData[contentId].viewportColumns = 1;
|
||||||
|
ViewerData[contentId].viewportRows = 1;
|
||||||
|
ViewerData[contentId].activeViewport = 0;
|
||||||
|
Session.set('ViewerData', ViewerData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Session.set('activeViewport', ViewerData[contentId].activeViewport || 0);
|
||||||
|
|
||||||
|
Session.set("studies", this.data.studies);
|
||||||
|
|
||||||
OHIF.viewer.updateImageSynchronizer = new cornerstoneTools.Synchronizer("CornerstoneNewImage", cornerstoneTools.updateImageSynchronizer);
|
OHIF.viewer.updateImageSynchronizer = new cornerstoneTools.Synchronizer("CornerstoneNewImage", cornerstoneTools.updateImageSynchronizer);
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.viewer.onDestroyed(function() {
|
Template.viewer.onDestroyed(function() {
|
||||||
|
log.info("onDestroyed");
|
||||||
OHIF.viewer.updateImageSynchronizer.destroy();
|
OHIF.viewer.updateImageSynchronizer.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -13,3 +13,9 @@
|
|||||||
|
|
||||||
.studyBrowser
|
.studyBrowser
|
||||||
width: auto
|
width: auto
|
||||||
|
|
||||||
|
.viewerMain
|
||||||
|
float: left
|
||||||
|
background-color: gray
|
||||||
|
height: 100%
|
||||||
|
width: calc(100% - 120px)
|
||||||
@ -1,6 +0,0 @@
|
|||||||
<template name="viewerMain">
|
|
||||||
<div class='viewerMain'>
|
|
||||||
{{ > toolbar activeViewport=activeViewport viewportRows=viewportRows viewportColumns=viewportColumns}}
|
|
||||||
{{ > imageViewerViewports studies=studies activeViewport=activeViewport viewportRows=viewportRows viewportColumns=viewportColumns}}
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
Template.viewerMain.helpers({
|
|
||||||
studies : function() {
|
|
||||||
return this.studies;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
.viewerMain
|
|
||||||
float: left
|
|
||||||
background-color: gray
|
|
||||||
height: 100%
|
|
||||||
width: calc(100% - 120px)
|
|
||||||
3
OHIFViewer/client/log.js
Normal file
3
OHIFViewer/client/log.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
// Create application logger using loglevel
|
||||||
|
// https://atmospherejs.com/spacejamio/loglevel
|
||||||
|
log = loglevel.createAppLogger('OHIFViewer', defaultLevel = 'info');
|
||||||
@ -1,49 +1,45 @@
|
|||||||
Router.configure({
|
|
||||||
layoutTemplate: 'layout',
|
|
||||||
//loadingTemplate: '',
|
|
||||||
notFoundTemplate: 'notFound'
|
|
||||||
});
|
|
||||||
|
|
||||||
Router.route('/', function () {
|
|
||||||
this.render('worklist', {});
|
|
||||||
});
|
|
||||||
|
|
||||||
tabs = new Meteor.Collection(null);
|
tabs = new Meteor.Collection(null);
|
||||||
Session.setDefault('ViewerData', {});
|
Session.setDefault('ViewerData', {});
|
||||||
Session.setDefault('ViewerDataUpdated', Random.id());
|
|
||||||
|
|
||||||
|
// Re-add any tab data saved in the Session
|
||||||
Object.keys(ViewerData).forEach(function(contentId) {
|
Object.keys(ViewerData).forEach(function(contentId) {
|
||||||
var tabData = ViewerData[contentId];
|
var tabData = ViewerData[contentId];
|
||||||
var data = {
|
var data = {
|
||||||
title: tabData.title,
|
title: tabData.title,
|
||||||
contentid: tabData.contentId,
|
contentid: tabData.contentid,
|
||||||
};
|
};
|
||||||
tabs.insert(data);
|
tabs.insert(data);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Router.configure({
|
||||||
|
layoutTemplate: 'layout',
|
||||||
|
loadingTemplate: 'layout',
|
||||||
|
notFoundTemplate: 'notFound'
|
||||||
|
});
|
||||||
|
|
||||||
|
Router.onBeforeAction('loading');
|
||||||
|
|
||||||
|
Router.route('/', function () {
|
||||||
|
this.render('worklist');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
Router.route('/viewer/:_id', {
|
Router.route('/viewer/:_id', {
|
||||||
layoutTemplate: 'layout',
|
layoutTemplate: 'layout',
|
||||||
name: 'viewer',
|
name: 'viewer',
|
||||||
onBeforeAction: function() {
|
onBeforeAction: function() {
|
||||||
var self = this;
|
log.info('Router GetStudyMetadata');
|
||||||
|
|
||||||
Meteor.call('GetStudyMetadata', this.params._id, function(error, study) {
|
var studyInstanceUid = this.params._id;
|
||||||
sortStudy(study);
|
|
||||||
|
|
||||||
var title = study.seriesList[0].instances[0].patientName;
|
// Check if this study is already loaded in a tab
|
||||||
var contentid = generateUUID();
|
// If it is, stop here so we don't keep adding tabs on hot-code reloads
|
||||||
|
var tab = tabs.find({'studyInstanceUid' : studyInstanceUid}).fetch();
|
||||||
|
if (tab) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var data = {
|
this.render('worklist');
|
||||||
title: title,
|
openNewTab(studyInstanceUid);
|
||||||
contentid: contentid,
|
|
||||||
};
|
|
||||||
tabs.insert(data);
|
|
||||||
|
|
||||||
data.studies = [study];
|
|
||||||
|
|
||||||
self.render('worklist');
|
|
||||||
Session.set('OpenNewTabEvent', data);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -2148,7 +2148,7 @@ if(typeof cornerstone === 'undefined'){
|
|||||||
|
|
||||||
function initShaders() {
|
function initShaders() {
|
||||||
for (var id in cornerstone.webGL.shaders) {
|
for (var id in cornerstone.webGL.shaders) {
|
||||||
console.log("WEBGL: Loading shader", id);
|
//console.log("WEBGL: Loading shader", id);
|
||||||
var shader = cornerstone.webGL.shaders[ id ];
|
var shader = cornerstone.webGL.shaders[ id ];
|
||||||
shader.attributes = {};
|
shader.attributes = {};
|
||||||
shader.uniforms = {};
|
shader.uniforms = {};
|
||||||
@ -2168,13 +2168,13 @@ if(typeof cornerstone === 'undefined'){
|
|||||||
|
|
||||||
function initRenderer() {
|
function initRenderer() {
|
||||||
if (cornerstone.webGL.isWebGLInitialized === true) {
|
if (cornerstone.webGL.isWebGLInitialized === true) {
|
||||||
console.log("WEBGL Renderer already initialized");
|
//console.log("WEBGL Renderer already initialized");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ( initWebGL( renderCanvas ) ) {
|
if ( initWebGL( renderCanvas ) ) {
|
||||||
initBuffers();
|
initBuffers();
|
||||||
initShaders();
|
initShaders();
|
||||||
console.log("WEBGL Renderer initialized!");
|
//console.log("WEBGL Renderer initialized!");
|
||||||
cornerstone.webGL.isWebGLInitialized = true;
|
cornerstone.webGL.isWebGLInitialized = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,12 +3,22 @@ TabsTimepoints = new Meteor.Collection(null);
|
|||||||
|
|
||||||
Template.lesionTable.helpers({
|
Template.lesionTable.helpers({
|
||||||
'measurement': function() {
|
'measurement': function() {
|
||||||
|
<<<<<<< HEAD
|
||||||
var contentId = Session.get("activeContentId");
|
var contentId = Session.get("activeContentId");
|
||||||
return Measurements.find({contentId: contentId});
|
return Measurements.find({contentId: contentId});
|
||||||
},
|
},
|
||||||
'tabTimepoints': function() {
|
'tabTimepoints': function() {
|
||||||
var contentId = Session.get("activeContentId");
|
var contentId = Session.get("activeContentId");
|
||||||
return TabsTimepoints.find({contentId: contentId});
|
return TabsTimepoints.find({contentId: contentId});
|
||||||
|
=======
|
||||||
|
var contentId = this.contentId;
|
||||||
|
console.log(Measurements.find({contentId: contentId}));
|
||||||
|
return Measurements.find({contentId: contentId});
|
||||||
|
},
|
||||||
|
'timepointNames': function() {
|
||||||
|
var contentId = this.contentId;
|
||||||
|
return Template.instance().timepointNamesDictionary.get(contentId);
|
||||||
|
>>>>>>> Updates to improve reactivity, session storage, logging
|
||||||
},
|
},
|
||||||
'lesionData': function() {
|
'lesionData': function() {
|
||||||
var array = [];
|
var array = [];
|
||||||
@ -21,19 +31,16 @@ Template.lesionTable.helpers({
|
|||||||
});
|
});
|
||||||
|
|
||||||
Template.lesionTable.onRendered(function() {
|
Template.lesionTable.onRendered(function() {
|
||||||
|
var contentId = this.data.contentId;
|
||||||
|
var viewportColumns = ViewerData[contentId].viewportColumns;
|
||||||
|
var viewportRows = ViewerData[contentId].viewportRows;
|
||||||
|
|
||||||
var cols = Template.instance().data.viewportColumns.curValue;
|
var totalViewports = viewportColumns * viewportRows;
|
||||||
var rows = Template.instance().data.viewportRows.curValue;
|
|
||||||
|
|
||||||
var totalViewports = cols * rows;
|
|
||||||
|
|
||||||
var contentId = Session.get('activeContentId');
|
|
||||||
var timepointsArray = [];
|
|
||||||
for(var i=0; i< totalViewports; i++) {
|
for(var i=0; i< totalViewports; i++) {
|
||||||
|
var timepointID = contentId.toString() + i.toString();
|
||||||
var timepointID = contentId.toString()+ i.toString();
|
|
||||||
var timepointName = "Baseline";
|
var timepointName = "Baseline";
|
||||||
if(i > 0) {
|
if (i > 0) {
|
||||||
timepointName = "Follow Up "+i;
|
timepointName = "Follow Up "+i;
|
||||||
}
|
}
|
||||||
var timepointObject = {timepointID: timepointID, timepointName: timepointName};
|
var timepointObject = {timepointID: timepointID, timepointName: timepointName};
|
||||||
@ -43,7 +50,7 @@ Template.lesionTable.onRendered(function() {
|
|||||||
|
|
||||||
// Prevent duplicate data when onRendered is called
|
// Prevent duplicate data when onRendered is called
|
||||||
var tabTimepoint = TabsTimepoints.find({contentId: contentId}).fetch();
|
var tabTimepoint = TabsTimepoints.find({contentId: contentId}).fetch();
|
||||||
if (tabTimepoint != undefined && tabTimepoint.length > 0) {
|
if (tabTimepoint !== undefined && tabTimepoint.length > 0) {
|
||||||
// Update timepoints
|
// Update timepoints
|
||||||
TabsTimepoints.update(
|
TabsTimepoints.update(
|
||||||
{ contentId: contentId},
|
{ contentId: contentId},
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
Template.studyBrowser.helpers({
|
Template.studyBrowser.helpers({
|
||||||
studies : function() {
|
studies : function() {
|
||||||
return this.studies;
|
return Session.get('studies');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -6,8 +6,9 @@
|
|||||||
* @param element
|
* @param element
|
||||||
*/
|
*/
|
||||||
function enablePrefetchOnElement(viewportIndex) {
|
function enablePrefetchOnElement(viewportIndex) {
|
||||||
|
log.info("imageViewerViewport enablePrefetchOnElement");
|
||||||
|
|
||||||
var element = $('.imageViewerViewport').get(viewportIndex);
|
var element = $('.imageViewerViewport').get(viewportIndex);
|
||||||
//console.log('Enabling prefetch on new element');
|
|
||||||
|
|
||||||
// Loop through all viewports and disable stackPrefetch
|
// Loop through all viewports and disable stackPrefetch
|
||||||
$('.imageViewerViewport').each(function() {
|
$('.imageViewerViewport').each(function() {
|
||||||
@ -25,6 +26,8 @@ function enablePrefetchOnElement(viewportIndex) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function displayReferenceLines(viewportIndex) {
|
function displayReferenceLines(viewportIndex) {
|
||||||
|
log.info("imageViewerViewport displayReferenceLines");
|
||||||
|
|
||||||
var element = $('.imageViewerViewport').get(viewportIndex);
|
var element = $('.imageViewerViewport').get(viewportIndex);
|
||||||
|
|
||||||
$('.imageViewerViewport').each(function(index, element) {
|
$('.imageViewerViewport').each(function(index, element) {
|
||||||
@ -49,17 +52,22 @@ function displayReferenceLines(viewportIndex) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function loadSeriesIntoViewport(data) {
|
function loadSeriesIntoViewport(data) {
|
||||||
|
log.info("imageViewerViewport loadSeriesIntoViewport");
|
||||||
|
|
||||||
if (!data.series || !data.element) {
|
if (!data.series || !data.element) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var contentId = $("#viewer").parents('.tab-pane.active').attr('id');
|
var contentId = Session.get('activeContentId');
|
||||||
|
|
||||||
|
|
||||||
var study = data.study;
|
var study = data.study;
|
||||||
var series = data.series;
|
var series = data.series;
|
||||||
var element = data.element;
|
var element = data.element;
|
||||||
var viewportIndex = $(".imageViewerViewport").index(element);
|
var viewportIndex = $(".imageViewerViewport").index(element);
|
||||||
|
|
||||||
|
ViewerData[contentId].loadedSeriesData[viewportIndex] = {};
|
||||||
|
|
||||||
var allEvents = 'CornerstoneToolsMouseDown CornerstoneToolsMouseDownActivate ' +
|
var allEvents = 'CornerstoneToolsMouseDown CornerstoneToolsMouseDownActivate ' +
|
||||||
'CornerstoneToolsMouseClick CornerstoneToolsMouseDrag CornerstoneToolsMouseUp ' +
|
'CornerstoneToolsMouseClick CornerstoneToolsMouseDrag CornerstoneToolsMouseUp ' +
|
||||||
'CornerstoneToolsMouseWheel CornerstoneToolsTap CornerstoneToolsTouchPress ' +
|
'CornerstoneToolsMouseWheel CornerstoneToolsTap CornerstoneToolsTouchPress ' +
|
||||||
@ -115,6 +123,8 @@ function loadSeriesIntoViewport(data) {
|
|||||||
endLoadingHandler(element);
|
endLoadingHandler(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cornerstone.resize(element, true);
|
||||||
|
|
||||||
element.classList.remove('empty');
|
element.classList.remove('empty');
|
||||||
$(element).siblings('.viewportInstructions').hide();
|
$(element).siblings('.viewportInstructions').hide();
|
||||||
$(element).siblings('.imageViewerViewportOverlay').show();
|
$(element).siblings('.imageViewerViewportOverlay').show();
|
||||||
@ -142,9 +152,11 @@ function loadSeriesIntoViewport(data) {
|
|||||||
cornerstoneTools.magnify.enable(element);
|
cornerstoneTools.magnify.enable(element);
|
||||||
|
|
||||||
function onImageRendered(e, eventData) {
|
function onImageRendered(e, eventData) {
|
||||||
|
log.info('imageViewerViewport onImageRendered');
|
||||||
|
|
||||||
Session.set('CornerstoneImageRendered' + viewportIndex, Random.id());
|
Session.set('CornerstoneImageRendered' + viewportIndex, Random.id());
|
||||||
var viewport = cornerstone.getViewport(element);
|
var viewport = cornerstone.getViewport(element);
|
||||||
ViewerData[contentId].viewer.imageViewerLoadedSeriesDictionary[viewportIndex].viewport = viewport;
|
ViewerData[contentId].loadedSeriesData[viewportIndex].viewport = viewport;
|
||||||
Session.set('ViewerData', ViewerData);
|
Session.set('ViewerData', ViewerData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,6 +165,8 @@ function loadSeriesIntoViewport(data) {
|
|||||||
Session.set('CornerstoneImageRendered' + viewportIndex, Random.id());
|
Session.set('CornerstoneImageRendered' + viewportIndex, Random.id());
|
||||||
|
|
||||||
function onNewImage(e, eventData) {
|
function onNewImage(e, eventData) {
|
||||||
|
log.info('imageViewerViewport onNewImage');
|
||||||
|
|
||||||
// Update the templateData with the new imageId
|
// Update the templateData with the new imageId
|
||||||
// This allows the template helpers to update reactively
|
// This allows the template helpers to update reactively
|
||||||
templateData.imageId = eventData.enabledElement.image.imageId;
|
templateData.imageId = eventData.enabledElement.image.imageId;
|
||||||
@ -161,7 +175,7 @@ function loadSeriesIntoViewport(data) {
|
|||||||
var stack = cornerstoneTools.getToolState(element, 'stack');
|
var stack = cornerstoneTools.getToolState(element, 'stack');
|
||||||
if (stack && stack.data.length && stack.data[0].imageIds.length > 1) {
|
if (stack && stack.data.length && stack.data[0].imageIds.length > 1) {
|
||||||
var imageIdIndex = stack.data[0].imageIds.indexOf(templateData.imageId);
|
var imageIdIndex = stack.data[0].imageIds.indexOf(templateData.imageId);
|
||||||
ViewerData[contentId].viewer.imageViewerLoadedSeriesDictionary[viewportIndex].currentImageIdIndex = imageIdIndex;
|
ViewerData[contentId].loadedSeriesData[viewportIndex].currentImageIdIndex = imageIdIndex;
|
||||||
Session.set('ViewerData', ViewerData);
|
Session.set('ViewerData', ViewerData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -170,14 +184,17 @@ function loadSeriesIntoViewport(data) {
|
|||||||
$(element).on('CornerstoneNewImage', onNewImage);
|
$(element).on('CornerstoneNewImage', onNewImage);
|
||||||
|
|
||||||
function sendActivationTrigger(e, eventData) {
|
function sendActivationTrigger(e, eventData) {
|
||||||
var activeViewportIndex = data.activeViewport.curValue;
|
log.info('imageViewerViewport sendActivationTrigger');
|
||||||
|
var activeViewportIndex = Session.get('activeViewport');
|
||||||
var viewportIndex = $(".imageViewerViewport").index(eventData.element);
|
var viewportIndex = $(".imageViewerViewport").index(eventData.element);
|
||||||
if (viewportIndex === activeViewportIndex) {
|
if (viewportIndex === activeViewportIndex) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
eventData.viewportIndex = viewportIndex;
|
eventData.viewportIndex = viewportIndex;
|
||||||
var customEvent = jQuery.Event('ActivateViewport', eventData);
|
var customEvent = $.Event('ActivateViewport', eventData);
|
||||||
customEvent.type = 'ActivateViewport'; // Need to overwrite the type set in the touch tools
|
|
||||||
|
// Need to overwrite the type set in the original event
|
||||||
|
customEvent.type = 'ActivateViewport';
|
||||||
$(e.target).trigger(customEvent, eventData);
|
$(e.target).trigger(customEvent, eventData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,7 +203,7 @@ function loadSeriesIntoViewport(data) {
|
|||||||
|
|
||||||
Session.set('CornerstoneNewImage' + viewportIndex, Random.id());
|
Session.set('CornerstoneNewImage' + viewportIndex, Random.id());
|
||||||
|
|
||||||
OHIF.viewer.imageViewerLoadedSeriesDictionary[viewportIndex] = {
|
OHIF.viewer.loadedSeriesData[viewportIndex] = {
|
||||||
studyInstanceUid: data.studyInstanceUid,
|
studyInstanceUid: data.studyInstanceUid,
|
||||||
seriesInstanceUid: data.seriesInstanceUid,
|
seriesInstanceUid: data.seriesInstanceUid,
|
||||||
currentImageIdIndex: data.currentImageIdIndex,
|
currentImageIdIndex: data.currentImageIdIndex,
|
||||||
@ -206,16 +223,19 @@ function loadSeriesIntoViewport(data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Template.imageViewerViewport.onRendered(function() {
|
Template.imageViewerViewport.onRendered(function() {
|
||||||
var studies = this.data.studies;
|
log.info("imageViewerViewport onRendered");
|
||||||
|
|
||||||
|
var studies = Session.get('studies');
|
||||||
|
var activeViewport = Session.get('activeViewport');
|
||||||
var element = this.find(".imageViewerViewport");
|
var element = this.find(".imageViewerViewport");
|
||||||
|
|
||||||
var data = {
|
var data = {
|
||||||
element: element,
|
element: element,
|
||||||
viewport: this.data.viewport,
|
viewport: this.data.viewport,
|
||||||
currentImageIdIndex: this.data.currentImageIdIndex,
|
currentImageIdIndex: this.data.currentImageIdIndex,
|
||||||
activeViewport: this.data.activeViewport,
|
|
||||||
studyInstanceUid: this.data.studyInstanceUid,
|
studyInstanceUid: this.data.studyInstanceUid,
|
||||||
seriesInstanceUid: this.data.seriesInstanceUid
|
seriesInstanceUid: this.data.seriesInstanceUid,
|
||||||
|
activeViewport: activeViewport
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.data.seriesInstanceUid === undefined || this.data.studyInstanceUid === undefined) {
|
if (this.data.seriesInstanceUid === undefined || this.data.studyInstanceUid === undefined) {
|
||||||
@ -246,18 +266,23 @@ Template.imageViewerViewport.onRendered(function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Template.imageViewerViewport.onDestroyed(function() {
|
Template.imageViewerViewport.onDestroyed(function() {
|
||||||
|
log.info("imageViewerViewport onDestroyed");
|
||||||
|
|
||||||
var element = this.find(".imageViewerViewport");
|
var element = this.find(".imageViewerViewport");
|
||||||
|
|
||||||
|
try {
|
||||||
|
cornerstoneTools.stopClip(element);
|
||||||
|
} catch(error) {
|
||||||
|
}
|
||||||
|
|
||||||
cornerstone.disable(element);
|
cornerstone.disable(element);
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.imageViewerViewport.events({
|
Template.imageViewerViewport.events({
|
||||||
'ActivateViewport .imageViewerViewport': function(e) {
|
'ActivateViewport .imageViewerViewport': function(e) {
|
||||||
if (this.viewportIndex === this.activeViewport.curValue) {
|
log.info("imageViewerViewport ActivateViewport");
|
||||||
return;
|
|
||||||
}
|
Session.set("activeViewport", this.viewportIndex);
|
||||||
Session.set("ActivateViewportIndex", this.viewportIndex);
|
|
||||||
console.log('ActivateViewport index: ' + this.viewportIndex);
|
|
||||||
this.activeViewport.curValue = this.viewportIndex;
|
|
||||||
enablePrefetchOnElement(this.viewportIndex);
|
enablePrefetchOnElement(this.viewportIndex);
|
||||||
displayReferenceLines(this.viewportIndex);
|
displayReferenceLines(this.viewportIndex);
|
||||||
},
|
},
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
{{ #each viewportArray }}
|
{{ #each viewportArray }}
|
||||||
<div class="viewportContainer" style="height:{{height}}%;width:{{width}}%;">
|
<div class="viewportContainer" style="height:{{height}}%;width:{{width}}%;">
|
||||||
<div class="removable">
|
<div class="removable">
|
||||||
{{ >imageViewerViewport viewportIndex=viewportIndex studies=studies activeViewport=activeViewport seriesInstanceUid=seriesInstanceUid studyInstanceUid=studyInstanceUid currentImageIdIndex=currentImageIdIndex viewport=viewport}}
|
{{ >imageViewerViewport viewportIndex=viewportIndex seriesInstanceUid=seriesInstanceUid studyInstanceUid=studyInstanceUid currentImageIdIndex=currentImageIdIndex viewport=viewport}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{ /each }}
|
{{ /each }}
|
||||||
|
|||||||
@ -1,49 +1,44 @@
|
|||||||
Template.imageViewerViewports.helpers({
|
Template.imageViewerViewports.helpers({
|
||||||
height: function() {
|
height: function() {
|
||||||
var viewportRows;
|
var viewportRows = this.viewportRows || 1;
|
||||||
if (!Template.parentData(1).viewportRows) {
|
|
||||||
viewportRows = 1;
|
|
||||||
} else {
|
|
||||||
viewportRows = Template.parentData(1).viewportRows.curValue; //Having issues with .get(), not sure why?
|
|
||||||
}
|
|
||||||
return 100 / viewportRows;
|
return 100 / viewportRows;
|
||||||
},
|
},
|
||||||
width: function() {
|
width: function() {
|
||||||
var viewportColumns;
|
var viewportColumns = this.viewportColumns || 1;
|
||||||
if (!Template.parentData(1).viewportColumns) {
|
|
||||||
viewportColumns = 1;
|
|
||||||
} else {
|
|
||||||
viewportColumns = Template.parentData(1).viewportColumns.curValue; //Having issues with .get(), not sure why?
|
|
||||||
}
|
|
||||||
return 100 / viewportColumns;
|
return 100 / viewportColumns;
|
||||||
},
|
},
|
||||||
viewportArray: function() {
|
viewportArray: function() {
|
||||||
// This is a really annoying thing to have to do, but Meteor
|
log.info("imageViewerViewports viewportArray");
|
||||||
// doesn't want to let me use another type of helper.
|
|
||||||
var viewportRows;
|
var studies = Session.get('studies');
|
||||||
if (!this.viewportRows) {
|
|
||||||
viewportRows = 1;
|
var viewportRows = this.viewportRows || 1;
|
||||||
} else {
|
var viewportColumns = this.viewportColumns || 1;
|
||||||
viewportRows = this.viewportRows.curValue; //Having issues with .get(), not sure why?
|
|
||||||
|
var contentId = this.contentId || $("#viewer").parents(".tab-pane.active").attr('id');
|
||||||
|
if (this.viewportRows && this.viewportColumns) {
|
||||||
|
viewportRows = this.viewportRows || 1;
|
||||||
|
viewportColumns = this.viewportColumns || 1;
|
||||||
|
} else if (ViewerData[contentId].viewportRows && ViewerData[contentId].viewportColumns) {
|
||||||
|
viewportRows = ViewerData[contentId].viewportRows;
|
||||||
|
viewportColumns = ViewerData[contentId].viewportColumns;
|
||||||
}
|
}
|
||||||
|
|
||||||
var viewportColumns;
|
// Update viewerData
|
||||||
if (!this.viewportColumns) {
|
ViewerData[contentId].viewportRows = viewportRows;
|
||||||
viewportColumns = 1;
|
ViewerData[contentId].viewportColumns = viewportColumns;
|
||||||
} else {
|
Session.set("ViewerData", ViewerData);
|
||||||
viewportColumns = this.viewportColumns.curValue; //Having issues with .get(), not sure why?
|
|
||||||
}
|
|
||||||
|
|
||||||
var viewportData;
|
var viewportData;
|
||||||
if (OHIF && OHIF.viewer && !$.isEmptyObject(OHIF.viewer.imageViewerLoadedSeriesDictionary)) {
|
if (!$.isEmptyObject(ViewerData[contentId].loadedSeriesData)) {
|
||||||
viewportData = OHIF.viewer.imageViewerLoadedSeriesDictionary;
|
viewportData = ViewerData[contentId].loadedSeriesData;
|
||||||
}
|
}
|
||||||
|
|
||||||
var hangingProtocol = getHangingProtocol();
|
var hangingProtocol = getHangingProtocol();
|
||||||
var inputData = {
|
var inputData = {
|
||||||
viewportColumns: viewportColumns,
|
viewportColumns: viewportColumns,
|
||||||
viewportRows: viewportRows,
|
viewportRows: viewportRows,
|
||||||
studies: this.studies
|
studies: studies
|
||||||
};
|
};
|
||||||
var hangingProtocolViewportData = hangingProtocol(inputData);
|
var hangingProtocolViewportData = hangingProtocol(inputData);
|
||||||
|
|
||||||
@ -52,8 +47,10 @@ Template.imageViewerViewports.helpers({
|
|||||||
for (var i=0; i < numViewports; ++i) {
|
for (var i=0; i < numViewports; ++i) {
|
||||||
var data = {
|
var data = {
|
||||||
viewportIndex: i,
|
viewportIndex: i,
|
||||||
studies: this.studies,
|
// These two are necessary because otherwise the width and height helpers
|
||||||
activeViewport: this.activeViewport
|
// don't get the right data context. Seems to be related to the "each" loop.
|
||||||
|
viewportColumns: viewportColumns,
|
||||||
|
viewportRows: viewportRows
|
||||||
};
|
};
|
||||||
if (viewportData && viewportData[i]) {
|
if (viewportData && viewportData[i]) {
|
||||||
data.seriesInstanceUid = viewportData[i].seriesInstanceUid;
|
data.seriesInstanceUid = viewportData[i].seriesInstanceUid;
|
||||||
|
|||||||
@ -27,31 +27,18 @@ Template.layoutChooser.events({
|
|||||||
},
|
},
|
||||||
'click .layoutChooser table td': function(evt) {
|
'click .layoutChooser table td': function(evt) {
|
||||||
$('#imageViewerViewports').remove();
|
$('#imageViewerViewports').remove();
|
||||||
var container = $(".viewerMain").get(0);
|
|
||||||
|
|
||||||
var currentCell = $(evt.currentTarget);
|
var currentCell = $(evt.currentTarget);
|
||||||
var rowIndex = currentCell.closest('tr').index();
|
var rowIndex = currentCell.closest('tr').index();
|
||||||
var columnIndex = currentCell.index();
|
var columnIndex = currentCell.index();
|
||||||
|
|
||||||
var data = {};
|
|
||||||
|
|
||||||
// Add 1 because the indices start from zero
|
// Add 1 because the indices start from zero
|
||||||
if (this.viewportRows) {
|
var data = {
|
||||||
this.viewportRows.curValue = rowIndex + 1;
|
viewportRows: rowIndex + 1,
|
||||||
data.viewportRows = this.viewportRows;
|
viewportColumns: columnIndex + 1,
|
||||||
} else {
|
};
|
||||||
data.viewportRows = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.viewportColumns) {
|
var container = $(".viewerMain").get(0);
|
||||||
this.viewportColumns.curValue = columnIndex + 1;
|
|
||||||
data.viewportColumns = this.viewportColumns;
|
|
||||||
} else {
|
|
||||||
data.viewportColumns = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
data.studies = Template.parentData(2).studies;
|
|
||||||
data.activeViewport = Template.parentData(2).activeViewport;
|
|
||||||
UI.renderWithData(Template.imageViewerViewports, data, container);
|
UI.renderWithData(Template.imageViewerViewports, data, container);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1,7 +1,7 @@
|
|||||||
Template.playClipButton.helpers({
|
Template.playClipButton.helpers({
|
||||||
'isPlaying': function() {
|
'isPlaying': function() {
|
||||||
Session.get('UpdateCINE');
|
Session.get('UpdateCINE');
|
||||||
var viewportIndex = this.activeViewport.curValue;
|
var activeViewport = Session.get('activeViewport');
|
||||||
return !!OHIF.viewer.isPlaying[viewportIndex];
|
return !!OHIF.viewer.isPlaying[activeViewport];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -6,11 +6,11 @@
|
|||||||
{{ /each }}
|
{{ /each }}
|
||||||
|
|
||||||
{{ #if includePlayClipButton }}
|
{{ #if includePlayClipButton }}
|
||||||
{{ >playClipButton activeViewport=activeViewport}}
|
{{ >playClipButton }}
|
||||||
{{ /if }}
|
{{ /if }}
|
||||||
|
|
||||||
{{ #if includeLayoutButton }}
|
{{ #if includeLayoutButton }}
|
||||||
{{ >layoutButton viewportRows=viewportRows viewportColumns=viewportColumns}}
|
{{ >layoutButton }}
|
||||||
{{ /if }}
|
{{ /if }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -84,8 +84,8 @@ Template.toolbar.events({
|
|||||||
if (!OHIF.viewer.functionList.hasOwnProperty(command)) {
|
if (!OHIF.viewer.functionList.hasOwnProperty(command)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var viewportIndex = Template.parentData(0).activeViewport.get();
|
var activeViewport = Session.get('activeViewport');
|
||||||
var element = $('.imageViewerViewport').get(viewportIndex);
|
var element = $('.imageViewerViewport').get(activeViewport);
|
||||||
OHIF.viewer.functionList[command](element);
|
OHIF.viewer.functionList[command](element);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -12,7 +12,7 @@ rerenderViewportWithNewSeries = function(element, data) {
|
|||||||
data.viewportIndex = viewportIndex;
|
data.viewportIndex = viewportIndex;
|
||||||
|
|
||||||
// Update the dictionary of loaded series for the specified viewport
|
// Update the dictionary of loaded series for the specified viewport
|
||||||
OHIF.viewer.imageViewerLoadedSeriesDictionary[viewportIndex] = {
|
OHIF.viewer.loadedSeriesData[viewportIndex] = {
|
||||||
seriesInstanceUid: data.seriesInstanceUid,
|
seriesInstanceUid: data.seriesInstanceUid,
|
||||||
studyInstanceUid: data.studyInstanceUid,
|
studyInstanceUid: data.studyInstanceUid,
|
||||||
currentImageIdIndex: 0
|
currentImageIdIndex: 0
|
||||||
|
|||||||
3
Packages/viewerbase/log.js
Normal file
3
Packages/viewerbase/log.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
// Create package logger using loglevel
|
||||||
|
// https://atmospherejs.com/spacejamio/loglevel
|
||||||
|
log = loglevel.createPackageLogger('viewerbase', defaultLevel = 'warn');
|
||||||
@ -11,9 +11,13 @@ Package.onUse(function (api) {
|
|||||||
api.use('jquery');
|
api.use('jquery');
|
||||||
api.use('stylus');
|
api.use('stylus');
|
||||||
|
|
||||||
|
api.use('practicalmeteor:loglevel');
|
||||||
|
|
||||||
// Our custom package
|
// Our custom package
|
||||||
api.use('cornerstone');
|
api.use('cornerstone');
|
||||||
|
|
||||||
|
api.addFiles('log.js', 'client');
|
||||||
|
|
||||||
// ---------- Components ----------
|
// ---------- Components ----------
|
||||||
|
|
||||||
// Basic components
|
// Basic components
|
||||||
|
|||||||
@ -1,8 +1,105 @@
|
|||||||
ViewerData = Session.get('ViewerData') || {};
|
ViewerData = Session.get('ViewerData') || {};
|
||||||
|
StudyMetaData = {};
|
||||||
|
|
||||||
|
getStudyMetadata = function(studyInstanceUid, doneCallback) {
|
||||||
|
log.info('worklistStudy getStudyMetadata');
|
||||||
|
|
||||||
|
if (StudyMetaData.hasOwnProperty(studyInstanceUid) && StudyMetaData[studyInstanceUid]) {
|
||||||
|
var study = StudyMetaData[studyInstanceUid];
|
||||||
|
doneCallback(study);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Meteor.call('GetStudyMetadata', studyInstanceUid, function(error, study) {
|
||||||
|
sortStudy(study);
|
||||||
|
|
||||||
|
StudyMetaData[studyInstanceUid] = study;
|
||||||
|
|
||||||
|
doneCallback(study);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
switchToTab = function(contentId) {
|
||||||
|
log.info("Switching to tab: " + contentId);
|
||||||
|
|
||||||
|
$('.tabTitle a[data-target="#' + contentId + '"]').tab('show');
|
||||||
|
|
||||||
|
$("#viewer").remove();
|
||||||
|
|
||||||
|
if (contentId === 'worklistTab') {
|
||||||
|
document.body.style.overflow = null;
|
||||||
|
document.body.style.height = null;
|
||||||
|
document.body.style.minWidth = null;
|
||||||
|
document.body.style.position = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set active tab
|
||||||
|
Session.set("activeContentId", contentId);
|
||||||
|
|
||||||
|
// Get tab content container
|
||||||
|
var container = $('.tab-content').find("#" + contentId).get(0);
|
||||||
|
if (!container) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var studyInstanceUid = ViewerData[contentId].studyInstanceUid;
|
||||||
|
getStudyMetadata(studyInstanceUid, function(study) {
|
||||||
|
var data = {
|
||||||
|
viewportRows: ViewerData[contentId].viewportRows,
|
||||||
|
viewportColumns: ViewerData[contentId].viewportColumns,
|
||||||
|
contentId: contentId,
|
||||||
|
studies: [study],
|
||||||
|
};
|
||||||
|
|
||||||
|
Session.set('studies', data.studies);
|
||||||
|
|
||||||
|
UI.renderWithData(Template.viewer, data, container);
|
||||||
|
var imageViewer = $("#viewer");
|
||||||
|
if (imageViewer) {
|
||||||
|
document.body.style.overflow = "hidden";
|
||||||
|
document.body.style.height = '100%';
|
||||||
|
document.body.style.width = '100%';
|
||||||
|
document.body.style.minWidth = 0;
|
||||||
|
document.body.style.position = 'fixed'; // Prevent overscroll on mobile devices
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
openNewTab = function(studyInstanceUid) {
|
||||||
|
getStudyMetadata(studyInstanceUid, function(study) {
|
||||||
|
var title = study.seriesList[0].instances[0].patientName;
|
||||||
|
var contentid = generateUUID();
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
title: title,
|
||||||
|
contentid: contentid,
|
||||||
|
};
|
||||||
|
tabs.insert(data);
|
||||||
|
|
||||||
|
ViewerData[contentid] = {
|
||||||
|
title: title,
|
||||||
|
contentid: contentid,
|
||||||
|
studyInstanceUid: studyInstanceUid
|
||||||
|
};
|
||||||
|
switchToTab(contentid);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Template.worklist.onRendered(function() {
|
||||||
|
// If there is a tab set as active in the Session,
|
||||||
|
// switch to that now.
|
||||||
|
var contentId = Session.get("activeContentId");
|
||||||
|
if (contentId) {
|
||||||
|
switchToTab(contentId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
Template.worklist.helpers({
|
Template.worklist.helpers({
|
||||||
'tabs': function() {
|
'tabs': function() {
|
||||||
console.log('Updating tabs');
|
log.info('Updating tabs');
|
||||||
return tabs.find();
|
return tabs.find();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -13,68 +110,3 @@ Template.worklist.events({
|
|||||||
switchToTab(contentId);
|
switchToTab(contentId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
switchToTab = function(contentId) {
|
|
||||||
var data = ViewerData[contentId];
|
|
||||||
|
|
||||||
console.log("Switching to tab: " + contentId);
|
|
||||||
|
|
||||||
// Set active tab
|
|
||||||
Session.set("activeContentId", contentId);
|
|
||||||
|
|
||||||
$('.tabTitle a[data-target="#' + contentId + '"]').tab('show');
|
|
||||||
|
|
||||||
$("#viewer").remove();
|
|
||||||
|
|
||||||
var container = $('.tab-content').find("#" + contentId).get(0);
|
|
||||||
if (!container) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (contentId === 'worklistTab') {
|
|
||||||
console.log('Switching to worklist');
|
|
||||||
document.body.style.overflow = null;
|
|
||||||
document.body.style.height = null;
|
|
||||||
document.body.style.minWidth = null;
|
|
||||||
document.body.style.position = null;
|
|
||||||
} else {
|
|
||||||
UI.renderWithData(Template.viewer, data, container);
|
|
||||||
var imageViewer = $("#viewer");
|
|
||||||
if (imageViewer) {
|
|
||||||
document.body.style.overflow = "hidden";
|
|
||||||
document.body.style.height = '100%';
|
|
||||||
document.body.style.width = '100%';
|
|
||||||
document.body.style.minWidth = 0;
|
|
||||||
document.body.style.position = 'fixed'; // Prevent overscroll on mobile devices
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Template.worklist.onRendered(function() {
|
|
||||||
this.autorun(function() {
|
|
||||||
var data = Session.get('OpenNewTabEvent');
|
|
||||||
|
|
||||||
// If we have no new tab data, stop here
|
|
||||||
// (e.g. if we are rendering the worklist)
|
|
||||||
if (!data) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var contentId = data.contentid;
|
|
||||||
if (ViewerData.hasOwnProperty(contentId)) {
|
|
||||||
console.warn('Contentid already exists?');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the viewer data object
|
|
||||||
ViewerData[contentId] = {
|
|
||||||
contentId: contentId,
|
|
||||||
studies: data.studies,
|
|
||||||
title: data.title
|
|
||||||
};
|
|
||||||
Session.set('ViewerData', ViewerData);
|
|
||||||
|
|
||||||
|
|
||||||
switchToTab(contentId);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,5 +1,5 @@
|
|||||||
Template.worklistStudy.events({
|
Template.worklistStudy.events({
|
||||||
'click': function (){
|
'click': function () {
|
||||||
Router.go('viewer', {_id: this.studyInstanceUid});
|
openNewTab(this.studyInstanceUid);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
3
Packages/worklist/log.js
Normal file
3
Packages/worklist/log.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
// Create package logger using loglevel
|
||||||
|
// https://atmospherejs.com/spacejamio/loglevel
|
||||||
|
log = loglevel.createPackageLogger('worklist', defaultLevel = 'info');
|
||||||
@ -11,6 +11,13 @@ Package.onUse(function (api) {
|
|||||||
api.use('jquery');
|
api.use('jquery');
|
||||||
api.use('stylus');
|
api.use('stylus');
|
||||||
|
|
||||||
|
api.use('practicalmeteor:loglevel');
|
||||||
|
|
||||||
|
// Our custom package
|
||||||
|
api.use('dicomweb');
|
||||||
|
|
||||||
|
api.addFiles('log.js', 'client');
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
api.addFiles('components/worklist.html', 'client');
|
api.addFiles('components/worklist.html', 'client');
|
||||||
api.addFiles('components/worklist.js', 'client');
|
api.addFiles('components/worklist.js', 'client');
|
||||||
@ -37,6 +44,7 @@ Package.onUse(function (api) {
|
|||||||
api.addFiles('lib/generateUUID.js', 'client');
|
api.addFiles('lib/generateUUID.js', 'client');
|
||||||
api.export('generateUUID', 'client');
|
api.export('generateUUID', 'client');
|
||||||
|
|
||||||
|
api.export('openNewTab', 'client');
|
||||||
api.export('switchToTab', 'client');
|
api.export('switchToTab', 'client');
|
||||||
|
|
||||||
api.export('ViewerData', 'client');
|
api.export('ViewerData', 'client');
|
||||||
|
|||||||
14
README.md
14
README.md
@ -1,2 +1,16 @@
|
|||||||
# Viewers
|
# Viewers
|
||||||
This repo contains the OHIF DICOM Viewer and Lesion Trackers, and various shared meteor packages
|
This repo contains the OHIF DICOM Viewer and Lesion Trackers, and various shared meteor packages
|
||||||
|
|
||||||
|
|
||||||
|
### Docker usage
|
||||||
|
#### Temporary data storage
|
||||||
|
docker run --rm -p 4242:4242 -p 8042:8042 jodogne/orthanc-plugins
|
||||||
|
|
||||||
|
#### Persistent data storage
|
||||||
|
1. Create a persistant data volume for Orthanc to use
|
||||||
|
docker create --name sampledata -v /sampledata jodogne/orthanc-plugins
|
||||||
|
|
||||||
|
2. Run Orthanc from Docker with the data volume attached
|
||||||
|
docker run --volumes-from sampledata -p 4242:4242 -p 8042:8042 jodogne/orthanc-plugins
|
||||||
|
|
||||||
|
3. Upload your data and it will be persisted
|
||||||
Loading…
Reference in New Issue
Block a user