Фильтр выбора по массиву без потери порядка 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);            
  });
Другие вопросы по тегам