0

I am working with d3js where lib create nodes and links according to data. At some place have some specific requirement to add multiple text in same line like url "www.xyz.com/home/user" (here 3 strings "www.xyz.com","/home","/user"). They are not separate nodes so I can't find position with d3. It's just a <text> element with 3 <tspan> children.

<text id="TaxFilingResource_URL" class="label url" dy="24" dx="30">
  <tspan id="TaxFilingResource.URL.1">www.xyz.com</tspan>
  <tspan id="TaxFilingResource.URL.2">/home</tspan>
  <tspan id="TaxFilingResource.URL.3">/user</tspan>
</text> 

and displaying like this below

  www.xyz.com/home/user 

I need to get the position and width of each <tspan> element. My code is

var el = document.getElementById(d.source);
x = el.getStartPositionOfChar('').x   (or)
x = el.getClientRects().left;

that give relative position on text inside g element , but in some browser and on mac it will return absolute position.

Is there any right way to find position and width of tspan in JavaScript that worked with all browsers ( IE must > 9th version). enter image description here

1

1 Answer 1

10

In SVG 1.1 tspan doesn't have a getBBox method, but in SVG2 it does, I've reported a chromium bug for it reporting the wrong value, http://code.google.com/p/chromium/issues/detail?id=349835.

This would give you the proper position and dimensions if the browsers implemented SVG2:

var bbox = document.getElementById("TaxFilingResource.URL.2").getBBox();

See jsfiddle for a full example.

For now, you can do a workaround using the methods that are available in SVG 1.1:

var home = document.getElementById("TaxFilingResource.URL.2");
var extent = home.getExtentOfChar(0); // pos+dimensions of the first glyph
var width = home.getComputedTextLength(); // width of the tspan
var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
rect.x.baseVal.value = extent.x;
rect.y.baseVal.value = extent.y;
rect.width.baseVal.value = width;
rect.height.baseVal.value = extent.height;

See jsfiddle.

If you need to transform to another place in the tree:

var dest = document.getElementById("dest"); // some arbitrary container element
var fromHometoDestmatrix = home.getTransformToElement(dest);
rect.transform.baseVal.appendItem(
  rect.transform.baseVal.createSVGTransformFromMatrix(fromHometoDestmatrix));
dest.appendChild(rect);

See jsfiddle.

2
  • I forgot to mention that d3js node is inside the <g> element so there is issue with relative and absolute points
    – Amit Rana
    Commented Mar 6, 2014 at 10:34
  • thanks for this, but it doesn't seem to account for dy and doesn't provide a tight box around the tspan? is there a way to do so, do you know?
    – Crashalot
    Commented Dec 28, 2018 at 4:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.