I'm aware this question has been asked several times, but it seems like the way I have my data set up is making this much more difficult than it should be. I'm trying to select nodes neighboring the node that the mouse hovers over so that I can lower the opacity of the non-neighboring nodes. I managed to do this to the links without any problem.
I've already tried re-writing Mike Bostock's solution here several times, but nothing works. At most, I can get every node to fade out when I hover over, which isn't helpful. This comment in a Google group makes me think that I need to have a section in my node data that tells what other nodes a node is connected to. My JSONs current look like this:
Nodes:
[
{
"id":0,
"name":"Test Writer 1"
},
{
"id":1,
"name":"Test Writer 2"
}
]
Links:
[
{
"relationship":"Teacher/student",
"source":73, //These numbers align to the ids and index of the nodes
"target":74
},
{
"relationship":"Teacher/student",
"source":73,
"target":75
}
]
The simplest solution, I think, would be to add link data to the node JSON, like the Google group comment suggested. However, I don't think I can do that with the way the database I'm drawing from is set up (I am really bad at SQL though, so I'm not positive that's true.). I also don't have permission to edit the database; I can only select.
Here's the current state of the adjacent node code, which doesn't really do anything at all:
var hash_lookup = [];
nodesData.forEach(function(d, i) {
hash_lookup[d.id] = d;
});
linksData.forEach(function(d, i) {
d.source = hash_lookup[d.source];
d.target = hash_lookup[d.target];
});
function neighboring(a, b) {
return hash_lookup[a.index + "," + b.index];
}
And here's a fiddle.
I'm new to coding, so I'm not sure if I'm making a stupid mistake somewhere. I've been working on this for the better part of a week and haven't made any progress on my own, though. Any help is appreciated.
Edit:
Here's another version of the code, adapted from Mike Bostock's solution:
var linkedByIndex = {};
linksData.forEach(function(d) {
linkedByIndex[d.source.index + "," + d.target.index] = 1;
});
function neighboring(a, b) {
return linkedByIndex[a.index + "," + b.index];
}
node.on("mouseover.four", function () {
node.style("opacity", function(d,o) {
return neighboring(d, o) ? 1 : 0.3;
});
});
Edit 2:
Here's the solution. You have to put the code after the force function is called or it won't work:
force
.nodes(nodesData)
.links(linksData)
.on("tick", tick)
.start();
node.on("mouseover", fade(.1))
.on("mouseout", fade(1));
var linkedByIndex = {};
linksData.forEach(function(d) {
linkedByIndex[d.source.index + "," + d.target.index] = 1;
});
function isConnected(a, b) {
return linkedByIndex[a.index + "," + b.index] || linkedByIndex[b.index + "," + a.index] || a.index == b.index;
}
function tick() {
//code code code//
}
function fade(opacity) {
return function(d) {
node.style("stroke-opacity", function(o) {
thisOpacity = isConnected(d, o) ? 1 : opacity;
this.setAttribute('fill-opacity', thisOpacity);
return thisOpacity;
});
link.style("stroke-opacity", opacity).style("stroke-opacity", function(o) {
return o.source === d || o.target === d ? 1 : opacity;
});
};
};