from legacy to functional and very little in between.

Elm Line Charts Part III: Lines and the Chart

This 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 Hospitalizations, 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)

nonIcuBeds: List Hospitalization -> List ChartModel
nonIcuBeds days =
List.map (\d -> d.acuteNonIcuBedsTotal/d.acuteNonIcuBedsTotalCapacity
|> \ratio -> ratio * 100
|> ChartModel d.date

ventilators : List Hospitalization -> List ChartModel
ventilators days =
List.map (\d -> d.ventilatorsTotal/d.ventilatorsTotalCapacity
|> \ratio -> ratio * 100
|> ChartModel d.date)

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 =
{ 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.

← Home