2

I'm trying to get highcharts graphs to update automatically from a table. Currently i'm coding each record in one by one as follows:

<script> ... }, series: [{ name: 'Number of Notes By Class Module', data: [<%= Note.where(:subject_type => 'English').count %>, <%= Note.where(:subject_type => 'Geography Class C').count %>, <%= Note.where(:subject_type => 'Maths Class B').count %>] }] }); }); </script> 

And in the model notes.rb:

def self.subject_analysis(subject_type) Note.where(:subject_type => English).count if subject_type == :english Note.where(:subject_type => Geography_Class_C).count if subject_type == :Geography_Class_C Note.where(:subject_type => Maths_Class_B).count if subject_type == :Maths_Class_B end 

Classmodules schema

 t.integer "student_id" t.string "subject" t.datetime "created_at", null: false t.datetime "updated_at", null: false 

Clearly this is not ideal. What I want is for the column chart to update automatically when a new record is put in the table. To do this I think I need to use JSON in my controller and pass it to Highcharts. Only I don't know how to do this. Any guidance? Thanks. If more info required I will provide.

    2 Answers 2

    1

    You need 3 steps to set it up:

    1. Create a route for the JSON API in your routes file like:

      get 'highchart-data', to: 'controller_name#action_name' 
    2. Create an action in a controller (match the route you just created):

      def action_name @data = [Note.where(:subject_type => 'English').count, Note.where(:subject_type => 'Geography Class C').count, Note.where(:subject_type => 'Maths Class B').count] render json: @data end 
    3. In your js file, assuming you are using jQuery and run on your localhost with port 3000, get the data from the route created above. Add this line before you create the series:

      $.getJSON('http://localhost:3000/highchart-data', function(data) { var highChartData = data; }); 

    And in series replace the data line with:

     data: highChartData 
      1

      If by 'update automatically' you mean that a chart is always up to date when the browser is refreshed, you don't need to use JSON and your implementation can be relatively simple.

      First, I would move the actual data compilation into the model itself. Something like this would construct the three-element array you require:

      class Note < ActiveRecord::Base ... def self.highchart_data data = [] self.subject_types.each do |type| data << self.type_count(type) end data end private def self.subject_types pluck(:subject_type).uniq end def self.type_count(type) where(subject_type: type).count end end 

      Then your controller is extremely simple:

      class BarChartController < ApplicationController def show @data = Note.highchart_data end ... end 

      As far as getting the @data instance variable into your JS, there are several different approaches. One of them might look like:

      In your show view:

      <%= javascript_tag do %> window.highchartDATA = '<%= @data %>'; <% end %> 

      In your JS:

      ... series: [{ name: 'Number of Notes By Class Module', data: highchartDATA }] ... 

      Note that this code is to illustrate concepts and not meant to be copy and pasted.

      Update

      Based on your comment, I've updated the example code to use the unique subject_types added by users.

      5
      • Thanks to both of you. What confuses me is that the subjects "English", "Maths Class B" and "Geography Class C" are records put in to the table by the user. Is the above not doing the same thing? Say Physics is added by a user for example I would like that just to show up rather than having to touch the code again. Really appreciate the guidance.
        – Co2
        CommentedNov 29, 2015 at 23:55
      • Thanks. Definitely closer. Have this error on trying to load the dashboard. undefined local variable or method `subject_types' for #<Class:0xbf3e1a0>
        – Co2
        CommentedNov 30, 2015 at 0:40
      • xAxis: { categories: [], title: { text: null }, I take it the x-axis should look like this?
        – Co2
        CommentedNov 30, 2015 at 1:00
      • @Co2 I've updated the Note class to use three class methods that I have tested to work.CommentedNov 30, 2015 at 3:09
      • Thanks. The view appears but the data does not render. I will post in more detail later. I'm just wondering do I have the categories syntax wrong in my previous comment.
        – Co2
        CommentedNov 30, 2015 at 12:03

      Start asking to get answers

      Find the answer to your question by asking.

      Ask question

      Explore related questions

      See similar questions with these tags.