Using FusionCharts with RoR - Creating Drill-down charts

In our previous example, we had used FusionCharts to plot a chart using data stored in database. We'll now extend that example itself to create a drill-down chart which can show more information.

If you recall from previous example, we were showing the sum of factory output in a pie chart as under:

In this example, we'll extend this example, so that when a user clicks on a pie slice for a factory, he can drill down to see date wise production for that factory.
 
Setting up the pie chart for Link
To set up the pie chart to enable links for drill-down involves just minor tweaking of our previous example. We basically need to add the link attribute for each <set> element.


Controller: dbexample_controller.rb
Action: basicdbexample


class DbexampleController < ApplicationController
def default
   oRs=''
   oRs2=''
   strQuery=''
   #strXML will be used to store the entire XML document generated
   strXML=''

   #We also keep a flag to specify whether we've to animate the chart or not.
   #If the user is viewing the detailed chart and comes back to this page, he shouldn't
   #see the animation again.

   animateChart=''
   animateChart = params["animate"]
   #Set default value of 1
   if animateChart==""
      animateChart = "1"
   end


   #Generate the chart element
   strXML = "<chart caption='Factory Output report' subCaption='By Quantity' pieSliceDepth='30' showBorder='1' formatNumberScale='0' numberSuffix=' Units' animation=' " + animateChart.to_s + "'>"

   #Iterate through each factory
   oRs = Factorymaster.find(:all)

   oRs.each do |recordset|
      #Now create second recordset to get details for this factory

      @oRs2 = Factoryoutput.find(:all,:conditions=>["FactoryId=?",recordset.FactoryId.to_s])
      recordcount = @oRs2.length
      count = 0
      quantity = 0
      while count < recordcount
         quantity = quantity + @oRs2[count][:Quantity].to_i
         count = count + 1
      end
   #puts quantity
   #Generate <set label='..' value='..' link='...'/>

   factoryid = ""
   @oRs2.each do |recordset2|
      if factoryid != recordset2.FactoryId
         strXML = strXML + "<set label='" + recordset.FactoryName + "' value='" + quantity.to_s + "' link='" + CGI.escape("/dbexample/detailed?FactoryId=" + recordset.FactoryId.to_s) + "'/>"
      end
      factoryid = recordset2.FactoryId   
      end
   end
   #Finally, close <chart> element
   strXML = strXML + "</chart>"

   #Create the chart - Pie 3D Chart with data from strXML
   @chart1= renderChart("/FusionCharts/Pie3D.swf", "", strXML, "FactorySum", 600, 300, false, false)
end
end


View:
<HTML>
  <HEAD>
   <TITLE> FusionCharts - Database and Drill-Down Example </TITLE>
   <SCRIPT LANGUAGE="Javascript" SRC="/FusionCharts/FusionCharts.js"></SCRIPT>
 </HEAD>
 <BODY>
   <%= @chart%>
 </BODY>
</HTML>

As you can see in the code above, we're doing the following:

  1. Include FusionCharts.js JavaScript class
  2. Thereafter, we generate the XML data document by iterating through the recordset. We store the XML data in strXML variable. To each <set> element, we add the link attribute. We pass the factory id of the respective factory by appending it to the link. We finally URL Encode the link, which is a very important step.
  3. Finally, we render the chart using renderChart() method and pass strXML as dataXML.

Let's now shift our attention to next page.

 
Creating the detailed data chart page


Controller: dbexample_controller.rb
Action: detailed


class DbexampleController < ApplicationController
 def detailed
   #First, get the factory Id
   #Request the factory Id from Querystring

   fid = params["FactoryId"]
   oRs=''
   strQuery=''
   #strXML will be used to store the entire XML document generated
   strXML=''
   intCounter = 0
   #Generate the chart element string
   strXML = "<chart palette='2' caption='Factory " + fid.to_s + " Output '    subcaption='(In Units)' xAxisName='Date' showValues='1'    labelStep='2' >"
   #Now, we get the data for that factory
   factoryid = Factorymaster.find_by_FactoryId(fid.to_s)
   oRs = Factoryoutput.find(:all,:conditions=>["FactoryId=?",factoryid[:FactoryId]])
   oRs.each do |recordset|     
     strXML = strXML + "<set label='" + recordset.DatePro.to_s + "' value='" + recordset.Quantity.to_s + "'/>"
   end
   strXML = strXML + "</chart>"
   #Create the chart - Column 2D Chart with data from strXML
   @chart1=renderChart("/FusionCharts/Column2D.swf", "", strXML, "FactoryDetailed", 600, 300, false, false)
 end
end


View
<HTML>
  <HEAD>
   <TITLE> FusionCharts - Database and Drill-Down Example </TITLE>   
   <SCRIPT LANGUAGE="Javascript" SRC="/FusionCharts/FusionCharts.js"></SCRIPT>   
 </HEAD>
 <BODY>   
   <%= @chart1%> 
 </BODY>
</HTML>

In this page, we're:

  1. Including FusionCharts.js JavaScript class
  2. Requesting the factory id for which we've to show detailed data. This data was sent to us as querystring, as a part of pie chart link.
  3. We get the requisite data for this factory from database and then convert it into XML using string concatenation.
  4. Finally, we render a Column 2D chart using renderChart() method to show detailed data.

When you now run the app, you'll see the detailed page as under: