DEV Community

webbureaucrat
webbureaucrat

Posted on • Originally published at webbureaucrat.gitlab.io on

1 1

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
           ) 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
Enter fullscreen mode Exit fullscreen mode

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

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)
]
Enter fullscreen mode Exit fullscreen mode

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

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more