我正在尝试更换d3图例绘制功能,该功能使用.data()
手动创建和将图例元素放置到一个。
我能够让一切正常工作,除了一件事:通过手动循环数据数组,我能够通过使用currentX
跟踪变量确保图例元素之间的间距相等。然而,对于.data()
,我无法引用其他元素,并且必须使用设计师讨厌的固定宽度框(我也是)。
鉴于下面的代码,我如何使新代码(顶行)的行为与旧代码(底行)完全相同?
(请不要建议我使用图例库,在提取此测试用例的"真实"代码中有很多事件处理和更多内容)
var config = {
circleYCenter: 170,
circleXCenter: 150,
legendMarginTop: 52,
legendMarginInner: 18,
legendDotHeight: 8,
legendDotWidth: 16,
};
var colors = {
'lightyellow': '#FEE284',
'darkblue': '#2872A3',
'dirtyorange': '#E68406',
};
function drawLegend(container, map) {
var legendGroup = container.append("g").attr({
"transform": "translate(0,50)",
"class": "legendGroup"
});
//New code
var elGroup = legendGroup.selectAll("g").data(map).enter().append("g").attr({
transform: function(d, i) {
return "translate(" + (i * 100) + ",0)"
}
});
elGroup.append("text").text(function(d) {
return d.label;
}).attr({
x: config.legendDotWidth + config.legendMarginInner
});
elGroup.append("rect").attr({
x: 0,
width: config.legendDotWidth,
y: -5,
height: config.legendDotHeight,
"fill": function(d) {
return d.color;
}
});
//Old code
var currentX = 0;
map.forEach(function(el, key) {
var elGroup = legendGroup.append("g").attr("transform", "translate(" + currentX + ",100)");
elGroup.append("rect").attr({
x: 0,
width: config.legendDotWidth,
y: -5,
height: config.legendDotHeight,
"fill": el.color
});
elGroup.append("text").attr({
"x": (config.legendDotWidth + 10),
"y": 0,
"alignment-baseline": "middle"
}).text(el.label);
currentX += elGroup.node().getBBox().width + config.legendMarginInner;
});
}
drawLegend(d3.select("svg"), [{
label: "foo",
color: colors.dirtyorange
}, {
label: "Banana",
color: colors.darkblue
}, {
label: "baz",
color: colors.lightyellow
}]);

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg width=600 height=300></svg>
&#13;
答案 0 :(得分:1)
首先组成小组:
var elGroup = legendGroup.selectAll("g").data(map).enter().append("g");
正如您所做的那样附加text
和rect
DOM:
elGroup.append("text").text(function(d) {
return d.label;
}).attr({
x: config.legendDotWidth + config.legendMarginInner
});
elGroup.append("rect").attr({
x: 0,
width: config.legendDotWidth,
y: -5,
height: config.legendDotHeight,
"fill": function(d) {
return d.color;
}
});
现在使用组的bbox将翻译添加到组中。
var currentX = 0;
elGroup.attr({
transform: function(d, i) {
var ret = "translate(" + currentX + ",0)"
currentX += this.getBBox().width + config.legendMarginInner;
return ret;
}
});
工作代码here