我试图通过D3了解条形图中的过渡。我现在正在做的是更新两个不同数据集之间的图表。我有一个转换,但它从轴的底部开始,而不是在两者之间转换。我的目标是让它在两者之间转换,然后改变颜色。我使用这个有用的example来了解更新的数据(我的代码段没有太大差异)。谢谢你看看。
var bothData = [
{
"year": "2014",
"product": "Books & DVDs",
"purchase": "0.5"
},
{
"year": "2002",
"product": "Books & DVDs",
"purchase": "10"
},
{
"year": "2014",
"product": "Beer & Wine",
"purchase": "7"
},
{
"year": "2002",
"product": "Beer & Wine",
"purchase": "3"
},
{
"year": "2014",
"product": "Food",
"purchase": "12"
},
{
"year": "2002",
"product": "Food",
"purchase": "12"
},
{
"year": "2014",
"product": "Home Supplies",
"purchase": "7"
},
{
"year": "2002",
"product": "Home Supplies",
"purchase": "6"
}
];
var data2002 = [];
var data2014 = [];
for(var i = 0; i < bothData.length; i++){
if(bothData[i]["year"] === "2002"){
data2002.push(bothData[i]);
}else{
data2014.push(bothData[i]);
}
}
function change(value){
if(value === '2002'){
update(data2002);
}else if(value === '2014'){
update(data2014);
}
}
function update(data){
xChart.domain(data.map(function(d){ return d.product; }) );
yChart.domain( [0, d3.max(data, function(d){ return + d.purchase; })] );
var barWidth = width / data.length;
var bars = chart.selectAll(".bar")
.remove()
.exit()
.data(data, function(d){ return d.purchase; })
.enter()
.append("rect")
.attr("class", "bar")
.attr("x", function(d, i){ return i * barWidth + 1 })
.attr("y",500)
.attr("height",0)
.attr("width", barWidth - 5)
.each(function(d){
if(d.year === "2014"){
d3.select(this)
.style('fill','#ea5454');
}else{
d3.select(this)
.style('fill','#4e97c4');
};
});
bars.transition()
.duration(600)
.ease(d3.easeLinear)
.attr('y', function(d){ return yChart(d.purchase); })
.attr('height', function(d){ return height - yChart(d.purchase); });
chart.select('.y').call(yAxis);
chart.select('.xAxis')
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", ".15em")
.attr("transform", function(d){
return "rotate(-65)";
});
}
var margin = {top: 20, right: 20, bottom: 95, left: 50};
var width = 400;
var height = 500;
var chart = d3.select(".chart")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var xChart = d3.scaleBand()
.range([0, width]);
var yChart = d3.scaleLinear()
.range([height, 0]);
var xAxis = d3.axisBottom(xChart);
var yAxis = d3.axisLeft(yChart);
chart.append("g")
.attr("class", "y axis")
.call(yAxis)
chart.append("g")
.attr("class", "xAxis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", ".15em")
.attr("transform", function(d){
return "rotate(-65)";
});
chart.append("text")
.attr("transform", "translate(-35," + (height+margin.bottom)/2 + ") rotate(-90)")
.text("Purchases");
chart.append("text")
.attr("transform", "translate(" + (width/2) + "," + (height + margin.bottom - 5) + ")")
.text("Products");
update(data2002);
答案 0 :(得分:2)
你有正确的想法......你想要实现Mike Bostock所描述的here对象的持久性。坚持不懈的关键应该是&#34;产品&#34;来自您的数据(不是&#34;购买&#34;)。
在update
功能中,定义bars
,如下所示:
var bars = chart.selectAll(".bar")
.data(data, function(d){ return d.product; })
然后将.enter
,.exit
和.transition
函数分开:
bars.exit()
.remove()
bars.enter()
....
bars.transition()
你的.enter
函数中有一些奇怪的东西 - 比如将条形高度设置为零。所以我修改了你的.enter和.transition函数:
bars.enter()
.append("rect")
.attr("class", "bar")
.attr("x", function(d, i){return i * barWidth + 1 })
.attr("y",function(d){ return yChart(d.purchase); })
.attr("height",function(d){ return height - yChart(d.purchase); })
.attr("width", barWidth - 5)
.attr('fill', function(d){
if(d.year === "2014"){
return'#ea5454'
}else{
return'#4e97c4'
}
})
bars.transition()
.duration(600)
.ease(d3.easeLinear)
.attr('y', function(d){ return yChart(d.purchase); })
.attr('height', function(d){ return height - yChart(d.purchase); })
.style('fill', function(d){
if(d.year === "2014"){
return '#ea5454'
} else {
return '#4e97c4'
}
})
这是一个有效的jsfiddle:https://jsfiddle.net/genestd/asoLph2w/
请注意顶部的按钮以实现转换。