LT-115: Adapting measurement table to the new tools structure

This commit is contained in:
Bruno Alves de Faria 2017-01-02 16:29:40 -02:00
parent b776e5f411
commit 0fccb48271
8 changed files with 103 additions and 72 deletions

View File

@ -19,5 +19,9 @@ export const ToolGroupBaseSchema = new SimpleSchema({
timepointId: { timepointId: {
type: String, type: String,
label: 'Timepoint ID' label: 'Timepoint ID'
},
measurementNumber: {
type: Number,
label: 'Measurement Number'
} }
}); });

View File

@ -39,23 +39,26 @@ class MeasurementApi {
const timepoint = this.timepointApi.timepoints.findOne({ const timepoint = this.timepointApi.timepoints.findOne({
studyInstanceUids: measurement.studyInstanceUid studyInstanceUids: measurement.studyInstanceUid
}); });
const measurementNumber = groupCollection.find({
studyInstanceUid: {
$in: timepoint.studyInstanceUids
}
}).count() + 1;
measurement.measurementNumber = measurementNumber;
groupCollection.insert({ groupCollection.insert({
toolId: tool.id, toolId: tool.id,
toolItemId: measurement._id, toolItemId: measurement._id,
timepointId: timepoint.timepointId, timepointId: timepoint.timepointId,
studyInstanceUid: measurement.studyInstanceUid, studyInstanceUid: measurement.studyInstanceUid,
createdAt: measurement.createdAt createdAt: measurement.createdAt,
measurementNumber
}); });
const measurementNumber = groupCollection.find({
studyInstanceUid: {
$in: timepoint.studyInstanceUids
}
}).count();
measurement.measurementNumber = measurementNumber;
collection.update(measurement._id, { collection.update(measurement._id, {
$set: { $set: {
measurementNumber measurementNumber,
timepointId: timepoint.timepointId
} }
}); });
}, },
@ -68,22 +71,27 @@ class MeasurementApi {
const timepoint = this.timepointApi.timepoints.findOne({ const timepoint = this.timepointApi.timepoints.findOne({
timepointId: measurement.timepointId timepointId: measurement.timepointId
}); });
const filter = {
studyInstanceUid: {
$in: timepoint.studyInstanceUids
},
measurementNumber: {
$gt: atIndex
}
};
const operator = {
$inc: {
measurementNumber: -1
}
};
const options = {
multi: true
};
groupCollection.update(filter, operator, options);
toolGroup.childTools.forEach(childTool => { toolGroup.childTools.forEach(childTool => {
this.tools[childTool.id].update({ const collection = this.tools[childTool.id];
studyInstanceUid: { collection.update(filter, operator, options);
$in: timepoint.studyInstanceUids
},
measurementNumber: {
$gt: atIndex
}
}, {
$inc: {
measurementNumber: -1
}
}, {
multi: true
});
}); });
} }
}); });
@ -186,11 +194,16 @@ class MeasurementApi {
} }
deleteMeasurements(measurementTypeId, filter) { deleteMeasurements(measurementTypeId, filter) {
const collection = this.tools[measurementTypeId]; const groupCollection = this.toolGroups[measurementTypeId];
// Get the entries information before removing them // Get the entries information before removing them
const entries = collection.find(filter).fetch(); const groupItems = groupCollection.find(filter).fetch();
collection.remove(filter); const entries = [];
groupItems.forEach(groupItem => {
const collection = this.tools[groupItem.toolId];
entries.push(collection.findOne(groupItem.toolItemId));
collection.remove(groupItem.toolItemId);
});
// Stop here if no entries were found // Stop here if no entries were found
if (!entries.length) { if (!entries.length) {
@ -219,24 +232,33 @@ class MeasurementApi {
// Synchronize the updated measurements with Cornerstone Tools // Synchronize the updated measurements with Cornerstone Tools
// toolData to make sure the displayed measurements show 'Target X' correctly // toolData to make sure the displayed measurements show 'Target X' correctly
const syncFilter = _.clone(updateFilter); const syncFilter = _.clone(filter);
syncFilter.measurementNumber = { syncFilter.measurementNumber = {
$gt: measurementNumber - 1 $gt: measurementNumber - 1
}; };
collection.find(syncFilter).forEach(measurement => { const toolTypes = _.uniq(entries.map(entry => entry.toolType));
OHIF.measurements.syncMeasurementAndToolData(measurement); toolTypes.forEach(toolType => {
const collection = this.tools[toolType];
collection.find(syncFilter).forEach(measurement => {
OHIF.measurements.syncMeasurementAndToolData(measurement);
});
}); });
} }
fetch(measurementTypeId, selector, options) { fetch(measurementTypeId, selector, options) {
if (!this.tools[measurementTypeId]) { if (!this.toolGroups[measurementTypeId]) {
throw 'MeasurementApi: No Collection with the id: ' + measurementTypeId; throw 'MeasurementApi: No Collection with the id: ' + measurementTypeId;
} }
selector = selector || {}; selector = selector || {};
options = options || {}; options = options || {};
return this.tools[measurementTypeId].find(selector, options).fetch(); const result = [];
const items = this.toolGroups[measurementTypeId].find(selector, options).fetch();
items.forEach(item => {
result.push(this.tools[item.toolId].findOne(item.toolItemId));
});
return result;
} }
} }

View File

@ -2,7 +2,7 @@
<div class="measurementTableRow {{#unless rowItem.location}}warning{{/unless}}{{#if responseStatus}}response-status{{/if}}" data-measurementid="{{_id}}"> <div class="measurementTableRow {{#unless rowItem.location}}warning{{/unless}}{{#if responseStatus}}response-status{{/if}}" data-measurementid="{{_id}}">
<div class='measurementRowSidebar'> <div class='measurementRowSidebar'>
<div class="measurementNumber"> <div class="measurementNumber">
{{rowItem.measurementNumberOverall}} {{rowItem.measurementNumber}}
</div> </div>
{{#unless rowItem.location}} {{#unless rowItem.location}}
<div class="warning-icon"> <div class="warning-icon">

View File

@ -31,12 +31,13 @@ Template.measurementTableRow.events({
'click .js-rename'(event, instance) { 'click .js-rename'(event, instance) {
const rowItem = instance.data.rowItem; const rowItem = instance.data.rowItem;
const entry = rowItem.entries[0];
// Show the measure flow for targets // Show the measure flow for targets
OHIF.measurements.toggleLabelButton({ OHIF.measurements.toggleLabelButton({
instance, instance,
measurementId: rowItem.entries[0]._id, measurementId: entry._id,
measurementTypeId: rowItem.measurementTypeId, toolType: entry.toolType,
element: document.body, element: document.body,
measurementApi: instance.data.measurementApi, measurementApi: instance.data.measurementApi,
position: { position: {
@ -56,16 +57,12 @@ Template.measurementTableRow.events({
OHIF.ui.showFormDialog('dialogConfirm', dialogSettings).then(formData => { OHIF.ui.showFormDialog('dialogConfirm', dialogSettings).then(formData => {
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 toolType = measurement.toolType;
const measurementNumber = measurement.measurementNumber; const measurementNumber = measurement.measurementNumber;
const measurementApi = instance.data.measurementApi; const measurementApi = instance.data.measurementApi;
const timepointApi = instance.data.timepointApi; 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, { measurementNumber });
toolType,
measurementNumber
});
// Update the Overall Measurement Numbers for all Measurements // Update the Overall Measurement Numbers for all Measurements
const baseline = timepointApi.baseline(); const baseline = timepointApi.baseline();
@ -74,27 +71,5 @@ Template.measurementTableRow.events({
// Repaint the images on all viewports without the removed measurements // Repaint the images on all viewports without the removed measurements
_.each($('.imageViewerViewport'), element => cornerstone.updateImage(element)); _.each($('.imageViewerViewport'), element => cornerstone.updateImage(element));
}); });
},
'keydown .location'(event) {
const keyCode = event.which;
if (keyCode === keys.DELETE ||
(keyCode === keys.D && event.ctrlKey === true)) {
const currentMeasurement = this;
const options = {
keyPressAllowed: false,
title: 'Remove measurement?',
text: 'Are you sure you would like to remove the entire measurement?'
};
showConfirmDialog(() => {
Meteor.call('removeMeasurement', currentMeasurement._id, (error, response) => {
if (error) {
OHIF.log.warn(error);
}
});
}, options);
}
} }
}); });

View File

@ -6,9 +6,10 @@ Template.measurementTableTimepointCell.helpers({
// exists for this Measurement at this Timepoint // exists for this Measurement at this Timepoint
const instance = Template.instance(); const instance = Template.instance();
const rowItem = instance.data.rowItem; const rowItem = instance.data.rowItem;
const timepointId = instance.data.timepointId;
if (this.timepointId) { if (timepointId) {
const dataAtThisTimepoint = _.where(rowItem.entries, {timepointId: this.timepointId}); const dataAtThisTimepoint = _.where(rowItem.entries, { timepointId });
return dataAtThisTimepoint.length > 0; return dataAtThisTimepoint.length > 0;
} else { } else {
return rowItem.entries.length > 0; return rowItem.entries.length > 0;
@ -16,11 +17,12 @@ Template.measurementTableTimepointCell.helpers({
}, },
displayData() { displayData() {
const instance = Template.instance(); const instance = Template.instance();
const rowItem = instance.data.rowItem; const rowItem = instance.data.rowItem;
const timepointId = instance.data.timepointId;
let data; let data;
if (this.timepointId) { if (timepointId) {
const dataAtThisTimepoint = _.where(rowItem.entries, {timepointId: this.timepointId}); const dataAtThisTimepoint = _.where(rowItem.entries, { timepointId });
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?';
} }
@ -32,7 +34,8 @@ Template.measurementTableTimepointCell.helpers({
const config = OHIF.measurements.MeasurementApi.getConfiguration(); const config = OHIF.measurements.MeasurementApi.getConfiguration();
const measurementTools = config.measurementTools; const measurementTools = config.measurementTools;
const tool = _.where(measurementTools, {id: rowItem.measurementTypeId})[0]; const toolGroup = _.findWhere(measurementTools, { id: rowItem.measurementTypeId });
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?'); console.warn('Something went wrong?');

View File

@ -1,11 +1,11 @@
<template name="measurementTableView"> <template name="measurementTableView">
<div class="measurementTableView scrollArea"> <div class="measurementTableView scrollArea">
{{#let config=measurementConfiguration}} {{#let config=measurementConfiguration}}
{{#each measurementType in config.measurementTools}} {{#each toolGroup in config.measurementTools}}
{{#if measurementType.options.measurementTable.displayFunction}} {{#if shallDisplayGroup toolGroup.id}}
{{#let collection=(groupByMeasurementNumber measurementType.id)}} {{#let collection=(groupByMeasurementNumber toolGroup.id)}}
{{>measurementTableHeaderRow {{>measurementTableHeaderRow
measurementType=measurementType measurementType=toolGroup
measurements=collection measurements=collection
currentTimepointId=currentTimepointId currentTimepointId=currentTimepointId
timepointApi=timepointApi timepointApi=timepointApi

View File

@ -10,6 +10,26 @@ OHIF.measurements.getLocation = collection => {
} }
}; };
Template.measurementTableView.onCreated(() => {
const instance = Template.instance();
const measurementApi = instance.data.measurementApi;
const configuration = OHIF.measurements.MeasurementApi.getConfiguration();
instance.displayToolGroupMap = {};
instance.displayToolList = [];
configuration.measurementTools.forEach(toolGroup => {
instance.displayToolGroupMap[toolGroup.id] = false;
toolGroup.childTools.forEach(tool => {
const willDisplay = !!(tool.options && tool.options.measurementTable && tool.options.measurementTable.displayFunction);
if (willDisplay) {
instance.displayToolList.push(tool.id);
instance.displayToolGroupMap[toolGroup.id] = true;
}
});
});
});
Template.measurementTableView.helpers({ Template.measurementTableView.helpers({
getNewMeasurementType(tool) { getNewMeasurementType(tool) {
// TODO: Check Conformance criteria here. // TODO: Check Conformance criteria here.
@ -22,6 +42,11 @@ Template.measurementTableView.helpers({
}; };
}, },
shallDisplayGroup(toolGroupId) {
const instance = Template.instance();
return instance.displayToolGroupMap[toolGroupId];
},
groupByMeasurementNumber(measurementTypeId) { groupByMeasurementNumber(measurementTypeId) {
const instance = Template.instance(); const instance = Template.instance();
const measurementApi = instance.data.measurementApi; const measurementApi = instance.data.measurementApi;
@ -44,6 +69,9 @@ Template.measurementTableView.helpers({
// Retrieve all the data for this Measurement type which // Retrieve all the data for this Measurement type which
// match the Measurement Numbers obtained above // match the Measurement Numbers obtained above
const data = measurementApi.fetch(measurementTypeId, { const data = measurementApi.fetch(measurementTypeId, {
toolId: {
$in: instance.displayToolList
},
measurementNumber: { measurementNumber: {
$in: numbers $in: numbers
} }

View File

@ -17,8 +17,7 @@ OHIF.measurements.toggleLabelButton = options => {
removeButtonView(); removeButtonView();
} }
const tool = options.toolType; const toolCollection = options.measurementApi.tools[options.toolType];
const toolCollection = options.measurementApi.tools[tool];
const measurement = toolCollection.findOne(options.measurementId); const measurement = toolCollection.findOne(options.measurementId);
const data = { const data = {