首页 > 解决方案 > d3.js - 使用 .selectAll() 根据属性值选择节点元素

问题描述

我有一个像这样的节点:

<div>
  <svg ...>
    <g class="graph">
      <path class="myarea" d="...AAA..." pos="p1">  </path>
    </g>
    <g class="graph">
      <path class="myarea" d="...BBB..." pos="p2">  </path>
    </g>
    <g class="graph">
      <path class="myarea" d="...CCC..." pos="p3">  </path>
    </g>
  /svg>
</div>

我正在尝试选择具有属性 的特定节点(例如 where d="...BBB..." )pos='p2'

d3.selectAll(".myarea").each(function(d,i) {
   console.log("-> ",  d3.select(this).attr("pos"), d3.select(this).attr("pos") == 'p2' );
  
});

这将产生/返回一个包含所有 3 个条目的数组:

-> p0 假

-> p1 真

-> p2 错误

-> [数组(3)]

我有兴趣只选择一个,在这种情况下,.attr("pos") == 'p2'我只想返回一个元素。

我尝试过map()filter()没有成功。

根据属性值选择特定元素的正确方法是什么?

标签: javascriptnode.jsd3.jsfilter

解决方案


选择.filter()

可以根据类选择一堆元素,然后使用以下内容过滤选择selection.filter()

svg.selectAll("whatever")
  .filter(function() {
    return d3.select(this).attr("col") == 2; // filter by single attribute
  })

var svg = d3.select("svg");

svg.selectAll("rect")
  .filter(function() {
    return d3.select(this).attr("col") == 2
  })
  .attr("fill","orange");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg>
  <rect width="20" height="20" x="5" y="5" col="1" row="1"></rect>
  <rect width="20" height="20" x="30" y="5" col="2" row="1" ></rect>
  <rect width="20" height="20" x="5" y="30" col="1" row="2" ></rect>
  <rect width="20" height="20" x="30" y="30" col="2" row="2" ></rect>
</svg>

使用 CSS 选择器按属性值选择

但是,与其选择一堆元素然后过滤选择,我们可以使用这里描述的 CSS 选择器一步完成所有事情。这让我们可以选择元素的属性等于特定值:

svg.selectAll("rect[col='2']")

var svg = d3.select("svg");

svg.selectAll("rect[col='2']")
  .attr("fill","orange");
  
d3.selectAll("rect[col='1'][row='1']")
  .attr("fill","steelblue");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg>
  <rect width="20" height="20" x="5" y="5" col="1" row="1"></rect>
  <rect width="20" height="20" x="30" y="5" col="2" row="1" ></rect>
  <rect width="20" height="20" x="5" y="30" col="1" row="2" ></rect>
  <rect width="20" height="20" x="30" y="30" col="2" row="2" ></rect>
</svg>

在上面我还使用:

d3.selectAll("rect[col='1'][row='1']") to select based on two attribute values.

您还可以用查找类代替通用标签,因此对您而言,这可能如下所示:

d3.selectAll(".myarea[d='BBB'][pos='p2']")

推荐阅读