2015-09-12 470 views
1

我在d3.js中有條形圖。 x軸標籤的文本太長,並互相重疊,所以我通過將以下4個屬性,以x軸文本旋轉x軸文本:在d3.js條形圖中切斷旋轉的x軸標籤

 .selectAll("text") 
      .style("text-anchor", "end") 
      .attr("dx", "-.8em") 
      .attr("dy", ".15em") 
      .attr("transform", "rotate(-65)"); 

的問題是,該空間的高度分配給x軸的標籤沒有展開,所以現在我只看到了標籤的最後幾個字符。如何擴展分配給x軸標籤的空間,以便擴展顯示所有旋轉的文本?

這裏是完整的d3.js代碼:

var margin = {top: 20, right: 20, bottom: 30, left: 40}, 
    width = 960 - margin.left - margin.right, 
    height = 500 - margin.top - margin.bottom; 

var x = d3.scale.ordinal() 
    .rangeRoundBands([0, width], .1); 

var y = d3.scale.linear() 
    .range([height, 0]); 

var xAxis = d3.svg.axis() 
    .scale(x) 
    .orient("bottom"); 

var yAxis = d3.svg.axis() 
    .scale(y) 
    .orient("left"); 

var svg = d3.select("body").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 + ")"); 

d3.csv("segmentcount.csv", type, function(error, data) { 
    if (error) throw error; 

    x.domain(data.map(function(d) { return d.name; })); 
    y.domain([0, d3.max(data, function(d) { return d.count; })]); 

    svg.append("g") 
     .attr("class", "x axis") 
     .attr("transform", "translate(0," + height + ")") 
     .call(xAxis) 
     .selectAll("text") 
      .style("text-anchor", "end") 
      .attr("dx", "-.8em") 
      .attr("dy", ".15em") 
      .attr("transform", "rotate(-65)"); 

    svg.append("g") 
     .attr("class", "y axis") 
     .call(yAxis) 
    .append("text") 
     .attr("transform", "rotate(-90)") 
     .attr("y", 6) 
     .attr("dy", ".71em") 
     .style("text-anchor", "end") 
     .text("Count"); 

    svg.selectAll(".bar") 
     .data(data) 
    .enter().append("rect") 
     .attr("class", "bar") 
     .attr("x", function(d) { return x(d.name); }) 
     .attr("width", x.rangeBand()) 
     .attr("y", function(d) { return y(d.count); }) 
     .attr("height", function(d) { return height - y(d.count); }) 
     .style('fill', function(d) { return '#' + d.colour }); 
}); 

非常感謝!

+0

你爲什麼不試試水平條形圖,你的X和Y軸將被替換。事實上,許多可視化專家建議在長標籤時使用水平條形圖。如果您仍然認爲垂直條形圖是您想要的條形圖,您可以將鏈接指向您的數據集嗎?然後我可以檢查我是否可以幫助你。 –

回答

2

找到最大標籤高度,並相應地轉換x軸。 (因爲標籤是旋轉的,我們比較標籤的寬度)。

代碼片段來說明:

<html> 
 
<body> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script> 
 
<script> 
 
\t var margin = {top: 20, right: 20, bottom: 30, left: 40}, 
 
\t \t width = 960 - margin.left - margin.right, 
 
\t \t height = 500 - margin.top - margin.bottom; 
 

 
\t var x = d3.scale.ordinal() 
 
\t \t .rangeRoundBands([0, width], .1); 
 

 
\t var xAxis = d3.svg.axis() 
 
\t \t .scale(x) 
 
\t \t .orient("bottom"); 
 

 
\t var data = [ 
 
\t \t {name: "long name", count: 20}, 
 
\t \t {name: "name", count: 30}, 
 
\t \t {name: "even longer name", count: 10}, 
 
\t \t {name: "long name 4", count: 6}, 
 
\t \t {name: "long name 5", count: 17}, 
 
\t \t {name: "long name 6", count: 30}, 
 
\t \t {name: "long name 7", count: 45}]; 
 

 
\t var svg = d3.select("body").append("svg") 
 
\t \t .attr("width", width + margin.left + margin.right) 
 
\t \t .attr("height", height + margin.top + margin.bottom) 
 
\t \t .append("g") 
 
\t \t .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 
 

 
\t x.domain(data.map(function (d) { 
 
\t \t return d.name; 
 
\t })); 
 

 
\t var gXAxis = svg.append("g") 
 
\t \t .attr("class", "x axis") 
 
\t \t .call(xAxis); 
 
\t gXAxis.selectAll("text") 
 
\t \t .style("text-anchor", "end") 
 
\t \t .attr("dx", "-.8em") 
 
\t \t .attr("dy", ".15em") 
 
\t \t .attr("transform", "rotate(-65)"); 
 

 
\t // Find the maxLabel height, adjust the height accordingly and transform the x axis. 
 
\t var maxWidth = 0; 
 
\t gXAxis.selectAll("text").each(function() { 
 
\t \t var boxWidth = this.getBBox().width; 
 
\t \t if (boxWidth > maxWidth) maxWidth = boxWidth; 
 
\t }); 
 
\t height = height - maxWidth; 
 

 
\t gXAxis.attr("transform", "translate(0," + height + ")"); 
 

 
\t var y = d3.scale.linear() 
 
\t \t .range([height, 0]); 
 

 
\t y.domain([0, d3.max(data, function (d) { 
 
\t \t return d.count; 
 
\t })]); 
 

 
\t var yAxis = d3.svg.axis() 
 
\t \t .scale(y) 
 
\t \t .orient("left"); 
 

 
\t svg.append("g") 
 
\t \t .attr("class", "y axis") 
 
\t \t .call(yAxis) 
 
\t \t .append("text") 
 
\t \t .attr("transform", "rotate(-90)") 
 
\t \t .attr("y", 6) 
 
\t \t .attr("dy", ".71em") 
 
\t \t .style("text-anchor", "end") 
 
\t \t .text("Count"); 
 

 
\t svg.selectAll(".bar") 
 
\t \t .data(data) 
 
\t \t .enter().append("rect") 
 
\t \t .attr("class", "bar") 
 
\t \t .attr("x", function (d) { 
 
\t \t \t return x(d.name); 
 
\t \t }) 
 
\t \t .attr("width", x.rangeBand()) 
 
\t \t .attr("y", function (d) { 
 
\t \t \t return y(d.count); 
 
\t \t }) 
 
\t \t .attr("height", function (d) { 
 
\t \t \t return height - y(d.count); 
 
\t \t }) 
 
\t \t .style('fill', "blue"); 
 
</script> 
 
</body> 
 
</html>

+0

謝謝你的工作完美!我很好奇,爲什麼你必須移動所有的y軸的東西,如var y = .....; y.domain .... var yAxis在d3.csv函數中包含的代碼中的較低位置,而x軸定義可以保持最高位置? – Snapula

+0

@Snapula - y軸的高度也發生了變化,以考慮標籤使用的空間,並且範圍使用新的高度。我可以剛剛下移'y.range([height,0]);'。 – brenzy