【D3.js数据可视化系列教程】(十八)--组合添加删除

最后效果:

单击更新能实现像之前那样的更新了。

但是,单击添加和删除时,只能捕获第一个p标签,不能捕获第二个。

  1. 根据ID确定点击的是哪个标签

var paragraphID=d3.select(this).attr("id") ;

  2. 添加删除组合起来

if(paragraphID=="add"){

  3. 根据最后一个key添加一个值

var lastKeyValue=dataset[dataset.length-1].key;
dataset.push({
    key:lastKeyValue+1,
    value:newNumber
});

  4. 根据i添加一个值

dataset.push({
    key:i,
    value:newNumber
});}

  5. 1/2 值函数

var value=function(d){
    return d.value;
};

  6. 2/2// 更新比例尺,免使纵坐标超出范围

yScale.domain([0,d3.max(dataset,value)]);//只要更新定义域就行了,映射到的值域不变
<!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 id="remove">单击删除</p>
    <p id="add">单击添加</p>
    <br>
        <script type="text/javascript">
//键值对数据集
var dataset = [ 
{key:0,value:5},
{key:1,value:10},
{key:2,value:13},
{key:3,value:19},
{key:4,value:21},
{key:5,value:25},
{key:6,value:22},
{key:7,value:18},
{key:8,value:15},
{key:9,value:13},
{key:10,value:11},
{key:11,value:12},
{key:12,value:15},
{key:13,value:20},
{key:14,value:18},
{key:15,value:17},
{key:16,value:16},
{key:17,value:18},
{key:18,value:23},
{key:19,value:25}];

//设置SVG的高宽
var w=600;
var h=250; 
var barPadding = 1;
//定义序数比例尺
var xScale=d3.scale.ordinal()//序数比例尺
             .domain(d3.range(dataset.length))  
             .rangeRoundBands([0,w],0.05); 
// 更新数据引用,包含下面所有关于要使用到d.value的地方             
var yScale=d3.scale.linear()//y仍然是线性比例尺
.domain([0,d3.max(dataset,function(d){
    return d.value;
})])
.range([0,h]);  
// 定义键函数(简洁),以备数据绑定到元素的时候使用
//把所有.data(dataset)改成.data(dataset,key)
var key=function(d){
    return d.key;
};
//(6)1/2 值函数  
var value=function(d){
    return d.value;
};
//Create SVG element
var svg = d3.select("body")//选中DOM中的目标元素
        .append("svg")//为目标元素附加上一个svg子元素
        .attr("width", w)//设置这个svg的宽
        .attr("height", h);//设置这个svg的高
//为SVG添加条形
svg.selectAll("rect")//选中空元素,表示即将创建这样的元素
    .data(dataset,key)//对此后的方法都执行dataset.length遍
    .enter()//数据元素值比前面选中的DOM元素多就创建一个新的DOM元素
    .append("rect")//取得enter的占位元素,并把rect追加到对应的DOM中
    .attr("x", function(d, i) {//设置横坐标,从0开始每次右移元素宽那么长(w / dataset.length)
            //return i * (w / dataset.length);
            return xScale(i);//这里使用序数比例尺,自己去找刚才划分好的档位
    })
    .attr("y", function(d) {//设置纵坐标,纵坐标正方向是从上往下的,所以条有多长就要设置起点是相对于h再向上移动条长
            return h - yScale(d.value);
    })
    //.attr("width", w / dataset.length - barPadding)//设置元素宽,留出间隙宽barPadding。
    .attr("width", xScale.rangeBand())//这里xScale比例尺已经设置间距了所以直接用
    .attr("height", function(d) {
            return yScale(d.value);
    })
    .attr("fill", function(d) {//设置RGB颜色与数值的关系
            return "rgb(0, 0, " + (d.value * 10) + ")";
    });
//为条加上数值
svg.selectAll("text")
               .data(dataset,key)
               .enter()
               .append("text")
               .text(function(d) {
                    return d.value;
               })
               .attr("text-anchor", "middle")
               .attr("x", function(d, i) {
                    return xScale(i)+xScale.rangeBand()/2;
               })
               .attr("y", function(d) {
                    return h - yScale(d.value) + 14;
               })
               .attr("font-family", "sans-serif")
               .attr("font-size",function(d) {
                     return xScale.rangeBand()/2;
               })
               .attr("fill", "white");
//删除一条、添加一条
d3.select("p")
.on("click",function(){
//(1)根据ID确定点击的是哪个标签
var paragraphID=d3.select(this).attr("id") ; 
console.log(paragraphID);
//(2)添加删除组合起来
if(paragraphID=="add"){
    //数据集最后添加数值
var maxValue=75;
var newNumber =Math.floor(Math.random()*maxValue);//0-24的整数
//(3)根据最后一个key添加一个值
var lastKeyValue=dataset[dataset.length-1].key; 
    dataset.push({
        key:lastKeyValue+1,
        value:newNumber
    });
//更新X轴比例尺
xScale.domain(d3.range(dataset.length));
//选择所有条
var bars=svg.selectAll("rect")
.data(dataset,key); //绑定数据到元素集,返回更新的元素集

var texts=svg.selectAll("text")
.data(dataset,key);
//添加条形元素到最右边
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.value) ;
 }) 
.attr("width", xScale.rangeBand())//这里xScale比例尺已经设置间距了所以直接用
.attr("height", function(d) {
            return yScale(d.value);
    })
.attr("fill", function(d) {//设置RGB颜色与数值的关系
            return "rgb(0, 0, " + (d.value * 10) + ")";
    });
    //
texts.transition()
.duration(500)
.text(function(d) {
                    return d.value;
               })
               .attr("text-anchor", "middle")
               .attr("x", function(d, i) {
                    return xScale(i)+xScale.rangeBand()/2;
               })
               .attr("y", function(d) {
                    return h - yScale(d.value) + 14;
               })
               .attr("font-family", "sans-serif")
               .attr("font-size", "12px")
               .attr("fill", "red");
}else if(paragraphID=="remove"){

//(4)删除的操作
//选择所有条
dataset.shift();
//更新X轴比例尺
xScale.domain(d3.range(dataset.length));

var bars=svg.selectAll("rect")
.data(dataset,key); 
//从左侧退出
bars.exit()
.transition()
.duration(500)
.attr("x", -xScale.rangeBand())//w-xScale.rangeBand()间隙宽其实其他负数也行
.remove();
}

});
// 更新条形数长短的代码,需要一个button标签配合
//特别注意:这里选中的元素必须在d3选择器之前,或许要先加载完了元素才能被选中
d3.select("button")
.on("click",function(){
// 新数据集,随机数组
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的整数
    //(5)根据i添加一个值
    dataset.push({
        key:i,
        value:newNumber
    });
}
//(6)1/2
// 更新比例尺,免使纵坐标超出范围
yScale.domain([0,d3.max(dataset,value)]);//只要更新定义域就行了,映射到的值域不变
    //更新所有的矩形
    svg.selectAll("rect")
    .data(dataset,key)
    .transition()// 加上过渡动画 
    .delay(function(d,i){
        return  i/dataset.length*1000;
    })//指定过度什么时间开始,可以用函数控制每一条的动画时间,这样就可得到钢琴版的效果
    .duration(2000)// 加上动画的持续时间,以毫秒计算
    .ease("linear")// 缓动函数:有circle(加速)elastic(伸缩),linear(匀速),bounce(弹跳)
    .attr("y",function(d){
        return h-yScale(d.value);
    })
    .attr("height",function(d){
        return yScale(d.value);
    });
    // 更新条上的数值
    svg.selectAll("text")
               .data(dataset,key)
               .text(function(d) {
                    return d.value;
               })
               .attr("text-anchor", "middle")
               .attr("x", function(d, i) {
                    return xScale(i)+xScale.rangeBand()/2;
               })
               .attr("y", function(d) {
                    return h - yScale(d.value) + 14;
               })
               .attr("font-family", "sans-serif")
               .attr("font-size", "12px")
               .attr("fill", "red");
}); 

        </script>
    </body>
</html>

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
文件已上传到百度网盘,附件中是下载地址。真正免积分免费完整版,绝不出现仅下载到部分章节,书中广 告页要求QQ联系支付宝购买完整版的流氓行为! 欢迎免积分下载更多本人独有网上难寻觅的 高清IT电子书:http://download.csdn.net/user/sinophp123 人无我有,人有我优,人优我廉!我的版本是全网最清晰的独家制作版本,还不要资源分。 同样一本书,下我的就可以了! 本人上传资料的原则: (1)如果CSDN和网上其他地方已随处可见高清下载,本人不再上传。 (2)如果网上已有我还上传,那么肯定是经重新制作,如不再缺页,清晰度更高,或者加上书签。 (3)每本书都经过逐页纯手工精心处理,包括清晰度的增强,水印的去除。当然最重要的,是尽量保证有书 签方便您浏览。 (4)如果是中译版,文件名前半部分是英文原版书名,后面是中译版书名。 如:“Implementing.Responsive.Design-响应式Web设计实践”。书名经反复校对绝无一字错漏。 (5)每本pdf书默认都是有书签的。来源不限“某星”网站,还有各大网络书店和出版社官网的页码信息。 凡无书签的pdf文件名均含“_no.bookmark”字样,如“HTML5程序开发范例宝典_no.bookmark”。请不要再 浪费时间去寻找书签,肯定没有,网上别人提供的下载版本也绝对不会有(除非您是出版社内部人员!), 没有人会浪费自己时间逐页输入章节页码来费时费力免费给您制作。 (6)只提供中文书籍,您不用担心下载的是英文原版。 (7)只提供完整版,绝不上传只有部分章节的所谓“迷你书”,“试读版”。 (8)书中绝不含广告页和水印LOGO。 Data.Visualization.with.D3.js.Cookbook-D3.js数据可视化实战手册 [加]nick qi zhu 著(著) | 杨锐 刘夏 王超 张沙沙(译) | 人民邮电出版社 | 9787115360960 | 2014-09- 01

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值