Sunday, 2 October 2011

Dojo Charts Part 2 - Bar Charts

Following on from last weeks Pie Chart post, this week I'm presenting an example of a Bar Chart generated via the Dojo JavaScript library.

As in the previous example, the Visualforce page pulls in the cross domain Dojo build from Google, has a couple of input fields (so that the data can be updated live) and responsibility for the production of the chart is delegated to a custom component:


<apex:page controller="DojoBarChartController">
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/dojo/1.5/dojo/dojo.xd.js"
        djConfig="parseOnLoad: true,
      modulePaths: { 
          'dojo': 'https://ajax.googleapis.com/ajax/libs/dojo/1.5/dojo', 
          'dijit': 'https://ajax.googleapis.com/ajax/libs/dojo/1.5/dijit', 
         'dojox': 'https://ajax.googleapis.com/ajax/libs/dojo/1.5/dojox' 
             }
    ">
</script>

<apex:sectionheader title="Dojo Bar Chart"/>
<apex:form >
 <apex:pageBlock title="Chart Data">
   <table>
    <tr>
      <td>Labels:</td>
      <td>
         <apex:inputText value="{!labels}" size="80"/>
      </td>
    </tr>
    <tr>
      <td>Values:</td>
      <td>
        <apex:inputText value="{!series1}"/>
      </td>
    </tr>
  </table>
  <apex:commandButton value="Update"/>
 </apex:pageBlock>
</apex:form>
<c:DojoBarChart id="barchart" minx="0" stepx="2"
			     labelsy="{!yAxisLabels}"   
			     title1="Data" 
			     series1="{!series1}"
                             color1="#000"
                             fill1="blue"
			     />
</apex:page>

The labels and series1 properties are simply comma separated lists of values, where the first entry in the series1 is associated with the first entry in labels and so on.  The controller converts the labels into a suitable format for use in the JavaScript that sets up the bar chart.

The component takes a number of attributes, not all of which are supplied from the page.  As an aside, this is by no means the full functionality available from a Dojo bar chart - there are click throughs, animations and many other features, some of which will be explored in later posts in this series.


<apex:component >
  <apex:attribute name="minx" description="Minimum X Axis value" type="Integer"/>
  <apex:attribute name="maxx" description="Maximum X Axis value" type="Integer"/>
  <apex:attribute name="stepx" description="Step value for X axis" type="Integer"/>
  <apex:attribute name="labelsy" description="Y Axis Labels" type="String" />
  <apex:attribute name="title1" description="Plot series 1 title - displayed in legend" type="String" />
  <apex:attribute name="series1" description="Plotext>
                       vertical: true, 
                       natural: false});
        <apex:outputPanel layout="none" rendered="{!NOT(ISBLANK(title1))}">
           chart1.addSeries("{!title1}", [{!series1}],
                {stroke: {color:"{!color1}"}, fill: "{!fill1}"});
        </apex:outputPanel>
        chart1.render();
        <apex:outputText rendered="{!showLegend}">
		var legend1 = new dojox.charting.widget.Legend({chart: chart1, horizontal: false}, "legend1");
		</apex:outputText>        
};

dojo.addOnLoadavascript">

  dojo.require("dojox.charting.Chart2D");
  dojo.require("dojox.charting.widget.Legend");

  makeCharts = function(){

        var chart1 = new dojox.charting.Chart2D("simplechart", {fill:"transparent"});
        chart1.addPlot("default", {type: "Bars", gap:10});
        chart1.addAxis("x", {
                       <apex:outputText value="min:{!minx}," rendered="{!NOT(ISBLANK(minx))}"/> 
                       <apex:outputText value="max:{!maxx}," rendered="{!NOT(ISBLANK(maxx))}"/> 
                       <apex:outputText value="majorTickStep:{!stepx}," rendered="{!NOT(ISBLANK(stepx))}"/> 
		});
		
        chart1.addAxis("y", 
                      {
  		   <apex:outputText rendered="{!NOT(ISBLANK(labelsy))}">
            labels:
               [
                 {!labelsy}
               ],
            </apex:outputText>
                       vertical: true, 
                       natural: false});
        <apex:outputPanel layout="none" rendered="{!NOT(ISBLANK(title1))}">
           chart1.addSeries("{!title1}", [{!series1}],
                {stroke: {color:"{!color1}"}, fill: "{!fill1}"});
        </apex:outputPanel>
        chart1.render();
        <apex:outputText rendered="{!showLegend}">
		var legend1 = new dojox.charting.widget.Legend({chart: chart1, horizontal: false}, "legend1");
		</apex:outputText>        
};

dojo.addOnLoad(makeCharts);

</script>

<table>
   <tr>
     <td>
	   <div id="simplechart" style="width: 800px; height: 300px;"></div>
	 </td>
     <td style="vertical-align:middle">
	   <div id="legend1"></div>
	 </td>
   </tr>
</table> 
 
</apex:component>

Some of the values (minx, maxx) are optional - Dojo will calculate these if you don't provide them.   The creation of the chart follows a simple path - create the chart, add a plot, add x and y axis, add the data series and render the chart.  In this case the chart is rendered into the div with the id of "simplechart".  If multiple charts were required on the same page, this should be passed as an attribute to the component.

The page with the generated chart is shown below:


As before, the chart is live, so updating the values in the Chart Data section and clicking "Update" regenerates the chart with the latest data:


The page, controller and component are available in the Google Code project, along with a number of additional examples.  The next post will cover how to generate a stacked chart.

4 comments:

  1. Where is the controller for this page?

    ReplyDelete
    Replies
    1. Its in the google code project, as detailed in the final paragraph of the post.

      Delete
  2. Hi, I can't find any of the files on your Google Code site.

    Thanks.

    ReplyDelete
    Replies
    1. You can view the code by browsing the trunk at:

      https://code.google.com/p/dojo-charts-sfdc/source/browse/#svn%2Ftrunk%2FDojoCharts%2Fsrc%2Fpages

      I've just tried it and it worked for me.

      Delete