D3.js 满足你对数据可视化的一切幻想

D3.js

D3的全称是Data-Driven Documents(数据驱动的文档),是一个用来做数据可视化的JavaScript函数库,而JavaScript文件的后缀通常为.js,所以D3被称为D3.js。

对D3来说,柱形图、散点图、折线图、饼图、弦图、力导向图、树状图等等都不在话下。总之,只要你愿意写代码,D3.js可以满足你对数据可视化的一切幻想。

今天我们以弦图为例进行介绍。

弦图

弦图主要用于表示两个节点之间的联系。两点之间的连线表示二者具有联系,线的粗细表示权重。

下面是之前做的一张电影类型相关性的弦图。

弦图

准备工作

D3是在HTML和CSS文件中编写代码,在浏览器中显示结果。

HTML文件用来描述内容,CSS文件用来定义内容的样式。定义样式可以单独写在外部CSS文件中,在HTML中用引用;也可以直接写在HTML文件中,在

body {

font: 20px sans-serif;

} //定义字号字体

.group-tick line {

stroke:#000000;

} //定义描边

.ribbons {

fill-opacity: 0.67;

} //定义填充不透明度

代码用来定义样式。

CSS选择器有多种类型。

元素选择器以HTML元素的标签作为名称,如:

body { font: 20px sans-serif;}

则所有主体内容的字号和字体都这样显示。

类选择器是在选择器名称前加一个点(.),如:

.ribbons { fill-opacity: 0.67;}

之后需要应用的话,在元素标签中添加一个class属性即可,后续我们会写到。

另外还有选择器分组、ID选择器、派生选择器,由于这次代码未涉及,暂不赘述。

//定义图形大小

SVG指可缩放矢量图形,绝大部分浏览器都支持,可以利用标签将形状嵌入HTML中。

var leixing = [ "喜剧" , "剧情" , "动作" , "冒险" , "爱情", "惊悚" , "动画" , "奇幻" , "悬疑" , "科幻"]; //定义类型标签

var matrix = [

[77, 108, 88,110,245,12,110,50,25,17],

[108, 102, 117,37,180,67,13,27,79,20],

[88,117,9,133,54,103,22,59,43,96],

[110, 37, 133,3,21,32,141,98,16,60],

[245, 180, 54,21,59,15,3,33,33,7],

[12, 67, 103,32,15,18,1,13,111,33],

[110, 13, 22,141,3,1,12,60,5,12],

[50, 27, 59,98,33,13,60,0,5,13],

[25, 79, 43,16,33,111,5,5,1,12],

[17, 20, 96,60,7,33,12,13,12,0]

]; //输入类型相关性数据

由于统计的是10种电影类型之间的交叉关系,所以是一个对称矩阵。

所以如果你也想画一个10个元素的弦图,也可以不看下边的内容,直接复制代码,修改这两段数据即可。

var svg = d3.select("svg"),

width = +svg.attr("width"),

height = +svg.attr("height"),

outerRadius = Math.min(width, height) * 0.5 - 40,

innerRadius = outerRadius - 40; //定义外部弦和内部弦的大小

绘制外部弦

var chord = d3.chord()

.padAngle(0.05) //设置外部弦间的角填充,也就是弦之间的间距

.sortSubgroups(d3.descending);//设置用于子分组的比较器

var arc = d3.arc()

.innerRadius(innerRadius)

.outerRadius(outerRadius);

var ribbon = d3.ribbon()

.radius(innerRadius);

var color = d3.scaleOrdinal()

.domain(d3.range(4))

.range(["#8EC21E","#C3D968","#009DE6","#7CCDF3","#E51573","#EC799F","#F39820","#FCD35A","#A0A0A2","#C9C9CA"]); //设置颜色(和元素标签数量相等即可,在本例中为10)

var g = svg.append("g")

.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")

.datum(chord(matrix));

var group = g.append("g")

.attr("class", "groups")

.selectAll("g")

.data(function(chords) { return chords.groups; })

.enter().append("g");

group.append("path")

.style("fill", function(d) { return color(d.index); })

.attr("d", arc);

写到这里,在代码末尾包含结束符“”的情况下,可以运行出以下结果。

添加标签

group.append("text")

.each(function(d,i) { d.angle = (d.startAngle + d.endAngle) / 2;d.name = leixing[i]; })

.attr("dy", ".35em")

.attr("transform", function(d){

return "rotate(" + ( d.angle * 180 / Math.PI ) + ")" +"translate(0,"+ -1.0*(outerRadius+10) +")" +( ( d.angle > Math.PI*3/4 && d.angle < Math.PI*5/4 ) ? "rotate(180)" : "");})

.text(function(d) { return d.name; });

var groupTick = group.selectAll(".group-tick")

.data(function(d) { return groupTicks(d, 1e3); })

.enter().append("g")

.attr("class", "group-tick")

.attr("transform", function(d) { return "rotate(" + (d.angle * 180 / Math.PI - 90) + ") translate(" + outerRadius + ",0)"; });

写到这里,在代码末尾包含结束符“”的情况下,可以运行出以下结果。

绘制内部弦

g.append("g")

.attr("class", "ribbons")

.selectAll("path")

.data(function(chords) { return chords; })

.enter().append("path")

.attr("d", ribbon)

.style("fill", function(d) { return color(d.target.index); })

function groupTicks(d, step) {

var k = (d.endAngle - d.startAngle) / d.value;

return d3.range(0, d.value, step).map(function(value) {

return ;

});

}

//不要忘记最后的结束标签

中文乱码

  • 发表于:
  • 原文链接:http://kuaibao.qq.com/s/20171210A007JH00?refer=cp_1026

扫码关注云+社区