【问题标题】:Create tree hierarchy from csv in d3.js在 d3.js 中从 csv 创建树层次结构
【发布时间】:2012-08-16 02:09:44
【问题描述】:

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

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

我的 csv 文件如下所示:

组流派、基本流派、值 地图,地图集(地理),10 目录,拍卖目录,28 没有更大的群体,学术论文,451 没有更大的团体,账簿,1 没有更大的组,Acrostics,56 没有更大的组,地址,62 没有更大的群体,广告,790 没有更大的群体,寓言,35 没有更大的组,年历,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]}
}

【问题讨论】:

标签: javascript csv charts d3.js


【解决方案1】:

第一个问题看起来是您将函数传递给entries,而不是根据the docs 所期望的数组。尝试将参数 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 所期望的树结构,请参阅文档here。您想使用 makeTree 方法创建如下对象。

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

基本上,您需要基于groupGenrebasicGenre 创建一棵类似heiarchary 的树,所有这些都位于某个包罗万象的根节点下。

您可能还想查看this SO question,因为它处理创建适当的对象以传递给tree.nodes

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

【讨论】:

  • 感谢您的快速回复!您的建议消除了错误消息,但仍然没有显示可视化。我查看了控制台,它看起来不像正在加载数据。还有其他想法吗?
  • 我已经尝试调整该代码(结果如上)。它仍然没有加载数据,我不知道为什么。也许我应该提到,数据列之间没有共享值。 groupGenre 是与 basicGenre 不同的字符串发送方式,因此基于共享值的索引是行不通的。 . .非常感谢您的宝贵时间!
  • 我添加了一个 JSFiddle,其中包含正在运行的更新代码。不完全确定您的问题是什么,因为我看不到您的所有数据。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-28
  • 2018-10-07
  • 2013-04-16
相关资源
最近更新 更多