-
Notifications
You must be signed in to change notification settings - Fork 1
Development tips: Reports
Here are some tips for creating a new report type, based on the architecture used for the Enrollment Bar Chart.
Data flow for creating a report:
- User submits a form, filling out the fields from
ChartFormFields.jsx(viaEditReport.react.js). - The form fields are sent with a
POSTrequest to the/api/v1/reportsAPI route. - The form fields are inserted into the MongoDB database
dpdmongoin the collectionreports.
If a new chart type is added, it should be added to this list, or if it is already in the list, the disabled prop should be removed from it.
Additionally, we have provided a form field that is currently unused, called variableMulti. It was intended to be used for the category-line chart type. However, as written, it will only work if there is only one assessment and all variables are in that assessment. If it needs to pull variables from more than one assessment, it will need to be rewritten, perhaps more like the valueLabels fields.
Reports are stored in MongoDB according to the following structure:
{
_id: String, // MongoDB ObjectId for the report
reportName: String, // Report title
user: String, // User ID of the creator
readers: Array<String>, // Array of user IDs for sharing
created: Date, // Date the report was created
charts: [ // An array of chart objects, which may be empty or contain empty fields
{
title: String, // The title of the chart
chartType: String, // The type of the chart (e.g. "bar")
variableSingle: String, // A single variable name (for multi-site charts)
variableMulti: Array<String>, // An array of variable names (for single-site charts)
assessmentSingle: String, // The name of the assessment containing the above variable(s)
valueLabels: [ // An array of value/label mappings
{
value: String, // A single value/range, or a list of comma-separated values/ranges
label: String, // The label for the value(s)
},
...
]
},
...
]
}Data flow for viewing a report:
- User selects a study or studies on
Report.react.jsand clicks "Generate report". - A
GETrequest is sent to/api/v1/reports/:idfor each chart via the functionfetchDataForChart. - If there are
valueLabelsin the returned data, raw data values will be replaced with the labels via the functionparseValueLabels. - The returned data is pushed as a new object containing
{ title, data }to thethis.state.chartsarray. - Each of those objects is passed to the
Chart.jsxdisambiguation component. - Depending on the chart type, a different component will be returned. So far, only
EnrollmentBarChart.jsxhas been programmed. That component will determine how data will be parsed and displayed.
If you are adding a chart type that is not bar, study-line, or category-line, it will need to be added to this if block in fetchDataForChart.
You will also need to create a new component along the lines of EnrollmentBarChart.jsx for any new chart type and add it to Chart.jsx.
The main library used for the Enrollment Bar Chart is called Recharts. Recharts has very good documentation, so it's not necessary to expand much further here.
For generating an arbitrary number of distinct colors for the chart, we have used a small library called distinct-colors with these settings.
Currently, fetchDataForChart returns data in the following format:
[
{
date: "2021-06-24",
study: "FAKE_2",
value: "White",
varName: "chrdemo_racial_background",
},
...
]Note that the value field, which was originally a number, has been replaced with the label "White" by parseValueLabels.
Note also that date here refers to the consent date, because this is data for the Enrollment Bar Chart. But if the same data structure is reused for another chart type that does not deal strictly with enrollments, it could refer to the date of data collection or entry.
For the Enrollment Bar Chart, we process the data like this:
- Determine all unique values in the array for the
valuefield and map each to a distinct color via the functiongetGroupings - For each unique value in the array for the
studyfield, count the total number of entries via the functiongetChartDataForStudy - Also for each
study, count the number of entries for each uniquevaluewithin that study via the functiongetCounts - Create an entry on the X-axis for each unique
study - For each entry on the X-axis, create a vertically-stacked bar for each unique
value - Display a label for each
valuewith the percentage out of the total enrollment for that study
You may want to make the sizing and margins of the chart dependent on the number of sites visualized rather than hard-coded.
Note also that one caveat to Recharts is that all of its positioning is relative, and it doesn't easily allow use of CSS helpers like Flexbox or Grid.