diff --git a/LesionTracker/.meteor/packages b/LesionTracker/.meteor/packages
index b9b9c9081..9cdc97fa1 100644
--- a/LesionTracker/.meteor/packages
+++ b/LesionTracker/.meteor/packages
@@ -36,3 +36,4 @@ random
reactive-var
reactive-dict
lesiontracker
+practicalmeteor:loglevel
diff --git a/LesionTracker/.meteor/versions b/LesionTracker/.meteor/versions
index 4a556777f..d00252c84 100644
--- a/LesionTracker/.meteor/versions
+++ b/LesionTracker/.meteor/versions
@@ -16,6 +16,7 @@ caching-compiler@1.0.0
caching-html-compiler@1.0.2
callback-hook@1.0.4
check@1.1.0
+coffeescript@1.0.11
cornerstone@0.0.1
ddp@1.2.2
ddp-client@1.2.1
@@ -67,6 +68,8 @@ npm-bcrypt@0.7.8_2
npm-mongo@1.4.39_1
observe-sequence@1.0.7
ordered-dict@1.0.4
+practicalmeteor:chai@1.9.2_3
+practicalmeteor:loglevel@1.1.0_3
promise@0.5.1
random@1.0.5
rate-limit@1.0.0
diff --git a/LesionTracker/client/components/viewer.html b/LesionTracker/client/components/viewer.html
index 8530698dc..0bc88f89a 100644
--- a/LesionTracker/client/components/viewer.html
+++ b/LesionTracker/client/components/viewer.html
@@ -1,10 +1,10 @@
- {{ >lesionDialog studies=studies activeViewport=activeViewport}}
+ {{ >lesionDialog }}
- {{ >hidingPanel studies=studies activeViewport=activeViewport}}
- {{ >viewerMain studies=studies activeViewport=activeViewport viewportRows=viewportRows viewportColumns=viewportColumns}}
+ {{ >hidingPanel }}
+ {{ >viewerMain }}
- {{ >lesionTable studies=studies activeViewport=activeViewport viewportRows=viewportRows viewportColumns=viewportColumns}}
+ {{ >lesionTable }}
\ No newline at end of file
diff --git a/LesionTracker/client/components/viewer.js b/LesionTracker/client/components/viewer.js
index f72198aa7..a79b498ad 100644
--- a/LesionTracker/client/components/viewer.js
+++ b/LesionTracker/client/components/viewer.js
@@ -1,4 +1,6 @@
function resizeViewports() {
+ log.info("viewer resizeViewports");
+
// Handle resizing of image viewer viewports
// For some reason, this seems to need to be on
// another delay, or the resizing won't work properly
@@ -15,7 +17,8 @@ function resizeViewports() {
}
Template.viewer.onCreated(function() {
- console.log("Image Viewer onCreated");
+ log.info("viewer onCreated");
+
OHIF = {
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;
- // Update the viewer data object
- ViewerData[contentId].viewportColumns = this.data.viewportColumns;
- ViewerData[contentId].viewportRows = this.data.viewportRows;
- ViewerData[contentId].activeViewport = this.data.activeViewport;
- Session.set('ViewerData', ViewerData);
+ if (ViewerData[contentId].loadedSeriesData) {
+ log.info('Reloading previous loadedSeriesData');
+
+ OHIF.viewer.loadedSeriesData = ViewerData[contentId].loadedSeriesData;
- if (ViewerData[contentId].viewer) {
- OHIF.viewer = ViewerData[contentId].viewer;
} else {
- OHIF.viewer.imageViewerLoadedSeriesDictionary = {};
- ViewerData[contentId].viewer = OHIF.viewer;
+ log.info('Setting default ViewerData');
+ 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);
});
Template.viewer.onDestroyed(function() {
+ log.info("onDestroyed");
OHIF.viewer.updateImageSynchronizer.destroy();
});
diff --git a/LesionTracker/client/components/viewerMain/viewerMain.html b/LesionTracker/client/components/viewerMain/viewerMain.html
index e7bdf403f..6bf8bf680 100644
--- a/LesionTracker/client/components/viewerMain/viewerMain.html
+++ b/LesionTracker/client/components/viewerMain/viewerMain.html
@@ -1,6 +1,6 @@
- {{ >toolbar toolbarOptions=toolbarOptions activeViewport=activeViewport viewportRows=viewportRows viewportColumns=viewportColumns}}
- {{ >imageViewerViewports studies=studies activeViewport=activeViewport viewportRows=viewportRows viewportColumns=viewportColumns}}
+ {{ >toolbar toolbarOptions=toolbarOptions }}
+ {{ >imageViewerViewports }}
\ No newline at end of file
diff --git a/LesionTracker/client/components/viewerMain/viewerMain.js b/LesionTracker/client/components/viewerMain/viewerMain.js
index 2062952f5..7db405613 100644
--- a/LesionTracker/client/components/viewerMain/viewerMain.js
+++ b/LesionTracker/client/components/viewerMain/viewerMain.js
@@ -1,7 +1,4 @@
Template.viewerMain.helpers({
- studies : function() {
- return this.studies;
- },
'toolbarOptions': function() {
var toolbarOptions = {};
diff --git a/LesionTracker/client/log.js b/LesionTracker/client/log.js
new file mode 100644
index 000000000..f4e50c3e4
--- /dev/null
+++ b/LesionTracker/client/log.js
@@ -0,0 +1,3 @@
+// Create application logger using loglevel
+// https://atmospherejs.com/spacejamio/loglevel
+log = loglevel.createAppLogger('LesionTracker', defaultLevel = 'info');
diff --git a/LesionTracker/client/route.js b/LesionTracker/client/route.js
deleted file mode 100644
index 2fa8c2777..000000000
--- a/LesionTracker/client/route.js
+++ /dev/null
@@ -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);
- });
- }
-});
\ No newline at end of file
diff --git a/LesionTracker/client/routes.js b/LesionTracker/client/routes.js
new file mode 100644
index 000000000..422eeb95c
--- /dev/null
+++ b/LesionTracker/client/routes.js
@@ -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);
+ }
+});
\ No newline at end of file
diff --git a/OHIFViewer/.meteor/packages b/OHIFViewer/.meteor/packages
index 2dbded030..78786adc7 100644
--- a/OHIFViewer/.meteor/packages
+++ b/OHIFViewer/.meteor/packages
@@ -33,3 +33,4 @@ dicomweb
viewerbase
worklist
reactive-var
+practicalmeteor:loglevel
diff --git a/OHIFViewer/.meteor/versions b/OHIFViewer/.meteor/versions
index 62a4a53a7..86aaf5f24 100644
--- a/OHIFViewer/.meteor/versions
+++ b/OHIFViewer/.meteor/versions
@@ -15,6 +15,7 @@ caching-compiler@1.0.0
caching-html-compiler@1.0.2
callback-hook@1.0.4
check@1.1.0
+coffeescript@1.0.11
cornerstone@0.0.1
ddp@1.2.2
ddp-client@1.2.1
@@ -64,6 +65,8 @@ npm-bcrypt@0.7.8_2
npm-mongo@1.4.39_1
observe-sequence@1.0.7
ordered-dict@1.0.4
+practicalmeteor:chai@1.9.2_3
+practicalmeteor:loglevel@1.1.0_3
promise@0.5.1
random@1.0.5
rate-limit@1.0.0
diff --git a/OHIFViewer/client/components/viewer/viewer.html b/OHIFViewer/client/components/viewer/viewer.html
index 173d21833..6e7b46e82 100644
--- a/OHIFViewer/client/components/viewer/viewer.html
+++ b/OHIFViewer/client/components/viewer/viewer.html
@@ -1,6 +1,9 @@
- {{> studyBrowser studies=studies activeViewport=activeViewport}}
- {{> viewerMain studies=studies activeViewport=activeViewport viewportRows=viewportRows viewportColumns=viewportColumns}}
+ {{> studyBrowser }}
+
+ {{ > toolbar }}
+ {{ > imageViewerViewports }}
+
\ No newline at end of file
diff --git a/OHIFViewer/client/components/viewer/viewer.js b/OHIFViewer/client/components/viewer/viewer.js
index ae0c0b139..058215c73 100644
--- a/OHIFViewer/client/components/viewer/viewer.js
+++ b/OHIFViewer/client/components/viewer/viewer.js
@@ -1,4 +1,6 @@
function resizeViewports() {
+ log.info("viewer resizeViewports");
+
// Handle resizing of image viewer viewports
// For some reason, this seems to need to be on
// another delay, or the resizing won't work properly
@@ -15,7 +17,8 @@ function resizeViewports() {
}
Template.viewer.onCreated(function() {
- console.log("Image Viewer onCreated");
+ log.info("viewer onCreated");
+
OHIF = {
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;
- // Update the viewer data object
- ViewerData[contentId].viewportColumns = this.data.viewportColumns;
- ViewerData[contentId].viewportRows = this.data.viewportRows;
- ViewerData[contentId].activeViewport = this.data.activeViewport;
- Session.set('ViewerData', ViewerData);
+ if (ViewerData[contentId].loadedSeriesData) {
+ log.info('Reloading previous loadedSeriesData');
+
+ OHIF.viewer.loadedSeriesData = ViewerData[contentId].loadedSeriesData;
- if (ViewerData[contentId].viewer) {
- OHIF.viewer = ViewerData[contentId].viewer;
} else {
- OHIF.viewer.imageViewerLoadedSeriesDictionary = {};
- ViewerData[contentId].viewer = OHIF.viewer;
+ log.info('Setting default ViewerData');
+ 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);
});
Template.viewer.onDestroyed(function() {
+ log.info("onDestroyed");
OHIF.viewer.updateImageSynchronizer.destroy();
});
diff --git a/OHIFViewer/client/components/viewer/viewer.styl b/OHIFViewer/client/components/viewer/viewer.styl
index 854b359f5..4a1c1f8df 100644
--- a/OHIFViewer/client/components/viewer/viewer.styl
+++ b/OHIFViewer/client/components/viewer/viewer.styl
@@ -12,4 +12,10 @@
user-select: none
.studyBrowser
- width: auto
\ No newline at end of file
+ width: auto
+
+.viewerMain
+ float: left
+ background-color: gray
+ height: 100%
+ width: calc(100% - 120px)
\ No newline at end of file
diff --git a/OHIFViewer/client/components/viewer/viewerMain/viewerMain.html b/OHIFViewer/client/components/viewer/viewerMain/viewerMain.html
deleted file mode 100644
index eb39a71c8..000000000
--- a/OHIFViewer/client/components/viewer/viewerMain/viewerMain.html
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
- {{ > toolbar activeViewport=activeViewport viewportRows=viewportRows viewportColumns=viewportColumns}}
- {{ > imageViewerViewports studies=studies activeViewport=activeViewport viewportRows=viewportRows viewportColumns=viewportColumns}}
-
-
\ No newline at end of file
diff --git a/OHIFViewer/client/components/viewer/viewerMain/viewerMain.js b/OHIFViewer/client/components/viewer/viewerMain/viewerMain.js
deleted file mode 100644
index 260bf1cc9..000000000
--- a/OHIFViewer/client/components/viewer/viewerMain/viewerMain.js
+++ /dev/null
@@ -1,5 +0,0 @@
-Template.viewerMain.helpers({
- studies : function() {
- return this.studies;
- }
-});
\ No newline at end of file
diff --git a/OHIFViewer/client/components/viewer/viewerMain/viewerMain.styl b/OHIFViewer/client/components/viewer/viewerMain/viewerMain.styl
deleted file mode 100644
index 7b269b4cd..000000000
--- a/OHIFViewer/client/components/viewer/viewerMain/viewerMain.styl
+++ /dev/null
@@ -1,5 +0,0 @@
-.viewerMain
- float: left
- background-color: gray
- height: 100%
- width: calc(100% - 120px)
\ No newline at end of file
diff --git a/OHIFViewer/client/log.js b/OHIFViewer/client/log.js
new file mode 100644
index 000000000..1f567f0c5
--- /dev/null
+++ b/OHIFViewer/client/log.js
@@ -0,0 +1,3 @@
+// Create application logger using loglevel
+// https://atmospherejs.com/spacejamio/loglevel
+log = loglevel.createAppLogger('OHIFViewer', defaultLevel = 'info');
diff --git a/OHIFViewer/client/routes.js b/OHIFViewer/client/routes.js
index 84ae25bfe..422eeb95c 100644
--- a/OHIFViewer/client/routes.js
+++ b/OHIFViewer/client/routes.js
@@ -1,49 +1,45 @@
-Router.configure({
- layoutTemplate: 'layout',
- //loadingTemplate: '',
- notFoundTemplate: 'notFound'
-});
-
-Router.route('/', function () {
- this.render('worklist', {});
-});
-
tabs = new Meteor.Collection(null);
Session.setDefault('ViewerData', {});
-Session.setDefault('ViewerDataUpdated', Random.id());
+// 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,
+ 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() {
- var self = this;
+ log.info('Router GetStudyMetadata');
- Meteor.call('GetStudyMetadata', this.params._id, function(error, study) {
- sortStudy(study);
+ 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;
+ }
- 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);
- });
+ this.render('worklist');
+ openNewTab(studyInstanceUid);
}
});
\ No newline at end of file
diff --git a/Packages/cornerstone/client/cornerstone.js b/Packages/cornerstone/client/cornerstone.js
index b68821d71..f2cca6c2d 100644
--- a/Packages/cornerstone/client/cornerstone.js
+++ b/Packages/cornerstone/client/cornerstone.js
@@ -2148,7 +2148,7 @@ if(typeof cornerstone === 'undefined'){
function initShaders() {
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 ];
shader.attributes = {};
shader.uniforms = {};
@@ -2168,13 +2168,13 @@ if(typeof cornerstone === 'undefined'){
function initRenderer() {
if (cornerstone.webGL.isWebGLInitialized === true) {
- console.log("WEBGL Renderer already initialized");
+ //console.log("WEBGL Renderer already initialized");
return;
}
if ( initWebGL( renderCanvas ) ) {
initBuffers();
initShaders();
- console.log("WEBGL Renderer initialized!");
+ //console.log("WEBGL Renderer initialized!");
cornerstone.webGL.isWebGLInitialized = true;
}
}
diff --git a/Packages/lesiontracker/components/lesionTable/lesionTable.js b/Packages/lesiontracker/components/lesionTable/lesionTable.js
index a219fdcb4..5a1d72bce 100644
--- a/Packages/lesiontracker/components/lesionTable/lesionTable.js
+++ b/Packages/lesiontracker/components/lesionTable/lesionTable.js
@@ -3,12 +3,22 @@ TabsTimepoints = new Meteor.Collection(null);
Template.lesionTable.helpers({
'measurement': function() {
+<<<<<<< HEAD
var contentId = Session.get("activeContentId");
return Measurements.find({contentId: contentId});
},
'tabTimepoints': function() {
var contentId = Session.get("activeContentId");
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() {
var array = [];
@@ -21,19 +31,16 @@ Template.lesionTable.helpers({
});
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 rows = Template.instance().data.viewportRows.curValue;
-
- var totalViewports = cols * rows;
-
- var contentId = Session.get('activeContentId');
- var timepointsArray = [];
+ var totalViewports = viewportColumns * viewportRows;
+
for(var i=0; i< totalViewports; i++) {
-
- var timepointID = contentId.toString()+ i.toString();
+ var timepointID = contentId.toString() + i.toString();
var timepointName = "Baseline";
- if(i > 0) {
+ if (i > 0) {
timepointName = "Follow Up "+i;
}
var timepointObject = {timepointID: timepointID, timepointName: timepointName};
@@ -43,7 +50,7 @@ Template.lesionTable.onRendered(function() {
// Prevent duplicate data when onRendered is called
var tabTimepoint = TabsTimepoints.find({contentId: contentId}).fetch();
- if (tabTimepoint != undefined && tabTimepoint.length > 0) {
+ if (tabTimepoint !== undefined && tabTimepoint.length > 0) {
// Update timepoints
TabsTimepoints.update(
{ contentId: contentId},
diff --git a/Packages/viewerbase/components/studyBrowser/studyBrowser/studyBrowser.js b/Packages/viewerbase/components/studyBrowser/studyBrowser/studyBrowser.js
index 512dd6076..2fcac4d84 100644
--- a/Packages/viewerbase/components/studyBrowser/studyBrowser/studyBrowser.js
+++ b/Packages/viewerbase/components/studyBrowser/studyBrowser/studyBrowser.js
@@ -1,5 +1,5 @@
Template.studyBrowser.helpers({
studies : function() {
- return this.studies;
+ return Session.get('studies');
}
});
\ No newline at end of file
diff --git a/Packages/viewerbase/components/viewer/imageViewerViewport/imageViewerViewport.js b/Packages/viewerbase/components/viewer/imageViewerViewport/imageViewerViewport.js
index cc8653e6d..f612b6cf2 100644
--- a/Packages/viewerbase/components/viewer/imageViewerViewport/imageViewerViewport.js
+++ b/Packages/viewerbase/components/viewer/imageViewerViewport/imageViewerViewport.js
@@ -6,8 +6,9 @@
* @param element
*/
function enablePrefetchOnElement(viewportIndex) {
+ log.info("imageViewerViewport enablePrefetchOnElement");
+
var element = $('.imageViewerViewport').get(viewportIndex);
- //console.log('Enabling prefetch on new element');
// Loop through all viewports and disable stackPrefetch
$('.imageViewerViewport').each(function() {
@@ -25,6 +26,8 @@ function enablePrefetchOnElement(viewportIndex) {
}
function displayReferenceLines(viewportIndex) {
+ log.info("imageViewerViewport displayReferenceLines");
+
var element = $('.imageViewerViewport').get(viewportIndex);
$('.imageViewerViewport').each(function(index, element) {
@@ -49,17 +52,22 @@ function displayReferenceLines(viewportIndex) {
}
function loadSeriesIntoViewport(data) {
+ log.info("imageViewerViewport loadSeriesIntoViewport");
+
if (!data.series || !data.element) {
return;
}
- var contentId = $("#viewer").parents('.tab-pane.active').attr('id');
+ var contentId = Session.get('activeContentId');
+
var study = data.study;
var series = data.series;
var element = data.element;
var viewportIndex = $(".imageViewerViewport").index(element);
+ ViewerData[contentId].loadedSeriesData[viewportIndex] = {};
+
var allEvents = 'CornerstoneToolsMouseDown CornerstoneToolsMouseDownActivate ' +
'CornerstoneToolsMouseClick CornerstoneToolsMouseDrag CornerstoneToolsMouseUp ' +
'CornerstoneToolsMouseWheel CornerstoneToolsTap CornerstoneToolsTouchPress ' +
@@ -115,6 +123,8 @@ function loadSeriesIntoViewport(data) {
endLoadingHandler(element);
}
+ cornerstone.resize(element, true);
+
element.classList.remove('empty');
$(element).siblings('.viewportInstructions').hide();
$(element).siblings('.imageViewerViewportOverlay').show();
@@ -142,9 +152,11 @@ function loadSeriesIntoViewport(data) {
cornerstoneTools.magnify.enable(element);
function onImageRendered(e, eventData) {
+ log.info('imageViewerViewport onImageRendered');
+
Session.set('CornerstoneImageRendered' + viewportIndex, Random.id());
var viewport = cornerstone.getViewport(element);
- ViewerData[contentId].viewer.imageViewerLoadedSeriesDictionary[viewportIndex].viewport = viewport;
+ ViewerData[contentId].loadedSeriesData[viewportIndex].viewport = viewport;
Session.set('ViewerData', ViewerData);
}
@@ -153,6 +165,8 @@ function loadSeriesIntoViewport(data) {
Session.set('CornerstoneImageRendered' + viewportIndex, Random.id());
function onNewImage(e, eventData) {
+ log.info('imageViewerViewport onNewImage');
+
// Update the templateData with the new imageId
// This allows the template helpers to update reactively
templateData.imageId = eventData.enabledElement.image.imageId;
@@ -161,7 +175,7 @@ function loadSeriesIntoViewport(data) {
var stack = cornerstoneTools.getToolState(element, 'stack');
if (stack && stack.data.length && stack.data[0].imageIds.length > 1) {
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);
}
}
@@ -170,14 +184,17 @@ function loadSeriesIntoViewport(data) {
$(element).on('CornerstoneNewImage', onNewImage);
function sendActivationTrigger(e, eventData) {
- var activeViewportIndex = data.activeViewport.curValue;
+ log.info('imageViewerViewport sendActivationTrigger');
+ var activeViewportIndex = Session.get('activeViewport');
var viewportIndex = $(".imageViewerViewport").index(eventData.element);
if (viewportIndex === activeViewportIndex) {
return;
}
eventData.viewportIndex = viewportIndex;
- var customEvent = jQuery.Event('ActivateViewport', eventData);
- customEvent.type = 'ActivateViewport'; // Need to overwrite the type set in the touch tools
+ var customEvent = $.Event('ActivateViewport', eventData);
+
+ // Need to overwrite the type set in the original event
+ customEvent.type = 'ActivateViewport';
$(e.target).trigger(customEvent, eventData);
}
@@ -186,7 +203,7 @@ function loadSeriesIntoViewport(data) {
Session.set('CornerstoneNewImage' + viewportIndex, Random.id());
- OHIF.viewer.imageViewerLoadedSeriesDictionary[viewportIndex] = {
+ OHIF.viewer.loadedSeriesData[viewportIndex] = {
studyInstanceUid: data.studyInstanceUid,
seriesInstanceUid: data.seriesInstanceUid,
currentImageIdIndex: data.currentImageIdIndex,
@@ -206,16 +223,19 @@ function loadSeriesIntoViewport(data) {
}
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 data = {
element: element,
viewport: this.data.viewport,
currentImageIdIndex: this.data.currentImageIdIndex,
- activeViewport: this.data.activeViewport,
studyInstanceUid: this.data.studyInstanceUid,
- seriesInstanceUid: this.data.seriesInstanceUid
+ seriesInstanceUid: this.data.seriesInstanceUid,
+ activeViewport: activeViewport
};
if (this.data.seriesInstanceUid === undefined || this.data.studyInstanceUid === undefined) {
@@ -246,18 +266,23 @@ Template.imageViewerViewport.onRendered(function() {
});
Template.imageViewerViewport.onDestroyed(function() {
+ log.info("imageViewerViewport onDestroyed");
+
var element = this.find(".imageViewerViewport");
+
+ try {
+ cornerstoneTools.stopClip(element);
+ } catch(error) {
+ }
+
cornerstone.disable(element);
});
Template.imageViewerViewport.events({
'ActivateViewport .imageViewerViewport': function(e) {
- if (this.viewportIndex === this.activeViewport.curValue) {
- return;
- }
- Session.set("ActivateViewportIndex", this.viewportIndex);
- console.log('ActivateViewport index: ' + this.viewportIndex);
- this.activeViewport.curValue = this.viewportIndex;
+ log.info("imageViewerViewport ActivateViewport");
+
+ Session.set("activeViewport", this.viewportIndex);
enablePrefetchOnElement(this.viewportIndex);
displayReferenceLines(this.viewportIndex);
},
diff --git a/Packages/viewerbase/components/viewer/imageViewerViewports/imageViewerViewports.html b/Packages/viewerbase/components/viewer/imageViewerViewports/imageViewerViewports.html
index aced504b7..3a22cc13d 100644
--- a/Packages/viewerbase/components/viewer/imageViewerViewports/imageViewerViewports.html
+++ b/Packages/viewerbase/components/viewer/imageViewerViewports/imageViewerViewports.html
@@ -3,7 +3,7 @@
{{ #each viewportArray }}
- {{ >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}}
{{ /each }}
diff --git a/Packages/viewerbase/components/viewer/imageViewerViewports/imageViewerViewports.js b/Packages/viewerbase/components/viewer/imageViewerViewports/imageViewerViewports.js
index 1cf4ec99b..9b52aee3e 100644
--- a/Packages/viewerbase/components/viewer/imageViewerViewports/imageViewerViewports.js
+++ b/Packages/viewerbase/components/viewer/imageViewerViewports/imageViewerViewports.js
@@ -1,49 +1,44 @@
Template.imageViewerViewports.helpers({
height: function() {
- var viewportRows;
- if (!Template.parentData(1).viewportRows) {
- viewportRows = 1;
- } else {
- viewportRows = Template.parentData(1).viewportRows.curValue; //Having issues with .get(), not sure why?
- }
+ var viewportRows = this.viewportRows || 1;
return 100 / viewportRows;
},
width: function() {
- var viewportColumns;
- if (!Template.parentData(1).viewportColumns) {
- viewportColumns = 1;
- } else {
- viewportColumns = Template.parentData(1).viewportColumns.curValue; //Having issues with .get(), not sure why?
- }
+ var viewportColumns = this.viewportColumns || 1;
return 100 / viewportColumns;
},
viewportArray: function() {
- // This is a really annoying thing to have to do, but Meteor
- // doesn't want to let me use another type of helper.
- var viewportRows;
- if (!this.viewportRows) {
- viewportRows = 1;
- } else {
- viewportRows = this.viewportRows.curValue; //Having issues with .get(), not sure why?
+ log.info("imageViewerViewports viewportArray");
+
+ var studies = Session.get('studies');
+
+ var viewportRows = this.viewportRows || 1;
+ var viewportColumns = this.viewportColumns || 1;
+
+ 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;
- if (!this.viewportColumns) {
- viewportColumns = 1;
- } else {
- viewportColumns = this.viewportColumns.curValue; //Having issues with .get(), not sure why?
- }
-
+ // Update viewerData
+ ViewerData[contentId].viewportRows = viewportRows;
+ ViewerData[contentId].viewportColumns = viewportColumns;
+ Session.set("ViewerData", ViewerData);
+
var viewportData;
- if (OHIF && OHIF.viewer && !$.isEmptyObject(OHIF.viewer.imageViewerLoadedSeriesDictionary)) {
- viewportData = OHIF.viewer.imageViewerLoadedSeriesDictionary;
+ if (!$.isEmptyObject(ViewerData[contentId].loadedSeriesData)) {
+ viewportData = ViewerData[contentId].loadedSeriesData;
}
var hangingProtocol = getHangingProtocol();
var inputData = {
viewportColumns: viewportColumns,
viewportRows: viewportRows,
- studies: this.studies
+ studies: studies
};
var hangingProtocolViewportData = hangingProtocol(inputData);
@@ -52,8 +47,10 @@ Template.imageViewerViewports.helpers({
for (var i=0; i < numViewports; ++i) {
var data = {
viewportIndex: i,
- studies: this.studies,
- activeViewport: this.activeViewport
+ // These two are necessary because otherwise the width and height helpers
+ // don't get the right data context. Seems to be related to the "each" loop.
+ viewportColumns: viewportColumns,
+ viewportRows: viewportRows
};
if (viewportData && viewportData[i]) {
data.seriesInstanceUid = viewportData[i].seriesInstanceUid;
diff --git a/Packages/viewerbase/components/viewer/layoutChooser/layoutChooser.js b/Packages/viewerbase/components/viewer/layoutChooser/layoutChooser.js
index 4d0cfac35..84e3ee81d 100644
--- a/Packages/viewerbase/components/viewer/layoutChooser/layoutChooser.js
+++ b/Packages/viewerbase/components/viewer/layoutChooser/layoutChooser.js
@@ -27,31 +27,18 @@ Template.layoutChooser.events({
},
'click .layoutChooser table td': function(evt) {
$('#imageViewerViewports').remove();
- var container = $(".viewerMain").get(0);
var currentCell = $(evt.currentTarget);
var rowIndex = currentCell.closest('tr').index();
var columnIndex = currentCell.index();
- var data = {};
-
// Add 1 because the indices start from zero
- if (this.viewportRows) {
- this.viewportRows.curValue = rowIndex + 1;
- data.viewportRows = this.viewportRows;
- } else {
- data.viewportRows = 1;
- }
-
- if (this.viewportColumns) {
- 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;
+ var data = {
+ viewportRows: rowIndex + 1,
+ viewportColumns: columnIndex + 1,
+ };
+
+ var container = $(".viewerMain").get(0);
UI.renderWithData(Template.imageViewerViewports, data, container);
}
});
\ No newline at end of file
diff --git a/Packages/viewerbase/components/viewer/playClipButton/playClipButton.js b/Packages/viewerbase/components/viewer/playClipButton/playClipButton.js
index 75d8e7947..ec35a6d47 100644
--- a/Packages/viewerbase/components/viewer/playClipButton/playClipButton.js
+++ b/Packages/viewerbase/components/viewer/playClipButton/playClipButton.js
@@ -1,7 +1,7 @@
Template.playClipButton.helpers({
'isPlaying': function() {
Session.get('UpdateCINE');
- var viewportIndex = this.activeViewport.curValue;
- return !!OHIF.viewer.isPlaying[viewportIndex];
+ var activeViewport = Session.get('activeViewport');
+ return !!OHIF.viewer.isPlaying[activeViewport];
}
});
\ No newline at end of file
diff --git a/Packages/viewerbase/components/viewer/toolbar/toolbar.html b/Packages/viewerbase/components/viewer/toolbar/toolbar.html
index 12c4ac125..b4616916a 100644
--- a/Packages/viewerbase/components/viewer/toolbar/toolbar.html
+++ b/Packages/viewerbase/components/viewer/toolbar/toolbar.html
@@ -6,11 +6,11 @@
{{ /each }}
{{ #if includePlayClipButton }}
- {{ >playClipButton activeViewport=activeViewport}}
+ {{ >playClipButton }}
{{ /if }}
{{ #if includeLayoutButton }}
- {{ >layoutButton viewportRows=viewportRows viewportColumns=viewportColumns}}
+ {{ >layoutButton }}
{{ /if }}
diff --git a/Packages/viewerbase/components/viewer/toolbar/toolbar.js b/Packages/viewerbase/components/viewer/toolbar/toolbar.js
index 77799e35e..b43711c81 100644
--- a/Packages/viewerbase/components/viewer/toolbar/toolbar.js
+++ b/Packages/viewerbase/components/viewer/toolbar/toolbar.js
@@ -84,8 +84,8 @@ Template.toolbar.events({
if (!OHIF.viewer.functionList.hasOwnProperty(command)) {
return;
}
- var viewportIndex = Template.parentData(0).activeViewport.get();
- var element = $('.imageViewerViewport').get(viewportIndex);
+ var activeViewport = Session.get('activeViewport');
+ var element = $('.imageViewerViewport').get(activeViewport);
OHIF.viewer.functionList[command](element);
}
});
diff --git a/Packages/viewerbase/lib/rerenderViewportWithNewSeries.js b/Packages/viewerbase/lib/rerenderViewportWithNewSeries.js
index a8dae13e9..35c6f3f16 100644
--- a/Packages/viewerbase/lib/rerenderViewportWithNewSeries.js
+++ b/Packages/viewerbase/lib/rerenderViewportWithNewSeries.js
@@ -12,7 +12,7 @@ rerenderViewportWithNewSeries = function(element, data) {
data.viewportIndex = viewportIndex;
// Update the dictionary of loaded series for the specified viewport
- OHIF.viewer.imageViewerLoadedSeriesDictionary[viewportIndex] = {
+ OHIF.viewer.loadedSeriesData[viewportIndex] = {
seriesInstanceUid: data.seriesInstanceUid,
studyInstanceUid: data.studyInstanceUid,
currentImageIdIndex: 0
diff --git a/Packages/viewerbase/log.js b/Packages/viewerbase/log.js
new file mode 100644
index 000000000..e188235f2
--- /dev/null
+++ b/Packages/viewerbase/log.js
@@ -0,0 +1,3 @@
+// Create package logger using loglevel
+// https://atmospherejs.com/spacejamio/loglevel
+log = loglevel.createPackageLogger('viewerbase', defaultLevel = 'warn');
\ No newline at end of file
diff --git a/Packages/viewerbase/package.js b/Packages/viewerbase/package.js
index 15f3418a4..52cdca459 100644
--- a/Packages/viewerbase/package.js
+++ b/Packages/viewerbase/package.js
@@ -11,9 +11,13 @@ Package.onUse(function (api) {
api.use('jquery');
api.use('stylus');
+ api.use('practicalmeteor:loglevel');
+
// Our custom package
api.use('cornerstone');
+ api.addFiles('log.js', 'client');
+
// ---------- Components ----------
// Basic components
diff --git a/Packages/worklist/components/worklist.js b/Packages/worklist/components/worklist.js
index 086f7bd72..acee1a9e7 100644
--- a/Packages/worklist/components/worklist.js
+++ b/Packages/worklist/components/worklist.js
@@ -1,43 +1,59 @@
ViewerData = Session.get('ViewerData') || {};
+StudyMetaData = {};
-Template.worklist.helpers({
- 'tabs': function() {
- console.log('Updating tabs');
- return tabs.find();
- }
-});
+getStudyMetadata = function(studyInstanceUid, doneCallback) {
+ log.info('worklistStudy getStudyMetadata');
-Template.worklist.events({
- 'click a[data-toggle="tab"]': function(e) {
- var contentId = $(e.currentTarget).data('target').replace("#", "");
- switchToTab(contentId);
+ 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) {
- var data = ViewerData[contentId];
-
- console.log("Switching to tab: " + contentId);
-
- // Set active tab
- Session.set("activeContentId", contentId);
+ log.info("Switching to tab: " + 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 {
+ 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) {
@@ -47,34 +63,50 @@ switchToTab = function(contentId) {
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() {
- 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);
-
-
+ // 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({
+ 'tabs': function() {
+ log.info('Updating tabs');
+ return tabs.find();
+ }
+});
+
+Template.worklist.events({
+ 'click a[data-toggle="tab"]': function(e) {
+ var contentId = $(e.currentTarget).data('target').replace("#", "");
+ switchToTab(contentId);
+ }
});
\ No newline at end of file
diff --git a/Packages/worklist/components/worklistStudy/worklistStudy.js b/Packages/worklist/components/worklistStudy/worklistStudy.js
index 389460128..f02950b9b 100644
--- a/Packages/worklist/components/worklistStudy/worklistStudy.js
+++ b/Packages/worklist/components/worklistStudy/worklistStudy.js
@@ -1,5 +1,5 @@
Template.worklistStudy.events({
- 'click': function (){
- Router.go('viewer', {_id: this.studyInstanceUid});
+ 'click': function () {
+ openNewTab(this.studyInstanceUid);
}
});
\ No newline at end of file
diff --git a/Packages/worklist/log.js b/Packages/worklist/log.js
new file mode 100644
index 000000000..3496daf76
--- /dev/null
+++ b/Packages/worklist/log.js
@@ -0,0 +1,3 @@
+// Create package logger using loglevel
+// https://atmospherejs.com/spacejamio/loglevel
+log = loglevel.createPackageLogger('worklist', defaultLevel = 'info');
\ No newline at end of file
diff --git a/Packages/worklist/package.js b/Packages/worklist/package.js
index 6414183dd..eb3c02907 100644
--- a/Packages/worklist/package.js
+++ b/Packages/worklist/package.js
@@ -11,6 +11,13 @@ Package.onUse(function (api) {
api.use('jquery');
api.use('stylus');
+ api.use('practicalmeteor:loglevel');
+
+ // Our custom package
+ api.use('dicomweb');
+
+ api.addFiles('log.js', 'client');
+
// Components
api.addFiles('components/worklist.html', 'client');
api.addFiles('components/worklist.js', 'client');
@@ -37,6 +44,7 @@ Package.onUse(function (api) {
api.addFiles('lib/generateUUID.js', 'client');
api.export('generateUUID', 'client');
+ api.export('openNewTab', 'client');
api.export('switchToTab', 'client');
api.export('ViewerData', 'client');
diff --git a/README.md b/README.md
index 3dfadfb50..011864000 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,16 @@
# Viewers
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
\ No newline at end of file