【发布时间】:2017-03-14 16:08:00
【问题描述】:
我有这个传说:
如您所见,每个图例条目的宽度相同。相反,我希望每个图例条目的宽度根据条目符号和文本的宽度而变化。最终,我希望前导条目文本的末端和下一个条目符号的开头之间的距离相同。换句话说,我希望“OA”和加号之间的距离与“OI”和菱形以及“RAC”和正方形之间的距离相同。我需要它基于像素(字符串长度不够)。我一直在尝试各种东西,但都没有成功。
这是我的代码:
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(或legendRect 或legend)的宽度来代替(I * (.15 * width))。我不知道该怎么做。
你可以看到我在后面的代码中使用了下面的来获取legendRectE的宽度:var node: SVGElement = <SVGElement>legendRectE.node(),然后是node.getBoundingClientRect().width。
node.getBoundingClientRect().width 给了我一个你现在看到的宽度值,但是当我使用相同的方法来确定我提到的翻译的值时,它会窒息;当我使用legendRect 或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。
【问题讨论】: