D3.js学习笔记十三:D3.js树图(Tree)

2015年03月05日 javascript 暂无评论 阅读 3,467 views 次

构图(d3.layout)——树图(Tree)的API说明

  • d3.layout.tree - position a tree of nodes tidily.
  • tree.sort - 设置或获取一个函数, 用来给兄弟节点(同一父结点的子结点)排序.
  • tree.children - 设置或获取子结点的访问器.
  • tree.nodes - 计算并返回指定结点的子结点信息.
  • tree.links - 指定一个子结点数组(通常是nodes函数返回值), 计算它们与父结点的连接信息.
  • tree.separation - 设置或获取相隔结点之间的间隔计算函数.
  • tree.size - 指定整个布局的宽和高.
  • tree.nodeSize - 给全部结点指定一个固定的大小(会导致tree.size失效).

和力学图一样,树图也有三个基本要素:控制结构,节点标记和节点连线。控制结构规范节点的行为,连线和节点显示节点信息和关系。控制结构的nodes(节点集合)元素有以下属性:

  • parent - 节点的父节点,根节点的父节点为null
  • children - 返回子节点的数组,每个元素仍然是一个节点对象,叶子节点的子节点为null
  • depth - 节点深度,编号从根节点开始,根节点深度为0
  • x - 节点的横坐标
  • y - 节点的纵坐标

树的Links(称为联系对象?)元素有以下属性:

  • source - 连线的前端节点
  • target - 连线的后端节点

容易混淆的概念是错把树的控制结构里面的节点和连线当做实体,事实上它们只是理论上的一个规范,如果我们想要看见它们,需要为它们生成实体,例如根据节点的坐标生成一个圆形,或者根据Links的信息生成折线。D3.js使用树的规范读取并绑定一系列具有父子关系的数据,我们借用这些绑定,能够方便地访问对象,并为它们指定一系列的行为和显示,这是D3.js树结构的正确应用。总之一句话,“树”是规范,不是外观

我们用以下代码产生一个树,思路和力学图差不多:使用Tree对象建立规则,然后应用规则摆放一些可见元素。

<script type="text/javascript"> //图像区域大小 var w = 960; var h = 800; //定义一个Tree对象 var tree = d3.layout.tree() .size([w,h]) .separation(function(a,b) { return a.parent == b.parent ? 1 : 2;}); //新建画布 var svg = d3.select("body").append("svg") .attr("width", w) .attr("height", h) .append("g"); //根据JSON数据生成树 d3.json("treeData.php", function(error, data) { //根据数据生成nodes集合 var nodes = tree.nodes(data); //获取node集合的关系集合 var links = tree.links(nodes); //为关系集合设置贝塞尔曲线连接 var link=svg.selectAll(".link") .data(links) .enter() .append("path") .attr("class", "link") .attr("d",d3.svg.diagonal()); //根据node集合生成节点 var node = svg.selectAll(".node") .data(nodes) .enter() .append("g") .attr("class", "node") .attr("transform", function(d){ return "translate("+d.x+"," + d.y + ")";}); //为节点添加圆形标记,如果有子节点为红色,否则绿色 node.append("circle") .attr("fill",function(d){return d.children==null?"#0F0":"#F00";}) .attr("r", function(d){return d.children==null?5:d.children.length+5;}); //为节点添加说明文字 node.append("text") .attr("dy", "1.5em") .attr("text-anchor","middle") .text(function(d){return d.name;}); }); </script>

代码运行后产生如下的树状图:

示例代码地址:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>画一个树图(Tree)</title>
<script type="text/javascript" src="js/d3.js"></script>
</head>
<style>
.node circle {
/*fill: #fff;*/
stroke: steelblue;
stroke-width: 1px;
}
.node {
font: 12px sans-serif;
}
.link {
fill: none;
stroke: #ccc;
stroke-width: 1px;
}
</style>
<body>
<script type="text/javascript">
//图像区域大小
var w = 960;
var h = 800;
//定义一个Tree对象
var tree = d3.layout.tree()
.size([w,h])
.separation(function(a,b) { return a.parent == b.parent ? 1 : 2;});
//新建画布
var svg = d3.select("body").append("svg")
.attr("width", w)
.attr("height", h)
.append("g");
//根据JSON数据生成树
d3.json("treeData.php", function(error, data) {
//根据数据生成nodes集合
var nodes = tree.nodes(data);
//获取node集合的关系集合
var links = tree.links(nodes);
//为关系集合设置贝塞尔曲线连接
var link=svg.selectAll(".link")
.data(links)
.enter()
.append("path")
.attr("class", "link")
.attr("d",d3.svg.diagonal());
//根据node集合生成节点
var node = svg.selectAll(".node")
.data(nodes)
.enter()
.append("g")
.attr("class", "node")
.attr("transform", function(d){ return "translate("+d.x+"," + d.y + ")";});
//为节点添加圆形标记,如果有子节点为红色,否则绿色
node.append("circle")
.attr("fill",function(d){return d.children==null?"#0F0":"#F00";})
.attr("r", function(d){return d.children==null?5:d.children.length+5;});
//为节点添加说明文字
node.append("text")
.attr("dy", "1.5em")
.attr("text-anchor","middle")
.text(function(d){return d.name;});
});
</script>
</body>
</html>

 

打开后右键查看源码。

JSON数据:php用来生成树的数据,主要是一个递归调用,代码很简单:

<?php $num=rand(0,10); $root=array(); $child=array(); $root["name"]="根节点"; for($i=0;$i<5;$i++) { $child[$i]=makeTree($index+1,$i); } $root["children"]=$child; $nodeIndex=0; function makeTree($index,$d) { global $nodeIndex; $num=rand(0,6); $arr=array(); $arr["name"]="节点(".$num.")"; if($index>=3 || $num==0) { $nodeIndex++; $arr["name"]="叶子".$nodeIndex; $arr["size"]=rand(50,1000); } else { $child=array(); for($i=0;$i<$num;$i++) { $child[$i]=makeTree($index+1,$i); } $arr["children"]=$child; } return $arr; } echo json_encode($root); ?>

递归调用makeTree函数,生成一个最多4层的树。关于树的应用很多,因此我们会在下一节继续这个学习。

给我留言

您必须 登录 才能发表留言!

Copyright © 大一网 保留所有权利.  

用户登录

分享到: