【问题标题】:d3.js size node based on label textd3.js 基于标签文本的大小节点
【发布时间】:2015-02-22 23:43:34
【问题描述】:

我有一个带有一堆不同节点的力有向图。每个节点都有一个单字或双字标签。

我在组元素中有 svg 圆圈和文本标签。我计划对标签进行样式设置,使其与节点重叠。我的问题是大多数时候,文本会溢出节点。

有没有办法根据标签大小改变节点的半径?

【问题讨论】:

  • 可以测量标签的大小——一旦它被渲染——然后用它来设置半径。您将使用this.getBBox() 进行测量。
  • 正如@meetamit 所说,我可以使用 getBBox 函数来执行此操作。我找到了一个示例作为对提出不同问题的问题的答案。 stackoverflow.com/a/27650414/1787122 我决定采用不同的路线来显示节点,所以希望有人可以试试这个例子:)

标签: javascript css d3.js


【解决方案1】:

假设nodes 包含您的g 组,您已经将数据绑定到它们,并且标签文本字符串位于属性name 中。当您告诉 d3 将 text 元素添加到 g 组时,您可能使用了此字符串。您可以在添加圆圈时使用相同的绑定数据来配置圆圈。像这样的东西应该可以工作:

nodes.append("circle")
     .attr("r", function(d) {return d.name.length * 2.5;})
     ... more stuff here.

第二行是关键。我只是根据标签文本的长度设置圆半径。我使用 2.5 作为 10pt 类型的默认 san-serif 基于反复试验的乘数。

理论上,最好有一些系统的方法来确定每个字符平均占用多少,并使用它来确定第二行中的乘数。 (即使是固定宽度的字体,对于具有相同点大小的不同字体使用多少空间也有很大差异。)如果是我,那将比它的价值更多。我可能会在脚本顶部附近设置一个包含乘数的变量,并尝试记住在更改字体时更改它。

编辑:可以在text 对象上使用getBBox()getBoundingClientRect() 函数之一(可能将其引用为this)来计算文本的大小。

【讨论】:

  • 感谢您的回答。我想这可能是唯一的选择。我实际上已经使用 getBBox 函数找到了答案,但还没有进行测试:stackoverflow.com/a/27650414/1787122。使用您的方法,我实际上使它起作用了,但是在某些情况下,标签中有多个单词,节点很大。我采取了包装文本,并根据字符串上最长的单词计算节点的半径,但是如果最长的单词在节点的顶部,那么它仍然会稍微溢出......
  • ...我认为这只是一个又一个问题,所以我暂时放弃它,暂时只在节点下方显示标签。感谢您的帮助。
【解决方案2】:

尝试使用getComputedTextLength()

来自迈克·博斯托克: http://bl.ocks.org/mbostock/1846692

node.append("text")
  .text(function(d) { return d.name; })
  .style("font-size", function(d) { return Math.min(2 * d.r, (2 * d.r - 8) / this.getComputedTextLength() * 24) + "px"; })

这使您可以用文本填充圆圈而不会溢出。我不完全确定这些数字是从哪里来的——也许有人可以更好地解释一下。

或者,您可以使用getBBox(),就像在这个example 中一样(以及火星的另一个答案),尽管您还需要对圆圈进行一些计算。您可以使用 .attr("text-anchor", "middle") 和一些几何图形来做到这一点。

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2013-03-20
    • 2013-12-05
    • 1970-01-01
    • 2019-01-15
    • 2013-09-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多