<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>testD3-18-update.html</title>
<script type="text/javascript" src="http://localhost:8080/spring/js/d3.v3.js"></script>
</head>
<body>
<button>单击更新</button>
<br>
<p>单击添加</p>
<br>
<a>单击删除</a>
<br>
<script type="text/javascript">
//(1) 准备数据集
var dataset = [ 5, 10, 13, 19, 21, 25, 22, 18, 15, 13,
11, 12, 15, 20, 18, 17, 16, 18, 23, 25 ];
//(2) 设置SVG的高宽
var w=600;
var h=250;
var barPadding = 1;
//(3) 定义比例尺
var xScale=d3.scale.ordinal()// x是序数比例尺
.domain(d3.range(dataset.length))
.rangeRoundBands([0,w],0.05);
var yScale=d3.scale.linear()// y仍然是线性比例尺
.domain([0,d3.max(dataset)])
.range([0,h]);
//(4) 创建SVG元素
var svg = d3.select("body")// 选中DOM中的目标元素
.append("svg")// 为目标元素附加上一个svg子元素
.attr("width", w)// 设置这个svg的宽
.attr("height", h);// 设置这个svg的高
//(5) 为SVG添加条形
svg.selectAll("rect")// 选中空元素,表示即将创建这样的元素
.data(dataset)// 对此后的方法都执行dataset.length次迭代
.enter()// 数据元素值比前面选中的DOM元素多就创建一个新的DOM元素
.append("rect")// 取得enter的占位元素,并把rect追加到对应的DOM中
.attr("x", function(d, i) {// 设置横坐标
//return i * (w / dataset.length); // 从0开始每次右移元素宽那么长(w / dataset.length)
return xScale(i);// 这里使用序数比例尺,自己去找刚才划分好的档位
})
.attr("y", function(d) {// 设置纵坐标,纵坐标正方向是从上往下的,所以条有多长就要设置起点是相对于h再向上移动条长
return h - yScale(d);
})
//.attr("width", w / dataset.length - barPadding)// 设置元素宽,留出间隙宽barPadding。
.attr("width", xScale.rangeBand())// 这里xScale比例尺已经设置间距了所以直接用
.attr("height", function(d) {
return yScale(d);
})
.attr("fill", function(d) {//设置RGB颜色与数值的关系
return "rgb(0, 0, " + (d * 10) + ")";
});
//(6) 为条加上数值
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text(function(d) {
return d;
})
.attr("text-anchor", "middle")
.attr("x", function(d, i) {
return xScale(i)+xScale.rangeBand()/2;
})
.attr("y", function(d) {
return h - yScale(d) + 14;
})
.attr("font-family", "sans-serif")
.attr("font-size",function(d) {
return xScale.rangeBand()/2;
})
.attr("fill", "white");
//(15) 删除一条
d3.select("a")
.on("click",function(){
//选择所有条
dataset.shift();
//更新X轴比例尺
xScale.domain(d3.range(dataset.length));
var bars=svg.selectAll("rect")
.data(dataset);
bars.exit()
.transition()
.duration(500)
.attr("x", w)
.remove();
});
//(14) 添加一条
d3.select("p")
.on("click",function(){
//数据集最后添加数值
var maxValue=75;
var newNumber =Math.floor(Math.random()*maxValue);//0-24的整数
dataset.push(newNumber);
//更新X轴比例尺
xScale.domain(d3.range(dataset.length));
//选择所有条
var bars=svg.selectAll("rect")
.data(dataset); //绑定数据到元素集,返回更新的元素集
var texts=svg.selectAll("text")
.data(dataset);
//添加条形元素到最右边
bars.enter()
.append("rect")
.attr("x",w);//在SVG最右边,不可见
//
texts.enter()
.append("text");
//更新新矩形到可见范围内
//并在这个时候根据数据集为每个条设置对应的属性
bars.transition()
.duration(500)
.attr("x", function(d, i) {
return xScale(i) ;
})//每个X对应到它相应的档位上
.attr("y", function(d) {
return h - yScale(d) ;
})
.attr("width", xScale.rangeBand())//这里xScale比例尺已经设置间距了所以直接用
.attr("height", function(d) {
return yScale(d);
})
.attr("fill", function(d) {//设置RGB颜色与数值的关系
return "rgb(0, 0, " + (d * 10) + ")";
});
texts.transition()
.duration(500)
.text(function(d) {
return d;
})
.attr("text-anchor", "middle")
.attr("x", function(d, i) {
return xScale(i)+xScale.rangeBand()/2;
})
.attr("y", function(d) {
return h - yScale(d) + 14;
})
.attr("font-family", "sans-serif")
.attr("font-size", "12px")
.attr("fill", "red");
});
//(7) 更新条形数长短的代码,需要一个button标签配合
//特别注意:这里选中的元素必须在d3选择器之前,或许要先加载完了元素才能被选中
d3.select("button")
.on("click",function(){
// (12)新数据集,随机数组
var numValues=dataset.length;
dataset=[];
var maxValue=75;
var newNumber;
for(var i=0;i<numValues;i++){
newNumber=Math.floor(Math.random()*maxValue);//0-24的整数
dataset.push(newNumber);
}
//(13)更新比例尺,免使纵坐标超出范围
yScale.domain([0,d3.max(dataset)]);//只要更新定义域就行了,映射到的值域不变
//更新所有的矩形
svg.selectAll("rect")
.data(dataset)
.transition()//(9)加上过渡动画
.delay(function(d,i){
return i/dataset.length*1000;
})//指定过度什么时间开始,可以用函数控制每一条的动画时间,这样就可得到钢琴版的效果
.duration(2000)//(10)加上动画的持续时间,以毫秒计算
.ease("linear")//(11)缓动函数:有circle(加速)elastic(伸缩),linear(匀速),bounce(弹跳)
.attr("y",function(d){
return h-yScale(d);
})
.attr("height",function(d){
return yScale(d);
});
//(8)更新条上的数值
svg.selectAll("text")
.data(dataset)
.text(function(d) {
return d;
})
.attr("text-anchor", "middle")
.attr("x", function(d, i) {
return xScale(i)+xScale.rangeBand()/2;
})
.attr("y", function(d) {
return h - yScale(d) + 14;
})
.attr("font-family", "sans-serif")
.attr("font-size", "12px")
.attr("fill", "red");
});
</script>
</body>
</html>
【D3.js数据可视化系列教程】(十六)--更新、过度和动画
最新推荐文章于 2024-06-15 13:08:27 发布