【 D3.js 入门系列 — 9.5 】 树状图的制作

树状图,其布局的用法与集群图几乎完全相同,本章只简单讲述两种图表之间的不同之处。

953

1. 树状图和集群图的区别

树状图( Tree )用于表示层级、上下级、包含与被包含关系。

树状图的代码和 【入门 – 第 9.4 章】 的集群图几乎完全一样。那么为何要把这两种图分开呢?它们有什么不同呢?先来看看对于同一组数据,它们的结果有什么不同。数据为:

集群图的结果为:

952

树状图的结果为:

951

看明白它们的区别了吗?

源代码

下载地址:rm95.zip

展示地址:http://www.ourd3js.com/demo/rm/R-9.5/tree.html

文档信息

【 D3.js 入门系列 — 9.5 】 树状图的制作》上有56条评论

  1. 馒头老师,
    您书中228页树状图章节中的树状图我按照书上的内容码出来了,但是在代码末尾我希望跟书中本章上一章节“弦图”的末尾添加交互。
    预想的交互式这样的,当鼠标移至文本上,其关联的到子元素的连线改变颜色,末尾我添加的代码如下:
    node.selectAll(“text”)
    .on(“mouseover”, focus(“limegreen”))
    .on(“mouseout”, focus(“orange”));
    function focus(color) {
    return function (d, i) {
    link.filter(function (d) {
    return d.source.depth == i;
    })
    .attr(“stroke”, color);
    };
    }
    但是,结果是无论我把鼠标放在哪个文字上,都只有中国这个父元素到省份的连线改变了颜色

    求救求救

    • 这样写说不定能行,但是我没有给你试过。

  2. qq:593982885我正在看你的教程,你可以加我一下吗

  3. 如何把树状图的节点换成其他图片,请指教:
    我仿照力学图的代码加入到树状图的代码中,json中也加入了image标签。加入的代码如下:

    var nodes_img = svg.selectAll(“image”)
    .data(root.nodes)
    .enter()
    .append(“image”)
    .attr(“width”,img_w)
    .attr(“height”,img_h)
    .attr(“xlink:href”,function(d){
    return d.image;
    }
    .call(force.drag);

  4. 粘贴了源代码,也把html发布到tomcat上了,但是就是无法读取json数据,请问怎么回事?

      • F12报的是d3.min.js中的错:
        Uncaught TypeError: Cannot set property ‘depth’ of undefined

        • 可能你的 JSON 文件的格式有误。
          把JSON 文件里的内容拷贝到:http://json.cn/
          检测一下看是否有误。

  5. 请问:如果想把末端的文字结尾与文字结尾链接起来,怎么实现?不是图中的圆圈与圆圈相连,而是圆圈后面文字结束的地方与另外一个圆圈后面文字结束的地方连成曲线

    • 那么你得计算字符串的像素长度,根据每一个字体的大小fontsize和字符的数目可以计算。

  6. 大神,请问 我的树数据一开始只有一个根节点,然后我想根据一些情况来更新节点,例如:一开始只有 中国 一个节点,然后用户通过一些操作,查到了 河北 河南 北京 三个数据,然后我将三个数据更新到中国节点上去,再继续 用户 通过 一些操作 得到了 朝阳 顺义 昌平 数据,再将这三条数据更新到 北京节点上去,请问这样的应该怎么实现?万分感谢

  7. 请问一下这种树状图可以从上之下排列吗?

    • 第40行改为:
      .projection(function(d) { return [d.x, d.y]; });

      第71行改为:
      .attr(“transform”, function(d) { return “translate(” + d.x + “,” + d.y + “)”;

      即可。
      谢谢。

  8. 前辈你好,我还想请教个问题,在svg上的text都是在绘制节点后append上去的,我如果要在text上面加边框和其他什么效果似乎不能直接对text增加style,我加了border-style和border-width都没用,敢问前辈有什么好方法?~

  9. 前辈你好,我想请问下如果我想实现:一个父节点对应多个子节点、用横平竖直的线来连接父子节点、能够在页面大小内自适应的现实出所有内容的这种组织架构图,使用D3的话还有需要自己写样式吗?大概哪些是需要自己写的?谢谢~~

    • 你好,所谓“自适应地显示出图形”这种都是图形库的基本功能,放心,是可以的。
      使用 d3.layout.treemap 获取节点数组后,你要用曲线用直线来绘制,这都是你自己可以决定的。D3的布局只是帮助你计算节点的坐标而已。
      直线的样式需要自己写,这是CSS的内容。

      • 多谢前辈指点,这个思路下我已经用M H V的PATH方法画出折线,感觉还很好用,哈哈~~

      • D3提供的虽然不能完全适应自己的树形需求,但接口和得到的数据也够底层,完全可以在计算出坐标后再按自己需求调整坐标,达到自己的需求。确实如前辈所说,可以很大程度上利用D3计算坐标~我对D3的认识又深了一层,多谢多谢~

  10. 刚学习,想问一下这个怎么把连接线改成直线

      • 是将diagonal换成line吗?我实现不了,请老师指教,谢谢!

      • 老师,是把diagonal改成line标签吗?我试了,没实现,我如果只画一条直线怎么做呢?谢谢老师

  11. 老师,您好!请问有BUBBLE CHART的教程吗?

  12. 老师 在这个基础上,你可以做个类似思维导图,就是让他有收缩的效果的,我自己试过,失败了,最后又在网上找到一个例子,这个例子:http://mbostock.github.io/d3/talk/20111018/tree.html
    不是很懂,我第一次学习d3,有时候还停留在看代码的层面上,下手去写的话问题会有很多,但是多练是没错的,在这里 也很感谢老师这个教程

  13. size第一个参数是高height,第二个参数是宽width。
    .size([width, height-200])

  14. 请问节点间上下间隔的距离是哪条代码控制的?怎样让上下间距大一些?
    谢谢!

    • 尝试了几次,只有加大svg和tree-size的height。

        • 多谢!看了API,
          .separation(function(a, b) { return (a.parent == b.parent ? 1 : 2) / a.depth; });
          中的/a.depth好像更适合圆形的树图,http://bl.ocks.org/mbostock/4063550.

          水平的树图,默认是 .separation(function(a, b) { return (a.parent == b.parent ? 1 : 2); });
          我试了一下,效果比加/ a.depth;要好,尤其当节点多的时候。

  15. 这个树状图,1.请问一个节点可以显示多个参数吗,比如除了name:”中国”,再显示面积area,人口population等。2.节点的图标除了圆圈circle函数,能否换成其他符号,甚至换成自定义图片?有没有d3接口,还是需要改d3.js文件
    谢谢!

    • 1. 可以的,多多少参数都可以
      2. 也可以的,用什么图形来绘制由你决定,d3.layout 只是用来转换数据的,并不是用来绘制的

        • 先在文件中写,例如:
          {“name”:”杭州” , “population”: 1000}

          那么读取文件后,
          d3.json(“city_tree.json”, function(error, root)

          的root里就会有population属性的。

  16. 我是刚学这个,一点都不会,我直接复制你的代码,显示什么都没有。。。

  17. 我最近遇到一个加载json格式中国地图的问题,想向你请教一下:
    http://chinamap.sinaapp.com/force-china.html
    这个网页加载了json格式的中国地图
    地图文件http://vdisk.weibo.com/s/hF0Vc
    原网址http://blog.sina.com.cn/s/blog_718b31d60101gjzt.html
    这个网页我自己测试了一下,发现如果用d3.v2.js就可以成功,用d3.v3.js就不行,能否请指教一下原因?我感觉貌似是投影那里的函数发生了变化
    谢谢!

    • 不错,是投影函数发生了变化。

      这个例子中用到了 d3.geo.azimuthal() 函数,这个函数在 v3.0 中已经被移除了,它被分成了:

      • d3.geo.orthographic
      • d3.geo.azimuthalEqualArea
      • d3.geo.azimuthalEquidistant
      • d3.geo.stereographic
      • d3.geo.gnomonic

      关于 v2.0 升级到 v3.0 的变化,可以查看:升级到3.0 ,中间部分有写到这一点。

      另外,关于地图的制作将在后面的章节中叙述,到时候欢迎阅读,这几天有点忙,没时间整理文章,呵呵O(∩_∩)O~

评论已关闭。