Linked study date to viewports in measurement grid
This commit is contained in:
parent
aec9ec8f8b
commit
27566c3865
@ -8,9 +8,15 @@ function getLesionLocationCallback(measurementData, eventData, doneCallback) {
|
|||||||
// Find the select option box
|
// Find the select option box
|
||||||
var selector = lesionDialog.find("select#selectLesionLocation");
|
var selector = lesionDialog.find("select#selectLesionLocation");
|
||||||
|
|
||||||
// Get the current element's timepointID
|
// Get the current element's timepointID from the study date metadata
|
||||||
// TODO: Change this when we are no longer storing timepointID in the viewport element DOM data
|
var element = eventData.element;
|
||||||
measurementData.timepointID = $(eventData.element).data('timepointID');
|
var enabledElement = cornerstone.getEnabledElement(element);
|
||||||
|
var study = cornerstoneTools.metaData.get('study', enabledElement.image.imageId);
|
||||||
|
var timepoint = Timepoints.findOne({timepointName: study.date});
|
||||||
|
if (!timepoint) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
measurementData.timepointID = timepoint.timepointID;
|
||||||
|
|
||||||
// Get a lesion number for this lesion, depending on whether or not the same lesion previously
|
// Get a lesion number for this lesion, depending on whether or not the same lesion previously
|
||||||
// exists at a different timepoint
|
// exists at a different timepoint
|
||||||
|
|||||||
@ -55,30 +55,27 @@ function updateLesions(e) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Template.lesionTable.onRendered(function() {
|
Template.lesionTable.onRendered(function() {
|
||||||
// For the moment we will associate the timepoint
|
// Observe ViewerStudies Collection Changes
|
||||||
// with the viewport element by storing the timepointID
|
// Note: This may not be the best place for this
|
||||||
// inside the element's DOM data. This is temporary.
|
ViewerStudies.find().observe({
|
||||||
$(".imageViewerViewport").each(function(index, element) {
|
added: function(study) {
|
||||||
var timepointID = uuid.v4();
|
log.info('ViewerStudies added to');
|
||||||
|
var timepointID = uuid.v4();
|
||||||
|
|
||||||
var timepointName = "Baseline";
|
var timepoint = Timepoints.findOne({timepointName: study.studyDate});
|
||||||
if (index > 0) {
|
if (timepoint) {
|
||||||
timepointName = "Current"; //"Follow Up "+i;
|
log.warn("A timepoint with that study date already exists!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Timepoints.insert({
|
||||||
|
timepointID: timepointID,
|
||||||
|
timepointName: study.studyDate
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// FUTURE = On load series data into viewport, create a new timepoint
|
|
||||||
// unless it already exists
|
|
||||||
Timepoints.insert({
|
|
||||||
timepointID: timepointID,
|
|
||||||
timepointName: timepointName
|
|
||||||
});
|
|
||||||
|
|
||||||
$(element).data('timepointID', timepointID);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
Template.lesionTable.helpers({
|
Template.lesionTable.helpers({
|
||||||
'measurement': function() {
|
'measurement': function() {
|
||||||
return Measurements.find();
|
return Measurements.find();
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
<template name="lesionTableTimepointHeader">
|
<template name="lesionTableTimepointHeader">
|
||||||
<th>{{timepointName}}</th>
|
<th>{{formatDA timepointName "MM/DD/YYYY"}}</th>
|
||||||
</template>
|
</template>
|
||||||
@ -1,12 +0,0 @@
|
|||||||
.studyDateList {
|
|
||||||
margin: 0px auto;
|
|
||||||
text-align: left;
|
|
||||||
width: 100%;
|
|
||||||
float: none;
|
|
||||||
border-top: 2px solid #777;
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.studyDateList label {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
@ -1,11 +1,11 @@
|
|||||||
<template name="studyDateList">
|
<template name="studyDateList">
|
||||||
<div class="studyDateList">
|
<div class="studyDateList">
|
||||||
<label>Study Date:</label>
|
<label>Study Date:</label>
|
||||||
|
<span class="loading"><i class="fa fa-spinner fa-spin"></i></span>
|
||||||
<select id="selectStudyDate">
|
<select id="selectStudyDate">
|
||||||
{{#each patientStudies}}
|
{{#each relatedStudies}}
|
||||||
<option value="{{studyInstanceUid}}">{{studyDate}}</option>
|
<option value="{{studyInstanceUid}}" selected={{selected}}>{{formatDA studyDate}}</option>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
@ -1,66 +1,68 @@
|
|||||||
|
|
||||||
Template.studyDateList.onCreated(function(){
|
|
||||||
|
|
||||||
// All studies of this patient at different dates
|
|
||||||
this.patientStudies = [];
|
|
||||||
this.selectedDate = "";
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
Template.studyDateList.onRendered(function(){
|
|
||||||
|
|
||||||
// Add Study dates to Timepoints
|
|
||||||
this.patientStudies.forEach(function(study) {
|
|
||||||
Timepoints.insert({
|
|
||||||
timepointID: uuid.v4(),
|
|
||||||
timepointName: study.studyDate
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Selected date option in combobox
|
|
||||||
var self = this;
|
|
||||||
$('#selectStudyDate option').filter(function () {
|
|
||||||
if ($(this).html() === self.selectedDate) {
|
|
||||||
$(this).prop('selected', true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
Template.studyDateList.helpers({
|
Template.studyDateList.helpers({
|
||||||
patientStudies: function(){
|
/**
|
||||||
var self = Template.instance();
|
* Returns an array of studies that are related to the current study by patient ID.
|
||||||
|
* The value for 'selected' for the currently loaded study is set to true, so that
|
||||||
var studyData = this.studies[0]; // study which is loaded in tab
|
* this becomes the current option in the combo box.
|
||||||
self.selectedDate = studyData.studyDate;
|
*
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
|
relatedStudies: function() {
|
||||||
// TODO= Fix this! This won't work to retrieve all studies
|
// TODO= Fix this! This won't work to retrieve all studies
|
||||||
// related to this patient. We will need to do a real search
|
// related to this patient. We will need to do a real search
|
||||||
// since the WorklistStudies Collection only contains the studies on-screen
|
// since the WorklistStudies Collection only contains the studies on-screen
|
||||||
|
|
||||||
var studies = WorklistStudies.find({}).fetch(); // All studies list
|
// Check which study is currently loaded into the study browser
|
||||||
var patientStudies = []; // Holds studies of patient
|
var currentStudyInBrowser = ViewerStudies.findOne({selected: true});
|
||||||
|
|
||||||
// Get all studies of patient with patientID
|
// Find studies which have the same patientId as the currently selected study
|
||||||
studies.forEach(function(study) {
|
var relatedStudies = WorklistStudies.find({patientId: currentStudyInBrowser.patientId}).fetch();
|
||||||
if (studyData.patientId === study.patientId) {
|
|
||||||
patientStudies.push(study);
|
// Modify the array of related studies so the default option is the currently selected study
|
||||||
|
relatedStudies.forEach(function(study) {
|
||||||
|
// If the studyInstanceUid matches that of the current study in the browser,
|
||||||
|
// Set this to 'selected', so that it becomes the default option
|
||||||
|
if (study.studyInstanceUid === currentStudyInBrowser.studyInstanceUid) {
|
||||||
|
study.selected = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
self.patientStudies = patientStudies;
|
// Use this array to populate the combo box
|
||||||
return patientStudies;
|
return relatedStudies;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
Template.studyDateList.events({
|
Template.studyDateList.events({
|
||||||
'change select#selectStudyDate': function(e, template) {
|
/**
|
||||||
var studyInstanceUid = $(e.currentTarget).val();
|
* When the study date selector combo box is changed, we will
|
||||||
|
* hide the select box, temporarily display a loading sign, and grab
|
||||||
|
* the selected study. Once the study has been retrieved it is added
|
||||||
|
* into the ViewerStudies collection and set as selected. This reactively
|
||||||
|
* populated the thumbnail browser.
|
||||||
|
*
|
||||||
|
* @param e The select box change event
|
||||||
|
*/
|
||||||
|
'change select#selectStudyDate': function(e) {
|
||||||
|
var selectBox = $(e.currentTarget);
|
||||||
|
|
||||||
|
var studyInstanceUid = selectBox.val();
|
||||||
|
|
||||||
|
// Hide the select box
|
||||||
|
selectBox.css('display', 'none');
|
||||||
|
|
||||||
|
// Show the loading indicator
|
||||||
|
var loadingIndicator = selectBox.siblings('.loading');
|
||||||
|
loadingIndicator.css('display', 'block');
|
||||||
|
|
||||||
Meteor.call('GetStudyMetadata', studyInstanceUid, function(error, study) {
|
Meteor.call('GetStudyMetadata', studyInstanceUid, function(error, study) {
|
||||||
sortStudy(study);
|
sortStudy(study);
|
||||||
|
|
||||||
|
// Hide the loading indicator
|
||||||
|
loadingIndicator.css('display', 'none');
|
||||||
|
|
||||||
|
// Show the select box again
|
||||||
|
selectBox.css('display', 'block');
|
||||||
|
|
||||||
// Set "Selected" to false for the entire collection
|
// Set "Selected" to false for the entire collection
|
||||||
ViewerStudies.update({},
|
ViewerStudies.update({},
|
||||||
{$set: {selected: false}},
|
{$set: {selected: false}},
|
||||||
|
|||||||
@ -0,0 +1,15 @@
|
|||||||
|
.studyDateList
|
||||||
|
margin: 0px auto
|
||||||
|
text-align: left
|
||||||
|
width: 100%
|
||||||
|
border-top: 2px solid #777
|
||||||
|
padding: 10px
|
||||||
|
|
||||||
|
label
|
||||||
|
font-weight: normal
|
||||||
|
color: white
|
||||||
|
|
||||||
|
.loading
|
||||||
|
display: none
|
||||||
|
color: white
|
||||||
|
text-align: center
|
||||||
@ -40,7 +40,7 @@ Package.onUse(function (api) {
|
|||||||
api.addFiles('components/nonTargetLesionDialog/nonTargetLesionDialog.js', 'client');
|
api.addFiles('components/nonTargetLesionDialog/nonTargetLesionDialog.js', 'client');
|
||||||
|
|
||||||
api.addFiles('components/studyDateList/studyDateList.html', 'client');
|
api.addFiles('components/studyDateList/studyDateList.html', 'client');
|
||||||
api.addFiles('components/studyDateList/studyDateList.css', 'client');
|
api.addFiles('components/studyDateList/studyDateList.styl', 'client');
|
||||||
api.addFiles('components/studyDateList/studyDateList.js', 'client');
|
api.addFiles('components/studyDateList/studyDateList.js', 'client');
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
<template name="imageViewerViewports">
|
<template name="imageViewerViewports">
|
||||||
<div id='imageViewerViewports'>
|
<div id='imageViewerViewports'>
|
||||||
{{ #each viewportArray }}
|
{{ #each viewerWindow }}
|
||||||
<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 seriesInstanceUid=seriesInstanceUid studyInstanceUid=studyInstanceUid currentImageIdIndex=currentImageIdIndex viewport=viewport}}
|
{{ >imageViewerViewport}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{ /each }}
|
{{ /each }}
|
||||||
|
|||||||
@ -1,13 +1,4 @@
|
|||||||
Template.imageViewerViewports.onRendered(function() {
|
ViewerWindows = new Meteor.Collection(null);
|
||||||
this.autorun(function() {
|
|
||||||
var studies = Session.get('studies');
|
|
||||||
var eventType = "ViewerBaseStudyLoaded";
|
|
||||||
var eventData = {
|
|
||||||
studies: studies
|
|
||||||
};
|
|
||||||
$(document).trigger(eventType, eventData);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
Template.imageViewerViewports.helpers({
|
Template.imageViewerViewports.helpers({
|
||||||
height: function() {
|
height: function() {
|
||||||
@ -18,7 +9,9 @@ Template.imageViewerViewports.helpers({
|
|||||||
var viewportColumns = this.viewportColumns || 1;
|
var viewportColumns = this.viewportColumns || 1;
|
||||||
return 100 / viewportColumns;
|
return 100 / viewportColumns;
|
||||||
},
|
},
|
||||||
viewportArray: function() {
|
viewerWindow: function() {
|
||||||
|
ViewerWindows = new Meteor.Collection(null);
|
||||||
|
|
||||||
log.info("imageViewerViewports viewportArray");
|
log.info("imageViewerViewports viewportArray");
|
||||||
|
|
||||||
var viewportRows = this.viewportRows || 1;
|
var viewportRows = this.viewportRows || 1;
|
||||||
@ -45,13 +38,11 @@ Template.imageViewerViewports.helpers({
|
|||||||
|
|
||||||
var inputData = {
|
var inputData = {
|
||||||
viewportColumns: viewportColumns,
|
viewportColumns: viewportColumns,
|
||||||
viewportRows: viewportRows,
|
viewportRows: viewportRows
|
||||||
studies: ViewerStudies
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var hangingProtocolViewportData = WindowManager.getHangingProtocol(inputData);
|
var hangingProtocolViewportData = WindowManager.getHangingProtocol(inputData);
|
||||||
|
|
||||||
var array = [];
|
|
||||||
var numViewports = viewportRows * viewportColumns;
|
var numViewports = viewportRows * viewportColumns;
|
||||||
for (var i=0; i < numViewports; ++i) {
|
for (var i=0; i < numViewports; ++i) {
|
||||||
var data = {
|
var data = {
|
||||||
@ -61,6 +52,7 @@ Template.imageViewerViewports.helpers({
|
|||||||
viewportColumns: viewportColumns,
|
viewportColumns: viewportColumns,
|
||||||
viewportRows: viewportRows
|
viewportRows: viewportRows
|
||||||
};
|
};
|
||||||
|
|
||||||
if (viewportData && viewportData[i]) {
|
if (viewportData && viewportData[i]) {
|
||||||
data.seriesInstanceUid = viewportData[i].seriesInstanceUid;
|
data.seriesInstanceUid = viewportData[i].seriesInstanceUid;
|
||||||
data.studyInstanceUid = viewportData[i].studyInstanceUid;
|
data.studyInstanceUid = viewportData[i].studyInstanceUid;
|
||||||
@ -72,9 +64,10 @@ Template.imageViewerViewports.helpers({
|
|||||||
data.currentImageIdIndex = hangingProtocolViewportData[i].currentImageIdIndex;
|
data.currentImageIdIndex = hangingProtocolViewportData[i].currentImageIdIndex;
|
||||||
data.viewport = hangingProtocolViewportData[i].viewport;
|
data.viewport = hangingProtocolViewportData[i].viewport;
|
||||||
}
|
}
|
||||||
array.push(data);
|
|
||||||
|
ViewerWindows.insert(data);
|
||||||
}
|
}
|
||||||
return array;
|
return ViewerWindows.find();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -177,7 +177,7 @@ function findSeries(displaySet, study) {
|
|||||||
function applyDICOMHangingProtocol(hangingProtocol, inputData) {
|
function applyDICOMHangingProtocol(hangingProtocol, inputData) {
|
||||||
log.info('applyDICOMHangingProtocol');
|
log.info('applyDICOMHangingProtocol');
|
||||||
var presentationGroup = inputData.DisplaySetPresentationGroup || 1;
|
var presentationGroup = inputData.DisplaySetPresentationGroup || 1;
|
||||||
var studies = inputData.studies;
|
var studies = ViewerStudies;
|
||||||
var currentDisplaySets = findSetsByPresentationGroup(hangingProtocol.DisplaySetsSequence, presentationGroup);
|
var currentDisplaySets = findSetsByPresentationGroup(hangingProtocol.DisplaySetsSequence, presentationGroup);
|
||||||
|
|
||||||
var viewportData = [];
|
var viewportData = [];
|
||||||
@ -188,7 +188,7 @@ function applyDICOMHangingProtocol(hangingProtocol, inputData) {
|
|||||||
|
|
||||||
studyInstanceUid = findStudy(displaySet, studies);
|
studyInstanceUid = findStudy(displaySet, studies);
|
||||||
|
|
||||||
var study = studies.findOne({studyInstanceUid: studyInstanceUid});
|
var study = ViewerStudies.findOne({studyInstanceUid: studyInstanceUid});
|
||||||
seriesInstanceUid = findSeries(displaySet, study);
|
seriesInstanceUid = findSeries(displaySet, study);
|
||||||
|
|
||||||
viewportData[index] = {
|
viewportData[index] = {
|
||||||
@ -213,7 +213,7 @@ function applyDICOMHangingProtocol(hangingProtocol, inputData) {
|
|||||||
* @returns {Array}
|
* @returns {Array}
|
||||||
*/
|
*/
|
||||||
function defaultHangingProtocol(inputData) {
|
function defaultHangingProtocol(inputData) {
|
||||||
var studies = inputData.studies.find().fetch();
|
var studies = ViewerStudies.find().fetch();
|
||||||
var viewportRows = inputData.viewportRows;
|
var viewportRows = inputData.viewportRows;
|
||||||
var viewportColumns = inputData.viewportColumns;
|
var viewportColumns = inputData.viewportColumns;
|
||||||
|
|
||||||
@ -259,7 +259,7 @@ var hangingProtocol;
|
|||||||
|
|
||||||
function getHangingProtocol(inputData) {
|
function getHangingProtocol(inputData) {
|
||||||
// TODO = Update this to use Collection logic
|
// TODO = Update this to use Collection logic
|
||||||
var studies = inputData.studies.find().fetch();
|
var studies = ViewerStudies.find().fetch();
|
||||||
|
|
||||||
if (!studies.length) {
|
if (!studies.length) {
|
||||||
log.warn("No studies provided to Hanging Protocol");
|
log.warn("No studies provided to Hanging Protocol");
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user