D3.js 如何为d3文本元素添加背景色?

D3.js 如何为d3文本元素添加背景色?,d3.js,D3.js,我试图在d3文本后面添加一个rect元素来模拟d3文本元素不存在的背景色。我希望rect的大小与文本本身的大小完全相同 node.append("text") .attr("class", "text") .attr("text-anchor", "middle") .attr("dx", 0) .attr("dy", ".35em") .text(function(d) { var bbox = this.getBBox();

我试图在d3文本后面添加一个rect元素来模拟d3文本元素不存在的背景色。我希望rect的大小与文本本身的大小完全相同

node.append("text") 
    .attr("class", "text")
    .attr("text-anchor", "middle")
    .attr("dx", 0)
    .attr("dy", ".35em")
    .text(function(d) {
          var bbox = this.getBBox();
          node.insert("rect",":first-child")
          .attr("x", bbox.x)
          .attr("y", bbox.y)
          .attr("width", bbox.width)
          .attr("height", bbox.height)
          .style("fill", "yellow");
        return d.name;
    });
getBBox()为x和y返回0

下面的代码显示该框,但它的大小与文本大小不太一致,并且即使文本不存在(当图像存在时),也会绘制该框

解决方案

多亏了Cool Blue,下面的代码现在可以正常工作:在文本后面显示一个rect,这样当它大于节点圆时就可以读取。在未来,它可以通过球面弧而不是矩形来改进,只隐藏文本后面的圆形框架


如评论中所述,使用此模式并添加所需的任何详细信息

var textNode = node.filter(function(d) {return (!d.image)})

textNode.append("text") 
    .attr("class", "text")
    .attr("text-anchor", "middle")
    .attr("dx", 0)
    .attr("dy", ".35em")
    .text(function(d) {
        return d.name;
    }).call(getBB);   
textNode.insert("rect","text")
    .attr("width", function(d){return d.bbox.width})
    .attr("height", function(d){return d.bbox.height})
    .style("fill", "yellow");

function getBB(selection) {
    selection.each(function(d){d.bbox = this.getBBox();})
}

如果将
box.x
替换为
d3.select(this).attr(“x”)
,会发生什么情况?但无论如何,边界框的宽度和高度将为零,因为尚未添加文本。我会用不同的方式。。。请看,我通过将代码移动到.each(函数(d){…})中使其部分工作,但是仍然存在问题:框的大小始终相同,而我希望它的大小随文本大小而变化,并且它为每个节点绘制一个框,即使那些节点没有标签(文本)。请参阅上面的代码。您的代码相当复杂,我不确定在那里查找什么。您是否使用getBB根据文本长度改变节点(圆)大小?是的,请查看我引用的示例和。您可以将getBBox返回的svgRect临时存储在文本元素的数据(d)上,并将其应用于单独语句中的rect选择。这对我不起作用,没有错误消息,但仍然没有矩形。按照前面的建议,我使用.call(getBB)获得了合适的框大小,现在我需要插入rect。您可能需要添加x和y属性。我想可能是零。node是一个g元素,它的数据是按方式绑定的吗?啊,是的,我看到问题了。。。文本还没有出现,是的,单独调用是一种方式。我试图变得过于简洁。在.text()之后紧接着使用.call(getTextBox),然后按如下所示插入节点,我得到一条错误消息,对d.bbox.width node.insert(“rect”,“text”).attr(“width”,function(d){return d.bbox.width}.attr(“height”,function(d){return d.bbox.height}.style(“fill”,“yellow”);是节点是一个g元素:var node=svg.selectAll(.node”).data(nodes.enter().append(“svg:g”).attr(“class”,“node”).on(“dblclick”,dblclick).call(force.drag);好啊你只按了一次密码?您不需要允许数据更新吗?如果是这样,你应该分开更新并输入选择。我更新了我的答案,仍然不起作用?
// only display node labels if node has no image 
node.filter(function(d) {return (!d.image)}).append("text") 
    .attr("class", function(d) { return "text "+d.type; })
    .attr("text-anchor", "middle")
    .attr("dx", 0)
    .attr("dy", ".35em")
    .text(function(d) {
        return d.name;
    })
    .call(getTextBox);

// only display a rect behind labels if node has no image 
node.filter(function(d) {return (!d.image)}).insert("rect","text")
    .attr("x", function(d){return d.bbox.x})
    .attr("y", function(d){return d.bbox.y})
    .attr("width", function(d){return d.bbox.width})
    .attr("height", function(d){return d.bbox.height})
    .style("fill", "#FFE6F0");

function getTextBox(selection) {
    selection.each(function(d) { d.bbox = this.getBBox(); })
}
var textNode = node.filter(function(d) {return (!d.image)})

textNode.append("text") 
    .attr("class", "text")
    .attr("text-anchor", "middle")
    .attr("dx", 0)
    .attr("dy", ".35em")
    .text(function(d) {
        return d.name;
    }).call(getBB);   
textNode.insert("rect","text")
    .attr("width", function(d){return d.bbox.width})
    .attr("height", function(d){return d.bbox.height})
    .style("fill", "yellow");

function getBB(selection) {
    selection.each(function(d){d.bbox = this.getBBox();})
}