- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我试图允许用户使用 d3 的力导向图选择和拖动多个节点,但似乎无法让它工作。
有一个很好的示例,说明如何选择多个节点并将它们拖动到 here 和标准力导向图 here 。
当我尝试将两者结合起来时,拖动多个节点的需求似乎有点不对劲,因为节点不会被拖动在一起,而是一个被拖动,而其他选定的节点则在其周围摆动:
http://jsfiddle.net/pkerpedjiev/w4a5makd/2/
有人可以告诉我我做错了什么吗?
代码如下:
var width = 960,
height = 500,
shiftKey;
var svg = d3.select("body")
.attr("tabindex", 1)
.on("keydown.brush", keydown)
.on("keyup.brush", keyup)
.each(function() { this.focus(); })
.append("svg")
.attr("width", width)
.attr("height", height);
var link = svg.append("g")
.attr("class", "link")
.selectAll("line");
var brush = svg.append("g")
.datum(function() { return {selected: false, previouslySelected: false}; })
.attr("class", "brush");
var node = svg.append("g")
.attr("class", "node")
.selectAll("circle");
graph.links.forEach(function(d) {
d.source = graph.nodes[d.source];
d.target = graph.nodes[d.target];
});
link = link.data(graph.links).enter().append("line")
.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
brush.call(d3.svg.brush()
.x(d3.scale.identity().domain([0, width]))
.y(d3.scale.identity().domain([0, height]))
.on("brushstart", function(d) {
node.each(function(d) { d.previouslySelected = shiftKey && d.selected; });
})
.on("brush", function() {
var extent = d3.event.target.extent();
node.classed("selected", function(d) {
return d.selected = d.previouslySelected ^
(extent[0][0] <= d.x && d.x < extent[1][0]
&& extent[0][1] <= d.y && d.y < extent[1][1]);
});
})
.on("brushend", function() {
d3.event.target.clear();
d3.select(this).call(d3.event.target);
}));
var force = d3.layout.force()
.charge(-120)
.linkDistance(30)
.nodes(graph.nodes)
.links(graph.links)
.size([width, height])
.start();
node = node.data(graph.nodes).enter().append("circle")
.attr("r", 4)
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.on("mousedown", function(d) {
if (!d.selected) { // Don't deselect on shift-drag.
if (!shiftKey) node.classed("selected", function(p) { return p.selected = d === p; });
else d3.select(this).classed("selected", d.selected = true);
}
})
.on("mouseup", function(d) {
if (d.selected && shiftKey) d3.select(this).classed("selected", d.selected = false);
})
.call(force.drag()
.on("drag", function(d) { nudge(d3.event.dx, d3.event.dy); }));
function tick() {
link.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
node.attr('cx', d.x).attr('cy', d.y);
};
force.on("tick", tick);
function nudge(dx, dy) {
node.filter(function(d) { return d.selected; })
.attr("cx", function(d) { return d.x += dx; })
.attr("cy", function(d) { return d.y += dy; })
link.filter(function(d) { return d.source.selected; })
.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; });
link.filter(function(d) { return d.target.selected; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
d3.event.sourceEvent.preventDefault();
}
function keydown() {
if (!d3.event.metaKey) switch (d3.event.keyCode) {
case 38: nudge( 0, -1); break; // UP
case 40: nudge( 0, +1); break; // DOWN
case 37: nudge(-1, 0); break; // LEFT
case 39: nudge(+1, 0); break; // RIGHT
}
shiftKey = d3.event.shiftKey || d3.event.metaKey;
}
function keyup() {
shiftKey = d3.event.shiftKey || d3.event.metaKey;
}
最佳答案
想通了。诀窍是覆盖默认的force.drag 行为。默认情况下,拖动行为将被拖动的节点标记为固定并直接更改其位置。这是为了防止它在拖动时被其他节点拉动。
当选择多个节点时,所有节点都必须固定,我们必须直接更改它们的位置(所有 px
、py
、x
和 y
)。这允许我们一次拖动多个节点。请参阅此处的 fiddle :
http://jsfiddle.net/pkerpedjiev/29majy5c/2/
以及相应的代码:
var width = 400,
height = 500,
shiftKey;
var svg = d3.select("body")
.attr("tabindex", 1)
.on("keydown.brush", keydown)
.on("keyup.brush", keyup)
.each(function() { this.focus(); })
.append("svg")
.attr("width", width)
.attr("height", height);
var link = svg.append("g")
.attr("class", "link")
.selectAll("line");
var brush = svg.append("g")
.datum(function() { return {selected: false, previouslySelected: false}; })
.attr("class", "brush");
var node = svg.append("g")
.attr("class", "node")
.selectAll("circle");
var graph = {"nodes":[{"x":444,"y":275},{"x":378,"y":324},{"x":478,"y":278},{"x":471,"y":256},{"x":382,"y":269},{"x":371,"y":247},{"x":359,"y":276},{"x":364,"y":302},{"x":400,"y":330},{"x":388,"y":298},{"x":524,"y":296},{"x":570,"y":243},{"x":552,"y":159},{"x":502,"y":287},{"x":511,"y":313},{"x":513,"y":265},{"x":602,"y":132},{"x":610,"y":90},{"x":592,"y":91},{"x":575,"y":89},{"x":607,"y":73},{"x":591,"y":68},{"x":574,"y":73},{"x":589,"y":149},{"x":620,"y":205},{"x":621,"y":230},{"x":589,"y":234},{"x":602,"y":223},{"x":548,"y":188},{"x":532,"y":196},{"x":548,"y":114},{"x":575,"y":174},{"x":497,"y":250},{"x":576,"y":196},{"x":504,"y":201},{"x":494,"y":186},{"x":482,"y":199},{"x":505,"y":219},{"x":486,"y":216},{"x":590,"y":306},{"x":677,"y":169},{"x":657,"y":258},{"x":667,"y":205},{"x":552,"y":227},{"x":518,"y":173},{"x":473,"y":125},{"x":796,"y":260},{"x":731,"y":272},{"x":642,"y":288},{"x":576,"y":269},{"x":605,"y":187},{"x":559,"y":289},{"x":544,"y":356},{"x":505,"y":365},{"x":579,"y":289},{"x":619,"y":282},{"x":574,"y":329},{"x":664,"y":306},{"x":627,"y":304},{"x":643,"y":327},{"x":664,"y":348},{"x":665,"y":327},{"x":653,"y":317},{"x":650,"y":338},{"x":622,"y":321},{"x":633,"y":338},{"x":647,"y":357},{"x":718,"y":362},{"x":636,"y":240},{"x":640,"y":227},{"x":617,"y":249},{"x":631,"y":254},{"x":566,"y":213},{"x":713,"y":322},{"x":716,"y":298},{"x":666,"y":241},{"x":627,"y":355}],"links":[{"source":1,"target":0},{"source":2,"target":0},{"source":3,"target":0},{"source":3,"target":2},{"source":4,"target":0},{"source":5,"target":0},{"source":6,"target":0},{"source":7,"target":0},{"source":8,"target":0},{"source":9,"target":0},{"source":11,"target":10},{"source":11,"target":3},{"source":11,"target":2},{"source":11,"target":0},{"source":12,"target":11},{"source":13,"target":11},{"source":14,"target":11},{"source":15,"target":11},{"source":17,"target":16},{"source":18,"target":16},{"source":18,"target":17},{"source":19,"target":16},{"source":19,"target":17},{"source":19,"target":18},{"source":20,"target":16},{"source":20,"target":17},{"source":20,"target":18},{"source":20,"target":19},{"source":21,"target":16},{"source":21,"target":17},{"source":21,"target":18},{"source":21,"target":19},{"source":21,"target":20},{"source":22,"target":16},{"source":22,"target":17},{"source":22,"target":18},{"source":22,"target":19},{"source":22,"target":20},{"source":22,"target":21},{"source":23,"target":16},{"source":23,"target":17},{"source":23,"target":18},{"source":23,"target":19},{"source":23,"target":20},{"source":23,"target":21},{"source":23,"target":22},{"source":23,"target":12},{"source":23,"target":11},{"source":24,"target":23},{"source":24,"target":11},{"source":25,"target":24},{"source":25,"target":23},{"source":25,"target":11},{"source":26,"target":24},{"source":26,"target":11},{"source":26,"target":16},{"source":26,"target":25},{"source":27,"target":11},{"source":27,"target":23},{"source":27,"target":25},{"source":27,"target":24},{"source":27,"target":26},{"source":28,"target":11},{"source":28,"target":27},{"source":29,"target":23},{"source":29,"target":27},{"source":29,"target":11},{"source":30,"target":23},{"source":31,"target":30},{"source":31,"target":11},{"source":31,"target":23},{"source":31,"target":27},{"source":32,"target":11},{"source":33,"target":11},{"source":33,"target":27},{"source":34,"target":11},{"source":34,"target":29},{"source":35,"target":11},{"source":35,"target":34},{"source":35,"target":29},{"source":36,"target":34},{"source":36,"target":35},{"source":36,"target":11},{"source":36,"target":29},{"source":37,"target":34},{"source":37,"target":35},{"source":37,"target":36},{"source":37,"target":11},{"source":37,"target":29},{"source":38,"target":34},{"source":38,"target":35},{"source":38,"target":36},{"source":38,"target":37},{"source":38,"target":11},{"source":38,"target":29},{"source":39,"target":25},{"source":40,"target":25},{"source":41,"target":24},{"source":41,"target":25},{"source":42,"target":41},{"source":42,"target":25},{"source":42,"target":24},{"source":43,"target":11},{"source":43,"target":26},{"source":43,"target":27},{"source":44,"target":28},{"source":44,"target":11},{"source":45,"target":28},{"source":47,"target":46},{"source":48,"target":47},{"source":48,"target":25},{"source":48,"target":27},{"source":48,"target":11},{"source":49,"target":26},{"source":49,"target":11},{"source":50,"target":49},{"source":50,"target":24},{"source":51,"target":49},{"source":51,"target":26},{"source":51,"target":11},{"source":52,"target":51},{"source":52,"target":39},{"source":53,"target":51},{"source":54,"target":51},{"source":54,"target":49},{"source":54,"target":26},{"source":55,"target":51},{"source":55,"target":49},{"source":55,"target":39},{"source":55,"target":54},{"source":55,"target":26},{"source":55,"target":11},{"source":55,"target":16},{"source":55,"target":25},{"source":55,"target":41},{"source":55,"target":48},{"source":56,"target":49},{"source":56,"target":55},{"source":57,"target":55},{"source":57,"target":41},{"source":57,"target":48},{"source":58,"target":55},{"source":58,"target":48},{"source":58,"target":27},{"source":58,"target":57},{"source":58,"target":11},{"source":59,"target":58},{"source":59,"target":55},{"source":59,"target":48},{"source":59,"target":57},{"source":60,"target":48},{"source":60,"target":58},{"source":60,"target":59},{"source":61,"target":48},{"source":61,"target":58},{"source":61,"target":60},{"source":61,"target":59},{"source":61,"target":57},{"source":61,"target":55},{"source":62,"target":55},{"source":62,"target":58},{"source":62,"target":59},{"source":62,"target":48},{"source":62,"target":57},{"source":62,"target":41},{"source":62,"target":61},{"source":62,"target":60},{"source":63,"target":59},{"source":63,"target":48},{"source":63,"target":62},{"source":63,"target":57},{"source":63,"target":58},{"source":63,"target":61},{"source":63,"target":60},{"source":63,"target":55},{"source":64,"target":55},{"source":64,"target":62},{"source":64,"target":48},{"source":64,"target":63},{"source":64,"target":58},{"source":64,"target":61},{"source":64,"target":60},{"source":64,"target":59},{"source":64,"target":57},{"source":64,"target":11},{"source":65,"target":63},{"source":65,"target":64},{"source":65,"target":48},{"source":65,"target":62},{"source":65,"target":58},{"source":65,"target":61},{"source":65,"target":60},{"source":65,"target":59},{"source":65,"target":57},{"source":65,"target":55},{"source":66,"target":64},{"source":66,"target":58},{"source":66,"target":59},{"source":66,"target":62},{"source":66,"target":65},{"source":66,"target":48},{"source":66,"target":63},{"source":66,"target":61},{"source":66,"target":60},{"source":67,"target":57},{"source":68,"target":25},{"source":68,"target":11},{"source":68,"target":24},{"source":68,"target":27},{"source":68,"target":48},{"source":68,"target":41},{"source":69,"target":25},{"source":69,"target":68},{"source":69,"target":11},{"source":69,"target":24},{"source":69,"target":27},{"source":69,"target":48},{"source":69,"target":41},{"source":70,"target":25},{"source":70,"target":69},{"source":70,"target":68},{"source":70,"target":11},{"source":70,"target":24},{"source":70,"target":27},{"source":70,"target":41},{"source":70,"target":58},{"source":71,"target":27},{"source":71,"target":69},{"source":71,"target":68},{"source":71,"target":70},{"source":71,"target":11},{"source":71,"target":48},{"source":71,"target":41},{"source":71,"target":25},{"source":72,"target":26},{"source":72,"target":27},{"source":72,"target":11},{"source":73,"target":48},{"source":74,"target":48},{"source":74,"target":73},{"source":75,"target":69},{"source":75,"target":68},{"source":75,"target":25},{"source":75,"target":48},{"source":75,"target":41},{"source":75,"target":70},{"source":75,"target":71},{"source":76,"target":64},{"source":76,"target":65},{"source":76,"target":66},{"source":76,"target":63},{"source":76,"target":62},{"source":76,"target":48},{"source":76,"target":58}]}
graph.links.forEach(function(d) {
d.source = graph.nodes[d.source];
d.target = graph.nodes[d.target];
});
link = link.data(graph.links).enter().append("line")
.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
brush.call(d3.svg.brush()
.x(d3.scale.identity().domain([0, width]))
.y(d3.scale.identity().domain([0, height]))
.on("brushstart", function(d) {
node.each(function(d) { d.previouslySelected = shiftKey && d.selected; });
})
.on("brush", function() {
var extent = d3.event.target.extent();
node.classed("selected", function(d) {
return d.selected = d.previouslySelected ^
(extent[0][0] <= d.x && d.x < extent[1][0]
&& extent[0][1] <= d.y && d.y < extent[1][1]);
});
})
.on("brushend", function() {
d3.event.target.clear();
d3.select(this).call(d3.event.target);
}));
var force = d3.layout.force()
.charge(-120)
.linkDistance(30)
.nodes(graph.nodes)
.links(graph.links)
.size([width, height])
.start();
node = node.data(graph.nodes).enter().append("circle")
.attr("r", 4)
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.on("mousedown", function(d) {
if (!d.selected) { // Don't deselect on shift-drag.
if (!shiftKey) node.classed("selected", function(p) { return p.selected = d === p; });
else d3.select(this).classed("selected", d.selected = true);
}
})
.on("mouseup", function(d) {
if (d.selected && shiftKey) d3.select(this).classed("selected", d.selected = false);
})
.call(d3.behavior.drag()
.on("dragstart", function(d1) {
node.filter(function(d) { return d.selected; })
.each(function(d) { d.fixed |= 2; })
})
.on("drag", function(d1) {
node.filter(function(d) { return d.selected; })
.each(function(d) {
d.x += d3.event.dx;
d.y += d3.event.dy;
d.px += d3.event.dx;
d.py += d3.event.dy;
})
force.resume();
})
.on("dragend", function(d) {
node.filter(function(d) { return d.selected; })
.each(function(d) { d.fixed &= ~6; })
}));
function tick() {
link.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
node.attr('cx', function(d) { return d.x; }).attr('cy', function(d) { return d.y; });
};
force.on("tick", tick);
function keydown() {
shiftKey = d3.event.shiftKey || d3.event.metaKey;
}
function keyup() {
shiftKey = d3.event.shiftKey || d3.event.metaKey;
}
关于javascript - d3.js 将可拖动网络与力导向图相结合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28113792/
这与 Payubiz payment gateway sdk 关系不大一体化。但是,主要问题与构建项目有关。 每当我们尝试在模拟器上运行应用程序时。我们得到以下失败: What went wrong:
我有一个现有的应用程序,其中包含在同一主机上运行的 4 个 docker 容器。它们已使用 link 命令链接在一起。 然而,在 docker 升级后,link 行为已被弃用,并且似乎有所改变。我们现
在 Internet 模型中有四层:链路 -> 网络 -> 传输 -> 应用程序。 我真的不知道网络层和传输层之间的区别。当我读到: Transport layer: include congesti
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
前言: 生活中,我们在上网时,打开一个网页,就可以看到网址,如下: https😕/xhuahua.blog.csdn.net/ 访问网站使用的协议类型:https(基于 http 实现的,只不过在
网络 避免网络问题降低Hadoop和HBase性能的最重要因素可能是所使用的交换硬件,在项目范围的早期做出的决策可能会导致群集大小增加一倍或三倍(或更多)时出现重大问题。 需要考虑的重要事项:
网络 网络峰值 如果您看到定期的网络峰值,您可能需要检查compactionQueues以查看主要压缩是否正在发生。 有关管理压缩的更多信息,请参阅管理压缩部分的内容。 Loopback IP
Pure Data 有一个 loadbang 组件,它按照它说的做:当图形开始运行时发送一个 bang。 NoFlo 的 core/Kick 在其 IN 输入被击中之前不会发送其数据,并且您无法在 n
我有一台 Linux 构建机器,我也安装了 minikube。在 minikube 实例中,我安装了 artifactory,我将使用它来存储各种构建工件 我现在希望能够在我的开发机器上做一些工作(这
我想知道每个视频需要多少种不同的格式才能支持所有主要设备? 在我考虑的主要设备中:安卓手机 + iPhone + iPad . 对具有不同比特率的视频进行编码也是一种好习惯吗? 那里有太多相互矛盾的信
我有一个使用 firebase 的 Flutter Web 应用程序,我有两个 firebase 项目(dev 和 prod)。 我想为这个项目设置 Flavors(只是网络没有移动)。 在移动端,我
我正在读这篇文章Ars article关于密码安全,它提到有一些网站“在传输之前对密码进行哈希处理”? 现在,假设这不使用 SSL 连接 (HTTPS),a.这真的安全吗? b.如果是的话,你会如何在
我试图了解以下之间的关系: eth0在主机上;和 docker0桥;和 eth0每个容器上的接口(interface) 据我了解,Docker: 创建一个 docker0桥接,然后为其分配一个与主机上
我需要编写一个java程序,通过网络将对象发送到客户端程序。问题是一些需要发送的对象是不可序列化的。如何最好地解决这个问题? 最佳答案 发送在客户端重建对象所需的数据。 关于java - 不可序列化对
所以我最近关注了this有关用 Java 制作基本聊天室的教程。它使用多线程,是一个“面向连接”的服务器。我想知道如何使用相同的 Sockets 和 ServerSockets 来发送对象的 3d 位
我想制作一个系统,其中java客户端程序将图像发送到中央服务器。中央服务器保存它们并运行使用这些图像的网站。 我应该如何发送图像以及如何接收它们?我可以使用同一个网络服务器来接收和显示网站吗? 最佳答
我正在尝试设置我的 rails 4 应用程序,以便它发送电子邮件。有谁知道我为什么会得到: Net::SMTPAuthenticationError 534-5.7.9 Application-spe
我正在尝试编写一个简单的客户端-服务器程序,它将客户端计算机连接到服务器计算机。 到目前为止,我的代码在本地主机上运行良好,但是当我将客户端代码中的 IP 地址替换为服务器计算机的本地 IP 地址时,
我需要在服务器上并行启动多个端口,并且所有服务器套接字都应在 socket.accept() 上阻塞。 同一个线程需要启动客户端套接字(许多)来连接到特定的 ServerSocket。 这能实现吗?
我的工作执行了大约 10000 次以下任务: 1) HTTP 请求(1 秒) 2)数据转换(0.3秒) 3)数据库插入(0.7秒) 每次迭代的总时间约为 2 秒,分布如上所述。 我想做多任务处理,但我
我是一名优秀的程序员,十分优秀!