nvd3 中一列饼图中的垂直图例
Vertical legend in pieChart in one column in nvd3
我需要饼图中的垂直图例。
现在库只提供 2 个选项:top/right。
如果使用正确 - 图例在几列中。我需要在一栏中显示图例。
我发现了一个 hack - 更正变换值并将图例放在一列中。
var positionX = 30;
var positionY = 30;
var verticalOffset = 25;
d3.selectAll('.nv-legend .nv-series')[0].forEach(function(d) {
positionY += verticalOffset;
d3.select(d).attr('transform', 'translate(' + positionX + ',' + positionY + ')');
});
它有效,但如果我单击图例对其进行更新 - 图例 return 开始位置(多列)。
解决此问题的方法是在每次单击和双击 .nv-legend 时更新图例。
(function() {
var h = 600;
var r = h / 2;
var arc = d3.svg.arc().outerRadius(r);
var data = [{
"label": "Test 1",
"value": 74
}, {
"label": "Test 2",
"value": 7
}, {
"label": "Test 3",
"value": 7
}, {
"label": "Test 4",
"value": 12
}];
var colors = [
'rgb(178, 55, 56)',
'rgb(213, 69, 70)',
'rgb(230, 125, 126)',
'rgb(239, 183, 182)'
]
nv.addGraph(function() {
var chart = nv.models.pieChart()
.x(function(d) {
return d.label
})
.y(function(d) {
return d.value
})
.color(colors)
.showLabels(true)
.labelType("percent");
d3.select("#chart svg")
.datum(data)
.transition().duration(1200)
.call(chart);
var svg = d3.select("#chart svg");
function updateLegendPosition() {
svg.selectAll(".nv-series")[0].forEach(function(d, i) {
d3.select(d).attr("transform", "translate(0," + i * 15 + ")");
})
}
svg.select('.nv-legend').on("click", function() {
updateLegendPosition();
});
svg.select('.nv-legend').on("dblclick", function() {
updateLegendPosition();
});
updateLegendPosition();
return chart;
});
}())
@import url(http://fonts.googleapis.com/css?family=Droid+Sans|Droid+Sans+Mono);
#chart svg {
height: 600px;
}
.nv-label text{
font-family: Droid Sans;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.1.15-beta/nv.d3.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.1.15-beta/nv.d3.min.js"></script>
<div id="chart">
<svg></svg>
</div>
快速破解。
修改nv.d3.js
第 11149 行(其他版本可能有所不同)
// Legend
if (showLegend) {
if (legendPosition === "top") {
添加另一个垂直选项
} else if (legendPosition === "vertical") {
var legendWidth = nv.models.legend().width();
var positionY = 10;
var positionX = availableWidth - 200;
var verticalOffset = 20;
if ( margin.top != legend.height()) {
margin.top = legend.height();
availableHeight = nv.utils.availableHeight(height, container, margin);
}
legend.width(200);
// legend.height(availableHeight).key(pie.x());
positionY += verticalOffset;
wrap.select('.nv-legendWrap')
.datum(data)
.call(legend)
.attr('transform', 'translate(' + positionX + ',' + positionY + ')');
}
也可以玩变量。
与 Legends 配合使用非常好。对于很长的传说列表。更多的逻辑想要应用。
我知道这是一个老问题,但我遇到了同样的问题并最终来到这里。 None 的答案对我有用,但我能够修改 Ranijth 的答案并让它工作(并且看起来不错)。
else if (legendPosition === "vertical") {
var pad=50;
var legendWidth=150; //might need to change this
legend.height(availableHeight).key(pie.x());
legend.width(legendWidth);
wrap.select('.nv-legendWrap')
.datum(data)
.call(legend)
.attr('transform', 'translate('+ ((availableWidth / 2)+legendWidth+pad)+','+pad+')');
}
我需要饼图中的垂直图例。 现在库只提供 2 个选项:top/right。 如果使用正确 - 图例在几列中。我需要在一栏中显示图例。
我发现了一个 hack - 更正变换值并将图例放在一列中。
var positionX = 30;
var positionY = 30;
var verticalOffset = 25;
d3.selectAll('.nv-legend .nv-series')[0].forEach(function(d) {
positionY += verticalOffset;
d3.select(d).attr('transform', 'translate(' + positionX + ',' + positionY + ')');
});
它有效,但如果我单击图例对其进行更新 - 图例 return 开始位置(多列)。
解决此问题的方法是在每次单击和双击 .nv-legend 时更新图例。
(function() {
var h = 600;
var r = h / 2;
var arc = d3.svg.arc().outerRadius(r);
var data = [{
"label": "Test 1",
"value": 74
}, {
"label": "Test 2",
"value": 7
}, {
"label": "Test 3",
"value": 7
}, {
"label": "Test 4",
"value": 12
}];
var colors = [
'rgb(178, 55, 56)',
'rgb(213, 69, 70)',
'rgb(230, 125, 126)',
'rgb(239, 183, 182)'
]
nv.addGraph(function() {
var chart = nv.models.pieChart()
.x(function(d) {
return d.label
})
.y(function(d) {
return d.value
})
.color(colors)
.showLabels(true)
.labelType("percent");
d3.select("#chart svg")
.datum(data)
.transition().duration(1200)
.call(chart);
var svg = d3.select("#chart svg");
function updateLegendPosition() {
svg.selectAll(".nv-series")[0].forEach(function(d, i) {
d3.select(d).attr("transform", "translate(0," + i * 15 + ")");
})
}
svg.select('.nv-legend').on("click", function() {
updateLegendPosition();
});
svg.select('.nv-legend').on("dblclick", function() {
updateLegendPosition();
});
updateLegendPosition();
return chart;
});
}())
@import url(http://fonts.googleapis.com/css?family=Droid+Sans|Droid+Sans+Mono);
#chart svg {
height: 600px;
}
.nv-label text{
font-family: Droid Sans;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.1.15-beta/nv.d3.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.1.15-beta/nv.d3.min.js"></script>
<div id="chart">
<svg></svg>
</div>
快速破解。
修改nv.d3.js 第 11149 行(其他版本可能有所不同)
// Legend
if (showLegend) {
if (legendPosition === "top") {
添加另一个垂直选项
} else if (legendPosition === "vertical") {
var legendWidth = nv.models.legend().width();
var positionY = 10;
var positionX = availableWidth - 200;
var verticalOffset = 20;
if ( margin.top != legend.height()) {
margin.top = legend.height();
availableHeight = nv.utils.availableHeight(height, container, margin);
}
legend.width(200);
// legend.height(availableHeight).key(pie.x());
positionY += verticalOffset;
wrap.select('.nv-legendWrap')
.datum(data)
.call(legend)
.attr('transform', 'translate(' + positionX + ',' + positionY + ')');
}
也可以玩变量。 与 Legends 配合使用非常好。对于很长的传说列表。更多的逻辑想要应用。
我知道这是一个老问题,但我遇到了同样的问题并最终来到这里。 None 的答案对我有用,但我能够修改 Ranijth 的答案并让它工作(并且看起来不错)。
else if (legendPosition === "vertical") {
var pad=50;
var legendWidth=150; //might need to change this
legend.height(availableHeight).key(pie.x());
legend.width(legendWidth);
wrap.select('.nv-legendWrap')
.datum(data)
.call(legend)
.attr('transform', 'translate('+ ((availableWidth / 2)+legendWidth+pad)+','+pad+')');
}