nvd3 multibarchart最后一个栏被隐藏不可见

时间:2018-12-01 22:47:05

标签: d3.js nvd3.js

基于this stackoverflow answer,我正在尝试复制必要的部分,以使时间表更合适。我将multibarcharts用于多重图形,从很少的记录到X轴具有从1930年至今的数据的数百条记录。

我已经像这样复制了它,但是有两个问题:

  1. 最后一个柱始终在图形之外
  2. 条重叠,我可以通过更改<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> 来部分修复,但是没有更好的方法吗?

                    

    {{1}}

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

2 个答案:

答案 0 :(得分:1)

签出下面的代码,这些代码来自您发布的代码:

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

答案 1 :(得分:0)

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

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

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>