nvd3 multibarchart 最后一根柱线隐藏不可见

nvd3 multibarchart last bar is hidden not visible

基于this Whosebug answer,我试图复制重要部分以获得时间轴的适当比例。我将 multibarcharts 用于多重图表,从几条记录到数百条记录,X 轴包含从 1930 年到今天的数据。

我是这样复制的,但是有两个问题:

  1. 最后一个柱总是在图表之外
  2. 条重叠,我可以通过更改numTicks来部分修复,但是没有更好的方法吗?

    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"></script>
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.1/nv.d3.js"></script>
    <script type="text/javascript">
        nv.addGraph(function() {
          var data = [{
            "values": [
    
                    { x: new Date("1999-12-01"), y: 42.27 } , 
    
                    { x: new Date("2000-12-01"), y: 41.73 } , 
    
                    { x: new Date("2001-12-01"), y: 41.34 } , 
    
                    { x: new Date("2002-12-01"), y: 41.84 } , 
    
                    { x: new Date("2003-12-01"), y: 43.93 } , 
    
                    { x: new Date("2004-12-01"), y: 42.18 } , 
    
                    { x: new Date("2005-12-01"), y: 42.31 } , 
    
                    { x: new Date("2006-12-01"), y: 43.14 } , 
    
                    { x: new Date("2007-12-01"), y: 43.24 } , 
    
                    { x: new Date("2008-12-01"), y: 39.30 } , 
    
                    { x: new Date("2009-12-01"), y: 43.80 } , 
    
                    { x: new Date("2010-12-01"), y: 44.10 } , 
    
                    { x: new Date("2011-12-01"), y: 54.10 } , 
    
                    { x: new Date("2012-12-01"), y: 62.10 } , 
    
                    { x: new Date("2013-12-01"), y: 56.70 } , 
    
                    { x: new Date("2014-12-01"), y: 45 } , 
    
                    { x: new Date("2015-12-01"), y: 55.60 } , 
    
                    { x: new Date("2026-12-01"), y: 54.40 } , 
    
                    { x: new Date("2027-12-01"), y: 57 } 
    
            ],
            "bar": true,
            "key": "Payout Ratio"
          }];
    
          var chart = nv.models.multiBarChart(),
              container = d3.select('#payout_ratio_chart svg'),
              availableWidth,
              numTicks = data[0].values.length,
              xScale = d3.time.scale();
    
          function updateAvailableWidth() {
              availableWidth = (chart.width() || parseInt(container.style('width')) || 960) - chart.margin().left - chart.margin().right;
          }
          updateAvailableWidth();
          nv.utils.windowResize(updateAvailableWidth);
    
          xScale.rangeBands = xScale.range;
          xScale.rangeBand = function() { return (1 - chart.groupSpacing()) * availableWidth / numTicks; };
    
          chart.multibar.xScale(xScale);
    
          var last_date = data[0].values[data[0].values.length-1].x;
          last_date.setMonth(last_date.getMonth() + 10);
          chart.xDomain([data[0].values[0].x, last_date]);
    
          chart.xAxis.tickFormat(function(d){ return d3.time.format('%b %Y')(new Date(d)); });
          chart.yAxis.tickFormat(d3.format(',f'));
    
    
          chart.showControls(false);
    
          container.datum(data).transition().duration(500).call(chart);
    
          nv.utils.windowResize(chart.update);
    
          return chart;
      });
    </script>
    

https://jsfiddle.net/lucas03/poamvfke/4/

检查下面派生自您发布的代码的代码:

nv.addGraph(function() {
  var data = [{
    "values": [

      {
        x: new Date("1999-12-01"),
        y: 42.27
      },

      {
        x: new Date("2000-12-01"),
        y: 41.73
      },

      {
        x: new Date("2001-12-01"),
        y: 41.34
      },

      {
        x: new Date("2002-12-01"),
        y: 41.84
      },

      {
        x: new Date("2003-12-01"),
        y: 43.93
      },

      {
        x: new Date("2004-12-01"),
        y: 42.18
      },

      {
        x: new Date("2005-12-01"),
        y: 42.31
      },

      {
        x: new Date("2006-12-01"),
        y: 43.14
      },

      {
        x: new Date("2007-12-01"),
        y: 43.24
      },

      {
        x: new Date("2008-12-01"),
        y: 39.30
      },

      {
        x: new Date("2009-12-01"),
        y: 43.80
      },

      {
        x: new Date("2010-12-01"),
        y: 44.10
      },

      {
        x: new Date("2011-12-01"),
        y: 54.10
      },

      {
        x: new Date("2012-12-01"),
        y: 62.10
      },

      {
        x: new Date("2013-12-01"),
        y: 56.70
      },

      {
        x: new Date("2014-12-01"),
        y: 45
      },

      {
        x: new Date("2015-12-01"),
        y: 55.60
      },

      {
        x: new Date("2026-12-01"),
        y: 54.40
      },

      {
        x: new Date("2027-12-01"),
        y: 57
      }

    ],
    "bar": true,
    "key": "Payout Ratio"
  }];


  var fDate = data[0].values[0].x,
  lDate = new Date(data[0].values[data[0].values.length - 1].x);
  lDate.setFullYear(lDate.getFullYear() + 1);
  
  var chart = nv.models.multiBarChart()
    .showControls(false)
    .reduceXTicks(false)
    .rotateLabels(-45),
    container = d3.select('#payout_ratio_chart svg'),
    availableWidth,
    numTicks = (lDate.getFullYear() - fDate.getFullYear()) + 1,
    xScale = d3.time.scale();

  function updateAvailableWidth() {
    availableWidth = (chart.width() || parseInt(container.style('width')) || 960) - chart.margin().left - chart.margin().right;
  }
  updateAvailableWidth();

  xScale.rangeBands = xScale.range;
  xScale.rangeBand = function() {
    return (1 - chart.groupSpacing()) * availableWidth / numTicks;
  };

  chart.multibar.xScale(xScale);

  chart.xDomain([fDate, lDate]);

  chart.xAxis.tickFormat(function(d) {
    return d3.time.format('%b %Y')(new Date(d));
  });
  chart.yAxis.tickFormat(d3.format(',f'));

  container.datum(data).transition().duration(500).call(chart);

  nv.utils.windowResize(function() {
    updateAvailableWidth();
    chart.update();
  });

  return chart;
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.1/nv.d3.css" rel="stylesheet"/>
<div id="payout_ratio_chart">
  <svg style="width:100%;height:400px" />
</div>

<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.1/nv.d3.js"></script>

修正:

您的代码和固定代码之间的唯一区别是 fDatelDatenumTicks 的计算方式。

fDate 是您的开始日期,而 lDate 是下一年数据的最后日期。最后,numTicksfDatelDate 的年份之间的差异。

查找 jsfiddle here.

您有一个条形图,因此您必须为不存在的日期插入数据点。

我在这里进行了硬编码,但您可以编写一些逻辑来添加缺失的日期。对于其他一些数据系列,您可以获取该系列缺失日期的值。

nvd3 以最小 1px 的高度绘制这些条,因此添加样式以隐藏这些小条

.nvd3 .nv-groups rect[height="1"] {
    opacity: 0;
}

nv.addGraph(function() {
  var data = [{
    "values": [
      { x: new Date("1999-12-01"), y: 42.27 },
      { x: new Date("2000-12-01"), y: 41.73 },
      { x: new Date("2001-12-01"), y: 41.34 },
      { x: new Date("2002-12-01"), y: 41.84 },
      { x: new Date("2003-12-01"), y: 43.93 },
      { x: new Date("2004-12-01"), y: 42.18 },
      { x: new Date("2005-12-01"), y: 42.31 },
      { x: new Date("2006-12-01"), y: 43.14 },
      { x: new Date("2007-12-01"), y: 43.24 },
      { x: new Date("2008-12-01"), y: 39.30 },
      { x: new Date("2009-12-01"), y: 43.80 },
      { x: new Date("2010-12-01"), y: 44.10 },
      { x: new Date("2011-12-01"), y: 54.10 },
      { x: new Date("2012-12-01"), y: 62.10 },
      { x: new Date("2013-12-01"), y: 56.70 },
      { x: new Date("2014-12-01"), y: 45 },
      { x: new Date("2015-12-01"), y: 55.60 },
      { x: new Date("2016-12-01"), y: 0 },
      { x: new Date("2017-12-01"), y: 0 },
      { x: new Date("2018-12-01"), y: 0 },
      { x: new Date("2019-12-01"), y: 0 },
      { x: new Date("2020-12-01"), y: 0 },
      { x: new Date("2021-12-01"), y: 0 },
      { x: new Date("2022-12-01"), y: 0 },
      { x: new Date("2023-12-01"), y: 0 },
      { x: new Date("2024-12-01"), y: 0 },
      { x: new Date("2025-12-01"), y: 0 },
      { x: new Date("2026-12-01"), y: 54.40 },
      { x: new Date("2027-12-01"), y: 57 }
    ],
    "bar": true,
    "key": "Payout Ratio"
  }];

  var chart = nv.models.multiBarChart(),
    container = d3.select('#payout_ratio_chart svg');

  chart.xAxis.tickFormat(function(d) {
    return d3.time.format('%b %Y')(new Date(d));
  });
  chart.yAxis.tickFormat(d3.format(',f'));

  chart.showControls(false);

  container.datum(data).transition().duration(500).call(chart);

  nv.utils.windowResize(chart.update);

  return chart;
});
.nvd3 .nv-groups rect[height="1"] {
    opacity: 0;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.1/nv.d3.css" rel="stylesheet"/>
<div id="payout_ratio_chart">
  <svg style="width:100%;height:400px" />
</div>

<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.1/nv.d3.js"></script>