Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

d3 js Hierarchical edge bundling Data Format

I am trying to visualize url to targetURL using hierarchical edge bundling. What type of relation is required between these columns?

Here is the sample:

enter image description here

Here is my code.

I am getting an error as

TypeError: node.parent.children is undefined
like image 986
Musakkhir Sayyed Avatar asked Feb 13 '15 06:02

Musakkhir Sayyed


People also ask

What is hierarchical edge bundling?

Definition. Hierarchical Edge Bundling allows to visualize adjacency relations between entities organized in a hierarchy . The idea is to bundle the adjacency edges together to decrease the clutter usually observed in complex networks.

What is force directed edge bundling?

Force Directed Edge Bundling (FDEB) is an edge layout algorithm. Gephi already has node layouts, which are placing the nodes (usually using force-directed algorithms).


1 Answers

As described in the docs for the Bundle Layout, the layout is applied to an array of links, each of which has a source and target property pointing to the nodes at the two ends of the link. In addition, these two nodes each need a parent attribute that points to the parent node in the hierarchy.

This data is (ideally) coming from the Cluster Layout, which positions the nodes before the links are bundled. The cluster layout will produce the data needed by the bundle layout (the cluster.nodes function returns nodes with more than just the parent property and cluster.links returns the links with source and target). This means you just need to make the cluster layout happy and you'll be fine.

There are a few problems with your code as written. In general, rather than modifying your data to fit a visualization you copy-pasted from an example, it's better practice to update the various D3 accessors to use the format of the data you have. That's why they're there.

The visualization you copied from is more consistent in its data cleanup, so you've introduced some issues there. We'll just work around them, but you should probably spend some time getting it right. The first issue is the error you noted: TypeError: node.parent.children is undefined. This is because you're getting to line 1483 in find and trying to add a child to a list that doesn't exist. We can go ahead and just power through here by adding a specific check for this (though, as mentioned, you should actually just clean up how this is handled):

if (typeof d.children === 'undefined') {
    d.children = []
}

Also you're adding a root node with the name of the empty string. This is because on line 1481 you call find regardless of the length of the substring. By checking the return value of the call to lastIndexOf you will know whether the node has a parent or not, and in the latter case, set parent to null (as the documentation states, parent - the parent node, or null for the root).

Once we get past these issues, you'll start seeing a TypeError: n is undefined. This is because your data is incomplete: you have references to nodes that don't exist, so on line 1510 you add a link that doesn't have a target property, so when you try to bundle the links the layout fails. This one can be ignored for the time being by only adding links to nodes that exist, but again, you probably should actually fix this rather than letting it be.

if (i in map) {
    imports.push({ source: map[d.name], target: map[i] });
}

The long and short of it is, read the docs, use your debugger, and don't copy-paste code without taking the time to understand it.

jsfiddle

like image 180
couchand Avatar answered Sep 28 '22 01:09

couchand