Функция переноса текста без создания новых строк - PullRequest
2 голосов
/ 21 марта 2020

У меня есть диаграмма d3 с заголовком. Название диаграммы. Однако на маленьких экранах текст необходимо переносить, чтобы не переполнить.

Однако метод переноса текста Bl.ocks не создает новые строки, а вместо этого создает новый tspan для каждого слова, а затем помещает каждый текст / tspan друг на друга

Вот jsfiddle вопроса: jsfiddle здесь

Вот соответствующий код

var chartTitle = svg.append("text")
                .attr("y", -15 )
                .attr("text-anchor", "start")  
                .text("This is a very long chart title that should be wrapped!")
                .attr('class','chartTitle')
                      .call(wrap, width/2);



        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"),
                  dy = parseFloat(text.attr("dy")),
                  tspan = text.text(null).append("tspan").attr("x", 0).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", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
                }
              }
            });
          }

CSS

.chartTitle{
  font-size:20px;
}

1 Ответ

1 голос
/ 21 марта 2020

Эта функция wrap, изначально написанная Майком Бостоком (создатель D3) для оберточных меток , использует атрибут текста dy (который автоматически создается генератором осей). При этом проблема вашего кода в том, что в этом текстовом элементе нет атрибута dy.

Вы можете просто настроить функцию или просто установить нулевой атрибут dy. Вот демонстрация с использованием последнего:

var svg = d3.select("body")
  .append("svg");

var chartTitle = svg.append("text")
  .attr("y", 20)
  .attr("dy", 0)//set the dy attribute
  .attr("text-anchor", "start")
  .text("This is a very long chart title that should be wrapped!")
  .attr('class', 'chartTitle')
  .call(wrap, 300 / 2);

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"),
      dy = parseFloat(text.attr("dy")),
      tspan = text.text(null).append("tspan").attr("x", 0).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", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
      }
    }
  });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
...