iamse7en iamse7en - 14 days ago 8
JSON Question

Rails Chartkick. Multiple Series line chart with nested hash

Trying to do a multiple series line chart. (Visualizer is Chartjs.) From the

README
:

<%= line_chart [
{name: "Series A", data: series_a},
{name: "Series B", data: series_b}
] %>


My data is coming in JSON format already, but takes a little manipulation to get right. Raw form looks like this:

=> [{"id"=>30,
"runner"=>"Golden State Warriors",
"price"=>1.51,
"histories"=>[{"price"=>1.51, "created_at"=>"2016-11-19T17:42:18.699Z"}, {"price"=>1.51, "created_at"=>"2016-11-20T07:56:55.662Z"}]},
{"id"=>32, ETC


So, with
markets.map{ |m| [name: m['runner'], data: m['histories'].map{|h| [h['created_at'], 1/h['price']] }]}.flatten!

which yields:

=> [
{:name=>"Golden State Warriors", :data=>[["2016-11-19T17:42:18.699Z", 0.6622516556291391], ["2016-11-20T07:56:55.662Z", 0.6622516556291391]]},
{:name=>"Los Angeles Clippers", :data=>[["2016-11-19T17:42:18.795Z", 0.1], ["2016-11-20T07:56:55.717Z", 0.1]]}, ETC


Although I don't get an error, the chart is an empty quadrant with
[object Object]
at 0,0.

The chart is in an
@markets.each
block in my view because I want to create multiple charts the page showing the same thing with different data. I played around with an
.each_with_index
and I can get the chart to show partially by just manually inputting the data as the
README
shows:

<%= line_chart [
{name: markets[i]['runner'], data: markets[i]['histories'].map{|h| [h['created_at'], 1/h['price']]}},
{name: markets[i+1]['runner'], data: markets[i+1]['histories'].map{|h| [h['created_at'], 1/h['price']]}}
] %>


Which shows the first two series on the chart, but can't be the right way as there are different i elements for each chart.

What can I do?

Answer

Figured it out using .each method. I'm sure there's a cleaner way to do this, but it's working for now.

def chart(markets)
  chart_data = markets.map{ |m| [name: m['runner'], data: m['histories'].map{|h| [h['created_at'], 1/h['price']]}]}.flatten
  line_chart chart_data.each do |m| 
    [{name: [:name], data: [:data]}]
  end
end