How to return all numbers in chartkick without using group_by

460 views Asked by At

I am fairly new to ruby and playing with ChartKick and not seeing any lines on the chart. I allow users to enter numbers 1-10 and I want to display all those values in a line_chart. I am returning all the values below in the loop and I want those numbers in the chart as well.

I know I am getting the data now because the colors are showing on the right for each value listed below. I have attached a screen shot to help. I would appreciate any help I can get. Thanks in advance!

Here is my view

<div class="col-xs-6">
    <h3>Numbers Added</h3>
      <%= line_chart @numbers, {height: "400px", library: {hAxis: {title: "All Entered Numbers"}, vAxis: {title: "Numbers", viewWindow: {min: 0, max:10}}}} %>
  </div>
</div>

<table>
  <tr>
    <th>All Numbers</th>
  </tr>

  <% @numbers.each do |number| %>
    <tr>
      <td><%= number.value %></td>
      <td><%= link_to 'Show', number_path(number) %></td>
      <td><%= link_to 'Edit', edit_number_path(number) %></td>
      <td><%= link_to 'Destroy', number_path(number),
              method: :delete,
              data: { confirm: 'Are you sure?' } %></td>
    </tr>
  <% end %>
  <%= link_to 'Add new number', new_number_path %>

</table>

Here is my controller

class NumbersController < ApplicationController
  def index
    @numbers = Number.all
  end

Screen shot:

screen shot

1

There are 1 answers

5
B.G. On BEST ANSWER

A line chart is basically just a X-Y Coordinate System.

X & Y Axis

To Draw a Point you need an X and an Y Coordinate. But you gave only 1 coordinate in an Array like this:

[1,21,44,12,55,12,9,0,78,12]

What you actually need is an Hash like this:

{
  0 => 1,
  1 => 21,
  2 => 44,
  ...
 }

To achiev that you can use following code:

<%= line_chart Hash[([email protected]).zip @numbers.map(&:values)], 
{height: "400px", library: {hAxis: {title: "All Entered Numbers"}, 
 vAxis: {title: "Numbers", viewWindow: {min: 0, max:10}}}} %>

This does multiple things at once. First it creates an Array with the numbers from 0 to the count (Exlusive the count) of your data:

([email protected]) =>
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

The next step is to collect all values from your numbers, @number is actually an array of ActiveRecord Objects, but you only want to have the values:

@numbers.map(&:values)

This function calls values on every object in @numbers and creates an Array with the results. Now we have two Arrays:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 21, 44, 12, 55, 12, 9, 0, 78, 12]

The .zip combines them, by taking one of each into an new Array, now we have the following:

[
  [0, 1], [1, 21], [2, 44], [3, 12], [4, 55], 
  [5, 12], [6, 9], [7, 0], [8, 78], [9, 12]
]

No we can just cast this into a hash with Hash[...] and voila we have this:

{
  0 => 1,
  1 => 21,
  2 => 44,
  ...
 }