D3.js 完整的柱形图
添加 SVG 画布
//画布大小
var width = 400;
var height = 400;
//在 body 里添加一个 SVG 画布
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
//画布周边的空白
var padding = {left:30, right:30, top:20, bottom:20};
1 2 3 4 5 6 7 8 9 10 11 12 | //画布大小 var width = 400 ; var height = 400 ; //在 body 里添加一个 SVG 画布 var svg = d3 . select ( "body" ) . append ( "svg" ) . attr ( "width" , width ) . attr ( "height" , height ) ; //画布周边的空白 var padding = { left : 30 , right : 30 , top : 20 , bottom : 20 } ; |
上面定义了一个 padding,是为了给 SVG 的周边留一个空白,最好不要将图形绘制到边
界上。
2. 定义数据和比例尺
//定义一个数组
var dataset = [10, 20, 30, 40, 33, 24, 12, 5];
//x轴的比例尺
var xScale = d3.scale.ordinal()
.domain(d3.range(dataset.length))
.rangeRoundBands([0, width - padding.left - padding.right]);
//y轴的比例尺
var yScale = d3.scale.linear()
.domain([0,d3.max(dataset)])
.range([height - padding.top - padding.bottom, 0]);
1 2 3 4 5 6 7 8 9 10 11 12 | //定义一个数组 var dataset = [ 10 , 20 , 30 , 40 , 33 , 24 , 12 , 5 ] ; //x轴的比例尺 var xScale = d3 . scale . ordinal ( ) . domain ( d3 . range ( dataset . length ) ) . rangeRoundBands ( [ 0 , width - padding . left - padding . right ] ) ; //y轴的比例尺 var yScale = d3 . scale . linear ( ) . domain ( [ 0 , d3 . max ( dataset ) ] ) . range ( [ height - padding . top - padding . bottom , 0 ] ) ; |
x 轴使用序数比例尺,y 轴使用线性比例尺。要注意两个比例尺值域的范围。
3. 定义坐标轴
//定义x轴
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom");
//定义y轴
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");
1 2 3 4 5 6 7 8 9 | //定义x轴 var xAxis = d3 . svg . axis ( ) . scale ( xScale ) . orient ( "bottom" ) ; //定义y轴 var yAxis = d3 . svg . axis ( ) . scale ( yScale ) . orient ( "left" ) ; |
x 轴刻度的方向向下,y 轴的向左。
4. 添加矩形和文字元素
//矩形之间的空白
var rectPadding = 4;
//添加矩形元素
var rects = svg.selectAll(".MyRect")
.data(dataset)
.enter()
.append("rect")
.attr("class","MyRect")
.attr("transform","translate(" + padding.left + "," + padding.top + ")")
.attr("x", function(d,i){
return xScale(i) + rectPadding/2;
} )
.attr("y",function(d){
return yScale(d);
})
.attr("width", xScale.rangeBand() - rectPadding )
.attr("height", function(d){
return height - padding.top - padding.bottom - yScale(d);
});
//添加文字元素
var texts = svg.selectAll(".MyText")
.data(dataset)
.enter()
.append("text")
.attr("class","MyText")
.attr("transform","translate(" + padding.left + "," + padding.top + ")")
.attr("x", function(d,i){
return xScale(i) + rectPadding/2;
} )
.attr("y",function(d){
return yScale(d);
})
.attr("dx",function(){
return (xScale.rangeBand() - rectPadding)/2;
})
.attr("dy",function(d){
return 20;
})
.text(function(d){
return d;
});
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | //矩形之间的空白 var rectPadding = 4 ; //添加矩形元素 var rects = svg . selectAll ( ".MyRect" ) . data ( dataset ) . enter ( ) . append ( "rect" ) . attr ( "class" , "MyRect" ) . attr ( "transform" , "translate(" + padding . left + "," + padding . top + ")" ) . attr ( "x" , function ( d , i ) { return xScale ( i ) + rectPadding / 2 ; } ) . attr ( "y" , function ( d ) { return yScale ( d ) ; } ) . attr ( "width" , xScale . rangeBand ( ) - rectPadding ) . attr ( "height" , function ( d ) { return height - padding . top - padding . bottom - yScale ( d ) ; } ) ; //添加文字元素 var texts = svg . selectAll ( ".MyText" ) . data ( dataset ) . enter ( ) . append ( "text" ) . attr ( "class" , "MyText" ) . attr ( "transform" , "translate(" + padding . left + "," + padding . top + ")" ) . attr ( "x" , function ( d , i ) { return xScale ( i ) + rectPadding / 2 ; } ) . attr ( "y" , function ( d ) { return yScale ( d ) ; } ) . attr ( "dx" , function ( ) { return ( xScale . rangeBand ( ) - rectPadding ) / 2 ; } ) . attr ( "dy" , function ( d ) { return 20 ; } ) . text ( function ( d ) { return d ; } ) ; |
矩形元素和文字元素的 x 和 y 坐标要特别注意,要结合比例尺给予适当的值。
5. 添加坐标轴的元素
//添加x轴
svg.append("g")
.attr("class","axis")
.attr("transform","translate(" + padding.left + "," + (height - padding.bottom) + ")")
.call(xAxis);
//添加y轴
svg.append("g")
.attr("class","axis")
.attr("transform","translate(" + padding.left + "," + padding.top + ")")
.call(yAxis);
1 2 3 4 5 6 7 8 9 10 11 | //添加x轴 svg . append ( "g" ) . attr ( "class" , "axis" ) . attr ( "transform" , "translate(" + padding . left + "," + ( height - padding . bottom ) + ")" ) . call ( xAxis ) ; //添加y轴 svg . append ( "g" ) . attr ( "class" , "axis" ) . attr ( "transform" , "translate(" + padding . left + "," + padding . top + ")" ) . call ( yAxis ) ; |
坐标轴的位置要结合空白 padding 的值来设定。