A Beginner’s Guide to Dojo Charting, Part 1 of 2 June 6th, 2008 at 12:30 am by Doug McMaster

Welcome! If you are looking for a way to quickly and easily add great looking and functional charts and graphs to your web pages, you’ve found the right place. All you need is a tiny bit of JavaScript skills and a copy of Dojo.

In this two part guide, we look at how easy it is to get Dojo Charting up and running, and then examine in greater detail the options available for different looks for your charts. Today in Part 1, we start with a basic example and then examine all the options available in defining your plot type. Part 2 will cover the options available in defining the axes and data sets for your charts.

Let’s get started. Here is the code for a basic Dojo Chart, make sure you have the proper path to your dojo.js file:

<html>
<head>
<title>Basic Charting</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 
<script type="text/javascript" src="dojo/dojo.js" djConfig="isDebug: true"></script>
 
<script type="text/javascript">
 
dojo.require("dojox.charting.Chart2D");
 
makeCharts = function(){
 
	var chart1 = new dojox.charting.Chart2D("simplechart");
	chart1.addPlot("default", {type: "Lines"});
	chart1.addAxis("x");
	chart1.addAxis("y", {vertical: true});
	chart1.addSeries("Series 1", [1, 2, 2, 3, 4, 5, 5, 7]);
	chart1.render();
 
};
 
dojo.addOnLoad(makeCharts);
 
</script>
</head>
<body>
<div id="simplechart" style="width: 250px; height: 150px;"></div>
</body>
</html>

This source code produces the following simple chart.

Simple Chart

Looking at this we can see that most of the work in defining the chart is done in the addPlot(), addAxis(), and addSeries() functions. Today we will examine the addPlot() call, and Part 2 will cover the options for addAxis() and addSeries().

Got Plot?

The addPlot() call determines what type of chart you are going to produce, and there are a variety of options to select. Here are a few examples:

Some Chart Types

addPlot() accepts 2 parameters, a name and an arguments array. The name is important if you want to have more than 1 plot type on your chart, a concept we will cover shortly. The arguments array contains your options, and these may vary depending on the type of plot you use. Note that your choice of plot type may define appropriate default options.

Let’s examine our options. Type is the main option, and the default value is a basic line chart.

chart1.addPlot("default", {type: "Areas"});

Available 2D chart types include:

  • Areas - Area under data line(s) will be filled
  • Bars - Horizontal bars.
  • ClusteredBars - Horizontal bars with clustered data sets
  • ClusteredColumns - Vertical bars with clustered data sets
  • Columns - Vertical bars
  • Grid - For adding a grid layer to you chart
  • Lines - Basic line chart
  • Markers - Lines with markers
  • MarkersOnly - Markers, sans lines
  • Pie - Goes great with punch!
  • Scatter - Cooler name for MarkersOnly
  • Stacked - Data sets charted in relation to the previous data set.
  • StackedAreas - Stacked data sets with filled areas under chart lines
  • StackedBars - Stacked data sets with horizontal bars
  • StackedColumns - Stacked data sets with vertical bars
  • StackedLines - Stacked data sets using lines

If you choose any of the lines, areas or markers types you have 5 specific options. First up we have 3 switches, which are lines, areas, and markers. These are often defined by the plot type you choose, but can be changed to get your desired behavior. The lines option determines whether or not lines are used to connect your data points. If the areas type is selected, the area below your data line will be filled. The markers option will determine if markers are placed at your data points.

chart1.addPlot("default", {type: "StackedAreas", lines: true, areas: true, 
	markers: false});

There are also 2 graphical options, tension and shadows. Tension allows you to add some curve to the lines on you plot. By default this option is set to 0 which is off. I found 2-4 to be a good range for natural looking curves. For some crazy effects try setting this to values < 1 or negatives. Shadows allow you to add a shadow effect, and consists of an array of 3 parameters, dx, dy and dw, which represent the offset to the right, the offset down, and the width of the shadow line, respectively. You can use negative values for your dx and dy parameters to produce a shadow that is to the left or above your chart line.

chart1.addPlot("default", {type: "StackedLines",tension:3, 
	shadows: {dx: 2, dy: 2, dw: 2}});

Bar and column graph types have 1 unique option: they will accept a gap parameter that determines the spacing between your bars or columns in pixels.

chart1.addPlot("default", {type: "Bars", gap: 5});

For any chart type that supports axes, you can also define custom names to your axes here. By default they are “x” and “y”, but this option becomes useful if you wish to have a chart with multiple plots and multiple axes.

chart1.addPlot("default", {type: "Bars", hAxis: "cool x", 
	vAxis: "super y"});

Pie charts are very different by nature, and have a separate list of parameters. I’ll leave it up to you to explore the parameters for the pie chart, from Pie.js:

defaultParams: {
	labels: true,
	ticks: false,
	fixed: true,
	precision: 1,
	labelOffset: 20,
	labelStyle: "default",      // default/rows/auto
	htmlLabels: true            // use HTML to draw labels
},
optionalParams: {
	font: "",
	fontColor: "",
	radius: 0
},

One other type with unique options is the grid. This plot type will draw grid lines along your tick marks and supports the following four boolean options to determine if lines will be displayed at the horizontal or vertical and major or minor axis tick marks. We will learn more about axes and look at a sample including the grid type in Part 2.

chart1.addPlot("default", {type: "Grid",
        hMajorLines: true, 
        hMinorLines: false,
        vMajorLines: true,
        vMinorLines: false});

Now, let’s go back to our starting example and spruce it up a bit. Let’s add a shadow, some curve to our line, and markers on our data points.

chart1.addPlot("default", {type: "Lines", markers: true, 
	tension:3, shadows: {dx: 2, dy: 2, dw: 2}});

And now our chart looks like this:

Some Chart Types

One last feature I’d like to touch on is adding multiple plots to the same chart. Multiple plots can be of differing types and can all be configured separately. Each plot you add with addPlot() will be layered behind the previous plot. In addition, plots can have their own axes or share them with other plots on the chart. Now, if we add an areas plot to our lines example, we can create the following effect.

var chart1 = new dojox.charting.Chart2D("simplechart");
chart1.addPlot("default", {type: "Lines"});
chart1.addPlot("other", {type: "Areas"});
chart1.addAxis("x");
chart1.addAxis("y", {vertical: true});
chart1.addSeries("Series 1", [1, 2, 2, 3, 4, 5, 5, 7]);
chart1.addSeries("Series 2", [1, 1, 4, 2, 1, 6, 4, 3], 
	{plot: "other", stroke: {color:"blue"}, fill: "lightblue"});
chart1.render();


Some Chart Types

That’s all for today. Check back soon for Part 2 where we will cover the options available in the addAxes() and addSeries() calls.

Tags: ,

29 Responses to “A Beginner’s Guide to Dojo Charting, Part 1 of 2”

  1. Shane O'Sullivan says:

    Excellent tutorial, very good explanation of charting basics

  2. Shane O'Sullivan says:

    One issue I’ve found is that setting the hAxis and vAxis parameters seems to stop the chart from renderering. e.g.

    var chart1 = new dojox.charting.Chart2D("simplechart");
        chart1.addPlot("default", {
    		hAxis: "X Axis",
    		vAxis: "V Axis",
    		type: "Bars", 
    		areas: true,
    		gap: 5
    	});
        chart1.addAxis("x");
        chart1.addAxis("y", {vertical: true});
        chart1.addSeries("Series 1", [1, 2, 2, 3, 4, 5, 5, 7]);
        chart1.render();

    does not render, but take out the hAxis and vAxis parameters, and it renders just fine in FF2

  3. Doug McMaster says:

    Shane, you need to change the name on your addAxis calls to match the values for the hAxis and vAxis parameters.

    chart1.addAxis(”X Axis”);
    chart1.addAxis(”V Axis”, {vertical: true});

    I’ll be covering the addAxis() call in detail in part 2, which I hope to be able to get posted in the next few days.

  4. Sishyan says:

    The beginners guide is a good place to start.

    I have the following

    makeCharts = function(){
    	var chart1 = new dojox.charting.Chart2D("simplechart");
    	chart1.addPlot("default", {type: "Bars", hAxis:"X Axis", 
    		vAxis:"Y Axis", areas: true, gap: 10});
    	chart1.addAxis("X Axis");
    	chart1.addAxis("Y Axis", {vertical: true});
    	chart1.addSeries("Series 1", [1, 2, 2, 3, 4, 5, 5, 7]);
    	chart1.render();
    };
    dojo.addOnLoad(makeCharts);

    The above does not render in Firefox.
    It renders in IE, but the horizontal bars don’t have a gap.

  5. Sishyan says:

    This is the second part of my example.

  6. Sishyan says:

    Oops, the DIV tags are not appearing in my comments.

    This a description of my DIV tag.

    I have a ContentPane in a DIV tag
    Then under that I have a TabContainer in a DIV tag
    The under that I have another ContentPane in a DIV tag
    The under that I have a DIV tag for the “simplechart” as in the example

  7. Sishyan says:

    It’s kind of working for me now in Firefox and in IE.

    But only when the DIV tag containing the id=”simplechart” is brought out of my structure [ContentPane–>TabContainer–>ContentPane–>DIV tag for chart]

    Looks like if its inside a ContentPane enclosed in a Tabcontainer which in itself is enclosed in a ContentPane, its not rendered in Firefox, either that or its rendered behind the TabContainer.

    Any help as to what Iam doing wrong or is it a bug in Dojo?

  8. Dylan says:

    Hi Sishyan, can you please post a link to the full code? If it’s a bug, we’ll file a ticket in Dojo’s issue tracking system.

  9. Shane O'Sullivan says:

    Hi Doug,

    I changed the names of the axes to match, and they still do not display. Is there another setting I need to enable axis labels?

    Looking at all demos/tests of the charts in dojo, none of them have labels, besides the Pie charts.

    Thanks

    Shane

  10. Doug McMaster says:

    Hi Sishyan, the issue where you are not seeing a gap may be due to size. If the gap between lines would make the bar less then 1 pixel it seems to reset to 0 gap. Try increasing the height of the div or reducing the gap size. I’m not sure why a chart wouldn’t render inside a ContentPane.

  11. Doug McMaster says:

    Hi Shane, I think I may have misunderstood your earlier question. There is currently no direct way to display the axis titles, just labels on the tick marks, which can be customized. However, the event support in 1.2 includes axis information, maybe that could be useful. There was a post about it a week or so ago by Eugene. He also mentions that a Chart Legend Widget is in the works, which I suspect should allow you to display axis information. Here is his post: http://www.sitepen.com/blog/2008/05/27/dojo-charting-event-support-has-landed/

  12. Colleen says:

    The first example doestn work for me
    http://colleenweb.com/testdojo.html
    what is wrong

  13. Colleen says:

    never mind I made one work. I still don’t know how.

  14. Colleen says:

    OK it was one of those invisible typos. Now all is good. WHere is part 2?

  15. Shane O'Sullivan says:

    Hi Doug,

    Not being able to display axis labels is quite a large limitation - was it deliberate? Surely it couldn’t be difficult to implement. Was it an oversight?

    Thanks

    Shane

  16. Sishyan says:

    Hi Dylan,

    I have pasted the codefragment here.

    http://wiki.planetvimal.com/codefragment.html

    The first one works fine, as the Chart DIV is outside the TabContainer.

    But the second fragment does not render.

  17. Horst says:

    Big thanks. Iam playing a little with dojo charting at moment. Your article was a great help for my first steps. I hope to see the second part, soon. 8-)

  18. Sishyan says:

    By the way, it works in IE,the chart inside contentpane in tab container, but not in firefox.

  19. Doug McMaster says:

    Hi Shane, I did some digging around and axis titles are on the to do list. They won’t make the 1.2 release, but they are on the list.

  20. SitePen Blog » A Beginner’s Guide to Dojo Charting, Part 2 of 2 says:

    […] Part 1 of this guide on Dojo charting covered a basic charting example and the options available in defining our chart type. Today we will examine the options for defining our axes and data sets. […]

  21. Denilson Nastacio says:

    I wanted to recreate the effect of the chart2d test for sparklines, but when I use dojox.charting.Chart2D instead of dojox.charting.widget.Chart2D the charting engine still leaves room on the left and on the bottom for the axis labels (which I am not setting)

    I played with the axis and plot parameters for several hours and still no luck.

  22. Dylan says:

    @Denilson: To make sure I understand correctly, are you comparing the results of http://archive.dojotoolkit.org/nightly/dojotoolkit/dojox/charting/tests/test_sparklines.html with a non-widget version of a Sparkline just using normal 2D charting? It sounds like a bug, just want to make sure I understand this correctly before I file a ticket on it.

  23. Denilson Nastacio says:

    @Dylan, your assumption is correct, my chart created with this snippet:

    sparkline = new dojox.charting.Chart2D(”sparkline”);
    sparkline.setTheme(dojox.charting.themes.ET.greys);
    sparkline.addPlot(”default”, { type: “Default”,
    lines: true,
    stroke: null,
    fill: null,
    margins: null,
    markers: false} );

    sparkline.addAxis(”x”, { min: 0,
    max: datesArray.length-1,
    majorTick: { length: 0},
    minorTick: { length: 0},
    minorTicks: false,
    microTicks: false,
    minorLabels: false,
    majorLabels: false});
    sparkline.addAxis(”y”, { vertical: true,
    majorTick: { length: 0},
    minorTick: { length: 0},
    minorTicks: false,
    microTicks: false,
    minorLabels: false,
    majorLabels: false});
    sparkline.addSeries(”Series A”, seriesArray);
    sparkline.render();

    has quite a bit of padding (~50-70px) on both left and bottom sides. When I enable labels and ticks, they fit quite nicely in that buffer area. A cursory look through the Chart2D.js seems to confirm my assumption.

  24. Alex says:

    hey Denilson:

    The issue here is the margins. If you look at the sparklines demo page you’ll see that it explicitly sets margins:

    http://download.dojotoolkit.org/current-stable/dojo-release-1.1.1/dojox/charting/tests/test_sparklines.html

    Like this:

    margins=”{ l: 0, r: 0, t: 0, b: 0 }”

    If you set the widget margins similarly you should get the same result. In the nightlies there’s also a new sparkline widget which makes this even easier:

    http://archive.dojotoolkit.org/nightly/dojotoolkit/dojox/charting/tests/test_sparklines.html

    Regards

  25. Destroyer says:

    Hi, When is the Part2 of this tutorial coming out? I want to create a chart with live data, and want to be able to go back in history or zoom-in to any section. Is this possible be dojo? Thanks.

  26. Dylan says:

    @Destroyer: Charting Part 2.

    Your other requests are possible, but would require some non-out-of-the-box work to make it happen. Free free to contact us if you want to explore engaging us to make that happen, or visit the IRC channel or Dojo forum to get additional community support (useful links to community support resources may be found at http://www.sitepen.com/labs/dojo.php .

  27. David S. says:

    I am trying to implement a dynamic chart using dojox charting. I’ve built a very simple JavaScript file that defines the chart and propagates it with randomly generated data, much like the dynamic demo that comes packaged with dojox. My charting works fine, but after about 125 points are added to a plot, the plot browser starts to consume an excessive amount of memory and adding more than one plot to a webpage as I’m wanting to do is nearly impossible with as much memory as is being consumed.

    I first tried my implementation on the nightly build of dojo so that I could incorporate events, tooltips, etc. Suspecting the memory problems were resulting from the version of dojo I was using, I commented out the new features from my JavaScript and tried running it with the newest stable release of DOJO. That was not quite as laggy initially, but again, after 100 points or so, it started to really slow down the browser.

    I’m attaching just my JavaScript to this post in case anyone has a suggestion. This JavaScript implementation will fit my needs perfectly, but I need to figure out how to make it consume less browser resources. Ultimately I’m wanting to put ~6 plots with 1-4 data series per chart. Each data series will have about 200 points each. Is this feasible, or am I expecting too much of this application?

    Thanks,
    David

    // auto loaded modules
    dojo.require("dojox.charting.Chart2D");
    dojo.require("dojox.charting.themes.PlotKit.blue");
    dojo.require("dojox.charting.action2d.Magnify");
    dojo.require("dojox.charting.action2d.Tooltip");
    dojo.require("dojox.charting.action2d.Highlight");
    dojo.require("dojox.charting.widget.Legend");
    dojo.require("dojox.layout.FloatingPane");
    dojo.require("dojo.colors");
    dojo.require("dojo.fx.easing");
    dojo.require("dojo.parser");
    dojo.require("dijit.Dialog");
    dojo.require("dijit.form.Button");
    dojo.require("dijit.form.TextBox");
     
    // variable declarations
    var dialog;
    var chart, limit = 300, magnitude = 10;
    var signal1Series = [1];
    var target = 50;
    var usl_value = 80;
    var lsl_value = 20;
    var ucl_value = 60;
    var lcl_value = 40;
     
    // random number generator
    var randomValue = function(){
    	return (Math.random() * magnitude) + 40;
    };
     
    // initialize the chart
    var makeObjects = function(){
    	chart = new dojox.charting.Chart2D("test");
    	chart.setTheme(dojox.charting.themes.PlotKit.blue);
    	chart.addAxis("x", {fixLower: "minor", fixUpper: "minor", natural: true});
          chart.addAxis("y", {vertical: true, min: 0, max: 100, majorTickStep: 5, minorTickStep: 1});
    	chart.addPlot("default", {type: "Default", lines:false, markers:true, tension:2});
     
    	// add limit and target lines
    	chart.addPlot("limits", {type: "Default", lines:true, markers: false, tension:3, shadows: {dx: 2, dy: 2, dw: 2}});
    	chart.addSeries("usl", [{x: 0, y: usl_value}, {x: signal1Series.length, y: usl_value}], {plot: "limits", stroke: {color:"red"}});
    	chart.addSeries("lsl", [{x: 0, y: lsl_value}, {x: signal1Series.length, y: lsl_value}], {plot: "limits", stroke: {color:"red"}});
    	chart.addSeries("ucl", [{x: 0, y: ucl_value}, {x: signal1Series.length, y: ucl_value}], {plot: "limits", stroke: {color:"yellow"}});
    	chart.addSeries("lcl", [{x: 0, y: lcl_value}, {x: signal1Series.length, y: lcl_value}], {plot: "limits", stroke: {color:"yellow"}});
    	chart.addSeries("ts",  [{x: 0, y: target}, {x: signal1Series.length, y: target}], {plot: "limits", stroke: {color:"green"}});
     
    	chart.addSeries("signal", signal1Series, {plot: "default", stroke: {color:"black"}, marker: "m-3,0 c0,-4 6,-4 6,0 m-6,0 c0,4 6,4 6,0"});
     
    	chart.connectToPlot(
      	     "default",
    	     function(evt) {
                      if(evt.type == "onclick") {
    				dijit.byId('dialog1').show();
    			}
    	     }
    	);
     
    	var anim2a = new dojox.charting.action2d.Magnify(chart, "default", {scale: 1.5});
    	var anim3b = new dojox.charting.action2d.Tooltip(chart, "default");
    	var anim2b = new dojox.charting.action2d.Highlight(chart, "default");
     
    	chart.addPlot("grid", {type: "Grid", hMinorLines: true});
          setInterval(function(){updateSignalData();}, 2000);
    	chart.render();
     
    	var legend = new dojox.charting.widget.Legend({chart: chart, horizontal: false}, "legend");
    };
     
    // add data to signal series
    var updateSignalData = function(){	
    	if(signal1Series.length == limit) {
    		signal1Series.shift(); // remove first item from the array
    	}
    	signal1Series.push(randomValue());
    	chart.updateSeries("signal", signal1Series);
     
    	updateLines(signal1Series.length);
     
    	chart.render();
    };
     
    // update target and limit lines
    var updateLines = function(length){
    	chart.updateSeries("usl", [{x: 0, y: usl_value}, {x: length, y: usl_value}]);
    	chart.updateSeries("lsl", [{x: 0, y: lsl_value}, {x: length, y: lsl_value}]);
    	chart.updateSeries("ucl", [{x: 0, y: ucl_value}, {x: length, y: ucl_value}]);
    	chart.updateSeries("lcl", [{x: 0, y: lcl_value}, {x: length, y: lcl_value}]);
    	chart.updateSeries("ts", [{x: 0, y: target}, {x: length, y: target}]);
    };
     
    // use dojo to build all objects
    dojo.addOnLoad(makeObjects);
  28. Trevor says:

    Doug, Dylan, and the Dojo crew,

    Great Job on this tutorial and this graphing widget! After much arm twisting from Matt, I finally gave Dojo a try, and I am very impressed. Dojo is looking like a very suitable replacement for JQuery. The dojo.query feature is very nice. Keep up the good work and I suspect I will be filling out one of those contributors forms in the near future.

  29. Sterling says:

    Thanks for this post! Keep the information about Dojo charts coming. There’s a big interest in this with the mapping and GIS community. For example, I am working on an example where a demographic chart appears when the user hovers the mouse over a county on a map. Hovering over a different county changes the chart.

Leave a Reply