Har*_*mer 12 javascript data-visualization d3.js
尽管经过无数次读取D3 API,我仍在努力理解D3中的合并功能.
API说:"此方法通常用于在数据连接后合并输入和更新选择.单独修改输入和更新元素后,您可以合并这两个选项并在两者上执行操作而无需重复代码."
这是一个在力导向图表中直截了当地使用它的例子,其中每个勾号都会调用勾选的函数:
var simulation = d3.forceSimulation(nodes)
.force("charge", chargeForce)
.force("center", centerForce)
.on("tick", ticked);
function ticked() {
var u = d3.select("svg").selectAll("circle").data(nodes)
u.enter().append("circle").attr("r",5)
.merge(u) // What is the merge function doing here?
.attr("cx", d => d.x)
.attr("cy", d => d.y)
u.exit().remove() // Why is it necessary to remove excess objects w/ the exit selection?
}
Run Code Online (Sandbox Code Playgroud)
我理解数据绑定是如何工作的,以及enter()和exit()选择是如何工作的.但是,我以前从未使用过"合并",我不明白它在这里做什么.如果有人可以一步一步地简要介绍这个功能中发生的事情,那将非常有用.我相信其他人也有类似的问题.
该文档很好地解释了该函数的作用,因此它所做的不是你必须这样做
u.attr("cx", d => d.x)
.attr("cy", d => d.y);
u.enter().append("circle").attr("r",5)
.attr("cx", d => d.x)
.attr("cy", d => d.y);
Run Code Online (Sandbox Code Playgroud)
你可以打电话attr一次
u.enter().append("circle").attr("r",5)
.merge(u) // after this point, any updates will apply to both u and u.enter() selections
.attr("cx", d => d.x)
.attr("cy", d => d.y)
Run Code Online (Sandbox Code Playgroud)
它将设置属性cx和cy两者u- 更新选择和u.enter()输入选择
为什么有必要删除多余的物体与退出选择?
因为出口选择包含未绑定到您传递给的数组中的元素的任何额外DOM元素data(),所以您可以在退出捕获上执行任何操作,例如通过调用u.exit().style(...)等设置样式,而不是调用remove删除它们来自DOM
您实际上在这里有两个问题:
merge()方法;关于#1,您已经收到了答案。关于#2,这是我的两分钱:代码并没有什么意义。
这很容易理解:该ticked函数每秒运行数十次。如果数据没有改变,为什么要每秒重新绑定数据并重新分配更新、进入和退出选择几十次?(值得一提的是,那段代码的作者是个好程序员,这里发生了一些奇怪的事情……毕竟我们都会犯错)
该ticked函数只需要计算元素的位置,仅此而已。
这是您与ticked函数链接的相同代码,简化为:
function ticked() {
u.attr('cx', function(d) {
return d.x;
})
.attr('cy', function(d) {
return d.y;
})
}
Run Code Online (Sandbox Code Playgroud)
这里是运行代码:
function ticked() {
u.attr('cx', function(d) {
return d.x;
})
.attr('cy', function(d) {
return d.y;
})
}
Run Code Online (Sandbox Code Playgroud)
var width = 600,
height = 400;
var colorScale = ['orange', 'lightblue', '#B19CD9'];
var xCenter = [100, 300, 500]
var numNodes = 100;
var nodes = d3.range(numNodes).map(function(d, i) {
return {
radius: Math.random() * 25,
category: i % 3
}
});
var u = d3.select('svg g')
.selectAll('circle')
.data(nodes);
var enter = u.enter()
.append('circle')
.attr('r', function(d) {
return d.radius;
})
.style('fill', function(d) {
return colorScale[d.category];
});
u = enter.merge(u);
u.exit().remove();
var simulation = d3.forceSimulation(nodes)
.force('charge', d3.forceManyBody().strength(5))
.force('x', d3.forceX().x(function(d) {
return xCenter[d.category];
}))
.force('collision', d3.forceCollide().radius(function(d) {
return d.radius;
}))
.on('tick', ticked);
function ticked() {
u.attr('cx', function(d) {
return d.x;
})
.attr('cy', function(d) {
return d.y;
})
}Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7886 次 |
| 最近记录: |