2016-05-17 166 views
2

我正在创建一个条形图,使用顺序标度为x轴,并使用rangeRoundBands。我正在关注这个示例:https://bl.ocks.org/mbostock/3885304使用rangeRoundBands的d3条形图 - 为什么有外部填充?

但是,我的图表有外部填充 - 在轴的开始和结束处有很大的空间,我希望这些柱完全扩展。下面的屏幕截图显示了我指的以红色圈出的空格。

screenshot of bar chart

如何删除这些空间?我需要我的边距和svg的宽度和高度保持不变。

这里是与图的Plunker因为它现在是: https://plnkr.co/edit/gMw7jvieKSlFbHLTNY9o?p=preview

代码也低于:

<!doctype html> 
    <html> 
    <head> 
     <style> 
     .axis path{ 
      fill: none; 
      stroke: #cccccc; 
      stroke-width: 2px; 
     } 
     .x.axis text{ 
      display:none; 
     } 
     .bar{ 
      fill: blue; 
     } 
     body{ 
      font-family:Helvetica, Arial, sans-serif; 
     } 
     </style> 
    </head> 
    <body> 
    <div id="barchart"></div> 

    <script src="https://d3js.org/d3.v3.min.js"></script> 

    <script> 

    var margin = {top: 20, right: 0, bottom: 50, left: 300}, 
     width = 800 - margin.left - margin.right; 
      height = 465 - margin.top - margin.bottom; 

    var x = d3.scale.ordinal() 
       .rangeRoundBands([0, width], .5); 
    var y = d3.scale.linear().range([height, 0]); 

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

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

    var barsvg = d3.select("#barchart") 
     .append("svg") 
      .attr("width", width + margin.left + margin.right) 
      .attr("height", height + margin.top + margin.bottom) 
     .append("g") 
      .attr("class", "barchartbox") 
      .attr("transform", 
      "translate(" + margin.left + "," + margin.top + ")"); 

    // Get the data 
     d3.json("population.json", function(error, data1) { 

     x.domain(data1.map(function(d) { return d.country; })); 
     y.domain([0, d3.max(data1, function(d) { return d.value; })]); 

     barsvg.selectAll(".axis").remove(); 

     // Add the Y Axis 
     barsvg.append("g") 
      .attr("class", "y axis") 
      .call(yAxis); 

     // Add the X Axis 
     barsvg.append("g") 
      .attr("class", "x axis") 
      .attr("transform", "translate(0," + height + ")") 
      .call(xAxis); 

     var bars = barsvg.selectAll(".bar") 
      .data(data1); 

     bars.enter().append("rect") 
      .attr("class", "bar") 
      .attr("x", function(d) { return x(d.country); }) 
      .attr("width", x.rangeBand()) 
      .attr("y", function(d) {return y(d.value); }) 
      .attr("height", function(d) { return height - y(d.value); }); 

     bars.exit().remove(); 

    }); 


    </script> 
    </body> 
    </html> 

回答

4

你做的事情。

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

而是使用rangeBands。

var x = d3.scale.ordinal() 
      .rangeBands([0, width], .5); 

工作代码here

2

据D3的文档中指定的是,虽然使用rangeRoundBands,舍入引入了附加的外平均而言,与域的长度成比例的填充。

例如,对于大小为50的域,可能需要在任一侧上额外添加25像素的外部填充。将范围范围修改为接近域长度的倍数可能会减少附加填充。

参考:rangeRoundBands

因此,解决办法是设置x轴晶畴后使用下面几行:

var mult = Math.max (1, Math.floor (width/x.domain().length)); 
x.rangeRoundBands ([0, (x.domain().length * mult)], 0.1, 0);