Skip to content

Commit

Permalink
#606: merge from master
Browse files Browse the repository at this point in the history
  • Loading branch information
breki committed Oct 24, 2020
1 parent 66f6e25 commit 9d79238
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 37 deletions.
4 changes: 2 additions & 2 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# TODO

- https://github.com/sledilnik/website/issues/606
- how is doubling calculated?
- see municipalities
- calculate doubling time of active cases
- use this value to show the projection
- show previous week, current, next 7, 14 days


Expand Down
2 changes: 1 addition & 1 deletion src/locales/sl.json
Original file line number Diff line number Diff line change
Expand Up @@ -780,7 +780,7 @@
"oneDay": "En dan",
"oneWeek": "En teden",
"oneMonth": "En mesec",
"ifExpGrowth": "Če bi primeri naraščali eksponentno s podvajanjem na 7 dni, potem bi lahko pričakovali:",
"ifExpGrowth": "Če bi se okužba širila eksponentno s takšnim podvajanjem, kot je sedaj (na {0} dni), potem bi lahko pričakovali:",
"today": "Danes",
"inOneWeek": "Čez en teden",
"inTwoWeeks": "Čez dva tedna",
Expand Down
2 changes: 1 addition & 1 deletion src/visualizations/MunicipalitiesChart.fs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ let init (queryObj : obj) (data : RegionsData) : State * Cmd<Msg> =
if activeCases.IsSome && activeCases.Value >= 5
then
dp
|> Seq.map (fun dp -> {| Date = dp.Date ; Value = dp.ActiveCases |})
|> Seq.map (fun dp -> (dp.Date,dp.ActiveCases))
|> Seq.toList
|> Utils.findDoublingTime
else None
Expand Down
87 changes: 62 additions & 25 deletions src/visualizations/SpreadChart.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module SpreadChart

open System
open Elmish
open Fable.Core
open Feliz
open Feliz.ElmishComponents
open Browser
Expand Down Expand Up @@ -213,7 +214,21 @@ let renderChartOptions scaleType state dispatch =
|}

let renderExplainer (data: StatsData) =
let curPositive, curHospitalized =
// calculate the current doubling time

// get the array of active cases by days
let activeByDays =
data
|> List.map(fun dp -> (dp.Date, dp.Cases.Active))

let currentDoublingTime = activeByDays |> Utils.findDoublingTime

let multiplicationForDaysFromNow daysFromNow =
match currentDoublingTime with
| Some doublingTime -> Math.Pow(2., daysFromNow / doublingTime) |> Some
| None -> None

let curActive, curHospitalized =
data
|> List.rev
|> List.choose (fun dp ->
Expand All @@ -224,32 +239,57 @@ let renderExplainer (data: StatsData) =
|> List.head
|> fun (p, h) -> (p,h)

let box (title: string) doublings positive hospitalized =
Html.div [
prop.className "box"
prop.children [
Html.h3 title
Html.p [
match doublings with
| 0 -> ""
| _ ->
let times = 1<<<doublings
let timesAsManyText = chartText "timesAsMany"
sprintf "%d%s" times timesAsManyText
|> Html.span
let box (title: string) weekFromNow =
let multiplication =
weekFromNow * 7
|> float
|> multiplicationForDaysFromNow

match multiplication with
| Some multiplication ->
Html.div [
prop.className "box"
prop.children [
Html.h3 title
Html.p [
match weekFromNow with
| 0 -> ""
| _ ->
let timesAsMany = multiplication - 1.
let timesAsManyRounded =
timesAsMany
|> Utils.formatTo1DecimalWithTrailingZero
let timesAsManyText = chartText "timesAsMany"
sprintf "%s%s" timesAsManyRounded timesAsManyText
|> Html.span
]

let activeCasesProjection =
(float curActive * multiplication)
|> Math.Round
|> int

let hospitalizedCasesProjection =
(float curHospitalized * multiplication)
|> Math.Round
|> int

Html.div [ Html.h4 (string activeCasesProjection)
Html.p (chartText "activeCases") ]
Html.div [ Html.h4 (string hospitalizedCasesProjection)
Html.p (chartText "hospitalized") ]
]
Html.div [ Html.h4 (string positive)
Html.p (chartText "activeCases") ]
Html.div [ Html.h4 (string hospitalized)
Html.p (chartText "hospitalized") ]
]
]
| None -> Html.div []

Html.div [
prop.className "exponential-explainer"
prop.style [ (Interop.mkStyle "width" "100%"); style.position.absolute ]
prop.children [
yield Html.h1 (chartText "ifExpGrowth")
let explanationTextFormat = chartText "ifExpGrowth"
let explanationText =
String.Format(explanationTextFormat, currentDoublingTime)
yield Html.h1 explanationText
yield Html.div [
prop.className "container"
prop.children [
Expand All @@ -259,11 +299,8 @@ let renderExplainer (data: StatsData) =
chartText "inTwoWeeks", 2
chartText "inThreeWeeks", 3
chartText "inFourWeeks", 4 ]
|> List.map (fun (title, doublings) ->
box title doublings
(curPositive <<< doublings)
(curHospitalized <<< doublings)
)
|> List.map (fun (title, weekFromNow) ->
box title weekFromNow)
]
]
]
Expand Down
19 changes: 11 additions & 8 deletions src/visualizations/Utils.fs
Original file line number Diff line number Diff line change
Expand Up @@ -66,22 +66,25 @@ let calculateDoublingTime (v1 : {| Day : int ; PositiveTests : int |}) (v2 : {|
if value < 0.0 then None
else Some value

let findDoublingTime (values : {| Date : DateTime ; Value : int option |} list) =
let findDoublingTime (values: (DateTime * int option) list) =
let reversedValues =
values
|> List.choose (fun dp ->
match dp.Value with
|> List.choose (fun (date, value) ->
match value with
| None -> None
| Some value -> Some {| Date = dp.Date ; Value = value |}
| Some value -> Some (date, value)
)
|> List.rev

match reversedValues with
| head :: tail ->
match tail |> List.tryFind (fun dp ->
float head.Value / 2. >= float dp.Value) with
| (headDate, headValue) :: tail ->
let halfValue = float headValue / 2.

match tail |> List.tryFind (fun (_, value) ->
float value <= halfValue) with
| None -> None
| Some halfValue -> (head.Date - halfValue.Date).TotalDays |> Some
| Some (halfValuePointDate, _) ->
(headDate - halfValuePointDate).TotalDays |> Some
| _ -> None

let classes (classTuples: seq<bool * string>) =
Expand Down

0 comments on commit 9d79238

Please sign in to comment.