如何使用d3 canvas渲染器添加鼠标事件以强制执行有向图? [英] how to add mouse events to force directed graph using the d3 canvas renderer?
问题描述
所有其他示例都带有svg.append()...的鼠标事件.我不知道在哪里进入"画布渲染器中的弧线并以v4样式添加.on('click', function(){})
.我想单击以获取d
的值.在此示例中,我应在哪里添加处理程序?我了解此示例下方的旧方法.
All the other examples have mouse events with svg.append().... I don't know where to "enter" to get the arcs in a canvas renderer and add .on('click', function(){})
in v4 style. I want to click to get the value of d
. Where do I add the handler in this example? I understand the old way below this example.
像这样的作品可能吗? d3.select(canvas).call(d3.mouse()).on("click", ...)
Might something like this work? d3.select(canvas).call(d3.mouse()).on("click", ...)
链接到工作示例
var links = d3.range(nodes.length - 1).map(function(i) {
return {
source: Math.floor(Math.sqrt(i)),
target: i + 1
};
});
var simulation = d3.forceSimulation(nodes)
.force("charge", d3.forceManyBody())
.force("link", d3.forceLink(links).distance(20).strength(1))
.force("x", d3.forceX())
.force("y", d3.forceY())
.on("tick", ticked);
var canvas = document.querySelector("canvas"),
context = canvas.getContext("2d"),
width = canvas.width,
height = canvas.height;
d3.select(canvas)
.call(d3.drag()
.container(canvas)
.subject(dragsubject)
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
function ticked() {
context.clearRect(0, 0, width, height);
context.save();
context.translate(width / 2, height / 2);
context.beginPath();
links.forEach(drawLink);
context.strokeStyle = "#aaa";
context.stroke();
context.beginPath();
nodes.forEach(drawNode);
context.fill();
context.strokeStyle = "#fff";
context.stroke();
context.restore();
}
function dragsubject() {
return simulation.find(d3.event.x - width / 2, d3.event.y - height / 2);
}
function dragstarted() {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d3.event.subject.fx = d3.event.subject.x;
d3.event.subject.fy = d3.event.subject.y;
}
function dragged() {
d3.event.subject.fx = d3.event.x;
d3.event.subject.fy = d3.event.y;
}
function dragended() {
if (!d3.event.active) simulation.alphaTarget(0);
d3.event.subject.fx = null;
d3.event.subject.fy = null;
}
function drawLink(d) {
context.moveTo(d.source.x, d.source.y);
context.lineTo(d.target.x, d.target.y);
}
function drawNode(d) {
context.moveTo(d.x + 3, d.y);
context.arc(d.x, d.y, 3, 0, 2 * Math.PI);
}
旧方式
var node = svg.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(graph.nodes)
.enter().append("circle")
.attr("r", 8)
.attr("fill", function(d) { return color(d.group); })
.on("click", togglenode)
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
推荐答案
由于我使用了画布渲染器,因此我只是作弊并使用了示例中的d3 dragstart事件.我想知道有办法做到这一点.
Since I used the canvas renderer, I just cheated and used the d3 dragstart event already in the example. There's probably a way to do it like this I'd like to know.
d3.select(canvas)
.call(d3.drag()
.container(canvas)
.subject(dragsubject)
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d3.event.subject.fx = d3.event.subject.x;
d3.event.subject.fy = d3.event.subject.y;
//broadcast the selection to parent
emitter.emit( d3.event.subject );
}
这篇关于如何使用d3 canvas渲染器添加鼠标事件以强制执行有向图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!