Interactive Brain Graph Visualization (7): force-directed layout with centrality information

Interactive Brain Graph Visualization (7): force-directed layout with centrality information

Note: all the codes are available at my github https://github.com/astro1860/visualization_project/tree/master/brain_info  To  run it, go to /brain_fisheye folder and copy the .json and .ipynb file and put them into the same folder.

Since we have calculated centrality informations in Interactive Brain Graph Visualization(4): From fMRI to json file, we would like to display the information in the visualization. Moreover, as the value of centrality represent the importance of a node in the network, we also need to perform a ranking of this information. In the following, we will go through the process of how to construct an integrated interface. To look at the demo:

ranking

We divided the interface into three column, the left column can show the value of eigenvector & degree of a node and also a selector of ranking by eigenvector centrality or degree centrality, the middle is a visualization of the network by position, while the right column is the ranking from largest to smallest. In this case, if we think twice, we should define some functions when we triggered an mouseover and mouseout event. Moreover, a function of extracting informations of centrality and compared the values to perform a ranking should also be designed.

- Event upon mouseover and mouseout

1. show node detail

When mouse is upon a node, we have these three triggered events:

a. the left column should display the value of eigenvector and degrees

 svg.selectAll(".nodetext").remove();
labels = [];
labels.push("" + d['name'],
"Eigenvector: " + d['eigen_cent'].toFixed(4),
"Degree: " + d['degree_cent'].toFixed(4))
setDetailLabels(labels);

b. if the node is in the ranking list, the name of the node in the right column should be highlighted.

d3.select(".id" + d.id)
.attr("fill", "#F00");

c. The node in the visualization network should specified with highlight effect.

 d3.select("." + d.name).selectAll("circle")
.transition()
.duration(100)
.attr("r", 20)
.attr("fill-opacity", 0.4);

Thus, we did a showNodeDetails function combining these three parts and call it upon a mouseover. The overall function is as follows:

function showNodeDetails() {
return function(d, i) {
svg.selectAll(".nodetext").remove();
labels = [];
labels.push("" + d['name'],
"Eigenvector: " + d['eigen_cent'].toFixed(4),
"Degree: " + d['degree_cent'].toFixed(4))
setDetailLabels(labels);
d3.select("." + d.name).selectAll("circle")
.transition()
.duration(100)
.attr("r", 20)
.attr("fill-opacity", 0.4);
d3.select("." + d.name).selectAll("text")
.attr("fill", "white")
.style("font", "20px sans-serif");
d3.select(".id" + d.id)
.attr("fill", "white");
}
}


2. remove node detail

Similarly, we designed a removeNodeDetails function when mouse is off a node.

a. reset the detail of labels(centrality)

function resetDetailLabels() {
svg.selectAll(".nodetext").remove();
labels = ["Hover on a circle", "to see details", "Eigenvector: ", "Degree: "];
setDetailLabels(labels);
}

b. nodes recovered the original effect

d3.select("." + d.name).selectAll("circle")
.attr("r", 10)
.attr("fill-opacity", 1)
.attr("class", "circle");

c. ranking text recovered

d3.select(".id" + d.id)
.attr("fill", "#000");

The overall function is as follows:

function removeNodeDetails() {
return function(d, i) {
resetDetailLabels();
d3.select("." + d.name).selectAll("circle")
.transition()
.duration(100)
.attr("r", 10)
.attr("fill-opacity", 1)
.attr("class", "circle");
d3.select("." + d.name).selectAll("text")
.attr("fill", "#000")
.style("font", "10px sans-serif");
d3.select(".id" + d.id)
.attr("fill", "#000");
}
}

Thus, when we construct the node visualization, we should call the shownodetail and removenodedetail functions as follows:

var node = graph.selectAll(".node")
.data(json.nodes)
.enter().append("g")
.attr("class", function(d) { return "node " + d['name']; })
.on("mouseover", showNodeDetails())
.on("mouseout", removeNodeDetails())
.call(force.drag);

- Construct ranking

We designed a function of drawRanking. Firstly we bound the data of node(with information of brain areas’ names). Then we compared the value of d[metric], representing either values of eigenvector centrality or value of degree centrality. In the end, we also called the showNodeDetails function upon mouseover and removeNodeDettails upon mouseout.

function drawRanking(data) {
svg.selectAll(".rankingtext")
.data(data.nodes)
.enter().append("svg:text")
.sort(function (a, b) { return compareVals(a[metric], b[metric]); })
.attr("class", function(d) { return "rankingtext id" + d['id'];} )
.text(function(d, i) { return d['name']; })
.attr("x", w + 63)
.attr("y", function(d, i) { return i * 25 + 63; })
.on("mouseover", showNodeDetails())
.on("mouseout", removeNodeDetails());
}

 

Leave a Reply