PWV-15: Creating routing branch
This commit is contained in:
parent
e618e32341
commit
efb4ca23b5
@ -2,7 +2,6 @@
|
|||||||
{{#if and Template.subscriptionsReady dataSourcesReady}}
|
{{#if and Template.subscriptionsReady dataSourcesReady}}
|
||||||
<div class="viewerDialogs">
|
<div class="viewerDialogs">
|
||||||
{{>confirmDeleteDialog}}
|
{{>confirmDeleteDialog}}
|
||||||
{{>measurementLocationDialog (clone this)}}
|
|
||||||
{{>measurementTableHUD (clone this)}}
|
{{>measurementTableHUD (clone this)}}
|
||||||
{{>cineDialog}}
|
{{>cineDialog}}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { Meteor } from 'meteor/meteor';
|
import { Meteor } from 'meteor/meteor';
|
||||||
import { Template } from 'meteor/templating';
|
import { Template } from 'meteor/templating';
|
||||||
|
import { Tracker } from 'meteor/tracker';
|
||||||
import { Session } from 'meteor/session';
|
import { Session } from 'meteor/session';
|
||||||
import { ReactiveDict } from 'meteor/reactive-dict';
|
import { ReactiveDict } from 'meteor/reactive-dict';
|
||||||
import { _ } from 'meteor/underscore';
|
import { _ } from 'meteor/underscore';
|
||||||
@ -24,6 +25,9 @@ Meteor.startup(() => {
|
|||||||
// Metadata configuration
|
// Metadata configuration
|
||||||
const metadataProvider = OHIF.viewer.metadataProvider;
|
const metadataProvider = OHIF.viewer.metadataProvider;
|
||||||
cornerstoneTools.metaData.addProvider(metadataProvider.getProvider());
|
cornerstoneTools.metaData.addProvider(metadataProvider.getProvider());
|
||||||
|
|
||||||
|
// Target tools configuration
|
||||||
|
OHIF.lesiontracker.configureTargetToolsHandles();
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.viewer.onCreated(() => {
|
Template.viewer.onCreated(() => {
|
||||||
@ -35,6 +39,20 @@ Template.viewer.onCreated(() => {
|
|||||||
|
|
||||||
const instance = Template.instance();
|
const instance = Template.instance();
|
||||||
|
|
||||||
|
const { TimepointApi, MeasurementApi, ConformanceCriteria } = OHIF.measurements;
|
||||||
|
const currentTimepointId = instance.data.currentTimepointId;
|
||||||
|
const timepointApi = new TimepointApi(currentTimepointId);
|
||||||
|
const measurementApi = new MeasurementApi(timepointApi);
|
||||||
|
const conformanceCriteria = new ConformanceCriteria(measurementApi, timepointApi);
|
||||||
|
const apis = {
|
||||||
|
timepointApi,
|
||||||
|
measurementApi,
|
||||||
|
conformanceCriteria
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.assign(OHIF.viewer, apis);
|
||||||
|
Object.assign(instance.data, apis);
|
||||||
|
|
||||||
ValidationErrors.remove({});
|
ValidationErrors.remove({});
|
||||||
|
|
||||||
instance.data.state = new ReactiveDict();
|
instance.data.state = new ReactiveDict();
|
||||||
@ -102,20 +120,15 @@ Template.viewer.onCreated(() => {
|
|||||||
OHIF.viewer.StudyMetadataList.insert(studyMetadata);
|
OHIF.viewer.StudyMetadataList.insert(studyMetadata);
|
||||||
});
|
});
|
||||||
|
|
||||||
instance.data.timepointApi = new OHIF.measurements.TimepointApi(instance.data.currentTimepointId);
|
|
||||||
|
|
||||||
// TODO: Find a better way to pass this to the ViewportOverlay
|
|
||||||
OHIF.viewer.timepointApi = instance.data.timepointApi;
|
|
||||||
|
|
||||||
const patientId = instance.data.studies[0].patientId;
|
const patientId = instance.data.studies[0].patientId;
|
||||||
|
|
||||||
// LT-382: Preventing HP to keep identifying studies in timepoints that might be removed
|
// LT-382: Preventing HP to keep identifying studies in timepoints that might be removed
|
||||||
instance.data.studies.forEach(study => (delete study.timepointType));
|
instance.data.studies.forEach(study => (delete study.timepointType));
|
||||||
|
|
||||||
// TODO: Consider combining the retrieval calls into one?
|
// TODO: Consider combining the retrieval calls into one?
|
||||||
const timepointsPromise = instance.data.timepointApi.retrieveTimepoints(patientId);
|
const timepointsPromise = timepointApi.retrieveTimepoints(patientId);
|
||||||
timepointsPromise.then(() => {
|
timepointsPromise.then(() => {
|
||||||
const timepoints = instance.data.timepointApi.all();
|
const timepoints = timepointApi.all();
|
||||||
|
|
||||||
// Set timepointType in studies to be used in hanging protocol engine
|
// Set timepointType in studies to be used in hanging protocol engine
|
||||||
timepoints.forEach(timepoint => {
|
timepoints.forEach(timepoint => {
|
||||||
@ -135,21 +148,19 @@ Template.viewer.onCreated(() => {
|
|||||||
Session.set('TimepointsReady', true);
|
Session.set('TimepointsReady', true);
|
||||||
|
|
||||||
const timepointIds = timepoints.map(t => t.timepointId);
|
const timepointIds = timepoints.map(t => t.timepointId);
|
||||||
instance.data.measurementApi = new OHIF.measurements.MeasurementApi(instance.data.timepointApi);
|
|
||||||
instance.data.conformanceCriteria = new OHIF.measurements.ConformanceCriteria(instance.data.measurementApi, instance.data.timepointApi);
|
|
||||||
|
|
||||||
const measurementsPromise = instance.data.measurementApi.retrieveMeasurements(patientId, timepointIds);
|
const measurementsPromise = measurementApi.retrieveMeasurements(patientId, timepointIds);
|
||||||
measurementsPromise.then(() => {
|
measurementsPromise.then(() => {
|
||||||
Session.set('MeasurementsReady', true);
|
Session.set('MeasurementsReady', true);
|
||||||
|
|
||||||
instance.data.measurementApi.syncMeasurementsAndToolData();
|
measurementApi.syncMeasurementsAndToolData();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Provide the necessary data to the Measurement API and Timepoint API
|
// Provide the necessary data to the Measurement API and Timepoint API
|
||||||
const prior = instance.data.timepointApi.prior();
|
const prior = timepointApi.prior();
|
||||||
if (prior) {
|
if (prior) {
|
||||||
instance.data.measurementApi.priorTimepointId = prior.timepointId;
|
measurementApi.priorTimepointId = prior.timepointId;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instance.data.currentTimepointId) {
|
if (instance.data.currentTimepointId) {
|
||||||
@ -177,8 +188,6 @@ Template.viewer.onCreated(() => {
|
|||||||
const tools = config.measurementTools[0].childTools;
|
const tools = config.measurementTools[0].childTools;
|
||||||
const firstTool = tools[Object.keys(tools)[0]];
|
const firstTool = tools[Object.keys(tools)[0]];
|
||||||
const measurementTypeId = firstTool.id;
|
const measurementTypeId = firstTool.id;
|
||||||
const measurementApi = instance.data.measurementApi;
|
|
||||||
const timepointApi = instance.data.timepointApi;
|
|
||||||
|
|
||||||
const collection = measurementApi.tools[measurementTypeId];
|
const collection = measurementApi.tools[measurementTypeId];
|
||||||
const sorting = {
|
const sorting = {
|
||||||
@ -230,44 +239,45 @@ const setActiveToolAndSidebar = () => {
|
|||||||
const { studies, currentTimepointId, measurementApi, timepointIds } = instance.data;
|
const { studies, currentTimepointId, measurementApi, timepointIds } = instance.data;
|
||||||
|
|
||||||
// Default actions for Associated Studies
|
// Default actions for Associated Studies
|
||||||
if(currentTimepointId) {
|
if (currentTimepointId) {
|
||||||
// Follow-up studies: same as the first measurement in the table
|
// Follow-up studies: same as the first measurement in the table
|
||||||
// Baseline studies: target-tool
|
// Baseline studies: target-tool
|
||||||
if(studies[0]) {
|
if (studies[0]) {
|
||||||
let activeTool;
|
let activeTool;
|
||||||
// In follow-ups, get the baseline timepointId
|
// In follow-ups, get the baseline timepointId
|
||||||
const timepointId = timepointIds.find(id => id !== currentTimepointId);
|
const timepointId = timepointIds.find(id => id !== currentTimepointId);
|
||||||
|
|
||||||
// Follow-up studies
|
// Follow-up studies
|
||||||
if(studies[0].timepointType === 'followup' && timepointId) {
|
if (studies[0].timepointType === 'followup' && timepointId) {
|
||||||
const measurementTools = OHIF.measurements.MeasurementApi.getConfiguration().measurementTools;
|
const measurementTools = OHIF.measurements.MeasurementApi.getConfiguration().measurementTools;
|
||||||
|
|
||||||
// Create list of measurement tools
|
// Create list of measurement tools
|
||||||
const measurementTypes = measurementTools.map(
|
const measurementTypes = measurementTools.map(
|
||||||
tool => {
|
tool => {
|
||||||
const { id, cornerstoneToolType } = tool;
|
const { id, cornerstoneToolType } = tool;
|
||||||
return {
|
return {
|
||||||
id,
|
id,
|
||||||
cornerstoneToolType
|
cornerstoneToolType
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// Iterate over each measurement tool to find the first baseline
|
// Iterate over each measurement tool to find the first baseline
|
||||||
// measurement. If so, stops the loop and prevent fetching from all
|
// measurement. If so, stops the loop and prevent fetching from all
|
||||||
// collections
|
// collections
|
||||||
measurementTypes.every(({id, cornerstoneToolType}) => {
|
measurementTypes.every(({ id, cornerstoneToolType }) => {
|
||||||
// Get measurement
|
// Get measurement
|
||||||
if(measurementApi[id]) {
|
if (measurementApi[id]) {
|
||||||
const measurement = measurementApi[id].findOne({ timepointId });
|
const measurement = measurementApi[id].findOne({ timepointId });
|
||||||
|
|
||||||
// Found a measurement, save tool and stop loop
|
// Found a measurement, save tool and stop loop
|
||||||
if(measurement) {
|
if (measurement) {
|
||||||
activeTool = cornerstoneToolType;
|
activeTool = cornerstoneToolType;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -276,14 +286,14 @@ const setActiveToolAndSidebar = () => {
|
|||||||
OHIF.viewerbase.toolManager.setActiveTool(activeTool || 'bidirectional');
|
OHIF.viewerbase.toolManager.setActiveTool(activeTool || 'bidirectional');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toggle Measurement Table
|
// Toggle Measurement Table
|
||||||
if(instance.data.state) {
|
if (instance.data.state) {
|
||||||
instance.data.state.set('rightSidebar', 'measurements');
|
instance.data.state.set('rightSidebar', 'measurements');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Hide as default for single study
|
// Hide as default for single study
|
||||||
else {
|
else {
|
||||||
if(instance.data.state) {
|
if (instance.data.state) {
|
||||||
instance.data.state.set('rightSidebar', null);
|
instance.data.state.set('rightSidebar', null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,3 @@ import './optionsModal/optionsModal.js';
|
|||||||
|
|
||||||
import './optionsModal/recistDescription/recistDescription.html';
|
import './optionsModal/recistDescription/recistDescription.html';
|
||||||
import './optionsModal/irRCDescription/irRCDescription.html';
|
import './optionsModal/irRCDescription/irRCDescription.html';
|
||||||
|
|
||||||
import './measurementLocationDialog/measurementLocationDialog.html';
|
|
||||||
import './measurementLocationDialog/measurementLocationDialog.js';
|
|
||||||
import './measurementLocationDialog/measurementLocationDialog.styl';
|
|
||||||
|
|||||||
@ -1,38 +0,0 @@
|
|||||||
<template name="measurementLocationDialog">
|
|
||||||
<div id="measurementLocationDialog" class="dialog-animated" tabindex="0">
|
|
||||||
<div class="dialogHeader">
|
|
||||||
<h4>Select Location</h4>
|
|
||||||
</div>
|
|
||||||
<div class="dialogContent">
|
|
||||||
<div class="measurementLocation">
|
|
||||||
<label>Location</label>
|
|
||||||
<select class="selectMeasurementLocation">
|
|
||||||
<option value="-1"></option>
|
|
||||||
{{ #each measurementLocations}}
|
|
||||||
<option value='{{_id}}'>{{location}}</option>
|
|
||||||
{{ /each}}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="measurementLocationRelabelDialog" class="dialog-animated" tabindex="0">
|
|
||||||
<div class="dialogHeader">
|
|
||||||
<h4>Change Location</h4>
|
|
||||||
</div>
|
|
||||||
<a></a>
|
|
||||||
<div class="dialogContent">
|
|
||||||
<div class="measurementLocation">
|
|
||||||
<label>Location</label>
|
|
||||||
<select class="selectMeasurementLocation">
|
|
||||||
<option value="-1"></option>
|
|
||||||
{{ #each measurementLocations}}
|
|
||||||
<option value='{{_id}}' selected={{selected}}>{{location}}</option>
|
|
||||||
{{ /each}}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<button id="removeLesion" class="btn btn-link">Remove</button>
|
|
||||||
<button id="convertToNonTarget" class="btn btn-link">Convert to Non-Target</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
@ -1,91 +0,0 @@
|
|||||||
// Note: This component is not in use, but the functions below are still being used. This
|
|
||||||
// is in the process of being moved into another location
|
|
||||||
import { OHIF } from 'meteor/ohif:core';
|
|
||||||
|
|
||||||
Template.measurementLocationDialog.onCreated(() => {
|
|
||||||
const instance = Template.instance();
|
|
||||||
const measurementApi = instance.data.measurementApi;
|
|
||||||
|
|
||||||
const toggleLabel = (measurementData, eventData, doneCallback) => {
|
|
||||||
delete measurementData.isCreating;
|
|
||||||
|
|
||||||
if (OHIF.lesiontracker.removeMeasurementIfInvalid(measurementData, eventData)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const getHandlePosition = key => _.pick(measurementData.handles[key], ['x', 'y']);
|
|
||||||
const start = getHandlePosition('start');
|
|
||||||
const end = getHandlePosition('end');
|
|
||||||
const getDirection = axis => start[axis] < end[axis] ? 1 : -1;
|
|
||||||
const position = OHIF.cornerstone.pixelToPage(eventData.element, end);
|
|
||||||
|
|
||||||
OHIF.measurements.toggleLabelButton({
|
|
||||||
instance,
|
|
||||||
measurement: measurementData,
|
|
||||||
element: eventData.element,
|
|
||||||
measurementApi,
|
|
||||||
position: position,
|
|
||||||
direction: {
|
|
||||||
x: getDirection('x'),
|
|
||||||
y: getDirection('y')
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const callbackConfig = {
|
|
||||||
// TODO: Check the position for these, the Add Label button position seems very awkward
|
|
||||||
getMeasurementLocationCallback: toggleLabel,
|
|
||||||
changeMeasurementLocationCallback: toggleLabel,
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: Reconcile this with the configuration in toolManager
|
|
||||||
// it would be better to have this all in one place.
|
|
||||||
const bidirectionalConfig = cornerstoneTools.bidirectional.getConfiguration();
|
|
||||||
const config = {
|
|
||||||
...bidirectionalConfig,
|
|
||||||
...callbackConfig
|
|
||||||
};
|
|
||||||
|
|
||||||
cornerstoneTools.bidirectional.setConfiguration(config);
|
|
||||||
|
|
||||||
// Set CR-Tool, UN-Tool, EX-Tool configurations
|
|
||||||
cornerstoneTools.targetCR.setConfiguration(config);
|
|
||||||
cornerstoneTools.targetUN.setConfiguration(config);
|
|
||||||
cornerstoneTools.targetEX.setConfiguration(config);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
// Note: None of these events work anymore
|
|
||||||
Template.measurementLocationDialog.events({
|
|
||||||
'click #removeMeasurement'() {
|
|
||||||
const measurementData = Template.measurementLocationDialog.measurementData;
|
|
||||||
const doneCallback = Template.measurementLocationDialog.doneCallback;
|
|
||||||
const dialog = Template.measurementLocationDialog.dialog;
|
|
||||||
|
|
||||||
const options = {
|
|
||||||
keyPressAllowed: false,
|
|
||||||
title: 'Remove measurement?',
|
|
||||||
text: 'Are you sure you would like to remove the entire measurement?'
|
|
||||||
};
|
|
||||||
|
|
||||||
showConfirmDialog(function() {
|
|
||||||
if (doneCallback && typeof doneCallback === 'function') {
|
|
||||||
const deleteTool = true;
|
|
||||||
doneCallback(measurementData, deleteTool);
|
|
||||||
}
|
|
||||||
}, options);
|
|
||||||
|
|
||||||
closeHandler(dialog);
|
|
||||||
},
|
|
||||||
|
|
||||||
'click #convertToNonTarget'() {
|
|
||||||
const measurementData = Template.measurementLocationDialog.measurementData;
|
|
||||||
const dialog = Template.measurementLocationDialog.dialog;
|
|
||||||
|
|
||||||
const instance = Template.instance();
|
|
||||||
const measurementApi = instance.data.measurementApi;
|
|
||||||
OHIF.measurementTracker.convertToNonTarget(measurementApi, measurementData);
|
|
||||||
|
|
||||||
closeHandler(dialog);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
#measurementLocationDialog, #measurementLocationRelabelDialog
|
|
||||||
display: none
|
|
||||||
position: absolute
|
|
||||||
top: 0
|
|
||||||
bottom: 0
|
|
||||||
left: 0
|
|
||||||
right: 0
|
|
||||||
z-index: 100
|
|
||||||
width: 300px
|
|
||||||
height: 130px
|
|
||||||
border-radius: 5px
|
|
||||||
padding: 10px 20px 10px 20px
|
|
||||||
background-color: rgba(255,255,255,1)
|
|
||||||
outline: none
|
|
||||||
|
|
||||||
#closeLesionPopup
|
|
||||||
outline: none
|
|
||||||
border: none
|
|
||||||
background-color: transparent
|
|
||||||
|
|
||||||
#selectMeasurementLocation
|
|
||||||
margin-top: 5px
|
|
||||||
|
|
||||||
.dialogContent
|
|
||||||
margin-bottom: 10px
|
|
||||||
|
|
||||||
#removeLesion
|
|
||||||
outline: none
|
|
||||||
text-decoration: none
|
|
||||||
|
|
||||||
#measurementLocationDialog
|
|
||||||
height: 110px
|
|
||||||
|
|
||||||
#measurementLocationRelabelDialog
|
|
||||||
height: 125px
|
|
||||||
@ -1,4 +1,3 @@
|
|||||||
import { Template } from 'meteor/templating';
|
|
||||||
import { OHIF } from 'meteor/ohif:core';
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
|
|
||||||
// Define the Trial Criteria Structure
|
// Define the Trial Criteria Structure
|
||||||
@ -21,9 +20,9 @@ OHIF.lesiontracker.TrialCriteriaConstraints = {
|
|||||||
* - Time Point Measurement Total = Sum of long axis measurements for extranodal target lesion + short axis measurements for nodal lesions
|
* - Time Point Measurement Total = Sum of long axis measurements for extranodal target lesion + short axis measurements for nodal lesions
|
||||||
*/
|
*/
|
||||||
function RECIST(image) {
|
function RECIST(image) {
|
||||||
var acquisitionSliceThickness;
|
let acquisitionSliceThickness;
|
||||||
|
|
||||||
var isChestXray;
|
let isChestXray;
|
||||||
if (image) {
|
if (image) {
|
||||||
acquisitionSliceThickness = image.acquisitionSliceThickness;
|
acquisitionSliceThickness = image.acquisitionSliceThickness;
|
||||||
|
|
||||||
@ -32,7 +31,7 @@ function RECIST(image) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Define the RECIST 1.1 structure
|
// Define the RECIST 1.1 structure
|
||||||
var criteria = {
|
const criteria = {
|
||||||
baseline: {
|
baseline: {
|
||||||
target: {},
|
target: {},
|
||||||
nonTarget: {},
|
nonTarget: {},
|
||||||
@ -160,13 +159,13 @@ function RECIST(image) {
|
|||||||
* - Target lesions must have measurements (cannot be assessed as CR, UN/NE, EX)
|
* - Target lesions must have measurements (cannot be assessed as CR, UN/NE, EX)
|
||||||
*/
|
*/
|
||||||
function irRC(image) {
|
function irRC(image) {
|
||||||
var acquisitionSliceThickness;
|
let acquisitionSliceThickness;
|
||||||
if (image) {
|
if (image) {
|
||||||
acquisitionSliceThickness = image.acquisitionSliceThickness;
|
acquisitionSliceThickness = image.acquisitionSliceThickness;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define the irRC structure
|
// Define the irRC structure
|
||||||
var criteria = {
|
const criteria = {
|
||||||
baseline: {
|
baseline: {
|
||||||
target: {},
|
target: {},
|
||||||
nonTarget: {}
|
nonTarget: {}
|
||||||
@ -372,7 +371,7 @@ OHIF.lesiontracker.getTrialCriteriaConstraints = (criteriaTypes, imageId) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find the related Timepoint document
|
// Find the related Timepoint document
|
||||||
const timepointApi = Template.instance().timepointApi;
|
const { timepointApi } = OHIF.viewer;
|
||||||
if (!timepointApi) {
|
if (!timepointApi) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,47 @@
|
|||||||
|
import { _ } from 'meteor/underscore';
|
||||||
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
|
|
||||||
|
OHIF.lesiontracker.configureTargetToolsHandles = () => {
|
||||||
|
const toggleLabel = (measurementData, eventData, doneCallback) => {
|
||||||
|
delete measurementData.isCreating;
|
||||||
|
|
||||||
|
if (OHIF.lesiontracker.removeMeasurementIfInvalid(measurementData, eventData)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const getHandlePosition = key => _.pick(measurementData.handles[key], ['x', 'y']);
|
||||||
|
const start = getHandlePosition('start');
|
||||||
|
const end = getHandlePosition('end');
|
||||||
|
const getDirection = axis => start[axis] < end[axis] ? 1 : -1;
|
||||||
|
const position = OHIF.cornerstone.pixelToPage(eventData.element, end);
|
||||||
|
|
||||||
|
OHIF.measurements.toggleLabelButton({
|
||||||
|
measurement: measurementData,
|
||||||
|
element: eventData.element,
|
||||||
|
measurementApi: OHIF.viewer.measurementApi,
|
||||||
|
position: position,
|
||||||
|
direction: {
|
||||||
|
x: getDirection('x'),
|
||||||
|
y: getDirection('y')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const callbackConfig = {
|
||||||
|
// TODO: Check the position for these, the Add Label button position seems very awkward
|
||||||
|
getMeasurementLocationCallback: toggleLabel,
|
||||||
|
changeMeasurementLocationCallback: toggleLabel,
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: Reconcile this with the configuration in toolManager
|
||||||
|
// it would be better to have this all in one place.
|
||||||
|
const bidirectionalConfig = cornerstoneTools.bidirectional.getConfiguration();
|
||||||
|
const config = Object.assign({}, bidirectionalConfig, callbackConfig);
|
||||||
|
|
||||||
|
cornerstoneTools.bidirectional.setConfiguration(config);
|
||||||
|
|
||||||
|
// Set CR-Tool, UN-Tool, EX-Tool configurations
|
||||||
|
cornerstoneTools.targetCR.setConfiguration(config);
|
||||||
|
cornerstoneTools.targetUN.setConfiguration(config);
|
||||||
|
cornerstoneTools.targetEX.setConfiguration(config);
|
||||||
|
};
|
||||||
@ -1,72 +0,0 @@
|
|||||||
import { OHIF } from 'meteor/ohif:core';
|
|
||||||
|
|
||||||
var responseTypes = {
|
|
||||||
targetCR: 'CR',
|
|
||||||
targetUN: 'UN',
|
|
||||||
targetEX: 'EX'
|
|
||||||
};
|
|
||||||
|
|
||||||
convertNonTarget = function(measurementApi, measurementData, newTooltype) {
|
|
||||||
if (measurementData.toolType !== 'nonTarget') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var measurement = Measurements.findOne(measurementData.id);
|
|
||||||
|
|
||||||
var timepoint = Timepoints.findOne({
|
|
||||||
timepointId: measurementData.timepointId
|
|
||||||
});
|
|
||||||
|
|
||||||
if (timepoint && timepoint.timepointType !== 'followup') {
|
|
||||||
OHIF.log.warn('Not a followup');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Next, update the measurementData and add it to the new tool type
|
|
||||||
var newMeasurement = {
|
|
||||||
id: 'notready',
|
|
||||||
lesionNumber: measurementApi.getNewLesionNumber(measurementData.timepointId, false),
|
|
||||||
visible: true,
|
|
||||||
active: true,
|
|
||||||
imageId: measurementData.imageId,
|
|
||||||
seriesInstanceUid: measurementData.seriesInstanceUid,
|
|
||||||
studyInstanceUid: measurementData.studyInstanceUid,
|
|
||||||
patientId: measurementData.patientId,
|
|
||||||
isTarget: false,
|
|
||||||
toolType: newTooltype
|
|
||||||
};
|
|
||||||
|
|
||||||
newMeasurement.handles = measurementData.handles;
|
|
||||||
|
|
||||||
if (responseTypes[newTooltype]) {
|
|
||||||
newMeasurement.response = responseTypes[newTooltype];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adds lesion data to timepoints array
|
|
||||||
measurementApi.updateLesionData(newMeasurement);
|
|
||||||
|
|
||||||
// Set the new Measurement to have the same location as the old one
|
|
||||||
if (measurement.location && measurement.locationId) {
|
|
||||||
var existingMeasurement = Measurements.findOne({
|
|
||||||
lesionNumber: newMeasurement.lesionNumber,
|
|
||||||
isTarget: newMeasurement.isTarget
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!existingMeasurement) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Measurements.update(existingMeasurement._id, {
|
|
||||||
$set: {
|
|
||||||
location: measurement.location,
|
|
||||||
locationId: measurement.locationId
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (measurement) {
|
|
||||||
// Remove the timepointData from this Measurement and update it
|
|
||||||
// in the database, if it is already in the database
|
|
||||||
OHIF.lesiontracker.clearMeasurementTimepointData(measurement._id, measurementData.timepointId);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@ -1,86 +0,0 @@
|
|||||||
import { OHIF } from 'meteor/ohif:core';
|
|
||||||
|
|
||||||
OHIF.lesiontracker.convertToNonTarget = (measurementApi, measurementData) => {
|
|
||||||
if (measurementData.isTarget === false) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const measurement = Measurements.findOne(measurementData.id);
|
|
||||||
|
|
||||||
const timepoint = Timepoints.findOne({
|
|
||||||
timepointId: measurementData.timepointId
|
|
||||||
});
|
|
||||||
|
|
||||||
// Next, update the measurementData and add it to the new tool type
|
|
||||||
const toolType = 'nonTarget';
|
|
||||||
const newMeasurement = {
|
|
||||||
id: 'notready',
|
|
||||||
lesionNumber: LesionManager.getNewLesionNumber(measurementData.timepointId, false),
|
|
||||||
visible: true,
|
|
||||||
active: true,
|
|
||||||
imageId: measurementData.imageId,
|
|
||||||
seriesInstanceUid: measurementData.seriesInstanceUid,
|
|
||||||
studyInstanceUid: measurementData.studyInstanceUid,
|
|
||||||
patientId: measurementData.patientId,
|
|
||||||
isTarget: false,
|
|
||||||
toolType: toolType
|
|
||||||
};
|
|
||||||
|
|
||||||
if (timepoint && timepoint.timepointType === 'baseline') {
|
|
||||||
newMeasurement.response = 'Present';
|
|
||||||
} else {
|
|
||||||
newMeasurement.response = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
newMeasurement.handles = {
|
|
||||||
start: {
|
|
||||||
x: (measurementData.handles.start.x + measurementData.handles.end.x) / 2,
|
|
||||||
y: (measurementData.handles.start.y + measurementData.handles.end.y) / 2,
|
|
||||||
highlight: true,
|
|
||||||
active: false
|
|
||||||
},
|
|
||||||
end: {
|
|
||||||
x: Math.min(measurementData.handles.start.x, measurementData.handles.end.x),
|
|
||||||
y: Math.min(measurementData.handles.start.y, measurementData.handles.end.y),
|
|
||||||
highlight: true,
|
|
||||||
active: false
|
|
||||||
},
|
|
||||||
textBox: {
|
|
||||||
x: measurementData.handles.textBox.x,
|
|
||||||
y: measurementData.handles.textBox.y,
|
|
||||||
active: false,
|
|
||||||
movesIndependently: false,
|
|
||||||
drawnIndependently: true,
|
|
||||||
allowedOutsideImage: true,
|
|
||||||
hasBoundingBox: true
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Adds lesion data to timepoints array
|
|
||||||
LesionManager.updateLesionData(newMeasurement);
|
|
||||||
|
|
||||||
// Set the new Measurement to have the same location as the old one
|
|
||||||
if (measurement.location && measurement.locationId) {
|
|
||||||
var existingMeasurement = Measurements.findOne({
|
|
||||||
lesionNumber: newMeasurement.lesionNumber,
|
|
||||||
isTarget: newMeasurement.isTarget
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!existingMeasurement) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Measurements.update(existingMeasurement._id, {
|
|
||||||
$set: {
|
|
||||||
location: measurement.location,
|
|
||||||
locationId: measurement.locationId
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (measurement) {
|
|
||||||
// Remove the timepointData from this Measurement and update it
|
|
||||||
// in the database, if it is already in the database
|
|
||||||
OHIF.lesiontracker.clearMeasurementTimepointData(measurement._id, measurementData.timepointId);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@ -9,5 +9,4 @@ import './pixelSpacingAutorunCheck.js';
|
|||||||
import './removeMeasurementIfInvalid.js';
|
import './removeMeasurementIfInvalid.js';
|
||||||
import './toggleLesionTrackerTools.js';
|
import './toggleLesionTrackerTools.js';
|
||||||
import './clearMeasurementTimepointData.js';
|
import './clearMeasurementTimepointData.js';
|
||||||
import './convertToNonTarget.js';
|
import './configureTargetToolsHandles.js';
|
||||||
import './convertNonTarget.js';
|
|
||||||
|
|||||||
@ -12,8 +12,6 @@ Template.caseProgress.onCreated(() => {
|
|||||||
instance.path = 'viewer.studyViewer.measurements';
|
instance.path = 'viewer.studyViewer.measurements';
|
||||||
|
|
||||||
instance.saveData = () => {
|
instance.saveData = () => {
|
||||||
const api = instance.data.measurementApi;
|
|
||||||
|
|
||||||
// Clear signaled unsaved changes...
|
// Clear signaled unsaved changes...
|
||||||
const successHandler = () => {
|
const successHandler = () => {
|
||||||
OHIF.ui.unsavedChanges.clear(`${instance.path}.*`);
|
OHIF.ui.unsavedChanges.clear(`${instance.path}.*`);
|
||||||
@ -22,7 +20,7 @@ Template.caseProgress.onCreated(() => {
|
|||||||
// Display the error messages
|
// Display the error messages
|
||||||
const errorHandler = data => OHIF.ui.showDialog('dialogInfo', data);
|
const errorHandler = data => OHIF.ui.showDialog('dialogInfo', data);
|
||||||
|
|
||||||
const promise = api.storeMeasurements();
|
const promise = instance.data.measurementApi.storeMeasurements();
|
||||||
promise.then(successHandler).catch(errorHandler);
|
promise.then(successHandler).catch(errorHandler);
|
||||||
OHIF.ui.showDialog('dialogLoading', {
|
OHIF.ui.showDialog('dialogLoading', {
|
||||||
promise,
|
promise,
|
||||||
@ -51,16 +49,17 @@ Template.caseProgress.onDestroyed(() => {
|
|||||||
|
|
||||||
Template.caseProgress.onRendered(() => {
|
Template.caseProgress.onRendered(() => {
|
||||||
const instance = Template.instance();
|
const instance = Template.instance();
|
||||||
|
const { timepointApi, measurementApi } = instance.data;
|
||||||
|
|
||||||
// Stop here if we have no current timepoint ID (and therefore no defined timepointAPI)
|
// Stop here if we have no current timepoint ID (and therefore no defined timepointAPI)
|
||||||
if (!instance.data.timepointApi) {
|
if (!timepointApi) {
|
||||||
instance.progressPercent.set(100);
|
instance.progressPercent.set(100);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the current timepoint
|
// Get the current timepoint
|
||||||
const current = instance.data.timepointApi.current();
|
const current = timepointApi.current();
|
||||||
const prior = instance.data.timepointApi.prior();
|
const prior = timepointApi.prior();
|
||||||
if (!current || !prior || !current.timepointId) {
|
if (!current || !prior || !current.timepointId) {
|
||||||
instance.progressPercent.set(100);
|
instance.progressPercent.set(100);
|
||||||
return;
|
return;
|
||||||
@ -72,7 +71,6 @@ Template.caseProgress.onRendered(() => {
|
|||||||
// follow-up. Note that this is done outside of the reactive function
|
// follow-up. Note that this is done outside of the reactive function
|
||||||
// below so that new lesions don't change the initial target count.
|
// below so that new lesions don't change the initial target count.
|
||||||
|
|
||||||
const api = instance.data.measurementApi;
|
|
||||||
const config = OHIF.measurements.MeasurementApi.getConfiguration();
|
const config = OHIF.measurements.MeasurementApi.getConfiguration();
|
||||||
const toolGroups = config.measurementTools;
|
const toolGroups = config.measurementTools;
|
||||||
|
|
||||||
@ -95,7 +93,7 @@ Template.caseProgress.onRendered(() => {
|
|||||||
|
|
||||||
let count = 0;
|
let count = 0;
|
||||||
toolGroups.forEach(toolGroup => {
|
toolGroups.forEach(toolGroup => {
|
||||||
count += api.fetch(toolGroup.id, filter).length;
|
count += measurementApi.fetch(toolGroup.id, filter).length;
|
||||||
});
|
});
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
@ -108,8 +106,8 @@ Template.caseProgress.onRendered(() => {
|
|||||||
let totalRemaining = 0;
|
let totalRemaining = 0;
|
||||||
toolGroups.forEach(toolGroup => {
|
toolGroups.forEach(toolGroup => {
|
||||||
const toolGroupId = toolGroup.id;
|
const toolGroupId = toolGroup.id;
|
||||||
const numCurrent = api.fetch(toolGroupId, currentFilter).length;
|
const numCurrent = measurementApi.fetch(toolGroupId, currentFilter).length;
|
||||||
const numPrior = api.fetch(toolGroupId, priorFilter).length;
|
const numPrior = measurementApi.fetch(toolGroupId, priorFilter).length;
|
||||||
const remaining = Math.max(numPrior - numCurrent, 0);
|
const remaining = Math.max(numPrior - numCurrent, 0);
|
||||||
totalRemaining += remaining;
|
totalRemaining += remaining;
|
||||||
});
|
});
|
||||||
@ -125,7 +123,7 @@ Template.caseProgress.onRendered(() => {
|
|||||||
// Setup a reactive function to update the progress whenever
|
// Setup a reactive function to update the progress whenever
|
||||||
// a measurement is made
|
// a measurement is made
|
||||||
instance.autorun(() => {
|
instance.autorun(() => {
|
||||||
api.changeObserver.depend();
|
measurementApi.changeObserver.depend();
|
||||||
// Obtain the number of Measurements for which the current Timepoint has
|
// Obtain the number of Measurements for which the current Timepoint has
|
||||||
// no Measurement data
|
// no Measurement data
|
||||||
const totalMeasurements = getNumMeasurementsAtTimepoint(prior.timepointId);
|
const totalMeasurements = getNumMeasurementsAtTimepoint(prior.timepointId);
|
||||||
|
|||||||
@ -14,13 +14,14 @@ Template.measurementTable.onCreated(() => {
|
|||||||
// Get the current table layout
|
// Get the current table layout
|
||||||
const tableLayout = instance.data.measurementTableLayout.get();
|
const tableLayout = instance.data.measurementTableLayout.get();
|
||||||
|
|
||||||
|
const timepointApi = instance.data.timepointApi;
|
||||||
let timepoints;
|
let timepoints;
|
||||||
if (!instance.data.timepointApi) {
|
if (!timepointApi) {
|
||||||
timepoints = [];
|
timepoints = [];
|
||||||
} else if (tableLayout === 'key') {
|
} else if (tableLayout === 'key') {
|
||||||
timepoints = instance.data.timepointApi.key();
|
timepoints = timepointApi.key();
|
||||||
} else {
|
} else {
|
||||||
timepoints = instance.data.timepointApi.currentAndPrior();
|
timepoints = timepointApi.currentAndPrior();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return key timepoints
|
// Return key timepoints
|
||||||
|
|||||||
@ -1,9 +1,14 @@
|
|||||||
|
import { Template } from 'meteor/templating';
|
||||||
|
import { Session } from 'meteor/session';
|
||||||
|
import { ReactiveVar } from 'meteor/reactive-var';
|
||||||
|
|
||||||
Template.measurementTableHUD.onCreated(() => {
|
Template.measurementTableHUD.onCreated(() => {
|
||||||
const instance = Template.instance();
|
const instance = Template.instance();
|
||||||
|
const timepointApi = instance.data.timepointApi;
|
||||||
|
|
||||||
instance.isRemoved = true;
|
instance.isRemoved = true;
|
||||||
if (instance.data.timepointApi) {
|
if (timepointApi) {
|
||||||
instance.data.timepoints = new ReactiveVar(instance.data.timepointApi.currentAndPrior());
|
instance.data.timepoints = new ReactiveVar(timepointApi.currentAndPrior());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -37,6 +42,7 @@ Template.measurementTableHUD.helpers({
|
|||||||
|
|
||||||
return instance.isRemoved !== true ? 'dialog-animated dialog-closed' : 'hidden';
|
return instance.isRemoved !== true ? 'dialog-animated dialog-closed' : 'hidden';
|
||||||
},
|
},
|
||||||
|
|
||||||
toolbarButtons() {
|
toolbarButtons() {
|
||||||
let buttonData = [];
|
let buttonData = [];
|
||||||
|
|
||||||
|
|||||||
@ -52,7 +52,6 @@ Template.measurementTableRow.events({
|
|||||||
|
|
||||||
// Show the measure flow for targets
|
// Show the measure flow for targets
|
||||||
OHIF.measurements.toggleLabelButton({
|
OHIF.measurements.toggleLabelButton({
|
||||||
instance,
|
|
||||||
measurement: entry,
|
measurement: entry,
|
||||||
element: document.body,
|
element: document.body,
|
||||||
measurementApi: instance.data.measurementApi,
|
measurementApi: instance.data.measurementApi,
|
||||||
@ -78,8 +77,7 @@ Template.measurementTableRow.events({
|
|||||||
const measurementTypeId = instance.data.rowItem.measurementTypeId;
|
const measurementTypeId = instance.data.rowItem.measurementTypeId;
|
||||||
const measurement = instance.data.rowItem.entries[0];
|
const measurement = instance.data.rowItem.entries[0];
|
||||||
const measurementNumber = measurement.measurementNumber;
|
const measurementNumber = measurement.measurementNumber;
|
||||||
const measurementApi = instance.data.measurementApi;
|
const { timepointApi, measurementApi } = instance.data;
|
||||||
const timepointApi = instance.data.timepointApi;
|
|
||||||
|
|
||||||
// Remove all the measurements with the given type and number
|
// Remove all the measurements with the given type and number
|
||||||
measurementApi.deleteMeasurements(measurementTypeId, { measurementNumber });
|
measurementApi.deleteMeasurements(measurementTypeId, { measurementNumber });
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import { Template } from 'meteor/templating';
|
||||||
|
import { _ } from 'meteor/underscore';
|
||||||
import { OHIF } from 'meteor/ohif:core';
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
|
|
||||||
Template.measurementTableTimepointCell.helpers({
|
Template.measurementTableTimepointCell.helpers({
|
||||||
@ -15,6 +17,7 @@ Template.measurementTableTimepointCell.helpers({
|
|||||||
return rowItem.entries.length > 0;
|
return rowItem.entries.length > 0;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
displayData() {
|
displayData() {
|
||||||
const instance = Template.instance();
|
const instance = Template.instance();
|
||||||
const rowItem = instance.data.rowItem;
|
const rowItem = instance.data.rowItem;
|
||||||
@ -26,6 +29,7 @@ Template.measurementTableTimepointCell.helpers({
|
|||||||
if (dataAtThisTimepoint.length > 1) {
|
if (dataAtThisTimepoint.length > 1) {
|
||||||
throw 'More than one measurement was found at the same timepoint with the same measurement number?';
|
throw 'More than one measurement was found at the same timepoint with the same measurement number?';
|
||||||
}
|
}
|
||||||
|
|
||||||
data = dataAtThisTimepoint[0];
|
data = dataAtThisTimepoint[0];
|
||||||
} else {
|
} else {
|
||||||
data = rowItem.entries[0];
|
data = rowItem.entries[0];
|
||||||
@ -38,29 +42,14 @@ Template.measurementTableTimepointCell.helpers({
|
|||||||
const tool = _.findWhere(toolGroup.childTools, { id: data.toolType });
|
const tool = _.findWhere(toolGroup.childTools, { id: data.toolType });
|
||||||
if (!tool) {
|
if (!tool) {
|
||||||
// TODO: Figure out what is going on here?
|
// TODO: Figure out what is going on here?
|
||||||
console.warn('Something went wrong?');
|
OHIF.log.warn('Something went wrong?');
|
||||||
}
|
}
|
||||||
|
|
||||||
const displayFunction = tool.options.measurementTable.displayFunction;
|
const displayFunction = tool.options.measurementTable.displayFunction;
|
||||||
return displayFunction(data);
|
return displayFunction(data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function doneCallback(measurementData, deleteTool) {
|
|
||||||
// If a Lesion or Non-Target is removed via a dialog
|
|
||||||
// opened by the Lesion Table, we should clear the data for
|
|
||||||
// the specified Timepoint Cell
|
|
||||||
if (deleteTool === true) {
|
|
||||||
OHIF.log.info('Confirm clicked!');
|
|
||||||
OHIF.lesiontracker.clearMeasurementTimepointData(measurementData.id, measurementData.timepointId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete a lesion if Ctrl+D or DELETE is pressed while a lesion is selected
|
|
||||||
const keys = {
|
|
||||||
D: 68,
|
|
||||||
DELETE: 46
|
|
||||||
};
|
|
||||||
|
|
||||||
Template.measurementTableTimepointCell.events({
|
Template.measurementTableTimepointCell.events({
|
||||||
'click .measurementTableTimepointCell'(event, instance) {
|
'click .measurementTableTimepointCell'(event, instance) {
|
||||||
if (!instance.data.timepointId) {
|
if (!instance.data.timepointId) {
|
||||||
@ -71,14 +60,18 @@ Template.measurementTableTimepointCell.events({
|
|||||||
const timepoints = instance.data.timepoints.get();
|
const timepoints = instance.data.timepoints.get();
|
||||||
OHIF.measurements.jumpToRowItem(rowItem, timepoints);
|
OHIF.measurements.jumpToRowItem(rowItem, timepoints);
|
||||||
},
|
},
|
||||||
|
|
||||||
'keydown .measurementTableTimepointCell'(event, instance) {
|
'keydown .measurementTableTimepointCell'(event, instance) {
|
||||||
|
// Delete a lesion if Ctrl+D or DELETE is pressed while a lesion is selected
|
||||||
|
const keys = {
|
||||||
|
D: 68,
|
||||||
|
DELETE: 46
|
||||||
|
};
|
||||||
const keyCode = event.which;
|
const keyCode = event.which;
|
||||||
|
|
||||||
if (keyCode === keys.DELETE || keyCode === keys.BACKSPACE || (keyCode === keys.D && event.ctrlKey === true)) {
|
if (keyCode === keys.DELETE || keyCode === keys.BACKSPACE || (keyCode === keys.D && event.ctrlKey === true)) {
|
||||||
const currentMeasurement = Template.parentData(1).rowItem;
|
const timepointId = instance.data.timepointId;
|
||||||
const timepointId = this.timepointId;
|
|
||||||
|
|
||||||
const dialogSettings = {
|
const dialogSettings = {
|
||||||
title: 'Delete measurements',
|
title: 'Delete measurements',
|
||||||
message: 'Are you sure you want to delete this measurement?'
|
message: 'Are you sure you want to delete this measurement?'
|
||||||
@ -88,8 +81,7 @@ Template.measurementTableTimepointCell.events({
|
|||||||
const measurementTypeId = instance.data.rowItem.measurementTypeId;
|
const measurementTypeId = instance.data.rowItem.measurementTypeId;
|
||||||
const measurement = instance.data.rowItem.entries[0];
|
const measurement = instance.data.rowItem.entries[0];
|
||||||
const measurementNumber = measurement.measurementNumber;
|
const measurementNumber = measurement.measurementNumber;
|
||||||
const measurementApi = instance.data.measurementApi;
|
const { timepointApi, measurementApi } = instance.data;
|
||||||
const timepointApi = instance.data.timepointApi;
|
|
||||||
|
|
||||||
// Remove all the measurements with the given type and number
|
// Remove all the measurements with the given type and number
|
||||||
measurementApi.deleteMeasurements(measurementTypeId, {
|
measurementApi.deleteMeasurements(measurementTypeId, {
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
<template name="measurementTableTimepointHeader">
|
<template name="measurementTableTimepointHeader">
|
||||||
<div class="measurementTableTimepointHeader">
|
<div class="measurementTableTimepointHeader">
|
||||||
<div class="timepointName">
|
<div class="timepointName">
|
||||||
{{timepointName}}
|
{{timepointName this}}
|
||||||
</div>
|
</div>
|
||||||
<div class="timepointDate">
|
<div class="timepointDate">
|
||||||
{{formatDA latestDate "DD-MMM-YY"}}
|
{{formatDA latestDate "DD-MMM-YY"}}
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
|
import { Template } from 'meteor/templating';
|
||||||
|
|
||||||
Template.measurementTableTimepointHeader.helpers({
|
Template.measurementTableTimepointHeader.helpers({
|
||||||
'timepointName': function() {
|
timepointName(timepoint) {
|
||||||
const timepoint = this;
|
return Template.instance().data.timepointApi.name(timepoint);
|
||||||
const instance = Template.instance();
|
|
||||||
const timepointApi = instance.data.timepointApi;
|
|
||||||
return timepointApi.name(timepoint);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { Template } from 'meteor/templating';
|
import { Template } from 'meteor/templating';
|
||||||
import { Tracker } from 'meteor/tracker';
|
import { Tracker } from 'meteor/tracker';
|
||||||
|
import { ReactiveVar } from 'meteor/reactive-var';
|
||||||
import { _ } from 'meteor/underscore';
|
import { _ } from 'meteor/underscore';
|
||||||
import { OHIF } from 'meteor/ohif:core';
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
|
|
||||||
@ -31,7 +32,7 @@ Template.measurementTableView.helpers({
|
|||||||
if (!groups) {
|
if (!groups) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const group = _.find(groups, item => item.toolGroup.id === toolGroupId);
|
const group = _.find(groups, item => item.toolGroup.id === toolGroupId);
|
||||||
return group && !!group.measurementRows.length;
|
return group && !!group.measurementRows.length;
|
||||||
},
|
},
|
||||||
@ -57,10 +58,8 @@ Template.measurementTableView.helpers({
|
|||||||
},
|
},
|
||||||
|
|
||||||
newMeasurements(toolGroup) {
|
newMeasurements(toolGroup) {
|
||||||
const instance = Template.instance();
|
const { measurementApi, timepointApi } = Template.instance().data;
|
||||||
const measurementApi = instance.data.measurementApi;
|
const current = timepointApi.current();
|
||||||
const timepointApi = instance.data.timepointApi;
|
|
||||||
const current = instance.data.timepointApi.current();
|
|
||||||
const baseline = timepointApi.baseline();
|
const baseline = timepointApi.baseline();
|
||||||
|
|
||||||
if (!measurementApi || !timepointApi || !current || !baseline) return;
|
if (!measurementApi || !timepointApi || !current || !baseline) return;
|
||||||
|
|||||||
@ -6,8 +6,8 @@ import { OHIF } from 'meteor/ohif:core';
|
|||||||
class MeasurementHandlers {
|
class MeasurementHandlers {
|
||||||
|
|
||||||
static onAdded(e, instance, eventData) {
|
static onAdded(e, instance, eventData) {
|
||||||
|
const { measurementApi } = instance.data;
|
||||||
const measurementData = eventData.measurementData;
|
const measurementData = eventData.measurementData;
|
||||||
const measurementApi = instance.data.measurementApi;
|
|
||||||
const Collection = measurementApi.tools[eventData.toolType];
|
const Collection = measurementApi.tools[eventData.toolType];
|
||||||
|
|
||||||
// Stop here if the tool data shall not be stored (e.g. temp tools)
|
// Stop here if the tool data shall not be stored (e.g. temp tools)
|
||||||
@ -74,8 +74,8 @@ class MeasurementHandlers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static onModified(e, instance, eventData) {
|
static onModified(e, instance, eventData) {
|
||||||
|
const { measurementApi } = instance.data;
|
||||||
const measurementData = eventData.measurementData;
|
const measurementData = eventData.measurementData;
|
||||||
const measurementApi = instance.data.measurementApi;
|
|
||||||
const Collection = measurementApi.tools[eventData.toolType];
|
const Collection = measurementApi.tools[eventData.toolType];
|
||||||
|
|
||||||
// Stop here if the tool data shall not be stored (e.g. temp tools)
|
// Stop here if the tool data shall not be stored (e.g. temp tools)
|
||||||
@ -119,8 +119,7 @@ class MeasurementHandlers {
|
|||||||
OHIF.log.info('CornerstoneToolsMeasurementRemoved');
|
OHIF.log.info('CornerstoneToolsMeasurementRemoved');
|
||||||
const measurementData = eventData.measurementData;
|
const measurementData = eventData.measurementData;
|
||||||
const measurementNumber = measurementData.measurementNumber;
|
const measurementNumber = measurementData.measurementNumber;
|
||||||
const measurementApi = instance.data.measurementApi;
|
const { measurementApi, timepointApi } = instance.data;
|
||||||
const timepointApi = instance.data.timepointApi;
|
|
||||||
const collection = measurementApi.tools[eventData.toolType];
|
const collection = measurementApi.tools[eventData.toolType];
|
||||||
const measurementTypeId = measurementApi.toolsGroupsMap[measurementData.toolType];
|
const measurementTypeId = measurementApi.toolsGroupsMap[measurementData.toolType];
|
||||||
const measurement = collection.findOne(measurementData._id);
|
const measurement = collection.findOne(measurementData._id);
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { Meteor } from 'meteor/meteor';
|
import { Meteor } from 'meteor/meteor';
|
||||||
import { Template } from 'meteor/templating';
|
|
||||||
import { Viewerbase } from 'meteor/ohif:viewerbase';
|
import { Viewerbase } from 'meteor/ohif:viewerbase';
|
||||||
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
|
|
||||||
const { InstanceMetadata, StudySummary } = Viewerbase.metadata;
|
const { InstanceMetadata, StudySummary } = Viewerbase.metadata;
|
||||||
|
|
||||||
@ -11,9 +11,9 @@ const { InstanceMetadata, StudySummary } = Viewerbase.metadata;
|
|||||||
* @return {String|undefined} Timepoint type if found or undefined if not found or any error/missing information
|
* @return {String|undefined} Timepoint type if found or undefined if not found or any error/missing information
|
||||||
*/
|
*/
|
||||||
const getTimepointType = study => {
|
const getTimepointType = study => {
|
||||||
const timepointApi = OHIF.viewer.timepointApi;
|
const { timepointApi } = OHIF.viewer;
|
||||||
|
|
||||||
if (!timepointApi || !(study instanceof InstanceMetadata || study instanceof StudySummary) ) {
|
if (!timepointApi || !(study instanceof InstanceMetadata || study instanceof StudySummary)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,17 +6,18 @@ import { OHIF } from 'meteor/ohif:core';
|
|||||||
OHIF.measurements.toggleLabelButton = options => {
|
OHIF.measurements.toggleLabelButton = options => {
|
||||||
const toolType = options.measurement.toolType;
|
const toolType = options.measurement.toolType;
|
||||||
const measurementId = options.measurement._id;
|
const measurementId = options.measurement._id;
|
||||||
|
let buttonView = null;
|
||||||
|
|
||||||
const removeButtonView = () => {
|
const removeButtonView = () => {
|
||||||
if (!options.instance.buttonView) {
|
if (!buttonView) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Blaze.remove(options.instance.buttonView);
|
Blaze.remove(buttonView);
|
||||||
options.instance.buttonView = null;
|
buttonView = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (options.instance.buttonView) {
|
if (buttonView) {
|
||||||
removeButtonView();
|
removeButtonView();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,6 +54,5 @@ OHIF.measurements.toggleLabelButton = options => {
|
|||||||
options.measurement.description = description;
|
options.measurement.description = description;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const view = Blaze.renderWithData(Template.measureFlow, data, options.element);
|
buttonView = Blaze.renderWithData(Template.measureFlow, data, options.element);
|
||||||
options.instance.buttonView = view;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -146,22 +146,23 @@ Template.studyTimepointBrowser.helpers({
|
|||||||
// Get the current study
|
// Get the current study
|
||||||
const currentStudy = instance.getCurrentStudy();
|
const currentStudy = instance.getCurrentStudy();
|
||||||
// Declare the timepoints
|
// Declare the timepoints
|
||||||
|
const { timepointApi } = instance.data;
|
||||||
let timepoints;
|
let timepoints;
|
||||||
if (currentStudy && !instance.showAdditionalTimepoints.get()) {
|
if (currentStudy && !instance.showAdditionalTimepoints.get()) {
|
||||||
// Show only the current study's timepoint
|
// Show only the current study's timepoint
|
||||||
timepoints = instance.data.timepointApi.study(currentStudy.studyInstanceUid);
|
timepoints = timepointApi.study(currentStudy.studyInstanceUid);
|
||||||
} else {
|
} else {
|
||||||
if (!instance.data.timepointApi) {
|
if (!timepointApi) {
|
||||||
// If there is no timepoint API defined whatsoever, this means that there is no
|
// If there is no timepoint API defined whatsoever, this means that there is no
|
||||||
// current timepoint ID, so we can just display all of the currently loaded studies
|
// current timepoint ID, so we can just display all of the currently loaded studies
|
||||||
// in the study sidebar
|
// in the study sidebar
|
||||||
timepoints = [];
|
timepoints = [];
|
||||||
} else if (instance.timepointViewType.get() === 'all') {
|
} else if (instance.timepointViewType.get() === 'all') {
|
||||||
// Show all timepoints
|
// Show all timepoints
|
||||||
timepoints = instance.data.timepointApi.all();
|
timepoints = timepointApi.all();
|
||||||
} else {
|
} else {
|
||||||
// Show only key timepoints
|
// Show only key timepoints
|
||||||
timepoints = instance.data.timepointApi.key();
|
timepoints = timepointApi.key();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Returns the timepoints
|
// Returns the timepoints
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import { Meteor } from 'meteor/meteor';
|
import { Meteor } from 'meteor/meteor';
|
||||||
import { Template } from 'meteor/templating';
|
import { Template } from 'meteor/templating';
|
||||||
import { Session } from 'meteor/session';
|
import { Session } from 'meteor/session';
|
||||||
|
import { Random } from 'meteor/random';
|
||||||
import { OHIF } from 'meteor/ohif:core';
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
// Local Modules
|
// Local Modules
|
||||||
import { toolManager } from '../../../lib/toolManager';
|
|
||||||
import { unloadHandlers } from '../../../lib/unloadHandlers';
|
import { unloadHandlers } from '../../../lib/unloadHandlers';
|
||||||
import { hotkeyUtils } from '../../../lib/hotkeyUtils';
|
import { hotkeyUtils } from '../../../lib/hotkeyUtils';
|
||||||
import { ResizeViewportManager } from '../../../lib/classes/ResizeViewportManager';
|
import { ResizeViewportManager } from '../../../lib/classes/ResizeViewportManager';
|
||||||
@ -13,7 +13,7 @@ import { StudyPrefetcher } from '../../../lib/classes/StudyPrefetcher';
|
|||||||
Meteor.startup(() => {
|
Meteor.startup(() => {
|
||||||
window.ResizeViewportManager = window.ResizeViewportManager || new ResizeViewportManager();
|
window.ResizeViewportManager = window.ResizeViewportManager || new ResizeViewportManager();
|
||||||
|
|
||||||
// Set initial value for OHIFViewerMainRendered
|
// Set initial value for OHIFViewerMainRendered
|
||||||
// session variable. This can used in viewer main template
|
// session variable. This can used in viewer main template
|
||||||
Session.set('OHIFViewerMainRendered', false);
|
Session.set('OHIFViewerMainRendered', false);
|
||||||
});
|
});
|
||||||
@ -22,7 +22,7 @@ Template.viewerMain.onCreated(() => {
|
|||||||
// Attach the Window resize listener
|
// Attach the Window resize listener
|
||||||
// Don't use jQuery here. "window.onresize" will always be null
|
// Don't use jQuery here. "window.onresize" will always be null
|
||||||
// If its necessary, check all the code for window.onresize getter
|
// If its necessary, check all the code for window.onresize getter
|
||||||
// and change it to jQuery._data(window, 'events')['resize'].
|
// and change it to jQuery._data(window, 'events')['resize'].
|
||||||
// Otherwise this function will be probably overrided.
|
// Otherwise this function will be probably overrided.
|
||||||
// See cineDialog instance.setResizeHandler function
|
// See cineDialog instance.setResizeHandler function
|
||||||
window.addEventListener('resize', window.ResizeViewportManager.getResizeHandler());
|
window.addEventListener('resize', window.ResizeViewportManager.getResizeHandler());
|
||||||
@ -59,7 +59,7 @@ Template.viewerMain.onDestroyed(() => {
|
|||||||
OHIF.viewer.updateImageSynchronizer.destroy();
|
OHIF.viewer.updateImageSynchronizer.destroy();
|
||||||
|
|
||||||
delete OHIF.viewerbase.layoutManager;
|
delete OHIF.viewerbase.layoutManager;
|
||||||
delete ProtocolEngine;
|
ProtocolEngine = null;
|
||||||
|
|
||||||
Session.set('OHIFViewerMainRendered', false);
|
Session.set('OHIFViewerMainRendered', false);
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user