Я новичок в 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 работает с другими элементами.
Я считаю, что @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>