我有这样一个传说:
如您所见,每个图例条目的宽度相同。相反,我希望每个图例条目的宽度根据条目符号和文本的宽度而变化。最终,我希望前导条目文本的末尾与后续条目符号的开头之间的距离相同。换句话说,我希望“OA”和加号之间的距离与“OI”和菱形以及“RARC”和正方形之间的距离相同。我需要它基于像素(字符串长度不够)。我一直在尝试各种各样的事情,但还没有成功。
这是我的代码:
var legendData = [["OA", "yellow", "circle"], ["OI", "blue", "cross"], ["RARC", "green", "diamond"], ["CAPE", "red", "square"], ["Other", "black", "triangle-down"]];
this.svg.selectAll('.legend').remove() //remove remnants of previous legend so new legend has clean slate...eliminates overlays during resizing
var legend = this.svg.append('g')
.attr("class", "legend")
.attr("height", 0)
.attr("width", 0)
.attr('transform', 'translate(' + (ScatterChart.Config.margins.left + (width * .008)) + ',' + (height += .40 * ScatterChart.Config.margins.bottom) + ')');
var legendRect = legend
.selectAll('g')
.data(legendData)
;
var labelLength = 0
var labelLengthPrevious = 0
var legendRectE = legendRect.enter()
.append("g")
.attr("transform", function (d, i) {
//labelLength = labelLengthPrevious //Need to figure out pixel lengths
//labelLengthPrevious += (d[0].length) + 50
//return 'translate(' + labelLength + ', ' + 0 + ' )'; // y is constant and x growing
return 'translate(' + (i * (.15 * width)) + ', ' + 0 + ' )'; // y is constant and x growing
})
;
legendRectE
.append('path')
.attr("d", d3.svg.symbol().type((d) => {
return d[2]
}
).size((d3.min([height, width]) * ScatterChart.Config.axisFontMultiplier) * (d3.min([height, width]) * ScatterChart.Config.symbolSizeMultiplier)))
.style("fill", function (d) {
return d[1];
})
.attr('stroke', 'black')
;
//This asserts legendRectE as a node...I think. I do this so I can use the width and height measurements of legendRectE.
var node: SVGElement = <SVGElement>legendRectE.node()
legendRectE
.append("text")
.attr("x", function (d) {
return node.getBoundingClientRect().width
})
.attr("y", function (d) {
return node.getBoundingClientRect().height / 2.25
})
.text(function (d) {
return d[0];
})
.style('font-size', function () { return d3.min([height, width]) * ScatterChart.Config.axisFontMultiplier + "px" })
;
我认为答案与这一行有关:return 'translate(' + (i * (.15 * width)) + ', ' + 0 + ' )'; // y is constant and x growing
。现在,它只是通过将指数乘以图表宽度的 15% 来向右移动。我想我需要以某种方式替换的宽度legendRectE
(or of legendRect
or legend
)代替(I * (.15 * width))
。我不知道该怎么做。
你可以看到我使用下面的方法来获取宽度legendRectE
稍后在代码中:var node: SVGElement = <SVGElement>legendRectE.node()
, 其次是node.getBoundingClientRect().width
.
node.getBoundingClientRect().width
给我一个宽度值,您现在看到它正在使用,但是当我使用相同的方法来确定我提到的翻译的值时,它会令人窒息;当我使用时legendRect
or legend
代替legendRectE
我只得到“0”。
我想我可以像这样编辑转换函数:
var legendRectE = legendRect.enter()
.append("g")
.attr("transform", function (d, i) {
var node: SVGElement = <SVGElement>legendRectE.node()
return 'translate(' + node.getBoundingClientRect().width + ', ' + 0 + ' )'; // y is constant and x growing
})
;
显然,我错了。有什么想法/建议吗?
附注我正在使用 d3 v3.5。