在保持旧元素位置的同时应用过渡

时间:2018-10-05 00:59:18

标签: javascript d3.js

在页面上,我有许多具有相同类的矩形,例如类one

如何对所有这些矩形应用过渡,以使它们移动到具有新类(也许是类two)的新位置,但将那些旧矩形保持在相同位置?

如果我的解释不正确,有人可以纠正我吗?

例如,我有这些带有“开始”类的矩形

d3.select("svg")
  .selectAll("rect")
  .data([10,20,30,40,50])
  .enter()
  .append("rect")
  .attr("class", "start")
  .attr("x", d => d)
  .attr("y", 1)
  .attr("width", 5)
  .attr("height", 5);

这些矩形坐标是(10,1),(20,1),(30,1)...

然后我移动它们

d3.selectAll("rect")
  .transition()
  .attr("y", (d, i) => i + 5 * 10); 

它们将出现在新的坐标(10,50),(20,51),(30,52)...

我该如何做,使得({10,1),(20,1),(30,1)...类start的原始矩形仍然存在,但在( 10、50),(20、51),(30、52)...类别为stop

2 个答案:

答案 0 :(得分:1)

正如您在编辑中已经明确指出的那样,您不想将过渡应用于现有元素:您想要克隆它们并将过渡应用于其克隆(或在将过渡应用于原始元素之前对其进行克隆,一样...)。

话虽如此,D3有一个非常方便的方法,名为clone,该方法:

  

在所选元素之后立即插入所选元素的克隆,并返回新添加的克隆的选择。

因此,假设您的选择名为rectangles(建议:始终为您的选择命名),而不是这样做...

rectangles.transition()
    .attr("class", "stop")
    .attr("y", (d, i) => i + 5 * 10);

...首先克隆它们:

rectangles.each(cloneNodes)
    .transition()
    .attr("class", "stop")
    .attr("y", (d, i) => i + 5 * 10);

function cloneNodes() {
    d3.select(this).clone(false);
}

这是演示:

const svg = d3.select("svg");

const rectangles = d3.select("svg")
  .selectAll(null)
  .data([10, 20, 30, 40, 50])
  .enter()
  .append("rect")
  .attr("class", "start")
  .attr("x", d => d)
  .attr("y", 1)
  .attr("width", 5)
  .attr("height", 5);

rectangles.each(cloneNodes)
  .transition()
  .attr("class", "stop")
  .attr("y", (d, i) => i + 5 * 10);

function cloneNodes() {
  d3.select(this).clone(false);
}
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg></svg>

答案 1 :(得分:0)

无需使用each和要克隆的函数。

rectangles.clone(false)
  .transition()
  .attr("class", "stop")
  .attr("y", (d, i) => i + 5 * 10);

const svg = d3.select("svg");

const rectangles = d3.select("svg")
  .selectAll(null)
  .data([10, 20, 30, 40, 50])
  .enter()
  .append("rect")
  .attr("class", "start")
  .attr("x", d => d)
  .attr("y", 1)
  .attr("width", 5)
  .attr("height", 5);

rectangles.clone(false)
  .transition()
  .attr("class", "stop")
  .attr("y", (d, i) => i + 5 * 10);
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg></svg>