【 D3.js 进阶系列 — 2.1 】 力学图的事件 + 顶点的固定

本章讨论在力学图中常用到的事件( Event ),然后对【进阶 – 第 2.0 章】的人物关系图进行改进,使用户能够固定拖拽的对象。

211

在【入门 – 第 9.2 章】和【进阶 – 第 2.0 章】中,都用到了以下代码:

这里的 force 是之前代码中定义的布局( Layout ),tick 表示当运动进行中每更新一帧时。这是力学图中最常使用的事件,用于设定力学图每一帧是如何更新的。除此之外,还有一些其他常用的事件。

1. 布局的事件

代码中,假设定义如下的布局:

力学图布局 force 本身的事件,D3 提供了3个,分别为 start ,end,tick。在写代码时,可形如:

各事件发生时,就会执行相应的代码。

2. 拖拽的事件

在【入门 – 第 9.2 章】和【进阶 – 第 2.0 章】中,都出现了以下代码:

即设定当拖拽时调用函数 force.drag()。D3 中提供了3种拖拽事件:dragstart、dragend、drag。

上面代码中,分别定义了三种事件后,将此拖拽函数赋值给变量 drag,在调用时,只要使用:

即可。

3. 顶点的固定

使用布局转换数据之后,顶点有一个属性 fixed 。当这个值为 true 时,顶点就是固定不动的;为 false 时,它就是运动的。默认是 false 的。

如果要改进【进阶 – 第 2.0 章】的代码,使得用户能够任意固定和解锁顶点,可添加代码如下:

当拖拽开始时,被拖拽顶点设定为固定的:

当鼠标双击顶点时,对顶点解锁:

4. 结果

在左上角添加了标签文字,请好好体会一下各事件发生的状况。

拖拽后顶点会固定,双击顶点能够解锁。

完整代码请点击下面链接,右键选择“查看网页源代码”:

http://www.ourd3js.com/demo/J-2.1/relationforce.html

源代码和图片打包下载:j21.zip

谢谢阅读。


文档信息


【 D3.js 进阶系列 — 2.1 】 力学图的事件 + 顶点的固定》上有34条评论

  1. 老师您好,我想问下,如何在鼠标放上某个人物时,让和他相连的那几根线变高亮颜色,如您能回答,能否发到我邮箱463962344@qq.com呢。万分感谢。

  2. 老师,从入门一直学过来,觉得您真的给我们提供了一个很好的平台。有两个问题请教一下:
    1.如何让页面加载的时候图片是固定的,而不是会跳一下
    2.我发现做出来的图的各个部分的位置是不固定的,怎么样设置为固定位置呢?
    再次感谢老师的指导!

    • 你好。回答如下:
      1. 这个问题不好解决,如果没有强烈要求需要做到的话,还是不要解决的好。
      2. 本例中,节点的位置,在移动之后就会固定。主要是通过设定节点的 fixed 属性。
      谢谢。

      • 老师您好,我想问下,如何在鼠标放上某张人物图片的时候,和他相连的那些线也变高亮的颜色?

  3. 遇到一个问题,目前这个一旦节点比较多了以后 就显得有些乱 所以我现在想把每个节点 按照我给的x,y值初始排列出来, 试了好久 都没法弄好 请大神指点指点 比较急 可联系我QQ或者邮箱

    • 节点的初始值是可以手动赋予的,在布局的作用发生之前更改节点的坐标即可。

      • 老师 节点初始值的手动赋予 到底是怎么操作的啊

  4. Hello,我有个需求,就是拖拽后保存位置,下次打开还是那个位置,请问我应该保存什么信息?如果有新增删除之类的操作又该怎么处理呢?谢谢 :)

    • 应当保存节点的位置信息。下一次重新打开网页时,调用布局,不理会布局如何作用,强行将节点的位置赋值为保存的位置。

      新增删除的操作可参考:http://www.ourd3js.com/wordpress/841

      处理起来仍然不简单的,你需要多加研究。

      • 谢谢啦,我已经实现了,但是发现了一个新的问题,元素的拖拽和整个svg的缩放平移存在冲突,即当你移动过元素后,再用d3.behavior.zoom进行平移或缩放,zoom里的d3.event.translate坐标是元素移动过的坐标,也就是会产生跳动。请问有什么好的解决方案么?

  5. 老师好,什么时候能做个pack和force结合的例子呢

  6. 您好,请教一下:
    如果想做成节点以此逐层添加的效果,怎么实现?
    类似http://arborjs.org/例子,只不过把鼠标划过去的事件去掉,作为开场动画,节点以此添加。
    谢谢

    • 您好,向节点数组中增加节点,向边数组中增加边即可,力导向图布局会为我们计算的。

      但是,对于新增加的数据,要增加相应的图形元素,这一部分如果您是新手,可能比较难做。可参考:
      http://www.ourd3js.com/wordpress/841

      PS:以上是我凭经验回答的,具体细节不写代码确认一下不敢确定。

  7. 前辈请教个问题,我的力学图拖拽功能失效了,不晓得怎么解

  8. 能给个完整的json文件吗?貌似运行不了,是空白的!

  9. 老师你好我想请教一下有什么好方法可以吧pack和force这两张layout结合使用么?
    http://bl.ocks.org/mbostock/7607535
    这是一个pack结合zoom的例子我希望把最小的子圈做成force这样点和点之间有连线然后可以拖拽的的不知道可不可以
    请指导
    谢谢

    • 新年好。
      是可以做到的。先用pack布局将各顶点配置到指定坐标(变成一环套一环的)。

      然后,对于每一个最小的子圈里的顶点,再使用 force布局。但是要注意,每一个顶点都要限制其在自己的圈里运动,这个算法要你自己来写,D3没有提供。

  10. 你好, var nodes_text = svg.selectAll(“.nodetext”)
    .data(root.nodes)
    .enter()
    .append(“text”)
    .attr(“class”,”nodetext”)
    .attr(“dx”,text_dx)
    .attr(“dy”,text_dy)
    .text(function(d){
    return d.name;
    });
    这段代码是显示名字,我这边有个类似的需求,但是显示不只有名字,显示内容需要换行,这个怎么解决?希望有空能回答下,谢谢!

    • 有两种方法:
      1.分别定义两个文本元素,一个显示名字,一个显示内容。
      2.首先,SVG中不支持自动换行,需要用tspan标签模拟换行的功能:
      <text x=”300″ y=”300″ >
      <tspan x=”300″ dy=”20″ >tspan line 1</tspan>
      <tspan x=”300″ dy=”20″ >tspan line 2</tspan>
      </text>
      这样书写,就是在300,300坐标处输出两行文字,主要是要灵活运用dy属性。不知道这一点好理解不?

  11. 提点建议O(∩_∩)O哈! 人物关系,箭头很重要的,这个画起来也比较容易。
    再一个,如果鼠标移到人物头像处,能够在附近(或其他)区域显示人物属性(技能、武器等),那便是锦上添花了

  12. 你好,有2个问题请教一下:

    1、请问如果图片不存在,返回一个默认的图片怎么处理?
    2、name如果太长,如何换行?

    谢谢!

    • 你好,
      1. 图片不存在,会在目标位置什么都不显示。我暂时没有找到返回默认图片的方法。如果兄台能找到也请在此处留个言。
      2. 可以插入 标签,这个标签用于分隔字符串,每个子串可以重新定义位置,然后要好好利用dy属性实现换行,如
      <text x=”300″ y=”300″ >
      <tspan x=”300″ dy=”20″ >tspan line 1</tspan>
      <tspan x=”300″ dy=”20″ >tspan line 2</tspan>
      </text>
      结果就是两行文字。

  13. 我也不知道算不算问题把。就是我参照上个例子做的项目以前IE9、360都能打开,最近都打不开,换了百度能打开。现在的情况是IE9浏览这个网站的关于D3的都打不开了,360能打开这些例子但我项目还是打不开。

    • 关于浏览器的问题不好解决。我只能说希望尽可能用高版本浏览器。我的电脑上装的 IE11、Firefox、Chrome,手机上的 Safari,浏览本站都没什么问题。
      但是做项目可能需要考虑到用户使用的较低版本,甚至 IE6 的都要考虑到,这个我无能为力。o(>﹏<)o

      • 这么好的文章怎么没人评论呢。老师好像把json里的content去了。我觉得下一步做优化比如细节放大或者高亮。
        参考http://bl.ocks.org/samuelleach/5497403
        动态生成节点线http://bl.ocks.org/benzguo/4370043

  14. 解决了太好了,一直在关注呢。

    • 如果有什么问题,或希望解决的,可以在任意一篇文章下留言。我会尽量解决,不过时间可能会相对滞后,呵呵。

评论已关闭。