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

Jea*_*uer 5 javascript csv charts d3.js

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

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

我的 csv 文件如下所示:

组流派、基本流派、值
地图,地图册(地理),10
目录、拍卖目录、28
没有更大的群体,学术论文,451
没有更大的组,账簿,1
没有更大的团体,离合诗,56
没有更大的组,地址,62
没有更大的团体,广告,790
没有更大的群体,寓言,35
没有更大的组,年鉴,3401
没有更大的组,字母,100
没有更大的群体,字谜,4
没有更大的团体,选集,133
没有更大的团体,反奴隶制文学,1

其中价值是该类型出版的书籍数量。

这是我根据下面的建议改编并修改的代码,也可以在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]}
}
Run Code Online (Sandbox Code Playgroud)

Bra*_*sen 4

第一个问题似乎是您正在传递一个函数而不是按照文档entries所期望的数组。尝试将参数传递给该方法。csventries

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

   return data;
}
Run Code Online (Sandbox Code Playgroud)

第二个问题是您的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": []
    }
   ]
  }
 ]
}
Run Code Online (Sandbox Code Playgroud)

基本上,您需要创建一个类似于层次结构的树,其基础是某些包含所有根节点的所有内容groupGenrebasicGenre

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

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