Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions js/components/Chart.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ define([
this.container = container;
this.chartName = params.chartName ? params.chartName : '';
this.reportName = ko.unwrap(params.reportName);
this.filename = ko.computed (() => {
this.fileName = ko.computed (() => {
const fileName = this.reportName ? `${ko.unwrap(params.reportName)}_${this.chartName}`.replace(/ /g, '') : 'untitled';
return fileName.length > 90 ? fileName.slice(0,90) : fileName;
});
Expand All @@ -49,11 +49,11 @@ define([

export() {
const svg = this.container.element.querySelector('svg');
ChartUtils.downloadSvgAsPng(svg, this.filename() || "untitled.png");
ChartUtils.downloadSvgAsPng(svg, this.fileName() || "untitled.png");
}
exportSvg() {
const svg = this.container.element.querySelector('svg');
ChartUtils.downloadSvg(svg, this.filename() + ".svg" || "untitled.svg");
ChartUtils.downloadSvg(svg, this.fileName() + ".svg" || "untitled.svg");
}
dispose() {
this.renderer && this.renderer.dispose();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
define([
'knockout',
'pages/data-sources/const',
'components/reports/const',
'services/http',
'components/Component',
], function (
Expand All @@ -14,7 +14,6 @@ define([
super(params);
this.isLoading = ko.observable(true);
this.chartFormats = {};

this.context = params.context;
this.source = this.context.currentSource;
this.title = ko.computed(() => {
Expand All @@ -35,9 +34,10 @@ define([
}

getData() {

const url = constants.apiPaths.report({
sourceKey: this.source() ? this.source().sourceKey : this.context.routerParams.sourceKey,
path: this.context.routerParams.reportName,
path: this.context.currentReport().path || this.context.routerParams.reportName,
conceptId: this.conceptId,
});
this.context.loadingReport(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ define([
// abstract, no need to define component name here

constructor(params) {

super(params);
this.treeData = ko.observable();
this.tableData = ko.observable();
Expand Down
97 changes: 97 additions & 0 deletions js/components/reports/const.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
define(
(require, factory) => {
const ko = require('knockout');
const config = require('appConfig');

const apiPaths = {
report: ({ sourceKey, path, conceptId }) => `${config.api.url}cdmresults/${sourceKey}/${path}${conceptId !== null ? `/${conceptId}` : ''}`,
};

// aggregate property descriptors
const recordsPerPersonProperty = {
name: "recordsPerPerson",
description: ko.i18n('dataSources.const.recordsPerPerson', 'Records per person')
};
const lengthOfEraProperty = {
name: "lengthOfEra",
description: ko.i18n('dataSources.const.lengthOfEra', 'Length of era')
};

const reports = [{
name: ko.i18n('dataSources.reports.dashboard', 'Dashboard'),
path: "dashboard",
component: "report-dashboard",
summary: ko.observable()
},
{
name: ko.i18n('dataSources.reports.dataDensity', 'Data Density'),
path: "datadensity",
component: "report-datadensity",
},
{
name: ko.i18n('dataSources.reports.person', 'Person'),
path: "person",
component: "report-person",
},
{
name: ko.i18n('dataSources.reports.visit', 'Visit'),
path: "visit",
component: "report-visit",
},
{
name: ko.i18n('dataSources.reports.conditionOccurrence', 'Condition Occurrence'),
path: "condition",
component: "report-condition",
},
{
name: ko.i18n('dataSources.reports.conditionEra', 'Condition Era'),
path: "conditionera",
component: "report-condition-era",
},
{
name: ko.i18n('dataSources.reports.procedure', 'Procedure'),
path: "procedure",
component: "report-procedure",
},
{
name: ko.i18n('dataSources.reports.drugExposure', 'Drug Exposure'),
path: "drug",
component: "report-drug",
},
{
name: ko.i18n('dataSources.reports.drugEra', 'Drug Era'),
path: "drugera",
component: "report-drug-era",
},
{
name: ko.i18n('dataSources.reports.measurement', 'Measurement'),
path: "measurement",
component: "report-measurement",
},
{
name: ko.i18n('dataSources.reports.observation', 'Observation'),
path: "observation",
component: "report-observation",
},
{
name: ko.i18n('dataSources.reports.observationPeriod', 'Observation Period'),
path: "observationPeriod",
component: "report-observation-period"
},
{
name: ko.i18n('dataSources.reports.death', 'Death'),
path: "death",
component: "report-death",
}
];

return {
apiPaths,
aggProperties: {
byPerson: recordsPerPersonProperty,
byLengthOfEra: lengthOfEraProperty,
},
reports,
};
}
);
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
<loading params="status: ko.i18n('dataSources.loadingReport', 'Loading report')" data-bind="visible: !context.loadingDrilldownDone()">
</loading>
<!-- ko if: context.loadingDrilldownDone() -->
<!-- ko if: isError -->
<empty-state params="message: ko.i18n('dataSources.drilldown.noData', 'No data')"></empty-state>
<!-- /ko -->
<!-- ko if: !isData() -->
<empty-state params="message: ko.i18n('dataSources.drilldown.reportNoData', 'No data to display this report')"></empty-state>
<!-- /ko -->

<div data-bind="visible: !isError()" id="drilldownReport">
<!-- ko if: currentConcept() -->
<div data-bind="visible: !isError() && isData()" id="drilldownReport">
<!-- ko if: (currentConcept() && !hideReportName()) -->
<span class="report-heading-title" data-bind="text: `${currentConcept().name} ${ko.i18n('dataSources.drilldown.drilldownReport', 'Drilldown Report')()}`"></span>
<a class="scroll-to-top-link" data-bind="click: () => document.getElementById('dataSourcesTop').scrollIntoView()">scroll to the top</a>
<!-- /ko -->
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
define([
'knockout',
'text!./treemapDrilldown.html',
'text!./reportDrilldown.html',
'd3',
'atlascharts',
'utils/CommonUtils',
'utils/ChartUtils',
'const',
'pages/data-sources/classes/Report',
'./classes/Report',
'components/Component',
'components/charts/histogram',
'components/charts/line',
Expand All @@ -25,17 +25,17 @@ define([
commonUtils,
ChartUtils,
constants,
Report,
Component
Report
) {
class TreemapDrilldown extends Report {
class ReportDrilldown extends Report {
constructor(params) {
super(params);

this.currentConcept = ko.observable({
name: '',
});
this.isError = ko.observable(false);
this.hideReportName = ko.observable(params.hideReportName || false);

// options
this.byFrequency = false;
Expand Down Expand Up @@ -145,7 +145,7 @@ define([
},
};

this.currentReport = params.currentReport;
this.currentReport = params.currentReport();
this.byFrequency = params.byFrequency;
this.byUnit = params.byUnit;
this.byType = params.byType;
Expand All @@ -154,13 +154,23 @@ define([
this.byQualifier = params.byQualifier;
this.byLengthOfEra = params.byLengthOfEra;
this.context = params.context;
this.refreshReport = !!params.refreshReport;
this.subscriptions.push(params.currentConcept.subscribe(this.loadData.bind(this)));

if (params.currentSource) {
this.subscriptions.push(params.currentSource.subscribe(newValue => {
if (newValue && this.refreshReport) {
this.loadData(params.currentConcept());
}
})
)};
this.loadData(params.currentConcept());
this.reportName = ko.computed(() => `${this.currentReport.name()}_${this.currentConcept().name}`);
this.reportName = ko.computed(() => this.currentConcept().name ? `${this.currentReport.name()}_${this.currentConcept().name}`: `${this.currentReport.name()}`);
this.isData= ko.observable(true);
}

parseAgeData(rawAgeData) {
this.ageData(this.parseBoxplotData(rawAgeData).data);
this.ageData(this.parseBoxplotData(rawAgeData)?.data);
}

parseLengthOfEra(rawLengthOfEra) {
Expand All @@ -178,18 +188,26 @@ define([
this.chartFormats.prevalenceByMonth.xScale = d3.scaleTime()
.domain(d3.extent(byMonthSeries[0].values, d => d.xValue));
this.prevalenceByMonthData(byMonthSeries);
} else {
this.prevalenceByMonthData(null);
}
}

parsePrevalenceByType(rawPrevalenceByType) {
if (!!rawPrevalenceByType && rawPrevalenceByType.length > 0) {
this.prevalenceByTypeData(ChartUtils.mapConceptData(rawPrevalenceByType));
} else {
this.prevalenceByTypeData(null);
}
}

parsePrevalenceByGenderAgeYear(rawPrevalenceByGenderAgeYear) {
this.chartFormats.prevalenceByGenderAgeYear.trellisSet = constants.defaultDeciles;
this.prevalenceByGenderAgeYearData(rawPrevalenceByGenderAgeYear);
if (rawPrevalenceByGenderAgeYear) {
this.chartFormats.prevalenceByGenderAgeYear.trellisSet = constants.defaultDeciles;
this.prevalenceByGenderAgeYearData(rawPrevalenceByGenderAgeYear);
} else {
this.prevalenceByGenderAgeYearData(null);
}
}

parseFrequencyDistribution(rawData, report) {
Expand Down Expand Up @@ -223,6 +241,8 @@ define([
const freqHistData = atlascharts.histogram.mapHistogram(frequencyHistogram);
this.frequencyDistributionData(freqHistData);
}
} else {
this.frequencyDistributionData(null);
}
}

Expand Down Expand Up @@ -281,7 +301,7 @@ define([
this.parsePrevalenceByType(data.byType);
this.parsePrevalenceByGenderAgeYear(data.prevalenceByGenderAgeYear);
if (this.byFrequency) {
this.parseFrequencyDistribution(data.frequencyDistribution, this.currentReport.name);
this.parseFrequencyDistribution(data.frequencyDistribution, this.currentReport.name());
}

if (this.byValueAsConcept) {
Expand Down Expand Up @@ -324,6 +344,10 @@ define([
}
}

checkData(data) {
const isData = Object.values(data).find(item => !!item.length);
this.isData(!!isData);
}
getData() {
const response = super.getData();
return response;
Expand All @@ -333,23 +357,29 @@ define([
if (!selectedConcept) {
return;
}
this.conceptId = selectedConcept.concept_id;

this.context.loadingDrilldownDone(false);
this.conceptId = selectedConcept.concept_id !== undefined ? selectedConcept.concept_id : selectedConcept.CONCEPT_ID;
this.currentConcept(selectedConcept);
this.isError(false);
this.getData()
.then((data) => {
this.checkData(data.data);
this.parseData(data);
this.context.loadingDrilldownDone(true);
this.context.showLoadingDrilldownModal(false);
setTimeout(() => document.getElementById('drilldownReport').scrollIntoView(), 0);
if (!this.hideReportName()) {
setTimeout(() => document.getElementById('drilldownReport').scrollIntoView(), 0);
}
})
.catch((er) => {
this.isError(true);
console.error(er);
this.context.loadingDrilldownDone(true);
this.context.showLoadingDrilldownModal(false);
});
}
}

return commonUtils.build('report-treemap-drilldown', TreemapDrilldown, view);
});
return commonUtils.build('report-drilldown', ReportDrilldown, view);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<div class="paddedWrapper">
<access-denied params="isAuthenticated: isAuthenticated, isPermitted: hasRCAccess"></access-denied>
<div class="row">
<div class="col-xs-12">
<select class="form-control" data-bind="options: sources, optionsText: 'sourceName', value: currentSource"></select>
</div>
</div>
<!-- ko if: currentSource() -->
<report-drilldown
params="
currentReport: currentReport,
context: $component,
currentConcept: currentConcept,
currentSource: currentSource,
hideReportName: true,
refreshReport: true"
></report-drilldown>
<!-- /ko -->
</div>
Loading