0

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;
            });
        };
    };
Community
  • 1
  • 1
kellyh
  • 113
  • 2
  • 8
  • Have you seen [this question](http://stackoverflow.com/questions/8739072/highlight-selected-node-its-links-and-its-children-in-a-d3-force-directed-grap)? The force layout puts all the information you need into the data once you run it. – Lars Kotthoff Jul 11 '14 at 17:49
  • @Lars Kotthoff I did, but I couldn't get it to work. When I copy what mbostock wrote, the console in Chrome returns `Uncaught ReferenceError: d is not defined` at `return neighboring(d, o) ? 1 : opacity;` (his last code snippet), and when I add `d` to the parameters, all of the nodes have their opacity affected. – kellyh Jul 11 '14 at 18:02
  • Have you tried starting from the code there with your data? It looks like you should be able to use your data format directly. – Lars Kotthoff Jul 11 '14 at 18:04
  • @Lars Kotthoff What do you mean by "starting from the code there"? I've tried moving the code to a few different places, under the lines where links and nodes are defined, and I get the same result. Do you mean that I need to call the data in a different way? I'll update my question with what my code looks like now. – kellyh Jul 11 '14 at 18:18
  • No, I mean start with the working example and plug your data in. – Lars Kotthoff Jul 11 '14 at 18:27
  • Oh yeah, that makes sense. I'll see if I can get that to work. – kellyh Jul 11 '14 at 18:41
  • Oh my gosh, I finally figured it out. The key was to put the code after the force function is called. I thought I had tried that before but apparently not. Thanks for your help! – kellyh Jul 11 '14 at 19:46

0 Answers0