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:
Erik Ziegler 2015-11-22 12:20:19 +01:00
parent a3c0048490
commit 9ad2ccaaaf
11 changed files with 254 additions and 259 deletions

View File

@ -8,4 +8,6 @@ Meteor.startup(function() {
mouse: cornerstoneTools.nonTarget, mouse: cornerstoneTools.nonTarget,
touch: cornerstoneTools.nonTargetTouch touch: cornerstoneTools.nonTargetTouch
}); });
toolManager.setAlwaysEnabledTools(['lesion', 'nonTarget']);
}); });

View File

@ -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,

View File

@ -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);
});
} }
} else if (eventObject.type === "inactive") {
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);
} }
}
//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({

View File

@ -1,153 +1,137 @@
// 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});
return timepoint;
}
/**
* Switch to the image of the correct image index
* Activate the selected measurement on the switched image (color to be green)
* 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
var enabledElement = cornerstone.getEnabledElement(element);
var imageId = enabledElement.image.imageId;
var timepointData = getTimepointObject(imageId);
var measurementData = Measurements.findOne(measurementId);
var measurementAtTimepoint = measurementData.timepoints[timepointData.timepointID];
if (!measurementAtTimepoint) {
return;
}
// Defines event data
var eventData = {
enabledElement: enabledElement,
lesionData: {
id: measurementId,
isTarget: measurementData.isTarget,
lesionNumber: measurementData.lesionNumber,
imageId: imageId,
seriesInstanceUid: measurementAtTimepoint.seriesInstanceUid,
studyInstanceUid: measurementAtTimepoint.studyInstanceUid
},
type: "active"
};
// If isTarget = false, this measurement is nonTarget measurement
// Activate related nonTarget measurement
// Deactivate all target measurements to activate only nonTarget measurement
if (!isTarget) {
$(element).trigger("NonTargetToolSelected", eventData);
// Deactivate lesion tool measurements
eventData.type = "inactive";
$(element).trigger("LesionToolSelected", eventData);
} else {
// Trigger event for target measurements
$(element).trigger("LesionToolSelected", eventData);
// Deactivate nonTarget tool measurements
eventData.type = "inactive";
// Trigger event for nonTarget measurements
// Inactivate all nonTarget measurements if any measurement is active
$(element).trigger("NonTargetToolSelected", eventData);
}
}
/**
* Activates a set of lesions when lesion table row is clicked
*
* @param measurementId The unique key for a specific Measurement
*/
function activateLesion(measurementId) {
// Find Measurement data for this lesion
var measurementData = Measurements.findOne(measurementId);
// If there is no measurement with this ID, stop here
if (!measurementData) {
log.warn('No Measurements entry associated to an ID in a lesion table row');
return;
}
// Get the timepoint data from this Measurement
var timepoints = measurementData.timepoints;
// Loop through the viewports and display each timepoint
$(".imageViewerViewport").each(function(viewportIndex, element) {
// Stop if we run out of timepoints before viewports
if (viewportIndex >= Object.keys(timepoints).length) {
return false;
}
// Find the image that is currently in this viewport
var enabledElement = cornerstone.getEnabledElement(element); var enabledElement = cornerstone.getEnabledElement(element);
if (!enabledElement) { if (!enabledElement || !enabledElement.image) {
return; return;
} }
enabledElementsInViewport.push({element: element, enabledElement: enabledElement}); // 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];
return enabledElementsInViewport; // If there is no measurement data to display, stop here
} if (!measurementAtTimepoint) {
return;
// Switch to the image of the correct image index
// Activate the selected measurement on the switched image (color to be green)
// Deactivate all other measurements on the switched image (color to be white)
function activateMeasurementsInRelatedImages(timepoints, lesionNumber, isTarget) {
//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
//TODO: we can switch to the related image and activate the selected measurement on the switched image.
var intervalListener = setInterval(function() {
window.clearInterval(intervalListener);
var enabledElementsInViewport = getEnabledElementsInViewport();
for(var i = 0; i < enabledElementsInViewport.length; i++) {
var element = enabledElementsInViewport[i].element;
var enabledElement = enabledElementsInViewport[i].enabledElement;
var timepointObject = getTimepointObject(timepoints, enabledElement);
if (timepointObject === undefined) {
continue;
}
// Defines event data
var eventData = {
enabledElement: enabledElement,
lesionData: {
isTarget: isTarget,
lesionNumber: lesionNumber,
imageId: timepointObject.imageId,
seriesInstanceUid: timepointObject.seriesInstanceUid,
studyInstanceUid: timepointObject.studyInstanceUid
},
type: "active"
};
// If isTarget = false, this measurement is nonTarget measurement
// Activate related nonTarget measurement
// Deactivate all target measurements to activate only nonTarget measurement
if (!isTarget) {
$(element).trigger("NonTargetToolSelected", eventData);
// Deactivate lesion tool measurements
eventData.type = "inactive";
$(element).trigger("LesionToolSelected", eventData);
} else {
// Trigger event for target measurements
$(element).trigger("LesionToolSelected", eventData);
// Deactivate nonTarget tool measurements
eventData.type = "inactive";
// Triggger event for nonTarget measurements
// Inactivate all nonTarget measurements if any measurement is active
$(element).trigger("NonTargetToolSelected", eventData);
}
}
}, 100);
}
// Returns timepoint object based on timepoint id of the enabled element
function getTimepointObject(timepoints, enabledElement) {
var imageId = enabledElement.image.imageId;
var study = cornerstoneTools.metaData.get('study', imageId);
var series = cornerstoneTools.metaData.get('series', imageId);
// 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 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 (!measurementData) {
return;
}
var timepoints = measurementData.timepoints;
var enabledElementsInViewport = getEnabledElementsInViewport();
// Render related series
for(var i = 0; i < enabledElementsInViewport.length; i++) {
var element = enabledElementsInViewport[i].element;
var enabledElement = enabledElementsInViewport[i].enabledElement;
var timepointObject = getTimepointObject(timepoints, enabledElement);
if (timepointObject === undefined || timepointObject.seriesInstanceUid === "") {
continue;
} }
var newSeriesData = { // Check which study and series are required to display the measurement at this timepoint
seriesInstanceUid: timepointObject.seriesInstanceUid, var requiredSeriesData = {
studyInstanceUid: timepointObject.studyInstanceUid 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);
} }
}); });

View File

@ -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>

View File

@ -1,5 +1,5 @@
Template.lesionTableRow.helpers({ Template.lesionTableRow.helpers({
'timepoints': function() { 'timepoints': function() {
return Timepoints.find(); return Timepoints.find({}, {sort: {timepointName: 1}});
} }
}); });

View File

@ -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) {

View File

@ -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();

View File

@ -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);
}; };

View File

@ -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,61 +88,68 @@ 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) {
// First, deactivate the current active tool return;
tools[activeTool].mouse.deactivate(element, 1);
if (tools[activeTool].touch) {
tools[activeTool].touch.deactivate(element);
}
// First, get the stack toolData
var toolData = cornerstoneTools.getToolState(element, 'stack');
if (!toolData || !toolData.data || !toolData.data.length) {
return;
}
// Get the imageIds for this element
var imageIds = toolData.data[0].imageIds;
// Deactivate all the middle mouse, right click, and scroll wheel tools
cornerstoneTools.pan.deactivate(element);
cornerstoneTools.zoom.deactivate(element);
cornerstoneTools.zoomWheel.deactivate(element);
cornerstoneTools.stackScrollWheel.deactivate(element);
// Reactivate the relevant scrollwheel tool for this element
if (imageIds.length > 1) {
// scroll is the default tool for middle mouse wheel for stacks
cornerstoneTools.stackScrollWheel.activate(element);
} else {
// zoom is the default tool for middle mouse wheel for single images (non stacks)
cornerstoneTools.zoomWheel.activate(element);
}
// This block ensures that the middle mouse and scroll tools keep working
if (tool === 'pan') {
cornerstoneTools.pan.activate(element, 3); // 3 means left mouse button and middle mouse button
cornerstoneTools.zoom.activate(element, 4); // zoom is the default tool for right mouse button
} else if (tool === 'zoom') {
cornerstoneTools.pan.activate(element, 2); // pan is the default tool for middle mouse button
cornerstoneTools.zoom.activate(element, 5); // 5 means left mouse button and right mouse button
} else {
// Reactivate the middle mouse and right click tools
cornerstoneTools.pan.activate(element, 2); // pan is the default tool for middle mouse button
cornerstoneTools.zoom.activate(element, 4); // zoom is the default tool for right mouse button
// Activate the chosen tool
tools[tool].mouse.activate(element, 1);
}
if (tools[tool].touch) {
tools[tool].touch.activate(element);
}
cornerstoneTools.zoomTouchPinch.activate(element);
cornerstoneTools.panMultiTouch.activate(element);
} }
// First, deactivate the current active tool
tools[activeTool].mouse.deactivate(element, 1);
if (tools[activeTool].touch) {
tools[activeTool].touch.deactivate(element);
}
// 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');
if (!toolData || !toolData.data || !toolData.data.length) {
return;
}
// Get the imageIds for this element
var imageIds = toolData.data[0].imageIds;
// Deactivate all the middle mouse, right click, and scroll wheel tools
cornerstoneTools.pan.deactivate(element);
cornerstoneTools.zoom.deactivate(element);
cornerstoneTools.zoomWheel.deactivate(element);
cornerstoneTools.stackScrollWheel.deactivate(element);
// Reactivate the relevant scrollwheel tool for this element
if (imageIds.length > 1) {
// scroll is the default tool for middle mouse wheel for stacks
cornerstoneTools.stackScrollWheel.activate(element);
} else {
// zoom is the default tool for middle mouse wheel for single images (non stacks)
cornerstoneTools.zoomWheel.activate(element);
}
// This block ensures that the middle mouse and scroll tools keep working
if (tool === 'pan') {
cornerstoneTools.pan.activate(element, 3); // 3 means left mouse button and middle mouse button
cornerstoneTools.zoom.activate(element, 4); // zoom is the default tool for right mouse button
} else if (tool === 'zoom') {
cornerstoneTools.pan.activate(element, 2); // pan is the default tool for middle mouse button
cornerstoneTools.zoom.activate(element, 5); // 5 means left mouse button and right mouse button
} else {
// Reactivate the middle mouse and right click tools
cornerstoneTools.pan.activate(element, 2); // pan is the default tool for middle mouse button
cornerstoneTools.zoom.activate(element, 4); // zoom is the default tool for right mouse button
// Activate the chosen tool
tools[tool].mouse.activate(element, 1);
}
if (tools[tool].touch) {
tools[tool].touch.activate(element);
}
cornerstoneTools.zoomTouchPinch.activate(element);
cornerstoneTools.panMultiTouch.activate(element);
}); });
activeTool = tool; activeTool = tool;
}, },

View File

@ -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,