d3.js:具有动态元素宽度的图例

d3.js:具有动态元素宽度的图例,d3.js,D3.js,我正在尝试将使用手动创建和放置图例元素的d3图例绘图功能替换为使用.data()的功能 我能够让一切正常工作,除了一件事:通过手动循环数据数组,我能够通过使用currentXtracker变量确保图例元素之间的间距相等。但是,使用.data()时,我无法引用其他元素,必须使用固定宽度的框,这是设计师(我也是)所不喜欢的 给定下面的代码,如何使新代码(第一行)的行为与旧代码(第二行)完全相同 (请不要建议我使用图例库,在提取此测试用例的“真实”代码中有大量事件处理和更多内容) var配置={ 环

我正在尝试将使用手动创建和放置图例元素的d3图例绘图功能替换为使用
.data()
的功能

我能够让一切正常工作,除了一件事:通过手动循环数据数组,我能够通过使用
currentX
tracker变量确保图例元素之间的间距相等。但是,使用
.data()
时,我无法引用其他元素,必须使用固定宽度的框,这是设计师(我也是)所不喜欢的

给定下面的代码,如何使新代码(第一行)的行为与旧代码(第二行)完全相同

(请不要建议我使用图例库,在提取此测试用例的“真实”代码中有大量事件处理和更多内容)

var配置={
环路中心:170,
循环中心:150,
legendMarginTop:52,
legendMarginInner:18,
legendDotHeight:8,
legendDotWidth:16,
};
变量颜色={
“浅黄色”:“FEE284”,
“暗蓝色”:“2872A3”,
“脏橙色”:“E68406”,
};
函数drawLegend(容器、地图){
var legendGroup=container.append(“g”).attr({
“转换”:“转换(0,50)”,
“类”:“legendGroup”
});
//新代码
var elGroup=legendGroup.selectAll(“g”).data(map.enter().append(“g”).attr({
变换:函数(d,i){
返回“translate(“+(i*100)+”,0)”
}
});
elGroup.append(“text”).text(函数(d){
返回d.标签;
})艾特先生({
x:config.legendDotWidth+config.legendMarginInner
});
elGroup.append(“rect”).attr({
x:0,,
宽度:config.legendDotWidth,
y:-5,
高度:config.legendDotHeight,
“填充”:功能(d){
返回d.color;
}
});
//旧代码
var-currentX=0;
映射forEach(函数(el,键){
var elGroup=legendGroup.append(“g”).attr(“transform”,“translate”(+currentX+”,100)”);
elGroup.append(“rect”).attr({
x:0,,
宽度:config.legendDotWidth,
y:-5,
高度:config.legendDotHeight,
“填充”:el.color
});
elGroup.append(“text”).attr({
“x”:(config.legendDotWidth+10),
“y”:0,
“路线基线”:“中间”
}).文本(el.标签);
currentX+=elGroup.node().getBBox().width+config.legendMarginInner;
});
}
绘图图例(d3.选择(“svg”)[{
标签:“foo”,
颜色:colors.dirtyorange
}, {
标签:“香蕉”,
颜色:colors.darkblue
}, {
标签:“baz”,
颜色:颜色。浅黄色
}]);

首先创建组:

 var elGroup = legendGroup.selectAll("g").data(map).enter().append("g");
在执行以下操作时附加
文本
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将translate添加到组中

var currentX = 0;   
elGroup.attr({
    transform: function(d, i) {
            var ret = "translate(" + currentX + ",0)"
            currentX += this.getBBox().width + config.legendMarginInner;
      return ret;
    }
  });

工作代码

@Cyril,你能看看这个问题吗,它是关于图例的,我将使用多行图表,其中大约有20条趋势线,我需要显示图例(在这种情况下为20条),所有图例都彼此堆叠,直到它到达终点,但我需要它们与svg框/滚动框一起工作,非常感谢您的帮助。