如何使用d3 canvas渲染器添加鼠标事件以强制执行有向图? [英] how to add mouse events to force directed graph using the d3 canvas renderer?

查看:227
本文介绍了如何使用d3 canvas渲染器添加鼠标事件以强制执行有向图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所有其他示例都带有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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆