LT-55: Exposing grouping measurements method in OHIF namespace

This commit is contained in:
Bruno Alves de Faria 2017-01-23 20:04:42 -02:00
parent fc3eb30f8b
commit 28ac391c52
6 changed files with 125 additions and 129 deletions

View File

@ -7,9 +7,9 @@
</svg> </svg>
</div> </div>
{{/if}} {{/if}}
<div class="type">{{measurementType.name}}</div> <div class="type">{{toolGroup.name}}</div>
<div class="max {{#if gt numberOfMeasurements maxNumMeasurements}}warning{{/if}}"> <div class="max {{#if gt numberOfMeasurements maxNumMeasurements}}warning{{/if}}">
{{#if and maxNumMeasurements (eq measurementType.id 'targets')}} {{#if and maxNumMeasurements (eq toolGroup.id 'targets')}}
<p class="maxNumMeasurements">Max {{maxNumMeasurements}}</p> <p class="maxNumMeasurements">Max {{maxNumMeasurements}}</p>
{{/if}} {{/if}}
</div> </div>

View File

@ -3,37 +3,30 @@ import { OHIF } from 'meteor/ohif:core';
Template.measurementTableHeaderRow.helpers({ Template.measurementTableHeaderRow.helpers({
numberOfMeasurements() { numberOfMeasurements() {
const instance = Template.instance(); const { measurementRows } = Template.instance().data;
if (!instance.data.measurements) { return measurementRows.length ? measurementRows.length : null;
return;
}
return instance.data.measurements.length;
}, },
maxNumMeasurements() { maxNumMeasurements() {
const instance = Template.instance(); const { conformanceCriteria } = Template.instance().data;
if (!instance.data.conformanceCriteria) { if (!conformanceCriteria) return;
return;
}
return instance.data.conformanceCriteria.maxTargets.get(); return conformanceCriteria.maxTargets.get();
}, },
anyUnmarkedLesionsLeft() { anyUnmarkedLesionsLeft() {
// Skip New Lesions section // Skip New Lesions section
const instance = Template.instance(); const instance = Template.instance();
if (!instance.data.measurements) { const { toolGroup, measurementRows, timepointApi, measurementApi } = instance.data;
if (!measurementRows) {
return; return;
} }
const measurementType = instance.data.measurementType;
const config = OHIF.measurements.MeasurementApi.getConfiguration(); const config = OHIF.measurements.MeasurementApi.getConfiguration();
if (measurementType.id === config.newMeasurementTool.id) { if (toolGroup.id === config.newMeasurementTool.id) {
return; return;
} }
const timepointApi = instance.data.timepointApi;
const current = timepointApi.current(); const current = timepointApi.current();
const prior = timepointApi.prior(); const prior = timepointApi.prior();
if (!prior) { if (!prior) {
@ -42,11 +35,10 @@ Template.measurementTableHeaderRow.helpers({
const currentFilter = { timepointId: current.timepointId }; const currentFilter = { timepointId: current.timepointId };
const priorFilter = { timepointId: prior.timepointId }; const priorFilter = { timepointId: prior.timepointId };
const measurementTypeId = measurementType.id; const toolGroupId = toolGroup.id;
const measurementApi = instance.data.measurementApi; const numCurrent = measurementApi.fetch(toolGroupId, currentFilter).length;
const numCurrent = measurementApi.fetch(measurementTypeId, currentFilter).length; const numPrior = measurementApi.fetch(toolGroupId, priorFilter).length;
const numPrior = measurementApi.fetch(measurementTypeId, priorFilter).length;
const remaining = Math.max(numPrior - numCurrent, 0); const remaining = Math.max(numPrior - numCurrent, 0);
return remaining > 0; return remaining > 0;
} }
@ -54,7 +46,7 @@ Template.measurementTableHeaderRow.helpers({
Template.measurementTableHeaderRow.events({ Template.measurementTableHeaderRow.events({
'click .js-setTool'(event, instance) { 'click .js-setTool'(event, instance) {
const measurementType = instance.data.measurementType; const { toolGroup } = instance.data;
toolManager.setActiveTool(measurementType.cornerstoneToolType); toolManager.setActiveTool(toolGroup.childTools[0].cornerstoneToolType);
} }
}); });

View File

@ -1,22 +1,13 @@
<template name="measurementTableView"> <template name="measurementTableView">
<div class="measurementTableView scrollArea"> <div class="measurementTableView scrollArea">
{{#let config=measurementConfiguration}} {{#let config=measurementConfiguration measurementGroups=getMeasurementsGroupedByNumber}}
{{#each toolGroup in config.measurementTools}} {{#each measurementGroup in measurementGroups}}
{{#if shallDisplayGroup toolGroup.id}} {{>measurementTableHeaderRow (clone this
{{#let collection=(groupByMeasurementNumber toolGroup.id)}} toolGroup=measurementGroup.toolGroup
{{>measurementTableHeaderRow measurementRows=measurementGroup.measurementRows)}}
measurementType=toolGroup {{#each rowItem in measurementGroup.measurementRows}}
measurements=collection {{>measurementTableRow (clone this rowItem=rowItem)}}
currentTimepointId=currentTimepointId
timepointApi=timepointApi
measurementApi=measurementApi
conformanceCriteria=conformanceCriteria}}
{{#each entry in collection}}
{{>measurementTableRow (clone this rowItem=entry)}}
{{/each}} {{/each}}
{{/let}}
{{/if}}
{{/each}} {{/each}}
{{#if config.newMeasurementTool}} {{#if config.newMeasurementTool}}

View File

@ -2,34 +2,6 @@ import { Template } from 'meteor/templating';
import { _ } from 'meteor/underscore'; import { _ } from 'meteor/underscore';
import { OHIF } from 'meteor/ohif:core'; import { OHIF } from 'meteor/ohif:core';
OHIF.measurements.getLocation = collection => {
for (let i = 0; i < collection.length; i++) {
if (collection[i].location) {
return collection[i].location;
}
}
};
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.
@ -42,56 +14,9 @@ Template.measurementTableView.helpers({
}; };
}, },
shallDisplayGroup(toolGroupId) { getMeasurementsGroupedByNumber() {
const instance = Template.instance(); const { measurementApi, timepointApi } = Template.instance().data;
return instance.displayToolGroupMap[toolGroupId]; return OHIF.measurements.getMeasurementsGroupedByNumber(measurementApi, timepointApi);
},
groupByMeasurementNumber(measurementTypeId) {
const instance = Template.instance();
const measurementApi = instance.data.measurementApi;
const timepointApi = instance.data.timepointApi;
const baseline = timepointApi.baseline();
if (!measurementApi || !timepointApi || !baseline) {
return;
}
// Retrieve all the data for this Measurement type (e.g. 'targets')
// which was recorded at baseline.
const atBaseline = measurementApi.fetch(measurementTypeId, {
timepointId: baseline.timepointId
});
// Obtain a list of the Measurement Numbers from the
// measurements which have baseline data
const numbers = atBaseline.map(m => m.measurementNumber);
// Retrieve all the data for this Measurement type which
// match the Measurement Numbers obtained above
const data = measurementApi.fetch(measurementTypeId, {
toolId: {
$in: instance.displayToolList
},
measurementNumber: {
$in: numbers
}
});
// Group the Measurements by Measurement Number
const groupObject = _.groupBy(data, entry => entry.measurementNumber);
// Reformat the data for display in the table
return Object.keys(groupObject).map(key => {
const anEntry = groupObject[key][0];
return {
measurementTypeId: measurementTypeId,
measurementNumber: key,
location: OHIF.measurements.getLocation(groupObject[key]),
responseStatus: false, // TODO: Get the latest timepoint and determine the response status
entries: groupObject[key]
};
});
}, },
newMeasurements(measurementType) { newMeasurements(measurementType) {
@ -135,16 +60,12 @@ Template.measurementTableView.helpers({
const groupObject = _.groupBy(data, entry => entry.measurementNumber); const groupObject = _.groupBy(data, entry => entry.measurementNumber);
// Reformat the data for display in the table // Reformat the data for display in the table
return Object.keys(groupObject).map(key => { return Object.keys(groupObject).map(key => ({
const anEntry = groupObject[key][0];
return {
measurementTypeId: measurementTypeId, measurementTypeId: measurementTypeId,
measurementNumber: key, measurementNumber: key,
location: OHIF.measurements.getLocation(groupObject[key]), location: OHIF.measurements.getLocation(groupObject[key]),
responseStatus: false, // TODO: Get the latest timepoint and determine the response status responseStatus: false, // TODO: Get the latest timepoint and determine the response status
entries: groupObject[key] entries: groupObject[key]
}; }));
});
} }
}); });

View File

@ -0,0 +1,91 @@
import { OHIF } from 'meteor/ohif:core';
import { _ } from 'meteor/underscore';
// TODO: change this to a const after refactoring newMeasurements code on measurementTableView.js
OHIF.measurements.getLocation = collection => {
for (let i = 0; i < collection.length; i++) {
if (collection[i].location) {
return collection[i].location;
}
}
};
/**
* Group all measurements by its tool group and measurement number.
*
* @param measurementApi
* @param timepointApi
* @returns {*} A list containing each toolGroup and an array containing the measurement rows
*/
OHIF.measurements.getMeasurementsGroupedByNumber = (measurementApi, timepointApi) => {
const getPath = OHIF.utils.ObjectPath.get;
const configuration = OHIF.measurements.MeasurementApi.getConfiguration();
if (!measurementApi || !timepointApi || !configuration) return;
// Check which tools are going to be displayed
const displayToolGroupMap = {};
const displayToolList = [];
configuration.measurementTools.forEach(toolGroup => {
displayToolGroupMap[toolGroup.id] = false;
toolGroup.childTools.forEach(tool => {
const willDisplay = !!getPath(tool, 'options.measurementTable.displayFunction');
if (willDisplay) {
displayToolList.push(tool.id);
displayToolGroupMap[toolGroup.id] = true;
}
});
});
// Create the result object
const groupedMeasurements = [];
const baseline = timepointApi.baseline();
if (!baseline) return;
configuration.measurementTools.forEach(toolGroup => {
// Skip this tool group if it should not be displayed
if (!displayToolGroupMap[toolGroup.id]) return;
// Retrieve all the data for this Measurement type (e.g. 'targets')
// which was recorded at baseline.
const atBaseline = measurementApi.fetch(toolGroup.id, {
timepointId: baseline.timepointId
});
// Obtain a list of the Measurement Numbers from the
// measurements which have baseline data
const numbers = atBaseline.map(m => m.measurementNumber);
// Retrieve all the data for this Measurement type which
// match the Measurement Numbers obtained above
const data = measurementApi.fetch(toolGroup.id, {
toolId: {
$in: displayToolList
},
measurementNumber: {
$in: numbers
}
});
// Group the Measurements by Measurement Number
const groupObject = _.groupBy(data, entry => entry.measurementNumber);
// Reformat the data for display in the table
const measurementRows = Object.keys(groupObject).map(key => ({
measurementTypeId: toolGroup.id,
measurementNumber: key,
location: OHIF.measurements.getLocation(groupObject[key]),
responseStatus: false, // TODO: Get the latest timepoint and determine the response status
entries: groupObject[key]
}));
// Add the group to the result
groupedMeasurements.push({
toolGroup,
measurementRows
});
});
return groupedMeasurements;
};

View File

@ -2,6 +2,7 @@ import './jumpToRowItem.js';
import './activateMeasurements.js'; import './activateMeasurements.js';
import './deactivateAllToolData.js'; import './deactivateAllToolData.js';
import './exportPdf.js'; import './exportPdf.js';
import './getMeasurementsGroupedByNumber.js';
import './getTimepointName.js'; import './getTimepointName.js';
import './hangingProtocolCustomizations.js'; import './hangingProtocolCustomizations.js';
import './MeasurementHandlers.js'; import './MeasurementHandlers.js';