Measurements and Timepoint interaction in Lesion Table and tools
This commit is contained in:
parent
5363880e40
commit
b49c36493e
@ -37,3 +37,4 @@ reactive-var
|
||||
reactive-dict
|
||||
lesiontracker
|
||||
practicalmeteor:loglevel
|
||||
momentjs:moment
|
||||
|
||||
@ -62,6 +62,7 @@ minifiers@1.1.7
|
||||
minimongo@1.0.10
|
||||
mobile-experience@1.0.1
|
||||
mobile-status-bar@1.0.6
|
||||
momentjs:moment@2.10.6
|
||||
mongo@1.1.3
|
||||
mongo-id@1.0.1
|
||||
npm-bcrypt@0.7.8_2
|
||||
|
||||
@ -11,13 +11,6 @@ Template.viewerMain.helpers({
|
||||
iconClasses: 'fa fa-sun-o'
|
||||
});
|
||||
|
||||
buttonData.push({
|
||||
id: 'invert',
|
||||
title: 'Invert',
|
||||
classes: 'imageViewerCommand',
|
||||
iconClasses: 'fa fa-adjust'
|
||||
});
|
||||
|
||||
buttonData.push({
|
||||
id: 'zoom',
|
||||
title: 'Zoom',
|
||||
@ -46,20 +39,6 @@ Template.viewerMain.helpers({
|
||||
iconClasses: 'fa fa-arrows-v'
|
||||
});
|
||||
|
||||
buttonData.push({
|
||||
id: 'angle',
|
||||
title: 'Angle Measurement',
|
||||
classes: 'imageViewerTool',
|
||||
iconClasses: 'fa fa-angle-left'
|
||||
});
|
||||
|
||||
buttonData.push({
|
||||
id: 'dragProbe',
|
||||
title: 'Pixel Probe',
|
||||
classes: 'imageViewerTool',
|
||||
iconClasses: 'fa fa-dot-circle-o'
|
||||
});
|
||||
|
||||
buttonData.push({
|
||||
id: 'lesion',
|
||||
title: 'Lesion Tool',
|
||||
|
||||
@ -1,26 +1,24 @@
|
||||
var lineIndex = 0; //This holds drawn line index
|
||||
var activeLesionMeasurementData;
|
||||
var timepointID;
|
||||
var cornerstoneTools = (function ($, cornerstone, cornerstoneMath, cornerstoneTools) {
|
||||
var cornerstoneTools = (function($, cornerstone, cornerstoneMath, cornerstoneTools) {
|
||||
|
||||
"use strict";
|
||||
|
||||
if(cornerstoneTools === undefined) {
|
||||
if (cornerstoneTools === undefined) {
|
||||
cornerstoneTools = {};
|
||||
}
|
||||
|
||||
var toolType = "lesion";
|
||||
|
||||
///////// BEGIN ACTIVE TOOL ///////
|
||||
function createNewMeasurement(mouseEventData)
|
||||
{
|
||||
function createNewMeasurement(mouseEventData) {
|
||||
var element = mouseEventData.element;
|
||||
timepointID = getActiveTimepointID(element);
|
||||
var lesionNumber = measurementManagerDAL.getLesionNumber(timepointID);
|
||||
timepointID = $(element).data('timepointID');
|
||||
var lesionNumber = measurementManagerDAL.getNewLesionNumber(timepointID);
|
||||
var lesionCounter = "";
|
||||
|
||||
// Subscribe CornerstoneMouseup event, when mouse is up, call lesionDialog
|
||||
$(element).on("CornerstoneToolsMouseUp", function (e) {
|
||||
$(element).on("CornerstoneToolsMouseUp", function(e) {
|
||||
|
||||
// Unsubscribe CornerstoneToolsMouseUp event
|
||||
$(element).off("CornerstoneToolsMouseUp");
|
||||
@ -31,11 +29,10 @@ var cornerstoneTools = (function ($, cornerstone, cornerstoneMath, cornerstoneTo
|
||||
|
||||
// Show LesionDialog
|
||||
$(document).trigger("ShowLesionDialog", [e, activeLesionMeasurementData]);
|
||||
|
||||
});
|
||||
|
||||
// Set Lesion Name
|
||||
$(element).on("LesionNameSet", function(e,lesionName){
|
||||
$(element).on("LesionNameSet", function(e, lesionName) {
|
||||
lesionCounter = lesionName;
|
||||
});
|
||||
|
||||
@ -45,55 +42,52 @@ var cornerstoneTools = (function ($, cornerstone, cornerstoneMath, cornerstoneTo
|
||||
console.log(mouseEventData.image.imageId);
|
||||
// create the measurement data for this tool with the end handle activated
|
||||
var measurementData = {
|
||||
visible : true,
|
||||
active : true,
|
||||
handles : {
|
||||
start : {
|
||||
x : mouseEventData.currentPoints.image.x,
|
||||
y : mouseEventData.currentPoints.image.y,
|
||||
visible: true,
|
||||
active: true,
|
||||
handles: {
|
||||
start: {
|
||||
x: mouseEventData.currentPoints.image.x,
|
||||
y: mouseEventData.currentPoints.image.y,
|
||||
highlight: true,
|
||||
active: false
|
||||
},
|
||||
end: {
|
||||
x : mouseEventData.currentPoints.image.x,
|
||||
y : mouseEventData.currentPoints.image.y,
|
||||
x: mouseEventData.currentPoints.image.x,
|
||||
y: mouseEventData.currentPoints.image.y,
|
||||
highlight: true,
|
||||
active: true
|
||||
}
|
||||
},
|
||||
index: lineIndex,
|
||||
imageId: mouseEventData.image.imageId,
|
||||
measurementText: "",
|
||||
measurementText: 0,
|
||||
linkedTextCoords: {
|
||||
start : {
|
||||
x : mouseEventData.currentPoints.image.x,
|
||||
y : mouseEventData.currentPoints.image.y,
|
||||
start: {
|
||||
x: mouseEventData.currentPoints.image.x,
|
||||
y: mouseEventData.currentPoints.image.y,
|
||||
highlight: true,
|
||||
active: false
|
||||
},
|
||||
end: {
|
||||
x : mouseEventData.currentPoints.image.x,
|
||||
y : mouseEventData.currentPoints.image.y,
|
||||
x: mouseEventData.currentPoints.image.x,
|
||||
y: mouseEventData.currentPoints.image.y,
|
||||
highlight: true,
|
||||
active: true
|
||||
},
|
||||
init: false
|
||||
},
|
||||
lesionName: "Target "+lesionNumber,
|
||||
lesionName: "Target " + lesionNumber,
|
||||
isDeleted: false,
|
||||
lineNumber:"", //Indicates line number on image
|
||||
lesionNumber: lesionNumber,
|
||||
uid: uuid.v4()
|
||||
};
|
||||
lineIndex++;
|
||||
return measurementData;
|
||||
}
|
||||
///////// END ACTIVE TOOL ///////
|
||||
|
||||
function pointNearTool(element, data, coords)
|
||||
{
|
||||
function pointNearTool(element, data, coords) {
|
||||
var lineSegment = {
|
||||
start: cornerstone.pixelToCanvas(element, data.handles.start), end: cornerstone.pixelToCanvas(element, data.handles.end)
|
||||
start: cornerstone.pixelToCanvas(element, data.handles.start),
|
||||
end: cornerstone.pixelToCanvas(element, data.handles.end)
|
||||
};
|
||||
var distanceToPoint = cornerstoneMath.lineSegment.distanceToPoint(lineSegment, coords);
|
||||
return (distanceToPoint < 25);
|
||||
@ -101,7 +95,8 @@ var cornerstoneTools = (function ($, cornerstone, cornerstoneMath, cornerstoneTo
|
||||
|
||||
function pointNearToolForText(element, data, coords) {
|
||||
var lineSegment = {
|
||||
start: cornerstone.pixelToCanvas(element, data.linkedTextCoords.start), end: cornerstone.pixelToCanvas(element, data.linkedTextCoords.end)
|
||||
start: cornerstone.pixelToCanvas(element, data.linkedTextCoords.start),
|
||||
end: cornerstone.pixelToCanvas(element, data.linkedTextCoords.end)
|
||||
};
|
||||
|
||||
var distanceToPoint = cornerstoneMath.lineSegment.distanceToPoint(lineSegment, coords);
|
||||
@ -109,8 +104,8 @@ var cornerstoneTools = (function ($, cornerstone, cornerstoneMath, cornerstoneTo
|
||||
|
||||
}
|
||||
|
||||
function suscribeLesionToolModifiedEvent (element) {
|
||||
var elementEvents = $._data(element, "events" );
|
||||
function suscribeLesionToolModifiedEvent(element) {
|
||||
var elementEvents = $._data(element, "events");
|
||||
var index = Object.keys(elementEvents).indexOf("LesionToolModified");
|
||||
if (index < 0) {
|
||||
// Subscribe LesionToolModified and calls measurementModified function when lesion measurement is changed or updated.
|
||||
@ -125,7 +120,7 @@ var cornerstoneTools = (function ($, cornerstone, cornerstoneMath, cornerstoneTo
|
||||
|
||||
// if we have no toolData for this element, return immediately as there is nothing to do
|
||||
var toolData = cornerstoneTools.getToolState(e.currentTarget, toolType);
|
||||
if (toolData === undefined) {
|
||||
if (!toolData) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -146,7 +141,7 @@ var cornerstoneTools = (function ($, cornerstone, cornerstoneMath, cornerstoneTo
|
||||
function updateLesionCollection(lesionData, currentElement) {
|
||||
|
||||
if (lesionData.active) {
|
||||
if(lesionData.timepointID !== undefined && lesionData.timepointID !== "") {
|
||||
if (lesionData.timepointID !== undefined && lesionData.timepointID !== "") {
|
||||
// Update Measurements Collection
|
||||
measurementManagerDAL.updateTimepointData(lesionData);
|
||||
|
||||
@ -156,13 +151,13 @@ var cornerstoneTools = (function ($, cornerstone, cornerstoneMath, cornerstoneTo
|
||||
}
|
||||
}
|
||||
|
||||
function renderLesion(lesion, context, eventData){
|
||||
function renderLesion(lesion, context, eventData) {
|
||||
context.save();
|
||||
|
||||
var color;
|
||||
var lineWidth = cornerstoneTools.toolStyle.getToolWidth();
|
||||
var font = cornerstoneTools.textStyle.getFont();
|
||||
var config = cornerstoneTools.length.getConfiguration();
|
||||
var config = cornerstoneTools.lesion.getConfiguration();
|
||||
|
||||
// configurable shadow from CornerstoneTools
|
||||
if (config && config.shadow) {
|
||||
@ -194,7 +189,7 @@ var cornerstoneTools = (function ($, cornerstone, cornerstoneMath, cornerstoneTo
|
||||
//Set coordinates of text
|
||||
var linkedTextStartCanvas = cornerstone.pixelToCanvas(eventData.element, lesion.linkedTextCoords.start);
|
||||
var linkedTextEndCanvas = cornerstone.pixelToCanvas(eventData.element, lesion.linkedTextCoords.end);
|
||||
if(!lesion.linkedTextCoords.init){
|
||||
if (!lesion.linkedTextCoords.init) {
|
||||
lesion.linkedTextCoords.start.x = lesion.handles.start.x + 50;
|
||||
lesion.linkedTextCoords.start.y = lesion.handles.start.y + 40;
|
||||
linkedTextStartCanvas = cornerstone.pixelToCanvas(eventData.element, lesion.linkedTextCoords.start);
|
||||
@ -209,12 +204,13 @@ var cornerstoneTools = (function ($, cornerstone, cornerstoneMath, cornerstoneTo
|
||||
}
|
||||
|
||||
//Draw linked line as dashed
|
||||
context.setLineDash([2,3]);
|
||||
context.setLineDash([2, 3]);
|
||||
context.beginPath();
|
||||
context.strokeStyle = color;
|
||||
context.lineWidth = 1 / eventData.viewport.scale;
|
||||
var mid = {
|
||||
x:(handleStartCanvas.x + handleEndCanvas.x) / 2, y:(handleStartCanvas.y + handleEndCanvas.y) / 2
|
||||
x: (handleStartCanvas.x + handleEndCanvas.x) / 2,
|
||||
y: (handleStartCanvas.y + handleEndCanvas.y) / 2
|
||||
};
|
||||
|
||||
context.moveTo(mid.x, mid.y);
|
||||
@ -235,17 +231,18 @@ var cornerstoneTools = (function ($, cornerstone, cornerstoneMath, cornerstoneTo
|
||||
|
||||
var text = '' + length.toFixed(2) + suffix;
|
||||
var textCoords = {
|
||||
x: linkedTextStartCanvas.x, y: linkedTextStartCanvas.y
|
||||
x: linkedTextStartCanvas.x,
|
||||
y: linkedTextStartCanvas.y
|
||||
};
|
||||
|
||||
cornerstoneTools.drawTextBox(context, lesion.lesionName, textCoords.x, textCoords.y, color);
|
||||
cornerstoneTools.drawTextBox(context, text, textCoords.x, textCoords.y + 20, color);
|
||||
|
||||
//Set measurement text to show lesion table
|
||||
lesion.measurementText = length.toFixed(2);
|
||||
// Set measurement text to show lesion table
|
||||
lesion.measurementText = length.toFixed(1);
|
||||
|
||||
// Lesion Measurement is changed
|
||||
$(eventData.enabledElement.element).trigger("LesionTextChanged",lesion);
|
||||
$(eventData.enabledElement.element).trigger("LesionTextChanged", lesion);
|
||||
|
||||
context.restore();
|
||||
}
|
||||
@ -266,7 +263,7 @@ var cornerstoneTools = (function ($, cornerstone, cornerstoneMath, cornerstoneTo
|
||||
}
|
||||
|
||||
//If type is delete, remove measurement
|
||||
if(type === "delete") {
|
||||
if (type === "delete") {
|
||||
var deletedDataIndex = -1;
|
||||
|
||||
for (var i = 0; i < toolData.data.length; i++) {
|
||||
@ -282,17 +279,17 @@ var cornerstoneTools = (function ($, cornerstone, cornerstoneMath, cornerstoneTo
|
||||
if (deletedDataIndex >= 0 && deletedDataIndex < toolData.data.length) {
|
||||
toolData.data.splice(deletedDataIndex, 1);
|
||||
}
|
||||
} else if(type === "active") {
|
||||
} else if (type === "active") {
|
||||
for (var i = 0; i < toolData.data.length; i++) {
|
||||
var data = toolData.data[i];
|
||||
//When click a row of table measurements, measurement will be active and color will be green
|
||||
if (data.lesionNumber === eventObject.lesionData.lesionNumber && eventObject.type === "active") {
|
||||
data.active = true;
|
||||
} else{
|
||||
} else {
|
||||
data.active = false;
|
||||
}
|
||||
}
|
||||
} else if(type === "inactive") {
|
||||
} else if (type === "inactive") {
|
||||
for (var i = 0; i < toolData.data.length; i++) {
|
||||
var data = toolData.data[i];
|
||||
// Make inactive all lesions for the timepoint
|
||||
@ -310,15 +307,15 @@ var cornerstoneTools = (function ($, cornerstone, cornerstoneMath, cornerstoneTo
|
||||
//console.log(diff + ' ms');
|
||||
|
||||
var eventData = {
|
||||
viewport : enabledElement.viewport,
|
||||
element : enabledElement.element,
|
||||
image : enabledElement.image,
|
||||
enabledElement : enabledElement,
|
||||
viewport: enabledElement.viewport,
|
||||
element: enabledElement.element,
|
||||
image: enabledElement.image,
|
||||
enabledElement: enabledElement,
|
||||
canvasContext: context,
|
||||
measurementText: "",
|
||||
renderTimeInMs : diff,
|
||||
lesionNumber : lesionNumber,
|
||||
type : type //Holds image will be deleted or active
|
||||
renderTimeInMs: diff,
|
||||
lesionNumber: lesionNumber,
|
||||
type: type //Holds image will be deleted or active
|
||||
};
|
||||
|
||||
enabledElement.invalid = false;
|
||||
@ -339,11 +336,11 @@ var cornerstoneTools = (function ($, cornerstone, cornerstoneMath, cornerstoneTo
|
||||
var indexOfImage = imageIdsArr.indexOf(eventObject.lesionData.imageId);
|
||||
if (indexOfImage > -1) {
|
||||
cornerstone.loadAndCacheImage(stackData.imageIds[indexOfImage]).then(function(image) {
|
||||
cornerstone.displayImage(eventObject.enabledElement.element,image);
|
||||
cornerstone.displayImage(eventObject.enabledElement.element, image);
|
||||
updateLesion(e, eventObject);
|
||||
});
|
||||
}
|
||||
} else if(eventObject.type === "inactive") {
|
||||
} else if (eventObject.type === "inactive") {
|
||||
updateLesion(e, eventObject);
|
||||
}
|
||||
|
||||
@ -351,17 +348,17 @@ var cornerstoneTools = (function ($, cornerstone, cornerstoneMath, cornerstoneTo
|
||||
}
|
||||
|
||||
//This function is called from cornerstone-viewport.html and updates lesion measurement and makes the lesion active
|
||||
function measurementModified(e, eventObject){
|
||||
loadImage(e,eventObject);
|
||||
function measurementModified(e, eventObject) {
|
||||
loadImage(e, eventObject);
|
||||
}
|
||||
|
||||
// module exports
|
||||
cornerstoneTools.lesion = cornerstoneTools.mouseButtonTool({
|
||||
createNewMeasurement : createNewMeasurement,
|
||||
createNewMeasurement: createNewMeasurement,
|
||||
onImageRendered: onImageRendered,
|
||||
pointNearTool : pointNearTool,
|
||||
pointNearTool: pointNearTool,
|
||||
pointNearToolForText: pointNearToolForText,
|
||||
toolType : toolType
|
||||
toolType: toolType
|
||||
});
|
||||
cornerstoneTools.lesionTouch = cornerstoneTools.touchTool({
|
||||
createNewMeasurement: createNewMeasurement,
|
||||
@ -371,4 +368,5 @@ var cornerstoneTools = (function ($, cornerstone, cornerstoneMath, cornerstoneTo
|
||||
toolType: toolType
|
||||
});
|
||||
return cornerstoneTools;
|
||||
|
||||
}($, cornerstone, cornerstoneMath, cornerstoneTools));
|
||||
@ -1,203 +1,165 @@
|
||||
var measurementManagerDAL = (function () {
|
||||
var measurementManagerDAL = (function() {
|
||||
var trialPatientLocations = [];
|
||||
var timepoints = [];
|
||||
|
||||
// Returns trialPatientLocations array
|
||||
function getPatientLocations () {
|
||||
function getPatientLocations() {
|
||||
return trialPatientLocations;
|
||||
}
|
||||
|
||||
function getLocationName (locationUID) {
|
||||
for(var i = 0; i< trialPatientLocations.length; i++) {
|
||||
function getLocationName(locationUID) {
|
||||
for (var i = 0; i < trialPatientLocations.length; i++) {
|
||||
var locationObject = trialPatientLocations[i];
|
||||
if(locationObject.uid === locationUID) {
|
||||
if (locationObject.uid === locationUID) {
|
||||
return locationObject.location.location;
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
function getTimepoints() {
|
||||
return timepoints;
|
||||
}
|
||||
|
||||
// Adds new location to trialPatientLocations array
|
||||
function addPatientLocation (location) {
|
||||
var contentId = getContentId();
|
||||
function addPatientLocation(location) {
|
||||
var locationUID = uuid.v4();
|
||||
var locationObject = {contentId: contentId, uid: locationUID, location: location};
|
||||
var locationObject = {
|
||||
uid: locationUID,
|
||||
location: location
|
||||
};
|
||||
trialPatientLocations.push(locationObject);
|
||||
|
||||
return locationUID;
|
||||
}
|
||||
|
||||
function getContentId () {
|
||||
return Session.get("activeContentId");
|
||||
}
|
||||
|
||||
function getTimepointsOfTab (){
|
||||
var contentId = getContentId();
|
||||
var tabData = TabsTimepoints.find({contentId: contentId}).fetch();
|
||||
return tabData[0].timepoints;
|
||||
}
|
||||
|
||||
// Add timepoint data to Measurements collection
|
||||
function addTimepointData(lesionData) {
|
||||
var timepoints = Timepoints.find().fetch();
|
||||
var timepointsObject = {};
|
||||
|
||||
var contentId = getContentId();
|
||||
var timepointsOfTab = getTimepointsOfTab();
|
||||
var timepointsArr = [];
|
||||
for(var i=0; i< timepointsOfTab.length; i++) {
|
||||
var timepointId = timepointsOfTab[i].timepointID;
|
||||
for (var i = 0; i < timepoints.length; i++) {
|
||||
var timepointId = timepoints[i].timepointID;
|
||||
var lesionTimepointId = lesionData.timepointID;
|
||||
|
||||
var timepointObject;
|
||||
if (timepointId === lesionTimepointId) {
|
||||
// Add real mesurement
|
||||
var timepointObject = {};
|
||||
timepointObject[timepointId] = {longestDiameter: lesionData.measurementText, imageId: lesionData.imageId};
|
||||
timepointsArr.push(timepointObject);
|
||||
timepointObject = {
|
||||
longestDiameter: lesionData.measurementText,
|
||||
imageId: lesionData.imageId
|
||||
};
|
||||
} else {
|
||||
// Add null measurement
|
||||
var timepointObject = {};
|
||||
timepointObject[timepointId] = {longestDiameter: "", imageId: ""};
|
||||
timepointsArr.push(timepointObject);
|
||||
|
||||
timepointObject = {
|
||||
longestDiameter: "",
|
||||
imageId: ""
|
||||
};
|
||||
}
|
||||
timepointsObject[timepointId] = timepointObject;
|
||||
}
|
||||
|
||||
var lesionDataCollectionObject = {
|
||||
var lesionDataObject = {
|
||||
lesionNumber: lesionData.lesionNumber,
|
||||
isTarget: true,
|
||||
locationUID: lesionData.locationUID,
|
||||
location: getLocationName(lesionData.locationUID),
|
||||
timepoints: timepointsArr
|
||||
timepoints: timepointsObject
|
||||
};
|
||||
|
||||
Measurements.insert({contentId: contentId, lesionData: lesionDataCollectionObject});
|
||||
Measurements.insert(lesionDataObject);
|
||||
}
|
||||
|
||||
// Update timepoint data in Measurements collection
|
||||
function updateTimepointData (lesionData) {
|
||||
var contentId = getContentId();
|
||||
var timepointID = lesionData.timepointID;
|
||||
var tabMeasurements = Measurements.find({contentId: contentId, "lesionData.lesionNumber": lesionData.lesionNumber}).fetch();
|
||||
var tabMeasurementsData = tabMeasurements[0];
|
||||
if (tabMeasurements != undefined && tabMeasurements.length > 0) {
|
||||
|
||||
// Update timepoint
|
||||
var timepointArr = tabMeasurementsData.lesionData.timepoints;
|
||||
for(var i=0; i< timepointArr.length; i++) {
|
||||
var timepoint = timepointArr[i];
|
||||
if(timepoint[timepointID] != undefined) {
|
||||
timepoint[timepointID].longestDiameter = lesionData.measurementText;
|
||||
timepoint[timepointID].imageId = lesionData.imageId;
|
||||
|
||||
}
|
||||
}
|
||||
Measurements.update(
|
||||
{ contentId: contentId, "lesionData.lesionNumber": lesionData.lesionNumber},
|
||||
{
|
||||
$set: {
|
||||
"lesionData.timepoints": timepointArr
|
||||
}
|
||||
}, {multi: true}
|
||||
);
|
||||
function updateTimepointData(lesionData) {
|
||||
// Find the specific lesion to be updated
|
||||
var measurement = Measurements.find({
|
||||
lesionNumber: lesionData.lesionNumber
|
||||
}).fetch()[0];
|
||||
|
||||
// If no such lesion exists, stop here
|
||||
if (!measurement) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Update this specific lesion at the given timepoint
|
||||
var timepointID = lesionData.timepointID;
|
||||
|
||||
// Update timepoints from lesion data
|
||||
var timepoints = measurement.timepoints;
|
||||
timepoints[timepointID].longestDiameter = lesionData.measurementText;
|
||||
timepoints[timepointID].imageId = lesionData.imageId;
|
||||
|
||||
Measurements.update({
|
||||
lesionNumber: lesionData.lesionNumber
|
||||
}, {
|
||||
$set: {
|
||||
timepoints: timepoints
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Check timepointData is found in Measurements collection
|
||||
function timepointDataIsFound (lesionNumber) {
|
||||
var contentId = getContentId();
|
||||
var timepointData = Measurements.findOne({contentId: contentId, "lesionData.lesionNumber": lesionNumber});
|
||||
if (timepointData != undefined) {
|
||||
function timepointDataIsFound(lesionNumber) {
|
||||
var timepointData = Measurements.findOne({
|
||||
lesionNumber: lesionNumber
|
||||
});
|
||||
if (timepointData) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Adds new timepoint item to tiemepoints array
|
||||
function addLesionData (lesionData) {
|
||||
if(timepointDataIsFound(lesionData)) {
|
||||
function addLesionData(lesionData) {
|
||||
if (timepointDataIsFound(lesionData)) {
|
||||
// Update data
|
||||
updateTimepointData(lesionData);
|
||||
} else{
|
||||
} else {
|
||||
// Insert data
|
||||
addTimepointData(lesionData);
|
||||
}
|
||||
|
||||
// TODO: This code block will be removed
|
||||
// Populate timepoints array
|
||||
var roi = {
|
||||
uid: lesionData.uid,
|
||||
number: lesionData.lesionNumber,
|
||||
measurement: lesionData.measurementText,
|
||||
locationUID: lesionData.locationUID
|
||||
};
|
||||
if (timepoints.length) {
|
||||
timepoints.forEach(function(timepoint) {
|
||||
if(timepoint.timepointID === timepointID) {
|
||||
timepoint.rois.push(roi);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
timepoints.push({timepointID: timepointID, rois: [roi]});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Returns new lesion number according to timepointID
|
||||
function getNewLesionNumber (timepointID) {
|
||||
var contentId = getContentId();
|
||||
var lesionNumberCounter = 0;
|
||||
var timepointsData = Measurements.find({contentId: contentId}).fetch();
|
||||
if(timepointsData.length > 0) {
|
||||
for(var i=0; i< timepointsData.length; i++) {
|
||||
var timepointData = timepointsData[i];
|
||||
var timepoints = timepointData.lesionData.timepoints;
|
||||
for(var j=0; j< timepoints.length; j++) {
|
||||
var timepoint = timepoints[j];
|
||||
var key = Object.keys(timepoint);
|
||||
if(key == timepointID) {
|
||||
if (timepoint[key].longestDiameter === "") {
|
||||
return timepointData.lesionData.lesionNumber;
|
||||
function getNewLesionNumber(timepointID) {
|
||||
// Get all current lesion measurements
|
||||
var measurements = Measurements.find().fetch();
|
||||
|
||||
} else {
|
||||
lesionNumberCounter = lesionNumberCounter + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log(lesionNumberCounter + 1);
|
||||
|
||||
return lesionNumberCounter + 1;
|
||||
// If no measurements exist yet, start at 1
|
||||
if (!measurements.length) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
// If measurements exist, find the last lesion number
|
||||
// from the given timepoint
|
||||
var lesionNumberCounter = 0;
|
||||
for (var i = 0; i < measurements.length; i++) {
|
||||
var measurement = measurements[i];
|
||||
var timepoints = measurement.timepoints;
|
||||
|
||||
if (timepoints[timepointID].longestDiameter === '') {
|
||||
return measurement.lesionNumber;
|
||||
} else {
|
||||
lesionNumberCounter = lesionNumberCounter + 1;
|
||||
}
|
||||
}
|
||||
console.log(lesionNumberCounter + 1);
|
||||
return lesionNumberCounter + 1;
|
||||
}
|
||||
|
||||
// If lesion number is added for any timepoint, returns lesion locationUID
|
||||
function isLesionNumberAdded (lesionNumber) {
|
||||
if (timepointDataIsFound(lesionNumber)){
|
||||
var contentId = getContentId();
|
||||
var timepointData = Measurements.find({contentId: contentId, "lesionData.lesionNumber": lesionNumber}).fetch();
|
||||
return timepointData[0].lesionData.locationUID;
|
||||
|
||||
function isLesionNumberAdded(lesionNumber) {
|
||||
if (!timepointDataIsFound(lesionNumber)) {
|
||||
return;
|
||||
}
|
||||
return null
|
||||
|
||||
var measurement = Measurements.find({
|
||||
lesionNumber: lesionNumber
|
||||
}).fetch()[0];
|
||||
|
||||
return measurement.locationUID;
|
||||
}
|
||||
|
||||
return {
|
||||
addNewLocation: addPatientLocation,
|
||||
getLocations: getPatientLocations,
|
||||
addLesionData: addLesionData,
|
||||
getLesionNumber: getNewLesionNumber,
|
||||
getNewLesionNumber: getNewLesionNumber,
|
||||
isLesionNumberAdded: isLesionNumberAdded,
|
||||
getTimepoints: getTimepoints,
|
||||
updateTimepointData: updateTimepointData
|
||||
|
||||
};
|
||||
})();
|
||||
@ -1,15 +1,15 @@
|
||||
Template.lesionDialog.onRendered(function () {
|
||||
// Show Lesion Dialog
|
||||
$(document).on("ShowLesionDialog", function (e, eventData, activeLesionMeasurementData) {
|
||||
|
||||
var locationUID = measurementManagerDAL.isLesionNumberAdded(activeLesionMeasurementData.lesionNumber);
|
||||
|
||||
if(locationUID != null) {
|
||||
|
||||
activeLesionMeasurementData.locationUID = locationUID;
|
||||
measurementManagerDAL.updateTimepointData(activeLesionMeasurementData);
|
||||
}else{
|
||||
// This event determines whether or not to show the lesion dialog
|
||||
// If there already exists a lesion with this specific lesion number,
|
||||
// related to the chosen location.
|
||||
|
||||
$(document).on("ShowLesionDialog", function (e, eventData, lesionData) {
|
||||
var locationUID = measurementManagerDAL.isLesionNumberAdded(lesionData.lesionNumber);
|
||||
|
||||
if (locationUID) {
|
||||
lesionData.locationUID = locationUID;
|
||||
measurementManagerDAL.updateTimepointData(lesionData);
|
||||
} else {
|
||||
// Show Dialog
|
||||
var dialogPointsOnPage = eventData.currentPoints.page;
|
||||
$("#modal-dialog-container").css({
|
||||
@ -19,7 +19,6 @@ Template.lesionDialog.onRendered(function () {
|
||||
|
||||
$("#lesionDialog").modal("show");
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -1,22 +1,36 @@
|
||||
var lastAddedLesionData;
|
||||
|
||||
//fill selectLesionLocation element
|
||||
var lesionLocationsArray = [
|
||||
{location:"Brain Brainstem",hasDescription:false, description:""},
|
||||
{location:"Brain Cerebellum Left",hasDescription:false, description:""},
|
||||
{location:"Brain Cerebrum Left",hasDescription:false, description:""},
|
||||
{location:"Brain Cerebrum Right",hasDescription:false, description:""},
|
||||
{location:"Brain Multiple Sites",hasDescription:false, description:""}
|
||||
];
|
||||
var lesionLocationsArray = [{
|
||||
location: "Brain Brainstem",
|
||||
hasDescription: false,
|
||||
description: ""
|
||||
}, {
|
||||
location: "Brain Cerebellum Left",
|
||||
hasDescription: false,
|
||||
description: ""
|
||||
}, {
|
||||
location: "Brain Cerebrum Left",
|
||||
hasDescription: false,
|
||||
description: ""
|
||||
}, {
|
||||
location: "Brain Cerebrum Right",
|
||||
hasDescription: false,
|
||||
description: ""
|
||||
}, {
|
||||
location: "Brain Multiple Sites",
|
||||
hasDescription: false,
|
||||
description: ""
|
||||
}];
|
||||
|
||||
Template.lesionLocationDialog.onRendered(function () {
|
||||
Template.lesionLocationDialog.onRendered(function() {
|
||||
console.log(this.data);
|
||||
|
||||
function fillSelectLesionLocation () {
|
||||
function fillSelectLesionLocation() {
|
||||
var el = $("#selectLesionLocation");
|
||||
el.find('option:not(:first)').remove();
|
||||
$.each(lesionLocationsArray, function(key, value) {
|
||||
el.append("<option value='" + key+ "'>" + value.location + "</option>");
|
||||
el.append("<option value='" + key + "'>" + value.location + "</option>");
|
||||
});
|
||||
}
|
||||
|
||||
@ -25,7 +39,7 @@ Template.lesionLocationDialog.onRendered(function () {
|
||||
|
||||
// Observe Measurements Collection Changes
|
||||
Measurements.find().observe({
|
||||
added: function (lesionData) {
|
||||
added: function(lesionData) {
|
||||
lastAddedLesionData = lesionData;
|
||||
},
|
||||
changed: function(lesionData) {
|
||||
@ -35,44 +49,44 @@ Template.lesionLocationDialog.onRendered(function () {
|
||||
});
|
||||
|
||||
Template.lesionLocationDialog.events({
|
||||
'click button#btnCloseLesionPopup': function (e) {
|
||||
'click button#btnCloseLesionPopup': function(e) {
|
||||
$("#lesionDialog").modal("hide");
|
||||
// TODO: Remove lastAddedLesionData from canvas
|
||||
// TODO: Remove lastAddedLesionData from collection
|
||||
|
||||
},
|
||||
|
||||
'change select#selectLesionLocation': function (e) {
|
||||
'change select#selectLesionLocation': function(e) {
|
||||
var el = $(e.target);
|
||||
var selectedLocationIndex = el.val();
|
||||
if(selectedLocationIndex !== "-1"){
|
||||
|
||||
// Get selected location data
|
||||
var locationObj = lesionLocationsArray[selectedLocationIndex];
|
||||
|
||||
// Gets active lesion measurement data that is latest added data
|
||||
var activeLesionMeasurementData = Session.get("lesionMeasurementData");
|
||||
|
||||
// Adds location data to trialPatientLocations array and returns locationUID
|
||||
var locationUID = measurementManagerDAL.addNewLocation(locationObj);
|
||||
|
||||
// Linkk locationUID with activeLesionMeasurementData
|
||||
activeLesionMeasurementData.locationUID = locationUID;
|
||||
|
||||
// Adds lesion data to timepoints array
|
||||
measurementManagerDAL.addLesionData(activeLesionMeasurementData);
|
||||
|
||||
// Trigger location selected event
|
||||
$(document).trigger("lesionLocationSelected",locationObj);
|
||||
|
||||
// Set activeModule parameters in index.html
|
||||
$("#lesionDialog").modal("hide");
|
||||
|
||||
// Select first option
|
||||
el.val($("#selectLesionLocation option:first").val());
|
||||
|
||||
// Set lesion location selected session to prevent open
|
||||
Session.set("lesionLocationSelected", true);
|
||||
if (selectedLocationIndex < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get selected location data
|
||||
var locationObj = lesionLocationsArray[selectedLocationIndex];
|
||||
|
||||
// Gets active lesion measurement data that is latest added data
|
||||
var activeLesionMeasurementData = Session.get("lesionMeasurementData");
|
||||
|
||||
// Adds location data to trialPatientLocations array and returns locationUID
|
||||
var locationUID = measurementManagerDAL.addNewLocation(locationObj);
|
||||
|
||||
// Linkk locationUID with activeLesionMeasurementData
|
||||
activeLesionMeasurementData.locationUID = locationUID;
|
||||
|
||||
// Adds lesion data to timepoints array
|
||||
measurementManagerDAL.addLesionData(activeLesionMeasurementData);
|
||||
|
||||
// Trigger location selected event
|
||||
$(document).trigger("lesionLocationSelected", locationObj);
|
||||
|
||||
// Set activeModule parameters in index.html
|
||||
$("#lesionDialog").modal("hide");
|
||||
|
||||
// Select first option
|
||||
el.val($("#selectLesionLocation option:first").val());
|
||||
|
||||
// Set lesion location selected session to prevent open
|
||||
Session.set("lesionLocationSelected", true);
|
||||
}
|
||||
});
|
||||
@ -7,21 +7,17 @@
|
||||
<th id="thLocation">Location</th>
|
||||
<th id="thTarget">Target</th>
|
||||
<!--Each time point name as a column-->
|
||||
{{ #each tabTimepoints }}
|
||||
{{ #each timepoints }}
|
||||
{{ >lesionTableTimepointHeader }}
|
||||
{{ /each }}
|
||||
{{ #each timepoints }}
|
||||
{{ >lesionTableTimepointHeader }}
|
||||
{{ /each }}
|
||||
<th id="thSpacer"> </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!--Each measurement as row-->
|
||||
{{ #each measurement }}
|
||||
{{ >lesionTableRow }}
|
||||
{{ /each }}
|
||||
|
||||
<!--Each measurement as row-->
|
||||
<!--Each time point as a column-->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@ -1,103 +1,78 @@
|
||||
Measurements = new Meteor.Collection(null);
|
||||
TabsTimepoints = new Meteor.Collection(null);
|
||||
Timepoints = new Meteor.Collection(null);
|
||||
|
||||
// Activate selected lesions when lesion table row is clicked
|
||||
function updateLesions(e) {
|
||||
// lesionNumber of measurement = id of row
|
||||
var lesionNumber = parseInt($(e.currentTarget).attr("id"), 10);
|
||||
|
||||
// Find data for specific lesion
|
||||
var measurementData = Measurements.find({
|
||||
lesionNumber: lesionNumber
|
||||
}).fetch()[0];
|
||||
|
||||
var timepoints = measurementData.timepoints;
|
||||
|
||||
$(".imageViewerViewport").each(function(index, element) {
|
||||
// Get the timepointID related to the image viewer viewport
|
||||
// from the DOM itself. This will be changed later when a
|
||||
// real association between viewports and timepoints is created.
|
||||
var timepointID = $(element).data('timepointID');
|
||||
var timepointObject = timepoints[timepointID];
|
||||
|
||||
// Defines event data
|
||||
var eventData = {
|
||||
enabledElement: cornerstone.getEnabledElement(element),
|
||||
lesionData: {
|
||||
lesionNumber: lesionNumber,
|
||||
imageId: timepointObject.imageId
|
||||
},
|
||||
type: "active"
|
||||
};
|
||||
|
||||
if (timepointObject.longestDiameter === "") {
|
||||
eventData.type = "inactive";
|
||||
}
|
||||
|
||||
$(element).trigger("LesionToolModified", eventData);
|
||||
});
|
||||
}
|
||||
|
||||
Template.lesionTable.onRendered(function() {
|
||||
// For the moment we will associate the timepoint
|
||||
// with the viewport element by storing the timepointID
|
||||
// inside the element's DOM data. This is temporary.
|
||||
$(".imageViewerViewport").each(function(index, element) {
|
||||
var timepointID = uuid.v4();
|
||||
|
||||
var timepointName = "Baseline";
|
||||
if (index > 0) {
|
||||
timepointName = "Current"; //"Follow Up "+i;
|
||||
}
|
||||
|
||||
|
||||
// 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({
|
||||
'measurement': function() {
|
||||
var contentId = this.contentId;
|
||||
return Measurements.find({contentId: contentId});
|
||||
return Measurements.find();
|
||||
},
|
||||
'tabTimepoints': function() {
|
||||
var contentId = this.contentId;
|
||||
return TabsTimepoints.find({contentId: contentId});
|
||||
},
|
||||
'lesionData': function() {
|
||||
var array = [];
|
||||
var lesions = this.lesionData;
|
||||
Object.keys(lesions).forEach(function(key) {
|
||||
array.push(lesions[key]);
|
||||
});
|
||||
return array;
|
||||
'timepoints': function() {
|
||||
return Timepoints.find();
|
||||
}
|
||||
});
|
||||
|
||||
Template.lesionTable.onRendered(function() {
|
||||
|
||||
var contentId = this.data.contentId;
|
||||
var viewportColumns = ViewerData[contentId].viewportColumns;
|
||||
var viewportRows = ViewerData[contentId].viewportRows;
|
||||
|
||||
var totalViewports = viewportColumns * viewportRows;
|
||||
|
||||
var timepointsArray = [];
|
||||
for(var i=0; i< totalViewports; i++) {
|
||||
var timepointID = contentId.toString() + i.toString();
|
||||
var timepointName = "Baseline";
|
||||
if (i > 0) {
|
||||
timepointName = "Current"; //"Follow Up "+i;
|
||||
}
|
||||
var timepointObject = {timepointID: timepointID, timepointName: timepointName};
|
||||
timepointsArray.push(timepointObject);
|
||||
|
||||
}
|
||||
|
||||
// Prevent duplicate data when onRendered is called
|
||||
var tabTimepoint = TabsTimepoints.find({contentId: contentId}).fetch();
|
||||
if (tabTimepoint !== undefined && tabTimepoint.length > 0) {
|
||||
// Update timepoints
|
||||
TabsTimepoints.update(
|
||||
{ contentId: contentId},
|
||||
{
|
||||
$set: {
|
||||
timepoints: timepointsArray
|
||||
}
|
||||
}, {multi: true}
|
||||
);
|
||||
} else {
|
||||
|
||||
// Insert new timepoints array
|
||||
TabsTimepoints.insert({contentId: contentId, timepoints: timepointsArray});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Activate selected lesions when lesion table row is clicked
|
||||
function updateLesions (e) {
|
||||
|
||||
// lesionNumber of measurement = id of row
|
||||
var lesionNumber = parseInt($(e.currentTarget).attr("id"));
|
||||
var contentId = Session.get("activeContentId");
|
||||
var measurementData = Measurements.find({contentId:contentId,"lesionData.lesionNumber":lesionNumber}).fetch();
|
||||
var timepoints = measurementData[0].lesionData.timepoints;
|
||||
var imageViewportElements = $("#"+contentId).find(".imageViewerViewport");
|
||||
|
||||
for( var i=0; i< imageViewportElements.length; i++) {
|
||||
var timepointObject = timepoints[i];
|
||||
var timepointKey = Object.keys(timepointObject);
|
||||
var imageId = timepointObject[timepointKey].imageId;
|
||||
var longestDiameter = timepointObject[timepointKey].longestDiameter;
|
||||
var imageViewportElement = imageViewportElements[i];
|
||||
var eventObject = {};
|
||||
|
||||
if(longestDiameter != "") {
|
||||
eventObject = {
|
||||
enabledElement: cornerstone.getEnabledElement(imageViewportElement),
|
||||
lesionData: {lesionNumber: lesionNumber, imageId: imageId},
|
||||
type: "active"
|
||||
};
|
||||
} else {
|
||||
eventObject = {
|
||||
enabledElement: cornerstone.getEnabledElement(imageViewportElement),
|
||||
lesionData: {lesionNumber: lesionNumber, imageId: imageId},
|
||||
type: "inactive"
|
||||
};
|
||||
}
|
||||
$(imageViewportElement).trigger("LesionToolModified", eventObject);
|
||||
}
|
||||
}
|
||||
|
||||
Template.lesionTable.events({
|
||||
'click table#tblLesion tbody tr': function(e) {
|
||||
updateLesions(e);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
@ -1,11 +1,11 @@
|
||||
<template name="lesionTableRow">
|
||||
<tr id="{{lesionData.lesionNumber}}" class="lesionTableRow">
|
||||
<td class='lesionNumber'>{{lesionData.lesionNumber}}</td>
|
||||
<td class='location'>{{lesionData.location}}</td>
|
||||
<td class='target'>{{#if lesionData.isTarget}} Y {{else}} N {{/if}}</td>
|
||||
<tr id="{{lesionNumber}}" class="lesionTableRow">
|
||||
<td class='lesionNumber'>{{lesionNumber}}</td>
|
||||
<td class='location'>{{location}}</td>
|
||||
<td class='target'>{{#if isTarget}} Y {{else}} N {{/if}}</td>
|
||||
<!--Each time point as a column-->
|
||||
{{# each timepoints }}
|
||||
{{> lesionTableTimepointCell }}
|
||||
{{> lesionTableTimepointCell}}
|
||||
{{/ each }}
|
||||
</tr>
|
||||
</template>
|
||||
@ -1,5 +1,5 @@
|
||||
Template.lesionTableRow.helpers({
|
||||
'timepoints': function() {
|
||||
return this.lesionData.timepoints;
|
||||
return Timepoints.find();
|
||||
}
|
||||
});
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
Template.lesionTableTimepointCell.helpers({
|
||||
'longestDiameter': function() {
|
||||
var longestDiameter = this[Object.keys(this)[0]].longestDiameter;
|
||||
return longestDiameter;
|
||||
// Search Measurements by lesion and timepoint
|
||||
var lesionData = Template.parentData(1);
|
||||
return lesionData.timepoints[this.timepointID].longestDiameter;
|
||||
}
|
||||
});
|
||||
@ -1,5 +0,0 @@
|
||||
Template.lesionTableTimepointHeader.helpers({
|
||||
'timepoints': function (){
|
||||
return this.timepoints;
|
||||
}
|
||||
});
|
||||
@ -1,7 +0,0 @@
|
||||
getActiveTimepointID = function (viewportElement) {
|
||||
var contentId = Session.get("activeContentId");
|
||||
var imageViewportElements = $("#"+contentId).find(".imageViewerViewport");
|
||||
var index = $(imageViewportElements).index(viewportElement);
|
||||
|
||||
return contentId.toString() + index.toString();
|
||||
};
|
||||
@ -41,4 +41,7 @@ Package.onUse(function (api) {
|
||||
api.addFiles('lib/getActiveTimepointID.js', 'client');
|
||||
api.addFiles('lib/uuid.js', 'client');
|
||||
|
||||
api.export('Measurements', 'client');
|
||||
api.export('Timepoints', 'client');
|
||||
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user