简体   繁体   English

改变 D3 条形图中特定条形之间的间隙

[英]Varying the gaps between specific bars in a D3 bar chart

I have a bar chart where I want to make the gap more pronounced between the 6th and the bar in my chart and the 12th and 13th bar in my chart.我有一个条形图,我想让图表中的第 6 个和条形与图表中的第 12 个和第 13 个条形之间的差距更加明显。 Right now I'm using .rangeRoundBands which results in even padding and there doesn't seem to be a way to override that for specific rectangles (I tried appending padding and margins to that particular rectangle with no success).现在我正在使用.rangeRoundBands ,它会产生均匀的填充,而且似乎没有办法为特定的矩形覆盖它(我尝试将填充和边距附加到那个特定的矩形,但没有成功)。

Here's a jsfiddle of the graph这是图表的jsfiddle

And my code for generating the bands and the bars themselves:我自己生成条带和条形的代码:

    var yScale = d3.scale.ordinal()
                    .domain(d3.range(dataset.length))
                    .rangeRoundBands([padding, h- padding], 0.05);

    svg.selectAll("rect.bars")
                .data(dataset)
                .enter()
                .append("rect")
                .attr("class", "bars")
                .attr("x", 0 + padding)
                .attr("y", function(d, i){
                    return yScale(i);
                })
                .attr("width", function(d) {
                    return xScale(d.values[0]);
                })
                .attr("height", yScale.rangeBand())

You can provide a function to calculate the height based on data and index. 您可以提供根据数据和索引计算高度的功能。 That is, you could use something like 也就是说,您可以使用类似

.attr("height", function(d,i) {
            if(i == 5) {
                return 5;
            }
            return yScale.rangeBand();
        })

to make the 6th bar 5 pixels high. 将第6个小节设为5像素高。 You can of course base this value on yScale.rangeBand() , ie subtract a certain number to make the gap wider. 您当然可以将此值基于yScale.rangeBand() ,即减去某个数字以使间隙变宽。

Here's a function for D3 v6 that takes a band scale and returns a scale with gaps.这是 D3 v6 的 function,它采用波段比例并返回带间隙的比例。

// Create a new scale from a band scale, with gaps between groups of items
//
// Parameters:
//       scale:            a band scale
//       where:            how many items should be before each gap?
//       gapSize:          gap size as a fraction of scale.size()
function scaleWithGaps(scale, where, gapSize) {
  scale = scale.copy();
  var offsets = {};
  var i = 0;
  var offset = -(scale.step() * gapSize * where.length) / 2;
  scale.domain().forEach((d, j) => {
    if (j == where[i]) {
      offset += scale.step() * gapSize;
      ++i;
    }
    offsets[d] = offset;
  });
  var newScale = value => scale(value) + offsets[value];
  // Give the new scale the methods of the original scale
  for (var key in scale) {
    newScale[key] = scale[key];
  }
  newScale.copy = function() {
    return scaleWithGaps(scale, where, gapSize);
  };
  return newScale;
}

To use this, first create a band scale...要使用它,首先要创建一个带刻度...

let y_ = d3
  .scaleBand()
  .domain(data.map(d => d.name))
  .range([margin.left, width - margin.right])
  .paddingInner(0.1)
  .paddingOuter(0.5)

... then call scaleWithGaps() on it: ...然后在其上调用scaleWithGaps()

y = scaleWithGaps(y_, [1, 5], .5)

You can create a bar chart in the normal way with this scale.您可以使用此比例以正常方式创建条形图。

Here is an example on Observable. 是一个关于 Observable 的例子。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM