- 手艺 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的。