diff --git a/Packages/lesiontracker/compatibility/nonTargetTool.js b/Packages/lesiontracker/compatibility/nonTargetTool.js index 895097b53..4f3365beb 100644 --- a/Packages/lesiontracker/compatibility/nonTargetTool.js +++ b/Packages/lesiontracker/compatibility/nonTargetTool.js @@ -4,38 +4,42 @@ var toolType = 'nonTarget'; - // Define a callback to get your text annotation - // This could be used, e.g. to open a modal - function getTextCallback(doneChangingTextCallback) { - doneChangingTextCallback(prompt('Enter your annotation:')); - } - - function changeTextCallback(data, doneChangingTextCallback) { - doneChangingTextCallback(prompt('Change your annotation:')); - } - - var configuration = { - getTextCallback: getTextCallback, - changeTextCallback: changeTextCallback, + setLesionNumberCallback: setLesionNumberCallback, + getNonTargetLesionLocationCallback: getNonTargetLesionLocationCallback, + changeNonTargetLesionLocationCallback: changeNonTargetLesionLocationCallback, drawHandles: false, drawHandlesOnHover: true, arrowFirst: true }; + // Set lesion number + // Get Non-Target lesions on image + function setLesionNumberCallback(measurementData, eventData, doneCallback) { + var lesionNumber = 1; + doneCallback(lesionNumber); + } + // Define a callback to get your text annotation + // This could be used, e.g. to open a modal + function getNonTargetLesionLocationCallback(measurementData, eventData, doneCallback) { + doneCallback(prompt('Enter your lesion location:')); + } + + function changeNonTargetLesionLocationCallback(measurementData, eventData, doneCallback) { + doneCallback(prompt('Change your lesion location:')); + } + /// --- Mouse Tool --- /// ///////// BEGIN ACTIVE TOOL /////// function addNewMeasurement(mouseEventData) { - function doneChangingTextCallback(text) { - if (text !== null) { - measurementData.text = text; - } else { - cornerstoneTools.removeToolState(mouseEventData.element, toolType, measurementData); - } + var element = mouseEventData.element; - measurementData.active = false; - cornerstone.updateImage(mouseEventData.element); + function doneCallback(lesionNumber) { + measurementData.lesionName = "Non-Target "+lesionNumber; + measurementData.lesionNumber = lesionNumber; + measurementData.active = true; + cornerstone.updateImage(element); } var measurementData = createNewMeasurement(mouseEventData); @@ -53,21 +57,24 @@ $(mouseEventData.element).off('CornerstoneToolsMouseDown', cornerstoneTools.nonTarget.mouseDownCallback); $(mouseEventData.element).off('CornerstoneToolsMouseDownActivate', cornerstoneTools.nonTarget.mouseDownActivateCallback); - cornerstone.updateImage(mouseEventData.element); + var config = cornerstoneTools.nonTarget.getConfiguration(); + + // Set lesion number and lesion name + if (measurementData.lesionName === undefined) { + config.setLesionNumberCallback(measurementData, mouseEventData, doneCallback); + } + + cornerstone.updateImage(element); + cornerstoneTools.moveNewHandle(mouseEventData, measurementData.handles.end, function() { if (cornerstoneTools.anyHandlesOutsideImage(mouseEventData, measurementData.handles)) { // delete the measurement cornerstoneTools.removeToolState(mouseEventData.element, toolType, measurementData); } - var config = cornerstoneTools.nonTarget.getConfiguration(); - if (measurementData.text === undefined) { - config.getTextCallback(doneChangingTextCallback); - } + config.getNonTargetLesionLocationCallback(measurementData, mouseEventData, doneCallback); $(mouseEventData.element).on('CornerstoneToolsMouseMove', eventData, cornerstoneTools.nonTarget.mouseMoveCallback); - - // CornerstoneToolsMouseDown Event $(mouseEventData.element).on('CornerstoneToolsMouseDown', eventData, cornerstoneTools.nonTarget.mouseDownCallback); $(mouseEventData.element).on('CornerstoneToolsMouseDownActivate', eventData, cornerstoneTools.nonTarget.mouseDownActivateCallback); @@ -77,17 +84,6 @@ function createNewMeasurement(mouseEventData) { // create the measurement data for this tool with the end handle activated - // TODO: Get text from measurements collection - // Subscribe CornerstoneMouseup event, when mouse is up, call lesionDialog - $(mouseEventData.element).on("CornerstoneToolsMouseUp", function (e) { - // Unsubscribe CornerstoneToolsMouseUp event - $(mouseEventData.element).off("CornerstoneToolsMouseUp"); - $(mouseEventData.element).trigger("NonTargetToolAdded", [e, measurementData]); - - }); - var timepointID = $(mouseEventData.element).data('timepointID'); - var lesionNumber = measurementManagerDAL.getNewLesionNumber(timepointID, false); - var measurementData = { visible: true, active: true, @@ -114,9 +110,9 @@ } }, imageId: mouseEventData.image.imageId, - lesionNumber: lesionNumber, - text: "Non-Target " + lesionNumber, - isTarget: false + measurementText: '', + isTarget: false, + uid: uuid.v4() }; return measurementData; @@ -271,9 +267,9 @@ // Draw the text - if (lesion.text && lesion.text !== '') { + if (lesion.lesionName && lesion.lesionName !== '') { context.font = font; - var boundingBox = cornerstoneTools.drawTextBox(context, lesion.text, canvasTextLocation.x, canvasTextLocation.y, color); + var boundingBox = cornerstoneTools.drawTextBox(context, lesion.lesionName, canvasTextLocation.x, canvasTextLocation.y, color); lesion.handles.textBox.boundingBox = boundingBox; } diff --git a/Packages/lesiontracker/components/lesionTable/lesionTable.js b/Packages/lesiontracker/components/lesionTable/lesionTable.js index 565dbf75e..5e7a46ae4 100644 --- a/Packages/lesiontracker/components/lesionTable/lesionTable.js +++ b/Packages/lesiontracker/components/lesionTable/lesionTable.js @@ -1,47 +1,6 @@ Measurements = new Meteor.Collection(null); Timepoints = new Meteor.Collection(null); -// When nonTarget lesion is added to image, insert data to lesion table -function nonTargetToolAdded(e, eventData, lesionData) { - - // Set timepointID - lesionData.timepointID = $(e.currentTarget).data('timepointID'); - - var locationUID = measurementManagerDAL.isLesionNumberAdded(lesionData); - if (locationUID) { - // location is selected and disable select location in dialog - lesionData.locationUID = locationUID; - var locationName = measurementManagerDAL.getLocationName(locationUID); - - $("#selectNonTargetLesionLocation option").each(function() - { - if ($(this).text() === locationName) { - // Select location in locations dropdown list - $("#selectNonTargetLesionLocation option").eq($(this).index()).attr("selected", "selected"); - return; - } - }); - - $("#selectNonTargetLesionLocation").attr("disabled", "disabled"); - } else{ - - // If selectNonTargetLesionLocation is disabled, make it enable - $("#selectNonTargetLesionLocation").removeAttr("disabled"); - } - - // Save lesionData in Session to use after location and response are selected - Session.set("nonTargetLesionData", lesionData); - - var dialogPointsOnPage = eventData.currentPoints.page; - $("#modal-dialog-container-nonTargetLesion").css({ - "top": dialogPointsOnPage.y, - "left": dialogPointsOnPage.x - }); - - $("#nonTargetLesionLocationDialog").modal("show"); - -} - // Activate selected lesions when lesion table row is clicked function updateLesions(e) { // lesionNumber of measurement = id of row @@ -116,9 +75,6 @@ Template.lesionTable.onRendered(function() { }); $(element).data('timepointID', timepointID); - - // Listen NonTargetToolAdded Event - $(element).on("NonTargetToolAdded", nonTargetToolAdded); }); }); diff --git a/Packages/lesiontracker/components/nonTargetLesionDialog/nonTargetLesionDialog.css b/Packages/lesiontracker/components/nonTargetLesionDialog/nonTargetLesionDialog.css index 3128c92ef..4ea5e85d5 100644 --- a/Packages/lesiontracker/components/nonTargetLesionDialog/nonTargetLesionDialog.css +++ b/Packages/lesiontracker/components/nonTargetLesionDialog/nonTargetLesionDialog.css @@ -1,20 +1,16 @@ #nonTargetLesionLocationDialog { - background: transparent; -} - -#modal-dialog-container-nonTargetLesion { + display: none; position: absolute; - border: none; -} + z-index: 100; + background: white; + padding: 10px 20px 10px 20px; + border-radius: 10px; + -#btnCloseNonTargetLesionPopup { - outline: 0; - border: none; - background-color: transparent; } #selectNonTargetLesionLocation, #selectNonTargetLesionLocationResponse { - width: 80%; + width: 100%; } .dialogContent, .lesionLocation, .locationResponse { diff --git a/Packages/lesiontracker/components/nonTargetLesionDialog/nonTargetLesionDialog.html b/Packages/lesiontracker/components/nonTargetLesionDialog/nonTargetLesionDialog.html index 025ae16ac..8a3e76f93 100644 --- a/Packages/lesiontracker/components/nonTargetLesionDialog/nonTargetLesionDialog.html +++ b/Packages/lesiontracker/components/nonTargetLesionDialog/nonTargetLesionDialog.html @@ -1,40 +1,43 @@ \ No newline at end of file diff --git a/Packages/lesiontracker/components/nonTargetLesionDialog/nonTargetLesionDialog.js b/Packages/lesiontracker/components/nonTargetLesionDialog/nonTargetLesionDialog.js index f0d1f3ec1..b0c5c7ada 100644 --- a/Packages/lesiontracker/components/nonTargetLesionDialog/nonTargetLesionDialog.js +++ b/Packages/lesiontracker/components/nonTargetLesionDialog/nonTargetLesionDialog.js @@ -1,135 +1,231 @@ -//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: "" -}]; +// This event sets lesion number for new lesion -var lesionLocationsResponseArray = [ +function setLesionNumberCallback(measurementData, eventData, doneCallback) { + + measurementData.timepointID = $(eventData.element).data('timepointID'); + // Get a lesion number for this lesion, depending on whether or not the same lesion previously + // exists at a different timepoint + var lesionNumber = measurementManagerDAL.getNewLesionNumber(measurementData.timepointID, isTarget=false); + measurementData.lesionNumber = lesionNumber; + + // Set lesion number + doneCallback(lesionNumber); +} + +// This event determines whether or not to show the Non-Target lesion dialog +// If there already exists a lesion with this specific lesion number, +// related to the chosen location. + +function getNonTargetLesionLocationCallback(measurementData, eventData, doneCallback) { + + // Get the non-target lesion location dialog + var nonTargetlesionDialog = $("#nonTargetLesionLocationDialog"); + + // Find the select option box + var selectorLocation = nonTargetlesionDialog.find("select#selectNonTargetLesionLocation"); + var selectorResponse = nonTargetlesionDialog.find("select#selectNonTargetLesionLocationResponse"); + + // OK button + var btnOK = nonTargetlesionDialog.find("button#nonTargetLesionOK"); + + + // If selector location is disabled, make it enable + enableLocationSelection(); + + // Find out if this lesion number is already added in the lesion manager for another timepoint + // If it is, disable selector location + var locationUID = measurementManagerDAL.lesionNumberExists(measurementData); + if (locationUID) { + measurementData.locationUID = locationUID; + // Disable the selection of a new location + disableLocationSelection(measurementData.locationUID); + } + + // Disable selector location to prevent selecting a new location + function disableLocationSelection(locationUID) { + var locationName = measurementManagerDAL.getLocationName(locationUID); + selectorLocation.find('option').each(function() + { + if ($(this).text().trim() === locationName.trim()) { + // Select location in locations dropdown list + selectorLocation.find('option').eq($(this).index()).attr("selected", "selected"); + return; + } + }); + + selectorLocation.attr("disabled", "disabled"); + } + + // Enable selector location + function enableLocationSelection() { + selectorLocation.removeAttr("disabled"); + } + + function closeHandler() { + + // Hide the lesion dialog + nonTargetlesionDialog.css('display', 'none'); + // Enable selector location + enableLocationSelection(); + + // Get the current value of the select option box + selectorLocation.find("option:first").prop("selected", "selected"); + selectorResponse.find("option:first").prop("selected", "selected"); + + } + + // Attach keypress handlers so the user can close with the Enter button + nonTargetlesionDialog.off("keypress"); + nonTargetlesionDialog.on('keypress', keyPressHandler); + + // This is the keypress callback function + function keyPressHandler(e) { + // If Enter is pressed, close the dialog + if (e.which === 13) { + closeHandler(); + } + } + + // Show the lesion location dialog above + nonTargetlesionDialog.css({ + top: eventData.currentPoints.page.y, + left: eventData.currentPoints.page.x, + display: 'block' + }); + + // Click OK button + // Add lesion to lesion table + btnOK.off('click'); + btnOK.on('click', function(e) { + // Get the current value of the selector + var selectedOptionId = selectorLocation.find("option:selected").val(); + var responseOptionCode = nonTargetlesionDialog.find("select#selectNonTargetLesionLocationResponse option:selected").val(); + + // If the selected option is still the default (-1) + // then stop here + if (selectedOptionId < 0) { + return; + } + + // If the selected response option is still the default (-1) + // then stop here + if (responseOptionCode < 0) { + return; + } + + // Get selected location data + var locationObj = LesionLocations.findOne({_id: selectedOptionId}); + + var id; + var existingLocation = PatientLocations.findOne({location: locationObj.location}); + if (existingLocation) { + id = existingLocation._id; + } else { + // Adds location data to PatientLocation and retrieve the location ID + id = PatientLocations.insert({location: locationObj.location}); + } + + // Link locationUID with active lesion measurementData + measurementData.locationUID = id; + + /// Set the isTarget value to true, since this is the target-lesion dialog callback + measurementData.isTarget = false; + + // measurementText is set from location response list + measurementData.measurementText = responseOptionCode; + + // Adds lesion data to timepoints array + measurementManagerDAL.addLesionData(measurementData); + + // Close the dialog + closeHandler(); + }); +} + +function changeNonTargetLesionLocationCallback(measurementData, eventData, doneCallback) { + doneCallback(prompt('Change your lesion location:')); +} + +var config = { + setLesionNumberCallback: setLesionNumberCallback, + getNonTargetLesionLocationCallback: getNonTargetLesionLocationCallback, + changeNonTargetLesionLocationCallback: changeNonTargetLesionLocationCallback +}; + +cornerstoneTools.nonTarget.setConfiguration(config); + + +LocationResponses = new Meteor.Collection(null); + +LocationResponses.insert( { text: "Complete response", code: "CR", description: "" - }, + } +); +LocationResponses.insert( { text: "Progressive disease", code: "PD", description: "" - }, + } +); +LocationResponses.insert( + { + text: "Complete response", + code: "CR", + description: "" + } +); +LocationResponses.insert( { text: "Stable disease", code: "SD", description: "" - }, + } +); +LocationResponses.insert( { text: "Non-measurable", code: "NM", description: "" - }, + } +); +LocationResponses.insert( { text: "Unknown", code: "UN", description: "" - }, + } +); +LocationResponses.insert( { text: "Not Evaluable", code: "NE", description: "" - }, + } +); +LocationResponses.insert( { text: "Non-CR/Non-PD", code: "NN", description: "" - }, + } +); +LocationResponses.insert( { text: "Excluded", code: "EX", description: "" } -]; +); -Template.nonTargetLesionDialog.onRendered(function() { - - function fillSelectLesionLocation() { - var el = $("#selectNonTargetLesionLocation"); - el.find('option:not(:first)').remove(); - $.each(lesionLocationsArray, function(key, value) { - el.append(""); - }); - } - - function fillResponses() { - var el = $("#selectNonTargetLesionLocationResponse"); - el.find('option:not(:first)').remove(); - $.each(lesionLocationsResponseArray, function(key, value) { - el.append(""); - }); - } - - // Fill dropdown - fillSelectLesionLocation(); - - // Fill location responses - fillResponses(); - -}); - -Template.nonTargetLesionDialog.events({ - 'click button#btnCloseNonTargetLesionPopup': function(e) { - $("#nonTargetLesionLocationDialog").modal("hide"); +Template.nonTargetLesionDialog.helpers({ + 'lesionLocations': function() { + return LesionLocations.find(); }, - - 'click button#nonTargetLesionOK': function() { - - var lesionData = Session.get("nonTargetLesionData"); - // Get selected location data - var selectedLocationIndex = $("#selectNonTargetLesionLocation").val(); - if (selectedLocationIndex < 0) { - return; - } - // Get selected location data - var locationObj = lesionLocationsArray[selectedLocationIndex]; - lesionData.location = $("#selectNonTargetLesionLocation :selected").text(); - - var response = $("#selectNonTargetLesionLocationResponse").val(); - if(response === "-1") { - return; - } - $("#nonTargetLesionLocationDialog").modal("hide"); - lesionData.measurementText = response; - - // Select first option - $("#selectNonTargetLesionLocation").val($("#selectNonTargetLesionLocation option:first").val()); - $("#selectNonTargetLesionLocationResponse").val($("#selectNonTargetLesionLocationResponse option:first").val()); - - if (typeof lesionData.locationUID !== 'undefined') { - measurementManagerDAL.updateTimepointData(lesionData); - return; - } - - // Adds location data to trialPatientLocations array and returns locationUID - var locationUID = measurementManagerDAL.addNewLocation(locationObj); - // Link locationUID with activeLesionMeasurementData - lesionData.locationUID = locationUID; - measurementManagerDAL.addLesionData(lesionData); - - - + 'locationResponses': function() { + return LocationResponses.find(); } }); \ No newline at end of file