学习d3.js(以下都简称d3)也有一段时间了,运行d3做了几个项目。我发现中文的d3教程很少,国外资料多但要求有一定的英文阅读能力(推荐网址:http://bl.ocks.org/mbostock),于是就萌发了写一个d3实际运用系列文章的想法,现在开始付之行动。在系列中,我会用d3+html5 canvas实现一些实际效果(如统计结果展示,地图数据展示等),希望可以跟大家共同学习交流。
代码我公布在git.cschina.com上,大家可以clone到本地运行,地址是:http://git.oschina.net/0604hx/d3lesson
运行环境是java 7+,tomcat 7.0.47+(以后会用到websocket,所以需要javaee7 跟 tomcat 7+的支持),IDE 是IntelliJ IDEA 13, 项目的视图使用了freemarker。
这一章的示例代码主要介绍了d3.js的基本使用,如选择元素,动态修改元素属性、样式,为元素添加动画、鼠标事件监听。
示例中包含了d3.js对html元素(div,p,span这些)的操作(增删改),也包含了对svg元素(circle 圆,rect 矩形,line 线条等)的操作。
这里重点说一下d3中的data函数,如下:
//创建一个长度为10的整形数组, 得到的是: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
var data = d3.range(10);
//然后可以利用这个数组,创建10个对应的div元素,数组中的每个对象对应一个div
//这里选取的是class=test的div(好跟其他的div区别开来),在一开始调用selectAll('div.test')得到的其实是一个空集合
//接着调用data方法,就会根据传入对象的长度,创建相应长度的集合(这时集合里面元素都是空的,是给之后的div预留的空位置)
//再接着调用enter()方法,就是进入具体的集合元素里面,这时可以用append()、insert()这些方法创建html元素
//创建好div后,就可以给这个div属性赋值了
//在这里,我给div设置了class属性,接着往div中加入了文字。可以看到每个div就对应了上一步创建的数据中的一个元素,可以使用数据元素的数据了
d3.selectAll("div.test")
.data(data)
.enter()
.append("div")
.attr("class","test")
.html(function(d){
return d;
})
;
截图中有3个页面链接:
页面1 使用d3操作div元素,点击屏幕可以刷div的位置
页面2 效果同上,只是将div元素换成了svg的rect
页面3 介绍了d3对svg基本元素的操作,也包括data(),enter(),exit() 函数的使用
页面3的截图如下
附上核心代码:
/**
* 根据cmd命令在执行任务
*/
function work(cmd){
cmd = cmd ||'';
//随机画一个圆形
if(cmd=='circle'){
var c = g.append("circle")
.attr("class", "child")
.attr("cx", random(width))
.attr("cy", random(height))
.attr("r", random(100) + 20)
.attr("fill", colors(count))
;
count ++;
}
else if(cmd=='rect'){
var w = random(100)+20;
var r = g.append("rect")
.attr("class", "child")
.attr("x", random(width))
.attr("y", random(height))
.attr("width", w)
.attr('height', w)
.attr("fill", colors(count))
;
count ++ ;
}
//随机线条
else if(cmd=='line'){
var l= g.append("line")
.attr("class", "child")
.attr("x1", random(width))
.attr("y1", random(height))
.attr("x2", random(width))
.attr("y2", random(height))
.attr("stroke", colors(count))
;
count ++;
}
//清除最近添加的元素
else if(cmd=='clear'){
lastest.attr("opacity", 1)
.transition()
.duration(duration)
.attr("opacity", 0)
.each("end", function(){
d3.select(this)
.remove();
})
;
}
//清空全部的元素
else if(cmd=='clearAll'){
g.selectAll(".child")
.attr("opacity", 1)
.transition()
.duration(duration)
.delay(function(d,i){
return 50*i;
})
.attr("opacity", 0)
.each("end", function(){
d3.select(this)
.remove();
})
}
}