0

As a follow up question of D3.js change width of container after it is drawn I create the rectangles that fits the text length, I want to link the rectangles from bottom. But I'm stuck in getting the width of rectangle when I draw the link. This is the js code:

var rectW = 140, rectH = 40;

// Declare the nodes.
var node = draw.selectAll('g.node')
               .data(nodes, function(d) { return d.id; });

// Enter the nodes.
var nodeLabel = node.enter().append('g')
                    .attr('transform', function(d) { return 'translate(' + source.x0 + ',' + source.y0 + ')'; });

var nodeRect = nodeLabel.append('rect')
                        .attr('width', rectW)
                        .attr('height', rectH);

var nodeText = nodeLabel.append('text')
                        .attr('x', rectW / 2)
                        .attr('y', rectH / 2)
                        .text(function (d) { return d.name; });
// 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;
})

Next,I'd like to link the nodeRects. Linking the top left corner is ugly, so I adjust a bit:

link.attr('d', function (d) {
            var sourceX = d.source.x + 0.5*d.source.getComputedTextlength() + 10,
                sourceY = (d.source.y > d.target.y)? d.source.y: (d.source.y + rectH),
                targetX = d.target.x + 0.5*d.target.getComputedTextlength() +10,
                targetY = (d.source.y >= d.target.y)? (d.target.y + rectH) : d.target.y;

It returns error. Is there a way that I can get access to the target rect and source rect's textlength or width?

1 Answers1

0

I find an answer by myself. d.source.width doesn't work because it is not defined. Change

nodeRect.attr("width", function() {
    return this.nextSibling.getComputedTextLength() + 20;
})

to

nodeRect.attr("width", function(d) {
    d.width = this.nextSibling.getComputedTextLength() + 20;
    return d.width;
})

Then use d.source.width works well.