D3 变更检测如何工作?

2024-03-31

如果我有一个 JSON 对象数组。 D3 如何确定哪些进入enter() set?

如果我有一个对象数组,如下所示:

var data = [
  {label:'a', value:1},
  {label:'b', value:3},
  {label:'c', value:2}
]

然后我将它绑定到一个选择:

var bars = vis.selectAll("rect.bar")
  .data(data)

The enterset 现在包含所有这些数据。如果我现在更改数据:

var data = [
  {label:'a', value:99},
  {label:'c', value:2}
  {label:'b', value:3},
]

D3 如何判断哪些值是更新、移动还是新的?是根据对象身份完成的吗?有没有办法让它使用标签字段来填充输入集?


如果我正确理解你的问题,你想知道 D3 如何将给定对象关联到给定 DOM 元素。

默认情况下,如果您没有设置关键功能(更多内容请参见下文),对象将按其顺序关联。根据API:

...data 中的第一个数据分配给第一个选定的元素,第二个数据分配给第二个选定的元素,依此类推。

让我们在下面的示例中看看这一点。第一个数组是这样的:

var data = [{
    label: 'a',
    value: 1
}, {
    label: 'b',
    value: 3
}, {
    label: 'c',
    value: 2
}];

第二个数组也有 3 个对象。但要注意变化:第一个是标签c,第三个是标签a。它们被交换了:

var data2 = [{
    label: 'c',
    value: 99
}, {
    label: 'b',
    value: 2
}, {
    label: 'a',
    value: 3
}];

因此,相对于a第一个数据将得到的值c在第二个中。检查演示,单击按钮:

var svg = d3.select("svg");

var data = [{
  label: 'a',
  value: 1
}, {
  label: 'b',
  value: 3
}, {
  label: 'c',
  value: 2
}];

var data2 = [{
  label: 'c',
  value: 99
}, {
  label: 'b',
  value: 2
}, {
  label: 'a',
  value: 3
}];

var xScale = d3.scaleLinear()
  .domain([0, d3.max(data, d => d.value)])
  .range([0, 260]);

var yScale = d3.scaleBand()
  .domain(data.map(d => d.label))
  .range([10, 140])
  .padding(0.3);

var rects = svg.selectAll("foo")
  .data(data)
  .enter()
  .append("rect");

rects.attr("x", 40)
  .attr("y", d => yScale(d.label))
  .attr("height", yScale.bandwidth)
  .attr("width", d => xScale(d.value))
  .attr("fill", "teal");
  
d3.axisLeft(yScale)(svg.append("g").attr("transform", "translate(40,0)"))

d3.select("button").on("click", function() {

  xScale.domain([0, d3.max(data2, d => d.value)]);

  rects.data(data2);

  rects.transition()
    .duration(1000)
    .attr("width", d => xScale(d.value))

})
<script src="https://d3js.org/d3.v4.min.js"></script>
<button>Click</button>
<br>
<svg></svg>

正如您所看到的,单击按钮后的图表显然是不正确的。

为了避免这种情况,请确保 DOM 元素之前绑定到标签a仍将绑定到该标签a当数据数组发生变化时,我们必须使用一个关键函数:

可以指定一个关键函数来控制将哪个数据分配给哪个元素,以替换默认的按索引连接。此关键函数针对每个选定元素按顺序进行评估,传递当前数据 (d)、当前索引 (i) 和当前组(节点),并将其作为当前 DOM 元素 (nodes[i]) 。然后,还会针对 data 中的每个新数据评估 key 函数,传递当前数据 (d)、当前索引 (i) 和组的新数据,并将其作为组的父 DOM 元素。给定键的数据被分配给具有匹配键的元素。如果多个元素有相同的key,则将重复的元素放入退出选择中;如果多个数据具有相同的键,则将重复的数据放入输入选择中。

在你的情况下,这将是关键功能:

.data(data, d => d.label)
//key-------^

检查完全相同的代码,但具有关键功能:

var svg = d3.select("svg");

var data = [{
  label: 'a',
  value: 1
}, {
  label: 'b',
  value: 3
}, {
  label: 'c',
  value: 2
}];

var data2 = [{
  label: 'c',
  value: 99
}, {
  label: 'b',
  value: 2
}, {
  label: 'a',
  value: 3
}];

var xScale = d3.scaleLinear()
  .domain([0, d3.max(data, d => d.value)])
  .range([0, 260]);

var yScale = d3.scaleBand()
  .domain(data.map(d => d.label))
  .range([10, 140])
  .padding(0.3);

var rects = svg.selectAll("foo")
  .data(data, d => d.label)
  .enter()
  .append("rect");

rects.attr("x", 40)
  .attr("y", d => yScale(d.label))
  .attr("height", yScale.bandwidth)
  .attr("width", d => xScale(d.value))
  .attr("fill", "teal");
  
d3.axisLeft(yScale)(svg.append("g").attr("transform", "translate(40,0)"))

d3.select("button").on("click", function() {

  xScale.domain([0, d3.max(data2, d => d.value)]);

  rects.data(data2, d => d.label);

  rects.transition()
    .duration(1000)
    .attr("width", d => xScale(d.value))

})
<script src="https://d3js.org/d3.v4.min.js"></script>
<button>Click</button>
<br>
<svg></svg>

你可以看到,尽管order新数据数组中不同的对象的数量(c是第三个,现在c是第一个),这并不重要,因为 D3 将数据绑定到每个 DOM 元素,同时考虑到label财产。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

D3 变更检测如何工作? 的相关文章

  • 数据与线的日期和时间转换

    我使用 D3 V5 创建了此图表 另外 我已在小提琴上附加了示例数据 您可以点击此处查看 https plnkr co edit pINxcS9yt9AuJmSk02Fs p preview 我已经包括了tick函数代码块 它在向左滑动的路
  • 当节点扩展时增加d3中的连接链路长度

    我正在 d3 中研究可折叠力布局 我面临的问题是 当单击节点时 我需要增加节点之间链接的长度 以保持子节点之间的链接距离相同 当分析扩展时 如何增加分析和耀斑之间的距离 保持与子级的距离较小 是的 您可以通过定义一个函数来做到这一点力 链接
  • d3.js:在树布局中展开多个路径

    My JSON contains same node names in different paths I would like to be able to open all children with the same name or h
  • 为什么这个标题图形不随世界更新

    对于以下内容 我很高兴组合框默认为世界 但当收音机被点击时 我也希望标题移回 世界 我该怎么做 我有这个笨蛋 http plnkr co edit 9FXJXVqLZLPFdDrmVJez p preview http plnkr co e
  • 我可以补间 D3 弧的结束角度,但不能补间起始角度。我究竟做错了什么?

    我只是在玩这个演示并自己重新创建它 http bl ocks org mbostock 5100636 http bl ocks org mbostock 5100636 我可以定义一个新的 endAngle 并且它会很好地制作动画 但现在
  • 如何在 d3.scale.ordinal() 中指定域?

    var W 100 var H 200 var data v 4 v 8 v 15 v 16 v 23 v 42 var x d3 scale linear domain 0 max x range 0 W var y d3 scale o
  • D3js 多折线图 mouseOver

    我正在努力适应this http bl ocks org mbostock 3902569D3js 折线图示例 将鼠标悬停在我的多线图表上的使用情况 看起来d3 mouse this 0 on the mousemove函数生成以下错误 无
  • D3:如何在Groups of Force布局节点上绘制多个凸包?

    我试图在力布局中的所有组上绘制凸包 但我只画出了一半的凸包 当 D3 尝试绘制其余的船体时 控制台返回错误 元素尚未创建 然而 当我检查控制台中的 groups 变量时 所有组数据都在那里 x y 数据都设置得很好 见下图 我什至尝试在ti
  • d3.js:非线性图轴

    我正在尝试在轴上添加自定义比例 如下所示 这个想法是 一个刻度总是比前一个刻度大 2 倍 我的理解是 这是一个定制秤 我做了一些研究 但找不到类似的东西 所以我想我的问题实际上是两个问题 这个尺度是数学世界的 标准 吗 这是否可以使用来实现
  • 如何在没有 DOM 的情况下将 javascript 作为 node.js 脚本运行?

    https github com jasondavies d3 cloud https github com jasondavies d3 cloud是一个使用 D3 库的 javascript 文字云 这是一个交互式演示 http www
  • 将任何 D3.js 图表与 DC.js 集成

    我试图弄清楚如何轻松地将任何 D3 js 图表与 DC js 库集成 以便在所有图表之间使用交叉过滤功能 我也确实理解以前曾问过这种性质的问题 添加链接以供参考 DC js 监听图表组渲染 https stackoverflow com q
  • D3 v4 在同一元素上进行画笔和缩放(鼠标事件不冲突)

    我的目标是构建一个使用两者的 D3 v4 图表d3 zoom https github com d3 d3 zoom and d3 brush https github com d3 d3 brush一起 如下 当鼠标位于 x 轴上时 用户
  • D3.js - 具有多个环的圆环图

    以下示例显示了 D3 js 中的圆环图 是否可以向图表添加多个圆环 var dataset apples 53245 28479 19697 24037 40245 var width 460 height 300 radius Math
  • d3力定向布局-链接距离优先

    在 d3 中使用力导向布局 如何使链接距离成为优先事项 同时仍然保持良好的图形布局 如果我指定动态链接距离 但保留默认费用 则我的图形距离会因费用函数而发生一些变形 并且不再是准确的距离 但是 如果我删除电荷 图表将如下所示 任何建议表示赞
  • 如何将此数据编码为 JSON 中的父/子结构

    我正在使用 d3 js 将动物 有机体 家族 一次最多 4000 个 可视化为树形图 尽管数据源也可以是目录列表或命名空间对象列表 我的数据如下 json organisms name Hemiptera Miridae Kanakamir
  • DC.js 中的工具提示(D3 库)

    DC js 具有强大的内置功能 可显示每个工具提示文档 https github com dc js dc js blob master web docs api latest md title titleFunction 功能 无论如何
  • 在 d3.js 中操纵鼠标悬停在“点击区域”

    我想show and hideSVG 中的一个节点 当鼠标移到 mouseout 问题是我的节点内部的形状是一条宽度只有1 5px的路径 因此在鼠标悬停事件中不容易击中该区域 这对用户体验肯定不方便 我想知道是否有办法做到这一点打击范围更广
  • 如何避免多系列折线图d3.js的工具提示重叠

    我已经在多系列折线图上创建了工具提示 如下所示在这里回答 https stackoverflow com questions 34886070 d3 js multiseries line chart with mouseover tool
  • 如何在“object”标签内选择 SVG?

    HTML 页面的内容如下所示 方法如下script js looks var tooltip d3 select body append div style position absolute sty
  • 使用 d3-geo-projection 命令行工具设置自定义投影

    我正在尝试使用 geoproject 在 geojson 文件上设置投影 具体来说 我正在尝试将投影设置为 BCalbers http spatialreference org ref epsg 3005 http spatialrefer

随机推荐

  • 如何使用urllib3打印原始html字符串?

    我使用下面的语句来获取 html 字符串 import urllib3 url http urllib3 readthedocs org http pool urllib3 connection from url url r http po
  • Python ftplib 损坏文件?

    我正在使用 ftplib 在 Python 中下载文件 直到最近一切似乎都工作正常 我正在下载这样的文件 ftpSession ftplib FTP host username password ftpSession cwd rlmfile
  • 在 Corda 中,节点的内置网络服务器上没有安装自定义 CorDapps。

    我定义了一个包含 API 的 CorDapp 但是 当我部署 CorDapp 并运行节点时 我在 Web 服务器 URL 上看到以下消息 No installed custom CorDapps 如何让节点的内置网络服务器加载我的 API
  • file_get_contents 创建一个空文件

    在 if 子句中用作测试条件时 如何防止 file get contents 创建空文件 不管怎样 都会创建一个空文件 这会导致后续调用不同方法中的 getimagesize 失败 问题是 当我设置代码时 第一次调用它时将确定保存图像或显示
  • PHP:preg_match_all首先匹配内括号?

    在 PHP 中 我有带有嵌套括号的字符串 bar foo test abc def bar foo 我需要一个与内部括号对匹配的正则表达式first 所以顺序是preg match all发现匹配的括号对应该是 abc def test a
  • 将 Zapier 自定义请求 Webhook 与 JSON Web 令牌结合使用

    我需要访问使用 JSON Web 令牌作为身份验证方法的 API 有没有一种好方法可以使用 python 代码步骤创建此令牌 然后将该令牌作为标头添加到自定义请求 Webhook 步骤中 我使用 API 进行身份验证的经验是使用简单的API
  • 我什么时候应该在sql server中使用表变量和临时表?

    我正在表变量中了解更多详细信息 它说临时表总是在磁盘上 而表变量在内存中 也就是说 表变量的性能比临时表更好 因为表变量比临时表使用更少的IO操作 但有时 如果表变量中的记录太多而无法容纳在内存中 则该表变量将像临时表一样放在磁盘上 但我不
  • 使用C#设置全局热键

    I need to capture a key press when my program is not in focus i e Ctrl Alt J and trigger an event in my program 到目前为止 我发
  • LINQ 查找大于/小于输入的最接近的数字

    假设我有这个号码列表 List
  • NTFS 提供哪些可靠性保证?

    我想知道 NTFS 为存储在其上的数据提供了什么样的可靠性保证 例如 假设我正在打开一个文件 追加到末尾 然后关闭它 并且在此操作过程中随机时间断电 我能找到完全损坏的文件吗 我这么问是因为我刚刚遇到了系统锁定 并发现其中两个正在附加的文件
  • Docker - 无法准备上下文:无法评估 Dockerfile 路径中的符号链接:GetFileAttributesEx

    我今天刚刚下载了适用于 Windows 10 64 位的 Docker Toolbox 我正在浏览教程 我在尝试使用 Dockerfile 构建映像时收到以下错误 Steps 推出 Docker 快速入门终端 创建后测试docker 按照
  • “自动打包存储库以获得最佳性能”是什么意思?

    我的 git 存储库有问题 在过去的几天里 每当我向服务器推送时 我都会收到此消息 自动打包存储库以获得最佳性能 并且它似乎不会消失并返回 shell 我还尝试签出一个新分支 然后对我之前的分支进行变基 然后执行git gc删除未使用的历史
  • 如何确定 NSDate 是否是工作日?

    我怎样才能知道是否NSDate是工作日吗 也就是说 根据用户当前的区域设置和日历设置是否是周末 所以不硬编码为周一到周五 NSCalendar has a firstWeekday财产 但这似乎只是一种表象 美国是周日 英国是周一 编辑 我
  • MySQL 分组依据/排序依据索引

    请参阅下面的查询 我应该在表上创建什么索引 以便查询将使用该索引并避免使用临时和文件排序 我尝试了许多不同的索引组合并阅读这里的建议 http mysqldba blogspot com 2008 06 how to pick indexe
  • 将 Unique-ids 传递给 Javascript 以实现水平滚动

    我正在尝试开发一个类似于 Netflix 的水平滚动界面 一切都显示并正常工作 但由于某种原因 Javascript 只滚动浏览索引页面中的第一个出版商书籍 当我尝试悬停和滚动任何其他出版商书籍时 它只会水平滚动第一出版商书籍 我知道 sc
  • 具有多个条件的 Linq where 子句

    此方法返回通用列表 但它有多个条件来获取选择 我只是用 if else if else if 来写这个 我的意思是这么多 if else 有没有更短的方法来做到这一点 谢谢 public List
  • 使用 HttpURLConnection 设置自定义标头

    我只是在做一个GET使用 Rest API 请求HttpURLConnection 我需要添加一些自定义标头 但我得到了null同时试图找回他们的价值观 Code URL url try url new URL http www examp
  • 使用指向单个值的指针作为数组

    请注意 该问题已针对 注册 变量进行了扩展 简而言之 我的问题是 这个合法的 C 代码是否合法 按照不同 ISO 9899 C 规范的标准字母 最好在标准的文字中加上 证明 int a 0 int b a 0 const int c 0 b
  • 如何在ajax请求中将带有formdata的数组发送到mvc操作

    我试图将带有表单数据的数组发送到带有 Ajax 请求的操作 但每当我这样做时 我都会收到表单数据和空数组 scope SubmitForm function var sLangs supportedLanguages data kendoM
  • D3 变更检测如何工作?

    如果我有一个 JSON 对象数组 D3 如何确定哪些进入enter set 如果我有一个对象数组 如下所示 var data label a value 1 label b value 3 label c value 2 然后我将它绑定到一