#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. Если у вас есть другая проблема, пожалуйста, опубликуйте ее как новый вопрос с соответствующими подробностями.