Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extending Cohort generation results with simple demographics available in Cohort Characterization #2959

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
11 changes: 10 additions & 1 deletion js/pages/cohort-definitions/cohort-definition-manager.html
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ <h3 data-bind="text: ko.i18n('cohortDefinitions.cohortDefinitionManager.panels.a
</tbody>
</table>
<!-- ko if: selectedReportSource() -->
<cohort-reports params="cohort: currentCohortDefinition, source: selectedReportSource"></cohort-reports>
<cohort-reports params="cohort: currentCohortDefinition, source: selectedReportSource, infoSelected: selectedReportSource"></cohort-reports>
<!-- /ko -->
</div>
<div role="tabpanel" data-bind="css: { active: $component.tabMode() == 'reporting' }" class="tab-pane">
Expand Down Expand Up @@ -793,4 +793,13 @@ <h3 data-bind="text: ko.i18n('cohortDefinitions.cohortDefinitionManager.panels.a
</div>
</script>

<script type="text/html" id="generation-checkbox-demographic">
<span>
<input class="hover-toolbox" type="checkbox" data-bind="attr:{ id: $data.sourceKey } , checked: viewDemographic, tooltip: 'Results with Demographics', eventListener: [
{event: 'mouseover', selector: 'input', callback: $component.addToolTipDemographic },
{event: 'mouseout', selector: 'input', callback: $component.removeToolTipDemographic },
{event: 'mouseup', selector: 'input', callback: $component.handleViewDemographic }]" data-placement="right"/>
</span>
</script>

<!-- /ko -->
95 changes: 93 additions & 2 deletions js/pages/cohort-definitions/cohort-definition-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ define(['jquery', 'knockout', 'text!./cohort-definition-manager.html',
'utilities/sql',
'components/conceptset/conceptset-list',
'components/name-validation',
'components/versions/versions'
'components/versions/versions',
'databindings/tooltipBinding'
], function (
$,
ko,
Expand Down Expand Up @@ -601,6 +602,16 @@ define(['jquery', 'knockout', 'text!./cohort-definition-manager.html',
title: ko.i18n('cohortDefinitions.cohortDefinitionManager.panels.generationDuration', 'Generation Duration'),
data: 'executionDuration'
}, {
title: ko.i18n(
'cohortDefinitions.cohortDefinitionManager.panels.generationDuration3',
'Demographics'
),
data: 'viewDemographic',
sortable: false,
tooltip: 'Results with Demographics',
render: () =>
`<span data-bind="template: {name: 'generation-checkbox-demographic', data: $data }"></span>`,
},{
sortable: false,
className: 'generation-buttons-column',
render: () => `<span data-bind="template: { name: 'generation-buttons', data: $data }"></span>`
Expand Down Expand Up @@ -653,6 +664,8 @@ define(['jquery', 'knockout', 'text!./cohort-definition-manager.html',
source.personCount(commaFormatted(info.personCount));
source.recordCount(commaFormatted(info.recordCount));
source.failMessage(info.failMessage);
source.ccGenerateId(info.ccGenerateId);
source.viewDemographic(info.isChooseDemographic);
}
}
});
Expand Down Expand Up @@ -1094,13 +1107,25 @@ define(['jquery', 'knockout', 'text!./cohort-definition-manager.html',
if (this.selectedSource() && this.selectedSource().sourceId === source.sourceId) {
this.toggleCohortReport(null);
}
cohortDefinitionService.generate(this.currentCohortDefinition().id(), source.sourceKey)
cohortDefinitionService.generate(this.currentCohortDefinition().id(), source.sourceKey, source.viewDemographic())
.catch(this.authApi.handleAccessDenied)
.then(({data}) => {
jobDetailsService.createJob(data);
});
}

handleCheckboxDemographic(source) {
const targetSource = this.getSourceKeyInfo(source.sourceKey);
targetSource.viewDemographic(targetSource.viewDemographic());
const restSourceInfos = this.cohortDefinitionSourceInfo().filter(
(d) => {
return d.sourceKey !== source.sourceKey;
}
);

this.cohortDefinitionSourceInfo([...restSourceInfos, targetSource])
}

cancelGenerate (source) {
this.stopping()[source.sourceKey](true);
cohortDefinitionService.cancelGenerate(this.currentCohortDefinition().id(), source.sourceKey);
Expand Down Expand Up @@ -1261,6 +1286,9 @@ define(['jquery', 'knockout', 'text!./cohort-definition-manager.html',
}
cdsi.failMessage = ko.observable(sourceInfo.failMessage);
cdsi.createdBy = ko.observable(sourceInfo.createdBy);
cdsi.viewDemographic = ko.observable(sourceInfo?.viewDemographic || sourceInfo.isChooseDemographic || false);
cdsi.tooltipDemographic = ko.observable(sourceInfo?.tooltipDemographic || null);
cdsi.ccGenerateId = ko.observable(sourceInfo.ccGenerateId);
} else {
cdsi.isValid = ko.observable(false);
cdsi.isCanceled = ko.observable(false);
Expand All @@ -1271,6 +1299,9 @@ define(['jquery', 'knockout', 'text!./cohort-definition-manager.html',
cdsi.recordCount = ko.observable('n/a');
cdsi.failMessage = ko.observable(null);
cdsi.createdBy = ko.observable(null);
cdsi.viewDemographic = ko.observable(false);
cdsi.tooltipDemographic = ko.observable(null);
cdsi.ccGenerateId = ko.observable(null);
}
return cdsi;
}
Expand Down Expand Up @@ -1316,6 +1347,23 @@ define(['jquery', 'knockout', 'text!./cohort-definition-manager.html',

async prepareCohortDefinition(cohortDefinitionId, conceptSetId, selectedSourceId, sourceKey, versionNumber) {
this.isLoading(true);
ko.bindingHandlers.tooltip = {
init: function (element, valueAccessor) {
const value = ko.utils.unwrapObservable(valueAccessor());
$("[aria-label='Demographics']").attr('data-original-title', 'Results with Demographics').bstooltip({
html: true,
container:'body',
});
$(element).attr('data-original-title', value).bstooltip({
html: true,
container:'body'
});
},
update: function (element, valueAccessor) {
const value = ko.utils.unwrapObservable(valueAccessor());
$(element).attr('data-original-title', value);
}
}
if(parseInt(cohortDefinitionId) === 0) {
this.setNewCohortDefinition();
} else if (versionNumber) {
Expand Down Expand Up @@ -1348,6 +1396,49 @@ define(['jquery', 'knockout', 'text!./cohort-definition-manager.html',
}
}

addToolTipDemographic(source){
const targetSource = this.getSourceKeyInfo(source?.sourceKey);
targetSource?.tooltipDemographic('Results with Demographics');
const restSourceInfos = this.cohortDefinitionSourceInfo().filter(
(d) => {
return d.sourceKey !== source?.sourceKey;
}
);
this.cohortDefinitionSourceInfo([
...restSourceInfos,
targetSource
])
}

removeToolTipDemographic(source){
const targetSource = this.getSourceKeyInfo(source?.sourceKey);
targetSource?.tooltipDemographic(null);
const restSourceInfos = this.cohortDefinitionSourceInfo().filter(
(d) => {
return d?.sourceKey !== source?.sourceKey;
}
);
this.cohortDefinitionSourceInfo([
...restSourceInfos,
targetSource
])
}

handleViewDemographic(source) {
const targetSource = this.getSourceKeyInfo(source?.sourceKey);
targetSource.viewDemographic(!targetSource.viewDemographic());
targetSource?.tooltipDemographic(null);
const restSourceInfos = this.cohortDefinitionSourceInfo().filter(
(d) => {
return d?.sourceKey !== source?.sourceKey;
}
);
this.cohortDefinitionSourceInfo([
...restSourceInfos,
targetSource
])
}

checkifDataLoaded(cohortDefinitionId, conceptSetId, sourceKey) {
if (this.currentCohortDefinition() && this.currentCohortDefinition().id() == cohortDefinitionId) {
if (this.currentConceptSet() && this.currentConceptSet().id == conceptSetId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ define([
PluginRegistry.add(globalConstants.pluginTypes.COHORT_REPORT, {
title: ko.i18n('cohortDefinitions.cohortreports.inclusionReport', 'Inclusion Report'),
priority: 1,
html: `<cohort-report-inclusion params="{ sourceKey: sourceKey, cohortId: cohortId }"></cohort-report-inclusion>`
html: `<cohort-report-inclusion params="{ sourceKey: sourceKey, cohortId: cohortId, isViewDemographic: isViewDemographic, ccGenerateId: ccGenerateId }"></cohort-report-inclusion>`
});

class CohortReports extends Component {
Expand All @@ -30,18 +30,37 @@ define([

this.sourceKey = ko.computed(() => params.source() && params.source().sourceKey);
this.cohortId = ko.computed(() => params.cohort().id());

this.isViewDemographic = ko.computed(() => params.source() && params.source().viewDemographic());
this.ccGenerateId = ko.computed(() => params.infoSelected() && params.infoSelected().ccGenerateId());

const componentParams = {
sourceKey: this.sourceKey,
cohortId: this.cohortId
cohortId: this.cohortId,
isViewDemographic: this.isViewDemographic,
ccGenerateId: this.ccGenerateId,
};

this.tabs = PluginRegistry.findByType(globalConstants.pluginTypes.COHORT_REPORT).map(t => ({ ...t, componentParams }));

if (this.isViewDemographic()) {
this.tabs.push({
title: ko.i18n('cohortDefinitions.cohortreports.tabs.byPerson3', 'Demographics'),
componentName: 'demographic-report',
componentParams: {
...componentParams,
reportType: constants.INCLUSION_REPORT.BY_DEMOGRAPHIC,
buttons: null,
tableDom: "Blfiprt"
}
});
}
}

dispose() {
this.sourceKey.dispose();
this.cohortId.dispose();
this.isViewDemographic.dispose();
this.ccGenerateId.dispose();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,18 @@ define([], () => {
const INCLUSION_REPORT = {
BY_EVENT: 0,
BY_PERSON: 1,
BY_DEMOGRAPHIC: 2
};

const feAnalysisTypes = {
PRESET: 'PRESET',
CRITERIA_SET: 'CRITERIA_SET',
CUSTOM_FE: 'CUSTOM_FE'
};

return {
INCLUSION_REPORT
INCLUSION_REPORT,
feAnalysisTypes
};
}
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
define([
'knockout',
'./BaseStatConverter',
'./DistributionStat',
], function (
ko,
BaseStatConverter,
DistributionStat,
) {

class BaseDistributionStatConverter extends BaseStatConverter {

constructor(classes) {
super(classes);
}

convertAnalysisToTabularData(analysis, stratas = null) {

const result = super.convertAnalysisToTabularData(analysis, stratas);
stratas && stratas.filter(s => result.data.findIndex(row => row.strataId === s.strataId) < 0)
.forEach(s => result.data.push(this.getResultObject(
{
analysisId: analysis.analysisId,
analysisName: analysis.analysisName,
domainId: analysis.domainId,
cohorts: [],
strataId: s.strataId,
strataName: s.strataName,
}
)));
return result;
}

getRowId(stat) {
return stat.strataId * 100000 + stat.covariateId;
}

getResultObject(stat) {
return new DistributionStat(stat);
}

extractStrata(stat) {
return { strataId: 0, strataName: '' };
}

getDefaultColumns(analysis) {
return [{
title: ko.i18n('columns.strata', 'Strata'),
data: 'strataName',
className: this.classes('col-distr-title'),
xssSafe:false,
},
{
title: 'Covariate',
data: 'covariateName',
className: this.classes('col-distr-cov'),
xssSafe: false,
},
{
title: 'Value field',
data: (row, type) => {
let data = (row.faType === 'CRITERIA_SET' && row.aggregateName) || "Events count" ;
if (row.missingMeansZero) {
data = data + "*";
}
return data;
}
}];
}

convertFields(result, strataId, cohortId, stat, prefix) {
result.strataName = stat.strataName;
['count', 'avg', 'pct', 'stdDev', 'median', 'max', 'min', 'p10', 'p25', 'p75', 'p90'].forEach(field => {
const statName = prefix ? prefix + field.charAt(0).toUpperCase() + field.slice(1) : field;
this.setNestedValue(result, field, strataId, cohortId, stat[statName]);
});
}

convertCompareFields(result, strataId, stat) {
this.convertFields(result, strataId, stat.targetCohortId, stat, "target");
this.convertFields(result, strataId, stat.comparatorCohortId, stat, "comparator");
}
}

return BaseDistributionStatConverter;
});
Loading
Loading