Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

d3.js - Select node element based on attributes value using .selectAll()

I've the a node like:

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

I am trying to select a specific node (e.g where d="...BBB...") which has the attribute pos='p2'

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

This produces/returns an arrays with all 3 entries:

-> p0 false

-> p1 true

-> p2 false

-> [Array(3)]

I am interested in selecting just one, in this case the one with .attr("pos") == 'p2' so I'd like to return just one element.

I've tried with map() and filter() but without success.

What is the correct way to select a specific element based on an attribute value?

like image 556
Lou_Ds Avatar asked Mar 04 '23 05:03

Lou_Ds


1 Answers

Selection.filter()

You could select a bunch of elements based on class, and then filter the selection with 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>

Using CSS selectors to select by attribute value

But, rather than selecting a bunch of elements and then filtering the selection, we can do everything in one step with the CSS selectors described here. This lets us select elements an attribute they have is equal to a specific value:

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>

In the above I also use:

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

You can also substitute look for a class rather than a generic tag, so for you this might look like:

d3.selectAll(".myarea[d='BBB'][pos='p2']")
like image 166
Andrew Reid Avatar answered Apr 20 '23 00:04

Andrew Reid