【 D3.js 入门系列 --- 10.2 】 你可以拖动地图
我的个人博客是:www.ourd3js.com
csdn博客为:blog.csdn.net/lzhlzz
转载请注明出处。谢谢。
本节是结合9.2节 和10节 的内容制作的一个可力学导向的中国地图,用户能够拖动中国的各个省份。
数据用的是 10.1节 中简化的中国地图文件: china_simplify.json
1. 定义各函数
var projection = d3.geo.mercator()
.center([107, 31])
.scale(850)
.translate([width/2, height/2]); var path = d3.geo.path()
.projection(projection); var force = d3.layout.force().size([width, height]); var color = d3.scale.category20();
projection 函数是用于将三维地图的坐标投影到二维所用的投影函数。详细可见: 10节
path 函数用于绘制地图路径,里面要传入投影函数 projection 。详细可见: 10节
force 是定义力学图的 layout 。详细可见: 9.2节
color 是颜色函数。
2. 读取数据
d3.json("china_simplify.json", function(error, root) {
if (error)
return console.error(error);
console.log(root.features);
}
和前几节一样,用 d3.json() 读取文件,后面两句是用于检測错误,以及输出错误信息。
3. 转换数据
var nodes = [];
var links = []; root.features.forEach(function(d, i) {
var centroid = path.centroid(d);
centroid.x = centroid[0];
centroid.y = centroid[1];
centroid.feature = d;
nodes.push(centroid);
}); var triangles = d3.geom.voronoi().triangles(nodes); triangles.forEach(function(d,i){
links.push( edge( d[0] , d[1] ) );
links.push( edge( d[1] , d[2] ) );
links.push( edge( d[2] , d[0] ) );
});
读取后的文件信息都存在变量 root 中,上面的代码是将 root 中的数据分别转换为力学图所须要的点和线。存在变量 nodes 和 links 中。
第1-2行: 定义变量 nodes 和 links
第4-10行: 对于 root.features 中存有每个省的数据, root.features.forEach() 即对每个省的数据。运行后面的无名函数。函数里面是计算出各省的中点,保存在 centroid.x 和 centroid.y 中,再把其它信息赋值给 centroid.feature。最后插入到 nodes 中。
第12行: 对 nodes 中的顶点进行三角剖分。即用三角形来连接各顶点。结果保存在 triangles 中。
第14-18行: 将三角形的各边存到 links 变量中。当中的 edge 函数的实现为:
function edge(a, b) {
var dx = a[0] - b[0], dy = a[1] - b[1];
return {
source: a,
target: b,
distance: Math.sqrt(dx * dx + dy * dy)
};
}
4. 绘制地图
force.gravity(0)
.charge(0)
.nodes(nodes)
.links(links)
.linkDistance(function(d){ return d.distance; })
.start(); var node = svg.selectAll("g")
.data(nodes)
.enter().append("g")
.attr("transform", function(d) { return "translate(" + -d.x + "," + -d.y + ")"; })
.call(force.drag)
.append("path")
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
.attr("stroke","#000")
.attr("stroke-width",1)
.attr("fill", function(d,i){
return color(i);
})
.attr("d", function(d){
return path(d.feature);
} ); var link = svg.selectAll("line")
.data(links)
.enter()
.append("line")
.attr("class","link")
.attr("x1",function(d) { return d.source.x; } )
.attr("y1",function(d) { return d.source.y; } )
.attr("x2",function(d) { return d.target.x; } )
.attr("y2",function(d) { return d.target.y; } );
第1-6行: 设定 force 的各參数进行设定。
第8-22行: 绘制各顶点。即中国各省。当中要注意。第11行和第14行,是全然相反的两个平移函数,不错,这么做就是为了移过去,再移回来,即初始时显示的是各省拼成的完整的地图且显示在最初设定的位置,由于拖拽的过程中变化的量是 d.x 和 d.y 。所以要这么做。
这里有点难理解,请好好体会一下,如有疑问,请在以下留言。另外。第12行是调用 force.drag 函数。
第24-32行: 绘制连接各省的线条。
5. 力学图的结合
force.on("tick", function() {
link.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
node.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
});
这里和 9.2节 一样,tick 指的是时间间隔,也就是每个时间间隔之后就刷新一遍画面。刷新的内容写在后面的无名函数 function 中, function 函数中写上作图的内容。
这里看到了吧。第7-9行里是用于平移的,平移的參数为 d.x 和 d.y 。
结果图:
拖动试试吧。哈哈:
自己用鼠标试试吧,点击以下的链接,完整代码请右键点击浏览器后选择查看:
http://www.ourd3js.com/demo/mapforce.html
感谢您的阅读。
版权声明:本文博客原创文章,博客,未经同意,不得转载。
【 D3.js 入门系列 --- 10.2 】 你可以拖动地图的更多相关文章
- 【 D3.js 入门系列 — 11 】 入门总结
D3 新专题首页 一转眼,这个入门系列已经积累了二十二篇文章之多,我想作为 D3.js 这款数据可视化工具的入门来说已经足够了.相信仅仅要看完本系列.以后全然能够在辅以查询的情况下完毕大部分可视化工作 ...
- 【 D3.js 入门系列 --- 3 】 做一个简单的图表!
前面说了几节,都是对文字进行处理,这一节中将用 D3.js 做一个简单的柱形图. 做柱形图有很多种方法,比如用 HTML 的 div 标签,或用 svg . 推荐用 SVG 来做各种图形.SVG 意为 ...
- 【 D3.js 入门系列 — 1 】 第一个程序 HelloWorld
记得以前刚上大一学 C 语言的时候,写的第一个程序就是在控制台上输出 HelloWorld .当时很纳闷,为什么要输出这个.老师解释说所有学编程入门的第一个程序都是在屏幕上输出 HelloWorld, ...
- 【 D3.js 入门系列 --- 2.1 】 关于如何选择,插入,删除元素
在D3.js中,选择元素的函数有两个:select 和 selectAll . 先说明一下它们的区别: select 是选择所有指定元素的第一个 selectAll 是选择指定元素的全部(以用于后面同 ...
- 【 D3.js 入门系列 --- 2 】 如何使用数据和选择元素
接着上一讲的内容,这次讨论如何选择元素和使用数据. 现在页面中有三行文字,代码为: <p>Hello World 1</p> <p>Hello World 2 ...
- 【 D3.js 入门系列 --- 1 】 第一个程序HelloWorld
下面开始用D3.js处理第一个简单问题,先看下面的代码: <html> <head> <meta charset="utf-8"> <ti ...
- 【 D3.js 入门系列 --- 0 】 简介和安装
D3的全称是(Data-Driven Documents),顾名思义可以知道是一个关于数据驱动的文档的javascript类库.如果你不知道什么是javascript,请先学习javascript的相 ...
- 【 D3.js 高级系列 — 10.0 】 思维导图
思维导图的节点具有层级关系和隶属关系,很像枝叶从树干伸展开来的形状.在前面讲解布局的时候,提到有五个布局是由层级布局扩展来的,其中的树状图(tree layout)和集群图(cluster layou ...
- 【 D3.js 入门系列 --- 2 】 怎样使用数据和选择元素
本人的个人博客首页为: http://www.ourd3js.com/ ,csdn博客首页为:http://blog.csdn.net/lzhlzz/. 转载请注明出处,谢谢. 接着上一讲的内容,这 ...
随机推荐
- 大并发连接的oracle在Linux下内存不足的问题的分析(转)
最近一台装有Rhel5.3的40G内存的机器上有一个oracle数据库,数据库的SGA设置为20G,当运行业务时,一个业务高峰期时,发现swap频繁交换,CPU 100%,Load很高,基本体现为内存 ...
- 国庆去学校的国际象棋(Latex)
国庆节去学棋与朋友. 看国外的网站更有趣的事情. 很快打下来. 首先效应: 嘿嘿 代码来了哟: \usepackage[utf8]{inputenc} \usepackage[T1]{fontenc ...
- 通过angularjs的directive以及service来实现的列表页加载排序分页(转)
前两篇:(列表页的动态条件搜索,我是如何做列表页的)分别介绍了我们是如何做后端业务系统数据展示类的列表页以及动态搜索的,那么还剩下最重要的一项:数据展示.数据展示一般包含三部分: 数据列头 数据行 分 ...
- Linux游(1): diff, patch和quilt (下一个)
Linux游(1): diff, patch和quilt (下一个) 2 quilt 我们自己的项目可以用cvs或svn管理所有代码.但有时我们要使用其它开发人员维护的项目.我们须要改动一些文件.但又 ...
- virtio-blk分析
和virtio-network相同,virtio-blk驱动程序使用Virtio机制Guest它提供了一个高性能的设备I/O方法.我们期待在这里virtio-blk实现. [点击查看全文] http: ...
- php定时运行任务(windows7)
1:自己写的php档,下面是我的一些php档 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzE2MDAyNA==/font/5a6L5L2T/f ...
- 【转】求质数算法的N种境界
原文地址:http://blog.csdn.net/program_think/article/details/7032600/ ★引子 前天,俺在<俺的招聘经验[4]:通过笔试答题能看出啥?& ...
- 【Jqurey EasyUI+Asp.net】---DataGrid增加、删、更改、搜
在前面写了两,但不知道如何完成,对比刚刚开始学这个,他们摸着石头过河,一步步.在最后两天DataGridCRUD融合在一起.因此份额.我希望像我这样谁是刚刚开始学习一些帮助. 直接主题酒吧. 它是说数 ...
- UVA 12103 - Leonardo's Notebook(数论置换群)
UVA 12103 - Leonardo's Notebook 题目链接 题意:给定一个字母置换B.求是否存在A使得A^2=B 思路:随意一个长为 L 的置换的k次幂,会把自己分裂成gcd(L,k) ...
- ORACLE触发特定的解释
ORACLE PL/SQL编程八: 把触发器说透 本篇主要内容例如以下: 8.1 触发器类型 8.1.1 DML触发器 8.1.2 替代触发器 8.1.3 系统触发器 8.2 创建触发器 8.2.1 ...