Updated lesionTable to store measurement ID. Worked on refactoring functions in lesionTable.js to allow loading of series from a click on a row
This commit is contained in:
parent
a3c0048490
commit
9ad2ccaaaf
@ -8,4 +8,6 @@ Meteor.startup(function() {
|
|||||||
mouse: cornerstoneTools.nonTarget,
|
mouse: cornerstoneTools.nonTarget,
|
||||||
touch: cornerstoneTools.nonTargetTouch
|
touch: cornerstoneTools.nonTargetTouch
|
||||||
});
|
});
|
||||||
|
|
||||||
|
toolManager.setAlwaysEnabledTools(['lesion', 'nonTarget']);
|
||||||
});
|
});
|
||||||
@ -9,7 +9,7 @@ var cornerstoneTools = (function($, cornerstone, cornerstoneMath, cornerstoneToo
|
|||||||
|
|
||||||
var configuration = {
|
var configuration = {
|
||||||
getLesionLocationCallback: getLesionLocationCallback,
|
getLesionLocationCallback: getLesionLocationCallback,
|
||||||
changeLesionLocationCallback: changeLesionLocationCallback,
|
changeLesionLocationCallback: changeLesionLocationCallback
|
||||||
};
|
};
|
||||||
|
|
||||||
// Define a callback to get your text annotation
|
// Define a callback to get your text annotation
|
||||||
@ -179,19 +179,19 @@ var cornerstoneTools = (function($, cornerstone, cornerstoneMath, cornerstoneToo
|
|||||||
return cornerstoneMath.point.insideRect(coords, handle.boundingBox);
|
return cornerstoneMath.point.insideRect(coords, handle.boundingBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
function suscribeLesionToolSelectedEvent(element) {
|
function subscribeLesionToolSelectedEvent(element) {
|
||||||
var elementEvents = $._data(element, "events");
|
var elementEvents = $._data(element, "events");
|
||||||
var index = Object.keys(elementEvents).indexOf("LesionToolSelected");
|
var index = Object.keys(elementEvents).indexOf("LesionToolSelected");
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
// Subscribe LesionToolSelected and calls measurementModified function when lesion measurement is changed or updated.
|
// Subscribe LesionToolSelected and calls loadImage when lesion measurement is changed or updated.
|
||||||
$(element).on("LesionToolSelected", measurementModified);
|
$(element).on("LesionToolSelected", loadImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
///////// BEGIN IMAGE RENDERING ///////
|
///////// BEGIN IMAGE RENDERING ///////
|
||||||
function onImageRendered(e, eventData) {
|
function onImageRendered(e, eventData) {
|
||||||
|
|
||||||
suscribeLesionToolSelectedEvent(e.currentTarget);
|
subscribeLesionToolSelectedEvent(e.currentTarget);
|
||||||
|
|
||||||
// if we have no toolData for this element, return immediately as there is nothing to do
|
// if we have no toolData for this element, return immediately as there is nothing to do
|
||||||
var toolData = cornerstoneTools.getToolState(e.currentTarget, toolType);
|
var toolData = cornerstoneTools.getToolState(e.currentTarget, toolType);
|
||||||
@ -228,14 +228,13 @@ var cornerstoneTools = (function($, cornerstone, cornerstoneMath, cornerstoneToo
|
|||||||
var color;
|
var color;
|
||||||
var element = eventData.element;
|
var element = eventData.element;
|
||||||
var lineWidth = cornerstoneTools.toolStyle.getToolWidth();
|
var lineWidth = cornerstoneTools.toolStyle.getToolWidth();
|
||||||
var font = cornerstoneTools.textStyle.getFont();
|
|
||||||
var config = cornerstoneTools.lesion.getConfiguration();
|
var config = cornerstoneTools.lesion.getConfiguration();
|
||||||
|
|
||||||
// configurable shadow from CornerstoneTools
|
// configurable shadow from CornerstoneTools
|
||||||
if (config && config.shadow) {
|
if (config && config.shadow) {
|
||||||
context.shadowColor = '#000000';
|
context.shadowColor = '#000000';
|
||||||
context.shadowOffsetX = +1;
|
context.shadowOffsetX = 1;
|
||||||
context.shadowOffsetY = +1;
|
context.shadowOffsetY = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.active) {
|
if (data.active) {
|
||||||
@ -364,21 +363,23 @@ var cornerstoneTools = (function($, cornerstone, cornerstoneMath, cornerstoneToo
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO=Refactor because this function is repeated in nonTargetTool!
|
||||||
function loadImage(e, eventData) {
|
function loadImage(e, eventData) {
|
||||||
// If type is active, load image and activate lesion
|
// If type is active, load image and activate lesion
|
||||||
// If type is inactive, update lesions of enabledElement as inactive
|
// If type is inactive, update lesions of enabledElement as inactive
|
||||||
|
log.info('lesionTool loadImage');
|
||||||
|
var element = eventData.enabledElement.element;
|
||||||
|
var imageId = eventData.lesionData.imageId;
|
||||||
if (eventData.type === "active") {
|
if (eventData.type === "active") {
|
||||||
var stackToolDataSource = cornerstoneTools.getToolState(e.currentTarget, 'stack');
|
var stackToolDataSource = cornerstoneTools.getToolState(element, 'stack');
|
||||||
var stackData = stackToolDataSource.data[0];
|
var stackData = stackToolDataSource.data[0];
|
||||||
var imageIds = stackData.imageIds;
|
var imageIdIndex = stackData.imageIds.indexOf(imageId);
|
||||||
var imageIdIndex = imageIds.indexOf(eventData.lesionData.imageId);
|
|
||||||
if (imageIdIndex < 0) {
|
if (imageIdIndex < 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cornerstone.loadAndCacheImage(imageIds[imageIdIndex]).then(function(image) {
|
cornerstone.loadAndCacheImage(imageIds[imageIdIndex]).then(function(image) {
|
||||||
cornerstone.displayImage(eventData.enabledElement.element, image);
|
cornerstone.displayImage(element, image);
|
||||||
updateLesion(e, eventData);
|
updateLesion(e, eventData);
|
||||||
});
|
});
|
||||||
} else if (eventData.type === "inactive") {
|
} else if (eventData.type === "inactive") {
|
||||||
@ -386,11 +387,6 @@ var cornerstoneTools = (function($, cornerstone, cornerstoneMath, cornerstoneToo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//This function is called from cornerstone-viewport.html and updates lesion measurement and makes the lesion active
|
|
||||||
function measurementModified(e, eventData) {
|
|
||||||
loadImage(e, eventData);
|
|
||||||
}
|
|
||||||
|
|
||||||
// module exports
|
// module exports
|
||||||
cornerstoneTools.lesion = cornerstoneTools.mouseButtonTool({
|
cornerstoneTools.lesion = cornerstoneTools.mouseButtonTool({
|
||||||
createNewMeasurement: createNewMeasurement,
|
createNewMeasurement: createNewMeasurement,
|
||||||
|
|||||||
@ -186,19 +186,18 @@
|
|||||||
context.fill();
|
context.fill();
|
||||||
}
|
}
|
||||||
|
|
||||||
function suscribeNonTargetToolModifiedEvent(element) {
|
function subscribeNonTargetToolModifiedEvent(element) {
|
||||||
var elementEvents = $._data(element, "events");
|
var elementEvents = $._data(element, "events");
|
||||||
var index = Object.keys(elementEvents).indexOf("NonTargetToolSelected");
|
var index = Object.keys(elementEvents).indexOf("NonTargetToolSelected");
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
// Subscribe LesionToolModified and calls measurementModified function when lesion measurement is changed or updated.
|
// Subscribe LesionToolModified and calls loadImage function when lesion measurement is changed or updated.
|
||||||
$(element).on("NonTargetToolSelected", measurementModified);
|
$(element).on("NonTargetToolSelected", loadImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
///////// BEGIN IMAGE RENDERING ///////
|
///////// BEGIN IMAGE RENDERING ///////
|
||||||
function onImageRendered(e, eventData) {
|
function onImageRendered(e, eventData) {
|
||||||
|
subscribeNonTargetToolModifiedEvent(e.currentTarget);
|
||||||
suscribeNonTargetToolModifiedEvent(e.currentTarget);
|
|
||||||
|
|
||||||
// if we have no toolData for this element, return immediately as there is nothing to do
|
// if we have no toolData for this element, return immediately as there is nothing to do
|
||||||
var toolData = cornerstoneTools.getToolState(e.currentTarget, toolType);
|
var toolData = cornerstoneTools.getToolState(e.currentTarget, toolType);
|
||||||
@ -268,7 +267,7 @@
|
|||||||
context.beginPath();
|
context.beginPath();
|
||||||
context.strokeStyle = color;
|
context.strokeStyle = color;
|
||||||
context.lineWidth = 1 / eventData.viewport.scale;
|
context.lineWidth = 1 / eventData.viewport.scale;
|
||||||
var mid = {
|
mid = {
|
||||||
x: mid.x,
|
x: mid.x,
|
||||||
y: mid.y
|
y: mid.y
|
||||||
};
|
};
|
||||||
@ -390,7 +389,7 @@
|
|||||||
|
|
||||||
// if we have no toolData for this element, return immediately as there is nothing to do
|
// if we have no toolData for this element, return immediately as there is nothing to do
|
||||||
var toolData = cornerstoneTools.getToolState(e.currentTarget, toolType);
|
var toolData = cornerstoneTools.getToolState(e.currentTarget, toolType);
|
||||||
if (toolData === undefined) {
|
if (!toolData) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -463,31 +462,27 @@
|
|||||||
onImageRendered(e, eventData);
|
onImageRendered(e, eventData);
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadImage(e, eventObject) {
|
function loadImage(e, eventData) {
|
||||||
// If type is active, load image and activate lesion
|
// If type is active, load image and activate lesion
|
||||||
// If type is inactive, update lesions of enabledElement as inactive
|
// If type is inactive, update lesions of enabledElement as inactive
|
||||||
|
log.info('nonTargetTool loadImage');
|
||||||
if (eventObject.type === "active") {
|
var element = eventData.enabledElement.element;
|
||||||
var stackToolDataSource = cornerstoneTools.getToolState(e.currentTarget, 'stack');
|
var imageId = eventData.lesionData.imageId;
|
||||||
|
if (eventData.type === "active") {
|
||||||
|
var stackToolDataSource = cornerstoneTools.getToolState(element, 'stack');
|
||||||
var stackData = stackToolDataSource.data[0];
|
var stackData = stackToolDataSource.data[0];
|
||||||
var imageIdsArr = stackData.imageIds;
|
var imageIdIndex = stackData.imageIds.indexOf(imageId);
|
||||||
var indexOfImage = imageIdsArr.indexOf(eventObject.lesionData.imageId);
|
if (imageIdIndex < 0) {
|
||||||
if (indexOfImage > -1) {
|
return;
|
||||||
cornerstone.loadAndCacheImage(stackData.imageIds[indexOfImage]).then(function(image) {
|
}
|
||||||
cornerstone.displayImage(eventObject.enabledElement.element, image);
|
|
||||||
updateLesion(e, eventObject);
|
cornerstone.loadAndCacheImage(stackData.imageIds[imageIdIndex]).then(function(image) {
|
||||||
|
cornerstone.displayImage(element, image);
|
||||||
|
updateLesion(e, eventData);
|
||||||
});
|
});
|
||||||
|
} else if (eventData.type === "inactive") {
|
||||||
|
updateLesion(e, eventData);
|
||||||
}
|
}
|
||||||
} else if (eventObject.type === "inactive") {
|
|
||||||
updateLesion(e, eventObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//This function is called from cornerstone-viewport.html and updates lesion measurement and makes the lesion active
|
|
||||||
function measurementModified(e, eventObject) {
|
|
||||||
loadImage(e, eventObject);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cornerstoneTools.nonTarget = cornerstoneTools.mouseButtonTool({
|
cornerstoneTools.nonTarget = cornerstoneTools.mouseButtonTool({
|
||||||
|
|||||||
@ -1,50 +1,46 @@
|
|||||||
// Get enabled elements in viewport
|
/**
|
||||||
// Returns enabled elements with associated elements as object array
|
* Returns timepoint object based on timepoint id of the enabled element
|
||||||
function getEnabledElementsInViewport() {
|
*
|
||||||
var enabledElementsInViewport = [];
|
* @param timepoints
|
||||||
|
* @param enabledElement
|
||||||
|
* @returns {*|{}} Timepoint object based on timepoint id of the enabled element (or an empty Object)
|
||||||
|
*/
|
||||||
|
function getTimepointObject(imageId) {
|
||||||
|
var study = cornerstoneTools.metaData.get('study', imageId);
|
||||||
|
|
||||||
$(".imageViewerViewport").each(function(index, element) {
|
var timepoint = Timepoints.findOne({timepointName: study.studyDate});
|
||||||
var enabledElement = cornerstone.getEnabledElement(element);
|
return timepoint;
|
||||||
if (!enabledElement) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
enabledElementsInViewport.push({element: element, enabledElement: enabledElement});
|
|
||||||
});
|
|
||||||
|
|
||||||
return enabledElementsInViewport;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Switch to the image of the correct image index
|
/**
|
||||||
// Activate the selected measurement on the switched image (color to be green)
|
* Switch to the image of the correct image index
|
||||||
// Deactivate all other measurements on the switched image (color to be white)
|
* Activate the selected measurement on the switched image (color to be green)
|
||||||
function activateMeasurementsInRelatedImages(timepoints, lesionNumber, isTarget) {
|
* Deactivate all other measurements on the switched image (color to be white)
|
||||||
|
*/
|
||||||
|
function activateMeasurements(element, measurementId) {
|
||||||
|
// TODO=Switch this to use the new CornerstoneToolMeasurementModified event,
|
||||||
|
// Once it has 'modified on activation' set up
|
||||||
|
|
||||||
//TODO: This is a bad hack! We need to listen an event of the element and handle it when rendering of the element is completed
|
var enabledElement = cornerstone.getEnabledElement(element);
|
||||||
//TODO: we can switch to the related image and activate the selected measurement on the switched image.
|
var imageId = enabledElement.image.imageId;
|
||||||
var intervalListener = setInterval(function() {
|
var timepointData = getTimepointObject(imageId);
|
||||||
window.clearInterval(intervalListener);
|
var measurementData = Measurements.findOne(measurementId);
|
||||||
|
|
||||||
var enabledElementsInViewport = getEnabledElementsInViewport();
|
var measurementAtTimepoint = measurementData.timepoints[timepointData.timepointID];
|
||||||
|
if (!measurementAtTimepoint) {
|
||||||
for(var i = 0; i < enabledElementsInViewport.length; i++) {
|
return;
|
||||||
var element = enabledElementsInViewport[i].element;
|
|
||||||
var enabledElement = enabledElementsInViewport[i].enabledElement;
|
|
||||||
var timepointObject = getTimepointObject(timepoints, enabledElement);
|
|
||||||
|
|
||||||
if (timepointObject === undefined) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Defines event data
|
// Defines event data
|
||||||
var eventData = {
|
var eventData = {
|
||||||
enabledElement: enabledElement,
|
enabledElement: enabledElement,
|
||||||
lesionData: {
|
lesionData: {
|
||||||
isTarget: isTarget,
|
id: measurementId,
|
||||||
lesionNumber: lesionNumber,
|
isTarget: measurementData.isTarget,
|
||||||
imageId: timepointObject.imageId,
|
lesionNumber: measurementData.lesionNumber,
|
||||||
seriesInstanceUid: timepointObject.seriesInstanceUid,
|
imageId: imageId,
|
||||||
studyInstanceUid: timepointObject.studyInstanceUid
|
seriesInstanceUid: measurementAtTimepoint.seriesInstanceUid,
|
||||||
|
studyInstanceUid: measurementAtTimepoint.studyInstanceUid
|
||||||
},
|
},
|
||||||
type: "active"
|
type: "active"
|
||||||
};
|
};
|
||||||
@ -67,87 +63,75 @@ function activateMeasurementsInRelatedImages(timepoints, lesionNumber, isTarget)
|
|||||||
// Deactivate nonTarget tool measurements
|
// Deactivate nonTarget tool measurements
|
||||||
eventData.type = "inactive";
|
eventData.type = "inactive";
|
||||||
|
|
||||||
// Triggger event for nonTarget measurements
|
// Trigger event for nonTarget measurements
|
||||||
// Inactivate all nonTarget measurements if any measurement is active
|
// Inactivate all nonTarget measurements if any measurement is active
|
||||||
$(element).trigger("NonTargetToolSelected", eventData);
|
$(element).trigger("NonTargetToolSelected", eventData);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}, 100);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns timepoint object based on timepoint id of the enabled element
|
/**
|
||||||
function getTimepointObject(timepoints, enabledElement) {
|
* Activates a set of lesions when lesion table row is clicked
|
||||||
var imageId = enabledElement.image.imageId;
|
*
|
||||||
var study = cornerstoneTools.metaData.get('study', imageId);
|
* @param measurementId The unique key for a specific Measurement
|
||||||
var series = cornerstoneTools.metaData.get('series', imageId);
|
*/
|
||||||
|
function activateLesion(measurementId) {
|
||||||
// Get the timepointID related to the image viewer viewport
|
// Find Measurement data for this lesion
|
||||||
// from the DOM itself. This will be changed later when a
|
var measurementData = Measurements.findOne(measurementId);
|
||||||
// real association between viewports and timepoints is created.
|
|
||||||
var timepoint = Timepoints.findOne({timepointName: study.studyDate});
|
|
||||||
if (!timepoint) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var timepointID = timepoint.timepointID;
|
|
||||||
|
|
||||||
var timepointObject = timepoints[timepointID];
|
|
||||||
|
|
||||||
if (timepointObject === undefined) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!timepointObject ) {
|
|
||||||
timepointObject = {}
|
|
||||||
}
|
|
||||||
|
|
||||||
return timepointObject;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
// TODO= Clarify this
|
|
||||||
// Get Target column value
|
|
||||||
// Search and update data according to target type
|
|
||||||
var isTarget = $(e.currentTarget).find('td').eq(2).html().trim() === 'N'?false:true;
|
|
||||||
|
|
||||||
// Find data for specific lesion
|
|
||||||
var measurementData = Measurements.findOne({
|
|
||||||
lesionNumber: lesionNumber,
|
|
||||||
isTarget: isTarget
|
|
||||||
});
|
|
||||||
|
|
||||||
|
// If there is no measurement with this ID, stop here
|
||||||
if (!measurementData) {
|
if (!measurementData) {
|
||||||
|
log.warn('No Measurements entry associated to an ID in a lesion table row');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the timepoint data from this Measurement
|
||||||
var timepoints = measurementData.timepoints;
|
var timepoints = measurementData.timepoints;
|
||||||
var enabledElementsInViewport = getEnabledElementsInViewport();
|
|
||||||
|
|
||||||
// Render related series
|
// Loop through the viewports and display each timepoint
|
||||||
for(var i = 0; i < enabledElementsInViewport.length; i++) {
|
$(".imageViewerViewport").each(function(viewportIndex, element) {
|
||||||
var element = enabledElementsInViewport[i].element;
|
// Stop if we run out of timepoints before viewports
|
||||||
var enabledElement = enabledElementsInViewport[i].enabledElement;
|
if (viewportIndex >= Object.keys(timepoints).length) {
|
||||||
|
return false;
|
||||||
var timepointObject = getTimepointObject(timepoints, enabledElement);
|
|
||||||
|
|
||||||
if (timepointObject === undefined || timepointObject.seriesInstanceUid === "") {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var newSeriesData = {
|
// Find the image that is currently in this viewport
|
||||||
seriesInstanceUid: timepointObject.seriesInstanceUid,
|
var enabledElement = cornerstone.getEnabledElement(element);
|
||||||
studyInstanceUid: timepointObject.studyInstanceUid
|
if (!enabledElement || !enabledElement.image) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find measurements related to the Nth timepoint
|
||||||
|
// TODO=Re-evaluate this approach to populating viewports with timepoints
|
||||||
|
// What is the desired behaviour here?
|
||||||
|
var key = Object.keys(measurementData.timepoints)[viewportIndex];
|
||||||
|
var measurementAtTimepoint = measurementData.timepoints[key];
|
||||||
|
|
||||||
|
// If there is no measurement data to display, stop here
|
||||||
|
if (!measurementAtTimepoint) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check which study and series are required to display the measurement at this timepoint
|
||||||
|
var requiredSeriesData = {
|
||||||
|
seriesInstanceUid: measurementAtTimepoint.seriesInstanceUid,
|
||||||
|
studyInstanceUid: measurementAtTimepoint.studyInstanceUid
|
||||||
};
|
};
|
||||||
|
|
||||||
// Rerender the viewport using data for new series
|
// Check if the study / series we need is already the one in the viewport
|
||||||
rerenderViewportWithNewSeries(element, newSeriesData);
|
var currentSeriesData = OHIF.viewer.loadedSeriesData[viewportIndex];
|
||||||
|
if (currentSeriesData.seriesInstanceUid === measurementAtTimepoint.seriesInstanceUid &&
|
||||||
|
currentSeriesData.studyInstanceUid === measurementAtTimepoint.studyInstanceUid) {
|
||||||
|
// If it is, activate the measurements in this viewport and stop here
|
||||||
|
activateMeasurements(element, measurementId);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Activate selected measurements on the rendered series
|
// Otherwise, re-render the viewport with the required study/series, then
|
||||||
activateMeasurementsInRelatedImages(timepoints, lesionNumber, isTarget);
|
// add an onRendered callback to activate the measurements
|
||||||
|
rerenderViewportWithNewSeries(element, requiredSeriesData, function(element) {
|
||||||
|
activateMeasurements(element, measurementId);
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Template.lesionTable.helpers({
|
Template.lesionTable.helpers({
|
||||||
@ -155,12 +139,14 @@ Template.lesionTable.helpers({
|
|||||||
return Measurements.find({}, {sort: {number: 1}});
|
return Measurements.find({}, {sort: {number: 1}});
|
||||||
},
|
},
|
||||||
'timepoints': function() {
|
'timepoints': function() {
|
||||||
return Timepoints.find();
|
return Timepoints.find({}, {sort: {timepointName: 1}});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.lesionTable.events({
|
Template.lesionTable.events({
|
||||||
'click table#tblLesion tbody tr': function(e) {
|
'click table#tblLesion tbody tr': function(e) {
|
||||||
updateLesions(e);
|
// Retrieve the lesion id from the DOM data for this row
|
||||||
|
var measurementId = $(e.currentTarget).data('measurementid');
|
||||||
|
activateLesion(measurementId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1,5 +1,5 @@
|
|||||||
<template name="lesionTableRow">
|
<template name="lesionTableRow">
|
||||||
<tr id="{{lesionNumber}}" class="lesionTableRow">
|
<tr id="{{lesionNumber}}" class="lesionTableRow" data-measurementid="{{_id}}">
|
||||||
<td class='lesionNumber'>{{number}}</td>
|
<td class='lesionNumber'>{{number}}</td>
|
||||||
<td class='location'>{{location}}</td>
|
<td class='location'>{{location}}</td>
|
||||||
<td class='target'>{{#if isTarget}} Y {{else}} N {{/if}}</td>
|
<td class='target'>{{#if isTarget}} Y {{else}} N {{/if}}</td>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
Template.lesionTableRow.helpers({
|
Template.lesionTableRow.helpers({
|
||||||
'timepoints': function() {
|
'timepoints': function() {
|
||||||
return Timepoints.find();
|
return Timepoints.find({}, {sort: {timepointName: 1}});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -199,9 +199,10 @@ Template.thumbnailEntry.onRendered(function() {
|
|||||||
Template.thumbnailEntry.events({
|
Template.thumbnailEntry.events({
|
||||||
// Touch drag/drop events
|
// Touch drag/drop events
|
||||||
'touchstart .thumbnailEntry, mousedown .thumbnailEntry': function(e) {
|
'touchstart .thumbnailEntry, mousedown .thumbnailEntry': function(e) {
|
||||||
var data = Template.parentData(2);
|
var data = {
|
||||||
data.studyInstanceUid = this.stack.studyInstanceUid;
|
studyInstanceUid: this.stack.studyInstanceUid,
|
||||||
data.seriesInstanceUid = this.stack.seriesInstanceUid;
|
seriesInstanceUid: this.stack.seriesInstanceUid
|
||||||
|
};
|
||||||
thumbnailDragStartHandler(e, data);
|
thumbnailDragStartHandler(e, data);
|
||||||
},
|
},
|
||||||
'touchmove .thumbnailEntry': function(e) {
|
'touchmove .thumbnailEntry': function(e) {
|
||||||
|
|||||||
@ -146,16 +146,6 @@ function loadSeriesIntoViewport(data) {
|
|||||||
|
|
||||||
// Start loading the image.
|
// Start loading the image.
|
||||||
cornerstone.loadAndCacheImage(imageId).then(function(image) {
|
cornerstone.loadAndCacheImage(imageId).then(function(image) {
|
||||||
// Fire an event to give notice that a new series was loaded in the viewport
|
|
||||||
var eventType = "ViewerBaseSeriesLoaded";
|
|
||||||
var eventData = {
|
|
||||||
element: element,
|
|
||||||
stack: stack,
|
|
||||||
study: data.study,
|
|
||||||
series: data.series
|
|
||||||
};
|
|
||||||
$(document).trigger(eventType, eventData);
|
|
||||||
|
|
||||||
// If there is a saved object containing Cornerstone viewport data
|
// If there is a saved object containing Cornerstone viewport data
|
||||||
// (e.g. scale, invert, window settings) in the input data, apply it now.
|
// (e.g. scale, invert, window settings) in the input data, apply it now.
|
||||||
//
|
//
|
||||||
@ -311,6 +301,11 @@ function loadSeriesIntoViewport(data) {
|
|||||||
if (viewportIndex === Session.get('activeViewport')) {
|
if (viewportIndex === Session.get('activeViewport')) {
|
||||||
enablePrefetchOnElement(element);
|
enablePrefetchOnElement(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Run any renderedCallback that exists in the data context
|
||||||
|
if (data.renderedCallback && typeof data.renderedCallback === "function") {
|
||||||
|
data.renderedCallback(element);
|
||||||
|
}
|
||||||
}, function(error) {
|
}, function(error) {
|
||||||
// If something goes wrong while loading the image, fire the error handler.
|
// If something goes wrong while loading the image, fire the error handler.
|
||||||
errorLoadingHandler(element, imageId, error);
|
errorLoadingHandler(element, imageId, error);
|
||||||
@ -392,7 +387,7 @@ Template.imageViewerViewport.onRendered(function() {
|
|||||||
|
|
||||||
// If no seriesInstanceUid or studyInstanceUid were supplied, display the drag/drop
|
// If no seriesInstanceUid or studyInstanceUid were supplied, display the drag/drop
|
||||||
// instructions and then stop here since we don't know what to display in the viewport.
|
// instructions and then stop here since we don't know what to display in the viewport.
|
||||||
if (this.data.seriesInstanceUid === undefined || this.data.studyInstanceUid === undefined) {
|
if (!this.data.seriesInstanceUid || !this.data.studyInstanceUid) {
|
||||||
element.classList.add('empty');
|
element.classList.add('empty');
|
||||||
$(element).siblings('.imageViewerLoadingIndicator').css('display', 'none');
|
$(element).siblings('.imageViewerLoadingIndicator').css('display', 'none');
|
||||||
$(element).siblings('.viewportInstructions').show();
|
$(element).siblings('.viewportInstructions').show();
|
||||||
|
|||||||
@ -5,8 +5,9 @@
|
|||||||
*
|
*
|
||||||
* @param element
|
* @param element
|
||||||
* @param data An object containing a seriesIndex and studyIndex for a study to load into this viewport
|
* @param data An object containing a seriesIndex and studyIndex for a study to load into this viewport
|
||||||
|
* @function renderedCallback An optional callback to be executed after the new template is rendered
|
||||||
*/
|
*/
|
||||||
rerenderViewportWithNewSeries = function(element, data) {
|
rerenderViewportWithNewSeries = function(element, data, renderedCallback) {
|
||||||
// Get the container and index of the current viewport.
|
// Get the container and index of the current viewport.
|
||||||
// The parent container is identified because it is later removed from the DOM
|
// The parent container is identified because it is later removed from the DOM
|
||||||
var container = $(element).parents('.viewportContainer').get(0);
|
var container = $(element).parents('.viewportContainer').get(0);
|
||||||
@ -37,6 +38,11 @@ rerenderViewportWithNewSeries = function(element, data) {
|
|||||||
|
|
||||||
container.appendChild(newViewportContainer);
|
container.appendChild(newViewportContainer);
|
||||||
|
|
||||||
|
// Pass the renderedCallback to the imageViewerViewport template
|
||||||
|
if (renderedCallback && typeof renderedCallback === "function") {
|
||||||
|
data.renderedCallback = renderedCallback;
|
||||||
|
}
|
||||||
|
|
||||||
// Render and insert the template
|
// Render and insert the template
|
||||||
UI.renderWithData(Template.imageViewerViewport, data, newViewportContainer);
|
UI.renderWithData(Template.imageViewerViewport, data, newViewportContainer);
|
||||||
};
|
};
|
||||||
@ -1,5 +1,7 @@
|
|||||||
var activeTool;
|
var activeTool;
|
||||||
|
|
||||||
|
var alwaysEnabledTools;
|
||||||
|
|
||||||
var tools = {};
|
var tools = {};
|
||||||
|
|
||||||
var initialized = false;
|
var initialized = false;
|
||||||
@ -72,6 +74,9 @@ toolManager = {
|
|||||||
addTool: function(name, base) {
|
addTool: function(name, base) {
|
||||||
tools[name] = base;
|
tools[name] = base;
|
||||||
},
|
},
|
||||||
|
setAlwaysEnabledTools: function(tools) {
|
||||||
|
alwaysEnabledTools = tools;
|
||||||
|
},
|
||||||
setActiveTool: function(tool) {
|
setActiveTool: function(tool) {
|
||||||
if (!initialized) {
|
if (!initialized) {
|
||||||
toolManager.init();
|
toolManager.init();
|
||||||
@ -83,7 +88,10 @@ toolManager = {
|
|||||||
|
|
||||||
$('.imageViewerViewport').each(function(index, element) {
|
$('.imageViewerViewport').each(function(index, element) {
|
||||||
var canvases = $(element).find('canvas');
|
var canvases = $(element).find('canvas');
|
||||||
if (!element.classList.contains('empty') && canvases.length > 0) {
|
if (element.classList.contains('empty') || !canvases.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// First, deactivate the current active tool
|
// First, deactivate the current active tool
|
||||||
tools[activeTool].mouse.deactivate(element, 1);
|
tools[activeTool].mouse.deactivate(element, 1);
|
||||||
|
|
||||||
@ -91,7 +99,12 @@ toolManager = {
|
|||||||
tools[activeTool].touch.deactivate(element);
|
tools[activeTool].touch.deactivate(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
// First, get the stack toolData
|
// Enable any tools set as 'Always enabled'
|
||||||
|
alwaysEnabledTools.forEach(function(toolType) {
|
||||||
|
cornerstoneTools[toolType].enable(element);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get the stack toolData
|
||||||
var toolData = cornerstoneTools.getToolState(element, 'stack');
|
var toolData = cornerstoneTools.getToolState(element, 'stack');
|
||||||
if (!toolData || !toolData.data || !toolData.data.length) {
|
if (!toolData || !toolData.data || !toolData.data.length) {
|
||||||
return;
|
return;
|
||||||
@ -137,7 +150,6 @@ toolManager = {
|
|||||||
|
|
||||||
cornerstoneTools.zoomTouchPinch.activate(element);
|
cornerstoneTools.zoomTouchPinch.activate(element);
|
||||||
cornerstoneTools.panMultiTouch.activate(element);
|
cornerstoneTools.panMultiTouch.activate(element);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
activeTool = tool;
|
activeTool = tool;
|
||||||
},
|
},
|
||||||
|
|||||||
@ -86,7 +86,7 @@ function getMammoHangingProtocol() {
|
|||||||
SelectorCSValue: 'R CC',
|
SelectorCSValue: 'R CC',
|
||||||
FilterByCategory: 'SERIES_DESCRIPTION',
|
FilterByCategory: 'SERIES_DESCRIPTION',
|
||||||
FilterByOperator: 'MEMBER_OF'
|
FilterByOperator: 'MEMBER_OF'
|
||||||
}],
|
}]
|
||||||
}, {
|
}, {
|
||||||
// Right side image (L MLO Current)
|
// Right side image (L MLO Current)
|
||||||
ImageSetNumber: 1,
|
ImageSetNumber: 1,
|
||||||
@ -102,7 +102,9 @@ function getMammoHangingProtocol() {
|
|||||||
FilterByCategory: 'SERIES_DESCRIPTION',
|
FilterByCategory: 'SERIES_DESCRIPTION',
|
||||||
FilterByOperator: 'MEMBER_OF'
|
FilterByOperator: 'MEMBER_OF'
|
||||||
}]
|
}]
|
||||||
}, {
|
},
|
||||||
|
// Stage 3
|
||||||
|
{
|
||||||
// Left side image (R MLO Current)
|
// Left side image (R MLO Current)
|
||||||
ImageSetNumber: 1,
|
ImageSetNumber: 1,
|
||||||
DisplaySetNumber: 1,
|
DisplaySetNumber: 1,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user