Reputation: 90
I have this HTML structure
<g class="type type-project" id="g-nsmart_city_lab" transform="translate(954.9537424482861,460.65694411587845)">
<circle class="highlighter-circles" fill-opacity="0" r="70" fill="rgb(150,150,150)" id="hc-nsmart_city_lab"></circle>
<circle class="node" r="50" fill="#768b83" id="nsmart_city_lab" filter="url(#blur)"></circle>
<text font-family="Comic Sans MS" font-size="18px" fill="black" class="nodetext" id="t-nsmart_city_lab" style="text-anchor: middle;" x="0" y="0">SMART CITY LAB</text>
<image href="./icons/project.svg" width="30" height="30" id="i-nsmart_city_lab" class="nodeimg"></image>
<image href="./icons/expand2.svg" width="30" height="30" for-node="nsmart_city_lab" x="25" y="-45" id="ne-nsmart_city_lab" class="nodeexp" style="visibility: hidden;" data-expandable="false"></image>
<circle class="inv_node" r="50" fill="red" fill-opacity="0" id="inv_nsmart_city_lab"></circle>
</g>
and I want to to something with the g
elements that fulfill certain condition. But when doing,
d3.selectAll("g.type").filter(g_element => g_element.class !== "whatever");
the filter does not work as expected (at least for me). g_element.class
is undefined
. After debugging, for some reason the filtering is returning <circle class="node" r="50" fill="#768b83" id="nsmart_city_lab" filter="url(#blur)"></circle>
instead of a g
object to access its attributes and do the filtering.
How could this be done then ?
Here you have a jsfiddle which always returns undefined, https://jsfiddle.net/k6Ldxtof/40/
Upvotes: 0
Views: 104
Reputation: 102198
In your snippet...
d3.selectAll("g.type").filter(g_element => g_element.class !== "whatever");
... the first argument, which you named g_element
, is the datum bound to that element. As there is no data bound here, that's obviously undefined
.
To get the element instead, you have to use this
. However, since you're using a arrow function here, you need to use the second and third arguments combined:
d3.selectAll("g.type")
.filter((_,i,n) => console.log(n[i]))
Then to get the classes, you can simply use a getter...
d3.selectAll("g.type")
.filter((_,i,n) => console.log(d3.select(n[i]).attr("class")))
Or, even simpler, using classList
:
d3.selectAll("g.type")
.filter((_, i, n) => console.log(n[i].classList))
Here is the demo:
function create() {
let g = d3.select("body")
.append("svg")
.attr("height", "500")
.attr("width", "500")
.append("g");
g.append("g")
.attr("class", "type type-red")
.attr("data-color", "red")
.append("circle")
.attr("r", 50)
.attr("fill", "red")
.attr("cx", 50)
.attr("cy", 50);
g.append("g")
.attr("class", "type type-green")
.attr("data-color", "green")
.append("circle")
.attr("r", 50)
.attr("fill", "green")
.attr("cx", 200)
.attr("cy", 50);
g.append("g")
.attr("class", "type type-blue")
.attr("data-color", "blue")
.append("circle")
.attr("r", 50)
.attr("fill", "blue")
.attr("cx", 100)
.attr("cy", 150);
filter_out();
}
/***************** USING THE SELECTOR ********************/
function filter_out() {
d3.selectAll("g.type")
.filter((_, i, n) => console.log(n[i].classList))
.attr("opacity", 0.5);
}
create();
<script src="https://d3js.org/d3.v4.js"></script>
Upvotes: 2