Equivalent of jQuery's 'not' selector in D3.js?

后端 未结 3 1302
隐瞒了意图╮
隐瞒了意图╮ 2020-12-30 01:28

Working in D3.js, I\'d like to select all the elements that match a selector except for the current element.

The reason is that I\'d like to mouseover a ci

相关标签:
3条回答
  • 2020-12-30 01:55

    You can filter a selection:

    vis.selectAll('circle.prospect')
    .on("mouseover", function(d) { 
         console.log(d);
        var circleUnderMouse = this;
        d3.selectAll('circle.prospect').filter(function(d,i) {
          return (this !== circleUnderMouse);
        }).transition().style('opacity','0.5');
        d3.select(this).attr('opacity','1.0');
      });
    
    0 讨论(0)
  • 2020-12-30 02:11

    If your elements have an unique CSS-accessible identifiers, you can use the :not() selector. Some potential examples:

    d3.selectAll("circle.prospect:not(#" + this.id + ")");
    d3.selectAll("circle.prospect:not(." + someUniqueClassFrom(d) + ")");
    d3.selectAll("circle.prospect:not([uniqueAttr=" + this.getAttribute('uniqueAttr') + "])");
    

    The reason d3.selectAll('circle.prospect:not(this)') doesn't work is because it's just literally saying to filter out any <this></this> elements — which is obviously not your intent, and since it's already selecting only <circle></circle> elements would have no effect regardless.

    Even if you don't generally apply some unique DOM attribute, there's no reason you couldn't set one temporarily:

    vis.selectAll('circle.prospect')
    .on("mouseover", function(d) {
        this.id = 'temp-' + Math.random();
        d3.selectAll('circle.prospect:not(#' + this.id + ')').transition().style('opacity','0.5');
        d3.select(this).attr('opacity','1.0');
        this.id = '';
      });
    

    That said, however, if your elements don't already have an ID assigned already, I think Ian Roberts' solution is probably what I would do instead of this temporary identifier hack.

    0 讨论(0)
  • 2020-12-30 02:15

    An even simpler way to approach this would be using the power of D3's operators:

    vis.selectAll('circle.prospect').on("mouseover", function(d) {
        var circleUnderMouse = this;
        d3.selectAll('circle.prospect').transition().style('opacity',function () {
            return (this === circleUnderMouse) ? 1.0 : 0.5;
        });
    });
    

    There's one difference here in that, unlike your original code, the circleUnderMouse element's opacity will be smoothly animated as well. If it's already fully opaque then probably not a big deal, otherwise you could use the .duration() operator in a similar fashion to speed the circleUnderMouse time to 0 and the others longer.

    0 讨论(0)
提交回复
热议问题