简体   繁体   中英

Google Charts API with Ruby on Rails

I would like to graph time-series data like the following,

   timestamp, temperature
   12-12-2013 05:05:05, 25.569
   12-12-2013 05:05:10, 25.570
   12-12-2013 05:05:15, 26.000

and I know I can create a chart with javascript, by just putting this into the view:

<head>
    <script type="text/javascript" src="https://www.google.com/jsapi" ></script>
    <script type="text/javascript">
    google.load("visualization", "1", {packages:["corechart"]});
    google.setOnLoadCallback(drawChart);
    function drawChart() {
     var data = google.visualization.arrayToDataTable([
    ['t', 'temperature', 'data'],
    ['2004',  1000,      400],
    ['2005',  1170,      460],
    ['2006',  660,       1120],
    ['2007',  1030,      540]
  ]);

  var options = {
    title: 'Company Performance'
  };

  var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
  chart.draw(data, options);
}
   </script>
</head>

My ruby array looks like this, similar to the format in the above code:

  [['timestamp', 'temperature'], [12-12-2013 05:05:05, 25.569], [12-12-2013 05:05:10, 25.570]
   ... and so on]

Do I need to convert the time to epoch time to graph it order, and how do I insert a ruby declared variable in the above javascript? Or am I doing something wrong here?

Thank you, any help is appreciated.

When I solved this issue, I had some problems with dates, can't remember now what exactly. But I've sent date from ruby as string like

date_for_js = "#{year}, #{month-1}, #{day}"

and the data as

points_by_dates << [date_for_js, user.points.to_i]

Then I created .html.erb file

<%= javascript_tag do %>
    google.load('visualization', '1.0', {'packages':['corechart'], 'language': '<%= @locale.code %>'});
    google.setOnLoadCallback(drawChart);

    function drawChart() {
            var progress_chart_data = new google.visualization.DataTable();
            progress_chart_data.addColumn('date', '<%=j t(".date") %>');
          progress_chart_data.addColumn('number', '<%=j t(".points") %>');
            var progress_ticks = [];
            <% @points_by_dates.each_with_index do |points_by_date, index| %>
                progress_chart_data.addRow([new Date(<%= points_by_date[0] %>), <%= points_by_date[1] %>]);
                progress_ticks[<%= index %>] = new Date(<%= points_by_date[0] %>);
            <% end %>

            var date_format = 'MMM yyyy';

            var progress_chart_options = {
                legend: {position: 'out'},
                axisTitlesPosition: 'out',
                width: '800px',
              height: '300',
              hAxis: {format: date_format, ticks: progress_ticks},
                colors: ['#63c6d9'],
                vAxis: {minValue: 0},
                chartArea: {left: 90, top: 10}
            };
            var formatter = new google.visualization.DateFormat({pattern: date_format});
        formatter.format(progress_chart_data, 0); // Apply formatter to first column

        <% if @points_by_dates.present? %>
                var progress_chart = new google.visualization.AreaChart(document.getElementById('progress_chart'));
            progress_chart.draw(progress_chart_data, progress_chart_options);
        <% end %>
    };
<% end -%>

where you define dates in ticks option.

Hope that will be useful for you.

Answer for your second question ie How to enter this variable in javascript is to use gon gem https://github.com/gazay/gon . Basically what it does is to create a variable named gon in window namespace for your javascript. Infact you may avoid this gem by making your own global variable inside script tags in view file and calling the helper which generate this array there. But Gon is a neat way hence I prefer it

The arrayToDataTable method does not support dates, so you have to use a regular DataTable constructor instead:

var data = new google.visualization.DataTable();
data.addColumn('date', 't');
data.addColumn('number', 'temperature');
data.addColumn('number', 'data');
data.addRows(/* output from Ruby */);

Your timestamps need to be output as javascript Date objects. You can do this either by using either Unix epoch time or by splitting up your timestamp into year, month, day, hour, minute, second. The format for using Unix epoch time is:

new Date(/* Unix epoch time */);

The format for year/month/day is:

new Date(year, month, day, hour, minute, second);

where month is 0-indexed, so January is 0, February is 1...December is 11.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM