javascript - 如何对过渡条形图进行排序?
问题描述
我有一个项目,我正在尝试使用转换来显示 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))
}
解决方案
您的问题只是关键功能,这是实现对象恒常性的基础。
现在你有这个:
var rects = g.selectAll("rect").data(data, function(d){
return d;
});
它返回d
,即整个数据。给定您的数据结构,数据是一个object。
但是,API对 key 函数返回的值很清楚:
如果未指定键功能,则将 data 中的第一个数据分配给第一个选定元素,将第二个数据分配给第二个选定元素,依此类推。通过计算每个数据和元素的字符串标识符,可以指定一个键函数来控制将哪个数据分配给哪个元素,替换默认的按索引连接。(强调我的)
因此,将键功能更改为:
var rects = g.selectAll("rect").data(data, function(d){
return d.country;
//string---^
});
推荐阅读
- .net-core - 如何在 .Net Core 2.2 的默认 Localizer 中提供/覆盖 ResourceBaseName
- spring - 如何持久化 spring-boot-admin-starter-server 服务数据
- symfony4 - EventSubscriber 中的多个 EntityManager
- javascript - Firebase 数据库 URL 无法确定 - React Native
- laravel - 无法使用 pm2 运行 laravel-echo-server
- python - 计算给定范围内数字的出现次数
- php - 获取数据并执行减法
- java - 如何为 GET Rest 服务创建单元测试(Spring)
- javascript - 比较 React.JS 中两个不同对象数组的值
- python - Python Dataframe Pandas - 按列值上的条件 issubset() 过滤数据帧行