Plans for barcharts, scatterplots etc?

171 views
Skip to first unread message
Message has been deleted

Grant Paton-Simpson

unread,
Jun 22, 2009, 7:01:13 PM6/22/09
to raph...@googlegroups.com
Hi,

I am looking for a charting library for my open source project SOFA
(Statistics Open For All) - http://www.sofastatistics.com. I need
charts which are web friendly, beautiful, and printable. Flash is
beautiful but printing is a big issue. RaphaelJS looks really good and
I like the use of SVG as the underpinning. I saw the pie chart but I
couldn't see bar charts (including clustered) etc. Are there plans to
create these or will I need to have a try at that myself?

My priority needs are:
bar charts (vertical), clustered bar charts (vertical), with error bars
as an option if possible
area charts (possibly allowing for stacked)
line charts (multiple lines)
scatterplots
pie charts

I could fall back on more prosaic options for other charts e.g. using
jqplot, but I would rather start with one approach and stick with it.


All the best, Grant


Dmitry Baranovskiy

unread,
Jun 22, 2009, 8:52:24 PM6/22/09
to Raphaël
I am working on set of plugins for Raphaël to do charting. Estimated
release date is November-ish. :)

On 23 June, 09:01, Grant Paton-Simpson <gr...@p-s.co.nz> wrote:
> Hi,
>
> I am looking for a charting library for my open source project SOFA
> (Statistics Open For All) -http://www.sofastatistics.com.  I need

pyGrant

unread,
Jun 22, 2009, 10:07:18 PM6/22/09
to Raphaël
Fantastic. Are you thinking of releasing them all at once or will you
start with one in particular? I estimate 70% of my users' needs would
be met by pie charts (already there) and simple bar charts.

On Jun 23, 12:52 pm, Dmitry Baranovskiy <dmitry.baranovs...@gmail.com>
wrote:

Dmitry Baranovskiy

unread,
Jun 22, 2009, 10:21:21 PM6/22/09
to raph...@googlegroups.com
Pie chart and simple bar chart are done. You could have it, but I will not guarantee that API will remain the same.

http://github.com/DmitryBaranovskiy/g.raphael/tree/master

Use it on your own risk. :)

pyGrant

unread,
Jun 23, 2009, 12:10:58 AM6/23/09
to Raphaël
Understood. I will have a look at it ASAP.

On Jun 23, 2:21 pm, Dmitry Baranovskiy <dmitry.baranovs...@gmail.com>

pyGrant

unread,
Jun 23, 2009, 11:36:11 PM6/23/09
to Raphaël
Reporting back:

Having some success with animating the graph and making it respond to
hover in and out with sequential animations (only changing colour and
stroke at this stage).

Dmitry - what are your plans for bar charts specifically? What
functionality are you planning to add? Will it be possible to animate
individual bars e.g. when hovering over?

Re: label font size and bar width, are those going to be controlled
internally somehow? Or should the external program handle that?

pyGrant

unread,
Jun 24, 2009, 6:12:49 PM6/24/09
to Raphaël
BTW imagine making it easy to do dynamic scatterplots like this:

http://www.ted.com/talks/hans_rosling_shows_the_best_stats_you_ve_ever_seen.html

Looking at the animate, size, colour etc methods for circles in
Raphael this looks very, very doable as a standard way of displaying
changing distributions (not necessarily by time but perhaps by any
other variable e.g. income, years in school etc.

Jack

unread,
Jun 23, 2009, 4:41:58 PM6/23/09
to Raphaël
Hi Dmitry,

I ran with your line graph example (http://raphaeljs.com/
analytics.html), and here is some code I added to label and scale the
y-axis. I'm using Prototype 1.6.0.3. This code isn't groundbreaking by
far, but maybe it'll save you a little time. I'm a boob (big + noob),
but I'd like to help where I can...

/**
* I return the appropriate scale for the y-axis.
* For example, a line graph with values between 0 and 1 should
have tick marks every 0.1 units while a graph
* with values between 1,000 and 2,000 should have tick marks
every 500 units.
*
* @param iMaxDiff int the difference between the largest and
smallest value on the graph
* @return int
*
*/
getYAxisScale: function (iMaxDiff) {
var iScale; // integer scale of y-axis
if (iMaxDiff < 500) {
if (iMaxDiff < 10) {
if (iMaxDiff < 1) {
iScale = 0.1;
} else {
iScale = 2;
}
} else {
if (iMaxDiff < 100) {
iScale = 5;
} else {
iScale = 25;
}
}
} else {
if (iMaxDiff < 1000) {
iScale = 50;
} else {
if (iMaxDiff < 10000) {
iScale = 500;
} else {
iScale = 1000;
}
}
}
return iScale;
},

For the y-axis, I found myself comparing small differences in big
numbers, and starting the y-axis from zero didn't make for a good
chart. In addition, I wanted the y-axis to begin and end at whole
numbers that made sense (instead of some Excel charts that start at
1,267 and run to 1,789 - who can remember that?).

The Raphael object (this.oR), width, height, gutter sizes, colors, and
text attributes are all defined as properties of my Chart_TimeSeries
class. I put a single character in front of most of my vars so I can
remember their type (i=int, s=str, o=obj, etc). In addition, the class
has an array of values (this.valuesArr), and an array of dates
(this.datesArr).

I just included the parts of the fxn that changed...

/**
* I draw this line chart.
*
*/
drawChart: function () {
var X, // width of one point (eg, if there are 5
values and chart width is 500px, each point gets 100px)
Y, // height of one unit of value (eg, if
value is 213 and chart height is 300px, each y 'unit' is 1.4px)
x, // x-coordinate of point
y, // y-coordinate of point
iMax, // min value in values array
iMin, // max value in values array
diffMinArr, // the difference between each value and the minimum
value
iMaxDiff, // the biggest difference (the peak-to-peak
amplitude)
iScale, // scale of the y-axis
iCeil, // closest multiple of scale that's larger than
max value
iFloor, // closest multiple of scale that's smaller than
min value
iWall, // difference between ceiling and floor
iTicks, // number of tick marks on left axis
diffArr; // the difference between each value and the
computed floor

// set grid and y-axis vars
iMax = Math.max.apply(Math, this.valuesArr);
iMin = Math.min.apply(Math, this.valuesArr);
diffMinArr = [];
for (var i=0, len=this.valuesArr.length; i<len; ++i) {
diffMinArr.push(this.valuesArr[i] - iMin);
}
iMaxDiff = iMax - iMin;
iScale = this.getYAxisScale(iMaxDiff);
iCeil = Math.ceil(iMax/iScale) * iScale;
iFloor = Math.floor(iMin/iScale) * iScale;
iWall = iCeil - iFloor;
iTicks = iWall / iScale;
X = (this.iWidth - this.iLeftgutter) / this.datesArr.length;
Y = (this.iHeight - this.iBottomgutter - this.iTopgutter) / iWall;
// adjust differences to new floor
diffArr = [];
for (i=0, len=this.valuesArr.length; i<len; ++i) {
diffArr.push(this.valuesArr[i] - iFloor);
}
// draw grid
// only change here is the number of grid lines change
with the data set
this.oR.drawGrid(this.iLeftgutter + X * 0.5, this.iTopgutter,
this.iWidth - this.iLeftgutter - X, this.iHeight - this.iTopgutter -
this.iBottomgutter, this.valuesArr.length - 1, iTicks, "#ccc");
// add y-axis labels
for (i=0; i<=iTicks; ++i) {
this.oR.text(this.iLeftgutter + X * 0.5 - 15, this.iTopgutter + i *
iScale * Y, (iCeil - i * iScale).comma()).attr(this.oYLabel).toBack();
}
// set chart vars

... no changes from your example ...

}

Hope that helps.



On 22 June, 21:21, Dmitry Baranovskiy <dmitry.baranovs...@gmail.com>
wrote:
Reply all
Reply to author
Forward
0 new messages