【 D3.js 高级系列 — 2.0 】 机械图 + 人物关系图
机械图(力路线图)结合老百姓的关系图中的生活,这是更有趣。
本文将以此为证据,所列的如何图插入外部的图像和文字的力学。
在【第 9.2 章】中制作了一个最简单的力学图。其后有非常多朋友有疑问,基本的问题包含:
- 怎样在小球旁插入文字
- 怎样将小球换为别的图形
- 怎样插入图片
- 怎样限制小球运动的边界
本文将对以上问题依次做出讲解。当中前三点是 SVG 元素的问题。和 D3 无多大关联。
1. SVG 图片
SVG 的图片元素的具体讲解可看【官方文档-图片】。通常,我们仅仅须要使用到图片元素的五个属性就够了。
<image xlink:href="image.png" x="200" y="200" width="100" height="100"></image>
当中:
- xlink:href - 图片名称或图片网址
- x - 图片坐上角 x 坐标
- y - 图片坐上角 y 坐标
- width - 图片宽度
- height- 图片高度
在 D3 中插入图片,代码形如:
svg.selectAll("image")
.data(dataset)
.enter()
.append("image")
.attr("x",200)
.attr("y",200)
.attr("width",100)
.attr("height",100)
.attr("xlink:href","image.png");
2. SVG 文本
SVG 的文本元素和图片类似,具体属性见【官方文档-文本】。
<text x="250" y="150" dx="10" dy="10" font-family="Verdana" font-size="55" fill="blue" >Hello</text>
当中:
- x - 文本 x 坐标
- y - 文本 y 坐标
- dx- x 轴方向的文本平移量
- dy- y 轴方向的文本平移量
- font-family - 字体
- font-size - 字体大小
- fill - 字体颜色
在 D3 中插入文本,代码形如:
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.attr("x",250)
.attr("y",150)
.attr("dx",10)
.attr("dy",10)
.text("Hello");
3. 源文件
接下来制作力学图的源文件。本次将数据写入 JSON 文件里。
呵呵。借用一下【仙剑4】的人物。本人也是个仙剑迷,期待15年7月【仙剑6】的上市。
{
"nodes":[
{ "name": "云天河" , "image" : "tianhe.png" },
{ "name": "韩菱纱" , "image" : "lingsha.png" },
{ "name": "柳梦璃" , "image" : "mengli.png" },
{ "name": "慕容紫英" , "image" : "ziying.png" }
],
"edges":[
{ "source": 0 , "target": 1 , "relation":"挚友" },
{ "source": 0 , "target": 2 , "relation":"挚友" },
{ "source": 0 , "target": 3 , "relation":"挚友" }
]
}
如上,在 JSON 文件里加入数据。再将图片文件与 JSON 文件放于同一文件夹下就可以(放哪都行,最主要是看程序中是怎样实现的)。
4. 力学图
4.1 读入文件
读入 JSON 文件,这点应该非常熟了吧。不然能够先看看【第 9.4 章】。
d3.json("relation.json",function(error,root){
if( error ){
return console.log(error);
}
console.log(root);
}
4.2 定义力学图的布局
力学图的 Layout(布局)例如以下:
var force = d3.layout.force()
.nodes(root.nodes)
.links(root.edges)
.size([width,height])
.linkDistance(200)
.charge(-1500)
.start();
当中 linkDistance 是结点间的距离, charge 是定义结点间是吸引(值为正)还是相互排斥(值为负),值越大力越强。
4.3 绘制连接线
绘制结点之间的连接线的代码例如以下:
var edges_line = svg.selectAll("line")
.data(root.edges)
.enter()
.append("line")
.style("stroke","#ccc")
.style("stroke-width",1);
var edges_text = svg.selectAll(".linetext")
.data(root.edges)
.enter()
.append("text")
.attr("class","linetext")
.text(function(d){
return d.relation;
});
当中,第 1 - 6 行:绘制直线
第 8 - 15 行:绘制直线上的文字
直线上文字的样式为:
.linetext {
font-size: 12px ;
font-family: SimSun;
fill:#0000FF;
fill-opacity:0.0;
}
fill-opacity 是透明度,0表示全然透明,1表示全然不透明。这里是0。表示初始状态下不显示。
4.4 绘制结点
绘制结点的图片和文字:
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;
})
.on("mouseover",function(d,i){
d.show = true;
})
.on("mouseout",function(d,i){
d.show = false;
})
.call(force.drag);
var text_dx = -20;
var text_dy = 20;
var nodes_text = svg.selectAll(".nodetext")
.data(root.nodes)
.enter()
.append("text")
.attr("class","nodetext")
.attr("dx",text_dx)
.attr("dy",text_dy)
.text(function(d){
return d.name;
});
第 1 - 16 行:绘制图片
第 10 - 15 行:当鼠标移到图片上时。显示与此结点想关联的连接线上的文字。在这里仅仅是对 d.show 进行布尔型赋值。在后面更新时会用到这个值。
第 21 - 30 行:绘制图片下方的文字
4.5 更新
让力学图不断更新,使用 force.on("tick",function(){ }),表示每一步更新都调用 function 函数。
force.on("tick", function(){
//限制结点的边界
root.nodes.forEach(function(d,i){
d.x = d.x - img_w/2 < 0 ?
img_w/2 : d.x ;
d.x = d.x + img_w/2 > width ? width - img_w/2 : d.x ;
d.y = d.y - img_h/2 < 0 ?
img_h/2 : d.y ;
d.y = d.y + img_h/2 + text_dy > height ? height - img_h/2 - text_dy : d.y ;
});
//更新连接线的位置
edges_line.attr("x1",function(d){ return d.source.x; });
edges_line.attr("y1",function(d){ return d.source.y; });
edges_line.attr("x2",function(d){ return d.target.x; });
edges_line.attr("y2",function(d){ return d.target.y; });
//更新连接线上文字的位置
edges_text.attr("x",function(d){ return (d.source.x + d.target.x) / 2 ; });
edges_text.attr("y",function(d){ return (d.source.y + d.target.y) / 2 ; });
//是否绘制连接线上的文字
edges_text.style("fill-opacity",function(d){
return d.source.show || d.target.show ? 1.0 : 0.0 ;
});
//更新结点图片和文字
nodes_img.attr("x",function(d){ return d.x - img_w/2; });
nodes_img.attr("y",function(d){ return d.y - img_h/2; });
nodes_text.attr("x",function(d){ return d.x });
nodes_text.attr("y",function(d){ return d.y + img_w/2; });
});
5. 结果
结果例如以下:
可点击以下的地址,右键点浏览器查看完整代码:http://www.ourd3js.com/demo/J-2.0/relationforce.html
6. 结束语
在【入门系列】中,疑问最多的是【树状图】,本想先解决问题的。可是因为我也有些问题还没想明确。所以先写本文这个较easy的。接下来还将有几篇关于力学图的,树状图的整理要略微拖一段时间。
谢谢阅读。
文档信息
- 版权声明:署名(BY)-非商业性(NC)-禁止演绎(ND)
- 发表日期:2014年10月25日
- 很多其它内容:OUR D3.JS - 数据可视化专题站 和CSDN个人博客
- 备注:转载请注明出处,谢谢
【 D3.js 高级系列 — 2.0 】 机械图 + 人物关系图的更多相关文章
- 【 D3.js 高级系列 — 10.0 】 思维导图
思维导图的节点具有层级关系和隶属关系,很像枝叶从树干伸展开来的形状.在前面讲解布局的时候,提到有五个布局是由层级布局扩展来的,其中的树状图(tree layout)和集群图(cluster layou ...
- 【 D3.js 高级系列 — 3.0 】 堆栈图
堆栈图布局(Stack Layout)能够计算二维数组每一数据层的基线,以方便将各数据层叠加起来.本文讲解堆栈图的制作方法. 先说说什么是堆栈图. 例如,有如下情况: 某公司,销售三种产品:个人电脑. ...
- 【 D3.js 高级系列 — 2.0 】 捆图
捆图(Bundle)是 D3 中比较奇特的一个布局,只有两个函数,而且需要与其它布局配合使用.本文讲述捆图的制作方法. 有关捆图的例子极少,很容易找到的是:http://bl.ocks.org/mbo ...
- 【 D3.js 高级系列 — 4.0 】 矩阵树图
矩阵树图(Treemap),也是层级布局的扩展,根据数据将区域划分为矩形的集合.矩形的大小和颜色,都是数据的反映.许多门户网站都能见到类似图1,将照片以不同大小的矩形排列的情形,这正是矩阵树图的应用. ...
- 【 D3.js 高级系列 — 1.0 】 文本的换行
在 SVG 中添加文本是使用 text 元素.但是,这个元素不能够自动换行,超出的部分就显示不出来了,怎么办呢? 高级系列开篇前言 从今天开始写高级系列教程.还是那句话,由于本人实力有限,不一定保证入 ...
- 【 D3.js 高级系列 — 9.0 】 交互式提示框
一般来说,图表中不宜存在过多文字.但是,有时需要一些文字来描述某些图形元素.那么,可以实现一种交互:当用户鼠标滑到某图形元素时,出现一个提示框,里面写有描述文字.这是一种简单.普遍的交互式,几乎适用于 ...
- 【 D3.js 高级系列 — 6.0 】 值域和颜色
在[入门 - 第 10 章]作了一张中国地图,其中各省份的颜色值都是随意赋值的.如果要将一些值反映在地图上,可以利用颜色的变化来表示值的变化. 1. 思路 例如,有值域的范围为: [10, 500] ...
- 【 D3.js 高级系列 — 8.0 】 标线
有时候,需要在地图上绘制连线,表示"从某处到某处"的意思,这种时候在地图上绘制的连线,称为"标线". 1. 标线是什么 标线,是指地图上需要两个坐标以上才能表示 ...
- 【 D3.js 高级系列 — 7.0 】 标注地点
有时需要告诉用户地图上的一些目标,如果该目标是只需要一个坐标就能表示的,称其为"标注". 1. 标注是什么 标注,是指地图上只需要一个坐标即可表示的元素.例如,在经纬度(116, ...
随机推荐
- C# 映射
public class Myclass1 { private int m_Count = 100; public string love{get;set;} public int Count { g ...
- [Mobx] Use MobX actions to change and guard state
This lesson explains how actions can be used to control and modify the state of your application. Th ...
- Redis实现Mybatis的二级缓存
一.Mybatis的缓存 通大多数ORM层框架一样,Mybatis自然也提供了对一级缓存和二级缓存的支持.一下是一级缓存和二级缓存的作用于和定义. 1.一级缓存是SqlSession级别的缓存.在操作 ...
- TransE论文剩余部分
4.3链接预測 表3:链接预測结果.不同方法的性能. 整体结果 表3显示了全部数据集全部方法的比較. 与预期结果一致,经过过滤设置的结果具有较低的平均排名和较高的hits@10,相信在链接预測方面对各 ...
- apache-spark导入eclipse环境
工作中用到了apache-spark,想深入了解一下,决定从源码开始. 先导入到常用的ide,eclipse吧: 准备工作 1. 下载Eclipse:http://scala-ide.org/ 2. ...
- 2、qq物联环境搭建
1.使用easyopenjtag.openjtag来烧写uboot 2.体验uboot 插讲<网络设置_ping问题解决_远程登录ssh_文件互传ftp> 192.168.1.183 wi ...
- 关于IO重定向
首先,Unix进程使用文件描述符0,1,2作为标准输入.输出和错误的通道. 其次,当进程请求一个新的文件描述符的时候,系统内核将最低可用的文件描述符赋给它. 第三,文件描述符集合通过exec调用传递, ...
- [Nuxt] Use Vuex Actions to Delete Data from APIs in Nuxt and Vue.js
You'll begin to notice as you build out your actions in Vuex, many of them will look quite similar. ...
- css3-12 transform:scale(1.2,1.2)实现移入元素变大特效
css3-12 transform:scale(1.2,1.2)实现移入元素变大特效 一.总结 一句话总结:transform:scale(1.2,1.2)鼠标移入的时候变大一点点,超出边框的部分隐藏 ...
- u-boot-2011.06在基于s3c2440开发板的移植之引导内核与加载根文件系统
http://www.linuxidc.com/Linux/2012-09/70510.htm 来源:Linux社区 作者:赵春江 uboot最主要的功能就是能够引导内核启动.本文就介绍如何实现该 ...