Open Source Charting Toolkits in JavaScript

Thu 22 October 2009
  • 手艺 tags:
  • canvas
  • dojo
  • html
  • javascript
  • mootools
  • svg
  • web published: true comments: true

项目的下一阶段,需要做一些数据展现方面的工作,处于对Adobe产品的抵触情绪,我个人还是倾向于用JavaScript来完成。今天找了几个画Chart的库,比较一下功能和编程接口的使用,为接下来的开发做一些准备。

dojox.charting

(BSD License)
没什么悬念,第一个想到的就是曾经用过的dojo。之前实习时候用dojo画chart也算是积累了一些心得。dojox.charting的最主要优点是编程接口完善、全面,可以配置的项目很多,接口易于编程,易于动态地生成、操作Chart。而另一方面最主要的问题就是文档比较匮乏,不了解的人可能问了,doc.dojotoolkit.org好强大,怎么会文档匮乏呢。其实是dojo和mootools类似,都很喜欢用option object来传递可选参数,但是这些option object在文档中没有任何涉及,很多关键的属性都在其中但是却没有办法查到,算是美中一大不足。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<script src="dojo-release-1.3.2/dojo/dojo.js" djConfig="isDebug: true"></script>

<title>Dojo</title>

<script type="text/javascript">

dojo.require("dojox.charting.Chart2D");

</script>

</head>

<body>

<h1>Dojox.charting</h1>

<div id="charting" style="width:400px; height:250px;">

</div>

<script type="text/javascript">

(function charting(){

dojo.empty("charting");

var data = [2,4,5,7,7,4,4,7];

var chart = new dojox.charting.Chart2D("charting");

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

chart.addPlot("additional", {type: "Areas"});

chart.addPlot("other", {type: "ClusteredColumns"})

chart.addAxis("x");

chart.addAxis("y", {vertical: true, min:0, max: 10});

chart.addSeries("Testing Data 1", data);

chart.addSeries("Average", dojo.map(data, function(it){return (Math.sin(it)+Math.random())*4}), {

fill: "rgba(145, 213, 100, 0.5)", plot:"additional"

});

chart.addSeries("All Random", dojo.map(data, function(it){return (Math.random()*5)}), {

plot: "other", fill: "#AEC6E2", stroke:{color:"#333", width:1}

});

chart.render();

})();

</script>

</body>

</html>

Protovis

(BSD License) Protovis,看域名就知道是斯坦福的项目,Protovis是在prototype基础上,不仅有charting的功能,还包括其他可视化方法的实现。看了Demo会发现它真的很不错,不过Protovis的本意似乎只是借助浏览器的图形功能实现可视化,它并没有提供超出可视化范畴的其他东西,甚至看过实例的代码你会发现,作者是不折不扣的函数式编程和链式方法的爱好者,Protovis的代码算是出神入化了,如果你想看看学术的JavaScript是如何写的,那就看看这个发表了论文的JavaScript库吧。
看起来是很出神入化,可是这样的编程接口如果要用在动态的数据展现上,实在是难以想象。况且,pv.Panel居然没有传入dom对象的接口,无从控制chart的生成位置。说白了,Protovis并不是一个满足项目需要的Library,不过它的功能和代码还是值得多看几眼的。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<script src="protovis-3.1/protovis-r3.1.js"></script>

</head>

<body>

<div id="page">

<h1>Protovis</h1>

<div style="border:1px #CCC solid;">

<script type="text/javascript">

var width = 300;

var height = 225;

var data = [1,2,3,4,6,7,5,8,9];

var dataMax = data[0];

for(var i=1; i<data.length; i++){

dataMax = dataMax > data[i] ? dataMax : data[i];

}

var x = pv.Scale.linear(0, dataMax).range(0, width);

var y = pv.Scale.ordinal(pv.range(10)).splitBanded(0, height, 0.9);

var charting = new pv.Panel();

charting.width(width).height(height).left(20).top(20);

var bar = charting.add(pv.Bar);

bar.data(data).top(function() y(this.index)).height(y.range().band).left(0).width(x);

bar.anchor("center").add(pv.Label)

.textStyle("white")

.textAlign("center")

.text(function(d) d.toFixed(1));

charting.add(pv.Rule)

.data(x.ticks())

.left(function(d) Math.round(x(d)) - .5)

.strokeStyle(function(d) d ? "rgba(255,255,255,.3)" : "#000")

.add(pv.Rule)

.bottom(0)

.height(5)

.strokeStyle("#C00")

.anchor("bottom").add(pv.Label)

.text(function(d) d);

charting.render();

</script>

</div>

</div>

</body>

</html>

Flotr

(MIT License)
不同于上面两个库通过SVG绘图,Flotr是用canvas api来完成绘制的。与dojo相比,Flotr的API比较简单,主要只有一个Flotr.draw方法,可以传入三个参数:目标DOM对象,数据和绘图选项。和dojo不同,Flotr的文档里关于这个option object有非常明确的文档。另外强大的是Flotr还提供了一些交互的功能,支持事件绑定。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<script src="flotr-0.2.0-alpha/flotr/lib/prototype-1.6.0.2.js"></script>

<script src="flotr-0.2.0-alpha/flotr/flotr-0.2.0-alpha.js"></script>

<title>Flotr</title>

<script type="text/javascript">

</script>

</head>

<body>

<h1>Flotr</h1>

<div id="charting" style="width:400px; height:250px;">

</div>

<script type="text/javascript">

(function d(){

var series1 = {data: (function(){

var d = [];

for(var i=0; i<10; i+=0.5){

d.push([i, Math.random()-0.5+Math.sin(i)*3]);

}

return d;

})(), label:"d1", lines:{fill:true}};

var series2 = {data: (function(){

var d = [];

for(var i=0; i<10; i+=0.5){

d.push([i, (Math.random()-0.5)*2+Math.cos(i)*2]);

}

return d;

})(), label: "s2", points:{show:true}, lines:{show:true}};

Flotr.draw($("charting"), [series1, series2], {

legend: {position :"se"},

yaxis: {min: -3.5, max:3.5}

});

})();

</script>

</body>

</html> 此外,还有一个与Flotr很类似的Protochart,后者的网站上写自己是motivated by Flotr,不过我很难想象功能几乎相同是如何motivated的。

MilkChart

(Apache License 2.0) MilkChart是一个建立在Mootools上的Charting库,采用canvas api绘图。它的特点是把HTML Table的数据绘制成Chart,如果场景允许,倒是省去了不少构建数组的麻烦。这个项目目前规模还不大,并且在作者积极的开发中,可以参考它的Wiki获得详细的使用方法。