簇布局
布局是一种数据处理算法,将输入的数据转换为某种构造器所需要的数据。D3有12中布局:捆绑布局、弦布局、簇布局、力布局、层次布局、直方图布局、包布局、分区布局、饼布局、堆叠布局、树布局、和矩形树布局。
数据格式
数据就需要有父子关系,如:
var data={"name":"A","children":[{"name":"B01","children":[{ "name":"C01" },{ "name":"C02" },{ "name":"C03" }]},{"name":"B02","children":[{ "name":"C04" },{ "name":"C05" }]}]};
但是经常我们拿到的数据并不是这样的。如数据库中一般都是以如下结构存储有父子关系的记录的:
因此从后端传过来的数据也就是数组对象
var stratify = d3.stratify().id(function (d) {return d.name;}).parentId(function(d){return d.parent;});var rawData=[{name:"Eve",parent:""},{name:"Cain",parent:"Eve"},{name:"Seth",parent:"Eve"},{name:"Enos",parent:"Seth"},{name:"Noam",parent:"Seth"},{name:"Abel",parent:"Eve"},{name:"Awan",parent:"Eve"},{name:"Enoch",parent:"Awan"},{name:"Azura",parent:"Eve"}];var data = stratify(rawData);
d3.stratify()返回一个层次结构,用于层次布局中的数据结构。
其中的data元素就是层次结构的root,children是root的children,parent表示它的父元素(root没有父元素),再往下每个每个节点都是这种结构形式。
转换数据
这里的转换主要是为上面的data添加坐标信息。
d3.cluster().size([200,300]).cluster(data);
这是经过Cluster转换后的data,其中size函数指定的是图形的大小。而转换出的data中的每个节点坐标就是每个节点在这个size区域中应该在的位置。那现在我们的任务就是:
①用贝塞尔曲线连接这些位置
②在这些位置上画一个圆
③添加text
在d3的第三版中提供了diagonal方法,可以直接用它来生成贝塞尔曲线,但是在第四版却没有这个方法了。那我们就在第四版中添加这个方法。
//扩展d3(function () {function d3_functor(v) {return typeof v === "function" ? v : function() {return v;};}d3.functor = d3_functor;//贝塞尔曲线连接起始和终止点function _diagonal() {var source = function (d, i) {return d.source;},target = function (d, i) {return d.target;}, data=null,projection = function (d) {return [ d.x, d.y ];};function diagonal(d, i) {var p0 = source.call(this, d, i), p3 = target.call(this, d, i), m = (p0.y + p3.y) / 2, p = [ p0, {x: p0.x,y: m}, {x: p3.x,y: m}, p3 ];p = p.map(projection);return "M" + p[0] + "C" + p[1] + " " + p[2] + " " + p[3];}diagonal.source = function(x) {if (!arguments.length) return source;source = d3_functor(x);return diagonal;};diagonal.target = function(x) {if (!arguments.length) return target;target = d3_functor(x);return diagonal;};diagonal.projection = function(x) {if (!arguments.length) return projection;projection = x;return diagonal;};return diagonal;}var __proto__=d3.constructor.prototype;__proto__.diagonal=__proto__.diagonal || function () {return _diagonal();};}());
那现在就添加连接线:
var diagonal = d3.diagonal().projection(function (d) {return [d.y,d.x]});g.selectAll(".link").data(data.descendants().slice(1))//过滤掉root.enter().append("path").attr("class", "link").attr("d", function(d) {return diagonal({source:{x:d.x,y:d.y},target:{x:d.parent.x,y:d.parent.y}});});
添加节点
var node = g.selectAll(".node").data(data.descendants()).enter().append("g").attr("class", function(d) { return "node" + (d.children ? " node--internal" : " node--leaf"); }).attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });node.append("circle").attr("r", 3);
添加text
node.append("text").attr("dy", 3).attr("x", function(d) { return d.children ? -8 : 8; }).style("text-anchor", function(d) { return d.children ? "end" : "start"; }).text(function(d) { return d.id; });
作者:禅楼望月
出处:http://www.cnblogs.com/yaoyinglong
如果,您认为阅读这篇博文让您有些收获,不妨点击一下右下角的【推荐】
如果,您希望这篇博文也能帮助到其他人,不妨点击一下右边的【分享到…】
如果,您希望更容易地发现我的新博客,不妨点击一下左下角的【关注我】
如果,您对我的博客内容感兴趣,请继续关注我的后续博客,我是【禅楼望月】
本文版权归作者和博客园共有,欢迎转载,但请注明出处,且在文章页面明显位置给出原文连接。
*\\(^o^)/* 请您毫不留情的指出错误和不足,或者发表您的见解(ɔˆ ³(ˆ⌣ˆc)我们共同进步(ง •̀_•́)ง




浙公网安备 33010602011771号