LT-55: Exposing grouping measurements method in OHIF namespace
This commit is contained in:
parent
fc3eb30f8b
commit
28ac391c52
@ -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>
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -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
|
{{/each}}
|
||||||
timepointApi=timepointApi
|
|
||||||
measurementApi=measurementApi
|
|
||||||
conformanceCriteria=conformanceCriteria}}
|
|
||||||
|
|
||||||
{{#each entry in collection}}
|
|
||||||
{{>measurementTableRow (clone this rowItem=entry)}}
|
|
||||||
{{/each}}
|
|
||||||
{{/let}}
|
|
||||||
{{/if}}
|
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
||||||
{{#if config.newMeasurementTool}}
|
{{#if config.newMeasurementTool}}
|
||||||
|
|||||||
@ -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];
|
measurementTypeId: measurementTypeId,
|
||||||
|
measurementNumber: key,
|
||||||
return {
|
location: OHIF.measurements.getLocation(groupObject[key]),
|
||||||
measurementTypeId: measurementTypeId,
|
responseStatus: false, // TODO: Get the latest timepoint and determine the response status
|
||||||
measurementNumber: key,
|
entries: groupObject[key]
|
||||||
location: OHIF.measurements.getLocation(groupObject[key]),
|
}));
|
||||||
responseStatus: false, // TODO: Get the latest timepoint and determine the response status
|
|
||||||
entries: groupObject[key]
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -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;
|
||||||
|
};
|
||||||
@ -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';
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user