簇布局

布局是一种数据处理算法,将输入的数据转换为某种构造器所需要的数据。D3有12中布局:捆绑布局、弦布局、簇布局、力布局、层次布局、直方图布局、包布局、分区布局、饼布局、堆叠布局、树布局、和矩形树布局。

簇布局可以产生树状图:将树的叶子节点放在同一深度的节点-连接图。簇布局遵循方法链模式,在该模式下setter方法返回布局本身,允许使用简单语句调用多个setter。

数据格式

数据就需要有父子关系,如:

  1. var data={
  2. "name":"A",
  3. "children":[
  4. {
  5. "name":"B01",
  6. "children":[
  7. { "name":"C01" },
  8. { "name":"C02" },
  9. { "name":"C03" }
  10. ]
  11. },
  12. {
  13. "name":"B02",
  14. "children":[
  15. { "name":"C04" },
  16. { "name":"C05" }
  17. ]
  18. }
  19. ]
  20. };

但是经常我们拿到的数据并不是这样的。如数据库中一般都是以如下结构存储有父子关系的记录的:

Name Parent
Eve  
Cain Eve
Seth Eve
Enos Seth
Noam Seth
Abel Eve
Awan Eve
Enoch Awan
Azura Eve

因此从后端传过来的数据也就是数组对象

这就需要我们进行转换了。d3.stratify()方法就是干这个事情的。

  1. var stratify = d3.stratify().id(function (d) {return d.name;}).parentId(function(d){return d.parent;});
  2. var rawData=[
  3. {name:"Eve",parent:""},
  4. {name:"Cain",parent:"Eve"},
  5. {name:"Seth",parent:"Eve"},
  6. {name:"Enos",parent:"Seth"},
  7. {name:"Noam",parent:"Seth"},
  8. {name:"Abel",parent:"Eve"},
  9. {name:"Awan",parent:"Eve"},
  10. {name:"Enoch",parent:"Awan"},
  11. {name:"Azura",parent:"Eve"}
  12. ];
  13. var data = stratify(rawData);

d3.stratify()返回一个层次结构,用于层次布局中的数据结构。

其中的data元素就是层次结构的root,children是root的children,parent表示它的父元素(root没有父元素),再往下每个每个节点都是这种结构形式。

转换数据

这里的转换主要是为上面的data添加坐标信息。

  1. d3.cluster().size([200,300]).cluster(data);

这是经过Cluster转换后的data,其中size函数指定的是图形的大小。而转换出的data中的每个节点坐标就是每个节点在这个size区域中应该在的位置。那现在我们的任务就是:

①用贝塞尔曲线连接这些位置

②在这些位置上画一个圆

③添加text

在d3的第三版中提供了diagonal方法,可以直接用它来生成贝塞尔曲线,但是在第四版却没有这个方法了。那我们就在第四版中添加这个方法。

  1. //扩展d3
  2. (function () {
  3. function d3_functor(v) {
  4. return typeof v === "function" ? v : function() {
  5. return v;
  6. };
  7. }
  8. d3.functor = d3_functor;
  9. //贝塞尔曲线连接起始和终止点
  10. function _diagonal() {
  11. var source = function (d, i) {return d.source;},
  12. target = function (d, i) {return d.target;}, data=null,
  13. projection = function (d) {return [ d.x, d.y ];};
  14. function diagonal(d, i) {
  15. var p0 = source.call(this, d, i), p3 = target.call(this, d, i), m = (p0.y + p3.y) / 2, p = [ p0, {
  16. x: p0.x,
  17. y: m
  18. }, {
  19. x: p3.x,
  20. y: m
  21. }, p3 ];
  22. p = p.map(projection);
  23. return "M" + p[0] + "C" + p[1] + " " + p[2] + " " + p[3];
  24. }
  25. diagonal.source = function(x) {
  26. if (!arguments.length) return source;
  27. source = d3_functor(x);
  28. return diagonal;
  29. };
  30. diagonal.target = function(x) {
  31. if (!arguments.length) return target;
  32. target = d3_functor(x);
  33. return diagonal;
  34. };
  35. diagonal.projection = function(x) {
  36. if (!arguments.length) return projection;
  37. projection = x;
  38. return diagonal;
  39. };
  40. return diagonal;
  41. }
  42. var __proto__=d3.constructor.prototype;
  43. __proto__.diagonal=__proto__.diagonal || function () {
  44. return _diagonal();
  45. };
  46. }());

那现在就添加连接线:

  1. var diagonal = d3.diagonal().projection(function (d) {return [d.y,d.x]});
  2. g.selectAll(".link")
  3. .data(data.descendants().slice(1))//过滤掉root
  4. .enter().append("path")
  5. .attr("class", "link")
  6. .attr("d", function(d) {
  7. return diagonal({source:{x:d.x,y:d.y},target:{x:d.parent.x,y:d.parent.y}});
  8. });

添加节点

  1. var node = g.selectAll(".node")
  2. .data(data.descendants())
  3. .enter().append("g")
  4. .attr("class", function(d) { return "node" + (d.children ? " node--internal" : " node--leaf"); })
  5. .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });
  6. node.append("circle")
  7. .attr("r", 3);

添加text

  1. node.append("text")
  2. .attr("dy", 3)
  3. .attr("x", function(d) { return d.children ? -8 : 8; })
  4. .style("text-anchor", function(d) { return d.children ? "end" : "start"; })
  5. .text(function(d) { return d.id; });

例子请移步这里

时间: 2025-01-01 02:17:42

簇布局的相关文章

硬件开发之pcb---PCB抗干扰设计原则

一 电源线布置: 1.电源线.地线的走向应与资料的传递方向一致. 二 地线布置: 1.数字地与模拟地分开. 2.接地线应尽量加粗,致少能通过3倍于印制板上的允许电流,一般应达2~3mm. 3.接地线应尽量构成死循环回路,这样可以减少地线电位差. 三 去耦电容配置: 1.印制板电源输入端跨接10~100μF的电解电容,若能大于100μF则更好. 2.每个集成芯片的Vcc和GND之间跨接一个0.01~0.1μF的陶瓷电容.如空间不允许,可为每4~10个芯片配置一个1~10μF的钽电容. 3.对抗噪能

【D3 API 中文手册】提交记录

[D3 API 中文手册]提交记录 声明:本文仅供学习所用,未经作者允许严禁转载和演绎 <D3 API 中文手册>是D3官方API文档的中文翻译.始于2014-3-23日,基于VisualCrew小组的六次协作任务之上,目前已经大致翻译完毕,将陆续向官网提交D3 API 中文版. 本文主要内容有: 列举初版翻译/校对人员列表 记录中文翻译的官网提交情况 提供校对联系方式 提供D3 API简版翻译 翻译/校对人员列表 翻译人员列表 API项目 文档页数 单词数 翻译 校对 core.select

如何用PADS进行PCB设计?这6步就够了

在使用PADS进行PCB设计的过程中,需要对印制板的设计流程以及相关的注意事项进行重点关注,这样才能更好的为工作组中的设计人员提供系统的设计规范,同时也方便设计人员之间进行相互的交流和检查. 02 设计的流程 PCB的设计流程分为网表输入.规则设置.元器件布局.布线.检查.复查.输出六个步骤. 2.1 网表输入 网表输入有两种方法,一种是使用PowerLogic的OLE PowerPCB ConnecTIon功能,选择Send Netlist,应用OLE功能,可以随时保持原理图和PCB图的一致,

如何使用Flexbox和CSS Grid,实现高效布局

CSS 浮动属性一直是网站上排列元素的主要方法之一,但是当实现复杂布局时,这种方法不总是那么理想.幸运的是,在现代网页设计时代,使用 Flexbox 和 CSS Grid 来对齐元素,变得相对容易起来. 使用 Flexbox 可以使元素对齐变得容易,因此 Flexbox 已经被广泛使用了. 同时,CSS Grid 布局也为网页设计行业带来了很大的便利.虽然 CSS Grid 布局未被广泛采用,但是浏览器逐渐开始增加对 CSS Grid 布局的支持. 虽然 Flexbox 和 CSS Grid 可

CSS布局技巧大全

参考资料:http://www.imooc.com/article/2235 单列布局 水平居中 父元素text-align:center;子元素:inline-block; 优点:兼容性好: 不足:需要同时设置子元素和父元素 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport"

CSS网页布局

一.主要内容 1.布局分类;131   121 2.display属性排版 3.float属性排版(横向多列布局) 4.防止父类盒子塌陷 二.标准文档流: a>组成 块级元素(block) 内联元素(inline) b>display属性值:block.inline.inline-block.none. 值block:将元素设置为块状元素 值inline:将元素设置为行内元素 值inline-block:拥有两种特性. 补充: visibility:hidden: 属性和 display:no

解决安卓手机键盘弹出时会把背景或百分比定位的布局压缩的问题

做移动端页面时经常遇到以下案例,在有背景的页面上写表单,而且底部为了适应不同手机还得运用绝对定位,因为通常是把容器高度设为了100%,这时在安卓手机上弹窗软键盘时就会把背景图片及其他东西挤压上去,解决方法如下: 在css样式中把大容器定义为fixed布局 .wrap{ position:fixed;left:0;top:0; } 在js中强制把页面的高度覆给他,就相当于自动撑开 var x =document.body.clientWidth; //查询设备的宽度 var y =document

微信小程序页面布局

页面布局: wcml: <view class="page"> <view class="page_hd"> </view> <view class="page_bd"> <view class="section_nav"> <view class="left border_right"> 酒店 </view> <vi

深度理解div+css布局嵌套盒子

1. 网页布局概述 网页布局的概念是把即将出现在网页中的所有元素进行定位,而CSS网页排版技术有别于传统的网页排版方法,它将页面首先在整体上使用<div>标记进行分块,然后对每个快进行CSS定位以及设置显示效果,最后在每个块中添加相应的内容.利用CSS排版方法更容易地控制页面每个元素的效果,更新也更容易,甚至页面的拓扑结构也可以通过修改相应的CSS属性来重新定位.  2. 盒子模型 盒子模型是CSS控制页面元素的一个重要概念,只有掌握了盒子模型,才能让CSS很好地控制页面上每一个元素,达到我们