Wednesday 21 September 2011

Dojo Charts Part 1 - Pie Charts

Dreamforce and Cloudforce are now over for another year, so its time to blog some code for a change.  This is the first in a short series of posts detailing how to produce charts in Visualforce using the Dojo Javascript toolkit.

I've been using Dojo Charting for around 18 months now on a variety of projects.  I don't propose to go into the minute detail in this post - there's plenty of information on this at the Sitepen site - a good starting point is: A Beginners Guide to Dojo Charting.  This post is concerned with integrating Dojo Charting into Visualforce pages. 

In view of the upcoming Winter 12 release, and the Developer Preview of Visualforce Charting, I'm sure some people will be wondering if there's any value to a Javascript charting solution.  My view on this is that its another tool in the box - plus Dojo Charting is available for production use now.

And so to the code.  The "parent" page provides the hooks into a cross domain build of Dojo hosted by Google.  There is always the option to upload the Dojo library as a static resource into your Salesforce org, but I prefer not to have to worry about managing this resource across every Salesforce org.  This page also contains sample data that is used to generate the sample pie chart.  The source for the page is shown below:

<apex:page controller="DojoPieChartController">
<script 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' 
             }
    " src="https://ajax.googleapis.com/ajax/libs/dojo/1.5/dojo/dojo.xd.js" type="text/javascript">
</script>

<apex:sectionheader title="Dojo Pie Chart">
<apex:form>
 <apex:pageblock title="Chart Data">
  <table>
    <tbody>
    <tr>
      <td>Value</td>
      <td>Color</td>
      <td>Text</td>
    </tr> 
    <tr>
      <td><apex:inputtext value="{!value1}">
      </apex:inputtext></td>
      <td><apex:inputtext value="{!color1}">
      </apex:inputtext></td>
      <td><apex:inputtext value="{!text1}">
      </apex:inputtext></td>
    </tr> 
    <tr>
      <td><apex:inputtext value="{!value2}">
      </apex:inputtext></td>
      <td><apex:inputtext value="{!color2}">
      </apex:inputtext></td>
      <td><apex:inputtext value="{!text2}">
      </apex:inputtext></td>
    </tr>
    <tr>
      <td><apex:inputtext value="{!value3}">
      </apex:inputtext></td>
      <td><apex:inputtext value="{!color3}">
      </apex:inputtext></td>
      <td><apex:inputtext value="{!text3}">
      </apex:inputtext></td>
    </tr>
</tbody>
</table>
<apex:commandbutton value="Update">
 </apex:commandbutton></apex:pageblock>
</apex:form>
<c:dojopiechart color1="{!color1}" color2="{!color2}" color3="{!color3}" 
id="piechart" text1="{!text1}" text2="{!text2}" text3="{!text3}" 
title="Example pie chart" value1="{!value1}" value2="{!value2}" 
value3="{!value3}">
</c:dojopiechart>
</apex:sectionheader>
</apex:page>

The real work is done by the dojopiechart component. This takes three sets of parameters, one set per wedge of the pie.  For each wedge, the colour (or color, as Dojo is clearly American!), the text to display in the legend and the value for the wedge - the values should add up to 100.

The component code is shown below.


<apex:component >
<apex:attribute name="value1" type="String" description="The value for slice 1"/>
<apex:attribute name="color1" type="String" description="The colour for slice 1"/>
<apex:attribute name="text1" type="String" description="Text to display against slice 1"/>
<apex:attribute name="value2" type="String" description="The value for slice 2"/>
<apex:attribute name="color2" type="String" description="The colour for slice 2"/>
<apex:attribute name="text2" type="String" description="Text to display against slice 2"/>
<apex:attribute name="value3" type="String" description="The value for slice 3"/>
<apex:attribute name="color3" type="String" description="The colour for slice 3"/>
<apex:attribute name="text3" type="String" description="Text to display against slice 3"/>
<apex:attribute name="divId" type="String" description="ID of the div to store the chart in" default="piechart"/>
<apex:attribute name="title" type="String" description="Title of the chart"/>

<script type="text/javascript">
dojo.require("dojox.charting.Chart2D");
dojo.require("dojox.charting.plot2d.Pie");
dojo.require("dojox.charting.widget.Legend");
dojo.require("dojox.charting.themes.MiamiNice");


makeCharts = function(){

		var chart=new dojox.charting.Chart2D("{!divId}");
        chart.addPlot("default", 
                {type: "Pie",
    	        font: "normal normal 11pt Tahoma",
        	    fontColor: "black",
            	labelOffset: -40,
	            radius: 80
                      });
                     
		chart.setTheme(dojox.charting.themes.MiamiNice);
        chart.addSeries("Series A", [
                  {y: {!value1}, text: "{!text1}", color: "{!color1}"},
                  {y: {!value2}, text: "{!text2}", color: "{!color2}"},
                  {y: {!value3}, text: "{!text3}", color: "{!color3}"}
                  ]);
        
        chart.render(); 
};

dojo.addOnLoad(makeCharts);

</script>
<div style="font-family:Verdana; font-size:14px; font-weight:bold;">{!Title}</div>
<div id="{!divId}" style="width: 300px; height: 300px; margin-left:50px;"></div>
</apex:component>
The dojo.require function calls pull in the Dojo modules that are needed to support generation of the chart. You can learn more about dojo.require at the Sitepen web site.

The chart is rendered into the <div> element identified by the divId attribute of the component  - this allows for multiple pie charts to appear in the same page. The wedges of the pie are supplied via the chart.addSeries function.

Below is a screenshot of the default page:


As the chart is "live", Changing the values in the Chart Data table and clicking Update generates an updated chart based on the new data:


I've made this available as a Google Code project, and also submitted it as a developer force code share, but it looks like it takes a while to get accepted and added to the list of projects.

Tuesday 13 September 2011

Dreamforce Day 3

Another day, another keynote. Excellent seats once again - a couple of rows back from Will.I.Am this time. Given that it's the same ballroom that Metallica played in last night, they've done an amazing job cleaning up and resetting the seats in a few hours. Got rid of the smell of booze too!

The highlight of day 3 for me was the session on Achieving Maximum Scale with Database.com Persistence Options. This turned into a deep dive on the Salesforce database architecture and confirmed (not that I doubted it for a moment) that there are some seriously smart people working for SFDC. Definitely worth checking out the recording/slide deck once available. Unfortunately I couldn't make the Eric Schmidt closing keynote as we were entertaining that night.

It all seems a long time ago now that we are setting up for Cloudforce London. Even worse, it's a whole year to the next Dreamforce rather than the usual 9 months.

Sunday 11 September 2011

Cloudforce London 2011



My company, BrightGen, is sponsoring Cloudforce London this year, and I'll be manning the stand.  As well as showcasing our consultancy work, we'll have details of the some of the products that we've been working on over the last year or so.

So if you are in need of Salesforce assistance or just fancy shooting the breeze, stop by and see us in the expo.

Dreamforce Day 2

As mentioned on the day 1 blog entry, day 2 started with the keynote. Thanks to @ericakuhl, there were excellent seats for the MVPs - Neil Young was four seats ahead, and it doesn't get much better than that. A couple of items from the keynote that really caught my attention were: 1. Customers in private chatter groups. Here at BrightGen we aim to use google docs for collaboration with customers, but have found that a number of customers don't have access to this, even anonymous access. Looking at the pre-release notes there's not much to it - simply create the customer users, mark the group as allowing customers and add them to it. I've just signed up for a pre-release trial so that I can play around with this. I'll post how I get on. 2. Data residency option. This allows sensitive data to be encrypted before it is sent to Salesforce, using software installed inside your firewall. Thus even in the event of the unthinkable happening, and your Salesforce data being compromised, only you have the key to the encrypted data. Obviously there are some downsides to this - searching for short tex snippets is unlikely to be successful, although exact match search should work better, as the search text will be encrypted using the same mechanism as the original record. It will also mean that all connections route through this software, which could get interesting for mobile working. There's also the option of storing data in your own database and putting associated tokens into the Salesforce database, but unfortunately I couldn't find out much more about this option - as soon as I do I'll share! The rest of the working day was streaming Api for me - an excellent live build from Pat Patterson in the second session. And so to Metallica - this was the busiest I've seen the Moscone Center - thousands stuck outside trying to get in. Luckily I joined the lines under the street early so didn't miss too much. Nothing like the feeling when your whole body is vibrating to the bass! A short set from Will.I.Am rounded off the evening, ith keynote 2 just a few hours away.