[dojo-contributors] Chart Markup Proposal

Tom Trenka ttrenka at gmail.com
Thu Aug 30 18:04:33 EDT 2007


It occurs to me that as part of this markup proposal, probably an
explanation of what the engine itself will support would be a good idea.  So
in that spirit, here's what I'm looking at:
Held over from 0.4:
> Property mapping (i.e. myProp->x);
> Pluggable plotting (see below on this one); i.e. if you have a specific
type of plotter you need that the engine doesn't have, you can write your
own and use it without any kind of registry;
> Plot overlaying: the idea that you can put any number of Plots on a single
chart, each with either distinct or shared axes (it makes any kind of
combination charts *very* easy to do).
> Updating: the new engine will retain the ability for you to add new data
and re-render both data lines and axes based on passed info.

New for 0.9+:
> Theming
This is one of the biggest changes (outside of infrastructure).  Basically,
you can define a theme (it's an object but essentially a JSON-based
structure) and that's what a chart will use to render itself.  In addition,
you will be able to switch themes on the fly.  Everything a chart needs for
visual rendering is available in a Theme, and you can define piecemeal (the
system will mix your theme in with the default one, so that if you're only
looking for, say, a background image under the plotarea, you can do that).

Anything that dojox.gfx supports with most shapes can be used as part of a
theme def, with two exceptions: both the entire chart and the plotarea can
also take a background image reference, and the engine will generate the
necessary code for rendering.  Also, based on browser support, you can turn
anti-aliasing off or on--though admittedly this may be spotty (mostly due to
the way various browsers implement things).

(Note that background image rendering is *vector-based* and not what you'd
expect with CSS; if you think you'll be able to do background-repeat with
this, it will depend entirely on dojox gfx and the pattern fills, support
for which is still spotty (thanks, IE)).

> Custom markers
Instead of simply defaulting to circles to show points on a plotter such as
a line, you have the ability to specify a marker to show exactly where a
point is.  There are a number of pre-defined markers, and you have the
ability to create custom markers of your own, based on SVG
paths...basically, you define a path based on the starting point (starting
point is the actual coordinate of the data representation, and the system
will prepend that value to your path as an absolute value), and the engine
will simply use your definition in conjunction with the theme to put markers
on a chart.

> Targeted rendering
The new engine includes a way of telling a chart to re-render only the parts
of a chart that need it; you can do this by passing an array of values to
the chart's *invalidate* method (or none at all, which tells the engine to
redraw everything).  This will cause the chart to either redraw immediately
(if the chart is static), or it will keep the changes queued (in the case of
a timed update).

> Event stubs
A chart object has a number of event stubs for you to connect to, so that
you can create things like custom tooltips.  Only certain things on a chart
will fire some of the interactive events (i.e. only clicking on a marker
will fire onClick)...right now these names are standard event names but if
anyone has suggestions, I can add them now.

> DojoX GFX
The entire engine is being rewritten to use DojoX GFX.

>  Simplification of the API
The 0.4 PlotArea, Axis and Series objects have been eliminated; PlotArea has
been consolidated into Chart, and Axis and Series have been incorporated
into Plot.  The basics of creating a chart programmatically look a little
like this (actual args are still in flux):

var chart=new dojox.charting.Chart(args);
var plot=new dojox.charting.Plot(args);
plot.setAxis("x", { props });
plot.setAxis("y", { props });
plot.add([]);
plot.add({ obj });
chart.invalidate();

The native data format is an array of JS objects; dojo.data will *not* be
supported directly by the engine (support for dojo.data will be through
Dijit wrappers, which should allow you to consume dojo.data.Stores both via
markup and programmatically).

When I have something working and checked in, I will provide much better
examples of doing a chart than with my original test_engine (which was my
selfish test bed as opposed to examples).

> Chaining
Whereever possible, I'm setting up the engine to be chainable (like gfx is),
so you could do something like:

plot.add(data0)
   .add(data1)
   .add(data2);

> New plotters
Will be adding 0D axis charts (pie), new 1D (stacked bars), and a couple of
other plotters.  Again, suggestions here would be welcome.

Plotters have also been split out into separate resources, so that you can
require only the ones you need (as opposed to getting all of them, like the
0.4 engine does).  The Line plotter is the default.

> Legend generation
Legends can be generated; they will not be attached to the "domNode" of a
chart, instead you'll get a dojox gfx surface wrapped in a block node, and
you can append that where you need it in your page.  Legends will include
the color, marker and title of all data series (if provided).

---
Future directions
Once the engine is checked in and working relatively bug free, I'm planning
on the following enhancements:

1. Zoom and Pan, with navigator
Individual axes will be zoomable, with a drag/pan type system in place.
 Still trying to figure out the best way to do this UI wise, but right now
my inspiration is being drawn from audio editors (specifically, Sony
Creative's Sound Forge).  Suggestions welcome.


2. Sparklines
I will be creating a constructor (at the same level as Chart) for inline
sparklines, optimized for small rendering.  In theory, creating a sparkline
would look like this:

var sl=new dojox.charting.Sparkline(node, w, h);
sl.plotter=dojox.charting.plotters.Bar;   // Line will be the default, using
for illustration purposes.
sl.add(data)
    .invalidate();

// alternately
var sl=new dojox.charting.Sparkline(node, w, h, theme)
    .add(data)
    .invalidate();

I figure only a few plotters will be allowed to be used with sparklines:
pie, line, bar, area, maybe bubble.  Thoughts on this are more than welcome.

...
You know, there was a couple of other enhancements I was looking at but
right now I'm not remembering them.  Oh well--if there's something I missed,
ask and I'll answer.

trt

On 8/29/07, Tom Trenka <ttrenka at gmail.com> wrote:
>
> Inline.
>
> On 8/29/07, Brian Douglas Skinner <skinner at dojotoolkit.org> wrote:
> >
> > Hopefully Jared can chime in on this too, but here's my thinking...
> >
> > > One thing we need to keep in mind is that charts (especially
> > > large charts) can take a long time to render, particularly if
> > > there are a lot of points on it.
> >
> > Yup, understood.  Although, in the case of handling a few onNew()
> > notifications, the chart might be able to very quickly draw a few new
> > data points on the existing plot, rather than needing to re-render the
> > entire plot.
>
>
>
> It doesn't really work that way.  Most of the charts in question will be
> based on paths, which expect a full path definition as opposed to being able
> to just append a few points to the end of it; it kind of sucks but that's
> the way it works :(
>
> > I'm not interested in throttling unnecessarily but at the same
> > > time if we're talking about something pushed to the desktops of,
> > > say, a Fortune100 company with a lot of Windows 2000 machines all
> > > running FF1.5, the perception will end up being "Dojo sucks", and
> > > that's not something I want to foster.
> > >
> > > At the same time, we could probably do something where update
> > > notifications are caught by the charting engine and rendered
> > > periodically.
> >
> > That sounds good.  It seems like a useful idea to set things up so that
> > update notifications don't automatically trigger a re-rendering.  The
> > updates and update notification could still happen frequently, but the
> > charting widget could buffer them and then choose to only re-render
> > after a given interval.
>
>
>
> Right, exactly what I was thinking.
>
> > The main thing to think of here is to let the charting widget
> > > determine when an update is made (as opposed to a Store); from
> > > experience I've found that this is (by far) the best method.
> >
> > I'm not sure I'm parsing that sentence correctly.  If the word "update"
> > basically means "re-rendering" (rather than changing the data in the
> > datastore cache), then the sentence makes sense to me, and it sounds
> > like a good plan.  Am I reading it right?
>
>
> You are, in fact :)
>
> > Plus we need to consider that the chart widget itself may be
> > > the one asking the store for the update...
> >
> > Right now we don't have any way for a widget to ask the store for an
> > update.  That's not a pattern we've designed for.  The closest thing you
> > could do is re-issue the original fetch() query again, and then process
> > the results a second time, and a third time, and so on -- but if you did
> > that, you'd have to either (a) blindly redisplay the entire result set
> > even though probably no data has changed, or (b) do a diff to compare
> > the old result set to the new result set, and only redisplay if there's
> > been a change.  You'd have less screen flicker and/or less code in the
> > widget if you watched for onNew/onDelete/onSet notifications and only
> > re-render then, after you find out a change has really happened.
> >
>
> That's true, and that's what I was thinking about (the former).  There's
> an unfortunate disconnect when it comes to timed things and non-timed
> things, and (like I said, from experience) I kind of need to support both :(
>
>
>
> Fortunately the charting engine was designed so that you can take the
> "main" axis (usually x), set the range on it, and then filter out values
> that don't fall within it, but that may incur some additional overhead as
> well (think BETWEEN in SQL).
>
>
> trt
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.dojotoolkit.org/pipermail/dojo-contributors/attachments/20070830/eba1bc32/attachment.htm 


More information about the dojo-contributors mailing list