繁体   English   中英

d3.js使用动态缩放时的奇怪拖动行为

[英]d3.js Strange dragging behaviour when using dynamic scaling

我正在尝试构建d3图(当前仅未连接的节点)以处理相对较小的节点值。 出于这个原因,我使用的是线性标度,它对输入值进行动态反应,并相应地缩放它们:

var xScale = d3.scale.linear().range([0, width]);
var yScale = d3.scale.linear().range([height, 0]);
[...]
xScale.domain(d3.extent(layout, function (d){ return d.x; }));
yScale.domain(d3.extent(layout, function (d){ return d.y; }));

在当前版本中(您可以在这里找到它: https : //jsfiddle.net/mn1wmbe3/6/ ),单个节点的拖动和值更改可以很好地工作。 这是我用来移动节点的代码:

node.filter(function(d) { return d.selected; })
    .each(function(d) {
        d.x = xScale.invert(d3.event.x);
        d.y = yScale.invert(d3.event.y);
    })
    .attr("cx", xScale(d.x))
    .attr("cy", yScale(d.y));

从其他示例中可以看出,为了能够同时移动多个节点,我需要将拖动运动的相对坐标( d3.event.dx )添加到每个选定的节点值。 像这样:

node.filter(function(d) { return d.selected; })
    .each(function(d) {
        d.x += xScale.invert(d3.event.dx);
        d.y += yScale.invert(d3.event.dy);
    })
    .attr("cx", xScale(d.x))
    .attr("cy", yScale(d.y));

但是,这的行为不符合预期,并将节点移到很远的地方。 您可以在此处查看它的运行情况。

您对此有何建议? 是否有可能解决该问题并以不同方式移动多个节点?

您只需要进行一些较小的更改即可使事情正常运行。 首先,从以下位置更改拖动事件:

d.x += xScale.invert(d3.event.dx);
d.y += yScale.invert(d3.event.dy);

至:

d.x = xScale.invert(d3.event.x);
d.y = yScale.invert(d3.event.y);

而且事情将不再像以前那样跳来跳去。 但是,如果增加半径的大小,您会注意到,当您第一次开始拖动时,对象将跳到鼠标位置的中心。 这是因为您现在需要指定一个原点函数。 更改此代码:

d3.behavior.drag()
    .on("drag", function(d) {

对此:

.call(d3.behavior.drag()
    .origin(function(d){return {x:xScale(d.x), y:yScale(d.y)};})
    .on("drag", function(d) {

这样,当您拖动某些东西时,它会记住偏移量。 现在一切都会好起来的。

现在要相对移动许多节点,您可以编写自己的dx,dy函数。 只需在dragstart上记录对象的坐标,然后在drag上计算dx,dy ,然后将这些值添加到要移动的其他节点上即可。

我想到了。 基本上,错误是使用动态缩放:

xScale.domain(d3.extent(layout, function (d){ return d.x; }));
yScale.domain(d3.extent(layout, function (d){ return d.y; }));

由于我的测试数据,这导致域蜂鸣:

xScale.domain(-2, 1);
yScale.domain(-1, 0);

如果您以这种方式移动节点,那么这将表现得很好:

d.x = xScale.invert(d3.event.x);
d.y = yScale.invert(d3.event.y);

但是,当尝试通过向节点添加增量距离( d3.event.dx )移动节点时, d3.event.dx会导致意外结果。 这样做的原因是xScale.invert(1)返回-1.994 ,将其添加到原始值后会产生意外的结果。

我使用的解决方法是计算数据的最小值和最大值之间的距离,并将域从零设置为该值:

 extentX = Math.abs(d3.max(graph.layout, function(d) { return d.x;}) - d3.min(graph.layout, function(d) { return d.x;}));
 extentY = Math.abs(d3.max(graph.layout, function(d) { return d.y;}) - d3.min(graph.layout, function(d) { return d.y;}));
 xScale.domain([0, extentX]);
 yScale.domain([0, extentY]);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM