Skip to content

Commit

Permalink
Cohort Definition Calculation Designer
Browse files Browse the repository at this point in the history
  • Loading branch information
wivern committed Dec 5, 2023
1 parent 596cde6 commit 8501843
Show file tree
Hide file tree
Showing 14 changed files with 154 additions and 7 deletions.
4 changes: 3 additions & 1 deletion js/components/cohortbuilder/CriteriaTypes/Measurement.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
define(['knockout', './Criteria', '../InputTypes/Range','conceptpicker/InputTypes/Concept', '../InputTypes/Text'], function (ko, Criteria, Range, Concept, Text) {
define(['knockout', './Criteria', '../InputTypes/Range','conceptpicker/InputTypes/Concept', '../InputTypes/Text', '../InputTypes/Calculation'], function (ko, Criteria, Range, Concept, Text, Calculation) {

function Measurement(data, conceptSets) {
var self = this;
Expand Down Expand Up @@ -65,6 +65,8 @@ define(['knockout', './Criteria', '../InputTypes/Range','conceptpicker/InputType
return new Concept(d);
})));

self.MeasurementOperand = ko.observable(data.MeasurementOperand != null ? new Calculation(data.MeasurementOperand, conceptSets) : null);

}

Measurement.prototype = new Criteria();
Expand Down
26 changes: 26 additions & 0 deletions js/components/cohortbuilder/InputTypes/Calculation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
define([
"knockout",
"../CriteriaTypes/Measurement",
"../CriteriaTypes",
"../InputTypes/Range",
], function (
ko,
Measurement,
CriteriaTypes,
Range,
){
function Calculation(data, conceptSets) {
var self = this;
data = data || {};

// var measurement = new Measurement((data.Measurement && data.Measurement.Measurement) ? data.Measurement.Measurement : {}, conceptSets);
// self.Measurement = ko.observable({Measurement: measurement});
self.Measurement = ko.observable({ Measurement: new CriteriaTypes.Measurement((data.Measurement && data.Measurement.Measurement) ? data.Measurement.Measurement : {}, conceptSets) });
self.Operator = ko.observable(data.Operator || "-");
self.Limit = ko.observable(data.Limit || "First");
self.SameVisit = ko.observable(!!data.SameVisit);
self.ValueAsNumber = ko.observable(new Range(data.ValueAsNumber));
}

return Calculation;
});
3 changes: 3 additions & 0 deletions js/components/cohortbuilder/components.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ define(function (require, exports) {
var locationRegion = require('./components/LocationRegion');
ko.components.register('location-region-criteria', locationRegion);

var measurementOperand = require("./components/MeasurementOperand");
ko.components.register("measurement-operand-criteria", measurementOperand);

require('./components/WindowedCriteria');

});
14 changes: 12 additions & 2 deletions js/components/cohortbuilder/components/Measurement.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@ define([
"../utils",
"../InputTypes/Range",
"../InputTypes/DateAdjustment",
"../InputTypes/Calculation",
"../CriteriaGroup",
"text!./MeasurementTemplate.html",
"../const"
], function (ko, options, utils, Range, DateAdjustment, CriteriaGroup, template, constants) {
], function (ko, options, utils, Range, DateAdjustment, Calculation, CriteriaGroup, template, constants) {
function MeasurementViewModel(params) {
var self = this;

self.expression = ko.utils.unwrapObservable(params.expression);
self.Criteria = params.criteria.Measurement;
self.Criteria = ko.unwrap(params.criteria).Measurement;
self.options = options;

self.addActions = [
Expand Down Expand Up @@ -160,6 +161,15 @@ define([
self.Criteria.MeasurementSourceConcept(ko.observable());
},
},
{
...constants.measurementAttributes.addMeasurementOperand,
selected: false,
action: () => {
if (self.Criteria.MeasurementOperand() == null) {
self.Criteria.MeasurementOperand(new Calculation({}, self.expression.ConceptSets));
}
}
},
{
...constants.measurementAttributes.addNested,
selected: false,
Expand Down
28 changes: 28 additions & 0 deletions js/components/cohortbuilder/components/MeasurementOperand.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
define([
"knockout",
"../options",
"text!./MeasurementOperandTemplate.html",
"less!./MeasurementOperand.less",
], function (
ko,
options,
template,
) {

function MeasurementOperandViewModel(params) {
var self = this;
self.expression = ko.unwrap(params.expression);
var criteria = ko.unwrap(params.criteria);
self.Measurement = criteria.Measurement;
self.Operator = criteria.Operator;
self.Limit = criteria.Limit;
self.SameVisit = criteria.SameVisit;
self.ValueAsNumber = criteria.ValueAsNumber;
self.options = options;
}

return {
viewModel: MeasurementOperandViewModel,
template: template,
};
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.measurement-operand {
margin-bottom: 0.5rem;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<div class="criteriaSection">
<div class="measurement-operand">
<select data-bind="options: $component.options.operatorOptions, value: $component.Operator"></select>
<select data-bind="options: $component.options.eventsLimit, optionsText: 'name', optionsValue: 'id', value: $component.Limit"></select>
<span data-bind="text: ko.i18n('components.conditionMeasurement.conditionMeasurement_32', 'of')">of</span>
</div>
<measurement-criteria params="{ criteria: ko.unwrap($component.Measurement), expression: ko.unwrap($component.expression) }"></measurement-criteria>
<div class="measurement-operand">
<span data-bind="text: ko.i18n('components.conditionMeasurement.conditionMeasurementText_31', 'restricted to the same visit')"></span> <input type="checkbox" data-bind="checked: $component.SameVisit" />
</div>
<div>
<span data-bind="text: ko.i18n('components.conditionMeasurement.conditionMeasurementText_6', 'with calculated value as number')"></span>
<numeric-range params="Range: ValueAsNumber"></numeric-range>
</div>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,12 @@
<criteria-group params="{expression: $component.expression, group: CorrelatedCriteria, indexMessage: $component.indexMessage}"></criteria-group>
</td>
</tr>
<tr data-bind="if: MeasurementOperand() != null, visible: MeasurementOperand() != null">
<td><i data-bind="click: function() { $component.removeCriterion('MeasurementOperand') }, title: ko.i18n('common.remove', 'Remmove')" class="fa fa-times" /></td>
<td>
<measurement-operand-criteria params="{expression: $component.expression, criteria: ko.unwrap(MeasurementOperand)}" ></measurement-operand-criteria>
</td>
</tr>
</table>
</div>
</div>
10 changes: 8 additions & 2 deletions js/components/cohortbuilder/const.js
Original file line number Diff line number Diff line change
Expand Up @@ -1062,7 +1062,12 @@ define(["knockout"], function (ko) {
descriptionGroup: 'const.eventsList.addLocationRegion.desc_group',
defaultDescriptionGroup: 'Find patients within geographical area.',
},

addMeasurementOperand: {
titleMeasurement: 'const.eventsList.addMeasurementOperand.title_measurement',
defaultTitleMeasurement: 'Add Calculation',
descriptionMeasurement: 'const.eventsList.addMeasurementOperand.desc_measurement',
defaultDescriptionMeasurement: 'Add calculated value based on a Measurement',
},
};

function setCriteria(criteria) {
Expand Down Expand Up @@ -1235,7 +1240,8 @@ define(["knockout"], function (ko) {
'addRangeHighRatio',
'addProviderSpecialty',
'addSourceConcept',
'addNested'
'addMeasurementOperand',
'addNested',
];
const drugexposureAttributesList = [
'addDateAdjustment',
Expand Down
13 changes: 12 additions & 1 deletion js/components/cohortbuilder/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,18 @@ define(["knockout"], function (ko) {
name: ko.i18n('options.eventEnds', 'event ends'),
value: true
}]


options.operatorOptions = [
'+', '-', '*', '/'
];

options.eventsLimit = [{
name: ko.i18n('options.earliestEvents', 'earliest event'),
id: "First"
}, {
name: ko.i18n('options.latestEvents', 'latest event'),
id: "Last"
}];

return options;
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
define([
"knockout",
"text!./MeasurementOperandTemplate.html",
], function (
ko,
template,
){
function MeasurementOperandViewModel(params) {
var self = this;

self.expression = ko.unwrap(params.expression);
var criteria = ko.unwrap(params.criteria);
self.Criteria = criteria;
const measurement = criteria.Measurement;
self.CodesetId = measurement.Measurement && measurement.Measurement.CodesetId;
self.ValueAsNumber = criteria.ValueAsNumber;
}

return {
viewModel: MeasurementOperandViewModel,
template: template,
};
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!-- ko with: Criteria -->
<span data-bind="text: Operator"></span> <span data-bind="text: ko.i18n('components.conditionMeasurement.conditionMeasurementText_1', 'a measurement of')"></span>
<conceptset-reference params="{conceptSetId: $component.CodesetId, conceptSets: $component.expression.ConceptSets, defaultName: ko.i18n('components.conditionMeasurement.anyMeasurement', 'Any Measurement')}"></conceptset-reference>
<!-- ko if: SameVisit -->
<span data-bind="text:ko.i18n('components.conditionMeasurement.conditionMeasurementText_30', 'at the same visit')"></span>
<!-- /ko -->
<span data-bind="text: ko.i18n('components.conditionMeasurement.conditionMeasurementText_6', 'with value as number')"></span>
<numeric-range-viewer params="Range: $component.ValueAsNumber"></numeric-range-viewer>
<!-- /ko -->
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@
<span data-bind="text: ko.i18n('components.conditionMeasurement.conditionMeasurementText_28', 'visit occurrence is any of:')"></span>
<concept-list-viewer params="ConceptList: ko.utils.unwrapObservable(VisitType)"></concept-list-viewer></li>
<!-- /ko -->
<!-- ko if: ko.unwrap(MeasurementOperand) != null -->
<measurement-operand-viewer params="{expression: $component.expression, criteria: ko.unwrap(MeasurementOperand)}"></measurement-operand-viewer>
<!-- /ko -->
<!-- ko if: ko.utils.unwrapObservable(CorrelatedCriteria) != null -->
<criteria-group-viewer params="{expression: $component.expression, group: CorrelatedCriteria}"></criteria-group-viewer>
<!-- /ko -->
Expand Down
4 changes: 3 additions & 1 deletion js/components/cohortdefinitionviewer/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,5 +86,7 @@ define(function (require, exports) {

var locationRegion = require('./components/LocationRegion');
ko.components.register('location-region-viewer', locationRegion);


var measurementOperand = require("./components/MeasurementOperand");
ko.components.register("measurement-operand-viewer", measurementOperand);
});

0 comments on commit 8501843

Please sign in to comment.