Zooming, Scrolling, and Panning in Dojo Charting May 15th, 2008 at 12:37 am by Eugene Lazutkin
As mentioned in my previous post Dojo Charting Reorganization, this week I worked on zooming, scrolling, and panning of charts. It turned out to be a more complex task than I anticipated due to the little-known fact that Dojo Charting can stack multiple plots per chart and can show multiple independent axes on all 4 sides of the chart. These problems were solved and a new API was introduced on the chart object:
- chart.setAxisWindow(name, scale, offset) — defines a window on the named axis with a scale factor, which starts at the set offset in data coordinates.
- The scale parameter must be >= 1.
- The offset parameter should be >= 0.
- For example if I have an array of 10 numeric values, and I want to show them ##3-8, chart.setWindow(”x”, 3, 2) will do the trick.
- This call affects only plots attached to the named axis, other plots are unaffected.
- chart.setWindow(sx, sy, dx, dy) — sets scale and offsets on all plots of the chart.
- The sx parameter specifies the magnification factor on horizontal axes. It should be >= 1.
- The sy parameter specifies the magnification factor on vertical axes. It should be >= 1.
- The dx parameter specifies the offset of horizontal axes in pixels. It should be >= 0.
- The dy parameter specifies the offset of vertical axes in pixels. It should be >= 0.
- All chart’s axes (and, by extension, plots) will be affected.
Obviously these new methods do sanity checks, and don’t allow you to scroll outside of axis’ boundaries, or zoom out too far.
As you can see these methods are enough to implement arbitrary zooming to drill down to the smallest details of your chart, scrolling, and panning (moving the chart with you mouse in two dimensions). The latter functionality is taxing on the browser, but the new generation of browsers (Firefox 3, Safari 3, Opera 9.5) are up to the task.
While this functionality is available now in the trunk, I plan to incorporate the panning support directly into the Charting widget, so it can be turned on and off by a parameter.
Now it is time for some show-and-tell. Below you can see my test chart in its normal state:
As you can see this chart has 4 independent axis on all sides, and two plots, each with independent axes: the light brown plot uses the bottom and the the left axes, while the dark brown plot uses the axes on the top and the right sides.
You can access this test application in Dojo Nightlies. Warning: this link uses the raw Dojo served directly from Dojo development server, so the initial loading will be relatively slow. In real applications you should use Dojo builds.
This is the code required to build this chart:
// create our chart var chart = new dojox.charting.Chart2D("test"); // set a theme chart.setTheme(dojox.charting.themes.PlotKit.orange); // create the ordinal horizontal axis with custom visual attributes, // by default it will be attached to the bottom of the plot area chart.addAxis("x", { fixLower: "minor", natural: true, stroke: "grey", majorTick: {stroke: "black", length: 4}, minorTick: {stroke: "gray", length: 2} }); // create the ordinal vertical axis with custom visual attributes, // by default it will be attached to the left of the plot area chart.addAxis("y", { vertical: true, min: 0, max: 30, majorTickStep: 5, minorTickStep: 1, stroke: "grey", majorTick: {stroke: "black", length: 4}, minorTick: {stroke: "gray", length: 2} }); // add the front plot, which uses default axes (named "x" and "y") chart.addPlot("default", {type: "Areas"}); // add series to the default plot chart.addSeries("Series A", [0, 25, 5, 20, 10, 15, 5, 20, 0, 25] ); // create the ordinal horizontal axis with custom visual attributes, // we specify explicitly that it should be attached to the top chart.addAxis("x2", { fixLower: "minor", natural: true, leftBottom: false, stroke: "grey", majorTick: {stroke: "black", length: 4}, minorTick: {stroke: "gray", length: 2} }); // create the ordinal vertical axis with custom visual attributes, // we specify explicitly that it should be attached to the right chart.addAxis("y2", { vertical: true, min: 0, max: 20, leftBottom: false, stroke: "grey", majorTick: {stroke: "black", length: 4}, minorTick: {stroke: "gray", length: 2} }); // create the back plot, which uses our custom axes ("x2" and "y2") chart.addPlot("plot2", { type: "Areas", hAxis: "x2", vAxis: "y2" }); // add series to "plot2" we just created chart.addSeries("Series B", [15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15], {plot: "plot2"} ); // add the bottom of our stack we put the grid // that shows major lines, and horizontal minor lines chart.addPlot("grid", {type: "Grid", hMinorLines: true}); // show what we've built chart.render();
Now let’s see it magnified by 2 in both dimensions and moved so we can see the peaks in the middle-left part of the chart:
This picture above was made from the previous picture with one call:
chart.setWindow(2, 2, 181, 143).render();
Obviously axes show new labels to reflect the new state of the chart. Using these labels we can get our bearings and understand what we are looking at.
If we want to return back we can always do:
chart.setWindow(1, 1, 0, 0).render();
Coming Attractions
Now is a good time to start working on Chart event support, so developers will be able to add actions depending on where the user clicked, or hovered over. A highly requested feature, events can be used to do a range of things starting from synchronizing an external table with the current position of the chart, to showing some supplementary information on clicked points.
I plan to add Tooltip widget support to the Chart widget — it will cover the most frequent case of the event processing. Stay tuned!
Tags: ajax, Dojo, Open Source, Vector Graphics





Posted May 15th, 2008 at 8:50 am
Awesome stuff!
What is the plan for making it work in IE(6)?
I.e. I tested http://archive.dojotoolkit.org/nightly/dojotoolkit/dojox/charting/tests/test_bars.html that one doenst show anything in IE6, is it because its using 3D bars? Is there a roadmap/plan one can look up?
Thanks for the great work
Wolfram
Posted May 15th, 2008 at 10:09 am
Only 2D charts are affected by recent changes. There is a new 3D graphics effort underway as a part of the Google SoC. I prefer waiting for it to be finished before we start advancing 3D charting.
Posted May 27th, 2008 at 11:21 pm
[…] mentioned in Zooming, Scrolling, and Panning in Dojo Charting, our next goal to tackle was charting events. I am happy to announce that event support for […]
Posted June 16th, 2008 at 12:08 am
[…] also want to check out Eugene’s posts on the new Dojo 1.2 Charting features, including scrolling and zooming, charting events and widgets, tooltips, and […]
Posted October 1st, 2008 at 12:54 am
Hi,
Is there a way to get the grid values through mouse movement. What i mean here is that i want to zoom the chart on the x-axis, and the functionality should be that, considering the second chart here, if the user clicks between 3 and 4 on the chart, the chart could be redrawn with x-axis starting from 3 and ending at 4.
SO to have a api from dojo which can give me the position of the mouse respective of the chart.
Thanks
Kunal
Posted October 3rd, 2008 at 12:09 pm
It appears the “Offset” functionality is broken now? I can’t get it working in code, and the Offset sliders on the demo page don’t do anything :(
http://archive.dojotoolkit.org/nightly/dojotoolkit/dojox/charting/tests/test_win2d.html
Posted October 6th, 2008 at 2:07 pm
@kunal: it is simple to do. You can do it like that (example for x):
var scaler = chart.getAxis(”x”).getScaler();
var fromPlot = dojox.charting.scaler.linear.getTransformerFromPlot(scaler);
var fromModel = dojox.charting.scaler.linear.getTransformerFromModel(scaler);
You can use it like that:
var x = 100; // x is a coordinate in pixel in the plot space
var X = fromPlot(x); // X is in your model coordinates
or:
var X = 5; // X is in your model coordinates
var x = fromModel(X); // x is in pixels relative to the plot
You can get the plot area coordinates from chart.surface.rawNode.
Posted October 6th, 2008 at 2:08 pm
@Laura: I’ll check this functionality tonight. It should work.
Posted October 7th, 2008 at 10:08 pm
A good product but nothing as frustrating as poor or lack of documentation. Since when did blogging replace proper documentation.
Posted October 8th, 2008 at 4:50 am
@Tony - There is a massive community and committer driven documentation project underway at http://docs.dojocampus.org - the initial tests from sphinx dumps has the content at a 500-page PDF, and a very comprehensive collection of working examples, notes, and techniques. We’ve gone to a wiki format for easiest editing, and will be producing static dumps in PDF and HTML form for offline viewing and increased online access speed.
Also, the API pages are back online at http://api.dojotoolkit.org
I urge you [and others] to participate in filling in any blanks in documentation, as Dojo is an enormous project, and our resources are not unlimited.
Posted October 8th, 2008 at 4:47 pm
@Laura: just checked and it works as expected. Offsets do not allow you to scroll outside of the visible area of the chart. You should zoom in first before using offsets. The initial state shows all data, so there is no room for scrolling.
Posted October 31st, 2008 at 11:30 pm
x:6~17 y:0~500 Can you tell me how to do this with chart.setWindow(….).render(); Thanks.
Posted October 31st, 2008 at 11:31 pm
chart.addAxis(”x”, {
fixLower: “minor”, natural: true, stroke: “grey”,
majorTick: {stroke: “black”, length: 4},
minorTick: {stroke: “gray”, length: 2}
});
chart.addAxis(”y”, {
vertical: true, min: 0, max: 500,
majorTickStep: 100, minorTickStep: 100, stroke: “grey”,
majorTick: {stroke: “black”, length: 4},
minorTick: {stroke: “gray”, length: 2}
});
Posted November 6th, 2008 at 2:37 pm
@胡三春: You can see how it is done in http://archive.dojotoolkit.org/nightly/dojotoolkit/dojox/charting/tests/test_win2d.html — the points of interest are calls to setWindow() method. The method itself is described in this blog post above. If you want to see a specific window, you should recalculate it to scale/offset parameters.
The scale of 1 is fully shown picture. The scale of 2 will zoom in 2x. All offsets are in pixels. For example, if your X span is 1000px, and you have 10 units fit in here, in order to zoom in 2x and show the second half you shold use scale = 2, and offset = 1000 * scale * 0.5 = 1000.
In order to know how much pixels you have for the plot, you can get a relevant axis using Chart2D.getAxis(name) (”y” in this case), and call getOffsets() on it. The latter returns an object with l, t, r, b properties (left, top, right, and bottom respectively). You should subtract relevant numbers from the total chart size you specified when creating the chart.
Posted December 7th, 2008 at 11:24 am
@Peter Higgins
“I urge you [and others] to participate in filling in any blanks in documentation, as Dojo is an enormous project, and our resources are not unlimited.”
This something that can only be done by the people that wrote the code.. they’re the only ones with the knowledge to write the documentation. The rest of us could subsequently help out with tutorials and examples, but only if we have access to good API documentation. As Tony remarks, the current experience with Dojo often results in frustration due to a lack of good API documentation.
Posted January 19th, 2009 at 4:00 am
Just tested http://archive.dojotoolkit.org/nightly/dojotoolkit/dojox/charting/tests/test_event2d.html and http://archive.dojotoolkit.org/nightly/dojotoolkit/dojox/charting/tests/test_win2d.html with Iceweasel (Firefox) 3.0.5 on Debian Lenny and no charts are drawn. Javascript console shouts about “dojo._hasResource is undefined” lots of times. ¿Any hint? Thanks.
Posted January 19th, 2009 at 11:04 am
@Eneko: you witnessed a very rare event: the nightlies are broken by some unsuccessful patch causing all tests to fail. I don’t recall such thing since … forever.
Do not forget that Dojo is under active development and nightlies are snapshots of the trunk. Just wait until the next snapshot is done (automatically once in 24 hourse) and try again.
Posted April 1st, 2009 at 1:11 am
Eugene Lazutkin :
Thanks for your excellent job make our life easy, and I have two question need your help.
1. Just as Kunal says, does dojo have api which can give us the position of the mouse respective of the chart when click.
2. Just as your reply to 胡三春,”if your X span is 1000px, and you have 10 units ….”. I want to know whether dojo has a api can tell us the current span of chart(and axis x,y).
Looking forward your kindly reply as soon as possible.