score:2

Accepted answer

You could just give the body a background instead:

function wrap(text, width) {
  text.each(function() {
    var text = d3.select(this),
      words = text.text().split(/\s+/).reverse(),
      word,
      line = [],
      lineNumber = 0,
      lineHeight = 1.1, // ems
      y = text.attr('y'),
      x = text.attr('x')
    dy = parseFloat(text.attr('dy')),
      tspan = text
      .text(null)
      .append('tspan')
      .attr('x', x)
      .attr('y', y)
      .attr('dy', dy + 'em');
    while ((word = words.pop())) {
      line.push(word);
      tspan.text(line.join(' '));
      if (tspan.node().getComputedTextLength() > width) {
        line.pop();
        tspan.text(line.join(' '));
        line = [word];
        tspan = text
          .append('tspan')
          .attr('x', x)
          .attr('y', y)
          .attr('dy', ++lineNumber * lineHeight + dy + 'em')
          .text(word);
      }
    }
  });
}

var svg = d3
  .select('body')
  .append('svg')
  .attr('width', 500)
  .attr('height', 5000);

// var longText =
//   'This is very very long text. This is very very long text. This is very very long text. This is very very long text. This is very very long text. This is very very long text.';

// var longText =
//   '<span>hi</span>';

var longText = '<span> hello[&times;10<sup>-15</sup> ss<sup>-1</sup>]hello[&times;10<sup>-15</sup> ss<sup>-1</sup>]hello[&times;10<sup>-15</sup> ss<sup>-1</sup>]hello[&times;10<sup>-15</sup> ss<sup>-1</sup>]hello[&times;10<sup>-15</sup> ss<sup>-1</sup>]</span>';

var totHeight = 0;

drawRect();

function drawRect() {
  //var someWidth = randomIntFromInterval(40, 300);
  var someWidth = 212;

  var g = svg
    .append('g')
    .attr('class', 'foreignObjwrapper')
    .attr('transform', 'translate(20,' + totHeight + ')');

  const text = g
    .append('foreignObject')
    .attr('width', 200)
    .attr('height', 200)
    .attr('id', 'textBox')
    .attr('x', 50)
    .attr('y', 60)
    .append('xhtml:body')
    .style("background", "steelblue")
    .style("border", "dashed black 1px")
    .html(longText);

  // var img = g.append('svg:image')
  //   .attr('x', 250)
  //   .attr('y', 40)
  //   .attr('width', 24)
  //   .attr('height', 24)
  //   .attr(
  //     'xlink:href',
  //     './img/edit-24-px.svg'
  //   );

  text.on('click', function() {
    var newText = '<span> bye[&times;10<sup>-15</sup> ss<sup>-1</sup>]</span>';
    //d3.append('text').html("<span> bye </span>");
    text.html(newText);
    console.log('hi', newText);
    //document.getElementsByClassName("textBox").innerHTML = newText;

  });

  //var height = text.node().getBBox().height + 25;
  // totHeight += height + 10;
  // rect.attr('height', height);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="body"></div>


Alternatively you can get the height of the body using text.node().clientHeight:

function wrap(text, width) {
  text.each(function() {
    var text = d3.select(this),
      words = text.text().split(/\s+/).reverse(),
      word,
      line = [],
      lineNumber = 0,
      lineHeight = 1.1, // ems
      y = text.attr('y'),
      x = text.attr('x')
    dy = parseFloat(text.attr('dy')),
      tspan = text
      .text(null)
      .append('tspan')
      .attr('x', x)
      .attr('y', y)
      .attr('dy', dy + 'em');
    while ((word = words.pop())) {
      line.push(word);
      tspan.text(line.join(' '));
      if (tspan.node().getComputedTextLength() > width) {
        line.pop();
        tspan.text(line.join(' '));
        line = [word];
        tspan = text
          .append('tspan')
          .attr('x', x)
          .attr('y', y)
          .attr('dy', ++lineNumber * lineHeight + dy + 'em')
          .text(word);
      }
    }
  });
}

var svg = d3
  .select('body')
  .append('svg')
  .attr('width', 500)
  .attr('height', 5000);

// var longText =
//   'This is very very long text. This is very very long text. This is very very long text. This is very very long text. This is very very long text. This is very very long text.';

// var longText =
//   '<span>hi</span>';

var longText = '<span> hello[&times;10<sup>-15</sup> ss<sup>-1</sup>]hello[&times;10<sup>-15</sup> ss<sup>-1</sup>]hello[&times;10<sup>-15</sup> ss<sup>-1</sup>]hello[&times;10<sup>-15</sup> ss<sup>-1</sup>]hello[&times;10<sup>-15</sup> ss<sup>-1</sup>]</span>';

var totHeight = 0;

drawRect();

function drawRect() {
  //var someWidth = randomIntFromInterval(40, 300);
  var someWidth = 212;

  var g = svg
    .append('g')
    .attr('class', 'foreignObjwrapper')
    .attr('transform', 'translate(20,' + totHeight + ')');

  const padding = 5;
  var rect = g
    .append('rect')
    .style('fill', 'steelblue')
    .attr("stroke", "black")
    .attr("stroke-dasharray", "5")
    .attr('x', 50)
    .attr('y', 60)
    .attr('width', someWidth + padding * 2);

  const text = g
    .append('foreignObject')
    .attr('width', someWidth)
    .attr('height', 200)
    .attr('id', 'textBox')
    .attr('x', 50 + padding)
    .attr('y', 60 + padding)
    .attr('id', 'textBox')
    .style('fill', 'black')
    .append('xhtml:body')
    .style("margin", 0)
    .html(longText);

  rect.attr("height", text.node().clientHeight + padding * 2);

  // var img = g.append('svg:image')
  //   .attr('x', 250)
  //   .attr('y', 40)
  //   .attr('width', 24)
  //   .attr('height', 24)
  //   .attr(
  //     'xlink:href',
  //     './img/edit-24-px.svg'
  //   );

  text.on('click', function() {
    var newText = '<span> bye[&times;10<sup>-15</sup> ss<sup>-1</sup>]</span>';
    //d3.append('text').html("<span> bye </span>");
    text.html(newText);
    console.log('hi', newText);
    //document.getElementsByClassName("textBox").innerHTML = newText;

  });

  //var height = text.node().getBBox().height + 25;
  // totHeight += height + 10;
  // rect.attr('height', height);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="body"></div>


Related Query

More Query from same tag