Как сделать весь текст длинной метки видимым? - PullRequest
0 голосов
/ 27 августа 2018

У нас есть длинный текст, который нужно обернуть, и при попытке в D3.js весь текст не виден.Я пробовал несколько вариантов переноса, но на самом деле не смог подогнать код.

Я вижу, что строка tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight * dy + "em").text(word); вычисляет длину, но я не могу понять, как динамически вписать текст / сделать длинный текст видимым.

Мой TSV:

name    value
Committed 671 birthdays to it if there is a relevant source of information , it would be better to understand it and kids can be assigned relevant groups to particiate     .19
it should end up like this in the $_POST[] array (PHP format for easy   .19
just leave it there    .19
Ex is doing too well    .10
High school friends all dead now    .15
Discovered how to “like” things mentally    .27

Мой код:

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.7/d3.min.js"></script>

<!DOCTYPE html>
<meta charset="utf-8">
<style>

.bar {
  fill: steelblue;
}

.bar:hover {
  fill: brown;
}

.title {
  font: bold 14px "Helvetica Neue", Helvetica, Arial, sans-serif;
}

.axis {
  font: 10px sans-serif;
}

.axis path,
.axis line {
  fill: none;
  stroke: #000;
  shape-rendering: crispEdges;
}

.x.axis path {
  display: none;
}

</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>

var margin = {top: 80, right: 180, bottom: 80, left: 180},
    width = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

var x = d3.scale.ordinal()
    .rangeRoundBands([0, width], .1, .3);

var y = d3.scale.linear()
    .range([height, 0]);

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom");

var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left")
    .ticks(8, "%");

var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

d3.tsv("data.tsv", type, function(error, data) {
  x.domain(data.map(function(d) { return d.name; }));
  y.domain([0, d3.max(data, function(d) { return d.value; })]);

  svg.append("text")
      .attr("class", "title")
      .attr("x", x(data[0].name))
      .attr("y", -26)
      .text("Why Are We Leaving Facebook?");

  svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis)
    .selectAll(".tick text")
      .call(wrap, x.rangeBand());

  svg.append("g")
      .attr("class", "y axis")
      .call(yAxis);

  svg.selectAll(".bar")
      .data(data)
    .enter().append("rect")
      .attr("class", "bar")
      .attr("x", function(d) { return x(d.name); })
      .attr("width", x.rangeBand())
      .attr("y", function(d) { return y(d.value); })
      .attr("height", function(d) { return height - y(d.value); });
});

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);
      }
    }
  });
}

function type(d) {
  d.value = +d.value;
  return d;
}

</script>

Вот результат:

enter image description here

1 Ответ

0 голосов
/ 27 августа 2018

Прежде всего, давайте сделаем правильную атрибуцию: эта функция с именем wrap была создана Майком Бостоком, как вы можете видеть здесь: https://bl.ocks.org/mbostock/7555321. Вы, вероятно, скопировали ее оттуда или из бесчисленных копий, которые мы можно найти в интернете.

Как говорится, в этом ответе будет предложено решение с использованием этой функции как есть. Конечно, существуют лучшие и более эффективные решения.

Предположим, у вас длинный ярлык, например:

"What would you think if I sang out of tune? 
Would you stand up and walk out on me?
Lend me your ears and I'll sing you a song 
And I'll try not to sing out of key"

В этом предлагаемом решении мы устанавливаем счетчик ...

var counter = 0;

... и внутри функции wrap мы получаем максимальное количество строк:

counter = lineNumber > counter ? lineNumber : counter;

С этой информацией мы можем использовать магическое число (например, 20), чтобы умножить максимальное количество строк и переместить ось вверх:

margin.bottom = 20 * counter;
height = 500 - margin.top - margin.bottom;
y.range([height, 0]);

Вот код Bostock с этой модификацией: https://bl.ocks.org/GerardoFurtado/91f656cf425cb630a4e5adf98d207f35/bcda7bdb86ffffdd84000a075811ea17d4f4218a

Здесь есть дубликаты и ненужные шаги, которые вы можете улучшить: этот ответ - просто грубая демонстрация, чтобы показать вам способ вычислить необходимое пространство, необходимое для меток.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...