Переходы в том же элементе просто перезапишут предыдущий переход.
https://bost.ocks.org/mike/transition/#per -элемент :
Запуск нового перехода для элемента останавливает любой переход, который уже запущен.
Чтобы решить эту проблему, я использовал async / await , и я обновил d3 до последней версии, которая добавила transition.end (что упрощает последовательность переходов с помощью обещаний).
Другая проблема заключается в том, что вы используете позиции индекса для выбора прямоугольников, а не фактические значения, и поэтому swapAnimation перемещает неправильные элементы. Это замена позиций на основе начальных позиций, а не обновленных позиций в пузырьковой сортировке. например:
Итерация:
- swap (0,1) [1,9,5 ...] rect0.x = 20, rect1.x = 10, rect2.x = 30
swap (1,2) [1,5,9 ...] rect0.x = 20, rect1.x = 30, rect2.x = 10
^^^^^ ^^^^^
Обратите внимание, что rect2, который содержит значение 5, теперь находится в первой позиции.
Поэтому вместо использования позиций индекса я изменил идентификаторы на rect $ {value}
Другой способ, который технически более точен, - это сохранить элементы <text>
в массиве и поменять их местами вместе с пузырьковой сортировкой массива данных. А затем анимируйте позиции индекса в массиве элементов <text>
.
Однако в целях демонстрации было короче просто привязать id к значениям вместо начального индекса.
dataArray = [9, 1, 5, 7, 2, 4, 3]
for (var i = 0; i < dataArray.length; i++)
document.querySelector('svg').innerHTML += `<text class="rects" id="rect${dataArray[i]}" x="${i*10}" y="10" >${dataArray[i]}</text>`
var durationTime = 1000
bubbleSort()
async function bubbleSort() {
let len = dataArray.length;
let swapped;
do {
swapped = false;
for (let i = 0; i < len; i++) {
if (dataArray[i] > dataArray[i + 1]) {
let temp = dataArray[i];
dataArray[i] = dataArray[i + 1];
dataArray[i + 1] = temp;
swapped = true;
// call function here for swap animation...
await swapAnimation(dataArray[i], i, dataArray[i + 1], i + 1); // did not work
}
}
} while (swapped);
return console.log(dataArray);
}
function swapAnimation(d, i, d1, i1) {
var sel = `#rect${d}`, sel1 = `#rect${d1}`
var x1 = d3.select(sel1).attr("x")
var x = d3.select(sel).attr("x")
return Promise.all([
d3.select(sel)
.transition()
.duration(durationTime)
.attr("x", x1)
.end(),
d3.select(sel1)
.transition()
.duration(durationTime)
.attr("x", x)
.end()
])
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.16.0/d3.js" integrity="sha256-LHLWSn9RC2p119R1eT2pO3Om+Ir2G0kTZOJmWQ2//pw=" crossorigin="anonymous"></script>
<svg></svg>