首页 > 解决方案 > 函数过滤器在 d3js 中没有按预期工作

问题描述

我有这个 HTML 结构

<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>

我想用g满足特定条件的元素来做一些事情。但是做的时候,

d3.selectAll("g.type").filter(g_element => g_element.class !== "whatever");

过滤器没有按预期工作(至少对我来说)。g_element.classundefined。调试后,由于某种原因,过滤返回<circle class="node" r="50" fill="#768b83" id="nsmart_city_lab" filter="url(#blur)"></circle>而不是g对象来访问其属性并进行过滤。

那怎么能做到呢?

在这里,您有一个始终返回未定义的 jsfiddle,https ://jsfiddle.net/k6Ldxtof/40/

标签: javascriptd3.js

解决方案


在你的片段中......

d3.selectAll("g.type").filter(g_element => g_element.class !== "whatever");

...您命名的第一个参数g_element是绑定到该元素的数据。由于这里没有数据绑定,显然是undefined.

要获取元素,您必须使用this. 但是,由于您在此处使用箭头函数,因此您需要结合使用第二个和第三个参数:

d3.selectAll("g.type")
    .filter((_,i,n) => console.log(n[i]))

然后要获取课程,您可以简单地使用getter ...

d3.selectAll("g.type")
    .filter((_,i,n) => console.log(d3.select(n[i]).attr("class"))) 

或者,甚至更简单,使用classList

d3.selectAll("g.type")
    .filter((_, i, n) => console.log(n[i].classList))

这是演示:

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>


推荐阅读