Creating a tree hierarchy from csv to d3.js

I read a series of questions on similar topics, but none of the answers seem to work for my use case (or I'm just very confused).

I have a dump of a csv file from a database and I want to show the data hierarchy using the Dendrogram example found here http://mbostock.github.com/d3/ex/cluster.html

My csv file is as follows:

  groupGenre, basicGenre, value
 Maps, Atlases (Geographic), 10
 Catalogs, Auction catalogs, 28
 No larger group, Academic dissertations, 451
 No larger group, Account books, 1
 No larger group, Acrostics, 56
 No larger group, Addresses, 62
 No larger group, Advertisements, 790
 No larger group, Allegories, 35
 No larger group, Almanacs, 3401
 No larger group, Alphabets, 100
 No larger group, Anagrams, 4
 No larger group, Anthologies, 133
 No larger group, Anti-slavery literature, 1

where the value is the number of books published in this genre.

Here is the code that I adapted and is now reworked based on the suggestions below. It can also be found at 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 [dy, dx]; }); 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(" + dy + "," + dx + ")"; }) 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]} } 
+4
source share
1 answer

The first problem is that you are passing the entries function instead of the array that it expects from docs . Try passing the csv parameter instead of entries .

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

The second problem is that your makeTree function makeTree not return a tree structure, as expected by tree.nodes , see docs here . You want to create an object as follows using the makeTree method.

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

Basically, you need to create a tree similar to heiarchary, based on groupGenre and basicGenre all under one of all spanning root nodes.

You can also look at this SO question as it deals with creating the appropriate object to go to tree.nodes .

Here is a valid JSFiddle using the updated code.

+2
source

All Articles