D3 — изменение порядка элементов на основе их данных

#d3.js

#d3.js

Вопрос:

Я создал составную гистограмму, представляющую футболистов в футбольных командах. Диаграмма здесь:http://andybarefoot.com/football/path.html

Я использовал d3 и построил страницу для работы в два этапа. Сначала я загружаю данные и создаю прямоугольник для каждого игрока. Затем я обновляю параметры прямоугольников на основе данных, присвоенных каждому элементу, в зависимости от того, какой вид выбран. Это означает, что различные параметры навигации изменяют размер и порядок прямоугольников на основе существующих данных, сопоставленных элементам, но дополнительные данные не загружаются.

Хотя изменение размера прямоугольников работает правильно, я не могу изменить порядок прямоугольников на основе данных.

Вертикальное положение каждого прямоугольника задается простым значением «i», умноженным на заданную переменную интервала. Чтобы изменить порядок, я подумал, что мог бы выбрать все элементы, отсортировать на основе соответствующих данных, а затем установить новое вертикальное положение таким же образом. (т. е. значение «i» изменилось бы). Однако я не могу заставить это работать.

Вот моя (неудачная) попытка:

 // select all elements and then reorder
svg
   .selectAll(".team")
   .sort(function(a, b) { 
       return b.totalClubContractDistance - a.totalClubContractDistance;
   })
;
// select all elements and reposition according to new order
svg
    .selectAll(".team")
    .duration(750)
    .attr("transform", function(d,i) {
       return "translate(0," teamSpacing*i ")";
    })
;
  

Комментарии:

1. Будет лучше, если вы дадите скрипку

Ответ №1:

В d3 есть 4 основные концепции. Объединение, обновление, ввод, выход. Вы можете прочитать больше здесь:https://bost.ocks.org/mike/join /

В принципе, каждый раз, когда вы хотите обновить положение элемента, вы должны изменить данные, затем выполнить объединение с последующим обновлением.

Таким образом, код будет выглядеть следующим образом:

 function render (data) {
    // join
    // this joins the new data to the existing data
    var teams = svg.selectAll('.team')
        .data(data);

    // update
    // this will update existing teams that have a different location
    teams.attr('transform', function (d, i) {
        return 'translate(0, '   teamSpacing * i   ')';
    });

    // enter
    // this will add new teams that were added to the data set
    teams.enter()
        .attr('transform', function (d, i) {
            return 'translate(0, '   teamSpacing * i   ')';
        });

    // exit
    // this will remove all the teams that are no longer part of the data set
    teams.exit()
        .remove();

}
  

Надеюсь, это поможет

Комментарии:

1. Спасибо @link! В этом случае я уже прикрепил все данные, но хочу иметь возможность переключать порядок элементов в зависимости от двух разных значений данных. В одном представлении элементы упорядочиваются по убыванию «totalBirthDistance», в другом — по убыванию «totalClubContractDistance». Должен ли я по-прежнему обновлять данные? У меня есть только один набор данных, поэтому не было бы дополнительных / меньшего количества элементов, просто одни и те же элементы отображались в другом порядке.

2. Вы бы обновили набор данных во время изменения порядка. Представьте, что данные управляют визуализацией d3. Если вы хотите, чтобы визуализация изменилась, вам нужно обновить данные.