how to get silbling elements in sunburst - d3.js

I am new to d3.js, I am creating a visualization based on surburst. Can somebody let me know how I can get siblings elements external element in d3.js.

The main part of building the hierarchy from your data will be done by d3. Check the spec for partition.nodes(root) on how this information is put into the nodes. Basically, d3 will populate each node with a reference to its parent and its children providing all that is needed to navigate the hierarchy.
As a starting point you may have a look at this sunburst diagram. When hovering over an arc, this arc as well as its ancestors up to the root node are highlighted. The selection of nodes up the hierarchy which are to be highlighted takes place in a single function:
// Given a node in a partition layout, return an array of all of its ancestor
// nodes, highest first, but excluding the root.
function getAncestors(node) {
var path = [];
var current = node;
while (current.parent) {
path.unshift(current);
current = current.parent;
}
return path;
}
An even simpler version of this function will select the node and its siblings instead of the ancestors:
function getAncestors(node) {
return node.parent.children;
}
I adapted the above example to a plunk demonstrating how this may help solve your problem. In this plunk the hovered node and its siblings will get highlighted.

Related

Hide root node and edges in D3 v4 Tree Diagram

For the following Fiddle I'd like to hide the root node. Any help is appreciated, to view the code please view the fiddle.
I imagine I would do something like the following but I'm unsure of how/where to implement it:
if (d.depth > 0) {
...node is drawn
}
Image below:
Not drawing it is not "drawing it with zero opacity" or "hidden display". It's actually not appending the element.
Therefore, the simplest option is removing it from the data array. Just filter out the first node:
nodes = nodes.filter(function(d){
return d.depth != 0;
})
As 0 is falsy, this is the same of:
nodes = nodes.filter(function(d){
return d.depth;
})
And also filter out all links from it:
links = links.filter(function(d){
return d.depth != 1;
})
Here is your updated fiddle: https://jsfiddle.net/wa21csbc/
Also, since those elements are not painted anymore, you can move the dataviz to the left, thus occupying the empty SVG space. That space is there because we're filtering out the first node after d3.tree() calculated the positions.

Expand IndentedTree to specific element

Is there a way to programatically expand an nvd3 IndentedTree as in http://nvd3.org/examples/indentedtree.html to a specific element of the tree and add a class "active" to this element?
Thanks!
Found it.
NVD3 uses the "values" property of a tree node to mark expanded elements, and "_values" for collapsed elements.
So, if you want to expand/collapse a tree or part of it, you move the content from _values to values or vice versa. After that, call chart.update() to get a redraw.
In addition, to add a class "active" to the element containing the tree node, I used the "classes" callback of the columns array. The callback runs on the child element of the table data element:
classes: function(d) {
if (d.isSelected) {
d3.select(this.parentNode).attr("class", "active");
}
}
"isSelected" is a property I added to the current node.

d3.js How to make all the nodes collapsed in Collapsible indented Tree

I am trying to work on a sample d3 collapsible tree. mbostock’s block #1093025. Initially when the form is loaded, how do i make all the nodes collapsed initially?
The way the nodes are collapsed in this example is by removing the .children member of the data elements such that no children are drawn. You can do this statically to have everything collapsed to start with. The code would look like this.
function moveChildren(node) {
if(node.children) {
node.children.forEach(function(c) { moveChildren(c); });
node._children = node.children;
node.children = null;
}
}
moveChildren(json);
Modified example here.
You have to add a function for that in your json loading.
Check that example : http://mbostock.github.io/d3/talk/20111018/tree.html

d3 js tree layout multiple parents

I am trying to get a tree layout for a data set in which i have nodes which can have multiple parents. The links that are created in such instances have extremely large path values. is there anyway to overcome this. I can create a force layout but the tree layout feels more structured and natural to the problem in hand.
Any help is much appreciated.
If you've got multiple parents, you don't really have a tree structure. A network layout is your best option. Here is an example of a a force layout with constraints. In that case I've forced the x-values to specific values. You could do something similar using the tree level to set your x or y value.
The relevant code is:
var adjust_x = function(d) {
return x(d.time);
};
force.on("tick", function () {
link.attr("x1", function (d) {
return adjust_x(d.source);
}) // snipped remainder...

Constraining d3 force layout graphs based on node degree

I have a force layout with potentially a very large number of nodes, too large for the graph to render responsively. I was thinking that one way to improve the performance of the system was to prune the graph by eliminating nodes based on in- and out-degree when the number of nodes gets too large.
Recomputing the node and link lists is a bit of a nuisance because links are related to indexes in the node array, and so all the links would need to be re-built.
It seems more elegant to be able to mark individual nodes for exclusion (analogously to the way some nodes are fixed) and have the layout algorithm skip those nodes. This would allow me to dynamically select subsets of the graph to show, while preserving as much state for each node (e.g., position) as practical.
Has anyone implemented something like this?
UPDATE:
I tried to implement the filter suggestion, but ran into an interesting error. It appears that the filter method returns an object that does not implement enter:
qChart apply limit:2
NODES BEF: [Array[218], enter: function, exit: function, select: function, selectAll: function, attr: function…]
NODES AFT: [Array[210], select: function, selectAll: function, attr: function, classed: function, style: function…]
Uncaught TypeError: Object [object Array] has no method 'enter'
The following code is run to get from BEF to AFT:
nodeSubset = nodeSubset.filter(function(n) { return (n.sentCount() <= limit); });
UPDATE 2:
I created a jsfiddle to isolate the problem. This example implements my interpretation of ChrisJamesC's answer. When I tried to implement his suggestion directly (putting the filter after the data), the subsequent call to enter failed because the object returned by filter did not have enter defined.
The goal is to make the layout select only those nodes that have active == true, so in this example, this means that node b should be excluded.
You can use the selection.filter() option combined with the node.weight attribute.
What you would normally do is:
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("circle")
Here you can do:
var node = svg.selectAll(".node")
.data(graph.nodes)
.filter(function(d){return d.weight>3})
.enter();
You might also have to remove from drawing the links going to these nodes using the same method.
EDIT You should just filter the data you provide if you want to mark nodes as active directly in the data array (and do the same for links)
var node = svg.selectAll(".node")
.data(force.nodes().filter(function(d) { return d.active; }));
var link = svg.selectAll(".link")
.data(force.links().filter(function(d) {
var show = d.source.active && d.target.active;
if (show)
console.log("kept", d);
else
console.log("excluded", d);
return show;
}) );
Fiddle
If you want to do this by computing the weight of each node, I would still recommend you to do this before passing the nodes and links to the graph and mark nodes as active or not following a specific criteria, then filter the links according to active nodes. Otherwise you would have to load the whole force directed layout only to get the weight to then filter the data to re-load the force directed graph.

Resources