Подтвердить что ты не робот

Эквивалент селектора jQuery 'not' в D3.js?

Работая в D3.js, я бы хотел выделить все элементы, соответствующие селектору, за исключением текущего элемента.

Причина в том, что я хотел бы навести на круг, и все остальные круги с тем же классом станут светло-голубыми, но текущий круг останется тем же.

Это то, что у меня есть:

vis.selectAll('circle.prospect')
.on("mouseover", function(d) { 
     console.log(d);
    d3.selectAll('circle.prospect').transition().style('opacity','0.5');
    d3.select(this).attr('opacity','1.0');
  });

В jQuery я мог бы сделать это с помощью not. Кто-нибудь знает эквивалент D3.js?

4b9b3361

Ответ 1

Еще более простой способ приблизиться к этому - использовать мощность D3-операторов:

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;
    });
});

Здесь одно отличие от этого, в отличие от вашего исходного кода, непрозрачность элемента circleUnderMouse будет плавно анимироваться. Если он уже полностью непрозрачен, то, вероятно, не имеет большого значения, в противном случае вы могли бы использовать оператор .duration() аналогичным образом, чтобы скорость circleUnderMouse была равна 0, а остальные больше.

Ответ 2

Если ваши элементы имеют уникальные идентификаторы, доступные для CSS, вы можете использовать селектор :not(). Некоторые потенциальные примеры:

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

Причина d3.selectAll('circle.prospect:not(this)') не работает, потому что она просто буквально говорит, чтобы отфильтровать любые элементы <this></this>, что явно не является вашим намерением, и поскольку он уже выбирает только теги <circle></circle>, это никак не повлияет.

Даже если вы обычно не применяете какой-либо уникальный атрибут DOM, нет причин, по которым вы не могли бы временно установить его:

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 = '';
  });

Однако, если у ваших элементов уже нет идентификатора, который уже назначен, я думаю, что решение Яна Робертса, вероятно, будет тем, что я сделал бы вместо этого временного хакера.

Ответ 3

Вы можете filter выбрать:

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');
  });