一、弦图

1、弦图是什么

  弦图(Chord),主要用于表示两个节点之间的联系的图表。两点之间的连线,表示谁和谁具有联系。

2、数据

  初始数据为:

var city_name = [ "北京" , "上海" , "广州" , "深圳" , "香港"  ];
var population = [
[ ,   ,  , , ],
[ ,   ,  , , ],
[ ,   ,  , , ],
[ , , , , ],
[ ,   , , , ]
];

  数据是一些城市名和一些数字,这些数字表示城市人口的来源。其意思如下:

  北京 上海
北京 1000 3045
上海 3214 2000

  左边第一列是被统计人口的城市,上边第一行是被统计的来源城市,即:

  北京市的人口有 1000 个人来自本地,有 3045 人是来自上海的移民,总人口为 1000 + 3045。

  上海市的人口有 2000 个人来自本地,有 3214 人是来自北京的移民,总人口为 3214 + 2000。

  好了!!!对于这样一组数据,怎么进行可视化。

3、布局(数据转换)

  弦图的布局如下:

 var chord_layout = d3.layout.chord()
.padding(0.03) //节点之间的间隔
.sortSubgroups(d3.descending) //排序
.matrix(population); //输入矩阵

  然后,应用此布局转换数据。

var groups = chord_layout.groups();
var chords = chord_layout.chords(); console.log( groups );
console.log( chords );

  population 经过转换后,实际上分成了两部分:groups 和 chords。前者是节点,后者是连线,也就是。chords 就是上图中的连线。chords 里面又分为 source 和 target ,也就是连线的两端。

  在控制台输出一下节点和连线,看看得到了怎样的数据。

  节点:

  连线(弦):

4、绘制节点

  先定义相关变量,很熟悉了

 var width = ;
var height = ;
var innerRadius = width/ * 0.7;
var outerRadius = innerRadius * 1.1; var color20 = d3.scale.category20(); var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width/ + "," + height/ + ")")

  绘制节点(即分组,有多少个城市画多少个弧形),及绘制城市名称

var outer_arc = d3.svg.arc()   //获取圆弧生成器的路径值
.innerRadius(innerRadius)
.outerRadius(outerRadius); var g_outer = svg.append("g"); //添加分组 g_outer.selectAll("path")
.data(groups)
.enter()
.append("path")
.style("fill", function(d) { return color20(d.index); })
.style("stroke", function(d) { return color20(d.index); })
.attr("d", outer_arc ); //绑定路径的属性值 g_outer.selectAll("text")
.data(groups)
.enter()
.append("text")
.each( function(d,i) {
d.angle = (d.startAngle + d.endAngle) / ;
d.name = city_name[i];
})
.attr("dy",".35em")
.attr("transform", function(d){
return "rotate(" + ( d.angle * / Math.PI ) + ")" +
"translate(0,"+ -1.0*(outerRadius+) +")" +
( ( d.angle > Math.PI*/ && d.angle < Math.PI*/ ) ? "rotate(180)" : "");
})
.text(function(d){
return d.name;
});

  节点位于弦图的外部。节点数组 groups 的每一项,都有起始角度和终止角度,因此节点其实是用弧形来表示的,这与饼状图类似。

  然后就是节点的文字(即城市名称),有两个地方要特别注意。

  each():表示对任何一个绑定数据的元素,都执行后面的无名函数 function(d,i) ,函数体里做两件事:

  • 计算起始角度和终止角度的平均值,赋值给 d.angle 。
  • 将 city_name[i] 城市名称赋值给 d.name 。

  transform 的参数:用 translate 进行坐标变换时,要注意顺序: rotate -> translate(先旋转再平移)。 此外,

( ( d.angle > Math.PI*/ && d.angle < Math.PI*/ ) ? "rotate(180)" : "")

  意思是,当角度在 135° 到 225° 之间时,旋转 180°。不这么做的话,下方的文字是倒的。

5、绘制连线(弦)

  绘制连线(即所有城市人口的来源,即有 5 * 5 = 25 条弧)

var inner_chord = d3.svg.chord()
.radius(innerRadius); svg.append("g")
.attr("class", "chord")
.selectAll("path")
.data(chords)
.enter()
.append("path")
.attr("d", inner_chord ) //path值
.style("fill", function(d) { return color20(d.source.index); })
.style("opacity", )
.on("mouseover",function(d,i){
d3.select(this)
.style("fill","yellow");
})
.on("mouseout",function(d,i) {
d3.select(this)
.transition()
.duration()
.style("fill",color20(d.source.index));
});

  SVG 中没有现成的弦元素(例如圆有 <circle>,但是弦却没有 <chord>),需要用路径元素 <path> 来制作。至于路径值是什么呢?我们不需要手动计算,D3 提供了 d3.svg.chord() ,只需要将弦的对象传递给它,即可得到路径值

  上面还有几句关于交互式操作的代码: mouseover 和 mouseout 。

二、集群图

  集群图,是一种用于表示包含与被包含关系的图表。

1、数据

  初始数据先写在一个 JSON 文件中,再用 D3 来读取。现有数据如下:

{
"name":"中国",
"children":
[
{
"name":"浙江" ,
"children":
[
{"name":"杭州" },
{"name":"宁波" },
{"name":"温州" },
{"name":"绍兴" }
]
}, {
"name":"广西" ,
"children":
[
{"name":"桂林"},
{"name":"南宁"},
{"name":"柳州"},
{"name":"防城港"}
]
}, {
"name":"黑龙江",
"children":
[
{"name":"哈尔滨"},
{"name":"齐齐哈尔"},
{"name":"牡丹江"},
{"name":"大庆"}
]
}, {
"name":"新疆" ,
"children":
[
{"name":"乌鲁木齐"},
{"name":"克拉玛依"},
{"name":"吐鲁番"},
{"name":"哈密"}
]
}
]
}

  这段数据表示:“中国 – 省份名 – 城市名”的包含于被包含关系。

2、布局(数据转换)

  定义一个集群图布局:

var cluster = d3.layout.cluster()
.size([width, height - ]);

  布局保存在变量 cluster 中,变量 cluster 可用于转换数据。

  size() 设定尺寸,即转换后的各节点的坐标在哪一个范围内。

  接下来,转换数据:

d3.json("city.json", function(error, root) {
var nodes = cluster.nodes(root);
var links = cluster.links(nodes); console.log(nodes);
console.log(links);
}

  d3.json() 是用来读取 JSON 文件的。要注意,d3.json() 不能读取本地文件。例如,将 html 文件与 json 文件放到本地同一目录,打开 html 文件是不能顺利读取的。需要搭建一个网络服务器来使用它,可用 Apache 搭建一个简单的服务器。否则,浏览器(Chrome)的控制台中,会出现以下错误:XMLHttpRequest cannot load file:///D:/*******/city.json. Cross origin requests are only supported for HTTP.

  经过测试,Firefox 可以直接读取本地文件,无需搭服务器,其他大多数浏览器不行。建议搭建服务器进行测试,这是正确的做法。

  d3.json() 函数后面跟一个无名函数 function(error) ,参数 root 是读入的数据。后两行代码调用 cluster 转换数据,保存到变量 nodes 和 links 中。然后输出转换后的数据,结果如下图所示:

  转换后的顶点数据(nodes):

  转换后的连接线数据(links):

  nodes 中有各个节点的子节点(children)、深度(depth)、名称(name)、位置(x,y)信息,其中名称(name)是 json 文件中就有的属性。

  links 中有连线两端( source , target )的节点信息。

3、绘制

  D3 已经基本上为我们准备好了绘制的函数:d3.svg.diagonal() 。这是一个对角线生成器,只需要输入两个顶点坐标,即可生成一条贝塞尔曲线

  创建一个对角线生成器:

var diagonal = d3.svg.diagonal()
.projection(function(d) { return [d.y, d.x]; });

  projection() 是一个点变换器,默认是 [ d.x , d.y ],即保持原坐标不变,如果写成 [ d.y , d.x ] ,即是说对任意输入的顶点,都交换 x 和 y 坐标

  绘制连线时,使用方法如下:

var link = svg.selectAll(".link")
.data(links)
.enter()
.append("path")
.attr("class", "link")
.attr("d", diagonal); //使用对角线生成器path值

  绘制节点时,还是用 <svg> 中的 <circle> 来绘制。

  //获取所有节点元素
var node = svg.selectAll(".node")
.data(nodes)
.enter()
.append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; })
//节点元素绘制圆
node.append("circle")
.attr("r", 4.5);
//添加文本
node.append("text")
.attr("dx", function(d) { return d.children ? - : ; })
.attr("dy", )
.style("text-anchor", function(d) { return d.children ? "end" : "start"; })
.text(function(d) { return d.name; });

三、树状图

  树状图( Tree )用于表示层级、上下级、包含与被包含关系,其布局的用法与集群图几乎完全相同。

D3.js系列——布局:弦图和集群图/树状图的更多相关文章

  1. D3.js系列——布局:饼状图和力导向图

    一.饼状图 在布局的应用中,最简单的就是饼状图. 1.数据 有如下数据,需要可视化: , , , , ]; 这样的值是不能直接绘图的.例如绘制饼状图的一个部分,需要知道一段弧的起始角度和终止角度,这些 ...

  2. D3.js系列——布局:打包图和地图

    一.打包图 打包图( Pack ),用于表示包含与被包含的关系,也可表示各对象的权重,通常用一圆套一圆来表示前者,用圆的大小来表示后者. 1.布局(数据转换) var pack = d3.layout ...

  3. D3.js系列——交互式操作和布局

    一.图表交互操作 与图表的交互,指在图形元素上设置一个或多个监听器,当事件发生时,做出相应的反应. 交互,指的是用户输入了某种指令,程序接受到指令之后必须做出某种响应.对可视化图表来说,交互能使图表更 ...

  4. SqlServer-无限递归树状图结构设计和查询

    在现实生活中,公司的部门设计会涉及到很多子部门,然后子部门下面又存在子部门,形成类似判断的树状结构,比如说评论楼中楼的评论树状图,职位管理的树状图结构等等,实现类似的树状图数据结构是在开发中经常出现的 ...

  5. 用D3.js画树状图

    做项目遇到一个需求,将具有层级关系的词语用树状图的形式展示它们之间的关系,像这样: 或者是这样: 上面的图片只是样例,跟我下面的代码里面用的数据不同 网上有很多这种数据可视化展示的js控件,我这里选择 ...

  6. d3.js(v5.7)树状图

    一.新建画布 二.数据处理 三.绘制连接线 图示: 四.绘制节点.文字 图示: 五.总结 path元素:其实就是定义了绘图的坐标点,从哪开始,移动到哪,怎样移动(命令) 具体可百度(或许以后我会总结一 ...

  7. 大数据系列(3)——Hadoop集群完全分布式坏境搭建

    前言 上一篇我们讲解了Hadoop单节点的安装,并且已经通过VMware安装了一台CentOS 6.8的Linux系统,咱们本篇的目标就是要配置一个真正的完全分布式的Hadoop集群,闲言少叙,进入本 ...

  8. D3树状图给指定特性的边特别显示颜色

    D3作为前端图形显示的利器,功能之强,对底层技术细节要求相对比较多. 有一点,就是要理解其基本的数据和节点的匹配规则架构,即enter,update和exit原理,我前面的D3基础篇中有介绍过,不明白 ...

  9. D3树状图异步按需加载数据

    D3.js这个绘图工具,功能强大不必多说,完全一个Data Driven Document的绘图工具,用户可以按照自己的数据以及希望实现的图形,随心所欲的绘图. 图形绘制,D3默认采用的是异步加载,但 ...

随机推荐

  1. MySQL 存储过程基本函数

    字符串类 CHARSET(str) //返回字串字符集CONCAT (string2 [,... ]) //连接字串INSTR (string ,substring ) //返回substring首次 ...

  2. 用NativeScript创建JavaScript原生移动应用

    Telerik公开了用于创建安卓.iOS和Windows Universal跨平台原生应用的框架,NativeScript的公共访问权限. NativeScript既不是一种新型的JavaScript ...

  3. .net程序在无.net环境下运行

    看了篇文章  测试了下竟然真的可以运行  测试环境是XP下  没有装NET2.0的情况下 可以运行的   不过需要每次输入命令才能运行 点击后还是会报错 原文如下 众所周知,.net程序必须运行在.n ...

  4. php产生随机字符串

    /** * 产生随机字符串 * * @param int $length 输出长度 * @param string $chars 可选的 ,默认为 0123456789 * @return strin ...

  5. thinkphp碰到的一些小问题

    1. 生成的html自动被去掉换行和空格,压缩挤到一起了. 解决: 开启debug即可,在入口文件增加 define("APP_DEBUG",true); 2. 添加mysql的 ...

  6. mybatis中#{}与${}的区别

    今天学习了下mybatis的查询,了解到了#{}与${}的区别, 配置文件如下: <?xml version="1.0" encoding="UTF-8" ...

  7. 浅谈角色换装功能--Unity简单例子实现

    在前置篇中,基本上梳理了一下换装功能背后涉及到的美术工作流.但程序员嘛,功能终归是要落到代码上的.本文中会结合Unity提供的API及之前提到的内容来实现一个简单的换装功能.效果如下: (图1:最终效 ...

  8. 问题: 揭秘Angualr2 书上问卷调查

    npm install 初夏下面问题: 0 info it worked if it ends with ok1 verbose cli [ '/home/linux_ubuntu164/tools/ ...

  9. ssh 登陆 端口转发

    man ssh ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec] [-D [bind_address:]port] ...

  10. C#.NET常见问题(FAQ)-delegate委托链如何使用

    委托链本质就是你把一堆要执行的东西放到一个list里面,当要触发一组事情的时候,就不需要一个一个写一遍了(比如厂里食堂开饭了,这个方法一执行,要让厨师A时间在食堂等候打饭,B类员工在某个时间排队打饭, ...