一個完整的柱形圖包含三部分:矩形、文字、坐標軸。制作一個實用的柱形圖,內容包括:選擇集、數據綁定、比例尺、坐標軸等內容。
1. 添加 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};
上面定義了一個 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]);
x 軸使用序數比例尺,y 軸使用線性比例尺。要注意兩個比例尺值域的范圍。
3. 定義坐標軸
//定義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; });
矩形元素和文字元素的 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);
坐標軸的位置要結合空白 padding 的值來設定。