Instead of using this
, you can use just the datum
argument.
When you hover over a node...
the specified listener will be evaluated for each selected element, being passed the current datum (d), the current index (i), and the current group (nodes), with this as the current DOM element.
So, to find all other elements with the same data, you can use only the first argument, which contains the datum, not this, which is the DOM element.
This is a demo to show you. We have a dataset with positions and a key named type
:
var data = [{type: "foo", x: 30, y: 90},
{type: "foo", x: 10, y: 50},
//etc...
];
Hovering over a circle, we will select all other circles that don't share the same value for the type
property, making them disappear:
circles.on("mouseover", function(d) {
var filtered = circles.filter(function(e) {
return e.type != d.type
});
filtered.attr("opacity", 0);
})
Here is the demo:
var svg = d3.select("svg");
var data = [{
type: "foo",
x: 30,
y: 90
}, {
type: "foo",
x: 10,
y: 50
}, {
type: "foo",
x: 220,
y: 130
}, {
type: "baz",
x: 40,
y: 40
}, {
type: "bar",
x: 170,
y: 20
}, {
type: "baz",
x: 220,
y: 110
}, {
type: "bar",
x: 130,
y: 120
}, {
type: "foo",
x: 150,
y: 50
}, {
type: "baz",
x: 30,
y: 110
}, {
type: "foo",
x: 100,
y: 220
}];
var color = d3.scaleOrdinal()
.domain(["foo", "bar", "baz"])
.range(["teal", "brown", "gold"]);
var circles = svg.selectAll(".circles")
.data(data)
.enter()
.append("circle")
.attr("cx", d => d.x)
.attr("cy", d => d.y)
.attr("r", 8)
.attr("fill", d => color(d.type));
circles.on("mouseover", function(d) {
var filtered = circles.filter(function(e) {
return e.type != d.type
});
filtered.attr("opacity", 0);
}).on("mouseout", function() {
circles.attr("opacity", 1)
})
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>