Как мне обернуть длинный текст метки в пузырьковую диаграмму в d3?

1

Я использую D3 версии 3, я очень новичок в D3, например, сегодня мой день 2 для d3....... Мне нужно, чтобы этот проект помещал каждую категорию в пузырь... Мне дали следуя кодам D3 из класса, профессор сказал, что просто измените набор данных, чтобы он работал... но мой ярлык данных слишком длинный, чтобы вписаться в каждый пузырь.... Из-за того, что у меня есть 0 знаний о D3, хотя я сделал нашел некоторые коды о том, как обернуть текст, но я понятия не имею, как его поместить. Пожалуйста, помогите ~~

Это коды D3 версии 3, данные профессором:

var diameter = 800, //max size of the bubbles
   color = d3.scale.category20(); //color category

var bubble = d3.layout.pack()
.sort(null)
.size([diameter, diameter])
.padding(1.5);

var svg = d3.select("section")
.append("svg")
.attr("width", diameter)
.attr("height", diameter)
.attr("class", "bubble");

d3.csv("data.csv", function(error, data){

//convert numerical values from strings to numbers
data = data.map(function(d){ d.value = +d["Amount"]; return d; });

//bubbles needs very specific format, convert data to this.
var nodes = bubble.nodes({children:data}).filter(function(d) { return !d.children; });

//setup the chart
var bubbles = svg.append("g")
    .attr("transform", "translate(0,0)")
    .selectAll(".bubble")
    .data(nodes)
    .enter();

//create the bubbles
bubbles.append("circle")
    .attr("r", function(d){ return d.r; })
    .attr("cx", function(d){ return d.x; })
    .attr("cy", function(d){ return d.y; })
    .style("fill", function(d) { return color(d.value); });

//format the text for each bubble
bubbles.append("text")
    .attr("x", function(d){ return d.x; })
    .attr("y", function(d){ return d.y + 5; })
    .attr("text-anchor", "middle")
    .text(function(d){ return d["Item"]; })
    .style({
        "fill":"white", 
        "font-family":"Verdana, san-serif",
        "font-size": "12px"
    });
})

И это мои data.csv, которые я использую:

Item,Amount
Daily Phone Pick-ups on Average: 183 Counts ,182
Daily Screen Time: 401 minutes,401.4
Daily Walking & Running Distance: 0.188 miles,188.36
Daily Steps: 44 Counts,448
Daily Flights Climbed: 39 Counts,393

Большое спасибо!!

Теги:
d3.js

1 ответ

2
Лучший ответ

Здесь немного упрощенная версия этой методики:

bubbles.append("text")
    .attr("x", function(d) {
      return d.x;
    })
    .attr("y", function(d) {
      return d.y + 5;
    })
    .attr("text-anchor", "middle")
    .text(function(d) {
      return d["Item"];
    })
    .style({
      "fill": "white",
      "font-family": "Verdana, san-serif",
      "font-size": "12px"
    })
    .each(wrap);

function wrap(d) {
    var text = d3.select(this),
      width = d.r * 2,
      x = d.x,
      y = d.y,
      words = text.text().split(/\s+/).reverse(),
      word,
      line = [],
      lineNumber = 0,
      lineHeight = 1.1,
      tspan = text.text(null).append("tspan").attr("x", x).attr("y", y);
    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 + "em").text(word);
      }
    }
}

Код запуска:

<!DOCTYPE html>
<html>

<head>
  <script data-require="[email protected]" data-semver="3.5.17" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.js"></script>
</head>

<body>
  <section></section>
  <script>
    var diameter = 800, //max size of the bubbles
      color = d3.scale.category20(); //color category

    var bubble = d3.layout.pack()
      .sort(null)
      .size([diameter, diameter])
      .padding(1.5);

    var svg = d3.select("section")
      .append("svg")
      .attr("width", diameter)
      .attr("height", diameter)
      .attr("class", "bubble");

    //d3.csv("data.csv", function(error, data) {
      
      var data = [{"Item":"Daily Phone Pick-ups on Average: 183 Counts ","Amount":"182"},{"Item":"Daily Screen Time: 401 minutes","Amount":"401.4"},{"Item":"Daily Walking & Running Distance: 0.188 miles","Amount":"188.36"},{"Item":"Daily Steps: 44 Counts","Amount":"448"},{"Item":"Daily Flights Climbed: 39 Counts","Amount":"393"}];

      //convert numerical values from strings to numbers
      data = data.map(function(d) {
        d.value = +d["Amount"];
        return d;
      });

      //bubbles needs very specific format, convert data to this.
      var nodes = bubble.nodes({
        children: data
      }).filter(function(d) {
        return !d.children;
      });

      //setup the chart
      var bubbles = svg.append("g")
        .attr("transform", "translate(0,0)")
        .selectAll(".bubble")
        .data(nodes)
        .enter();

      //create the bubbles
      bubbles.append("circle")
        .attr("r", function(d) {
          return d.r;
        })
        .attr("cx", function(d) {
          return d.x;
        })
        .attr("cy", function(d) {
          return d.y;
        })
        .style("fill", function(d) {
          return color(d.value);
        });

      //format the text for each bubble
      bubbles.append("text")
        .attr("x", function(d) {
          return d.x;
        })
        .attr("y", function(d) {
          return d.y + 5;
        })
        .attr("text-anchor", "middle")
        .text(function(d) {
          return d["Item"];
        })
        .style({
          "fill": "white",
          "font-family": "Verdana, san-serif",
          "font-size": "12px"
        })
        .each(wrap);
    //})

    function wrap(d) {
        var text = d3.select(this),
          width = d.r * 2,
          x = d.x,
          y = d.y,
          words = text.text().split(/\s+/).reverse(),
          word,
          line = [],
          lineNumber = 0,
          lineHeight = 1.1,
          tspan = text.text(null).append("tspan").attr("x", x).attr("y", y);
        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 + "em").text(word);
          }
        }
    }
  </script>
</body>

</html>

Ещё вопросы

Сообщество Overcoder
Наверх
Меню