D3.js如何使用嵌入式非分层数据的分层布局

时间:2014-08-02 13:49:01

标签: javascript d3.js

我正在尝试使用嵌入数据调整mike bostock的树形布局示例 http://bl.ocks.org/mbostock/4339083 。嵌入数据应该是非分层.csv文件的副本:

  

getData2()   从“预先”获取数据标记和嵌套它。   但由于某种原因,它不起作用。

     

getData3()由于某种原因也不起作用,我使用一个非嵌套数组的变量然后嵌套它。

如何更改getData2()和getData3()方法以使其正常工作?

这是我的html文件:

<!DOCTYPE html>
<html>
   <pre id="csvdata">
   Year,Make,Model,Length
    1997,BMW,E350,2.34
    1997,BMW,E350,2.34
    2000,Mercury,Cougar,2.38
    </pre>

  <head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
    <link type="text/css" rel="stylesheet" href="style.css"/>
    <script type="text/javascript" src="../lib/d3.min.js"></script>
    <!--<script type="text/javascript" src="d3/d3.layout.js"></script> -->
    <style type="text/css">
    .node circle {
      cursor: pointer;
      fill: #fff;
      stroke: steelblue;
      stroke-width: 1.5px;
    }

    .node text {
      font-size: 11px;
    }

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

    #csvdata {
        display: none;
    }
    </style>
  </head>
  <body>
    <div id="body">
      <div id="footer">
        d3.layout.tree
        <div class="hint">click or option-click to expand or collapse</div>
      </div>
    </div>
    <script type="text/javascript">

    var margin = {top: 20, right: 120, bottom: 20, left: 120},
    width = 960 - margin.right - margin.left,
    height = 800 - margin.top - margin.bottom;

var i = 0,
    duration = 750,
    root;

var tree = d3.layout.tree()
    .size([height, width]);

var diagonal = d3.svg.diagonal()
    .projection(function(d) { return [d.y, d.x]; });

var svg = d3.select("body").append("svg")
    .attr("width", width + margin.right + margin.left)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    // root = getData();  // that works
    // root = getData2(); // that doesn't work
  root = getData3(); // that doesn't work either
  console.log(root);
  root.x0 = height / 2;
  root.y0 = 0;

  function collapse(d) {
    if (d.children) {
      d._children = d.children;
      d._children.forEach(collapse);
      d.children = null;
    }
  }

  root.children.forEach(collapse);
  update(root);


d3.select(self.frameElement).style("height", "800px");

function update(source) {

  // Compute the new tree layout.
  var nodes = tree.nodes(root).reverse(),
      links = tree.links(nodes);

  // Normalize for fixed-depth.
  nodes.forEach(function(d) { d.y = d.depth * 180; });

  // Update the nodes…
  var node = svg.selectAll("g.node")
      .data(nodes, function(d) { return d.id || (d.id = ++i); });

  // Enter any new nodes at the parent's previous position.
  var nodeEnter = node.enter().append("g")
      .attr("class", "node")
      .attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
      .on("click", click);

  nodeEnter.append("circle")
      .attr("r", 1e-6)
      .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });

  nodeEnter.append("text")
      .attr("x", function(d) { return d.children || d._children ? -10 : 10; })
      .attr("dy", ".35em")
      .attr("text-anchor", function(d) { return d.children || d._children ? "end" : "start"; })
      .text(function(d) { return d.name; })
      .style("fill-opacity", 1e-6);

  // Transition nodes to their new position.
  var nodeUpdate = node.transition()
      .duration(duration)
      .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });

  nodeUpdate.select("circle")
      .attr("r", 4.5)
      .style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });

  nodeUpdate.select("text")
      .style("fill-opacity", 1);

  // Transition exiting nodes to the parent's new position.
  var nodeExit = node.exit().transition()
      .duration(duration)
      .attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; })
      .remove();

  nodeExit.select("circle")
      .attr("r", 1e-6);

  nodeExit.select("text")
      .style("fill-opacity", 1e-6);

  // Update the links…
  var link = svg.selectAll("path.link")
      .data(links, function(d) { return d.target.id; });

  // Enter any new links at the parent's previous position.
  link.enter().insert("path", "g")
      .attr("class", "link")
      .attr("d", function(d) {
        var o = {x: source.x0, y: source.y0};
        return diagonal({source: o, target: o});
      });

  // Transition links to their new position.
  link.transition()
      .duration(duration)
      .attr("d", diagonal);

  // Transition exiting nodes to the parent's new position.
  link.exit().transition()
      .duration(duration)
      .attr("d", function(d) {
        var o = {x: source.x, y: source.y};
        return diagonal({source: o, target: o});
      })
      .remove();

  // Stash the old positions for transition.
  nodes.forEach(function(d) {
    d.x0 = d.x;
    d.y0 = d.y;
  });
}

// Toggle children on click.
function click(d) {
  if (d.children) {
    d._children = d.children;
    d.children = null;
  } else {
    d.children = d._children;
    d._children = null;
  }
  update(d);
}

function getData2() {
    csv_data = d3.select("#csvdata");
    var nested_data = d3.nest()
        .key(function(d) { return d.Make; })
        .entries(csv_data);
    return nested_data; 
}

function getData3() {
    var yields = [{yield: 27.00, variety: "Manchuria", year: 1931, site: "University Farm"},
              {yield: 48.87, variety: "Manchuria", year: 1931, site: "Waseca"},
              {yield: 27.43, variety: "Manchuria", year: 1931, site: "Morris"}];
    var nest = d3.nest()
        .key(function(d) { return d.year; })
        .key(function(d) { return d.variety; })
        .entries(yields);
    return nest;        
}

function getData() {
return{
        "name": "flare",
            "children": [{
            "name": "analytics",
                "children": [{
                "name": "cluster",
                    "children": [{
                    "name": "AgglomerativeCluster",
                    "size": 3938
                }, {
                    "name": "CommunityStructure",
                    "size": 3812
                }, {
                    "name": "HierarchicalCluster",
                    "size": 6714
                }, {
                    "name": "MergeEdge",
                    "size": 743
                }]
            }, {
                "name": "graph",
                    "children": [{
                    "name": "BetweennessCentrality",
                    "size": 3534
                }, {
                    "name": "LinkDistance",
                    "size": 5731
                }, {
                    "name": "MaxFlowMinCut",
                    "size": 7840
                }, {
                    "name": "ShortestPaths",
                    "size": 5914
                }, {
                    "name": "SpanningTree",
                    "size": 3416
                }]
            }, {
                "name": "optimization",
                    "children": [{
                    "name": "AspectRatioBanker",
                    "size": 7074
                }]
            }]
        }, {
            "name": "animate",
                "children": [{
                "name": "interpolate",
                    "children": [{
                    "name": "ArrayInterpolator",
                    "size": 1983
                }, {
                    "name": "ColorInterpolator",
                    "size": 2047
                }, {
                    "name": "DateInterpolator",
                    "size": 1375
                }, {
                    "name": "Interpolator",
                    "size": 8746
                }, {
                    "name": "MatrixInterpolator",
                    "size": 2202
                }, {
                    "name": "NumberInterpolator",
                    "size": 1382
                }, {
                    "name": "ObjectInterpolator",
                    "size": 1629
                }, {
                    "name": "PointInterpolator",
                    "size": 1675
                }, {
                    "name": "RectangleInterpolator",
                    "size": 2042
                }]
            }, {
                "name": "ISchedulable",
                "size": 1041
            }, {
                "name": "Parallel",
                "size": 5176
            }, {
                "name": "Pause",
                "size": 449
            }, {
                "name": "Scheduler",
                "size": 5593
            }, {
                "name": "Sequence",
                "size": 5534
            }, {
                "name": "Transition",
                "size": 9201
            }, {
                "name": "Transitioner",
                "size": 19975
            }, {
                "name": "TransitionEvent",
                "size": 1116
            }, {
                "name": "Tween",
                "size": 6006
            }]
        }, {
            "name": "data",
                "children": [{
                "name": "converters",
                    "children": [{
                    "name": "Converters",
                    "size": 721
                }, {
                    "name": "DelimitedTextConverter",
                    "size": 4294
                }, {
                    "name": "GraphMLConverter",
                    "size": 9800
                }, {
                    "name": "IDataConverter",
                    "size": 1314
                }, {
                    "name": "JSONConverter",
                    "size": 2220
                }]
            }, {
                "name": "DataField",
                "size": 1759
            }, {
                "name": "DataSchema",
                "size": 2165
            }, {
                "name": "DataSet",
                "size": 586
            }, {
                "name": "DataSource",
                "size": 3331
            }, {
                "name": "DataTable",
                "size": 772
            }, {
                "name": "DataUtil",
                "size": 3322
            }]
        }]
    }
}
    </script>
  </body>
</html>

1 个答案:

答案 0 :(得分:0)

在getData2()函数中,抓取csv_data是错误的。你应该替换

csv_data = d3.select("#csvdata"); // won't work

csv_data = d3.csv.parse(d3.select("pre#csvdata").text()); // works

您可以阅读有关选择的更多信息here 并使用d3 there解析csv数据。

d3.nest()使用&#39;键&#39;生成嵌套数组。和#&#39;价值观&#39;属性。但这棵树使用的是“孩子们”。和&#39; name&#39;默认情况下。 因此,为了将其转换为&#39; name&#39;和孩子们&#39;:  1.您需要指定树的子访问器功能 tree.children()  2.更改节点的文本属性,如下所示:

.text(function(d) { return d.key; })

工作演示为here