【D3.js数据可视化系列教程】(二十七)--径向树

径向树也就是环状的树

  1. 效果

  2. 技术分解

  2.1 定义树布局

指定布局大小和节点邻距

【司机提示】 树布局就是一个函数,用来对原始的层次状数据进行加工处理,而这个加工主要就是生成节点的坐标深度等数据。由这些数据结合对角线,圆等就可以绘制径向树了。

var tree = d3.layout.tree()
    .size([360, 360])// 角度360度,半径360px
    .separation(function(a, b) { 
    	return (a.parent == b.parent ? 1 : 2) / a.depth; });// 父节点相同的节点邻距相等,不同的稍宽一点用来区分开
    });

  2.2 定义径向对角线生成器

【司机提示】 径向对角线生成器也是一个函数,主要用来生成用以绘制连线数据。

var diagonal = d3.svg.diagonal.radial()
    .projection(function(d) { 
    	return [d.y, d.x / 180 * Math.PI];// 半径d.y和角度d.x / 180 * Math.PI(转换成弧度制)
    });

  2.3 加载json数据

d3.json("tree.json", function(error, root) {
  var nodes = tree.nodes(root),//返回值是一个数组,它代表​​所有节点计算的位置。每个节点上填充一些属性:
      links = tree.links(nodes);//返回节点数组的连接数组
  //...
});

  2.4 为连线添加路径数据

var link = svg.selectAll(".link")
  .data(links)
.enter().append("path")
  .attr("class", "link")
  .attr("d", diagonal);

  2.5 节点转换位置

transform是变换,本例中用于平移

var node = svg.selectAll(".node")
  .data(nodes)
  .enter().append("g")
  .attr("class", "node")
  .attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + d.y + ")"; })

  2.6 节点添加圆圈

node.append("circle")
  .attr("r", 4.5);

  2.7 节点添加文字

node.append("text")
  .attr("dy", ".31em")
  .attr("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; })//小于180度的文字放在前面,否则放在后面
  .attr("transform", function(d) { return d.x < 180 ? "translate(8)" : "rotate(180)translate(-8)"; })
  .text(function(d) { return d.name; });

  3. JSON文件

很简单就是{}表示对象。[]表示数组。可以无限嵌套,可以无限重复

{
 "name": "AAA",
 "children": 
 [
  	  { "name": "BBB", 
  	  	"children": 
  	    [
  	      	{"name": "CCC", 
  	      	"children": 
  	      	[
  	          		{"name": "DDD", 
  	          		 "children":
                     [
                            {"name": "EEE", "size": 73},
                          	{"name": "EEE", "size": 39},
                          	{"name": "EEE", "size": 67},
                          	{"name": "EEE", "size": 73},
                          	{"name": "EEE", "size": 39},
                          	{"name": "EEE", "size": 67},
                          	{"name": "EEE", "size": 73},
                          	{"name": "EEE", "size": 39},
                          	{"name": "EEE", "size": 67},
                          	{"name": "EEE", "size": 73},
                          	{"name": "EEE", "size": 39},
                          	{"name": "EEE", "size": 67},
                          	{"name": "EEE", "size": 73},
                          	{"name": "EEE", "size": 39},
                          	{"name": "EEE", "size": 67},
                          	{"name": "EEE", "size": 73}
                     ]},
                  	{"name": "DDD", "size": 73},
                  	{"name": "DDD", "size": 39},
                  	{"name": "DDD", "size": 67},
                  	{"name": "DDD", "size": 73},
                  	{"name": "DDD", "size": 39},
                  	{"name": "DDD", "size": 67},
                  	{"name": "DDD", "size": 73},
                  	{"name": "DDD", "size": 39},
                  	{"name": "DDD", "size": 67},
                  	{"name": "DDD", "size": 73},
                  	{"name": "DDD", "size": 39},
                  	{"name": "DDD", "size": 67},
                  	{"name": "DDD", "size": 73},
                  	{"name": "DDD", "size": 39},
                  	{"name": "DDD", "size": 67},
                  	{"name": "DDD", "size": 73}
  	      	]},
          	{"name": "CCC", "size": 67},
          	{"name": "CCC", "size": 73},
          	{"name": "CCC", "size": 39},
          	{"name": "CCC", "size": 67},
          	{"name": "CCC", "size": 73},
          	{"name": "CCC", "size": 39},
          	{"name": "CCC", "size": 67},
          	{"name": "CCC", "size": 73},
          	{"name": "CCC", "size": 39},
          	{"name": "CCC", "size": 67},
          	{"name": "CCC", "size": 73},
          	{"name": "CCC", "size": 39},
          	{"name": "CCC", "size": 67},
          	{"name": "CCC", "size": 73},
          	{"name": "CCC", "size": 39},
          	{"name": "CCC", "size": 67},
          	{"name": "CCC", "size": 73}
  	  ]
      },
      {"name": "BBB", "size": 39},
      {"name": "BBB", "size": 67},
      {"name": "BBB", "size": 73},
      {"name": "BBB", "size": 39},
      {"name": "BBB", "size": 67},
      {"name": "BBB", "size": 73},
      {"name": "BBB", "size": 39},
      {"name": "BBB", "size": 67},
      {"name": "BBB", "size": 73},
      {"name": "BBB", "size": 39},
      {"name": "BBB", "size": 67},
      {"name": "BBB", "size": 73},
      {"name": "BBB", "size": 39},
      {"name": "BBB", "size": 67},
      {"name": "BBB", "size": 73},
      {"name": "BBB", "size": 39},
      {"name": "BBB", "size": 67},
      {"name": "BBB", "size": 73},
      {"name": "BBB", "size": 67},
      {"name": "BBB", "size": 73},
      {"name": "BBB", "size": 39},
      {"name": "BBB", "size": 67},
      {"name": "BBB", "size": 73},
      {"name": "BBB", "size": 39},
      {"name": "BBB", "size": 67},
      {"name": "BBB", "size": 73}
 ]
}

  4. 完整代码

<!DOCTYPE html>
<html>
  <head>
        <meta charset="utf-8">
        <title>testD3-24-Reingold–Tilford Tree.html</title>
        <script type="text/javascript" src="d3.js"></script>
    <style>

.node circle {
  fill:yellow ;
  stroke: red;
  stroke-width: 1.5px;
}

.node {
  font: 10px sans-serif ;
}

.link {
  fill: green;
  stroke: #ccc;
  stroke-width: 1.5px;
}

</style>
</head>
<body>
<script type="text/javascript">
var diameter = 960;//直径
//(1)树指定径向布局大小和节点邻距
var tree = d3.layout.tree()
    .size([360,  360])// 角度360度,半径360px
    .separation(function(a, b) { 
    	return (a.parent == b.parent ? 1 : 2) / a.depth;// 父节点相同的节点邻距相等,不同的稍宽一点用来区分开
    });

var diagonal = d3.svg.diagonal.radial()//(2)指定为径向布局
    .projection(function(d) { 
    	return [d.y, d.x / 180 * Math.PI];// 半径d.y和角度d.x / 180 * Math.PI(转换成弧度制) 
    });

var svg = d3.select("body").append("svg")
    .attr("width", diameter)
    .attr("height", diameter - 150)
  	.append("g")
    .attr("transform", "translate(" + diameter / 2 + "," + diameter / 2 + ")");
//(3)加载json
d3.json("flare.json", function(error, root) {
  var nodes = tree.nodes(root),//返回值是一个数组,每个节点上填充一些计算后的属性,例如深度,坐标等。
      links = tree.links(nodes);//返回节点数组的连接数组
  //(4)为链接添加路径
  var link = svg.selectAll(".link")
      .data(links)
    .enter().append("path")
      .attr("class", "link")
      .attr("d", diagonal);
  //(5)节点转换位置
  var node = svg.selectAll(".node")
      .data(nodes)
   	  .enter().append("g")
      .attr("class", "node")
      .attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + d.y + ")"; })
  //(6)节点添加圆圈
  node.append("circle")
      .attr("r", 4.5);

  //(7)节点添加文字
  node.append("text")
      .attr("dy", ".31em")
      .attr("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; })//小于180度的文字放在前面,否则放在后面
      .attr("transform", function(d) { return d.x < 180 ? "translate(8)" : "rotate(180)translate(-8)"; })
      .text(function(d) { return d.name; });
});

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值