使用D3.js实现框选节点并进行多节点拖动

2023-11-13

最近再使用d3.js关系图形展示时,需要选中多节点并进行拖动,一开始并不知道D3提供了此API,下面是我结合项目业务整理的框选操作的重点方面的应用。

这是d3提供的api:(使用鼠标或触摸选择一维或二维区域)

可参考示例:https://blockbuilder.org/mbostock/4566102

1、注册框选容器节点:

// 框选容器

container = d3.select(opt.selector).append("svg").classed("svgGraph", true).attr("width", opt.width).attr("height", opt.height);

brushGroup = container.append("g").attr("class", "brush");

2、给画布注册框选事件(按住ctrl,进入框选模式,就可以进行框选操作)

container.on('keydown.brush', keydownedEvent)

container.on('keyup.brush', keyuppedEvent)

// 键盘按键按下事件
function keydownedEvent() {
    const event = d3.event
    if (event.metaKey || event.ctrlKey) {
       // 禁止缩放平移       
       bindBrush();
    } else {
       unbindBrush();
       node.classed("selected", function (p) { return p.selected = false; });
    }
    ctrlKey = event.ctrlKey || event.metaKey;
}

// 键盘按键抬起事件
function keyuppedEvent() {
   ctrlKey = d3.event.ctrlKey || d3.event.metaKey;
}
// 绑定框选事件方法(svgScale:当前图形的缩放值)
function bindBrush() {
    // 因为我的框选容器的父级设置了缩放值transform,所以当前画布可能处于缩放状态下,需要计算当前框选容器的起点位置,而不能直接设置x,y为0
    let x = (0 - svgScale.x) / svgScale.k;
    let y = (0 - svgScale.y) / svgScale.k;
    brushGroup.call(d3.brush()
       .extent([[x, y], [(opt.width + 100) * (1 / svgScale.k), (opt.height + 100) * (1 / svgScale.k)]])
       .on("start", brushstarted)
       .on("brush", brushed)
       .on("end", brushended))
       .on("click.overlay", function (d) {
           if (node) {
               node.classed('selected', false)
           }
        });
}

function unbindBrush() {
    let x = (0 - svgScale.x) / svgScale.k;
    let y = (0 - svgScale.y) / svgScale.k;
    brushGroup.call(d3.brush()
        .extent([[x, y], [(opt.width + 100) * (1 / svgScale.k), (opt.height + 100) * (1 / svgScale.k)]])
        .on(".brush", null));
    brushGroup.selectAll('*').remove();
    brushGroup.attr('fill', false)
        .attr('pointer-events', false)
        .attr('style', false)
}
function brushstarted() {
   if (d3.event.sourceEvent.type !== "end") {
       node.classed("selected", function (d) {
           return d.selected = d.previouslySelected = ctrlKey && d.selected;
       });
   }
}
function brushed() {
    if (d3.event.sourceEvent.type !== "end") {
        var selection = d3.event.selection;
        let x0, y0, x1, y1;
        if (selection) {
            x0 = selection[0][0]
            x1 = selection[1][0]
            y0 = selection[0][1]
            y1 = selection[1][1]
        }
        node.classed("selected", function (d) {
            return d.selected = d.previouslySelected ^
                   (selection != null&& x0 <= d.x && d.x < x1&& y0 <= d.y && d.y < y1);
        });
    }
}
function brushended() {
    if (d3.event.selection != null) {
        d3.select(this).call(d3.event.target.move, null);
    }
}

 

 

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

使用D3.js实现框选节点并进行多节点拖动 的相关文章

  • 单独的数据间隔 bootstrap 轮播 4

    我想为 Bootstrap 4 轮播上的每张幻灯片设置单独的数据间隔 我尝试了一些其他的 javascript 片段 但是它们似乎不适用于我的代码 例如Bootstrap 4 轮播堆栈溢出 https stackoverflow com q
  • 在 userCodeAppPanel 中看不到我的 javascript 代码

    这是来自 Google 电子表格中包含的脚本的代码 唯一的其他代码是onOpen它创建菜单和showDialog 功能 function showDialog userInterface HtmlService createHtmlOutp
  • Jquery文件上传插件进度条

    这个插件 https github com blueimp jQuery File Upload wiki管理网页中的文件上传 并且可以在上传过程中添加很多 UI 元素 您创建一个输入文件类型元素 然后绑定 js 文件 使用实例化代码和 w
  • ES6 类文字中的 IIFE

    在 ES5 中我们都可以这样做 myClass prototype myMethod function return function 我可以对 ES6 类文字执行同样的操作吗 不 至少现在还没有 ES6 类仅支持声明方法 因此任何不直接为
  • Cordova SQLite 保存 BLOB

    我的 Cordova SQLite 插件有问题 如何将 BLOB 图像保存到 SQLite 我在 JS 中有 BLOB 对象 Blob size 96874 type image jpeg proto Blob length 1 我试图拯救
  • Javascript 制作音频 blob

    我正在测试 html 音频标签 我想制作音频 blob url 就像 youtube 或 vimeo 那样 并将其添加到 src 开始播放音频 我一直在测试new Blob and URL createObjectURL 但我不知道如何使用
  • 光标:IE 8 和 9 中的自动行为

    我想要的是为整个正文标记指定cursor pointer 这样页面的背景是可点击的 但我也希望页面的其余部分像以前一样工作 所以我尝试为div设置cursor auto 其中包含这一页 在 FF Chrome 和 safari 中 它工作得
  • Express JS:请求的资源上不存在“Access-Control-Allow-Origin”标头

    我有一个在服务器上运行的 API 和一个连接到它以检索数据的前端客户端 我对跨域问题做了一些研究并使其发挥作用 但我不确定发生了什么变化 我现在在控制台中收到此错误 XMLHttpRequest 无法加载https api mydomain
  • 使用 jquery 更改锚文本和图标

    我有一个隐藏或显示 div 的锚标记 但我无法更改它的文本和图标 如何更改文本和图标标签 因为目前它将图标标签解析为常规文本 锚标记 a class collapse info btn i class icon arrow up icon
  • dc lineChart 单击时弹出数据点信息

    我正在尝试检测折线图数据点上的点击 Per this answer dc scatter plot binding onClick event https stackoverflow com a 22772340 1873386 I am
  • 如何将OpenLayers多边形坐标转换为纬度和经度?

    我正在使用开放层 https openlayers org en latest examples draw freehand html绘制多边形并保存坐标的技术 这是我的代码 var raster new ol layer Tile sou
  • Google 地图 Javascript v3 折线点击事件

    我正在尝试显示一张地图 其中有多条路线布置为折线 单击多段线时 我想显示特定于该线的数据 将数据与线关联不是问题 但无论单击哪条线 显示的数据都会与最近绘制的线关联 就好像每条新折线都会覆盖最后一条线一样 我有一个数据库 其中包含 gpx
  • JavaScript/jQuery - “$ 未定义 - $function()”错误

    我正在尝试运行 JavaScript jQuery 函数并且Firebug http en wikipedia org wiki Firebug 28software 29得到错误 is not defined function JavaS
  • 如何处理 setTimeout() 的多个实例?

    阻止创建 setTimeout 函数的多个实例 在 JavaScript 中 的最推荐 最佳方法是什么 一个例子 伪代码 function mouseClick moveDiv div 0001 mouseX mouseY function
  • Ajax 函数在重定向后不保存滚动位置

    正如标题所述 我编写了一个 ajax 函数 该函数应该滚动到用户在重定向之前所在的位置 我写了一个alert对于测试场景 它确实触发了 但滚动不断回到顶部 我在这里做错了什么 JavaScript ajax type GET url Adm
  • jQuery 模板插件:如何创建双向绑定?

    我开始使用 jQuery 模板插件 微软创建的 但现在我面临这个问题 模板用于绑定到对象数组的一堆表单 当我更改其中一个表单上的某些内容时 我希望更新绑定的对象 但我不知道如何自动执行该操作 这是一个简单的例子 现实生活中的模板和对象要复杂
  • 如果突出显示一个单词并且用户单击连接单词,则同时突出显示两个单词

    我最近发布了一个question https stackoverflow com questions 34963610 how can i highlight a word term quicker and smarter寻求一种更智能地突
  • 为什么我从 c# 到 js 得到不同的 MD5 哈希值?

    我有一个用于加密密码的 C 函数 System Security Cryptography MD5CryptoServiceProvider md5Provider new System Security Cryptography MD5C
  • 如何在react.js中将/n替换为换行符?

    我正在尝试更换每一个 n to a br tag in ReactJS In my note note对象有一个包含多个的字符串 n in it 示例注释 注释 test ntest ntest 我尝试过的ReactJS note note
  • 如何更改数据表中标题单元格的内容?

    我正在使用数据表 http datatables net plugin 在我的可排序列上 我想用按钮替换列文本 但是这样做 oSettings aoColumns i nTh text 我可以检索相应列的文本 但是 oSettings ao

随机推荐