mGarsteck mGarsteck - 2 years ago 229
Ruby Question

Displaying data using Chartkick

I have data that is daily added by the user via a form. A few of these fields record temperature: :ambcur, :ambmin, :ambmax etc
this is all part of a tray which has a datalog

I am using chartkick and its great but I am unsure how to display the data over time.

Im trying to do a multiseries linechart.

<%= line_chart [
{name: "Series A", data: @tray.datalogs.ambcur},
{name: "Series B", data: @tray.datalogs.ambmin}
] %>

Also, a singular linechart does not work either.

<%= line_chart %>

Can someone help steer me in the right direction? thanks :)

Answer Source

The problem with your code is that you were not passing the correct data format to the line_chart. To draw an line chart the data must be in format of an Hash, like this:

<%= line_chart {"2016-05-21 23:50:40 UTC"=>20, "2016-05-21 23:50:57  TC"=>23} %>

{"2016-05-21 23:50:40 UTC"=>20, "2016-05-21 23:50:57 UTC"=>23}

In previous example you see dates (strings) as the keys to the hash and the values (integers) are 20 and 23. In your case you need an Hash where the keys are the dates and values of the Hash are the max,min or current temperature. { "date_1" => number, "date_2" => number, ... }

To test my code I created a model called Temperature. Here is the table:

  create_table "temperatures", force: :cascade do |t|
    t.integer  "max",        limit: 4
    t.integer  "min",        limit: 4
    t.integer  "current",    limit: 4
    t.datetime "created_at",           null: false
    t.datetime "updated_at",           null: false

In my view I called this:

<%= line_chart [
 {name: "Series A", data: Temperature.all.inject({}) {|res, v| res[v[:created_at]] = v.max; res }},
 {name: "Series B", data: Temperature.all.inject({}) {|res, v| res[v[:created_at]] = v.current; res }},
 {name: "Series C", data: Temperature.all.inject({}) {|res, v| res[v[:created_at]] = v.min; res }}
             ] %>

And I got the plot with 3 lines showing max,min and current temperature over time.

enter image description here

I used inject to create an Hash where keys are dates and values are the attributes [max,min, current] of model Temeperature. For additional information on inject method, read this stackoverflow thread.

In your case you should try this:

<%= line_chart [
 {name: "Series A", data: @tray.datalogs.inject({}) {|res, v| res[v[:created_at]] = v.ambmax; res }},
 {name: "Series B", data: @tray.datalogs.inject({}) {|res, v| res[v[:created_at]] = v.ambcur; res }},
 {name: "Series C", data: @tray.datalogs.inject({}) {|res, v| res[v[:created_at]] = v.ambmin; res }}
                 ] %>
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download