如何将NVD3条形图转换成面积折线图?

How to convert NVD3 bar graphs into area line graphs?

我的plnkr.

目前我的 NVD3 图表是基于他们的 linePlusBarChart

问题是,在我的真实应用程序中,我实际上有更多的条形刻度数据 (4000+),因此条形变得超细并且很难看到,因此我需要改为使用线面积图。 (这在我的 plnkr 示例中并不明显,因为它为条形图使用了一个小的假样本大小。)

有没有其他人尝试过这样做?将条形图转换为线面积图?

代码:

var data = [{
  "key": "Price",
  "color": "#4C73FF",
  "values": [
    [1443621600000, 71.89],
    [1443619800000, 75.51],
    [1443618000000, 68.49],
    [1443616200000, 62.72],
    [1443612600000, 70.39],
    [1443610800000, 59.77]
  ]
}, {
  "key": "Quantity",
  "bar": true,
  "values": [
    [1136005200000, 1],
    [1138683600000, 2],
    [1141102800000, 1],
    [1143781200000, 0],
    [1146369600000, 1],
    [1149048000000, 0]
  ]
}];

nv.addGraph(function() {
  var chart = nv.models.linePlusBarChart()
    .margin({
      top: 20,
      right: 40,
      bottom: 50,
      left: 40
    })
    .x(function(d, i) {
      return i
    })
    .y(function(d) {
      return d[1]
    })
    .color(d3.scale.category10().range());

  chart.xAxis.tickFormat(function(d) {
    var dx = data[0].values[d] && data[0].values[d][0] || 0;
    // return time in hours:
    return d3.time.format('%I:%M')(new Date(dx));
  });

  chart.y1Axis
    .tickFormat(d3.format(',f'));

  chart.y2Axis
    .tickFormat(function(d) {
      return '$' + d3.format(',f')(d)
    });

  chart.bars.forceY([0]);
  chart.lines.interactive(false);
  chart.height(300);

  d3.select('#chart svg')
    .datum(data)
    .transition().duration(500)
    .call(chart);

  chart.update();
  nv.utils.windowResize(chart.update);

  return chart;
});

开箱即用,NVD3 为您提供 multiChart (example),它结合了 line/bar/area 个图表。注:

  • yAxis1在左边,yAxis2在右边。
  • 后缀为“1”的成分图使用左y轴:lines1bars1stack1 .
  • 您不能使用 forceY 因为从 1.8.1 开始 it's not supported by the stacked area chart。您需要手动计算数据的 y 域并使用 yDomain1yDomain2.
  • 在图表上设置它们

最后,这是一个使用您的示例数据的简单多图表 (NVD3 1.8.1),左侧是数量(面积),右侧是价格(线):

var data = [{
  "key": "Price",
  "type": "line",
  "yAxis": 2,
  "values": [
    [1443621600000, 71.89],
    [1443619800000, 75.51],
    [1443618000000, 68.49],
    [1443616200000, 62.72],
    [1443612600000, 70.39],
    [1443610800000, 59.77],
  ]
}, {
  "key": "Quantity",
  "type": "area",
  "yAxis": 1,
  "values": [
    [1136005200000, 1],
    [1138683600000, 2],
    [1141102800000, 1],
    [1143781200000, 0],
    [1146369600000, 1],
    [1149048000000, 0],
  ]
}];

data = data.map(function(series) {
  series.values = series.values.map(function(d) {
    return {
      x: d[0],
      y: d[1]
    }
  });
  return series;
});

nv.addGraph(function() {
  var chart = nv.models.multiChart()
    .margin({
      top: 20,
      right: 40,
      bottom: 50,
      left: 40
    })
    .yDomain1([0, 10])
    .yDomain2([0, 100]) // hard-coded :<
    .interpolate("linear") // don't smooth out the lines
    .color(d3.scale.category10().range());

  chart.xAxis.tickFormat(function(d) {
    return d3.time.format('%I:%M')(new Date(d));
  });
  chart.yAxis1.tickFormat(d3.format(',f'));
  chart.yAxis2.tickFormat(function(d) {
    return '$' + d3.format(',f')(d)
  });

  chart.lines2.interactive(false); // line chart, right axis

  d3.select('svg#chart')
    .datum(data)
    .transition().duration(500).call(chart);

  chart.update();
  nv.utils.windowResize(chart.update);
  return chart;
});
text {
  font: 12px sans-serif;
}
svg {
  display: block;
}
html,
body,
svg#chart {
  margin: 0px;
  padding: 0px;
  height: 100%;
  width: 100%;
}
<link href="http://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.1/nv.d3.min.css" rel="stylesheet" />
<script src="http://cdnjs.cloudflare.com/ajax/libs/d3/3.5.2/d3.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.1/nv.d3.min.js"></script>
<svg id="chart"></svg>