Skip to content

Commit

Permalink
Merge pull request #67 from UBC-MDS/milestone4-maile
Browse files Browse the repository at this point in the history
  • Loading branch information
rissangs authored Feb 6, 2021
2 parents f22cc16 + 193599c commit ae2e354
Show file tree
Hide file tree
Showing 8 changed files with 153 additions and 61 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# COVID-19 Data Portal

## About
The goal of this repository is providing COVID-19 statistics by using <a href=https://github.com/plotly/dash>Dash</a> and <a href=https://github.com/python>Python</a>.

The COVID-19 Data Portal live dashboard can be accessed <a href=https://covid-data-portal.herokuapp.com/>here</a>
The goal of this repository is providing COVID-19 statistics by using [Dash](https://github.com/plotly/dash) and [Python](https://github.com/python).

The COVID-19 Data Portal live dashboard can be accessed [here](https://covid-data-portal.herokuapp.com).

## Description

Expand All @@ -13,11 +14,10 @@ On the left side of the dashboard, the user can view the world cases trend for r

On the right side of the dashboard, the country level statistics can be seen in both number format and trend-line format. By default, the user will see Canada's (based on locale) statistics when opening the dashboard. Users can also opt for other region's statistics by selecting from the drop-down menu to view both the case summary and the trend line.

## Dashboard Demo
## Dashboard

![](docs/images/dash-demo.gif)


### Build the dashboard locally

**Step 1: Clone this repository**
Expand All @@ -26,7 +26,7 @@ On the right side of the dashboard, the country level statistics can be seen in

Create and activate a conda environment using the env.yaml at the root of this project by running the following command at the root directory of the project. (Alternatively, you can manually install the dependencies listed in the env.yaml file)

```bash
``` {.bash}
conda env create --file env.yaml
conda activate covid_dash
```
Expand All @@ -35,7 +35,7 @@ Go to the root folder of the repo and execute `python src/python/app.py`

## License

The COVID-19 Data Portal materials here are licensed under the Creative Commons Attribution 2.5 Canada License (CC BY 2.5 CA). If re-using/re-mixing please provide attribution and link to this webpage.
- The COVID-19 Data Portal materials here are licensed under the Creative Commons Attribution 2.5 Canada License (CC BY 2.5 CA). If re-using/re-mixing please provide attribution and link to this web page.

## References

Expand Down
62 changes: 40 additions & 22 deletions docs/reflection-milestone4.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,47 @@
# Reflection
## Progress of the dashboard:
We have managed to achieve all the functionalities as we designed in our initial proposal. In this milestone, we have attempted to cover most of the high and middle priority feedback coming from the TA, Joel, and our peers. The main improvements have been listed as follow:
- As instructed by the TA from the <a href=https://github.com/UBC-MDS/DSCI_532_Group_12/issues/44>feedback</a>, we filled the middle panel with another new cases per day trendline which can be controled by the buttons in the middle panels to switch the cases type. This change filled up most of the spacing in the bottom of the dashboard, which rendered the layout more balanced.
- We also rescaled the middle panel map size and adjusted the bubble sizes, so that users can gain more information from the visualization. Especially for countries with smaller amount of cases, their bubbles can be more representative.
- We removed the scrolling bar from the left panel and resized the graph to provide the users with better a user experience. In addition, the total cases count has also been added to on the left panel to give the users more information.
- We adjusted the layout slightly for the right panel to make it less compact.
- The updated time has been added at the very bottom of the page following Joel's suggestion.

## Progress of the dashboard

We have managed to achieve most of the functionalities designed in our initial proposal. In this milestone, we have attempted to cover most of the high and medium priority feedback coming from the TA, Joel, and our peers.

The main improvements are listed as follow:

- As recommended by our TA's [feedback](https://github.com/UBC-MDS/DSCI_532_Group_12/issues/44), a line graph showing new cases trend is added to the middle panel. This change fills up most of the space under the world map, which makes the layout more balanced

- We adjusted the scale of the bubbles showing number of cases on the world map to highlight better the difference of Covid-19's impact among countries

- We removed the scroll-bar from the bar chart ranking Top 30 countries and added global statistics to the left panel

- We added some spacing among rows of component on the right panel per Joel's feedback

- A time-stamp showing the last updated date of the data is added

Up to this release, our panel should have the following functionalities:
The left panel contains a statistic summary and a bar chart which shows the user the ranking of case count by country with the button for user to choose if they want to see (Confirmed Cases, Active Cases, Recovered Cases or Deaths).

In the middle panel, the user could surface the distribution of the cases geographically in a map, with the options to choose confirmed cases, death cases, or recovered cases. The user can also check new cases per day for each categories from this categories.
- The left panel (Global) contains global statistics and a ranking bar chart which shows Top 30 countries most affected by the pandemic

- The middle panel (World Map) illustrates the case distribution geographically across the world and a line graph showing new cases trend

- The right panel shows a country's summary statistics and trends per user selection

## Development Discussion

There are some improvement opportunities acknowledged but delayed to future development due to the time constraint of this milestone, those can be found below.

- **New features with substantial development effort**

- Allow user to select a time frame for viewing data: it requires changes both to our data access and UI layers

- Allow user to switch between total case and case per population: this requires using another data set to get world population, changes to our data access and UI layers

- Allow interaction between panels: selecting a country in the world map/selecting a country from the world ranking will display its statistics on the right panel

- **Persistent layout issues without a technical proper solution**

- Horizontal scroll-bar is still displayed when displaying the dashboard on 1920x1080 screen: we tried applying `overflow:hidden` but it will always disable using scroll-bar for all components

In the right panel, the user can check the detailed trend by country and category. Meanwhile, the right panel also shows the user how many cases in the selected category each country currently have.
## Development Discussion
Due to the time constraint of the implementation for this milestone, we have prioritized the tasks to implement by their complexity, development efforts, benefits and demand rationality. During the implementation, it's been acknowledged by our team that customizing the CSS for some details has been tricky in python with dash library. That's why we haven't completed some of the UI enhacement tasks which couldn't bring about significant benefits from the UX perspective. We also found some potential improvements are complex due to the nature of our source data, as we have to refactor the code substantially to create a toggle button or a slide bar.
- **Small UI improvements suggested by our peer but not implemented**

***Below we have categorized what we have left by why we didn't choose to do it:***
- Change color palette for different types of case (confirmed, death, recovered): we find our current color scheme (creme, red, white, black, gray) reflect well the situation of the pandemic

- Relatively low benefits added with high development efforts
- Allow filtering by time frame for charts to show trends. (This task will need significant amount of effort to refactor the code for the data model, which is also out of the scope of our initial proposal)
- Technically complicated
- Add interaction between the left panel and middle panel. (As the left panel and middel panel were implemented seperately and they were different classes from higher level, it's technically hard to make them interactive without refactor the code extensively at this stage.)
- Add a toggle button to switch between cases number and cases per population density. (We had problem looking for a reliable population data that can be merged to our COVID data easily. This will also create a substantial amount of code change that can hardly be done within the given time.)
- Previously we thought we should have make the dashboard responsive, however this change can be relatively hard to achieve given the framework we are using and the time constraint.
- Not bring about many benefits with low priority
- Our peers suggested changing the color palettes for all panels, but it's really hard to tell as people all have different views on design of color.
- Our team also considered to cache the `.csv` file instead of load it everytime from John Hopkins Repository, but we haven't got time to refactor this code yet. This might be very minor in terms of affecting the usage of the dashboard.
- Highlight selected buttons: the buttons are currently wrapped by boxes around them, changing css style of those buttons will make the code more complicated to maintain as there is no easy way to do it but addressing that within callback methods (which are already quite complex)
Binary file modified src/python/__pycache__/data_model.cpython-39.pyc
Binary file not shown.
39 changes: 28 additions & 11 deletions src/python/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,28 @@
map_panel = mid_panel(data_reader)
alt.themes.enable("ggplot2")
app.title = "Covid-19 Data Portal"
dashboard_heading = (
"Covid-19 Data Portal"
)
dashboard_heading = "Covid-19 Data Portal"
last_updated = "Last Updated: " + data_reader.last_updated.strftime("%m/%d/%Y")
app.layout = dbc.Container(
[
dbc.Row(dbc.Col(html.Div([html.H1(dashboard_heading)]), className="heading")),
dbc.Row(
[

[
html.Div(
dashboard_heading,
style={
"font-size": "30pt",
"text-align": "center",
"left": "0%",
"right": "0%",
},
),
html.Div(className="space"),
html.Div(last_updated, style={"font-size": "14pt", "right": "0px"}),
],
className="heading",
),
dbc.Row(
[
dbc.Col([global_panel.render()], width=3, className="left_panel"),
dbc.Col([map_panel.render()], width=6, className="panel"),
dbc.Col(
Expand All @@ -55,13 +68,14 @@
),
],
),
dbc.Row(dbc.Col(html.Div([html.H4("Data Last Updated: " + data_reader.last_updated.strftime("%m/%d/%Y"))]), className="footer")),
],
fluid=True,
style={"border-width": "0",
"width": "100%",
"height": "100%"}

style={
"border-width": "0",
"width": "100%",
"height": "100%",
"overflow-x": "hidden",
},
)

# endregion
Expand All @@ -78,6 +92,7 @@
Input("rp_btn_new", "n_clicks"),
)
def update_right_panel(country, total_click, new_click):
"""update the right panel when changes triggered by its controls"""
ctx = dash.callback_context
if not ctx.triggered:
ntype = "Total"
Expand All @@ -101,6 +116,7 @@ def update_right_panel(country, total_click, new_click):
Input("btn_recovered", "n_clicks"),
)
def update_left_panel(active, confirmed, death, recovered):
"""update all components on the left panel upon callback"""
ctx = dash.callback_context
if not ctx.triggered:
ctype = "confirmed"
Expand All @@ -126,6 +142,7 @@ def update_left_panel(active, confirmed, death, recovered):
Input("wm_recovered", "n_clicks"),
)
def update_mid_panel(confirmed, death, recovered):
"""update all controls on mid panel upon callback"""
ctx = dash.callback_context
if not ctx.triggered:
ctype = "confirmed"
Expand Down
26 changes: 17 additions & 9 deletions src/python/assets/css/covid-dash.css
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,14 @@
}

.heading{
text-align: center;
background-color: black;
color:white
color:white;
place-items: center;
place-content: center;
}

.footer{
text-align: center;
background-color: white;
color:black
}

.h2{
Expand All @@ -41,8 +40,17 @@
text-align: center;
}

.body {
overflow: hidden; /* Hide scrollbars */
width: 100%,
height: 100%
}
body {
width: 100%;
height: 100%;
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}

.space{
width:50px
}

body::-webkit-scrollbar {
display: none;
}
25 changes: 23 additions & 2 deletions src/python/components/left_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@


class left_panel(panel):
"""handle all activities of the left panel"""

def __init__(self, datamodel):
super().__init__("Global", datamodel)

Expand All @@ -34,7 +36,7 @@ def __init__(self, datamodel):
id="chart_cases_ranking",
style={
"border-width": "0",
"width": "300px",
"width": "450px",
"height": "800px",
},
)
Expand Down Expand Up @@ -76,6 +78,11 @@ def refresh(self, chart_type="confirmed"):
return chart

def __create_button_groups(self):
"""create buttons Confirmed/Death/Recovered/Active
Returns:
dbc.ButtonGroup
"""
button_groups = dbc.ButtonGroup(
[
dbc.Button("Confirmed", active=True, id="btn_confirmed"),
Expand All @@ -89,6 +96,11 @@ def __create_button_groups(self):
return button_groups

def __create_total_statistics(self):
"""retrieve global statistics
Returns:
html: all statistics
"""
data = self.data_reader.cumulative_filter()
confirmed_cases = panel.format_number(data.Confirmed)
active_cases = panel.format_number(data.Active)
Expand All @@ -106,13 +118,22 @@ def __create_total_statistics(self):
return content

def __create_ranking_bar_chart(self, data, type):
"""create bar chart to rank countries by case type
Args:
data (dataframe): dataset
type (string): "confirmed", "death", "recovered
Returns:
altair barchart
"""
chart = (
alt.Chart(
data,
title=alt.TitleParams(
text="Top 30 Countries", subtitle="By " + type + " Cases"
),
width=130
width=290,
)
.mark_bar()
.encode(
Expand Down
13 changes: 7 additions & 6 deletions src/python/components/mid_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@


class mid_panel(panel):
"""handle all activities related to world map panel"""

def __init__(self, datamodel):
super().__init__("World Map", datamodel)

Expand Down Expand Up @@ -92,11 +94,11 @@ def refresh(self, chart_type="confirmed", ntype="Total"):
return world_map, trend_chart

def __create_button_groups(self):
"""Create button
"""Create button
Returns:
buttons for three cases
"""
"""
button_groups = dbc.ButtonGroup(
[
dbc.Button("Confirmed", active=True, id="wm_confirmed"),
Expand Down Expand Up @@ -125,7 +127,7 @@ def __create_world_map_chart(self, data, type):
base = (
alt.Chart(source, title="")
.mark_geoshape(fill="lightgray", stroke="white")
.properties(width=860, height=450 )
.properties(width=860, height=450)
.project("equirectangular")
# .padding({"left": 0, "right": 0, "bottom": 1, "top":1})
)
Expand All @@ -151,9 +153,8 @@ def __create_world_map_chart(self, data, type):
)

chart = base + points
chart = (
chart.configure_legend(orient="bottom")
.configure_view(strokeWidth=0, )
chart = chart.configure_legend(orient="bottom").configure_view(
strokeWidth=0,
)

return chart.to_html()
Expand Down
Loading

0 comments on commit ae2e354

Please sign in to comment.