我想显示一个rect
,旁边有一个text
标签。rect
的宽度应该延伸到svg容器的宽度,减去文本的宽度,这是动态的,可以是任何可变的长度。
JSFiddle
var text = 'Foobar';
var textWidth = 50; //how to calculate this?
var plotWidth = 400;
var barWidth = plotWidth-textWidth;
var plot = d3.select(container)
.insert("svg")
.attr('width', plotWidth)
.attr('height', 50);
plot.append("rect")
.style("fill", "steelblue")
.attr("x", 0)
.attr("width", barWidth)
.attr("y", 0)
.attr("height", 50);
plot.append("text")
.attr("x", barWidth)
.attr("y", 28)
.text(text);
在绘制之前,如何使用D3计算文本的宽度?或者,我如何以其他方式定位和调整取决于可变长度文本的尺寸的元素?
4条答案
按热度按时间r6hnlfcb1#
我知道你问了关于D3的问题,但这可能是解决你问题的一个原生解决方案。
HTML5 canvas 2D context有一些内置的功能来测量文本。你也许可以利用它来测量SVG等其他API的文本。如果它不是100%准确,那么它肯定与正确答案成比例。
5uzkadbs2#
我在一个复杂的图表中遇到了类似的问题,元素和文本之间有很多交互,这需要在显示任何元素之前知道文本宽度**。
我采取了创建一个虚拟文本来获取其宽度并立即删除它。注意
each
中函数的最后一行代码。aurhwmvo3#
下面是一个基于
getBBox().width
getComputedTextLength()
的工作示例:编辑:由于性能问题,将答案更新为使用
getComputedTextLength
(参见评论)http://jsfiddle.net/henbox/jzkj29nv/27/
我还切换到使用
text-anchor: end;
CSS的文本,所以你不需要计算文本的开始位置(只是在最后传递)svmlkihl4#
也可以在d3
selection.attr
中使用getComputedTextLength()
或getBBox()
。下面是一个基于
text
内容大小计算x
和y
坐标的最小示例:请注意,使用了两种函数样式,以说明以下内容:
在普通的
function ()
中,可以使用nodes[i]
或this
访问当前节点。但是,在arrow functions
=>
中,我们必须使用nodes[i]
,因为使用this
会引发错误:另见d3-selection issue 97和this SO answer。