In this article, learn how to use the Dojo Toolkit charting framework to create compelling charting applications that run on mobile devices. Learn how the charting component can be instantiated and configured inside a Dojo mobile application as well as how to enable touch interactions on the component for better integration with mobile devices. Also explore some advanced options for the charting application to load and render faster.
You can also download the source code of this article.
Creating a Dojo Mobile charting application
When building a mobile application with Dojo, it is recommended that you rely on
the dojox.mobile package. It's a relatively thin Dojo layer that
provides a mobile oriented set of lightweight widgets, a parser, and
a transition framework. Considering the importance of these features for
mobile applications, most mobile Dojo charting applications will likely
use this framework.
The simplest way to instantiate your chart in the context of a dojox.mobile
application is to rely on the parsing and put your
charting code inside the dojox.mobile widget markup (similar
to what you would do with a regular Dijit desktop application). First you
need an HTML file defining the markup of your application,
and a JavaScript source file referenced from the HTML that contains the
JavaScript logic for your application.
The example in this article shows you how to build a simple application that displays sales data using a column chart, divided by months, over a period of three years. Create an HTML file with the code in Listing 1.
Listing 1. Initial mobile charting application HTML file
<!DOCTYPE HTML>
<html>
<head>
<title>Dojo Toolkit Mobile Charting</title>
<meta name="viewport" content="width=device-width,initial-scale=1,
maximum-scale=1,minimum-scale=1,user-scalable=no"/>
<meta name="apple-mobile-web-app-capable" content="yes" />
<link rel="stylesheet" type="text/css"
href="../../../dojo_current/dojox/mobile/themes/iphone/iphone.css">
<script type="text/javascript" src="../../../dojo_current/dojo/dojo.js"
data-dojo-config="parseOnLoad: true"></script>
<script type="text/javascript" src="src_01.js" charset="utf-8"></script>
</head>
<body>
<div id="view1" data-dojo-type="dojox.mobile.View">
<h1 id="head1" data-dojo-type="dojox.mobile.Heading">Chart View</h1>
<div data-dojo-type="dojox.mobile.RoundRect">
<button id="b1" data-dojo-type="dojox.mobile.Button"
class="mblBlueButton">Zoom</button>
<button id="b2" data-dojo-type="dojox.mobile.Button"
class="mblBlueButton">Unzoom</button>
<div data-dojo-type="dojox.charting.widget.Chart" id="chart"
style="width: 100%; height: 180px;">
<div class="plot" name="grid" type="Grid"
vMinorLines="true"></div>
<div class="axis" name="x"
fixUpper="minor"
majorTickStep="1"
minorTicks="false"></div>
<div class="axis" name="y" vertical="true" min="0"></div>
<div class="plot" name="plot" type="Columns" ></div>
<div class="series" name="data" plot="plot"
data="20, 32, 32, 45, 37, 28, 24, 48, 44, 21, 32, 33,
32, 34, 44, 32, 39, 43, 44, 46, 36, 41, 25, 27,
28, 45, 46, 33, 34, 35, 29, 44, 48, 48, 49, 43"></div>
</div>
</div>
</div>
</body>
</html>
|
The code in Listing 1 is referencing dojox.mobile and
dojox.charting
classes in the Dojo data-type attributes. For this markup to be correctly
parsed and instantiated, the corresponding modules must be imported in the
JavaScript source file, as shown in Listing 2.
Listing 2. Initial mobile charting application JavaScript source file
require(["dojo", "dojox/mobile", "dojox/mobile/parser", "dojox/mobile/Button", "dojox/charting/widget/Chart", "dojox/charting/axis2d/Default", "dojox/charting/plot2d/Columns", "dojox/charting/plot2d/Grid"]); |
The examples in this article rely on the recently
introduced AMD syntax for managing dependencies of the Dojo
application. (See Resources to learn more
about AMD.) With backward
compatibility, a similar application can be built using the
superseded dojo.require format for dependencies if you don't want
to switch to the new format.
If you run the corresponding application, you should get the result shown in Figure 1.
Figure 1. A mobile charting application
The chart in Figure 1 is just a static non-interactive chart with hard-coded data from the data attribute of the series defined in the markup. Before going further, some minor adjustments to the application are needed.
At this point, the application is tailored for Webkit mobile and desktop browsers. If you want the application to run better on other desktop browsers, such as Firefox, you can update your dependency list to add the dojox/mobile/compat module, as shown in Listing 3. The example uses the dojo/has AMD plug-in to only include that module if you're not running a Webkit browser, so the compatibility module is required.
Listing 3. Adding non-Webkit browser support
require(["dojo/_base/kernel", "dojo/_base/sniff", "dojox/mobile", "dojox/mobile/parser", "dojo/has!webKit?:dojox/mobile/compat", "dojox/mobile/Button", "dojox/charting/widget/Chart", "dojox/charting/axis2d/Default", "dojox/charting/plot2d/Columns", "dojox/charting/plot2d/Grid"]); |
The next step is to feed the displayed charting data with an external data source instead of hard-coding data into the application. To do this, you can use the data store API of both Dojo Charting and Dojo Core.
There are classes in the dojo.data and dojox.data packages that let
you load data from various data sources and connect them to Dojo
components. For the example, assume you have the JSON data in Listing 4 on the server
and want to load it.
Listing 4. Sample JSON data
{
"items":
[
{"value": 0}, {"value": 32}, {"value": 32}, {"value": 45}, {"value": 37}, {"value": 28},
{"value": 24}, {"value": 48}, {"value": 44}, {"value": 21}, {"value": 32},
{"value": 33}, {"value": 32}, {"value": 34}, {"value": 44}, {"value": 32},
{"value": 39}, {"value": 43}, {"value": 44}, {"value": 46}, {"value": 36},
{"value": 41}, {"value": 25}, {"value": 27}, {"value": 28}, {"value": 45},
{"value": 46}, {"value": 33}, {"value": 34}, {"value": 35}, {"value": 29},
{"value": 44}, {"value": 48}, {"value": 48}, {"value": 49}, {"value": 43}
]
}
|
The JSON data can be loaded by an instance of
dojo.data.ItemFileReadStore. To proceed with charting, connect your dojo.data instance to a
Series object that will be in charge of populating the chart with data
items from the store.
You first have to modify the declaration of the series in the HTML
to not take hard-coded data as input, but to reference a data store named
"store." To do so, change the Series
definition in Listing 6 to include store="store", as shown in Listing 7.
Listing 6. Previous Series definition
<div class="series" name="data" plot="plot"
data="20, 32, 32, 45, 37, 28, 24, 48, 44, 21, 32, 33,
32, 34, 44, 32, 39, 43, 44, 46, 36, 41, 25, 27,
28, 45, 46, 33, 34, 35, 29, 44, 48, 48, 49, 43"></div>
|
Listing 7. Previous Series definition, including store
<div class="series" name="data" store="store" plot="plot"></div>
|
In the same HTML file you can define the store with the markup in Listing 8.
Listing 8. Store HTML definition
<div data-dojo-type="dojo.data.ItemFileReadStore" url="data.json"
data-dojo-id="store" urlPreventCache="true" clearOnClose="true"></div>
|
The code in Listing 8 uses the ItemFileReadStore class to load the data.json
file on the server and associate the results to the store variable that is
used as the input of the series. The data store class must be required into your
application as part of the source file require statement, as shown in
Listing 9.
Listing 9. Requiring
store class
require(["dojo/_base/kernel", "dojo/_base/sniff", "dojo/data/ItemFileReadStore",
"dojo/has!webKit?:dojox/mobile/compat",
"dojox/mobile", "dojox/mobile/parser",
"dojox/mobile/Button", "dojox/charting/widget/Chart",
"dojox/charting/axis2d/Default", "dojox/charting/plot2d/Columns",
"dojox/charting/plot2d/Grid"]);
|
You now have a mobile charting application rendering monthly data coming from the server. The example is still missing the x-axis displaying the target month instead of the data indexes. Reference a label function on the axis, as shown in Listing 10.
Listing 10. Specifying a label function
<div class="axis" name="x"
fixUpper="minor" majorTickStep="1"
minorTicks="false" labelFunc="displayDate"></div>
|
The displayDate function is then defined in the source file, as shown in Listing 11.
Listing 11. Implementing the label function in JavaScript
var displayDate;
require(["dojo/_base/kernel", "dojo/_base/sniff", "dojo/data/ItemFileReadStore",
"dojo/has!webKit?:dojox/mobile/compat",
"dojox/charting/action2d/TouchZoomAndPan",
"dojox/mobile", "dojox/mobile/parser",
"dojox/mobile/Button", "dojox/charting/widget/Chart",
"dojox/charting/axis2d/Default", "dojox/charting/plot2d/Columns",
"dojox/charting/plot2d/Grid"], function(dojo){
var months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
"Oct", "Nov", "Dec"];
var years = ["08", "09", "10", "11"];
displayDate = function(idx){
if ((idx%2) == 0){
return " ";
}
var m = parseInt(idx-1);
if (m%12 == 0){
// Display the year only for january
return months[m%12] + " " + years[m/12];
}else{
return months[m%12];
}
}
});
|
The code in Listing 11 basically maps each data index to a String. In the example, because there is monthly data over three years, the string is formed with the corresponding month for a given index.
You should now have the result shown in Figure 2.
Figure 2. Customizing axis labels
Enabling charting touch interaction
After you've created your Dojo mobile charting application, you might want to add specific mobile features to it, such as the ability to interact with the chart using touch gestures. This is relatively easy. Similar to other functions of the chart, you can add touch using a single line of code in the chart definition. For example, to add touch zoom and pan ability, you simply add the content of Listing 12 to the HTML markup.
Listing 12. Adding touch zoom and pan support
<div class="action" type="dojox.charting.action2d.TouchZoomAndPan"
plot="plot" maxScale="7"></div>
|
The plot attribute lets you attach the action to a particular plot of
the chart (in the example, the one named plot). You can also use various other
options, such as whether zooming is allowed (enableZoom="false"), or the
maximum scale you want to be applied onto the chart (maxScale="7").
Another useful touch interaction is to display a data indicator when touching the chart. It can even be a dual data indicator showing the trend between two touch points.
Using the code in Listing 13 yields the result in Figure 3 when touching the chart with a single touch.
Listing 13. Adding touch indicator support
<div class="action" type="dojox.charting.action2d.TouchIndicator" plot="plot"
series="data" dualIndicator="true"></div>
|
Figure 3. Interactive simple touch indicator
With a dual touch gesture you get the result shown in Figure 4.
Figure 4. Interactive dual touch indicator
Several other parameters are available on the touch interactions, such as the ability to change the colors and font of the data indicator. You can even decide to change the fill color of the indicator based on whether the trend between the two touch points is positive or negative. Listing 14 shows an example of how to build such an indicator in JavaScript.
Listing 14. Configuring a touch indicator in JavaScript
var indicatorFillFunc = function(v1, v2){
if(v2){
return v2.y>v1.y?"green":"red";
}else{
// single touch point
return "#ff9000";
}
};
var indicator = new TouchIndicator(chart, "plot", {
series: "series", dualIndicator: true,
font: "normal normal bold 12pt Helvetica",
fillFunc: indicatorFillFunc
});
|
Some mobile devices, such as Android 2.2 and 2.3, do not support multiple touch events in the browser. You might want to map certain actions that rely on dual touch, such as zooming in and out, to buttons and touch interactions to cover all devices. For this situation, there have been inactive buttons in the user interface since the first listing in this article. It's now time to add some code to react when clicking or touching these buttons. Listing 15 shows how to specify a zoom function.
Listing 15. Specifying a zoom function
<button id="b1" data-dojo-type="dojox.mobile.Button"
onclick="zoomChart()"
class="mblBlueButton">Zoom</button>
<button id="b2" data-dojo-type="dojox.mobile.Button"
onclick="zoomChart(true)"
class="mblBlueButton">Unzoom</button>
|
The code in Listing 15 calls the zoomChart function on
both the zoom and unzoom buttons. Because
zoom and unzoom actions are very similar, you use only one function with
an argument set to true for unzoom.
Define the zoomChart function in the JavaScript
source file, as shown in Listing 16. The idea is to get the current visible bounds to compute a
new range to pass to the zoomIn function of the Dojo chart component.
Listing 16. Implementing the zoom function in Javascript
zoomChart = function(back){
var chart = dijit.byId("chart").chart;
var b = chart.getAxis("x").getScaler().bounds;
var r = 1.25;
if (back){
// Unzoom
chart.zoomIn("x", [b.from / r, b.to * r]);
}else{
// Zoom
chart.zoomIn("x", [b.from * r, b.to / r]);
}
};
|
You now have a fully working Dojo mobile charting application, but it isn't fully optimized.
The first type of optimization you'll work on is improving
rendering time. Mobile devices usually have slower CPU and memory
than desktop devices and thus slower rendering. By default, Dojo does not
cache the rendered item of a chart. When using the touch
interaction to zoom or pan the chart, a lot of renderer items might be
destroyed and rebuilt. Not enabling caching is good when you have a static
chart because it gives a faster initial rendering. However, in a dynamic
use case, it's preferable to enable caching. You can use the
enableCache parameter of several charting elements.
In the code, set enableCache to true on the chart
elements, as shown in Listing 17.
Listing 17. Optimizing rendering
<div data-dojo-type="dojox.charting.widget.Chart" id="chart"
style="width: 100%; height: 180px;">
<div class="plot" name="grid" type="Grid"
vMinorLines="true" enableCache="true"></div>
<div class="axis" name="x" enableCache="true"
fixUpper="minor"
majorTickStep="1"
minorTicks="false"
labelFunc="displayDate"></div>
<div class="axis" name="y" vertical="true" min="0"></div>
<div class="plot" name="plot" type="Columns" enableCache="true"></div>
<div class="series" name="data" store="store" plot="plot"></div>
<div class="action" type="dojox.charting.action2d.TouchZoomAndPan"
plot="plot" maxScale="7"></div>
</div>
|
The example did not enable caching on the y-axis. When zooming in or out, the chart along the y-axis is not re-rendered and thus would not benefit from optimization.
Another way to optimize the mobile charting application rendering is to prevent
unnecessary rendering. For example, a column plot might have outlines or
shadows that are not absolutely necessary but they consume rendering time.
You might consider removing them. Another example is the data indicator,
for which you can remove outline strokes by setting the corresponding
style properties to null, as shown in Listing
18.
Listing 18. Removing unnecessary rendering
<div class="action" type="dojox.charting.action2d.TouchIndicator" plot="plot"
series="data" dualIndicator="true" outline="null" lineOutline="null"
markerOutline="null"></div>
|
It's important to optimize the loading time of the application, especially on mobile devices where network connections are
not always as fast as their desktop counterparts. With the new AMD loader available in Dojo, instead of loading the
various required files synchronously you'll be able to load the files
asynchronously and increase overall loading performance. Add the async parameter on Dojo initial
configuration, as shown in Listing 19.
Listing 19. Enabling asynchronous loading
<script type="text/javascript" src="../../../dojo_current/dojo/dojo.js"
data-dojo-config="parseOnLoad: true, async: true"></script>
|
You can improve loading time even further by removing any utilities
that are not absolutely needed by your application. For example,
the entire mobile charting application was defined using markup that relies on the
dojox.mobile parser. This lightweight parser is
much lighter
than the regular Dojo parser. If you really want to further reduce
your application download size, you can get rid of the parser entirely and
build your application in JavaScript.
In this article, you learned how you can use the Dojo charting package inside a mobile web application. It can be tailored to mobile devices to rely on touch events for interaction instead of relying on mouse or button paradigms. This article also explored some advanced options you can use to improve loading and rendering time.
If you are interested in pursuing the topic further, Dojo charting is designed to be extensible. You can build your own features on top of it. For example, if you are in need of a touch interaction not provided by the framework, you can extend the Dojo charting action package to create your own interactions.
| Description | Name | Size | Download method |
|---|---|---|---|
| Source code | source.zip | 10KB | HTTP |
Information about download methods
Learn
-
Read Asynchronous Modules Come to Dojo 1.6, a blog post about AMD.
- Review the Dojo charting
documentation.
- "Get started with Dojo Mobile 1.6" (developerWorks, June 2011)
describes how to include and use Dojo Mobile widgets and components in your
applications. Also see how to wrap your web application in a native application using PhoneGap.
- See the Mobile Charting Example on IBM
WebSphere Application Server Feature Pack for Web 2.0 and Mobile
Showcase.
- Learn about WebSphere Application Server Feature Pack for Web 2.0 and
Mobile.
Get products and technologies
- Get the Dojo Toolkit.
- Download IBM product
evaluation versions, and get your hands on application development
tools and middleware products from DB2, Lotus, Rational, Tivoli, and
WebSphere.
Discuss
- Create your developerWorks profile today and set up a watchlist on Dojo and mobile application development. Get
connected and stay connected with developerWorks community.
- Find other developerWorks members interested in web development.
- Share what you know: Join one of our developerWorks groups focused on web
topics.
- Roland Barcia talks about Web 2.0 and middleware in his blog.
- Follow developerWorks' members' shared bookmarks on web topics.
- Get answers quickly: Visit the Web 2.0 Apps forum.
- Get answers quickly: Visit the Ajax forum.

Christophe Jolif is an advisory software engineer at IBM France. He leads the IBM ILOG Elixir development team and contributes to the Dojo Toolkit open source project. He writes about ILOG Elixir on the team blog and in technical articles, and also contributes to the product technical documentation. Before joining IBM, Christophe worked for ILOG for more than a decade, developing advanced visualization components in Java™, Ajax and Adobe® Flex.

Damien Mandrioli is a software engineer at IBM. His professional interests include visualization components, web application development, and user interface usability. Damien spent five years developing components and demos for the IBM ILOG Elixir visualization product before joining the Dojo Toolkit development team.




