LT-92: Integrating RECIST and measurements table

This commit is contained in:
Leonardo Campos 2017-01-16 21:20:24 -02:00 committed by Bruno Alves de Faria
parent 7ef0dd812b
commit 1efe611497
7 changed files with 47 additions and 16 deletions

View File

@ -101,10 +101,13 @@ Template.viewer.onCreated(() => {
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);
console.warn('>>>>REMOVE THE LINES BELOW');
window.measurementApi = instance.data.measurementApi;
window.timepointApi = instance.data.timepointApi;
window.conformanceCriteria = new OHIF.measurements.ConformanceCriteria(window.measurementApi, instance.data.timepointApi);
window.conformanceCriteria = instance.data.conformanceCriteria;
const measurementsPromise = instance.data.measurementApi.retrieveMeasurements(patientId, timepointIds);
measurementsPromise.then(() => {
Session.set('MeasurementsReady', true);

View File

@ -1,16 +1,16 @@
<template name="measurementTableRow">
<div class="measurementTableRow {{#unless rowItem.location}}warning{{/unless}}{{#if responseStatus}}response-status{{/if}}" data-measurementid="{{_id}}">
<div class="measurementTableRow {{#if hasWarnings}}warning{{/if}}{{#if responseStatus}}response-status{{/if}}" data-measurementid="{{_id}}">
<div class='measurementRowSidebar'>
<div class="measurementNumber">
{{rowItem.measurementNumber}}
</div>
{{#unless rowItem.location}}
{{#if hasWarnings}}
<div class="warning-icon">
<svg>
<use xlink:href={{absoluteUrl "packages/ohif_viewerbase/assets/icons.svg#icon-ui-warning"}}></use>
</svg>
</div>
{{/unless}}
{{/if}}
{{#if rowItem.responseStatus}}
<div class="response-status-icon">
{{rowItem.responseStatus}}

View File

@ -22,6 +22,26 @@ const keys = {
DELETE: 46
};
Template.measurementTableRow.helpers({
hasWarnings() {
const toolsGroupsMap = this.measurementApi.toolsGroupsMap;
const nonConformities = this.conformanceCriteria.nonConformities.get();
const foundNonConformity = _.find(nonConformities, nonConformity => {
const measurement = _.find(nonConformity.measurements, measurement => {
if(toolsGroupsMap[measurement.toolType] !== this.rowItem.measurementTypeId) {
return false;
}
return measurement.measurementNumber === parseInt(this.rowItem.measurementNumber, 10);
});
return !!measurement;
});
return !!foundNonConformity;
}
});
Template.measurementTableRow.events({
'click .measurementRowSidebar'(event, instance) {
const $row = instance.$('.measurementTableRow');

View File

@ -9,7 +9,8 @@
measurements=collection
currentTimepointId=currentTimepointId
timepointApi=timepointApi
measurementApi=measurementApi}}
measurementApi=measurementApi
conformanceCriteria=conformanceCriteria}}
{{#each entry in collection}}
{{>measurementTableRow (clone this rowItem=entry)}}

View File

@ -8,7 +8,7 @@ class ConformanceCriteria {
constructor(measurementApi, timepointApi) {
this.measurementApi = measurementApi;
this.timepointApi = timepointApi;
this.results = [];
this.nonConformities = new ReactiveVar();
const validate = _.debounce(trialCriteriaType => {
this.validate(trialCriteriaType);
@ -32,23 +32,23 @@ class ConformanceCriteria {
const resultBoth = this.validateTimepoint('both', trialCriteriaType, mergedData);
const resultBaseline = this.validateTimepoint('baseline', trialCriteriaType, baselineData);
const resultFollowup = this.validateTimepoint('followup', trialCriteriaType, followupData);
const results = resultBaseline.concat(resultFollowup).concat(resultBoth);
const nonConformities = resultBaseline.concat(resultFollowup).concat(resultBoth);
console.warn('>>>> validate', results);
this.nonConformities.set(nonConformities);
return results;
return nonConformities;
}
validateTimepoint(timepointId, trialCriteriaType, data) {
const evaluators = this.getEvaluators(timepointId, trialCriteriaType);
let results = [];
let nonConformities = [];
evaluators.forEach(evaluator => {
const result = evaluator.evaluate(data);
results = results.concat(result);
nonConformities = nonConformities.concat(result);
});
return results;
return nonConformities;
}
getEvaluators(timepointId, trialCriteriaType) {

View File

@ -25,6 +25,10 @@ export class CriteriaEvaluator {
}
getCriteriaValidator() {
if(CriteriaEvaluator.criteriaValidator) {
return CriteriaEvaluator.criteriaValidator;
}
const schema = {
properties: {},
definitions: {}
@ -50,18 +54,18 @@ export class CriteriaEvaluator {
}
});
return new Ajv().compile(schema);
return CriteriaEvaluator.criteriaValidator = new Ajv().compile(schema);
}
evaluate(data) {
const nonconformity = [];
const nonConformities = [];
this.criteria.forEach(criterion => {
const criterionResult = criterion.evaluate(data);
if (!criterionResult.passed) {
nonconformity.push(criterionResult);
nonConformities.push(criterionResult);
}
});
return nonconformity;
return nonConformities;
}
}

View File

@ -6,8 +6,11 @@ export class BaseCriterion {
generateResponse(message, measurements) {
const passed = !message;
const isGlobal = !measurements || !measurements.length;
return {
passed,
isGlobal,
message,
measurements
};