Elm Line Charts Part III: Lines and the Chart
Tags: elm, datavisualization, dataviz, functional
Published: 2020-09-03 14:39:36

---
title: Elm Line Charts Part III: Lines and the Chart
published: true
date: 2020-07-31 00:00:00 UTC
tags: ["elm", "datavisualization", "dataviz", "functional"]
canonical_url: https://webbureaucrat.gitlab.io/posts/elm-line-charts-part-iii-lines-and-the-chart/
---

This is the last installment of a series describing how to configure an [Elm LineChart](https://package.elm-lang.org/packages/terezka/line-charts/latest/LineChart). In the [previous post](https://webbureaucrat.gitlab.io/posts/elm-line-charts-imports-and-axes/) 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.

```elm
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](https://www.reddit.com/r/restofthefuckingowl/)

I'm happy with the rest of the defaults and they don't generally 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.

```elm
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.)