Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert to D3's JSON format?

While following numerous D3 examples, data usually gets formatted in the format given in flare.json:

{  "name": "flare",  "children": [   {    "name": "analytics",    "children": [     {      "name": "cluster",      "children": [       {"name": "AgglomerativeCluster", "size": 3938},       : 

I have an adjacency list as follows:

A1 A2 A2 A3 A2 A4 

which I want to convert to the above format. Currently, I am doing this on the server-side but is there a way to achieve this using d3's functions? I found one here, but the approach seems to require modification of the d3 core library which I am not in favor due to maintainability. Any suggestions?

like image 918
Legend Avatar asked Jun 18 '12 17:06

Legend


People also ask

How to read JSON using d3?

js json() Function. The d3. json() function is used to fetch the JSON file. If this function got an init parameter, then this is called along with the fetch operation.

What does d3 JSON return?

The function d3. json() is an asynchronous function that directly returns (with an undefined value I assume). Only when the data is received from the backend, the callback function you passed to it will be called.

How to load a csv file into d3?

We can load a csv file or csv data using d3. csv() method.

What is d3 csv?

Wiki ▸ [[API Reference]] ▸ CSV. D3 provides built-in support for parsing comma-separated values, tab-separated values and arbitrary delimiter-separated values. These tabular formats are popular with spreadsheet programs such as Microsoft Excel.


2 Answers

There's no prescribed format, as you can usually redefine your data through various accessor functions (such as hierarchy.children) and array.map. But the format you quoted is probably the most convenient representation for trees because it works with the default accessors.

The first question is whether you intend to display a graph or a tree. For graphs, the data structure is defined in terms of nodes and links. For trees, the input to the layout is the root node, which may have an array of child nodes, and whose leaf nodes have an associated value.

If you want to display a graph, and all you have is a list of edges, then you'll want to iterate over the edges in order to produce an array of nodes and an array of links. Say you had a file called "graph.csv":

source,target A1,A2 A2,A3 A2,A4 

You could load this file using d3.csv and then produce an array of nodes and links:

d3.csv("graph.csv", function(links) {   var nodesByName = {};    // Create nodes for each unique source and target.   links.forEach(function(link) {     link.source = nodeByName(link.source);     link.target = nodeByName(link.target);   });    // Extract the array of nodes from the map by name.   var nodes = d3.values(nodeByName);    function nodeByName(name) {     return nodesByName[name] || (nodesByName[name] = {name: name});   } }); 

You can then pass these nodes and links to the force layout to visualize the graph:

  • http://bl.ocks.org/2949937

If you want to produce a tree instead, then you'll need to do a slightly different form of data transformation to accumulate the child nodes for each parent.

d3.csv("graph.csv", function(links) {   var nodesByName = {};    // Create nodes for each unique source and target.   links.forEach(function(link) {     var parent = link.source = nodeByName(link.source),         child = link.target = nodeByName(link.target);     if (parent.children) parent.children.push(child);     else parent.children = [child];   });    // Extract the root node.   var root = links[0].source;    function nodeByName(name) {     return nodesByName[name] || (nodesByName[name] = {name: name});   } }); 

Like so:

  • http://bl.ocks.org/2949981
like image 74
mbostock Avatar answered Oct 04 '22 14:10

mbostock


D3 doesn't require a specific format. It all depends on your application. You can certainly convert an adjacency list to the format used in flare.json, but this again would be application-specific code. In general, you can't do that as adjacency lists as such don't have "head" or "root" elements you would need to build a tree. In addition, you would need to handle cycles, orphans etc. separately.

Given that you're currently doing the conversion on the server side, I'd be tempted to say that "if it ain't broken, don't fix it" ;)

like image 36
Lars Kotthoff Avatar answered Oct 04 '22 14:10

Lars Kotthoff