D3.js数据可视化(二)——绘制弦图(Chord Layout)

树图网可视化实验

1. 实验要求

  要求通过树,或者图、网的可视化聚类,分析某个公司的邮件社交网络。根据要求设计可视化方案,并利用D3工具实现可视化效果。

2. 过程

2.1. 可视化方案的设计思路

2.1.1. 可视化要求

  1) 可视化该邮件社交网络。

  2) 该可视化中的每个Edge都对应着一个权重(Emails per month或者weight),要求将该权重属性映射到一个图形化的属性,比如,color,types of line,size or shapes。

  3) 可视化方案中要体现每个人的职业或部门属性(五类):director,CEO,Business Development Unit,Business Support Unit,Business Control Unit。

2.1.2. 设计思路

  根据可视化要求,分析某个公司的邮件社交网络,并可视化该邮件社交网络。

  1. 可视化效果应该是一张图;

  2. 这张图中的顶点要分为5类,体现每个人的职业或部门属性;

  3. 这张图中的边要分为7类,体现不同的权值;

  4. 每类顶点放在一起,并将不同顶点用不同颜色标识。

2.2. 对可视化方案的说明

  在此次的设计方案中,将使用弦图进行可视化。弦图的各弧代表各个人,弧的角度大小代表其收件箱内的邮件个数,弧被分为5种颜色,体现每个人的部门属性。弦图的各弦代表两个人之间的邮件往来,如A、B间的弦,与A相连的一端代表A收件箱中来自B的邮件,与B相连的一端代表B收件箱中来自A的邮件,弦被分为7种宽度,体现来往信件的多少。

2.3. 使用D3实现可视化效果的过程

2.3.1. 新建项目

  在项目目录下新建文件夹lab_3,再在文件夹lab_3内新建一个文件夹d3和文本文件index.html

2.3.2. 数据预处理

  将原始数据保存为staff.csv和mails.csv

2.3.3. 编写代码

html.index

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
    <title>My lab 3</title>
    <style>

        @import url(../style.css?aea6f0a);

        #circle circle {
            fill: none;
            pointer-events: all;
        }

        .group path {
            fill-opacity: .5;
        }

        path.chord {
            stroke: #000;
            stroke-width: .25px;
        }

        #circle:hover path.fade {
            display: none;
        }

        .Director {
            fill: navy;
        }

        .CEO {
            fill: black;
        }

        #group3, #group6, #group7, #group8 {
            fill: #00FF7F;
        }
        #group4, #group9, #group10, #group11, #group12, #group13, #group14 {
            fill: #DAA520;
        }
        #group5, #group16, #group17, #group15 {
            fill: #FF00FF;
        }
    </style>
</head>

<body>
    <script src="d3/d3.js" charset="utf-8"></script>
    <script src="d3/queue.js"></script>
    <script>
        var matrix = new Array(18);

        var width = 720,
            height = 720,
            outerRadius = Math.min(width, height) / 2 - 10,
            innerRadius = outerRadius - 24;   // 设置布局的长宽,半径

        var formatPercent = d3.format(".1%");

        var layout = d3.layout.chord()    // 从关系矩阵生成一个弦图,创建弦图布局,用来转换数据
            .padding(.04)     // 取得或设置 弦片段间的角填充
            .sortSubgroups(d3.descending)     // 取得或设置 用于子分组的比较器
            .sortChords(d3.ascending);    // 取得或设置 用于弦的比较器(Z轴顺序)

        var arc = d3.svg.arc()      // 新建一个弧度生成器,用来画弧
            .innerRadius(innerRadius)     // 设置内半径访问器
            .outerRadius(outerRadius);    // 设置外半径访问器

        var path = d3.svg.chord()     // 新建一个弦生成器,用来画弦
            .radius(innerRadius);

        var svg = d3.select("body").append("svg")     // 生成最父节点
            .attr("width", width)
            .attr("height", height)
          .append("g")
            .attr("id", "circle")
            .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");    // 坐标原点移到svg中间

        svg.append("circle")
            .attr("r", outerRadius);    // 画外圈的大圆,g的第一个孩子

        queue()
            .defer(d3.csv, "staff.csv")
            .defer(d3.csv, "mails.csv")
            .await(ready);    // 加载两个文件,之后执行回掉函数ready

        function ready(error, staffs, mails) {
              if (error) throw error;

              // 生成数据矩阵
              for (var i = 0; i < 18; i++)
              {
                      matrix[i] = new Array(18);
                      for (var j = 0; j < 18; j++)
                      {
                          matrix[i][j] = 0;
                      }
              }

              for (var i = 0; i < mails.length; i++)
              {
                       var toid1 = parseInt(mails[i].toID);
                      var id2 = parseInt(mails[i].ID);
                      var num = parseInt(mails[i].Weight);
                      matrix[toid1][id2] = num;
              }
              // Compute the chord layout. 加载数据矩阵
              layout.matrix(matrix);

              // Add a group per neighborhood. 就是每一个扇环形区域,都是一个group,包括title、path(arc)、text三个孩子
              var group = svg.selectAll(".group")
                  .data(layout.groups)    // layout = d3.layout.chord() ,所以layout是个chord;
                                          // chord.group()返回节点数组,用来生成节点:一个个弧
                .enter().append("g")
                  .attr("class", "group")
                  .on("mouseover", mouseover);    // 放上鼠标后调用mouseover函数

              // Add a mouseover title. 鼠标停留显示的提示
              group.append("title").text(function(d, i) { return staffs[i].Name + "‘s inbox"; });

              // Add the group arc. 画弧
              var groupPath = group.append("path")
                  .attr("id", function(d, i) { return "group" + i; })   // 每个扇环形区域是一个group,其中的path叫group i
                  .attr("d", arc)
                  .attr("class", function(d, i) { return staffs[i].Position; });

              // Add a text label. 添加文本标识
              var groupText = group.append("text")
                  .attr("x", 6)
                  .attr("dy", 15);

              groupText.append("textPath")
                  .attr("xlink:href", function(d, i) { return "#group" + i; })
                  .text( function(d, i) { return staffs[i].Name; } );

              // Remove the labels that don‘t fit. :(
              groupText.filter(function(d, i) { return groupPath[0][i].getTotalLength() / 2 - 16 < this.getComputedTextLength(); })
                  .remove();

              // Add the chords. 每条连接两个邻居的边都是一个path,拥有一个title孩子,所有的边在一起叫chord
              var chord = svg.selectAll(".chord")
                  .data(layout.chords)
                .enter().append("path")
                  .attr("class", "chord")
                  .style("fill", "#1E90FF")
                  .attr("d", path);

              // Add an elaborate mouseover title for each chord. 设置path的title
              // chord.append("title").text("haha");

              // 在此函数中,所有不是source也不是target的全都设"fade"为true
              function mouseover(d, i) {
                chord.classed("fade", function(p) {
                  return p.source.index != i
                      && p.target.index != i;
                });
              }
        }
    </script>
</body>
</html>

数据:mails.csv

ID,Emailspermonth,Weight,toID
0,5,1,1
0,6,1,2
1,5,1,2
2,25,2,3
2,36,2,4
2,53,3,5
3,150,4,6
3,213,5,7
3,298,5,8
4,345,6,9
4,123,4,10
4,212,5,11
4,453,7,12
4,156,4,13
4,278,5,14
5,300,5,15
5,78,3,16
5,256,5,17
6,78,3,7
6,145,4,8
7,139,4,8
9,34,2,10
9,134,4,11
9,546,7,12
9,23,2,13
9,145,4,14
10,256,5,11
10,222,5,12
10,190,4,12
10,56,3,14
11,78,3,12
11,112,4,13
12,98,3,14
15,88,3,16
15,123,4,17
16,238,5,17
17,5,1,7
16,15,2,6
16,23,2,7
16,54,3,8
16,18,2,9
16,23,2,11
16,41,2,13
16,13,2,14
16,27,2,10

数据:staff.csv

ID,Name,Position
0,James,Director
1,David,Director
2,George,CEO
3,Ronald,Business Development Manager
4,John,Business Support Manager
5,Richard,Business Control Manager
6,Daniel,Sales Department Leader
7,Kenneth,Product Department Leader
8,Anthony,Marketing Department Leader
9,Robert,Project Office Leader
10,Charles,Professional Service Leader
11,Paul,QA Leader
12,Mark,Design Office Leader
13,Kevin,Technical Support Office Leader
14,Edward,Software Development Leader
15,Joseph,Legal Office Leader
16,Michael,Finance Office Leader
17,Jason,HR Office Leader

3. 结果

图1   数据弦图

图2   鼠标移到某员工,显示该员工所有的邮件往来

4. 总结

   使用弦图能清晰地显示各部门、各员工之间的邮件往来,有良好的可视化效果。

时间: 2024-10-10 09:27:41

D3.js数据可视化(二)——绘制弦图(Chord Layout)的相关文章

《D3.js数据可视化实战手册》即将上市!

内容提要 如今这个互联网时代,人们每天都生产海量的数据,如果直接面对这些数据,可能让人无从下手.将数据可视化,用形象立体的形式将其展现,有利于分析其中的关联,攫取可能存在的商业机会.本书意图通过大量的示例和代码,向读者讲述如何利用D3.js来实现数据可视化.只要您了解Javascript,就能完全掌握本书的内容. 本书一共13章,从如何搭建D3.js的开发环境开始,逐步介绍D3中的各种操作,包括选集.数据的初步处理.数据映射.坐标轴组件.动画过渡效果.SVG相关介绍.绘制图表.安排布局.可视化交

d3.js:数据可视化利器之快速入门

hello,data! 在进入d3.js之前,我们先用一个小例子回顾一下将数据可视化的基本流程. 任务 用横向柱状图来直观显示以下数据: var data = [10,15,23,78,57,29,34,71]; 简单地思考一下,要完成这个任务有两个问题需要解决: 用什么可视元素来表现横向柱? 数据对应到可视元素的什么属性? 这个不算困难,我们使用HTML的DIV元素来实现,代码参见http://www.hubwiz.com/course/54fd40cfe564e50d50dcf284/:快速

【D3.js数据可视化实战】--(3)桑基图(sankey)的绘制

什么是桑基图 用D3绘制简单的Sankey图 添加文字 圆形节点 添加交互效果 注:本文未经作者允许严禁转载和演绎 1 什么是桑基图? 桑基图是流图 (flow diagram )的一种,用来描述能量,人口,经济等的流动情况.最早由爱尔兰人Matthew Henry Phineas Riall Sankey 提出.Sankey是一名船长也是工程师,1898年Sankey在土木工程师学会会报纪要的一篇关于蒸汽机能源效率的文章中首次推出了第一个能量流动图,后来被命名为Sankey图,中文音译为桑基图

前端编程提高之旅(八)----D3.js数据可视化data join解析

   D3.js作为一门轻型的可视化类库,非常便于将数据与web界面元素绑定,实现可视化.乐帝d3.js入门是大体看了一遍<d3js数据可视化实战>这本书,D3操作非常类似于jquery的使用,具体体现在两点: 选择器模块都采用CSS3标准 方法可以链式调用    有了jquery使用基础,相信再加上以上书籍的例子,调试很容易上手使用D3.js,乐帝目前认为D3.js与jquery区别在于:D3.js独有的数据结构概念及对SVG操作方便的实现.而深入理解D3原理,以上皮毛的理解就不够用了.  

[资料搜集狂]D3.js数据可视化开发库

偶然看到一个强大的D3.js,存档之. D3.js 是近年来十分流行的一个数据可视化开发库. 采用BSD协议 源码:https://github.com/mbostock/d3 官网:http://d3js.org/ 中文资料:http://www.ourd3js.com/ C3.js是一个基于D3.js的图表库. https://github.com/masayuki0812/c3 http://c3js.org/ 附:

D3.js数据可视化(一)——绘制热图(heat map)

二维标量可视化 1. 实验名称 二维标量的可视化. 2. 实验目的 使用d3以及提供的NBA篮球上个赛季的数据(basketball statics.xlsx),绘制一个热图(heat map). 3. 技术基础 Web, HTML, DOM, CSS, JavaScript, SVG. 核心技术为D3 —— Data-Driven Documents(数据驱动的文档).数据来源于你,而文档就是基于Web的文档(或者网页),代表可以在浏览器中展现的一切,比如HTML,SVG.D3扮演的是一个驱动

seaborn 数据可视化(二)带有类别属性的数据可视化

Seaborn的分类图分为三类,将分类变量每个级别的每个观察结果显示出来,显示每个观察分布的抽象表示,以及应用统计估计显示的权重趋势和置信区间: 第一个包括函数swarmplot()和stripplot() 第二个包括函数boxplot()和violinplot() 第三个包括函数barplot()和pointplt() 导入所需要的库: import numpy as np import matplotlib.pyplot as plt import seaborn as sns sns.se

D3.js 入门学习(二) V4的改动

//d3.scan /* 新的d3.scan方法对数组进行线性扫描,并根据指定的比较函数返回至少一个元素的索引. 这个方法有点类似于d3.min和d3.max. 而d3.scan可以得到极值的索引而不仅仅是计算极值. */ var a1 = [1,3,5,2,9]; var i = d3.scan(a1,function(a,b){ return b-a; // 返回最大值的索引, a-b; 返回最小值的索引 }); console.log(i); //4; //d3.ticks d3.tick

【 D3.js 高级系列 — 3.0 】 堆栈图

堆栈图布局(Stack Layout)能够计算二维数组每一数据层的基线,以方便将各数据层叠加起来.本文讲解堆栈图的制作方法. 先说说什么是堆栈图. 例如,有如下情况: 某公司,销售三种产品:个人电脑.智能手机.软件. 2005年,三种产品的利润分别为3000.2000.1100万. 2006年,三种产品的利润分别为1300.4000.1700万. 计算可得,2005年总利润为6100万,2006年为7000万. 如果要将2005年的利润用柱形表示,那么应该画三个矩形,三个矩形堆叠在一起.这时候就