gpt4 book ai didi

javascript - D3 : Using a closure to update a selection without re-binding data

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:13:21 25 4
gpt4 key购买 nike

我从 Mike Bostock's example of using D3 to create a line drawing tool 中提取了以下代码.

此工具创建拖动行为,使用户能够通过在 SVG Canvas 上拖动来绘制曲线。

当拖动行为开始时,此事件的监听器捕获行为开始的坐标并创建新的 SVG 路径。该监听器还将一个新的监听器附加到在拖动行为继续时触发的事件;此监听器(“拖动”监听器)更新 SVG 路径。这发生在代码行开头:active.attr("d", line)

“拖动”监听器如何在没有将坐标数据(作为变量“d”存储在监听器的闭包中)重新绑定(bind)到 SVG 路径的附加行的情况下更新 SVG 路径?

根据我对 d3 工作原理的理解,这个工具不应该工作。相反,必须将:active.attr("d", line) 更改为 active.datum(d).attr("d", line)

如有任何帮助,我们将不胜感激!

var line = d3.line()
.curve(d3.curveBasis);

var svg = d3.select("svg")
.call(d3.drag()
.container(function() { return this; })
.subject(function() { var p = [d3.event.x, d3.event.y]; return [p, p]; })
.on("start", dragstarted));

function dragstarted() {
var d = d3.event.subject,
active = svg.append("path").datum(d),
x0 = d3.event.x,
y0 = d3.event.y;

d3.event.on("drag", function() {
var x1 = d3.event.x,
y1 = d3.event.y,
dx = x1 - x0,
dy = y1 - y0;

if (dx * dx + dy * dy > 100) d.push([x0 = x1, y0 = y1]);
else d[d.length - 1] = [x1, y1];
active.attr("d", line);
});
}
<!DOCTYPE html>
<meta charset="utf-8">
<style>

path {
fill: none;
stroke: #000;
stroke-width: 3px;
stroke-linejoin: round;
stroke-linecap: round;
}

</style>
<svg width="960" height="500">
<rect fill="#fff" width="100%" height="100%"></rect>
</svg>
<script src="//d3js.org/d3.v4.min.js"></script>

更新 1:我已经尝试了一个基本的闭包结构(即一个用户启动的闭包,它返回一个类似于用户可以通过控制台调用的“拖动”事件监听器的函数)但我无法复制上面脚本的工作方式。我完全糊涂了。

最佳答案

在此示例中,没有需要重新绑定(bind)的数据更新。事实上,只有一个 datum 在拖动手势期间被修改。当拖动实际开始时,subject

指定
.subject(function() { var p = [d3.event.x, d3.event.y]; return [p, p]; })

被捕获并存储在变量d中:

var d = d3.event.subject,

从上面两行可以看出,这将作为一个数组开始,其中包含两个定义路径起点和终点的坐标对,它们最初是相同的。

下一行将此单个数据/主题绑定(bind)到为此拖动手势新创建的路径:

active = svg.append("path").datum(d),

请务必记住,变量 d 包含对绑定(bind)到路径的实际数据的引用。当修改 d 时,您实际上是在修改预先绑定(bind)的数据。发生这种情况是因为您正在处理引用。

也就是说,接下来的步骤非常简单,因为在手势期间,坐标数组通过调整坐标值或将新值推送到数组来保持最新。同样,这实际上是在修改绑定(bind)到路径的数据。

最后在路径的d属性上设置线生成器line

active.attr("d", line);

生成器将被调用,隐式传递基准边界的新值,从而生成在手势期间跟随指针移动的路径。

关于javascript - D3 : Using a closure to update a selection without re-binding data,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39590283/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com