Measurements collection is added for lesion table
This commit is contained in:
parent
dfb4f6a41c
commit
f5f10dea34
@ -34,4 +34,5 @@ stylus
|
|||||||
fortawesome:fontawesome
|
fortawesome:fontawesome
|
||||||
random
|
random
|
||||||
reactive-var
|
reactive-var
|
||||||
|
reactive-dict
|
||||||
lesiontracker
|
lesiontracker
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
var lineIndex = 0; //This holds drawn line index
|
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";
|
"use strict";
|
||||||
@ -13,6 +15,9 @@ var cornerstoneTools = (function ($, cornerstone, cornerstoneMath, cornerstoneTo
|
|||||||
function createNewMeasurement(mouseEventData)
|
function createNewMeasurement(mouseEventData)
|
||||||
{
|
{
|
||||||
var element = mouseEventData.element;
|
var element = mouseEventData.element;
|
||||||
|
timepointID = getActiveTimepointID(element);
|
||||||
|
var lesionNumber = measurementManagerDAL.getLesionNumber(timepointID);
|
||||||
|
console.log(lesionNumber);
|
||||||
var lesionCounter = "";
|
var lesionCounter = "";
|
||||||
|
|
||||||
// Subscribe CornerstoneMouseup event, when mouse is up, call lesionDialog
|
// Subscribe CornerstoneMouseup event, when mouse is up, call lesionDialog
|
||||||
@ -21,8 +26,12 @@ var cornerstoneTools = (function ($, cornerstone, cornerstoneMath, cornerstoneTo
|
|||||||
// Unsubscribe CornerstoneToolsMouseUp event
|
// Unsubscribe CornerstoneToolsMouseUp event
|
||||||
$(element).off("CornerstoneToolsMouseUp");
|
$(element).off("CornerstoneToolsMouseUp");
|
||||||
|
|
||||||
|
// Set lesionMeasurementData Session
|
||||||
|
activeLesionMeasurementData.timepointID = timepointID;
|
||||||
|
Session.set("lesionMeasurementData", activeLesionMeasurementData);
|
||||||
|
|
||||||
// Show LesionDialog
|
// Show LesionDialog
|
||||||
$(document).trigger("ShowLesionDialog", e);
|
$(document).trigger("ShowLesionDialog", [e, activeLesionMeasurementData]);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -72,9 +81,11 @@ var cornerstoneTools = (function ($, cornerstone, cornerstoneMath, cornerstoneTo
|
|||||||
},
|
},
|
||||||
init: false
|
init: false
|
||||||
},
|
},
|
||||||
lesionName: "Target "+lesionCounter,
|
lesionName: "Target "+lesionNumber,
|
||||||
isDeleted: false,
|
isDeleted: false,
|
||||||
lineNumber:"" //Indicates line number on image
|
lineNumber:"", //Indicates line number on image
|
||||||
|
lesionNumber: lesionNumber,
|
||||||
|
uid: uuid.v4()
|
||||||
};
|
};
|
||||||
lineIndex++;
|
lineIndex++;
|
||||||
return measurementData;
|
return measurementData;
|
||||||
@ -103,110 +114,201 @@ var cornerstoneTools = (function ($, cornerstone, cornerstoneMath, cornerstoneTo
|
|||||||
|
|
||||||
///////// BEGIN IMAGE RENDERING ///////
|
///////// BEGIN IMAGE RENDERING ///////
|
||||||
function onImageRendered(e, eventData) {
|
function onImageRendered(e, eventData) {
|
||||||
|
|
||||||
// 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 === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateLesions(toolData, eventData, e.currentTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateLesions(toolData, eventData, currentElement) {
|
||||||
// we have tool data for this element - iterate over each one and draw it
|
// we have tool data for this element - iterate over each one and draw it
|
||||||
var context = eventData.canvasContext.canvas.getContext('2d');
|
var context = eventData.canvasContext.canvas.getContext('2d');
|
||||||
context.setTransform(1, 0, 0, 1, 0, 0);
|
context.setTransform(1, 0, 0, 1, 0, 0);
|
||||||
|
|
||||||
|
for (var i = 0; i < toolData.data.length; i++) {
|
||||||
|
renderLesion(toolData.data[i], context, eventData);
|
||||||
|
updateLesionCollection(toolData.data[i], currentElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateLesionCollection(lesionData, currentElement) {
|
||||||
|
|
||||||
|
if (lesionData.active) {
|
||||||
|
activeLesionMeasurementData = lesionData;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Option1: Create a global variable like lesionMeasurementData
|
||||||
|
// TODO: Insert lesionData inside the lesionMeasurementData
|
||||||
|
// TODO: Send the lesionMeasurementData to lesionDialog by ShowLesionDialog event
|
||||||
|
|
||||||
|
/*if (lesionMeasurementData != undefined && lesionMeasurementData.lesionNumber === lesionData.index) {
|
||||||
|
lesionMeasurementData.timepoints.now.longestDiameter = lesionData.measurementText;
|
||||||
|
console.log(lesionMeasurementData.timepoints.now.longestDiameter);
|
||||||
|
} else {
|
||||||
|
lesionMeasurementData = {
|
||||||
|
lesionNumber: lesionData.index,
|
||||||
|
isTarget: true,
|
||||||
|
location: '',
|
||||||
|
timepoints: {
|
||||||
|
"now": {
|
||||||
|
imageId: "blah",
|
||||||
|
timepointUid: "timepointX",
|
||||||
|
date: 2010,
|
||||||
|
isDirty: true,
|
||||||
|
longestDiameter: lesionData.measurementText
|
||||||
|
},
|
||||||
|
"earlier": {
|
||||||
|
imageId: "blah2",
|
||||||
|
timepointUid: "timepointy",
|
||||||
|
date: 2010,
|
||||||
|
isDirty: true,
|
||||||
|
longestDiameter: 8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// TODO: Option2:
|
||||||
|
// Check collection has this lesionData
|
||||||
|
/*var isFound = Measurements.findOne({lesionNumber: lesionData.index});
|
||||||
|
|
||||||
|
// TODO: Decide which time point is changed
|
||||||
|
if (isFound) {
|
||||||
|
// Update measurement text
|
||||||
|
Measurements.update(
|
||||||
|
{ lesionNumber: lesionData.index },
|
||||||
|
{
|
||||||
|
$set: {
|
||||||
|
"timepoints.now.longestDiameter": lesionData.measurementText
|
||||||
|
}
|
||||||
|
}, {multi: true}
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log(Measurements.find());
|
||||||
|
} else {
|
||||||
|
var lesionObject = {
|
||||||
|
lesionNumber: lesionData.index,
|
||||||
|
isTarget: true,
|
||||||
|
location: '',
|
||||||
|
isHidden: true,
|
||||||
|
timepoints: {
|
||||||
|
"now": {
|
||||||
|
imageId: "blah",
|
||||||
|
timepointUid: "timepointX",
|
||||||
|
date: 2010,
|
||||||
|
isDirty: true,
|
||||||
|
longestDiameter: lesionData.measurementText
|
||||||
|
},
|
||||||
|
"earlier": {
|
||||||
|
imageId: "blah2",
|
||||||
|
timepointUid: "timepointy",
|
||||||
|
date: 2010,
|
||||||
|
isDirty: true,
|
||||||
|
longestDiameter: 8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Measurements.insert(lesionObject);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderLesion(lesion, context, eventData){
|
||||||
|
context.save();
|
||||||
|
|
||||||
var color;
|
var color;
|
||||||
var lineWidth = cornerstoneTools.toolStyle.getToolWidth();
|
var lineWidth = cornerstoneTools.toolStyle.getToolWidth();
|
||||||
var font = cornerstoneTools.textStyle.getFont();
|
var font = cornerstoneTools.textStyle.getFont();
|
||||||
var config = cornerstoneTools.length.getConfiguration();
|
var config = cornerstoneTools.length.getConfiguration();
|
||||||
|
|
||||||
for (var i = 0; i < toolData.data.length; i++) {
|
// configurable shadow from CornerstoneTools
|
||||||
context.save();
|
if (config && config.shadow) {
|
||||||
// configurable shadow
|
context.shadowColor = '#000000';
|
||||||
if (config && config.shadow) {
|
context.shadowOffsetX = +1;
|
||||||
context.shadowColor = '#000000';
|
context.shadowOffsetY = +1;
|
||||||
context.shadowOffsetX = +1;
|
|
||||||
context.shadowOffsetY = +1;
|
|
||||||
}
|
|
||||||
|
|
||||||
var data = toolData.data[i];
|
|
||||||
if (data.active) {
|
|
||||||
color = cornerstoneTools.toolColors.getActiveColor();
|
|
||||||
} else {
|
|
||||||
color = cornerstoneTools.toolColors.getToolColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
// draw the line
|
|
||||||
var handleStartCanvas = cornerstone.pixelToCanvas(eventData.element, data.handles.start);
|
|
||||||
var handleEndCanvas = cornerstone.pixelToCanvas(eventData.element, data.handles.end);
|
|
||||||
|
|
||||||
context.beginPath();
|
|
||||||
context.strokeStyle = color;
|
|
||||||
context.lineWidth = lineWidth;
|
|
||||||
context.moveTo(handleStartCanvas.x, handleStartCanvas.y);
|
|
||||||
context.lineTo(handleEndCanvas.x, handleEndCanvas.y);
|
|
||||||
context.stroke();
|
|
||||||
|
|
||||||
// draw the handles
|
|
||||||
cornerstoneTools.drawHandles(context, eventData, data.handles, color);
|
|
||||||
|
|
||||||
//Set coordinates of text
|
|
||||||
var linkedTextStartCanvas = cornerstone.pixelToCanvas(eventData.element, data.linkedTextCoords.start);
|
|
||||||
var linkedTextEndCanvas = cornerstone.pixelToCanvas(eventData.element, data.linkedTextCoords.end);
|
|
||||||
if(!data.linkedTextCoords.init){
|
|
||||||
data.linkedTextCoords.start.x = data.handles.start.x + 50;
|
|
||||||
data.linkedTextCoords.start.y = data.handles.start.y + 40;
|
|
||||||
linkedTextStartCanvas = cornerstone.pixelToCanvas(eventData.element, data.linkedTextCoords.start);
|
|
||||||
|
|
||||||
//Set end point of linkedTextCoords
|
|
||||||
data.linkedTextCoords.end.x = data.linkedTextCoords.start.x + 50;
|
|
||||||
data.linkedTextCoords.end.y = data.linkedTextCoords.start.y + 30;
|
|
||||||
linkedTextEndCanvas = cornerstone.pixelToCanvas(eventData.element, data.linkedTextCoords.end);
|
|
||||||
|
|
||||||
//initialized coordinates of text
|
|
||||||
data.linkedTextCoords.init = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Draw linked line as dashed
|
|
||||||
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
|
|
||||||
};
|
|
||||||
|
|
||||||
context.moveTo(mid.x, mid.y);
|
|
||||||
context.lineTo(linkedTextStartCanvas.x + 20, linkedTextStartCanvas.y + 20);
|
|
||||||
context.stroke();
|
|
||||||
|
|
||||||
// Draw the text
|
|
||||||
context.fillStyle = color;
|
|
||||||
context.font = font;
|
|
||||||
var dx = (data.handles.start.x - data.handles.end.x) * (eventData.image.columnPixelSpacing || 1);
|
|
||||||
var dy = (data.handles.start.y - data.handles.end.y) * (eventData.image.rowPixelSpacing || 1);
|
|
||||||
var length = Math.sqrt(dx * dx + dy * dy);
|
|
||||||
|
|
||||||
var suffix = ' mm';
|
|
||||||
if (!eventData.image.rowPixelSpacing || !eventData.image.columnPixelSpacing) {
|
|
||||||
suffix = ' pixels';
|
|
||||||
}
|
|
||||||
|
|
||||||
var text = '' + length.toFixed(2) + suffix;
|
|
||||||
var textCoords = {
|
|
||||||
x: linkedTextStartCanvas.x, y: linkedTextStartCanvas.y
|
|
||||||
};
|
|
||||||
|
|
||||||
cornerstoneTools.drawTextBox(context, data.lesionName, textCoords.x, textCoords.y, color);
|
|
||||||
cornerstoneTools.drawTextBox(context, text, textCoords.x, textCoords.y + 20, color);
|
|
||||||
|
|
||||||
//Set measurement text to show lesion table
|
|
||||||
data.measurementText = length.toFixed(2);
|
|
||||||
$(eventData.enabledElement.element).trigger("LesionTextChanged",data);
|
|
||||||
|
|
||||||
context.restore();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (lesion.active) {
|
||||||
|
color = cornerstoneTools.toolColors.getActiveColor();
|
||||||
|
} else {
|
||||||
|
color = cornerstoneTools.toolColors.getToolColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw the line
|
||||||
|
var handleStartCanvas = cornerstone.pixelToCanvas(eventData.element, lesion.handles.start);
|
||||||
|
var handleEndCanvas = cornerstone.pixelToCanvas(eventData.element, lesion.handles.end);
|
||||||
|
|
||||||
|
context.beginPath();
|
||||||
|
context.strokeStyle = color;
|
||||||
|
context.lineWidth = lineWidth;
|
||||||
|
context.moveTo(handleStartCanvas.x, handleStartCanvas.y);
|
||||||
|
context.lineTo(handleEndCanvas.x, handleEndCanvas.y);
|
||||||
|
context.stroke();
|
||||||
|
|
||||||
|
// draw the handles
|
||||||
|
cornerstoneTools.drawHandles(context, eventData, lesion.handles, color);
|
||||||
|
|
||||||
|
//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){
|
||||||
|
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);
|
||||||
|
|
||||||
|
//Set end point of linkedTextCoords
|
||||||
|
lesion.linkedTextCoords.end.x = lesion.linkedTextCoords.start.x + 50;
|
||||||
|
lesion.linkedTextCoords.end.y = lesion.linkedTextCoords.start.y + 30;
|
||||||
|
linkedTextEndCanvas = cornerstone.pixelToCanvas(eventData.element, lesion.linkedTextCoords.end);
|
||||||
|
|
||||||
|
//initialized coordinates of text
|
||||||
|
lesion.linkedTextCoords.init = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Draw linked line as dashed
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
context.moveTo(mid.x, mid.y);
|
||||||
|
context.lineTo(linkedTextStartCanvas.x + 20, linkedTextStartCanvas.y + 20);
|
||||||
|
context.stroke();
|
||||||
|
|
||||||
|
// Draw the text
|
||||||
|
context.fillStyle = color;
|
||||||
|
context.font = font;
|
||||||
|
var dx = (lesion.handles.start.x - lesion.handles.end.x) * (eventData.image.columnPixelSpacing || 1);
|
||||||
|
var dy = (lesion.handles.start.y - lesion.handles.end.y) * (eventData.image.rowPixelSpacing || 1);
|
||||||
|
var length = Math.sqrt(dx * dx + dy * dy);
|
||||||
|
|
||||||
|
var suffix = ' mm';
|
||||||
|
if (!eventData.image.rowPixelSpacing || !eventData.image.columnPixelSpacing) {
|
||||||
|
suffix = ' pixels';
|
||||||
|
}
|
||||||
|
|
||||||
|
var text = '' + length.toFixed(2) + suffix;
|
||||||
|
var textCoords = {
|
||||||
|
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);
|
||||||
|
|
||||||
|
// Lesion Measurement is changed
|
||||||
|
$(eventData.enabledElement.element).trigger("LesionTextChanged",lesion);
|
||||||
|
|
||||||
|
context.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
///////// END IMAGE RENDERING ///////
|
///////// END IMAGE RENDERING ///////
|
||||||
|
|
||||||
//This function is called from cornerstone-viewport.html and updates lesion measurement and makes the lesion active
|
//This function is called from cornerstone-viewport.html and updates lesion measurement and makes the lesion active
|
||||||
|
|||||||
206
Packages/lesiontracker/compatibility/measurementManagerDAL.js
Normal file
206
Packages/lesiontracker/compatibility/measurementManagerDAL.js
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
var measurementManagerDAL = (function () {
|
||||||
|
var trialPatientLocations = [];
|
||||||
|
var timepoints = [];
|
||||||
|
|
||||||
|
// timepointID = tabId + activeViewportIndex
|
||||||
|
/*timepoints = [
|
||||||
|
{
|
||||||
|
timepointID: "tp0",
|
||||||
|
rois: [
|
||||||
|
{
|
||||||
|
UID: "345",
|
||||||
|
number: 1,
|
||||||
|
measurement: "22.34",
|
||||||
|
locationUID: 12345
|
||||||
|
},
|
||||||
|
{
|
||||||
|
UID: "245",
|
||||||
|
number: 2,
|
||||||
|
measurement: "22.34",
|
||||||
|
locationUID: 1745
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
timepointID: "tp1",
|
||||||
|
rois: [
|
||||||
|
{
|
||||||
|
UID: "243",
|
||||||
|
number: 1,
|
||||||
|
measurement: "22.34",
|
||||||
|
locationUID: 12345
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
timepointID: "tp2",
|
||||||
|
rois: [
|
||||||
|
{
|
||||||
|
UID: "253",
|
||||||
|
number: 1,
|
||||||
|
measurement: "0.34",
|
||||||
|
locationUID: 12345
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Returns trialPatientLocations array
|
||||||
|
function getPatientLocations () {
|
||||||
|
return trialPatientLocations;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLocationName (locationUID) {
|
||||||
|
for(var i = 0; i< trialPatientLocations.length; i++) {
|
||||||
|
var locationObject = trialPatientLocations[i];
|
||||||
|
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();
|
||||||
|
var locationUID = uuid.v4();
|
||||||
|
var locationObject = {contentId: contentId, uid: locationUID, location: location};
|
||||||
|
trialPatientLocations.push(locationObject);
|
||||||
|
|
||||||
|
return locationUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Insert Measurements Collection
|
||||||
|
function insertDataToMeasurementCollection (lesionData) {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function getContentId () {
|
||||||
|
return Session.get("activeContentId");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds new timepoint item to tiemepoints array
|
||||||
|
function addLesionData (lesionData) {
|
||||||
|
|
||||||
|
// TODO: if find lesionNumber, add
|
||||||
|
// TODO: Unless create new object
|
||||||
|
var contentId = getContentId();
|
||||||
|
var timepointID = lesionData.timepointID;
|
||||||
|
var tabMeasurements = Measurements.find({contentId: contentId}).fetch();
|
||||||
|
var existingMeasurement;
|
||||||
|
if(tabMeasurements != undefined && tabMeasurements.length > 0) {
|
||||||
|
var tabLesionData = tabMeasurements.filter(function(item){return (item.lesionData.lesionNumber == lesionData.lesionNumber);} )[0];
|
||||||
|
if(tabLesionData != undefined) {
|
||||||
|
existingMeasurement = tabLesionData.lesionData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (existingMeasurement != undefined) {
|
||||||
|
|
||||||
|
var existingTimepoint = existingMeasurement.timepoints;
|
||||||
|
existingTimepoint[timepointID] = {longestDiameter: lesionData.measurementText};
|
||||||
|
|
||||||
|
Measurements.update(
|
||||||
|
{ contentId: contentId, "lesionData.lesionNumber": lesionData.lesionNumber},
|
||||||
|
{
|
||||||
|
$set: {
|
||||||
|
"lesionData.timepoints": existingTimepoint
|
||||||
|
}
|
||||||
|
}, {multi: true}
|
||||||
|
);
|
||||||
|
console.log(Measurements.find())
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
var timepointArr = {};
|
||||||
|
timepointArr[timepointID] = {longestDiameter: lesionData.measurementText};
|
||||||
|
var lesionDataCollectionObject = {
|
||||||
|
lesionNumber: lesionData.lesionNumber,
|
||||||
|
isTarget: true,
|
||||||
|
location: getLocationName(lesionData.locationUID),
|
||||||
|
timepoints: timepointArr
|
||||||
|
};
|
||||||
|
|
||||||
|
Measurements.insert({contentId: contentId, lesionData: lesionDataCollectionObject});
|
||||||
|
console.log(Measurements.find());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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]});
|
||||||
|
}
|
||||||
|
|
||||||
|
insertDataToMeasurementCollection(lesionData);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns new lesion number according to timepointID
|
||||||
|
function getNewLesionNumber (timepointID) {
|
||||||
|
// Check timepoint is in timepoints array
|
||||||
|
for (var i=0; i< timepoints.length; i++) {
|
||||||
|
var timepoint = timepoints[i];
|
||||||
|
if(timepoint.timepointID === timepointID) {
|
||||||
|
return timepoint.rois.length + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add new time point
|
||||||
|
timepoints.push({timepointID: timepointID, rois: []});
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If lesion number is added for any timepoint, returns lesion locationUID
|
||||||
|
function isLesionNumberAdded (lesionNumber) {
|
||||||
|
|
||||||
|
for (var i=0; i< timepoints.length; i++) {
|
||||||
|
var timepoint = timepoints[i];
|
||||||
|
var rois = timepoint.rois;
|
||||||
|
|
||||||
|
for(var j=0; j<rois.length; j++) {
|
||||||
|
var roi = rois[j];
|
||||||
|
if (roi.number === lesionNumber) {
|
||||||
|
return roi.locationUID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds lesion data to Measurements collection
|
||||||
|
function addLesionToMeasurementsCollection (lesionData){
|
||||||
|
Measurements.insert(lesionData);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
addNewLocation: addPatientLocation,
|
||||||
|
getLocations: getPatientLocations,
|
||||||
|
addLesionData: addLesionData,
|
||||||
|
getLesionNumber: getNewLesionNumber,
|
||||||
|
isLesionNumberAdded: isLesionNumberAdded,
|
||||||
|
getTimepoints: getTimepoints
|
||||||
|
|
||||||
|
};
|
||||||
|
})();
|
||||||
@ -1,13 +1,25 @@
|
|||||||
Template.lesionDialog.onRendered(function () {
|
Template.lesionDialog.onRendered(function () {
|
||||||
// Show Lesion Dialog
|
// Show Lesion Dialog
|
||||||
$(document).on("ShowLesionDialog", function (e, eventData) {
|
$(document).on("ShowLesionDialog", function (e, eventData, activeLesionMeasurementData) {
|
||||||
var dialogPointsOnPage = eventData.currentPoints.page;
|
|
||||||
$("#modal-dialog-container").css({
|
var locationUID = measurementManagerDAL.isLesionNumberAdded(activeLesionMeasurementData.lesionNumber);
|
||||||
"top": dialogPointsOnPage.y,
|
|
||||||
"left": dialogPointsOnPage.x
|
if(locationUID != null) {
|
||||||
});
|
|
||||||
|
activeLesionMeasurementData.locationUID = locationUID;
|
||||||
|
measurementManagerDAL.addLesionData(activeLesionMeasurementData);
|
||||||
|
}else{
|
||||||
|
|
||||||
|
// Show Dialog
|
||||||
|
var dialogPointsOnPage = eventData.currentPoints.page;
|
||||||
|
$("#modal-dialog-container").css({
|
||||||
|
"top": dialogPointsOnPage.y,
|
||||||
|
"left": dialogPointsOnPage.x
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#lesionDialog").modal("show");
|
||||||
|
}
|
||||||
|
|
||||||
$("#lesionDialog").modal("show");
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
var lastAddedLesionData;
|
||||||
|
|
||||||
//fill selectLesionLocation element
|
//fill selectLesionLocation element
|
||||||
var lesionLocationsArray = [
|
var lesionLocationsArray = [
|
||||||
{location:"Brain Brainstem",hasDescription:false, description:""},
|
{location:"Brain Brainstem",hasDescription:false, description:""},
|
||||||
@ -8,6 +10,7 @@ var lesionLocationsArray = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
Template.lesionLocationDialog.onRendered(function () {
|
Template.lesionLocationDialog.onRendered(function () {
|
||||||
|
console.log(this.data);
|
||||||
|
|
||||||
function fillSelectLesionLocation () {
|
function fillSelectLesionLocation () {
|
||||||
var el = $("#selectLesionLocation");
|
var el = $("#selectLesionLocation");
|
||||||
@ -19,11 +22,24 @@ Template.lesionLocationDialog.onRendered(function () {
|
|||||||
|
|
||||||
// Fill dropdown
|
// Fill dropdown
|
||||||
fillSelectLesionLocation();
|
fillSelectLesionLocation();
|
||||||
|
|
||||||
|
// Observe Measurements Collection Changes
|
||||||
|
Measurements.find().observe({
|
||||||
|
added: function (lesionData) {
|
||||||
|
lastAddedLesionData = lesionData
|
||||||
|
},
|
||||||
|
changed: function(lesionData) {
|
||||||
|
console.log("lesionData is changed!");
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.lesionLocationDialog.events({
|
Template.lesionLocationDialog.events({
|
||||||
'click button#btnCloseLesionPopup': function (e) {
|
'click button#btnCloseLesionPopup': function (e) {
|
||||||
$("#lesionDialog").modal("hide");
|
$("#lesionDialog").modal("hide");
|
||||||
|
// TODO: Remove lastAddedLesionData from canvas
|
||||||
|
// TODO: Remove lastAddedLesionData from collection
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
'change select#selectLesionLocation': function (e) {
|
'change select#selectLesionLocation': function (e) {
|
||||||
@ -31,8 +47,21 @@ Template.lesionLocationDialog.events({
|
|||||||
var selectedLocationIndex = el.val()
|
var selectedLocationIndex = el.val()
|
||||||
if(selectedLocationIndex !== "-1"){
|
if(selectedLocationIndex !== "-1"){
|
||||||
|
|
||||||
|
// Get selected location data
|
||||||
var locationObj = lesionLocationsArray[selectedLocationIndex];
|
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
|
// Trigger location selected event
|
||||||
$(document).trigger("lesionLocationSelected",locationObj);
|
$(document).trigger("lesionLocationSelected",locationObj);
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,8 @@
|
|||||||
{{ #each measurement }}
|
{{ #each measurement }}
|
||||||
{{ >lesionTableRow }}
|
{{ >lesionTableRow }}
|
||||||
{{ /each }}
|
{{ /each }}
|
||||||
|
|
||||||
|
|
||||||
<!--Each measurement as row-->
|
<!--Each measurement as row-->
|
||||||
<!--Each time point as a column-->
|
<!--Each time point as a column-->
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@ -1,187 +1,52 @@
|
|||||||
measurements = new Meteor.Collection(null);
|
Measurements = new Meteor.Collection(null);
|
||||||
|
TimepointNames = new Meteor.Collection(null);
|
||||||
var test = {
|
|
||||||
lesionNumber: 1,
|
|
||||||
isTarget: true,
|
|
||||||
location: 'Brain',
|
|
||||||
timepoints: {
|
|
||||||
"now": {
|
|
||||||
imageId: "blah",
|
|
||||||
timepointUid: "timepointX",
|
|
||||||
date: 2010,
|
|
||||||
isDirty: true,
|
|
||||||
longestDiameter: 5
|
|
||||||
},
|
|
||||||
"earlier": {
|
|
||||||
imageId: "blah2",
|
|
||||||
timepointUid: "timepointy",
|
|
||||||
date: 2010,
|
|
||||||
isDirty: true,
|
|
||||||
longestDiameter: 8
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
measurements.insert(test);
|
|
||||||
|
|
||||||
Template.lesionTable.helpers({
|
Template.lesionTable.helpers({
|
||||||
'measurement': function() {
|
'measurement': function() {
|
||||||
return measurements.find();
|
var contentId = Session.get("activeContentId");
|
||||||
|
console.log(Measurements.find({contentId: contentId}));
|
||||||
|
return Measurements.find({contentId: contentId});
|
||||||
},
|
},
|
||||||
'timepointNames': function() {
|
'timepointNames': function() {
|
||||||
return [
|
var contentId = Session.get("activeContentId");
|
||||||
{name: 'now'},
|
return Template.instance().timepointNamesDictionary.get(contentId);
|
||||||
{name: 'earlier'}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/*var lesionTableData;
|
|
||||||
setLesionTableData = function (data) {
|
|
||||||
lesionTableData = data;
|
|
||||||
};
|
|
||||||
|
|
||||||
getLesionTableData = function () {
|
|
||||||
return lesionTableData;
|
|
||||||
};
|
|
||||||
|
|
||||||
lesionNumberIsAdded = function(data) {
|
|
||||||
var tabId = data.tabId;
|
|
||||||
var returnValue = {isFound: false, rowIndex : -1};
|
|
||||||
$('#content'+tabId+' table tbody tr td.lesionNumber').each( function(){
|
|
||||||
console.log($(this).text());
|
|
||||||
var lesionNumber = parseInt($(this).text());
|
|
||||||
|
|
||||||
if(lesionNumber == data.lesionNumber) {
|
|
||||||
var $tr = $(this).closest('tr');
|
|
||||||
var rowIndex = $tr.index();
|
|
||||||
returnValue.rowIndex = rowIndex;
|
|
||||||
returnValue.isFound = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return returnValue;
|
|
||||||
};
|
|
||||||
|
|
||||||
returnTblStr = function (obj) {
|
|
||||||
// Get count of lds
|
|
||||||
var tabId = obj.tabId;
|
|
||||||
var lds = $("#content"+tabId).find(".lesionTable th.ld");
|
|
||||||
|
|
||||||
var rowStr = '<tr style="background-color: #b3b3b3;">' +
|
|
||||||
'<td style="text-align:center;"><button type="button" class="btnRemove fa fa-times fa-lg" title="Remove"></button></td>' +
|
|
||||||
'<td style="text-align:center;" class="lesionNumber">'+obj.lesionNumber+'</td>' +
|
|
||||||
'<td style="text-align:center;">Y</td>';
|
|
||||||
|
|
||||||
// Add measurement to right column
|
|
||||||
if(obj.totalViewportCount) {
|
|
||||||
for(var i=0; i< lds.length; i++) {
|
|
||||||
if(i === obj.viewportIndex) {
|
|
||||||
rowStr += '<td>'+obj.lesionLocationObj.location+'</td><td id='+obj.lineIndex+' class="lesion" style="text-align: left;">'+obj.lesions+'</td>';
|
|
||||||
|
|
||||||
}else{
|
|
||||||
rowStr += '<td>'+obj.lesionLocationObj.location+'</td><td class="lesion" style="text-align: left;"></td>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rowStr += '</tr>';
|
|
||||||
|
|
||||||
return rowStr;
|
|
||||||
};
|
|
||||||
|
|
||||||
//Link lesionLocationSelected event
|
|
||||||
$(document).on("lesionLocationSelected",function(event,data ){
|
|
||||||
var lesionData = getLesionTableData();
|
|
||||||
lesionData.lesionLocationObj = data;
|
|
||||||
var tabId = lesionData.tabId;
|
|
||||||
//var el_index = lesionData.viewportIndex;
|
|
||||||
var tableEl = $("#content"+tabId).find(".lesionTable");
|
|
||||||
var tblStr = returnTblStr(lesionData);
|
|
||||||
$(tableEl).append(tblStr);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
//Link addLesionToExistedRow event
|
|
||||||
$(document).on("addLesionToExistedRow",function(event,data ){
|
|
||||||
// Get count of lds
|
|
||||||
var tabId = data.tabId;
|
|
||||||
var lds = $("#content"+tabId).find(".lesionTable th.ld");
|
|
||||||
// Add measurement to right column
|
|
||||||
for(var i=0; i< lds.length; i++) {
|
|
||||||
if(i === data.viewportIndex) {
|
|
||||||
var rowIndex = data.rowIndex + 1;
|
|
||||||
var row = $("#content"+tabId).find(".lesionTable tr").eq(rowIndex);
|
|
||||||
var cell = $(row).find("td.lesion").eq(data.viewportIndex);
|
|
||||||
$(cell).attr("id", data.lineIndex);
|
|
||||||
$(cell).html(data.lesions);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$(document).on("lesionTextChanged", function(event, data){
|
|
||||||
var cellId = data.index;
|
|
||||||
$("td#"+cellId).html(data.measurementText);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
Template.lesionTable.onRendered( function () {
|
|
||||||
|
|
||||||
// TODO: Set lesion table as hiding-panel
|
|
||||||
console.log(this);
|
|
||||||
var template = this;
|
|
||||||
var tabId = this.data.tabId;
|
|
||||||
var viewports = $("#content"+tabId).find(".imageViewerViewport");
|
|
||||||
var lesionTable = $("#content"+tabId).find(".lesionTable");
|
|
||||||
|
|
||||||
var viewportCount = viewports.length;
|
|
||||||
|
|
||||||
var lesionTableWidth = $(lesionTable).width();
|
|
||||||
var viewportWidth = viewports.width();
|
|
||||||
var ldColumnRatio = viewportWidth / lesionTableWidth * 100;
|
|
||||||
|
|
||||||
// Add LD column as viewportCount
|
|
||||||
// Set lesion table columns width
|
|
||||||
|
|
||||||
if(viewportCount > 0) {
|
|
||||||
if(viewportCount == 1) {
|
|
||||||
$('#content'+tabId+' thead tr').append( $('<th />', {text : 'Location', width: ldColumnRatio/2+'%', class:'thLocation'}) )
|
|
||||||
$('#content'+tabId+' thead tr').append( $('<th />', {text : 'LD', width: ldColumnRatio/2+'%', class:'ld'}) )
|
|
||||||
|
|
||||||
} else if(viewportCount == 2) {
|
|
||||||
|
|
||||||
for(var i = 0; i< viewportCount; i++) {
|
|
||||||
$('#content'+tabId+' thead tr').append( $('<th />', {text : 'Location'+i, width: ldColumnRatio/2+'%', class:'thLocation'}) )
|
|
||||||
$('#content'+tabId+' thead tr').append( $('<th />', {text : 'LD'+i, width: ldColumnRatio/2+'%', class:'ld'}) )
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if(viewportCount > 2) {
|
|
||||||
// TODO: Set when viewport count is bigger than 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// TODO: When layout is changed, add and calculate new columns for measurement
|
|
||||||
});
|
|
||||||
|
|
||||||
Template.lesionTable.events({
|
|
||||||
'click button.btnRemove': function (e) {
|
|
||||||
var el = $(e.target);
|
|
||||||
},
|
},
|
||||||
'click table tbody tr': function(e) {
|
'lesionData': function() {
|
||||||
console.log(this);
|
var array = [];
|
||||||
var row = e.currentTarget;
|
var lesions = this.lesionData;
|
||||||
var lesionCells = $(row).find("td.lesion");
|
Object.keys(lesions).forEach(function(key) {
|
||||||
for(var i = 0; i< lesionCells.length; i++) {
|
array.push(lesions[key]);
|
||||||
var cell = lesionCells[i];
|
});
|
||||||
var idAttr = $(cell).attr("id");
|
return array;
|
||||||
if(idAttr != undefined) {
|
|
||||||
// TODO: Create eventObject and trigger LesionToolModified event
|
|
||||||
var viewports = $(".imageViewerViewport");
|
|
||||||
var eventObject = {
|
|
||||||
enabledElement: cornerstone.getEnabledElement(viewports[0]),
|
|
||||||
lineIndex: parseInt(idAttr),
|
|
||||||
type: "active"
|
|
||||||
};
|
|
||||||
$(viewports[0]).trigger("LesionToolModified", eventObject);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});*/
|
});
|
||||||
|
|
||||||
|
Template.lesionTable.onRendered(function() {
|
||||||
|
|
||||||
|
// TODO: Create seperate method
|
||||||
|
var cols = Template.instance().data.viewportColumns.curValue;
|
||||||
|
var rows = Template.instance().data.viewportRows.curValue;
|
||||||
|
|
||||||
|
var totalViewports = cols * rows;
|
||||||
|
|
||||||
|
var contentId = Session.get('activeContentId');
|
||||||
|
for(var i=0; i< totalViewports; i++) {
|
||||||
|
var timepointNamesArray = [];
|
||||||
|
if(Template.instance().timepointNamesDictionary.get(contentId) != undefined) {
|
||||||
|
timepointNamesArray = Template.instance().timepointNamesDictionary.get(contentId);
|
||||||
|
}
|
||||||
|
var timepointID = contentId.toString()+ i.toString();
|
||||||
|
var timepointName = "Baseline";
|
||||||
|
if(i > 0) {
|
||||||
|
timepointName = "Follow Up "+i;
|
||||||
|
}
|
||||||
|
var timepointObject = {id: timepointID, name: timepointName};
|
||||||
|
timepointNamesArray.push(timepointObject);
|
||||||
|
Template.instance().timepointNamesDictionary.set(contentId, timepointNamesArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.lesionTable.onCreated(function() {
|
||||||
|
this.timepointNamesDictionary = new ReactiveDict();
|
||||||
|
});
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#lesionTableContainer
|
#lesionTableContainer
|
||||||
width: 100%
|
width: 100%
|
||||||
height: 25%
|
height: 25%
|
||||||
|
overflow: auto
|
||||||
|
|
||||||
table.lesionTable
|
table.lesionTable
|
||||||
thead
|
thead
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
<template name="lesionTableRow">
|
<template name="lesionTableRow">
|
||||||
<tr>
|
<tr>
|
||||||
<th class='lesionNumber'>{{lesionNumber}}</th>
|
<th class='lesionNumber'>{{lesionData.lesionNumber}}</th>
|
||||||
<th class='target'>{{isTarget}}</th>
|
<th class='target'>{{#if lesionData.isTarget}} Y {{else}} N {{/if}}</th>
|
||||||
<th class='location'>{{location}}</th>
|
<th class='location'>{{lesionData.location}}</th>
|
||||||
<!--Each time point as a column-->
|
<!--Each time point as a column-->
|
||||||
{{ #each timepoints}}
|
{{# each timepoints }}
|
||||||
{{ >lesionTableTimepointCell}}
|
{{> lesionTableTimepointCell }}
|
||||||
{{ /each }}
|
{{/ each }}
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
@ -1,10 +1,10 @@
|
|||||||
Template.lesionTableRow.helpers({
|
Template.lesionTableRow.helpers({
|
||||||
'timepoints': function() {
|
'timepoints': function() {
|
||||||
var array = [];
|
var array = [];
|
||||||
var timepoints = this.timepoints;
|
var timepoints = this.lesionData.timepoints;
|
||||||
Object.keys(timepoints).forEach(function(key) {
|
Object.keys(timepoints).forEach(function(key) {
|
||||||
array.push(timepoints[key]);
|
array.push(timepoints[key]);
|
||||||
});
|
});
|
||||||
return array;
|
return array;
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
7
Packages/lesiontracker/lib/getActiveTimepointID.js
Normal file
7
Packages/lesiontracker/lib/getActiveTimepointID.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
getActiveTimepointID = function (viewportElement) {
|
||||||
|
var contentId = Session.get("activeContentId");
|
||||||
|
var imageViewportElements = $("#"+contentId).find(".imageViewerViewport");
|
||||||
|
var index = $(imageViewportElements).index(viewportElement);
|
||||||
|
|
||||||
|
return contentId.toString() + index.toString();
|
||||||
|
};
|
||||||
250
Packages/lesiontracker/lib/uuid.js
Executable file
250
Packages/lesiontracker/lib/uuid.js
Executable file
@ -0,0 +1,250 @@
|
|||||||
|
// uuid.js
|
||||||
|
//
|
||||||
|
// Copyright (c) 2010-2012 Robert Kieffer
|
||||||
|
// MIT License - http://opensource.org/licenses/mit-license.php
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
var _global = this;
|
||||||
|
|
||||||
|
// Unique ID creation requires a high quality random # generator. We feature
|
||||||
|
// detect to determine the best RNG source, normalizing to a function that
|
||||||
|
// returns 128-bits of randomness, since that's what's usually required
|
||||||
|
var _rng;
|
||||||
|
|
||||||
|
// Allow for MSIE11 msCrypto
|
||||||
|
var _crypto = _global.crypto || _global.msCrypto;
|
||||||
|
|
||||||
|
// Node.js crypto-based RNG - http://nodejs.org/docs/v0.6.2/api/crypto.html
|
||||||
|
//
|
||||||
|
// Moderately fast, high quality
|
||||||
|
if (typeof(_global.require) == 'function') {
|
||||||
|
try {
|
||||||
|
var _rb = _global.require('crypto').randomBytes;
|
||||||
|
_rng = _rb && function() {return _rb(16);};
|
||||||
|
} catch(e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_rng && _crypto && _crypto.getRandomValues) {
|
||||||
|
// WHATWG crypto-based RNG - http://wiki.whatwg.org/wiki/Crypto
|
||||||
|
//
|
||||||
|
// Moderately fast, high quality
|
||||||
|
var _rnds8 = new Uint8Array(16);
|
||||||
|
_rng = function whatwgRNG() {
|
||||||
|
_crypto.getRandomValues(_rnds8);
|
||||||
|
return _rnds8;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_rng) {
|
||||||
|
// Math.random()-based (RNG)
|
||||||
|
//
|
||||||
|
// If all else fails, use Math.random(). It's fast, but is of unspecified
|
||||||
|
// quality.
|
||||||
|
var _rnds = new Array(16);
|
||||||
|
_rng = function() {
|
||||||
|
for (var i = 0, r; i < 16; i++) {
|
||||||
|
if ((i & 0x03) === 0) r = Math.random() * 0x100000000;
|
||||||
|
_rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _rnds;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buffer class to use
|
||||||
|
var BufferClass = typeof(_global.Buffer) == 'function' ? _global.Buffer : Array;
|
||||||
|
|
||||||
|
// Maps for number <-> hex string conversion
|
||||||
|
var _byteToHex = [];
|
||||||
|
var _hexToByte = {};
|
||||||
|
for (var i = 0; i < 256; i++) {
|
||||||
|
_byteToHex[i] = (i + 0x100).toString(16).substr(1);
|
||||||
|
_hexToByte[_byteToHex[i]] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// **`parse()` - Parse a UUID into it's component bytes**
|
||||||
|
function parse(s, buf, offset) {
|
||||||
|
var i = (buf && offset) || 0, ii = 0;
|
||||||
|
|
||||||
|
buf = buf || [];
|
||||||
|
s.toLowerCase().replace(/[0-9a-f]{2}/g, function(oct) {
|
||||||
|
if (ii < 16) { // Don't overflow!
|
||||||
|
buf[i + ii++] = _hexToByte[oct];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Zero out remaining bytes if string was short
|
||||||
|
while (ii < 16) {
|
||||||
|
buf[i + ii++] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
// **`unparse()` - Convert UUID byte array (ala parse()) into a string**
|
||||||
|
function unparse(buf, offset) {
|
||||||
|
var i = offset || 0, bth = _byteToHex;
|
||||||
|
return bth[buf[i++]] + bth[buf[i++]] +
|
||||||
|
bth[buf[i++]] + bth[buf[i++]] + '-' +
|
||||||
|
bth[buf[i++]] + bth[buf[i++]] + '-' +
|
||||||
|
bth[buf[i++]] + bth[buf[i++]] + '-' +
|
||||||
|
bth[buf[i++]] + bth[buf[i++]] + '-' +
|
||||||
|
bth[buf[i++]] + bth[buf[i++]] +
|
||||||
|
bth[buf[i++]] + bth[buf[i++]] +
|
||||||
|
bth[buf[i++]] + bth[buf[i++]];
|
||||||
|
}
|
||||||
|
|
||||||
|
// **`v1()` - Generate time-based UUID**
|
||||||
|
//
|
||||||
|
// Inspired by https://github.com/LiosK/UUID.js
|
||||||
|
// and http://docs.python.org/library/uuid.html
|
||||||
|
|
||||||
|
// random #'s we need to init node and clockseq
|
||||||
|
var _seedBytes = _rng();
|
||||||
|
|
||||||
|
// Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
|
||||||
|
var _nodeId = [
|
||||||
|
_seedBytes[0] | 0x01,
|
||||||
|
_seedBytes[1], _seedBytes[2], _seedBytes[3], _seedBytes[4], _seedBytes[5]
|
||||||
|
];
|
||||||
|
|
||||||
|
// Per 4.2.2, randomize (14 bit) clockseq
|
||||||
|
var _clockseq = (_seedBytes[6] << 8 | _seedBytes[7]) & 0x3fff;
|
||||||
|
|
||||||
|
// Previous uuid creation time
|
||||||
|
var _lastMSecs = 0, _lastNSecs = 0;
|
||||||
|
|
||||||
|
// See https://github.com/broofa/node-uuid for API details
|
||||||
|
function v1(options, buf, offset) {
|
||||||
|
var i = buf && offset || 0;
|
||||||
|
var b = buf || [];
|
||||||
|
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
var clockseq = options.clockseq != null ? options.clockseq : _clockseq;
|
||||||
|
|
||||||
|
// UUID timestamps are 100 nano-second units since the Gregorian epoch,
|
||||||
|
// (1582-10-15 00:00). JSNumbers aren't precise enough for this, so
|
||||||
|
// time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'
|
||||||
|
// (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.
|
||||||
|
var msecs = options.msecs != null ? options.msecs : new Date().getTime();
|
||||||
|
|
||||||
|
// Per 4.2.1.2, use count of uuid's generated during the current clock
|
||||||
|
// cycle to simulate higher resolution clock
|
||||||
|
var nsecs = options.nsecs != null ? options.nsecs : _lastNSecs + 1;
|
||||||
|
|
||||||
|
// Time since last uuid creation (in msecs)
|
||||||
|
var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000;
|
||||||
|
|
||||||
|
// Per 4.2.1.2, Bump clockseq on clock regression
|
||||||
|
if (dt < 0 && options.clockseq == null) {
|
||||||
|
clockseq = clockseq + 1 & 0x3fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset nsecs if clock regresses (new clockseq) or we've moved onto a new
|
||||||
|
// time interval
|
||||||
|
if ((dt < 0 || msecs > _lastMSecs) && options.nsecs == null) {
|
||||||
|
nsecs = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Per 4.2.1.2 Throw error if too many uuids are requested
|
||||||
|
if (nsecs >= 10000) {
|
||||||
|
throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec');
|
||||||
|
}
|
||||||
|
|
||||||
|
_lastMSecs = msecs;
|
||||||
|
_lastNSecs = nsecs;
|
||||||
|
_clockseq = clockseq;
|
||||||
|
|
||||||
|
// Per 4.1.4 - Convert from unix epoch to Gregorian epoch
|
||||||
|
msecs += 12219292800000;
|
||||||
|
|
||||||
|
// `time_low`
|
||||||
|
var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;
|
||||||
|
b[i++] = tl >>> 24 & 0xff;
|
||||||
|
b[i++] = tl >>> 16 & 0xff;
|
||||||
|
b[i++] = tl >>> 8 & 0xff;
|
||||||
|
b[i++] = tl & 0xff;
|
||||||
|
|
||||||
|
// `time_mid`
|
||||||
|
var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff;
|
||||||
|
b[i++] = tmh >>> 8 & 0xff;
|
||||||
|
b[i++] = tmh & 0xff;
|
||||||
|
|
||||||
|
// `time_high_and_version`
|
||||||
|
b[i++] = tmh >>> 24 & 0xf | 0x10; // include version
|
||||||
|
b[i++] = tmh >>> 16 & 0xff;
|
||||||
|
|
||||||
|
// `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)
|
||||||
|
b[i++] = clockseq >>> 8 | 0x80;
|
||||||
|
|
||||||
|
// `clock_seq_low`
|
||||||
|
b[i++] = clockseq & 0xff;
|
||||||
|
|
||||||
|
// `node`
|
||||||
|
var node = options.node || _nodeId;
|
||||||
|
for (var n = 0; n < 6; n++) {
|
||||||
|
b[i + n] = node[n];
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf ? buf : unparse(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
// **`v4()` - Generate random UUID**
|
||||||
|
|
||||||
|
// See https://github.com/broofa/node-uuid for API details
|
||||||
|
function v4(options, buf, offset) {
|
||||||
|
// Deprecated - 'format' argument, as supported in v1.2
|
||||||
|
var i = buf && offset || 0;
|
||||||
|
|
||||||
|
if (typeof(options) == 'string') {
|
||||||
|
buf = options == 'binary' ? new BufferClass(16) : null;
|
||||||
|
options = null;
|
||||||
|
}
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
var rnds = options.random || (options.rng || _rng)();
|
||||||
|
|
||||||
|
// Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
|
||||||
|
rnds[6] = (rnds[6] & 0x0f) | 0x40;
|
||||||
|
rnds[8] = (rnds[8] & 0x3f) | 0x80;
|
||||||
|
|
||||||
|
// Copy bytes to buffer, if provided
|
||||||
|
if (buf) {
|
||||||
|
for (var ii = 0; ii < 16; ii++) {
|
||||||
|
buf[i + ii] = rnds[ii];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf || unparse(rnds);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export public API
|
||||||
|
var uuid = v4;
|
||||||
|
uuid.v1 = v1;
|
||||||
|
uuid.v4 = v4;
|
||||||
|
uuid.parse = parse;
|
||||||
|
uuid.unparse = unparse;
|
||||||
|
uuid.BufferClass = BufferClass;
|
||||||
|
|
||||||
|
if (typeof(module) != 'undefined' && module.exports) {
|
||||||
|
// Publish as node.js module
|
||||||
|
module.exports = uuid;
|
||||||
|
} else if (typeof define === 'function' && define.amd) {
|
||||||
|
// Publish as AMD module
|
||||||
|
define(function() {return uuid;});
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Publish as global (in browsers)
|
||||||
|
var _previousRoot = _global.uuid;
|
||||||
|
|
||||||
|
// **`noConflict()` - (browser only) to reset global 'uuid' var**
|
||||||
|
uuid.noConflict = function() {
|
||||||
|
_global.uuid = _previousRoot;
|
||||||
|
return uuid;
|
||||||
|
};
|
||||||
|
|
||||||
|
_global.uuid = uuid;
|
||||||
|
}
|
||||||
|
}).call(this);
|
||||||
@ -15,6 +15,7 @@ Package.onUse(function (api) {
|
|||||||
api.use('cornerstone');
|
api.use('cornerstone');
|
||||||
|
|
||||||
api.addFiles('compatibility/lesionTool.js', 'client', {bare: true});
|
api.addFiles('compatibility/lesionTool.js', 'client', {bare: true});
|
||||||
|
api.addFiles('compatibility/measurementManagerDAL.js', 'client', {bare: true});
|
||||||
|
|
||||||
api.addFiles('components/lesionDialog/lesionDialog.html', 'client');
|
api.addFiles('components/lesionDialog/lesionDialog.html', 'client');
|
||||||
api.addFiles('components/lesionDialog/lesionDialog.js', 'client');
|
api.addFiles('components/lesionDialog/lesionDialog.js', 'client');
|
||||||
@ -32,4 +33,9 @@ Package.onUse(function (api) {
|
|||||||
api.addFiles('components/lesionTableTimepointCell/lesionTableTimepointCell.html', 'client');
|
api.addFiles('components/lesionTableTimepointCell/lesionTableTimepointCell.html', 'client');
|
||||||
|
|
||||||
api.addFiles('components/lesionTableTimepointHeader/lesionTableTimepointHeader.html', 'client');
|
api.addFiles('components/lesionTableTimepointHeader/lesionTableTimepointHeader.html', 'client');
|
||||||
|
|
||||||
|
// Library functions
|
||||||
|
api.addFiles('lib/getActiveTimepointID.js', 'client');
|
||||||
|
api.addFiles('lib/uuid.js', 'client');
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -255,6 +255,7 @@ Template.imageViewerViewport.events({
|
|||||||
if (this.viewportIndex === this.activeViewport.curValue) {
|
if (this.viewportIndex === this.activeViewport.curValue) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Session.set("ActivateViewportIndex", this.viewportIndex);
|
||||||
console.log('ActivateViewport index: ' + this.viewportIndex);
|
console.log('ActivateViewport index: ' + this.viewportIndex);
|
||||||
this.activeViewport.curValue = this.viewportIndex;
|
this.activeViewport.curValue = this.viewportIndex;
|
||||||
enablePrefetchOnElement(this.viewportIndex);
|
enablePrefetchOnElement(this.viewportIndex);
|
||||||
|
|||||||
@ -18,6 +18,10 @@ switchToTab = function(contentId) {
|
|||||||
var data = ViewerData[contentId];
|
var data = ViewerData[contentId];
|
||||||
|
|
||||||
console.log("Switching to tab: " + contentId);
|
console.log("Switching to tab: " + contentId);
|
||||||
|
|
||||||
|
// Set active tab
|
||||||
|
Session.set("activeContentId", contentId);
|
||||||
|
|
||||||
$('.tabTitle a[data-target="#' + contentId + '"]').tab('show');
|
$('.tabTitle a[data-target="#' + contentId + '"]').tab('show');
|
||||||
|
|
||||||
$("#viewer").remove();
|
$("#viewer").remove();
|
||||||
@ -70,6 +74,7 @@ Template.worklist.onRendered(function() {
|
|||||||
};
|
};
|
||||||
Session.set('ViewerData', ViewerData);
|
Session.set('ViewerData', ViewerData);
|
||||||
|
|
||||||
|
|
||||||
switchToTab(contentId);
|
switchToTab(contentId);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -7,4 +7,4 @@ generateUUID = function() {
|
|||||||
return(c=='x' ? r :(r&0x3|0x8)).toString(8);
|
return(c=='x' ? r :(r&0x3|0x8)).toString(8);
|
||||||
});
|
});
|
||||||
return uuid;
|
return uuid;
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user