d3的enter和exit

网上有很多blog讲解。说的还凑合的见:https://blog.csdn.net/nicolecc/article/details/50786661

如何把自己的rude绘图代码,进行精致化(update)

不多比比,上代码示例:

d3.selectAll('.circle_group').children().remove();
var circle_group = d3.selectAll('.circle_group')
.data(circleData)
.enter().append('g')
.attr('class', 'circle_group brushNode')
.attr('transform',
function (d) {
return 'translate(' + d.x + ',' + d.y + ')';
})
.on('click', function (d) {
if (shiftKey) {
//标记当前点
d3.select(this).classed("selected", function (d) { d.selected = !d.selected;
d.previouslySelected = !d.selected;
return d.selected;
}) //阻止事件冒泡
d3.event.stopPropagation();
}
})
.on("contextmenu", function (node) {
contextmenu("Rmenu");
}) circle_group.append('circle')
.attr('r', function (d) {
return d.r;
})
.style("fill", function (d) {
return color20(d.index);
}) ;
circle_group.append('text')
.attr("dy", ".35em")
.attr("text-anchor", "middle")//在圆圈中加上数据
.style('fill', function (node) {
return '#555';
})
.attr("y", -7)
.text(d => d.text); circle_group.call(d3.drag()
//定义了元素拖拽行为的原点,设置为圆的圆心位置可以避免明显的元素跳动, 与d3v3中的origin方法类似。
.subject(function () {
var thisData = d3.select(this);
return {
x: thisData.datum().x,
y: thisData.datum().y
};
})
.on("start", dragstarted)
.on("drag", dragmove)
.on("end", dragended));

很明显,新手图省事都是这么绘图的。就绘图结果来看,如果你不加动画一点问题都没有,只要一加动画过渡动画,所有的图形都是从无到有的过程,而我们想看的是,如果点更新的话,能看到他从哪(位置)更新到哪(位置)。(这里就不加动画过渡了,就一行代码的事.transition().duration(300) )。

改造如下:

    //这部分代码是有则改之,无则添加的功能
const circle_data=d3.selectAll('.circle_group').data(circleData) //更新部分,如果你数据的数目没变,那circle_data.size()=你数据内容改变的数目,你可以把circle_data考虑成update部分就行,这样编代码准没错
.attr('transform', //首次运行的时候,因为没有元素circle_data.size()=0, 所以这个transform不会运行到
function (d) {
return 'translate(' + d.x + ',' + d.y + ')';
});
const circle_enter=circle_data.enter().append('g') //add 部分,首次运行的时候,circle_enter.size()=全部元素,所以在circle_enter进行所有的初始化设置操作
.attr('class', 'circle_group brushNode')
.attr('transform',
function (d) {
return 'translate(' + d.x + ',' + d.y + ')';
});
circle_data.exit().remove(); // 当你删一些数据的时候, .exit().size()>0 circle_enter.on('click', function (d) {
if (shiftKey) {
//标记当前点
d3.select(this).classed("selected", function (d) { d.selected = !d.selected;
d.previouslySelected = !d.selected;
return d.selected;
}) //阻止事件冒泡
d3.event.stopPropagation();
}
})
.on("contextmenu", function (node) {
contextmenu("Rmenu");
}) circle_enter.append('circle') //add
.attr('r', d=>d.r)
.style("fill", function (d) {
return color20(d.index);
});
circle_data.select('circle') //update,这里不要append ,因为元素已经在那了(enter().append()过了)。当然首次运行(视图首次显示)的时候,这几句代码是运行不到的。
.attr('r', d=>d.r)
.style("fill", function (d) {
return color20(d.index);
}); circle_enter.append('text') //add
.attr("dy", ".35em")
.attr("text-anchor", "middle")//在圆圈中加上数据
.style('fill', function (node) {
return '#555';
})
.attr("y", -7)
.text(d => d.text);
circle_data.select('text') //update 不要append
.text(d => d.text); const drag=d3.drag()
//定义了元素拖拽行为的原点,设置为圆的圆心位置可以避免明显的元素跳动, 与d3v3中的origin方法类似。
.subject(function () {
var thisData = d3.select(this);
return {
x: thisData.datum().x,
y: thisData.datum().y
};
})
.on("start", dragstarted)
.on("drag", dragmove)
.on("end", dragended);
circle_enter.call(drag);
circle_data.call(drag); //update 注意,这里一定要重新绑定一下,这里涉及到drag的初始化(subject用于初始化drag拖动点的初始位置)

敲黑板

1、更新部分的所有与位置有关的事件(比如d3.drag()的初始位置)要重新绑定,否则会出现不可预料的结果。

2、update部分与数据有关的attr,style要重新设置,这时就不用append了。(因为这个元素既然有了,你已经在之前的.enter().append().append(其他元素)添加过了,这里只需要更新一下即可。)。一些固定的attr,style就不用重复设置了(之前enter已经绑定过了)

d3代码如何改造成update结构(恰当处理enter和exit)的更多相关文章

  1. D3.js 理解 Update、Enter、Exit

    Update.Enter.Exit 是 D3 中三个非常重要的概念,它处理的是当选择集和数据的数量关系不确定的情况. 一.什么是 Update.Enter.Exit svg.selectAll(&qu ...

  2. D3.js:Update、Enter、Exit

    Update.Enter.Exit 是 D3 中三个非常重要的概念,它处理的是当选择集和数据的数量关系不确定的情况. 如果数组为 [3, 6, 9, 12, 15],将此数组绑定到三个 p 元素的选择 ...

  3. D3.js系列——动态效果和Update、Enter、Exit的理解

    一.动态效果 D3 支持制作动态的图表.有时候,图表的变化需要缓慢的发生,以便于让用户看清楚变化的过程,也能给用户不小的友好感. 1.什么是动态效果 前面制作的图表是一蹴而就地出现,然后绘制完成后不再 ...

  4. D3.js的v5版本入门教程(第四章)—— 理解Update、Enter、Exit

    D3.js的v5版本入门教程(第四章) Update.Enter.Exit是D3.js中很重要的概念,下面来讲一下它们到底是什么?(当你看完后.你就会知道如果数据集个数和选择集个数不匹配的情况下使用d ...

  5. 创建TFS团队项目时自动建立代码库的文件夹结构

    很多客户都跟我提过一个这样的需求,即需要在创建团队TFS项目时,自动创建起源代码库的文档结构,例如类似下列结构的文件夹: <teamProject>   |- DEVELOPMENT   ...

  6. Uboot优美代码赏析1:目录结构和malkefile分析

    Uboot优美代码赏析1:目录结构和malkefile分析 关于Uboot自己选的版本是目前最新的2011.06,官方网址为:http://www.denx.de/wiki/U-Boot/WebHom ...

  7. 《Three.js 入门指南》3.0 - 代码构建的最基本结构。

    3.0 代码构建的最基本结构 说明: 我们必需首先知道,Three.js 的一些入门级概念: 我们需要知道,OpenGL 是一套三维实现的标准,为什么说是标准,因为它是跨平台,跨语言的.甚至CAD以及 ...

  8. D3.js的基础部分之选择集的处理 enter和exit的处理方法 (v3版本)

    上一节给大家讲述额绑定数据的原理.当数组的长度与元素的数量不一致时,有enter部分和exit部分,前者表示存在多余的数据,后者表示存在多余的元素.本节将给大家介绍如何处理这些多余的东西,最后会给大家 ...

  9. 【 D3.js 选择集与数据详解 — 4 】 enter和exit的处理方法以及处理模板

    绑定数据之后,选择集分为三部分:update.enter.exit.这三部分的处理办法是什么呢?本文将讲解其处理方法,以及一个常用的处理模板. 1. enter的处理方法 如果没有足够的元素,那么处理 ...

随机推荐

  1. C语言提高 (4) 第四天 数组与数组作为参数时的数组指针

    1昨日回顾 const int 和 int const是一样的 const char *p;值不变 char * const p; 指针不能变 编译器对参数的退化: 第三种模型: 三级指针 三级指针局 ...

  2. BZOJ 2161 布娃娃 (主席树)

    题面 想了一个主席树做法 我们把每个区间的两个端点拆开 对$L,R$分别从小到大排序,分别从左到右依次把对应标号的$c_{i}$插入到权值主席树里 每次查询$p_{i}$,在排序后的$L,R$数组上分 ...

  3. CentOS 笔记(六) 历史命令 自动补充

    history #出现历史的命令 #执行具体的一条历史命令 !458 ②安装自动补充功能 yum install -y bash-completion #输入命令 按Tab 会显示所有内容 syste ...

  4. Linux学习一:图解CentOS 6.5安装步骤

    1 进入安装界面 2 选择语言 3 选择键盘 4 选择存储类型 5 是否格式化硬盘 6 设置主机名 7 配置网卡 (1)选择网卡并编辑 (2)配置IPv4 (3)查看虚拟网络编辑器 NAT设置 DHC ...

  5. rabbitMQ学习笔记(一)Windows 与Linux下rabbitMQ的安装

    版权声明:本文为博主原创文章,未经博主允许不得转载. Normal 0 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE /* Style Definiti ...

  6. 在magento的eav模型中如何在更新记录时只在value表的原值上更新

    1,一般情况下,当我们在调用getModel在load某条实体接着更新对应实体上的值是,都不会覆盖原来的实体value表上的值,而是保留原来的,并在value表上重新创建一条值记录,比如初始表如下: ...

  7. iOS开发一行代码系列:一行搞定输入框

    近期总结了下开发过程中经常使用的功能,发现有时候我在做反复性的劳动.于是决定把经常使用的功能抽出来,方便下次使用. 我的想法是:用最少的代码来解决这个问题.于是写了一些经常使用的工具类,名字就叫一行代 ...

  8. OC-JS交互(WebViewJavascriptBridge使用说明)

    首先确保一份已经配好功能的html文件. 1.初始化一个webview(viewdidload) UIWebView* webView = [[UIWebView alloc] initWithFra ...

  9. 关于server和虚拟主机的差别

    文章都是先由本人个人博客,孙占兴:www.teilim.com,先更新,随后CSDN博客才会更新.掌握第一动态请关注本人主站. 原文链接:http://www.teilim.com/guan-yu-y ...

  10. HTML5游戏实战之20行代码实现打地鼠

    之前写过一篇打地鼠的博客70行的代码实现打地鼠游戏,细致思考过后,发现70行代码都有点多余了,应用tangide的控件特性,能够将代码量缩减到20行左右. 先show一下终于成果,点击试玩:打地鼠.或 ...