Выбор по индексу внутри выбора d3

1

Я новичок в d3 и изо всех сил пытаюсь найти ответ на конкретную проблему, с которой я столкнулся. Ниже приведен соответствующий код...

circles = base.selectAll("circle");

circles.attr("cx", function (d, i) {
            return +d3.select(this).attr("cx") + 2;
        })

circles.attr("cy", function (d, i) {
            return +d3.select(this).attr("cy") + 2;
        })

Где base.selectAll("круг") выбирает все круги SVG, ранее созданные с d3, в другой функции.

Вышеупомянутое работает точно так, как я хочу, мой вопрос заключается в том, как заменить (this).attr() и заменить, выбрав индекс? Например, если бы я хотел выбрать круг до этого внутри функции, то что-то вроде ниже, но это явно не работает.

+d3.select(d[i-1]).attr("cy")

В принципе, я хочу зациклиться на функции и сравнить (this).attr("cy") со всеми другими выбранными позициями. Мой код до сих пор ниже

circles = base.selectAll("circle");

circles.attr("cx", function (d, i) {
    for (n = 0; n < circles.size(); n++) {
        if (n != i) {

            if (+d3.select(this).attr("cy") + +d3.select(this).attr("r") > +d3.select(d[n]).attr("cy") + +d3.select(d[n]).attr("r")) {
                 //do something
            }

        }
    }
})

где +d3.select(d [n]) неверен. Любая помощь будет оценена по достоинству или просто указана в правильном направлении, независимо от того, как я решаю эту проблему. Я просто получаю страницы о том, как d3.select работает с другими элементами.

Теги:
d3.js

1 ответ

2
Лучший ответ

Второй и третий аргументы

Я считаю, что @altocumulus является правильным в комментариях, говоря, что это, вероятно, проблема XY.

Тем не менее, я хочу написать ответ (для будущих пользователей), потому что это было задано много раз в разных вариантах:

Внутри выбора, как я могу выбрать следующий элемент? Как я могу выбрать два элемента раньше? Как я могу выбрать пять элементов впереди?

Вы можете сделать это, объединив второй и третий аргументы в анонимной функции:

.attr("foo", function(d, i, n){
//second and third ------^--^

Вот важная информация: this, текущий элемент, тот же n[i].

Поэтому, поскольку n[i] - this (то есть текущий элемент), вы можете просто использовать разные индексы для получения разных элементов. Например:

  • n[i-1] → получить предыдущий элемент
  • n[i+1] → получить следующий элемент
  • n[i+4] → вывести элемент 4 вперед

... и так далее.

демонстрация

Вот очень простое демонстрационное шоу. В демоверсии я перемещаю каждый круг в позицию следующего, который вычисляется с использованием:

.attr("cx", function(d, i, n) {
    return +d3.select(n[i + 1]).attr("cx")
})

Конечно, вы установили специальное правило для последнего элемента, потому что в этой точке нет n[i+1] (проверьте тернарный оператор).

Вот демо:

var data = [140, 200, 30, 70, 270, 100, 220, 80];
var svg = d3.select("svg");
var circles = svg.selectAll(null)
  .data(data)
  .enter()
  .append("circle")
  .attr("cy", function(d, i) {
    return 12 + 25 * i;
  })
  .attr("cx", function(d) {
    return d;
  })
  .attr("r", 10)
  .attr("fill", "tan")
  .attr("stroke", "dimgray")
  .transition()
  .duration(1000)
  .delay(function(d, i) {
    return 1000 + i * 1000
  })
  .attr("cx", function(d, i, n) {
    return n[i + 1] ? +d3.select(n[i + 1]).attr("cx") : +d3.select(n[i]).attr("cx")
  })
<script src="/d3.v4.min.js"></script>
<svg width="300" height="200"></svg>

Ещё вопросы

Сообщество Overcoder
Наверх
Меню