Javascript D3.js绘制后更改容器宽度

Javascript D3.js绘制后更改容器宽度,javascript,d3.js,Javascript,D3.js,我有一个看似简单的问题。我正在从一组json数据创建一个树。该树由标签组成,标签由一个环绕某些文本的矩形容器组成。我想根据文本的长度改变矩形的宽度。我知道我应该做一些类似的事情,但我正在努力理解如何做 以下是我的JS代码(去掉了大部分不必要的装饰): 如您所见,我创建了一个SVG组,将容器矩形和包含的文本都附加到该组中。 现在,我想检索每个文本元素的长度,并使用它来更改相应矩形元素的宽度。我该怎么做?我尝试了我能想到的所有可能的D3指令组合,但我对库的知识还不足以满足我的目的 更新 感谢您的回答

我有一个看似简单的问题。我正在从一组json数据创建一个树。该树由标签组成,标签由一个环绕某些文本的矩形容器组成。我想根据文本的长度改变矩形的宽度。我知道我应该做一些类似的事情,但我正在努力理解如何做

以下是我的JS代码(去掉了大部分不必要的装饰):

如您所见,我创建了一个SVG组,将容器矩形和包含的文本都附加到该组中。 现在,我想检索每个文本元素的长度,并使用它来更改相应矩形元素的宽度。我该怎么做?我尝试了我能想到的所有可能的
D3
指令组合,但我对库的知识还不足以满足我的目的

更新 感谢您的回答,我通过添加以下内容解决了此问题:

// This arranges the width of the rectangles
nodeRect.attr("width", function() {
    return this.nextSibling.getComputedTextLength() + 20;
})
// This repositions texts to be at the center of the rectangle
nodeText.attr('x', function() {
    return (this.getComputedTextLength() + 20) /2;
})

设置文本后,可以在脚本末尾添加以下行:

nodeRect
.transition()
.attr("width",function(){
return Math.max(rectW,nodeText.node().getComputedTextLength())
}).delay(0).duration(500)

我使用Math.max将其设置为rectW(如果足够大),或者在必要时进行扩展。您或许可以调整该部分。

这是节点的当前结构:

<g>
    <rect></rect>
    <text></text>
</g>
在这里,我添加了
rectW
,以保持左右两侧的填充相同,因为您将文本从
rectW/2
开始

如果您不确定文本和矩形之间的关系(谁是第一个孩子,谁是最后一个孩子…),可以向上选择group元素,然后选择其中的文本:

nodeRect.attr("width", function() {
    return d3.select(this.parentNode).select("text").node().getComputedTextLength() + rectW
})
下面是一个基本演示:

var数据=[{
名称:“一些文字”,
x:10,
y:10
},
{
名称:“这里有很长的文字”,
x:100,
y:50
},
{
名称:“另一个文本,此时间比前一个长”,
x:25,
y:100
},
{
名称:“此处有一些短文本”,
x:220,
y:150
}
];
var svg=d3.选择(“svg”);
var rectW=140,
rectH=30;
var node=svg.selectAll(空)
.数据(数据);
var nodeLabel=node.enter().append('g')
.attr('transform',函数(d){
返回“translate”(“+d.x+”,“+d.y+”);
});
var nodeLabel=nodeLabel.append('rect')
.attr('width',rectW)
.attr('height',rectH)
.style(“填充”、“无”)
.style(“笔划”、“灰色”)
var nodeText=nodeLabel.append('text')
.attr('x',rectW/2)
.attr('y',rectH/2)
.风格(“主导基线”、“中心”)
.文本(功能(d){
返回d.name;
});
attr(“宽度”,函数(){
返回此.nextSibling.getComputedTextLength()+rectW
})


太好了!我还通过添加
nodeText.attr('x',function(){return(this.getComputedTextLength()+20)/2;})来将文本的位置居中。现在,其他所有东西都没有对齐,因为它指的是带有固定宽度的矩形。是否有任何方法可以存储此可变宽度(作为排序数组)并在以后需要时使用它?我已经更新了我的第一个问题以澄清这一点。@alecive您的新问题并不完全清楚,但我只是编辑了我的答案以向您展示如何存储新变量。您也可以使用
d3.local
,但这更复杂。此外,请不要更新您的问题:下次,如果您有新问题,请发布另一个问题,链接上一个问题。。。毕竟,它是免费的!很抱歉,我不知道如何正确使用StackOverflow。。我会尝试你的解决方案,如果我还有问题,我会提出一个新问题@阿莱西夫:好的,请。因此,我们真的尽量避免在评论中出现新问题,因为回答者必须编辑答案以适应新问题,然后整个问答对就会变得一团糟。当发布基于另一个问题的新问题时,只需写“作为我以前问题的后续…”,然后链接以前的问题。但是,请注意,您必须在新问题中提供所有相关细节,即,您必须在不点击链接的情况下回答问题。请注意。我已经从第一个问题中删除了我的后续问题。再次感谢你的帮助!
nodeRect.attr("width", function() {
    return this.nextSibling.getComputedTextLength() + rectW
})
nodeRect.attr("width", function() {
    return d3.select(this.parentNode).select("text").node().getComputedTextLength() + rectW
})