javascript - 如何使用 d3 Canvas 渲染器添加鼠标事件以强制执行有向图?

标签 javascript events d3.js click mouse

所有其他示例都有带有 svg.append() 的鼠标事件....我不知道在哪里“输入”以在 Canvas 渲染器中获取弧线并添加 .on('click', function(){}) 采用 v4 风格。我想点击获取d的值。在此示例中我在哪里添加处理程序?我理解这个例子下面的旧方法。

这样的东西能行吗? d3.select(canvas).call(d3.mouse()).on("点击", ...)

链接到 working example

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 v4.x 中,您可以使用与在 v3.x 中几乎相同的方式添加点击事件:

selection.on("click", function(d){
    //do whatever you want with the datum
});

您问题中的问题不是 v3 与 v4,这不是您共享的代码中的问题。该代码的问题在于它使用 HTML canvas 而不是 SVG 来呈现数据可视化。

与 SVG 不同,canvas 没有元素的节点树。您不能“选择某物”并向其添加事件处理程序。

将 Canvas 视为光栅图像,如 BMP 或 JPEG。你可以找到你点击的 x 和 y 位置,你甚至可以找到那个像素的颜色,但是你不能选择给定的节点元素,因为 Canvas 没有。

例如,检查这个 tutorial from Nadieh Bremer看看在使用 HTML Canvas 时获得用户点击的圆圈有多复杂。

关于javascript - 如何使用 d3 Canvas 渲染器添加鼠标事件以强制执行有向图?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40988437/

相关文章:

c# - KeyDown 事件未触发?

javascript - dc.js 中带有计数的条形图

javascript - D3 v5 变焦口吃

javascript - 如何在单击按钮时更改组件颜色

javascript - 是否可以在不使用 href 的情况下添加事件类?

Javascript正则表达式试图转义/**

HTML 表单标签,实际的默认事件或行为是什么?

c# - ASP.net 和 Javascript 确认

objective-c - UIScrollview 事件将被包含的 UIButtons 捕获

javascript - D3 v4 Zoom x 轴缩放和平移问题