zoukankan      html  css  js  c++  java
  • 簇布局

    布局是一种数据处理算法,将输入的数据转换为某种构造器所需要的数据。D3有12中布局:捆绑布局、弦布局、簇布局、力布局、层次布局、直方图布局、包布局、分区布局、饼布局、堆叠布局、树布局、和矩形树布局。
     
    簇布局可以产生树状图:将树的叶子节点放在同一深度的节点-连接图。簇布局遵循方法链模式,在该模式下setter方法返回布局本身,允许使用简单语句调用多个setter。

    数据格式

    数据就需要有父子关系,如:
    1. var data={
    2. "name":"A",
    3. "children":[
    4. {
    5. "name":"B01",
    6. "children":[
    7. { "name":"C01" },
    8. { "name":"C02" },
    9. { "name":"C03" }
    10. ]
    11. },
    12. {
    13. "name":"B02",
    14. "children":[
    15. { "name":"C04" },
    16. { "name":"C05" }
    17. ]
    18. }
    19. ]
    20. };
    但是经常我们拿到的数据并不是这样的。如数据库中一般都是以如下结构存储有父子关系的记录的:
    Name Parent
    Eve  
    Cain Eve
    Seth Eve
    Enos Seth
    Noam Seth
    Abel Eve
    Awan Eve
    Enoch Awan
    Azura Eve
    因此从后端传过来的数据也就是数组对象
    070fe01e-66df-4c7c-89a0-e7ded6f32897
     这就需要我们进行转换了。d3.stratify()方法就是干这个事情的。
    1. var stratify = d3.stratify().id(function (d) {return d.name;}).parentId(function(d){return d.parent;});
    2. var rawData=[
    3. {name:"Eve",parent:""},
    4. {name:"Cain",parent:"Eve"},
    5. {name:"Seth",parent:"Eve"},
    6. {name:"Enos",parent:"Seth"},
    7. {name:"Noam",parent:"Seth"},
    8. {name:"Abel",parent:"Eve"},
    9. {name:"Awan",parent:"Eve"},
    10. {name:"Enoch",parent:"Awan"},
    11. {name:"Azura",parent:"Eve"}
    12. ];
    13. var data = stratify(rawData);
    2a58d1d6-7a17-4cdb-bdba-f4e1980ad885
     d3.stratify()返回一个层次结构,用于层次布局中的数据结构。
    其中的data元素就是层次结构的root,children是root的children,parent表示它的父元素(root没有父元素),再往下每个每个节点都是这种结构形式。

    转换数据

    这里的转换主要是为上面的data添加坐标信息。
    1. d3.cluster().size([200,300]).cluster(data);
    4f2d049c-200e-4c16-80dd-d3efc638a7da
    这是经过Cluster转换后的data,其中size函数指定的是图形的大小。而转换出的data中的每个节点坐标就是每个节点在这个size区域中应该在的位置。那现在我们的任务就是:
    ①用贝塞尔曲线连接这些位置
    ②在这些位置上画一个圆
    ③添加text
    在d3的第三版中提供了diagonal方法,可以直接用它来生成贝塞尔曲线,但是在第四版却没有这个方法了。那我们就在第四版中添加这个方法。
    1. //扩展d3
    2. (function () {
    3. function d3_functor(v) {
    4. return typeof v === "function" ? v : function() {
    5. return v;
    6. };
    7. }
    8. d3.functor = d3_functor;
    9. //贝塞尔曲线连接起始和终止点
    10. function _diagonal() {
    11. var source = function (d, i) {return d.source;},
    12. target = function (d, i) {return d.target;}, data=null,
    13. projection = function (d) {return [ d.x, d.y ];};
    14. function diagonal(d, i) {
    15. var p0 = source.call(this, d, i), p3 = target.call(this, d, i), m = (p0.y + p3.y) / 2, p = [ p0, {
    16. x: p0.x,
    17. y: m
    18. }, {
    19. x: p3.x,
    20. y: m
    21. }, p3 ];
    22. p = p.map(projection);
    23. return "M" + p[0] + "C" + p[1] + " " + p[2] + " " + p[3];
    24. }
    25. diagonal.source = function(x) {
    26. if (!arguments.length) return source;
    27. source = d3_functor(x);
    28. return diagonal;
    29. };
    30. diagonal.target = function(x) {
    31. if (!arguments.length) return target;
    32. target = d3_functor(x);
    33. return diagonal;
    34. };
    35. diagonal.projection = function(x) {
    36. if (!arguments.length) return projection;
    37. projection = x;
    38. return diagonal;
    39. };
    40. return diagonal;
    41. }
    42. var __proto__=d3.constructor.prototype;
    43. __proto__.diagonal=__proto__.diagonal || function () {
    44. return _diagonal();
    45. };
    46. }());
    那现在就添加连接线:
    1. var diagonal = d3.diagonal().projection(function (d) {return [d.y,d.x]});
    2. g.selectAll(".link")
    3. .data(data.descendants().slice(1))//过滤掉root
    4. .enter().append("path")
    5. .attr("class", "link")
    6. .attr("d", function(d) {
    7. return diagonal({source:{x:d.x,y:d.y},target:{x:d.parent.x,y:d.parent.y}});
    8. });
    添加节点
    1. var node = g.selectAll(".node")
    2. .data(data.descendants())
    3. .enter().append("g")
    4. .attr("class", function(d) { return "node" + (d.children ? " node--internal" : " node--leaf"); })
    5. .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });
    6. node.append("circle")
    7. .attr("r", 3);
    添加text
    1. node.append("text")
    2. .attr("dy", 3)
    3. .attr("x", function(d) { return d.children ? -8 : 8; })
    4. .style("text-anchor", function(d) { return d.children ? "end" : "start"; })
    5. .text(function(d) { return d.id; });
  • 相关阅读:
    Android中文API(119)——TableRow
    Android开发者指南(12) —— Android Supported Media Formats
    Android中文合集 最终版
    Android开发者指南(10) —— Android API Levels
    Android中文API(126) —— Message
    Android中文API(118)——FilterQueryProvider
    [Android]通过PhoneLookup读取所有电话号码
    Android中文API(124) —— DialerFilter
    Android开发者指南(15) —— Managing Virtual Devices
    Android中文API(127) —— MessageQueue
  • 原文地址:https://www.cnblogs.com/yaoyinglong/p/5918126.html
Copyright © 2011-2022 走看看