Posted on • Originally published atwebbureaucrat.gitlab.io on
Elm Line Charts Part I: Times and Timezones
Elm has avery fine third-party line chart library which I've enjoyed using in my passion project,Chicago Test Out. It's well-documented as a library, but if I haven't used it in a while, I find myself struggling to get started with it. I end up starting at the middle or near the end and then clumsily working backwards from where I want to end up. For this reason,I'm working on writing a step-by-step guide for working withterezka/line-charts
based on my own preferences and assuming a high-degree of customization apart from the defaults, usingChicago Test Out as a model.
One of my preferences is that a line chart almost always be used with time on the x-axis, and you can't use a time without knowing the time zone, so we'll start there.
Step 1: Add aTime.Zone
field to your model.
Time zones have to be fetched asynchronously, which means
- Open the file that has your model record in it and, if you have not already,
import Time
. - Add a field of type
Time.Zone
to yourModel
type record. - In your model initialization, initialize your time zone field to Time.utc.
- Compile.
If you haven't already usedelm/time
somewhere, the elm compiler may object and insist that you install the dependency, which it will walk you through Assuming you don't have a lot of different functions that initialize a new model, this should bring your code to a compiling state. I am including the full source forsrc/Models.elm from Chicago Test out below for reference.
moduleModelsexposing(..)importHospitalizationexposing(Hospitalization)importTestDayexposing(TestDay)importTimetypealiasModel={days:ListTestDay,hospitalizations:ListHospitalization,mode:Mode,zone:Time.Zone}typeMode=Test|HospitalizationModeinit:Modelinit={days=[],hospitalizations=[],mode=Test,zone=Time.utc}
Step 2: Add a time zone update message
- Open the file containing your Elm messages. (Mine is insrc/Msg.elm.)
- If you haven't already,
import Time
into that module. - Add an
UpdateZone
type that takes aTime.Zone
parameter, like so:
moduleMsgexposing(..)importHospitalizationexposing(Hospitalization)importHttpimportJson.EncodeimportModelsexposing(Mode(..))importRawTestDayexposing(RawTestDay)importTimetypeMsg=GotRawTestDays(ResultHttp.Error(ListRawTestDay))|SetModeMode|UpdateHospitalizationDaysJson.Encode.Value|UpdateZoneTime.Zone
- Implement your new message in your
update
method of your elm application,likely located insrc/Main.elm. (You may need toimport Time
here as well.) - Compile.
Your code should be once again in a compiling state.
Get the Timezone from a Task
Now, just hook aTask to getTime.here
into your new message, and you should be up and running with time zones.
This example shows how to do it frominit
, but in Chicago Test Out, I want to fetch the time zone after I've run a fetch, so I'm going to hook in from the end of my fetch event.This is what I mean:
update:Msg->Model->(Model,CmdMsg)updatemsgmodel=casemsgofGotRawTestDaysresult->caseresultofOkresponse->TestDay.fromRawsresponse|>\days->({model|days=days},Task.performUpdateZoneTime.here)Erre->caseeof...
That's a lot to look at, but as you can see I'm callingTask.perform
if the response fromGotRawTestDays
isOk
. If the Task is success full, the current time zone,Time.here
will be passed to the message handler ofUpdateZone
.
A word on modelling times in Elm
As a reminder, Elm rejects ISO 8601 as a standard for dates. If you want dates along the x-axis of your chart, you need to have those dates passed as a posix number. For line charts, this should be aFloat
type. The steps to get your data will vary, so I won't enumerate them here, but keep that in mind as you work on fetching your line chart dataset: You need aFloat
for a date.
In Conclusion
This pretty well covers our prerequisites for working with line charts. In thenext post, I'll start to scaffold a real chart.
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse