Visualization Build Code - reichlab/covid19-forecast-hub GitHub Wiki

Navigating this Page

Visualization Code Description

Debugging the Visualization

Editing the Visualization D3

Visualization Code Description

The visualization can be built with these commands. This page will do a deeper-dive into the visualization build code.

1. bash ./0-init-vis.sh

npm run test

Then, the testing script above, which can be found in ./visualization/scripts/test-data.js, is run. This script iterates through every metadata file and checks if the metadata files are present and readable. This test is somewhat redundant because we already have these validation checks in place. However, validation checks use pyyaml and this script double check readability with js-yaml. Note that this script is the same as mocha ./scripts/test-data.js -R min.

npm run parse-data

This script begins the data wrangling process to reformat forecasts to the visualization JSON. It creates a new ./data folder in the ./visualization directory. In the ./data directory, there are two sub directories: Cumulative Deaths and Incident Deaths. The contents of directories are identical (for now). Each directory has a bunch of folders with different models. The name format for the model folders is TeamAbbr-ModelAbbr found directly in the model's metadata. The metadata.txt contains each model's name (full name), description (from methods in the metadata file), and url. The forecasts for each model are named in the format YYYYEW.csv where YYYY is forecast year and EW is the current epidemiological week. All renaming is executed automatically with this script.

python3 ./scripts/convert-forecasts.py

This script loops through all of the forecasts in the ./visualization/data directory and converts them into the proper csv format for the visualization. The script filters out locations that are not able to be visualized, filters out unneeded targets, includes only the 50% and 95% confidence intervals (quantiles: 0.025, 0.25, 0.75, 0.975), renames, and reorders the columns.

# Get truth data
cd ../data-truth
python3 ./get-truth-data.py
cd ../visualization

This script gets the truth data from JHU csv. More information on this script can be found here.

# Replace already present data
rm -rf ./vis-master/data
mv ./data ./vis-master

These commands replaces the ./vis-master/data directory with the new data in ./visualization/data. All other visualization code will be executed in ./vis-master.

cd ./vis-master
npm run parse-viz-master # Parse visualization data to json

This script ultimately parses through the ./vis-master/data to create these visualization data These JSONs are the data that are rendered in the D3 visualization. Here are the high-level steps of this script:

  1. ./vis-master/scripts/parse.js is executed
    • creates ./src/assets/data/metadata.json which is used to configure the visualization config. It is not pushed to github.
  2. node scripts/parse-season.js Cumulative Deaths is executed
  3. node scripts/parse-season.js Incident Deaths is executed.
  4. The visualization is now ready to view locally. This is the end of bash ./0-init-vis.sh.

2. bash ./2-mac-build-vis.sh

This script is much simpler. It does some last formatting updates, and then builds the visualization with web pack. Thankfully, this script never fails if bash ./0-init-vis.sh runs correctly with the proper data.

# Change branding and metadata of website
cp ./config.yaml ./vis-master/config.yaml

This script changes some of the branding on the website, for example the website title and description.

# Clean footer
sed -i "" '/.modal#dis/,/footer.modal-card/d' ./src/components/Foot.vue
sed -ni "" '/and dis/{s/.*//;x;d;};x;p;${x;p;}' ./src/components/Foot.vue
sed -i "" '/let showModa/,/})$/d' ./src/components/Foot.vue

# Clean navbar
sed -i "" '/a($/,/logo")$/d' ./src/components/Navbar.vue
sed -i "" '/padding-left/,/border-left-width/d' ./src/components/Navbar.vue
sed -i "" '/href="branding.tweetUrl"/,/span Tweet/d' ./src/components/Navbar.vue
sed -i "" 's/span.brand.title-text {{ branding.title }}/a.brand.title-text(v-bind:href="branding.parentUrl") {{ branding.title }}/'\
    ./src/components/Navbar.vue

These scripts make minor updates to the footer and navbar of the visualization.

npm run build

This builds the website with node --max_old_space_size=6000 build/build.js. This build bundles scripts with webpack. The final visulization files are all in ./vis-master/dist. You can locally host the site by navigating to this directory and running a localhost server of your choice (I like using live-server).

Debugging the Visualization

The first place to look in any visualization bugs is the data itself. The issues is most likely not a D3 issue unless the D3 code has been recently changed. Here are some common errors that may occur with the visualization data.

Model does not show in the legend

This is most likely because it was previously removed with the rm -r ./data/Cumulative\ Deaths/Team-Model remove statements in bash ./0-init-vis.sh. Check if this is the case.

Model shows in legend but is always greyed out

  • Make sure that the model has the target (1/2/3/4 wk ahead cumulative/incident deaths), location (some models only forecast one state), and quantile (0.025, 0.25, 0.75, 0.975, and point) that you are trying to visualize in it's raw data in the ./data-processed folder.
  • Check the visualization data by looking into the forecasts in the ./vis-master/data folder
  • If the ./data-processed forecasts have the expected forecast but the ./vis-master/data forecasts do not, double check the filtering is working correctly in python3 ./scripts/convert-forecasts.py
  • Make sure you are looking at the correct epiweek. See below note on epiweeks.

The forecast is not lining up with the correct epiweek.

Make sure you have a good understanding of how we determine which forecast is a part of which epiweek.

  • If the forecast is made Tuesday of last week - Monday of this week: It is for this epiweek
  • If the forecast is made Tuesday of this week - Monday of next week: It is for next epiweek

Overall, we have a strict Monday cutoff for all forecasts visualized for this week.

A new model came in and suddenly the visualization went blank

Make sure the model has point values. Also, make sure the new model does not take on the same name/abbreviation as any other model. This SHOULD be validated, but perhaps something slipped under the cracks. Forecasts with no explicit point values or duplicate names/abbreviations will completely break the visualization.

Model keeps changing color and placement in legend

This is a known bug. Would be a good issue for future work.

Model name or abbreviation on legend is "NaN"

This means the metadata foes not have the correct model name and model abbreviation fields. Double check the model metadata.

Editing the Visualization D3

The visualization was build with D3.js.

The D3 code is broken up into two parts:

  1. covid-d3-foresight - main code for the time series visualization
  2. ./vis-master/src - main code for the choropleth and rendered views. This uses components from covid-d3-foresight to build the views.

Specifically, these are the objects imported from covid-d3-foresight

import {
  TimeChart,
  DistributionChart, # this isn't really used
  events
} from '../../covid-d3-foresight/dist/d3-foresight'

Editing covid-d3-foresight

If a change needs to be made to covid-d3-foresight, you must first make the change and then re-build the library with these commands:

cd ./vis-master/covid-d3-foresight
npx webpack --config webpack.config.js

Then, the changes will be reflected on the visualization dev server.

Debugging the visualization with a dev server

To be able to see all of your console.log statements and have a live-reload of edits, do this command:

cd ./vis-master
npm run dev