2016-04-30 192 views
9

绘制使用nvd3多轴条形图重叠酒吧。我的问题是酒吧重叠。 y轴上的图表位于左侧,另一个y轴位于右侧。NVD3多轴条形图上绘制

<!DOCTYPE html> 
<html> 
<head> 
    <meta charset="utf-8"> 
    <link href="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.3/nv.d3.css" rel="stylesheet" type="text/css"> 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.2/d3.min.js" charset="utf-8"></script> 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.3/nv.d3.js"></script> 
    <style> 
     text { 
      font: 12px sans-serif; 
     } 
     svg { 
      display: block; 
     } 
     html, body, #chart1, svg { 
      margin: 0px; 
      padding: 0px; 
      height: 100%; 
      width: 100%; 
     } 
    </style> 
</head> 
<body class='with-3d-shadow with-transitions'> 

<div id="chart1" > 
    <svg> </svg> 
</div> 

<script> 

    // var testdata = stream_layers(9,10+Math.random()*100,.1).map(function(data, i) { 
    //  return { 
    //   key: 'Stream' + i, 
    //   values: data.map(function(a){a.y = a.y * (i <= 100 ? 100 : 1); return a}) 
    //  }; 
    // }); 
    var testdata=[{"key":"stream1", "values": [ 
    { 
     "x": 0, 
     "y": 44 
    }, 
    { 
     "x": 1, 
     "y": 10 
    }, 
    { 
     "x": 2, 
     "y": 29 
    }, 
    { 
     "x": 3, 
     "y": 88 
    }, 
    { 
     "x": 4, 
     "y": 25 
    }, 
    { 
     "x": 5, 
     "y": 32 
    }, 
    { 
     "x": 6, 
     "y": 100 
    }, 
    { 
     "x": 7, 
     "y": 52 
    }, 
    { 
     "x": 8, 
     "y": 15 
    }, 
    { 
     "x": 9, 
     "y": 78 
    }, 
    { 
     "x": 10, 
     "y": 42 
    }, 
    { 
     "x": 11, 
     "y": 108 
    }, 
    { 
     "x": 12, 
     "y": 17 
    }, 
    { 
     "x": 13, 
     "y": 23 
    }, 
    { 
     "x": 14, 
     "y": 182 
    }, 
    { 
     "x": 15, 
     "y": 9 
    }, 
    { 
     "x": 16, 
     "y": 25 
    }, 
    { 
     "x": 17, 
     "y": 90 
    }, 
    { 
     "x": 18, 
     "y": 32 
    }, 
    { 
     "x": 19, 
     "y": 138 
    }, 
    { 
     "x": 20, 
     "y": 189 
    }, 
    { 
     "x": 21, 
     "y": 3 
    }, 
    { 
     "x": 22, 
     "y": 16 
    }, 
    { 
     "x": 23, 
     "y": 66 
    }, 
    { 
     "x": 24, 
     "y": 46 
    }, 
    { 
     "x": 25, 
     "y": 27 
    }, 
    { 
     "x": 26, 
     "y": 185 
    }, 
    { 
     "x": 27, 
     "y": 13 
    }, 
    { 
     "x": 28, 
     "y": 12 
    }, 
    { 
     "x": 29, 
     "y": 71 
    }, 
    { 
     "x": 30, 
     "y": 191 
    } 
    ]}, 
    {"key":"stream2","values":[ 
    { 
     "x": 0, 
     "y": 1.1 
    }, 
    { 
     "x": 1, 
     "y": 0.5 
    }, 
    { 
     "x": 2, 
     "y": 2.1 
    }, 
    { 
     "x": 3, 
     "y": 1.5 
    }, 
    { 
     "x": 4, 
     "y": 1.7 
    }, 
    { 
     "x": 5, 
     "y": 2.1 
    }, 
    { 
     "x": 6, 
     "y": 0.75 
    }, 
    { 
     "x": 7, 
     "y": 1.75 
    }, 
    { 
     "x": 8, 
     "y": 1 
    }, 
    { 
     "x": 9, 
     "y": 2.3 
    }, 
    { 
     "x": 10, 
     "y": 2 
    }, 
    { 
     "x": 11, 
     "y": 0.5 
    }, 
    { 
     "x": 12, 
     "y": 1.6 
    }, 
    { 
     "x": 13, 
     "y": 1.8 
    }, 
    { 
     "x": 14, 
     "y": 2.35 
    }, 
    { 
     "x": 15, 
     "y": 2.4 
    }, 
    { 
     "x": 16, 
     "y": 1.8 
    }, 
    { 
     "x": 17, 
     "y": 1 
    }, 
    { 
     "x": 18, 
     "y": 1.25 
    }, 
    { 
     "x": 19, 
     "y": 1.85 
    }, 
    { 
     "x": 20, 
     "y": 0.65 
    }, 
    { 
     "x": 21, 
     "y": 0.75 
    }, 
    { 
     "x": 22, 
     "y": 1.25 
    }, 
    { 
     "x": 23, 
     "y": 2.25 
    }, 
    { 
     "x": 24, 
     "y": 0.5 
    }, 
    { 
     "x": 25, 
     "y": 1.85 
    }, 
    { 
     "x": 26, 
     "y": 1.75 
    }, 
    { 
     "x": 27, 
     "y": 1.15 
    }, 
    { 
     "x": 28, 
     "y": 1.9 
    }, 
    { 
     "x": 29, 
     "y": 2.4 
    }, 
    { 
     "x": 30, 
     "y": 1.5 
    } 
    ]}]; 
    testdata[0].type = "bar"; 
    testdata[0].yAxis = 1; 
    testdata[1].type = "bar"; 
    testdata[1].yAxis = 2; 
    console.log(testdata); 

    nv.addGraph(function() { 
     var chart = nv.models.multiChart() 
      .margin({top: 30, right: 60, bottom: 50, left: 70}) 
      .color(d3.scale.category10().range()) 
      .height(450) 
      .width(1200) 
      .color(d3.scale.category10().range()) 
      .useInteractiveGuideline(true) 
      .interpolate('linear'); 

     chart.xAxis.tickFormat(d3.format(',f')); 
     chart.yAxis1.tickFormat(d3.format(',.1f')); 
     chart.yAxis2.tickFormat(d3.format(',.1f')); 

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

     return chart; 
    }); 

</script> 
</body> 
</html> 

甲Plunkr设置embeded此可以发现here

二组数据,以绘制所述多图形但杆是重叠的。我的输出屏幕截图在这里。

Screenshot of Barchart with two y-axes and different data range.

做的唯一的事情就是调整酒吧的宽度和位置。这些都是选择由类

d3.selectAll ('.bars1Wrap .nv-groups .nv-series-0 rect') 

当我切换轴

testdata[1].yAxis = 1; 

它可以完美运行。 Graph with one y-axis. But the Ranging is lost.

但问题是测距丢失的数据。我需要两个数据集的不同范围。

我试图绘制图表

var g3 = d3.selectAll ('.bars1Wrap .nv-groups .nv-series-0 rect') 
          .attr("width", function(d){ return d/2;}); 

但没有成功...... 赞赏任何帮助后,调整杆的宽度。

回答

2

当然,nvd3是multiChart越野车,当你选择需要显示两个可视化数据集类型“酒吧”

我想说的是,不是这个

testdata[0].type = "bar"; 
testdata[0].yAxis = 1; 
testdata[1].type = "bar"; 
testdata[1].yAxis = 2; 

如果当时

testdata[0].type = "line"; 
testdata[0].yAxis = 1; 
testdata[1].type = "bar"; 
testdata[1].yAxis = 2; 

它工作正常。

这样才能有拆散两个柱状图。 需要做一些开箱扭捏,调用该函数后图表呈现。

function resetBarSize(d1){ 
     //get the width of the bar, and make it half 
     var w2 = d3.select(".bars2Wrap .nv-bar").attr("width")/2; 
     if (!d1){ 
     //initial load d1 will be undefined 
     //in that case make all the bars half 
     d3.selectAll(".bars1Wrap .nv-bar").style("width", w2); 
     d3.selectAll(".bars2Wrap .nv-bar").style("width", w2); 
     //translate the last bar so that there is no overlapping 
     d3.selectAll(".bars2Wrap .nv-bar")[0].forEach(function(d){ 
      var t = d3.transform(d3.select(d).attr("transform")), 
      x = t.translate[0] + w2, 
      y = t.translate[1]; 
      d3.select(d).attr("transform", "translate(" + x +"," + y + ")"); 
     })   
     }else if (d1.yAxis ==2 && d1.disabled){ 
     //in this case axis 2 is disabled or not visible so make bar1 width double. 
     d3.selectAll(".bars1Wrap .nv-bar").style("width", w2 *2); 
     }else if (d1.yAxis ==1 && d1.disabled){ 
     //in this case axis 1 is disabled or not visible so make bar1 width double. 
     d3.selectAll(".bars2Wrap .nv-bar").style("width", w2 *2); 
     } else { 
     //in this case axis both axis is present. Make all the bars half and translate bar 2 so that they don't overlap. 

     d3.selectAll(".bars1Wrap .nv-bar").style("width", w2); 
     d3.selectAll(".bars2Wrap .nv-bar").style("width", w2); 
     d3.selectAll(".bars2Wrap .nv-bar")[0].forEach(function(d){ 
      var t = d3.transform(d3.select(d).attr("transform")), 
      x = t.translate[0] + w2, 
      y = t.translate[1]; 
      d3.select(d).attr("transform", "translate(" + x +"," + y + ")"); 
     }) 
     } 
     return; 
    } 

现在在绘制图表后调用该函数。

nv.dispatch.on('render_end', function(newState) { 
    resetBarSize(); 
    chart.legend.dispatch.on('legendClick', function(newState) { 
     chart.update(); 
     setTimeout(function(){resetBarSize(newState)}); 
}); 

工作代码提前here

+0

感谢的最佳解决方案。我在代码中发现的另外一个问题是,如果我关闭一个图例,则该条必须达到其全部宽度。同样在我的情况下,绘制图表后我不能调用第二个函数。无论如何,我会修改nvd3代码来做这件事情。感谢您指导我寻找最终解决方案。我希望这个答案对别人也是有用的。 –

+1

请检查我的编辑答案,我的代码使得现在的直板全宽,当传说是关闭的。 – Cyril