Elm Line Charts Part III: Lines and the Chart
data-visualization elmThis is the last installment of a series describing how to configure an Elm LineChart. In the previous post I used a viewmodel to configure an axis, so this post will cover how to use lists of those viewmodels to plot the rest of the chart.
Converting to the ViewModel
I want this line chart to have three lines based on my ChartModel
from the
previous post, and I know I'm starting with a model that has a list of
Hospitalization
s, so I'll start with ways to convert between the two.
icuBeds: List Hospitalization -> List ChartModel
icuBeds days =
List.map (\d -> d.icuBedsTotal/d.icuBedsTotalCapacity
|> \ratio -> ratio * 100
|> ChartModel d.date)
days
nonIcuBeds: List Hospitalization -> List ChartModel
nonIcuBeds days =
List.map (\d -> d.acuteNonIcuBedsTotal/d.acuteNonIcuBedsTotalCapacity
|> \ratio -> ratio * 100
|> ChartModel d.date
)
days
ventilators : List Hospitalization -> List ChartModel
ventilators days =
List.map (\d -> d.ventilatorsTotal/d.ventilatorsTotalCapacity
|> \ratio -> ratio * 100
|> ChartModel d.date)
days
All I'm doing here is taking different fields from Hospitalization
,
converting to a percent, and piping out to a ChartModel
. I've configured
this for each of the three percentages I want on my chart.
Draw the Rest of the Owl
I'm happy with the rest of the defaults and they don't generaly need a ton of explanation, so I'm just going to dump this pile of code unceremoniously here so that I can paste it someplace else when I need it.
chart : Time.Zone -> List Hospitalization -> Html Msg
chart zone days =
LineChart.viewCustom
{ x = xAxisConfig zone
, y = Axis.default 400 "Volume" .val
, area = Area.default
, container = Container.default "hospitalization-raw-chart"
, interpolation = Interpolation.default
, intersection = Intersection.default
, legends = Legends.default
, events = Events.default
, junk = Junk.default
, grid = Grid.default
, line = Line.default
, dots = Dots.default
}
[ LineChart.line Colors.blue Dots.none "ICU Beds" (icuBeds days)
, LineChart.line Colors.purple Dots.none "Acute Non-ICU Beds"
(nonIcuBeds days)
, LineChart.line Colors.red Dots.none "Ventilators" (ventilators days)
]
As you can see you plug in your time zone and some default values and a list of lines based on the functions defined above and give it a good stir.
In all seriousness, the important thing here is to use viewCustom
rather than fiddle with
making the numbered signatures work. (One thing I absolutely do not
understand is the way that Elm deals with parametric polymorphism by putting
numbers in the signatures. Elm, you are flawed and I love you anyway.)
I write to learn, so I welcome your constructive criticism. Report issues on GitLab.