The purpose of this project is to provide visualizations that will allow a user to understand how various health attributes impact the health of counties across the United States of America (USA). There are three types of visualizations in this project.
Distribution allows the user to compare the grouping of counties for the available attribute values.
Correlation allows the user to examine the relationship between attributes. For example, do counties with a high value for one attribute also have a high value for the other?
Spatial distribution allows the user to see how the attribute values are spread spatially across the USA.
The data used in this project was gathered from the Division for Heart Disease and Stroke Prevention (DHDSP) of the Centers for Disease Control and Prevention (CDC). In particular, the data is from the US Heart and Stroke Atlas. All available data for the following attributes is included for each county in the United States.
Economics
Percent of the population that lives in poverty
Median household income
Percent of the population that did not complete high school
Environment
Air quality
Park access
Behavioral factors of the population
Percent of the population that is inactive
Percent of the population that smokes
Demographics
Percent of the population that is elderly
Status (urban, rural, suburban, small city)
Health care
Number of hospitals
Number of primary care physicians
Percent of the population with no health insurance
Health
Percent of the population with high blood pressure
Percent of the population that has coronary heart disease
Percent of the population that has had a stroke
Percent of the population that has high cholesterol
Before starting to code, I first considered the layout and types of visualizations I wanted to include in my project. The following image is the initial sketch I used to begin implementing this project. The overall layout remained the same after implementation, but it did slightly change to better demonstrate which visualizations are associated with each attribute.
To help make it clear which attributes are in the same or different categories, I chose a specific color group for each attribute category:
Economics (orange)
Percent of the population that lives in poverty (#d49b2a)
Median household income (#b5732b)
Percent of the population that did not complete high school (#cfac38)
Environment (green)
Air quality (#8bbd53)
Park access (#367d3e)
Behavioral factors of the population (purple)
Percent of the population that is inactive (#6539a3)
Percent of the population that smokes (#8c2ed9)
Demographics (pink)
Percent of the population that is elderly (#b8407e)
Status (urban, rural, suburban, small city) (#c447b6)
Health care (blue)
Number of hospitals (#156796)
Number of primary care physicians (#072e73)
Percent of the population with no health insurance (#4650c7)
Health (red)
Percent of the population with high blood pressure (#941038)
Percent of the population that has coronary heart disease (#b5070a)
Percent of the population that has had a stroke (#800f09)
Percent of the population that has high cholesterol (#a12727)
Orange was chosen for economics because of its similarity to gold, which is often related to wealth, and the need for darker colors for visibility. Green was chosen for environment because of the prevalence of green in nature. Blue was chosen for health care because it is a common color used in health care settings. Red was chosen for health because of the color of blood and the fact that many of the attributes are related to blood. The colors for behavioral and demographics were chosen simply because of the colors that remained.Â
Histograms and a bar chart (depending on the value type of the selected attribute) allow the user to compare the grouping of counties for the available attribute values.
For quantitative attribute types, I used histograms. I chose to have the axes start at zero because I didn't want to mislead users if I started at the minimum data value. This is also more of a concern as they choose different attributes. The axes end at the largest data value to help "zoom" the view in so that trends can be better seen.
For the urban/rural status attribute, because it is nominal, I had to create a different visualization type. I chose to use a bar chart due to its similarity with a histogram and the fact that it works well with nominal attribute types. The vertical axis starts at zero and ends at the maximum value for the selected attribute.
Scatterplots were used to allow the user to examine the relationship between attributes. However, since the urban/rural status attribute is nominal, I had to create two types of scatterplots.
For both types of scatterplots, the coloring of the data points is determined by mixing the colors for the two attributes. For example, viewing the percent of the population that hasn't finished high school (orange) and the percent of the population that smokes (purple), the scatterplot data points are a combination of orange and purple, which is a pinkish color (shown below).
As with the histogram, both scatterplot types have axes that start at zero and end at the maximum value for the associated attribute.
To allow the user to see how the attribute values are spread spatially across the USA, I used one choropleth map for each attribute. As shown below, the choropleth map is similar for both quantitative and nominal data values, however, the color scale and associated legend are slightly modified.
The colors range from white to the color associated with the attribute, with the mapping applying from the minimum value to the maximum value.
The status of a county is depicted by the shade of pink used. Darker shades of pink are associated with more densely populated areas.
Two selection elements with options corresponding to the attributes available for each county exist above the visualizations. These dropdowns allow the user to choose which two attributes will be shown in the visualizations. The visualizations on the left side of the screen are associated with the first and left-most dropdown. The visualizations on the right side of the screen are associated with the second and right-most dropdown. The middle visualization, the scatterplot, shows data for both selected attributes.
Anytime the user selects a different attribute, all of the related graphs update to show the new attribute.
The poverty percentage is selected for attribute 1, and the median household income is selected for attribute 2.
The histogram and choropleth map for attribute 1 remained the same, but the other visualizations were updated to display the new attribute 2.
Regardless of the visualization type, a tooltip appears when a data element is hovered over with the mouse. The displayed tooltip shows the relevant data of the hovered element.
The user can brush over any of the visualizations to select data to be displayed on all of the visualizations. Shortly after brushing, all visualizations are updated to only display the counties that were included in the brush selection.
The histogram, bar chart, and connected scatterplot only show the data that is selected so that the counts are updated. The scales of these visualizations update to fit the data in the selection. The standard scatterplot highlights the selected data so that the overall trend is still visible and the axes remain the same. The choropleth maps have the non-selected counties greyed out and the scale remains the same. The option to grey out the non-selected counties was chosen because it highlights the selected counties and removing the non-selected counties would have made the map incomplete.
Within the standard scatterplot and choropleth maps, the brush remains, allowing the user to modify the current brush selection (extend/shrink the brush or move it). The brush is removed from the other visualizations due to the change in axes scales.
To remove the filtering, the user simply needs to click on any visualization outside of the brush area.
All data is displayed. None is filtered or de-emphasized.
The user clicks, drags, and lets go of the mouse to select data.
All visualizations are updated to only show/emphasize the selected data.
There are many different discoveries that a user can make based on which attributes and counties they select. However, see below for a few that I found after creating this project.
There is a positive correlation between the percentage of the population that is elderly and the percentage that has high cholesterol.
The counties with the largest percentage of smokers are in Alaska and South Dakota.
A large majority of the counties are considered rural, with a downward trend toward the urban status.
Unsurprisingly, there is a negative correlation between the percent of the population that did not complete high school and median household income.
Vanilla JavaScript, CSS, and HTML are used to create this project.
D3.js, a JavaScript library for data visualization, is used to create the visualizations for the data. The sixth version is used in this project.
TopoJSON is used to convert the geographical data into the maps for the choropleth maps. The third version is used in this project.
This file contains the initial HTML elements, including the headings, project description, div elements for the visualizations, and the empty select elements. It also loads in the style.css file and the required JavaScript files located within the 'js' directory of the project.
This directory contains the style.css file, which contains styling for all body elements, the layout of the visualizations, tooltips, and the counties on the maps.
This directory contains the counties-10m.json file, which is the geographic data used to generate the maps. It also contains the national_health_data.csv file, which contains the health data for each attribute for each county.
A class for each visualization type is created in a file within the js directory (barchart.js, choropleth.js, connectedScatterplot.js, histogram.js, scatterplot.js). These classes each contain a constructor, a method to initialize the visualization (initVis), a method to update the visualization (updateVis), and a method to filter the data when a selection is made with brushing (filterBySelection).
The d3.v6.min.js and topojson.v3.js files are for D3 and TopoJSON respectively.
The main.js file is responsible for the following:
Loading and processing the data
Adding options to the select elements for choosing attributes
Updating the visualizations when the data is filtered or a different attribute is selected
Creating the visualization objects from the classes
This project is deployed at https://data-vis-project-1.netlify.app/. The code is available at https://github.com/egardner2019/DataVisProject1. Instructions for running the code locally are available in the Readme file in GitHub.
There was certainly a learning curve with this project. Although I have experience with JavaScript, HTML, and CSS, I had not worked with D3 before this project. After better understanding the use of the .join() method and the general structure of generating the visualizations, I found it easier to create classes for another visualization type.
There was one feature in particular that I have not been able to figure out; this relates to the use of tooltips and brushing together. I wanted to provide a way for the user to see a tooltip when hovering over the data elements (bars, points, counties) and see the brush selection on top of the data when they click and drag. Unfortunately, the only way I was able to provide brushing and the tooltips together was to place the brushing layer behind the data elements. This means that, when the brush is used, the selection appears behind the data elements. This is especially a problem when brushing in the middle of a choropleth map. Although the brushing works, the user cannot see the selection until the map updates after the user releases the mouse to end the brushing. I spent hours trying to find a solution online without any luck. I hope that, as I work on future D3 projects, I will find a solution to this problem.