从d3.js中的csv创建树层次结构

Create tree hierarchy from csv in d3.js

本文关键字:创建 层次结构 csv 中的 d3 js      更新时间:2023-09-26

我读过很多关于类似主题的问题,但似乎没有一个答案适用于我的用例(或者我真的很困惑)。

我有一个来自数据库的csv文件转储,我想使用这里的树状图示例来显示数据的层次结构http://mbostock.github.com/d3/ex/cluster.html

我的csv文件如下所示:

groupGenre,basicGenre,value地图,地图册(地理),10目录,拍卖目录,28没有更大的群体,学术论文,451没有更大的组,账簿,1没有更大的团体,Acrotics,56没有更大的组,地址,62没有更大的群组,广告,790没有更大的团体,Allegories,35没有更大的团体,Almanacs,3401没有更大的组,字母表,100没有更大的组,Anagrams,4没有更大的群体,选集,133没有更大的群体,反奴隶制文学,1

其中value是该类型图书的出版数量。

以下是我根据以下建议改编并修改的代码它也可以在http://dev.stg.brown.edu/projects/Egan/Vis/tree/tree.html

var width = 960,
    height = 2000;
var tree = d3.layout.tree()
    .size([height, width - 160]);
var diagonal = d3.svg.diagonal()
    .projection(function(d) { return [d.y, d.x]; });
var vis = d3.select("#chart").append("svg")
    .attr("width", width)
    .attr("height", height)
  .append("g")
    .attr("transform", "translate(40, 0)");
d3.csv("../data/genreNested.csv", function(csv) {
  var nodes = tree.nodes(makeTree(csv));
  var link = vis.selectAll("path.link")
      .data(tree.links(nodes))
    .enter().append("path")
      .attr("class", "link")
      .attr("d", diagonal);
  var node = vis.selectAll("g.node")
      .data(nodes)
    .enter().append("g")
      .attr("class", "node")
      .attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; })
  node.append("circle")
      .attr("r", 4.5);
  node.append("text")
      .attr("dx", function(d) { return d.values ? -8 : 8; })
      .attr("dy", 3)
      .attr("text-anchor", function(d) { return d.values ? "end" : "start"; })
      .text(function(d) { return d.key; });
});
//NEW Function to Build Tree from CSV data
function makeTree(nodes) {
    var nodeByGenre = {};
    //index nodes by genre in case they are out of order
    nodes.forEach(function(d) {
        nodeByGenre[d.basicGenre] = d;
    });
    //Lazily compute children.
    nodes.forEach(function(d) {
        var groupGenre = nodeByGenre[d.groupGenre];
        if (groupGenre.children) groupGenre.children.push(d);
        else groupGenre.children = [d]
    });
    return {"name": "genres", "children": nodes[0]}
}

第一个问题似乎是将一个函数传递给entries,而不是根据文档所期望的数组。请尝试将参数csv传递给entries方法。

function makeTree(csv) {
   var data = d3.nest()
        .key(function(d) {return d.genre; })
        .key(function(d) {return d.groupGenre; })
        .entries(csv);
   return data;
}

第二个问题是makeTree函数没有返回tree.nodes所期望的树结构,请参阅此处的文档。您希望使用makeTree方法创建如下对象。

 var root = 
 {
 "basicGenre": "Maps",
 "value" : 5,
 "children": [
  {
   "basicGenre": "Atlases (Geographic)",
   "value" : 10
   "children": [
    {
     "basicGenre": "Atlases 1",
     "children": []
    },
    {
     "basicGenre": "Atlases 2",
     "children": []
    }
   ]
  }
 ]
}

基本上,您需要创建一个基于groupGenrebasicGenre的树状高度库,所有这些都位于某个包罗万象的根节点之下。

您可能还想看看这个SO问题,因为它涉及创建一个适当的对象来传递给tree.nodes

这是一个使用您更新的代码的工作JSFiddle