Built with blockbuilder.org
forked from highcold's block: transition of bar chart
xxxxxxxxxx
<html>
<style type="text/css">
svg {
font: 10px sans-serif;
}
.bar rect {
fill: steelblue;
}
.bar:hover rect {
fill: brown;
}
.value {
fill: white;
}
.axis {
shape-rendering: crispEdges;
}
.axis path {
stroke: none;
}
.x.axis line {
stroke: #fff;
stroke-opacity: .8;
}
.y.axis path {
stroke: black;
}
</style>
<body>
<p id="menu"><b>Top States by Age Bracket, 2008</b><br>Age: <select></select>
<script src="https://d3js.org/d3.v4.js"></script>
<script type="text/javascript">
var states,
age,
ages;
var margin = {top:20, right:40, bottom:10, left:40},
width = 960 - margin.left - margin.right,
height = 250 - margin.top - margin.bottom;
var format = d3.format('.1%');
var x = d3.scaleLinear().range([0,width]);
y = d3.scaleBand().rangeRound([0,height]);
var svg = d3.select("body")
.append('svg')
.attr('width',width+margin.left+ margin.right)
.attr('height',height+margin.bottom+margin.top);
var g = svg.append('g').attr('transform','translate('+margin.left+','+margin.top+")");
var menu = d3.select("#menu select")
.on("change", change);
d3.csv('stacked bar chart.csv',function(error,data){
if(error) throw error;
//debugger;
states =data;
ages = d3.keys(states[0]).filter(function(key){return key != 'State';});
//debugger;
//states数据处2
states.forEach(function(d){
var total =0;
for(var i =0;i<ages.length;i++){
total += +d[ages[i]];
}
for(var j =0;j<ages.length;j++){
d[ages[j]] = +d[ages[j]]/ total;
}
});
//debugger;
//在这个代码块里面主要处理数据的赋值
menu.selectAll("option")
.data(ages)
.enter().append("option")
.text(function(d) { return d; });
menu.property("value", "18 to 24 Years");
//debugger;
redraw();
});
var altKey;
d3.select(window)
.on("keydown", function() { altKey = d3.event.altKey; })
.on("keyup", function() { altKey = false; });
function change(){
clearTimeout(timeout);
d3.transition()
.duration(altKey ? 7500 : 750)
.each(redraw);
}
function redraw(){
if(d3.select(axis) != ''){
d3.select(axis).remove();
}
var select_age = menu.property('value');
var top = states.sort(function(a,b){return b[select_age]- a[select_age];}).slice(0,10); //选择年龄的top10国家
//debugger;
y.domain(top.map(function(d){return d.State;})).padding(0.1);
var barUpdate =g.selectAll('.bar')
.data(top,function(d){return d.State;})
.attr('class','bar bar_update');
var barEnter = barUpdate.enter().append('g','.axis')
.attr('class','bar bar_enter')
.attr('transform',function(d){return 'translate(0,'+ (height+ y(d.State))+')';})
.style('fill-opacity',0)
;
var barExit = barUpdate.exit()
.attr('class','bar bar_exit');
//只有这个group是需要开始值,bar_update、bar_exit有原始值
barEnter
.append('rect')
.attr('width',age && function(d){return x(d[age]);}) //age在前面为空,同时这个并的操作,如果前面age为空,就返回空
.attr('height',y.bandwidth()); //动画效果包含:位置的移动,宽度的移动,末尾字的移动
//debugger;
barEnter
.append('text')
.attr('class','label')
.attr('x',-3)
.attr('y',y.bandwidth()/2)
.attr('dy','.35em')
.attr('text-anchor','end')
.text(function(d){return d.State;});
barEnter
.append('text')
.attr('class','value')
.attr('x',age && function(d){return x(d[age])-3;})
.attr('y',y.bandwidth()/2)
.attr('dy','.35em')
.attr('text-anchor','end');
//debugger;
var x0 = d3.scaleLinear().range([0,width]).domain([0,0]);
x.domain([0,top[0][age = select_age]]); //下面来分析
var trans_barEnter = barEnter.transition()
.duration(800)
.attr('transform',function(d){return 'translate(0,'+(d.y0=y(d.State))+')';})
.style("fill-opacity", 1);
trans_barEnter.select('rect')
.attr('width',function(d){return x(d[age]);});
trans_barEnter.select('.value')
.attr('x',function(d){return x(d[age])-3;})
.text(function(d){return format(d[age]);});
var trans_barUpdate = barUpdate.transition()
.duration(800)
.attr('transform',function(d){return 'translate(0,'+y(d.State)+')';});
trans_barUpdate.select('rect')
.attr('width',function(d){return x(d[age]);});
trans_barUpdate.select('.value')
.attr('x',function(d){return x(d[age])-3;})
.text(function(d){return format(d[age]);});
var trans_barExit = barExit.transition()
.duration(800)
.attr('transform',function(d){return 'translate(0,'+ (height+d.y0)+')';})
.style('fill-opacity',0)
.remove();
d3.select('.x.axis').remove();
var axis =g.append('g').attr('class','x axis');
axis.call(d3.axisTop(x0).tickSize(-height).tickFormat(format))
.transition().duration(800)
.call(d3.axisTop(x).tickSize(-height).tickFormat(format));
}
var timeout = setTimeout(function() {
menu.property("value", "65 Years and Over").node().focus();
change();
}, 5000);
</script>
</body>
</html>
https://d3js.org/d3.v4.js