如何使用 d3 画布渲染器添加鼠标事件以强制定向图?

2024-01-27

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

这样的东西可能有效吗?d3.select(canvas).call(d3.mouse()).on("click", ...)

link to 工作示例 http://bl.ocks.org/mbostock/95aa92e2f4e8345aaa55a4a94d41ce37

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);
}

old way

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,这不是您共享的代码中的问题。该代码的问题在于它使用了 HTMLcanvas,而不是 SVG,来渲染数据可视化。

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

将画布视为光栅图像,如 BMP 或 JPEG。您可以找到您单击的 x 和 y 位置,您甚至可以找到该像素的颜色,但您无法选择给定的节点元素,因为画布没有。

例如,检查这个纳迪·布雷默 (Nadieh Bremer) 的教程 http://www.visualcinnamon.com/2015/11/learnings-from-a-d3-js-addict-on-starting-with-canvas.html看看使用 HTML canvas 时获取用户点击的圆圈有多复杂。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 d3 画布渲染器添加鼠标事件以强制定向图? 的相关文章

  • 使用 vscode 调试器调试 next.js

    我已经使用安装了一个项目创建下一个应用程序 https github com segmentio create next app 我需要使用我的编辑器 vscode 调试服务器端渲染 所以我访问过vscode recipes 如何调试 ne
  • 主干视图 DOM 元素已删除

    我一直在阅读有关 Backbone js 僵尸 或内存泄漏 问题的信息 基本上 当您不再需要该元素时 您必须从 DOM 中解除绑定并删除该元素 以确保所有事件也被删除 现在 我有一个包含几个容器的单页应用程序 div div div div
  • React js Stripe 结账不起作用

    我正在尝试在 React js 应用程序中呈现条带结账默认表单
  • 了解设置 JQuery 变量

    了解设置 JQuery 变量 最近 我通过在 StackOverflow 上遇到的另一个问题寻找帮助 了解到如何设置 JQuery 变量 如下所示 您可以通过简单地调用变量来创建输入字段 并且锚变量似乎也定义了样式 var clicked
  • 为什么 JavaScript base-36 转换看起来不明确

    我目前正在编写一段使用 Base 36 编码的 JavaScript 我遇到了这个问题 parseInt welcomeback 36 toString 36 看来要回归了 welcomebacg 我在 Chrome 开发者控制台和 Nod
  • jquery.find() 可以只选择直接子项吗?

    我应该向 jQuery find 提供什么参数来选择元素子元素而不选择其他元素 我不能用 gt 引导选择器 而用 将选择所有后代 而不仅仅是直接子代 我知道 jQuery children 但这是一个库 因此用户能够提供自己的选择器 并且我
  • 如何重置使用 JavaScript 更改的 CSS 属性?

    我的导航按钮的宽度从 100px 增加到 150px 当鼠标悬停在 nav li hover width 150px 但是使用 javascript 我已经做到了 无论选择哪个选项 宽度都将继续为 150px 当选择每个选项时 它会使其他选
  • 使用 JavaScript 使链接保持活动状态并在单击时显示悬停效果

    I am struggling to make this work I d like to make it where if O F is clicked the hover state stays active if another li
  • Google App Engine:修改云运行环境

    我正在尝试部署一个使用自定义 Node js 服务器的 Next js 应用程序 我想将自定义构建变量注入应用程序 next config js const NODE ENV process env NODE ENV const envTy
  • 如何监听 jQuery AJAX 请求?

    以下两种实现 ajaxRequest 1 2 的方法应该是等效的 话说回来 为什么验证回调已执行的单元测试 3 在 1 中成功而在 2 中失败 我应该如何重写测试 3 来监视 2 中的成功回调 如果我尝试stub jQuery ajax使用
  • 可以使用 jQuery 或 Javascript 将图片的特定部分用作链接吗?

    我有这个想法 将图片 而不是文本 的各个部分链接到不同的页面或网站 并且我想在不实际创建不同的照片并将它们彼此靠近的情况下完成 这样看起来就像是一张完整的图片 这里有人知道如何使用 JavaScript 的变体 例如 jQuery 或纯 J
  • Node.js:如何在检索数据(块)时关闭响应/请求

    我正在用 node js 构建一个应用程序 它加载多个页面并分析内容 因为 node js 发送块 所以我可以分析这些块 如果一个块包含例如索引 nofollow 我想关闭该连接并继续其余部分 var host example com to
  • 从未用 @flow 标记的导入文件中获取类型定义

    TL DR我怎么告诉flow从未声明的导入模块导入类型定义 flow 加长版 流接缝能够从不使用流语法的文件中派生类型 请参阅示例 示例文件 flow js if Math random lt 0 5 var y hello else va
  • JavaScript 重定向到新窗口

    我有以下代码 它根据下拉列表的值重定向到页面 我如何使其在新窗口中打开 function goto form var index form select selectedIndex if form select options index
  • Meteor - 从客户端取消服务器方法

    我正在通过服务器方法执行数据库计数 用户可以选择他们希望如何执行计数 然后调用该方法 我的问题是 计数可能需要一些时间 并且用户可能会在方法运行时改变主意并请求不同的计数 有什么方法可以取消调用的方法并运行新的计数吗 我认为 this un
  • 在javascript中解析json - 长数字被四舍五入

    我需要解析一个包含长数字的 json 在 java servlet 中生成 问题是长数字被四舍五入 当执行这段代码时 var s x 6855337641038665531 var obj JSON parse s alert obj x
  • Firefox 书签探索未超过 Javascript 的第一级

    我已经编写了一些代码来探索我的 Firefox 书签 但我只获得了第一级书签 即我没有获得文件夹中的链接 e g 搜索引擎 雅虎网站 谷歌网站 在此示例中 我只能访问 Search engines 和 google com 不能访问 yah
  • Javascript 纪元时间(以天为单位)

    我需要以天为单位的纪元时间 迄今为止 我已经看到过有关如何翻译它的帖子 但几天后就没有了 我对纪元时间很不好 我怎么能得到这个 我需要以天为单位的纪元时间 我将解释为您想要自纪元以来的天数 纪元本身是第 0 天 或第 1 天的开始 无论您如
  • 如何更改此 jquery 插件的时区/时间戳?

    我正在使用这个名为 timeago 的插件 在这里找到 timeago yarp com 它工作得很好 只是它在似乎不同的时区运行 我住在美国东部 费城时区 当我将准确的 EST 时间放入 timeago 插件时 比如 2011 05 28
  • 如何获取浏览器视口中当前显示的内容

    如何获取当前正在显示长文档的哪一部分的指示 例如 如果我的 html 包含 1 000 行 1 2 3 9991000 并且用户位于显示第 500 行的中间附近 那么我想得到 500 n501 n502 或类似的内容 显然 大多数场景都会比

随机推荐