LT-115: Adapting measurement table to the new tools structure
This commit is contained in:
parent
b776e5f411
commit
0fccb48271
@ -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'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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">
|
||||||
|
|||||||
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -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?');
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 = {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user