Dive Into Dojo Charting

By on July 13, 2010 12:01 am
Notice: There is a newer version of this post available

Chart Types

One of the most powerful pieces of Dojo is also one of the most underutilized: Charting.  The Dojo Charting library lives within the DojoX (extensions) branch of Dojo, and features numerous chart types, options, and a variety of themes. This post introduce you to the charting library and show you how you can take a boring data collection and make it a beautiful visual chart in any modern web browser.

Requiring Charting Classes

A common misconception with many Dojo libraries is that they require a large number of dependencies — this is not the case.  Dependencies change depending on the chart you’d like to make, but a simple chart can be created with only the following Dojo classes:

/* required modules for the basic chart */
//Main 2d chart class
dojo.require("dojox.charting.widget.Chart2D");
//Class to create a legend for our chart
dojo.require("dojox.charting.widget.Legend");
//A theme for our chart
dojo.require("dojox.charting.themes.PlotKit.green");

Two Ways to Play

Much like most of the widgets within the Dijit and DojoX libraries, the charting library allows you to create charts programmatically and declaratively.  Let’s take a look at an example of each approach.

Sample Data

The following JSON is used for our simple Pie chart:

var pieData = [{ "x": "1", "y": "9420" }, { "x":"2", "y":"10126" }, { "x": "3", "y": "9803" }, { "x": "4", "y": "15965" }, { "x": "5", "y": "17290" }, { "x": "6", "y": "15667" }, { "x": "7", "y": "17762" }];

Declarative Chart Creation

The declarative method of creating charts is done with HTML markup.  All chart data such as type, axis, plot, and other chart information is created within the chart container.  Here’s a simple pie chart:

<!-- create the chart -->
<div dojoType="dojox.charting.widget.Chart2D" id="viewsChart" theme="dojox.charting.themes.PlotKit.green" style="width: 550px; height: 550px;">
	
	<!-- add the plot -->
	<div class="plot" name="default" type="Pie" radius="200" fontColor="black" labelOffset="-20"></div>
	
	<!-- pieData is the data source -->
	<div class="series" name="January" array="pieData"></div> 
	
	<!-- tooltips! -->
	<div class="action" type="Tooltip"></div>
	
	<!-- slice animation! -->
	<div class="action" type="MoveSlice" shift="2"></div>
	
</div>

Dojo Pie Chart

Programmatic Chart Creation

Programmatic chart creation is also quite easy.  The JavaScript code below reproduces the chart above:

//create the chart
var pieChart = new dojox.charting.Chart2D("pieChart");
//set the theme
pieChart.setTheme(dojox.charting.themes.PlotKit.green);
//add plot 
pieChart.addPlot("default", {
	type: "Pie",
	radius: 200,
	fontColor: "black",
	labelOffset: "-20"
});
//add the data series
pieChart.addSeries("January",pieData);
//slice animation!
new dojox.charting.action2d.MoveSlice(pieChart,"default");
//tooltips!
new dojox.charting.action2d.Tooltip(pieChart,"default");
//render the chart
pieChart.render();

Take a moment to compare the two methods and you will quickly notice how similar the structures are. It’s the developer’s choice which method, declarative or programmatic, to use. This tutorial will focus on the programmatic method of chart creation though all examples work with both approaches.

Creating a Simple Chart

Now that the fundamental pieces of the charting puzzle have been explained, let’s create a very basic chart.  This chart will depict website visits over 3 months time.  The chart will be a basic StackedAreas chart with different colors to denote the different months. We’ll take it step by step.

The first step is to place our data in the format with which the chart works. The data for our StackedArea chart must hold each value in one array:

var json = {
	January: [9420,10126,9803,15965,17290, /* ... */  13165,12390],
	February: [23990,32975,23477,22513,18069, /* ... */ 12956,12815],
	March: [22477,24014,21116,20404,19142, /* ... */ 22077,20263]
};

The next step is to create the chart programatically.

//we have a DIV element with an ID of "chart1";  that's the argument
var chart1 = new dojox.charting.Chart2D('chart1'); 

Then it’s time to add the plot.

//add the default plot
chart1.addPlot("default", {
	//type of chart
	type: "StackedAreas",
	//show markers at number points?
	markers: true,
	//curve the lines on the plot?
	tension: "S",
	//show lines?
	lines: true,
	//fill in areas?
	areas: true,
	//offset position for label
	labelOffset: -30,
	//add shadows to lines
	shadows: { dx:2, dy:2, dw:2 }
});

Since the numbers in this type of chart are significant, we want to add an X axis (representing days) and a Y axis (representing traffic / views).

chart1.addAxis("x");
chart1.addAxis("y", { vertical:true });

Now that the frame of the chart has been created, it is time to add the information for each month. Since we want to fill areas, we’ll need to pass a stroke and fill color within the series:

chart1.addSeries("January Visits",json["January"], { stroke: "red", fill: "pink" });
chart1.addSeries("February Visits",json["February"], { stroke: "green", fill: "lightgreen" });
chart1.addSeries("March Visits",json["March"], { stroke: "blue", fill: "lightblue" });

Now that our chart is built and the data is in place, we can render the chart:

chart1.render();

The result is a beautiful chart:

Plain Chart

Chart Animations, Legends, and Extras

As with every other piece of the Dojo library, the Dojo charting library is flexible enough to incorporate other Dojo classes and widgets.  The basic chart we created above is nice but could use a few useful enhancements.

Legend

Adding a legend to the chart is very simple:

//this legend is created within an element with a "legend1" ID.
var legend1 = new dojox.charting.widget.Legend({chart: chart1}, "legend1");

Chart Animations

As with basic content on a web page, animation adds some flare and shows focus on an element. Each chart type supports different sets of animations. To keep it simple, we can add a “magnify” animation to the markers on our chart so that the marker grows when the mouse enters it:

//add the magnification animation to our chart for the default plot
var magnify = new dojox.charting.action2d.Magnify(chart1, "default");

Tooltips

Our chart features markers at the designated x/y axis numbers but we can enhance those markers with tooltips so that the user can see the exact number the marker represents.

var tip = new dojox.charting.action2d.Tooltip(chart1, "default");

Enhanced Chart

You may also pair Dijit themes with your chart to style the tooltip; I’ve added the “tundra” theme’s CSS file to enhance the style of my tooltip.

Zooming, Scrolling, and Panning

As you would expect from a vector graphic generation tool, Dojo’s charting library provides a method by which you may flawlessly zoom in and out on any chart. You may also accommodate panning and scrolling on your charts. Read Zooming, Scrolling, and Panning in Dojo Charting to learn more about these features or view a great example of panning, scrolling, and zooming!

Chart Events

Dojo’s charting library also has its own event connection method: connectToPlot.  This method allows you to add event listeners to your chart and trigger functionality based on the given event.

chart1.connectToPlot("default",function(e) {
	
	/* do something */
	
});

Chart events provide you a wealth of information, including the type of event, coordinates, plot, shape, and more. Visit the Dojo Charting Reference Guide to get detailed information about chart events.

Chart Themes

The Dojo charting library provides over 30 themes to make your charts stand out. You may see a complete list of bundled themes (with preview) in the Dojo Nightly Theme Previewer. SitePen will publish a post in the near future detailing how to create a custom theme!

Chart Themes

Chart Families

This tutorial showed you how to create a basic, but beautiful 2D chart; Dojo’s charting library has many advanced charting capabilities though. The different families of Dojo charts includes:

New Charting Features in Dojo 1.5

The release of Dojo 1.5 introduces new features to the charting library; most notably:

  • Linear and radial gradients can now be used with virtually all chart types (and they even work in IE).
  • Flexible data sourcing via DataSeries adds the ability to back charts with practically any sort of data store one would like, even supplying secondary information like tooltips.
  • Plot and series order manipulations enable one to programmatically shuffle plots and series as needed.
  • Indirect events that effectively make it possible for linked plots to share events.
  • External events allow a developer to programmatically generate things like mouseovers and apply them to charting objects.
  • The default axis is now smarter regarding scaling and sizing.
  • A new lightweight invisible axis type allows the user to control plot scale and alignment without displaying an axis.

Great Charting Resources

The concept of charting can seem difficult, but Dojo’s charting library is a breeze to dive into!

Other posts in the series

Comments

  • With regard to identifying different pieces of a pie chart and applying events to each piece individually, you may do so as follows:


    /* data and piece events */
    var pieData = [1,2,3,4,5,6];
    var pieEvents = [function(e) {
    /* executes when an event happens on pieData[0] */
    alert('You clicked on pieData[0]');
    },function(e) {
    /* executes when an event happens on pieData[1] */
    alert('You clicked on pieData[1]');
    }];

    /*
    programmatic chart creation here....
    */

    /* add event */
    pieChart.surface.connect('onclick',function(e) {

    //echo event
    var event = e;

    //get target
    var piece = e.target;
    var parent = e.target.parentElement;

    //loop through
    dojo.forEach(parent.childNodes,function(node,i){

    //if childNodes[i] is the one that was clicked...
    if(node == piece) { //found it!

    //look for an event
    if(pieEvents[i]) {
    pieEvents[i](e,i);
    }
    else {
    console.log('No function defined for this piece of the pie');
    }
    }
    });

    });

    Essentially it flows as follows:

    1. Define the data (pieData) and the event listener functions (pieEvents) in their own arrays.
    2. Create the chart.
    3. Use pieChart.surface.connect to listen to chart events. Once the “onclick” event fires:

    i. Grab the event target and its parent.
    ii. Loop through the parent’s children, comparing them to the event target.
    iii. If the event target and childNode[i] are the same, we’ve found the index of the target.
    iv. If an event exists in the pieEvents array for this index, fire it!

  • Chris

    thx. that is very nice. it helps me very much.

  • Anand

    Hi ,

    I am using MiamiNice theme for PIE Chart on my page , but the background color is coming as WHITE which i want accdording to my wish.
    here is the code:-

    dojo.require(“dojox.charting.Chart2D”);
    dojo.require(“dojox.charting.plot2d.Pie”);
    dojo.require(“dojox.charting.action2d.Highlight”);
    dojo.require(“dojox.charting.action2d.MoveSlice”);
    dojo.require(“dojox.charting.action2d.Tooltip”);
    dojo.require(“dojox.charting.themes.MiamiNice”);
    dojo.require(“dojox.charting.widget.Legend”);

    dojo.addOnLoad(function() {
    var dc = dojox.charting;
    var programmersChart = new dc.Chart2D(“programmersChart”,{fill:”transparent”});
    programmersChart.setTheme(dc.themes.MiamiNice).addPlot(“default”, {
    type: “Pie”,
    font: “normal normal 7pt Tahoma”,
    fontColor: “black”,
    labelOffset: -10,
    backgroundColor:”transparent”,
    radius: 40
    });
    20,
    ‘JavaScript’=>6,
    ‘Python’=>12,
    ‘Java’=>4

    );

    function array_to_chart_json($array) {
    $toReturn = array();
    foreach ($array as $key=>$value) {
    $toReturn[] = array(
    ‘y’=>$value,
    ‘text’=>$key,
    ‘stroke’=>’black’,
    ‘tooltip’=>$key
    );
    }
    return json_encode($toReturn);
    }

    ?>
    programmersChart.addSeries(“Series A”, );
    var anim_a = new dc.action2d.MoveSlice(programmersChart, “default”);
    var anim_b = new dc.action2d.Highlight(programmersChart, “default”);
    var anim_c = new dc.action2d.Tooltip(programmersChart, “default”);
    programmersChart.render();
    var programmersLegend = new dojox.charting.widget.Legend({
    chart: programmersChart
    },
    “programmersLegend”);
    });

    Please could you help in this.

    Thanks,
    Anand
    u can drop me a mail on my account: anandshahil11@gmail.com

  • Good question Anand! It takes a bit of work but the following will make the background transparent:

    programmersChart.surface.rawNode.childNodes[1].setAttribute(‘fill-opacity’,’0′);

    David

  • Jesse

    Has anyone else had issues where labels in pie charts overlap each other? If so, does anyone know what a good solution would be to prevent or fix it?

  • Pingback: Dive Into Dojo GFX | SitePen Blog()

  • voidstate

    One of the nicest features not mentioned here is animating your charts in. It’s as simple as adding an animate property to the addPlot property bag.

    this._chart.addPlot
    (
    ‘default’,
    {
    type: ‘Markers’,
    animate: { duration: 1000 } // <- this gives your charts a very nice visual impact
    }
    )

  • Chris

    @Jesse
    Smart label positioning for pie charts has been added to Dojo 1.6.
    See example at: http://archive.dojotoolkit.org/nightly/dojotoolkit/dojox/charting/tests/test_pie_smart_label.html

  • Neha

    Hello,

    I am trying to draw a chart with a custom image as its background.

    This is what I tried,
    I set the background of the div element to the image and the chart background transparent.

    But using
    myChart.surface.rawNode.childNodes[1].setAttribute(‘fill-opacity’,’0′);
    washes out the whole chart!

    Could you help?
    Thanks

  • Pingback: Version 2.5 of the Esri JavaScript API Released « Sean K McGinnis()

  • Romil Handoo

    I am looking for some solution to display the series value of clustered Columns chart in percentage. By default, the chart is being displayed as attached image.

    I need to display data in % instead of actual count (2.0,1.0 etc.).

    Is there any way to format chart series data? Please guide me.