NVD3 多轴条形图在绘图上重叠条形图
NVD3 Multiple Axis Barchart Overlapping Bars on Drawing
使用 nvd3 绘制多轴条形图。我的问题是条形重叠。在图表中,y 轴在左侧,另一个 y 轴在右侧。
<!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 for this can be found here。
两组数据绘制多图,但条形重叠。我的输出屏幕截图在这里。
唯一要做的就是调整条形的宽度和位置。这些可以通过 class
选择
d3.selectAll ('.bars1Wrap .nv-groups .nv-series-0 rect')
当我将轴切换到
testdata[1].yAxis = 1;
效果很好。
但问题是数据丢失的范围。我需要两个数据集的不同范围。
我尝试在绘制图表后调整条形的宽度
喜欢
var g3 = d3.selectAll ('.bars1Wrap .nv-groups .nv-series-0 rect')
.attr("width", function(d){ return d/2;});
但是没有成功...
任何帮助表示赞赏。
当然,nvd3 在 multiChart
上有问题,当您 select 为需要显示的两个可视化数据集键入 "bar" 时.
我要说的是,而不是这个
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;
它工作正常。
因此为了让两个条形图不堆叠。
需要做一些开箱即用的调整,调用此函数 post 图表已呈现。
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
使用 nvd3 绘制多轴条形图。我的问题是条形重叠。在图表中,y 轴在左侧,另一个 y 轴在右侧。
<!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 for this can be found here。
两组数据绘制多图,但条形重叠。我的输出屏幕截图在这里。
唯一要做的就是调整条形的宽度和位置。这些可以通过 class
选择d3.selectAll ('.bars1Wrap .nv-groups .nv-series-0 rect')
当我将轴切换到
testdata[1].yAxis = 1;
效果很好。
但问题是数据丢失的范围。我需要两个数据集的不同范围。
我尝试在绘制图表后调整条形的宽度
喜欢
var g3 = d3.selectAll ('.bars1Wrap .nv-groups .nv-series-0 rect')
.attr("width", function(d){ return d/2;});
但是没有成功... 任何帮助表示赞赏。
当然,nvd3 在 multiChart
上有问题,当您 select 为需要显示的两个可视化数据集键入 "bar" 时.
我要说的是,而不是这个
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;
它工作正常。
因此为了让两个条形图不堆叠。 需要做一些开箱即用的调整,调用此函数 post 图表已呈现。
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