Фильтр выбора по массиву без потери порядка d3js
Я новичок в d3js и хочу создать анимацию между двумя узлами на графике, представленном кружками.
Я рассчитал кратчайший путь между начальным и конечным узлами, используя путь функции. Он возвращает массив идентификаторов круга, которые представляют путь, по которому вы должны следовать от источника (начало) до цели (конец). Примерно так: 23, 24, 37, 29, 30.
var ruta = path(data.pred, start, end);
После этого я использовал функцию фильтра, чтобы выбрать узлы (круги), которые образуют кратчайший путь между началом и концом.
var selection = svg.selectAll('circle').filter(function(d){ return ruta.indexOf(d.index.toString()) >- 1;});
Затем я попытался анимировать путь, используя этот простой переход, меняя размер кругов один за другим.
selection.transition()
.delay(function(d,i) { return i/ len * enter_duration;})
.style("opacity",1.0)
.attr("r", 10.0)
.each("end",function() {
d3.select(this).
transition()
.delay(function(d,i) { return i/ len * enter_duration;})
.attr("r",7)
.style("opacity",0.7);
});
Проблема в том, что выбор фильтра теряет первоначальный порядок узлов.
Пример:
Исходный путь: 23, 24, 37, 29, 30. Порядок выбора: 23, 24, 29, 30, 37.
Как я могу изменить порядок объектов выделения на основе исходного массива?
1 ответ
Я использовал .sort()
как предложил @LarsKotthoff. Это моя функция сравнения, я сделал глобальный исходный массив (ruta) и затем использовал позицию индекса в ruta для сортировки массива выборки.
sortItems = function (a, b) {
value_a = ruta.indexOf(a.id.toString());
value_b = ruta.indexOf(b.id.toString())
return value_a - value_b ;
};
И это код для сортировки выбора
selection
**.sort(sortItems)**
.transition()
.delay(function(d,i) { return i/ len * enter_duration;})
.style("opacity",1.0)
.attr("r", 10.0)
.each("end",function() {
d3.select(this)
.transition()
.delay(function(d,i) { return i/ len * enter_duration;})
.attr("r",7)
.style("opacity",0.7);
});