1

I'm trying to create a Google chart using GoogleVisualr.

This input works:

data_table.add_rows([
      ['04/14', 1],  
      ['04/15', 2], 
      ['04/16', 3], 
      ['04/17', 4], 
      ['04/18', 5], 
      ['04/19', 1], 
      ['04/20', 12], 
      ['04/21', 13], 
      ['04/24', 14], 
      ['04/14', 15], 
      ['04/24', 16], 
      ['04/22', 17], 
      ['04/14', 18], 
      ['04/4', 19], 
    ])

I am currently using:

Product.find(:all, :order => "created_at ASC").each do |p|
    data_table.add_rows([
     [p.created_at.strftime("%m/%d"), p.rating]
    ])

which returns:

01/13
2
01/20
3
02/22
2
03/14
2
03/19
2
04/14
1
04/15
2
04/17
2
05/14
2
05/14
2
05/14
2
05/14
2...

How can I format my array to match what GoogleVisualr requires:

[ [data, value], [date, value]...]

7 Answers 7

3

No need to use a loop, just use map:

rows = Product.all.order("created_at ASC").map do |p| 
 [p.created_at.strftime("%m/%d"), p.rating]
end
data_table.add_rows(rows)
Sign up to request clarification or add additional context in comments.

Comments

1

This code "Product.find(:all, :order => "created_at ASC")" you can create a :scope and your controller assigns @products = Product.order_by_created

@products.inject([]) do {|result, p| result << [p.created_at.strftime("%m/%d"), p.rating])}

Comments

0

Since you're already looping over each row, you can just use DataTable#add_row.

Product.find(:all, :order => "created_at ASC").each do |p|
  data_table.add_row([p.created_at.strftime("%m/%d"), p.rating])
end

1 Comment

This does not generate new rows. I get the same out put as interpolating the data and rating values. stackoverflow.com/questions/16550285/…
0

Make it into a string and interpolate your values within it.

puts "data_table.add_rows(["
Product.find(:all, :order => "created_at ASC").each do |p|
  puts "['#{p.created_at.strftime("%m/%d")}', #{p.rating}],"
end
puts "    ])"

Comments

0

Try something like this

pry(main)> result = []
=> []
pry(main)> Project.find(:all, :order => "created_at ASC").each do |p|
pry(main)*   result << [p.created_at.strftime("%m/%d"), p.id]
pry(main)* end  
pry(main)> result
=> [["02/05", 1],
["02/14", 6],
["02/15", 7],
["02/18", 8]]

Comments

0

Probably not the most efficient way, but premature optimisation is the root of all evil:

@products = Product.all(:order => 'created_at ASC')  
@csv = CSV.generate do |csv|
        csv << ["Secret", "Timestamp"]
        @products.each { |secret|
                csv << ["#{secret.story}", "#{secret.updated_at.strftime('%s')}"]
        }
    end
@csv   

Comments

0

If you look at the Google Visualr API (https://github.com/winston/google_visualr) on Winston's Github page, you will see that the add_rows method requires a nested array, where each element of the array is another array of size (length) 2. The first element e[0] is the date and the second element e[1] is the data value for that date. Pass your data in this format, and it should work correctly.

It looks like your code should already be doing that, as far as we can tell from here without actually being on your machine. However, your code is calling the add_rows method for each iteration in your each method, and supplying the data_table.add_rows method with a nested array that only has one array inside of it.

So instead of looking like this:

[ ['04/14', 1], ['04/15', 2], ['04/16', 3], ['04/17', 4] ]

and calling add_rows just one time like you would normally do, you are calling add_rows over and over again like this:

add_rows ( [ ['04/14', 1] ] )

add_rows ( [ ['04/15', 2] ] )

add_rows ( [ ['04/16', 3] ] )

add_rows ( [ ['04/17', 4] ] )

once for each data point.

What you should do is use your each iterator to put each date and its corresponding data value into an array, then call add_rows with that array as the parameter. Something like this:

my_array = []

Product.find(:all, :order => "created_at ASC").each do |p|
  my_array <<  [p.created_at.strftime("%m/%d"), p.rating]
end

data_table.add_rows(my_array)

I hope this helps.

1 Comment

Thilo has the right idea, if you understand how the map iterator works. The map method is kind of like the each method, except it returns an array consisting of elements that are the result of executing the block for each value. So you are doing the same thing as I suggest, except you're using the map method as a syntactic shortcut. Even if you use the map method instead of filling in the array yourself with each, my comments should help explain what you are doing and why. Good luck!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.