1

In the code below, I seek to insert 3 strings on screen one next to the other

To do so, I need to calculate the screen width of the labels that I have been already displayed, as highlighted in the attr("x",...) line.

How do I refer to the previous elements during a selection in d3?

References: How to refer to the previous element, how to calculate width of text before displaying it

var labels = ['a label', 'another label', 'a third label']

var textItems = svg.append('g')
    .selectAll('.my_labels_text')
    .data(labels)
    .enter()
    .append("text")
    .attr("class", "my_labels_text")
    .attr("text-anchor", "left")
    .attr("x", function (d, i)   { return <cumulated width of labels previously displayed>})
    .attr("y", 10) // arbitrary y value
    .text(function(d) { return d })
Community
  • 1
  • 1
Pythonic
  • 2,091
  • 3
  • 21
  • 34

1 Answers1

2

If you need to keep a running width count; just use a variable in the outer scope:

<!DOCTYPE html>
<html>

  <head>
    <script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
  </head>

  <body>
    <script>
      var labels = ['a label', 'another label', 'a third label'];
      
      var svg = d3.select('body')
        .append('svg')
        .attr('width', 1000)
        .attr('height', 500);

      var runningWidth = 10;
      var textItems = svg.append('g')
          .selectAll('.my_labels_text')
          .data(labels)
          .enter()
          .append("text")
          .attr("class", "my_labels_text")
          .attr("text-anchor", "left")
          .text(function(d) { return d })
          .attr("y", 10) // arbitrary y value
          .attr("x", function (d, i)   { 
            var thisWidth = this.getComputedTextLength(),
                rV = runningWidth;
            runningWidth += thisWidth;
            return rV;
          });
      
    </script>
  </body>

</html>
Mark
  • 106,305
  • 20
  • 172
  • 230
  • Works thanks. Note: you need to read `getComputedTextLength` after attributing all text and formatting parameters for this to work properly – Pythonic May 28 '16 at 15:17
  • @Pythonic, yes, sorry, I should have mentioned that in my answer. That's why I changed the order of operations. The `.text` call renders it, which allows you to compute the text length. – Mark May 28 '16 at 15:19