Reputation: 787
I am working with D3.js and actually I am trying to select all elements with a certain class except one on the particular event "mouseover". I tried different kind of solutions, but no one worked or just partially.
This is my first solution:
.on("mouseover",
function(d) {
d3.select(this)
.style("stroke-width", "4px");
var selectedMethod = document.getElementById(d.name + "-line");
var notSelectedMethods = $(".method").not(selectedMethod);
d3.selectAll(notSelectedMethods)
.style("opacity", 0.2);
var selectedLegend = document.getElementById(d.name + "-legend");
var notSelectedLegends = $(".legend").not(selectedLegend);
d3.selectAll(notSelectedLegends)
.style("opacity", 0.2);
}
)
Debugging I can see that notSelectedMethods
store all nodes ignoring the not() function. This is true for the first part, because with the second one of the snippet work.
Looking around I found this one, so I tried what that they said (focusing on the first part, the line selection), but no one work.
d3.selectAll(".method")
.style("opacity",
function() {
return (this === selectedMethod) ? 1.0 : 0.2;
}
);
Or
var selectedMethod = this;
d3.selectAll(".method")
.filter(
function(n, i) {
return (this !== selectedMethod);
}
)
.style("opacity", 0.2);
Or
d3.selectAll(".method:not(." + this.id + ")")
.style("opacity", 0.2);
How can I solve this issue?
UPDATE:
@TomB and @altocumulus point me in the right direction. With some bit changes, code are now working.
var selectedMethod = d.name;
d3.selectAll(".method")
.style("opacity",
function(e) {
return (e.name === selectedMethod) ? 1.0 : 0.2;
}
);
I did not mention data structure of the d
element, that's was my bad.
This snipper do the job. I think I cannot do better, am I right?
UPDATE 2:
I cheered too soon. I tried to replicate previously on mouseover
solution on legend to change lines and legend (same logic as before)
.on("mouseover",
function(d) {
// Change opacity of legend's elements
var selectedLegend = d.name;
d3.selectAll(".legend")
.style("opacity",
function(e) {
return (e.name === selectedLegend) ? 1.0 : 0.2;
}
);
// Change width of selected line
var selectedMethod = d.name;
d3.selectAll(".method")
.style("stroke-width",
function(e) {
return (e.name === selectedMethod) ? "4.5px" : "1.5px";
}
);
// Change opacity of no-selected lines
d3.selectAll(".method")
.style("opacity",
function(e) {
return (e.name === selectedMethod) ? 1.0 : 0.2;
}
);
I do not know why, snippet where I change width do not work (width does not change).
Upvotes: 3
Views: 2417
Reputation: 787
@TomB and @altocumulus point me in the right direction. With some bit changes, code are now working.
var selectedMethod = d.name;
d3.selectAll(".method")
.style("opacity",
function(e) {
return (e.name === selectedMethod) ? 1.0 : 0.2;
}
);
I did not mention data structure of the d
element, that's was my bad.
Upvotes: 0
Reputation: 1983
You have to compare the id like that :
.on("mouseover", function(d) {
d3.select(this).style("stroke-width", "4px");
var selectedLine = d.name + "-line";
d3.selectAll(".method")
.style("opacity", function(e) {
return (e.id === selectedLine) ? 1.0 : 0.2;
});
})
All items with "method" class will have an opacity of 1 except the one with id === d.name + "-line"
You can't compare JQuery items and D3 items like that, have a look at http://collaboradev.com/2014/03/18/d3-and-jquery-interoperability/
Upvotes: 1