D3 v4 - 制作固定宽度的水平条形图

D3 v4 - make a horizontal bar chart with fixed width

我使用 d3 v4 制作了一个水平条形图,除了一件事外它工作正常。我无法固定条形高度。我目前正在使用 bandwidth() 并且如果我用固定值替换它说 (15) 问题是它不与 y 轴对齐 label/tick http://jsbin.com/gigesi/3/edit?html,css,js,output

var w = 200;
var h = 400;
var svg = d3.select("body").append("svg")
            .attr("width", w)
            .attr("height", h)
            .attr("transform", "translate(80,30)");

var data = [
            {Item: "Item 1", count: "11"},
            {Item: "Item 2", count: "14"},
            {Item: "Item 3", count: "10"},
            {Item: "Item 4", count: "14"}
           ];

var xScale = d3.scaleLinear()
               .rangeRound([0,w])
               .domain([0, d3.max(data, function(d) {
                   return d.count;
               })]);

var yScale = d3.scaleBand()
               .rangeRound([h,0]).padding(0.2)
               .domain(data.map(function(d) {
                   return d.Item;
             }));

var yAxis = d3.axisLeft(yScale);
svg.append('g')
   .attr('class','axis')
   .call(yAxis);
svg.selectAll('rect')
   .data(data)
   .enter()
   .append('rect')
       .attr('width', function(d,i) {
           return xScale(d.count);
        })
       .attr('height', yScale.bandwidth())
       .attr('y', function(d, i) {
           return yScale(d.Item);
       }).attr("fill","#000");

您提供的link中的y轴似乎偏离了SVG。 (也许您有 overflow: visible; 的 SVG。

无论如何,我在图表中添加了一些边距,以便可以看到整个图表。在这里(忽略link描述):

DEMO: H BAR CHART WITH HEIGHT POSITIONING TO THE TICKS

相关代码改动:

  1. 当您使用比例尺时,高度是在比例尺内计算的。你只需要使用 .bandWidth().

    .attr('height', yScale.bandwidth())
    
  2. 添加边距并变换轴和条形图以使整个图表可见: :我正在分配边距,以便 y-axis 位于 SVG 的视口内,这样也可以更轻松地根据刻度值调整左边距。我认为这应该是一种标准做法。 此外,如果您注意到,rects 现在是 <g class="bars"></g> 的一部分。如果愿意,请检查 DOM。这对于包含大量元素的复杂图表很有用,但它始终是一个好习惯。

    var margin = {top: 10, left: 40, right: 30, bottom: 10};
    
    var xScale = d3.scaleLinear()
          .rangeRound([0,w-margin.left-margin.right])
    
    var yScale = d3.scaleBand()
         .rangeRound([h-margin.top-margin.bottom,0]).padding(0.2)
    
    svg.append('g')
       .attr('class','axis')
       .attr('transform', 'translate(' + margin.left+', '+margin.top+')')
    

尝试更改数据,条形高度 将根据刻度进行调整和对齐。希望这可以帮助。如果您有任何问题,请告诉我。

编辑: 最初,我认为您在将条形图放置在 y 刻度的中心时遇到了问题,但正如您所说,您需要固定高度的条形图,这里是对上述代码的快速补充,可以让您做到这一点。我将很快添加另一种使用填充(内部和外部)的方法。

Updated JS BIN

为了将条形图精确定位在轴刻度的位置,我将条形图从顶部移动到 刻度的带宽 ,这是由 .bandWidth() 计算得出的它的位置将从刻度开始,现在从中减去 所需高度的一半 ,以便条形中心与刻度 y 匹配。希望这能解释。

.attr('height', 15)
.attr('transform', 'translate(0, '+(yScale.bandwidth()/2-7.5)+')')