Learning to code at Flatiron School

How to Use Custom Data With Highcharts in Your Rails App

Highcharts is a great tool for adding charts to your Rails application. Naturally, there is a very helpful Railscast on the topic, but I wanted to outline another example of using dynamic data to produce a chart.

For our app, OpenExam, we wanted a simple bar graph to display the distribution of quiz scores.

The examples on Highchart’s website all contain hard coded data, but what we needed was a way for Highcharts to take in dynamic data. Following the Railscast as our guide, our code initally looked like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$(function () {
  new Highcharts.Chart({
    chart: { renderTo: 'quiz_chart',
             type: 'column'
     },
    title: { text: 'Quiz Distribution' },
    xAxis: { type: 'Percent Correct' },
    yAxis: {
      title: { text: 'Number of Students'}
    },
    series: [{
      data: [1, 2, 5, 7, 3]
    }]
  });
});

Plugging this into jsfiddle, gave us a chart like this.

The formatting looks ok, but data is still static. Ultimately we want to give the Highcharts function two pieces of data to chart out; a correct percentage and the number of students who scored that percentage. The Highcharts documentation shows us that data can be passed in as an array, so now all we need to do is create that array from our data.

First, we created a new method that retrieves the score for each user who has taken a quiz and returns it as an array. In our app, each user’s quiz responses are stored in a user_quizzes table, that knows whether the response is correct or not.

1
2
3
  def self.student_correct_percent_by_quiz(quiz)
    quiz.user_quizzes.where(:status => "Completed").map { |quiz|  (quiz.num_correct.to_f / quiz.total_questions.to_f)*100 }
  end

Now that we have an array of every user’s correct percentage (their grade on the quiz), we want to count the number of users who got the same percentage correct. To do so, we created a empty hash and then iterated through our array counting the number of times the same percentage occurred.

1
2
3
<% scores_top = QuizGrader.student_correct_percent_by_quiz(@quiz) %>
<% count = Hash.new(0) %>
<% scores_top.each {|v| count[v]+=1} %>

This left us with a count hash, that we can easily turn into an array in a format that Highcharts likes : count.to_a.inspect. Plugging that into our Highcharts javascript gives us

and the corresponding chart