Skip to content

Commit

Permalink
Daily deceased by age groups no longer show age groups that have no d…
Browse files Browse the repository at this point in the history
…eceased (#770)
  • Loading branch information
breki committed Dec 26, 2020
1 parent 6e06a82 commit f53d441
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 25 deletions.
5 changes: 4 additions & 1 deletion TODO.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
# TODO

- https://github.com/sledilnik/website/issues/770
- remove age groups that don't have any deceased
- remove animations
- add relative page
- add translations for page switches
- try using different colors

- new OWID export
- return back the official URL, once it has been pushed to production
Expand Down
68 changes: 48 additions & 20 deletions src/visualizations/DataAnalysis/AgeGroupsTimeline.fs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ type CasesByAgeGroupsForDay = AgeGroupsList

type CasesByAgeGroupsTimeline = DatedArray<AgeGroupsList>

/// Calculates the difference of total cases by age groups between two
/// consecutive days which represents new cases by age groups.
let calcCasesByAgeForDay
(prevDay: AgeGroupsList option)
(currentDay: AgeGroupsList): AgeGroupsList =
Expand Down Expand Up @@ -49,7 +51,9 @@ let calcCasesByAgeForDay
// and calculate the difference
|> List.map (fun ageGroup -> calcAgeGroupDiff prevDayGroups ageGroup)

let calculateCasesByAgeTimeline
/// Converts total cases by age groups timeline into daily new cases by
/// age groups timeline.
let calculateDailyCasesByAgeTimeline
(totalCasesByAgeGroups: CasesByAgeGroupsTimeline)
: CasesByAgeGroupsTimeline =

Expand All @@ -65,11 +69,16 @@ let calculateCasesByAgeTimeline
)
|> not

// converts AgeGroupsList array to an array of options, with None as
// the first value in the array. We need this so we can apply pairwise
// function below.
let totalCasesTimelineArray: AgeGroupsList option[] =
Array.append
[| None |]
(totalCasesByAgeGroups.Data |> Array.map Some)

// converts the array of total AgeGroupsList values into diffs, which
// represent daily new cases
let newCasesTimelineArray =
totalCasesTimelineArray
|> Array.pairwise
Expand Down Expand Up @@ -103,14 +112,17 @@ type CasesInAgeGroupSeries = {

type ValueCalculationFormula = Daily | Active | Total

/// Calculates the timeline for an age group specified by its index.
/// The source data is the timeline of all age groups.
/// The metric/value of the timeline is defined by the calculation formula.
let extractTimelineForAgeGroup
ageGroupKey
(calculationFormula: ValueCalculationFormula)
(casesTimeline: CasesByAgeGroupsTimeline)
(allAgeGroupsTimeline: CasesByAgeGroupsTimeline)
: CasesInAgeGroupTimeline =

let newCasesTimeline =
casesTimeline
allAgeGroupsTimeline
|> mapDatedArrayItems (fun dayGroupsData ->
let dataForGroup =
dayGroupsData
Expand All @@ -129,19 +141,23 @@ let getAgeGroupTimelineAllSeriesData
(statsData: StatsData)
(valueCalculationFormula: ValueCalculationFormula)
(pointAgeGroupListSelector: StatsDataPoint -> AgeGroupsList) =
// extract just a list of date + AgeGroupsList tuples
let totalCasesByAgeGroupsList =
statsData
|> List.map (fun point -> (point.Date,
point |> pointAgeGroupListSelector))

// convert to DatedArray that has just a start date
// and an array of AgeGroupsList values
let totalCasesByAgeGroups =
mapDateTuplesListToArray totalCasesByAgeGroupsList

// calculate complete merged timeline
let timeline = calculateCasesByAgeTimeline totalCasesByAgeGroups
// converts total new cases to daily cases
let dailyCasesTimeline =
calculateDailyCasesByAgeTimeline totalCasesByAgeGroups

// get keys of all age groups
let allGroupsKeys = listAgeGroups timeline
let allGroupsKeys = listAgeGroups dailyCasesTimeline

let mapPoint
(startDate: DateTime)
Expand All @@ -160,21 +176,33 @@ let getAgeGroupTimelineAllSeriesData
let timelineArray = groupTimeline.Data

timelineArray
|> Array.mapi (fun i cases -> mapPoint startDate i cases)
|> Array.mapi (mapPoint startDate)

allGroupsKeys
|> List.mapi (fun index ageGroupKey ->
let points =
timeline
let renderAgeGroupSeriesMaybe index ageGroupKey =
let ageGroupTimeline =
dailyCasesTimeline
|> extractTimelineForAgeGroup ageGroupKey valueCalculationFormula
|> mapAllPoints

pojo {|
``type`` = "column"
visible = true
name = ageGroupKey.Label
color = AgeGroup.ColorOfAgeGroup index
data = points
|}
)
// if the timeline has just zero values, we will skip it so it doesn't
// show up in the chart
let hasAnyNonZeroValues =
ageGroupTimeline.Data |> Array.exists (fun value -> value > 0)

if hasAnyNonZeroValues then
let points = ageGroupTimeline |> mapAllPoints

pojo {|
``type`` = "column"
visible = true
name = ageGroupKey.Label
color = AgeGroup.ColorOfAgeGroup index
data = points
|} |> Some
else
None

allGroupsKeys
|> List.mapi renderAgeGroupSeriesMaybe
// skip series which do not have any non-0 data
|> List.choose id
|> List.toArray
2 changes: 1 addition & 1 deletion src/visualizations/DeceasedViz/Rendering.fs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ let availablePages = [|
MetricsType = HospitalsToday; ChartType = StackedBarNormal }
{ Id = "deceasedTodayRelative"
MetricsType = HospitalsToday; ChartType = StackedBarPercent }
{ Id = "deceasedToDateByAge"
{ Id = "deceasedTodayByAge"
MetricsType = ByAgeToDate; ChartType = StackedBarNormal }
|]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ let ``Can calculate timeline``() =
Data = [| onDay0; onDay1; onDay2 |]
}

test <@ calculateCasesByAgeTimeline sourceData = expectedTimeline @>
test <@ calculateDailyCasesByAgeTimeline sourceData = expectedTimeline @>

[<Fact>]
let ``Filters out leading and trailing days without any cases``() =
Expand Down Expand Up @@ -97,4 +97,4 @@ let ``Filters out leading and trailing days without any cases``() =
Data = [| onDay0; onDay1; onDay2 |]
}

test <@ calculateCasesByAgeTimeline sourceData = expectedTimeline @>
test <@ calculateDailyCasesByAgeTimeline sourceData = expectedTimeline @>
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ let ``Can fetch age groups from timeline``() =
Data = [| totalDay0; totalDay1 |]
}

let timeline = calculateCasesByAgeTimeline sourceData
let timeline = calculateDailyCasesByAgeTimeline sourceData

let ageGroupsKeys = listAgeGroups timeline

Expand Down

0 comments on commit f53d441

Please sign in to comment.