一、打包圖
打包圖( Pack ),用於表示包含與被包含的關系,也可表示各對象的權重,通常用一圓套一圓來表示前者,用圓的大小來表示后者。
1、布局(數據轉換)
var pack = d3.layout.pack() .size([ width, height ]) .radius(20);
第 1 行:打包圖的布局
第 2 行:size() 設定轉換的范圍,即轉換后頂點的坐標(x,y),都會在此范圍內。
第 3 行:radius() 設定轉換后最小的圓的半徑。
讀取數據並轉換的代碼
d3.json("city2.json", function(error, root) { var nodes = pack.nodes(root); var links = pack.links(nodes); console.log(nodes); console.log(links); }
上面用 pack 函數分別將數據轉換成了頂點 nodes 和 連線 links。來看看頂點數據被轉換成了什么樣:

數據被轉換后,多了深度信息(depth),半徑大小(r),坐標位置(x,y)等。打包圖無需對連線進行繪制。
注意:無論用什么 Layout 來轉換數據,一定要先看轉換后的數據是什么再繪制,否則很容易出錯。
2、繪制
繪制的內容有圓和文字,都在 SVG 中繪制。實例代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>vue生命周期學習</title>
<script src="d3.min.js"></script>
</head>
<body>
</body>
<script>
//准備畫布
var width=500,height=500; var svg = d3.select("body").append("svg").attr("width",width).attr("height",height); //布局
var pack = d3.layout.pack().size([width,height]).radius(20); //讀取數據並轉換數據
d3.json('city2.json',function(error,root){ var nodes = pack.nodes(root); var links = pack.links(nodes); console.log(nodes,links); //畫圓
svg.selectAll("circle") .data(nodes) .enter() .append("circle") .attr("fill","rgb(31, 119, 180)") .attr("fill-opacity","0.4") .attr("cx",function(d){ return d.x; }) .attr("cy",function(d){ return d.y; }) .attr("r",function(d){ return d.r; }) .on("mouseover",function(d,i){ d3.select(this).attr("fill","yellow") }) .on("mouseout",function(d,i){ d3.select(this).attr("fill","rgb(31, 119, 180)"); }); //給文本
svg.selectAll("text") .data(nodes) .enter() .append("text") .attr("font-size","10px") .attr("fill","white") .attr("fill-opacity",function(d){ if(d.depth == 2) return "0.9"; else
return "0"; }) .attr("x",function(d){ return d.x; }) .attr("y",function(d){ return d.y; }) .attr("dx",-12) .attr("dy",1) .text(function(d){ return d.name; }); }) </script>
</html>
二、地圖
在數據可視化中,地圖是很重要的一部分。很多情況會與地圖有關聯,如中國各省的人口多少,GDP多少等,都可以和地圖聯系在一起。
將 JSON 的格式應用於地理上的文件,叫做 GeoJSON 文件。本文就是用這種文件繪制地圖。
1、投影函數
var projection = d3.geo.mercator() .center([107, 31]) .scale(850) .translate([width/2, height/2]);
由於 GeoJSON 文件中的地圖數據,都是經度和緯度的信息。它們都是三維的,而要在網頁上顯示的是二維的,所以要設定一個投影函數來轉換經度緯度。如上所示,使用 d3.geo.mercator() 的投影方式。
第 2 行:center() 設定地圖的中心位置,[107,31] 指的是經度和緯度。
第 3 行:scale() 設定放大的比例。
第 4 行:translate() 設定平移。
2、地理路徑生成器
為了根據地圖的地理數據生成 SVG 中 path 元素的路徑值,需要用到 d3.geo.path(),我稱它為地理路徑生成器
var path = d3.geo.path() .projection(projection);
projection() 是設定生成器的投影函數,把上面定義的投影傳入即可。以后,當使用此生成器計算路徑時,會自己加入投影的影響。
3、向服務器請求文件並繪制地圖
<html>
<head>
<meta charset="utf-8">
<title>中國地圖</title>
</head>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var width = 1000; var height = 1000; var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height) .append("g") .attr("transform", "translate(0,0)"); var projection = d3.geo.mercator() .center([107, 31]) .scale(850) .translate([width/2, height/2]); var path = d3.geo.path() .projection(projection); var color = d3.scale.category20(); d3.json("china.geojson", function(error, root) { if (error) return console.error(error); console.log(root.features); svg.selectAll("path") .data( root.features ) .enter() .append("path") .attr("stroke","#000") .attr("stroke-width",1) .attr("fill", function(d,i){ return color(i); }) .attr("d", path ) .on("mouseover",function(d,i){ d3.select(this) .attr("fill","yellow"); }) .on("mouseout",function(d,i){ d3.select(this) .attr("fill",color(i)); }); }); </script>
</body>
</html>
再次聲明:d3.json() 不能直接讀取本地文件,因此你需要搭建一個服務器,例如 Apache。但是在火狐瀏覽器是可以直接讀取的。
接下來,就是給 svg 中添加 path 元素。本例中,每一個 path 表示一個省。要注意 attr(“d”,path) 這一行代碼,它相當於:
.attr("d",funtion(d){ return path(d); })
