Как отсортировать гистограммы перехода?

#javascript #d3.js

#javascript #d3.js

Вопрос:

У меня есть проект, в котором я пытаюсь использовать переходы для отображения данных за 1800-1805 годы

Я создал гистограмму и смог получить переход, но проблема здесь в том, что я пытаюсь отсортировать гистограмму так, чтобы данные отображались в порядке убывания. как всегда, когда я сортирую данные и выполняю переход вместо изменения значений атрибутов «y» прямоугольников, мой код заменяет существующие прямоугольники отсортированными для каждого отдельного перехода.

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

Как я мог это сделать.

Мои данные, как показано ниже

год 1800

Китай — 20000, США — 80000, Франция — 15000

год 1801

Китай — 25000, США -90000, Франция — 35000

теперь для этих данных мой код заменяет данные Франции и Китая, они не перемещаются вверх и вниз. что я должен добавить в свой код, чтобы сделать это?

 main.js
-------------

/*
*    main.js
*    Mastering Data Visualization with D3.js
*    2.5 - Activity: Adding SVGs to the screen
*/
var margin = { left:80, right:20, top:50, bottom:100 };

var width = 600 - margin.left - margin.right,
    height = 400 - margin.top - margin.bottom;

var g = d3.select("#chart-area")
    .append("svg")
        .attr("width", width   margin.left   margin.right)
        .attr("height", height   margin.top   margin.bottom)
    .append("g")
        .attr("transform", "translate("   margin.left   ", "   margin.top   ")");
var time = 0;
/*var xLabel = g.append("text")
    .attr("y", height   200)
    .attr("x", width / 2)
    .attr("font-size", "20px")
    .attr("text-anchor", "middle")
    .text("GDP Per Capita ($)");
var yLabel = g.append("text")
    .attr("transform", "rotate(-90)")
    .attr("y", -40)
    .attr("x", -170)
    .attr("font-size", "20px")
    .attr("text-anchor", "middle")
    .text("Life Expectancy (Years)")*/
var timeLabel = g.append("text")
    .attr("y", height  100)
    .attr("x", width   100)
    .attr("font-size", "40px")
    .attr("opacity", "0.4")
    .attr("text-anchor", "middle")
    .text("1800");
  var data =      d3.json("buildings.json").then(function(data){
            // console.log(data);

            // Clean data
            data.forEach(function(d) {
                d.Year =  d.Year;
                d.Budget= d.Budget;
            });



const formattedData = data.map(function(year){
    return year["countries"].filter(function(country){
        var dataExists = (country.budget);
        return dataExists
    })
});

// Run the code every 0.1 second
d3.interval(function(){
    // At the end of our data, loop back
    time = (time < 5) ? time 1 : 0
    update(formattedData[time]);
}, 10000);

// First run of the visualization
update(formattedData[0]);

})

function update(data) {
// Standard transition time for the visualization
var t = d3.transition()
    .duration(10000);

// JOIN new data with old elements.
var rects = g.selectAll("rect").data(data, function(d){

    return d;
});

// EXIT old elements not present in new data.
//rects.exit()
    //.attr("class", "exit")
    //.remove();
// ENTER new elements present in new data.

   rects.enter()
    .append("rect")
    .attr("class", "enter")
    //.attr("fill", function(d) { return continentColor(d.continent); })
  //  .merge(rects)

        .attr("x", 0)
        .attr("y", function(d,i){

          return i*20;
        }).transition(t)
        .attr("width", function(d,i){
          return d.budget/100;
          console.log(d.budget);
        })
        .attr("height", 18)
        .attr("fill",function(d,i){
if(d.country=="Italy")
{
  return "green";
}else if(d.country=="Australia"){
return "blue";

}

        });

// Update the time label
timeLabel.text( (time   1800))



}
 

Ответ №1:

Ваша проблема — это просто ключевая функция, которая имеет фундаментальное значение для достижения постоянства объекта.

Прямо сейчас у вас есть это:

 var rects = g.selectAll("rect").data(data, function(d){
    return d;
});
 

Который возвращает d , то есть, всю базу данных. Учитывая вашу структуру данных, datum является объектом.

Однако в API четко указано значение, возвращаемое ключевой функцией:

Если ключевая функция не указана, то первая базовая точка в данных присваивается первому выбранному элементу, вторая базовая точка — второму выбранному элементу и так далее. Может быть указана ключевая функция для управления тем, какой элемент данных присваивается какому элементу, заменяя стандартное соединение по индексу, путем вычисления строкового идентификатора для каждого элемента данных и элемента. (курсив мой)

Поэтому измените ключевую функцию на:

 var rects = g.selectAll("rect").data(data, function(d){
    return d.country;
    //string---^
});
 

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

1. Спасибо, я изменил его по мере необходимости, но как отсортировать столбцы?

2. Это еще одна проблема. Пожалуйста, оставьте только один вопрос на вопрос здесь, в Stack Overflow. Если у вас есть другая проблема, пожалуйста, опубликуйте ее как новый вопрос с соответствующими подробностями.