Working in D3.js, I'd like to select all the elements that match a selector except for the current element.
The reason is that I'd like to mouseover a circle, and have all the other circles with the same class turn light blue, but the current circle to stay the same shade.
This is what I have currently:
vis.selectAll('circle.prospect')
.on("mouseover", function(d) {
console.log(d);
d3.selectAll('circle.prospect').transition().style('opacity','0.5');
d3.select(this).attr('opacity','1.0');
});
In jQuery, I could do this using not
. Anyone know the D3.js equivalent?
enter() function creates the initial join of the data with our DOM elements. Thus selecting only the elements that were not in the DOM yet. merge() function will select the DOM elements that did not exist in the DOM before and the ones that did. exit() function will select the DOM elements that are left from the join.
selectAll() function in D3. js is used to select all the element that matches the specified selector string. Syntax: d3.selectAll("element") Parameters: This function accepts single parameter HTML tag as a parameter. Return Value: This function returns the selected elements.
d3 does not directly use jQuery, so the jQuery library of functions is not directly accessible in d3 by default.
If your elements have an unique CSS-accessible identifiers, you can use the :not()
selector. Some potential examples:
d3.selectAll("circle.prospect:not(#" + this.id + ")");
d3.selectAll("circle.prospect:not(." + someUniqueClassFrom(d) + ")");
d3.selectAll("circle.prospect:not([uniqueAttr=" + this.getAttribute('uniqueAttr') + "])");
The reason d3.selectAll('circle.prospect:not(this)')
doesn't work is because it's just literally saying to filter out any <this></this>
elements — which is obviously not your intent, and since it's already selecting only <circle></circle>
elements would have no effect regardless.
Even if you don't generally apply some unique DOM attribute, there's no reason you couldn't set one temporarily:
vis.selectAll('circle.prospect')
.on("mouseover", function(d) {
this.id = 'temp-' + Math.random();
d3.selectAll('circle.prospect:not(#' + this.id + ')').transition().style('opacity','0.5');
d3.select(this).attr('opacity','1.0');
this.id = '';
});
That said, however, if your elements don't already have an ID assigned already, I think Ian Roberts' solution is probably what I would do instead of this temporary identifier hack.
You can filter
a selection:
vis.selectAll('circle.prospect')
.on("mouseover", function(d) {
console.log(d);
var circleUnderMouse = this;
d3.selectAll('circle.prospect').filter(function(d,i) {
return (this !== circleUnderMouse);
}).transition().style('opacity','0.5');
d3.select(this).attr('opacity','1.0');
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With