我正在制作一个传奇,用我在D3 v4中创建的圆环图。到目前为止,我已经设法添加了彩色框和文本,并且图例正在包装到容器中。
图例位于中心,但其中的项目目前是left-aligned。我希望它们在图表中居中,如this和this(在调整大小时,取决于容器宽度)。还有一个奇怪的问题,第一个图例项目在调整大小/重绘时消失。
由于我是D3的完全新手,我在很大程度上依赖现有的例子,而且我找不到任何类似于我想要实现的东西。我使用this plunker作为图表的基础,使用this block作为图例包装代码。
这是我的传奇代码(完整的jsfiddle here):
var legendRectSize = 18;
var legendSpacing = 4;
var legendWrap = svg.append('g')
.attr('class', 'legendwrap');
var legend = svg.select('.legendwrap').selectAll('.legend')
.data(color.domain())
.enter()
.append('g')
.attr('class', 'legend');
legend.append('rect')
.attr('width', legendRectSize)
.attr('height', legendRectSize)
.style('fill', color)
.style('stroke', color);
legend.append('text')
.attr('x', legendRectSize + legendSpacing * 1.5)
.attr('y', legendRectSize - legendSpacing)
.text(function(d) {
return d;
});
var ypos = 0,
newxpos = 0,
maxwidth = 0,
xpos;
legend
.attr("transform", function(d, i) {
var length = d3.select(this).select("text").node().getComputedTextLength() + 40;
xpos = newxpos;
if (width < xpos + length + 0) {
newxpos = xpos = 0;
ypos += 30;
}
newxpos += length;
if (newxpos > maxwidth) maxwidth = newxpos;
return 'translate(' + xpos + ',' + ypos + ')';
});
var legendWidth = d3.select('.legendwrap').node().getBoundingClientRect().width;
legendWrap
.attr("transform", function(d, i) {
return "translate(" + (width - legendWidth) / 2 + "," + (height + 20) + ")";
});
在此先感谢您的任何帮助或建议!
我有同样的问题,在中心对齐图例项目,当谷歌搜索我遇到你的问题。其中有一半答案,我使用您的代码并进行修改以实现中心对齐,如您的问题中所述。
基本上遍历图例项两次,首先计算每行的x偏移量,然后通过将其添加到该行中每个图例项的x位置来使用它。
以下是两个循环,
var ypos = 0, newxpos = 0, rowOffsets = [];
var legendItemsCount = svg.selectAll('.legend').size();
legend.attr("transform", function (d, index) {
var length = d3.select(this).select("text").node().getComputedTextLength() + (legendRectSize + legendSpacing * 3);
if (width < newxpos + length) {
rowOffsets.push((width - newxpos) / 2);
newxpos = 0;
ypos += 30;
}
d.x = newxpos;
d.y = ypos;
d.rowNo = rowOffsets.length;
newxpos += length;
if (index === legendItemsCount - 1)
rowOffsets.push((width - newxpos) / 2);
});
legend.attr("transform", function (d, i) {
var x = d.x + rowOffsets[d.rowNo];
return 'translate(' + x + ',' + d.y + ')';
});