D3.js中Treemap(矩形树图)源码详解
Treemap(矩形树图)
聊⼀聊Treemap,即矩形树图,树形结构⾮常有意思的⼀种展现⽅式,外形规整⽽不失表达⼒。
矩形树状结构图(Treemap)是⼀种有效的实现层次结构可视化的图表结构,简称矩形树图或树图。在矩形树图中,各个⼩矩形的⾯积表⽰每个⼦节点的⼤⼩,矩形⾯积越⼤,表⽰⼦节点在⽗节点中的占⽐越⼤,整个矩形的⾯积之和表⽰整个⽗节点。通过矩形树图及其钻取情况,我们可以很清晰地知道数据的全局层级结构和每个层级的详情。——
接下来对d3.js实现treemap的过程进⾏解析
index.html——
<!DOCTYPE html>
<style>
form {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
svg {
font: 10px sans-serif;
}
</style>
<svg width="960"height="570"></svg>
<form>
<label><input type="radio"name="mode"value="sumBySize"checked> Size</label>
<label><input type="radio"name="mode"value="sumByCount"> Count</label>
</form>
<script src="/d3.v4.min.js"></script>
<script>
// 定义svg画布
var svg = d3.select("svg"),
// 获取svg画布宽度
width = +svg.attr("width"),
// 获取svg画布⾼度
height = +svg.attr("height");
// 定义fader函数⽤来获取颜⾊,返回颜⾊字符串
// d3.interpolateCubehelix(a, b)返回a和b之间的颜⾊插值,0.2是修正gamma值
var fader = function(color) { return d3.interpolateRgb(color, "#fff")(0.2); },
/
/ d3.schemeCategory20.map(fader),将d3.schemeCategory20返回的20个颜⾊值通过fader函数
// 进⾏映射转换,最终,⽣成离散颜⾊⽐例尺color函数
color = d3.scaleOrdinal(d3.schemeCategory20.map(fader)),
// 定义⼀个格式函数
format = d3.format(",d");
// 定义⼀个矩形树图布局函数treemap()函数
var treemap = d3.treemap()
// 设置tile为d3.treemapResquarify,即矩形按层排列
.apResquarify)
// 指定布局范围
.size([width, height])
/
/ 启⽤边界补偿
.round(true)
// 指定内部间距
.paddingInner(1);
// 读取数据
d3.json("flare.json", function(error, data) {
if (error) throw error;
// ⽣成树形层次结构的数据js文字动画特效
var root = d3.hierarchy(data)
// node.eachBefore⽤来前序遍历树节点,对于每⼀个node,计算id的格式
.eachBefore(function(d) { d.data.id = (d.parent ? d.parent.data.id + "." : "") + d.data.name; }) // 对节点的size属性求和
.sum(sumBySize)
// 对节点进⾏排序,按照深度或者值的⼤⼩来确定顺序
.sort(function(a, b) { return b.height - a.height || b.value - a.value; });
对root数据进⾏矩形树布局
treemap(root);
// 定义每个矩形的画布
var cell = svg.selectAll("g")
// 将叶⼦节点数据绑定到矩形元素上
.data(root.leaves())
.enter().append("g")
// 设置矩形的位置
.
attr("transform", function(d) { return"translate(" + d.x0 + "," + d.y0 + ")"; });
// 设置代表树节点的每个矩形的id,宽度,⾼度以及填充⾊
cell.append("rect")
.attr("id", function(d) { return d.data.id; })
.attr("width", function(d) { return d.x1 - d.x0; })
.attr("height", function(d) { return d.y1 - d.y0; })
// 填充⾊通过⽗节点的id来计算,保证同⼀⽗节点的所有⼦节点的颜⾊相同
.attr("fill", function(d) { return color(d.parent.data.id); });
// 定义矩形上的⽂字裁剪元素
cell.append("clipPath")
.attr("id", function(d) { return"clip-" + d.data.id; })
.
append("use")
.attr("xlink:href", function(d) { return"#" + d.data.id; });
// 为矩形上的⽂字使⽤clip-path,控制⽂字换⾏
cell.append("text")
.attr("clip-path", function(d) { return"url(#clip-" + d.data.id + ")"; })
.selectAll("tspan")
.data(function(d) { return d.data.name.split(/(?=[A-Z][^A-Z])/g); })
.enter().append("tspan")
.attr("x", 4)
.attr("y", function(d, i) { return13 + i * 10; })
.text(function(d) { return d; });
/
/ 为矩形绑定title属性,并设置title显⽰内容
cell.append("title")
.text(function(d) { return d.data.id + "\n" + format(d.value); });
// 定义两个控制按钮:按照节点的size或者节点⼦节点的个数进⾏布局排列
d3.selectAll("input")
.data([sumBySize, sumByCount], function(d) { return d ? d.name : this.value; })
.on("change", changed);
// 定义定时器,默认以count为排列依据
var timeout = d3.timeout(function() {
d3.select("input[value=\"sumByCount\"]")
.property("checked", true)
.
dispatch("change");
}, 2000);
// 当切换按钮被点击时,切换排列依据
function changed(sum) {
timeout.stop();
timeout.stop();
// 以当前的sum⽅式来排列布局
treemap(root.sum(sum));
// 切换布局的过程动画
.duration(750)
.
attr("transform", function(d) { return"translate(" + d.x0 + "," + d.y0 + ")"; })
.select("rect")
.attr("width", function(d) { return d.x1 - d.x0; })
.attr("height", function(d) { return d.y1 - d.y0; });
}
});
// 对节点的⼦节点个数求和
function sumByCount(d) {
return d.children ? 0 : 1;
}
// 返回节点的size属性
function sumBySize(d) {
return d.size;
}
</script>
⾄此,矩形树图的实现解释完毕,矩形树图⽐较简单,还是得感谢强⼤的d3布局,基本上帮助我们搞定绝⼤多数⼯作。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论