Нужна помощь, чтобы разбить длинный текст и отобразить в дуге в d3.js - PullRequest
1 голос
/ 09 июля 2019

У меня проблема с выравниванием и переносом большого текста в сегменте Arc.

Я пытался реализовать tspan, но не смог правильно его преобразовать.

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

.arc text,
.wedge text {
  font: 10px sans-serif;
  text-anchor: middle;
}

.arc path,
.wedge path {
  stroke: #fff;
}

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

var width = 494,
    height = 504,
    radius = Math.min(width, height) / 2;

var color = d3.scale.ordinal()
    .range(["#f38e36","#d79ae2","#dac2ad","#89e1ea"])
        .domain(["Social", "Livability","Knowledge","Economy"]);

var arc = d3.svg.arc()
    .outerRadius(radius - 0)
    .innerRadius(radius - 110);

var wedge = d3.svg.arc()
    .outerRadius(radius - 110)
    .innerRadius(0);

var labelWedge = d3.svg.arc()
    .outerRadius(radius-200)
    .innerRadius(radius-200);

var pie = d3.layout.pie()
    .sort(null)
    .value(function(d) { return d.count; });

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
  .append("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

d3.csv("data.csv", type, function(error, data) {
  if (error) throw error;

  nested = [{"category":"Social","count":25},{"category":"Livability","count":25},{"category":"Knowledge","count":25},{"category":"Economy","count":25}];
  data1=
    [{"category":"Social","subcategory":"Eduction and Employment","count":0.39},
     {"category":"Social","subcategory":"Social Support","count":0.39},
     {"category":"Social","subcategory":"Housing & Communities","count":0.39},
     {"category":"Social","subcategory":"Civil Society","count":0.39},
     {"category":"Livability","subcategory":"Activation and Calendaring","count":0.26},
     {"category":"Livability","subcategory":"Mobility","count":0.26},
     {"category":"Livability","subcategory":"Nature","count":0.26},
     {"category":"Livability","subcategory":"Healthy and Sustainable Lifestyle","count":0.26},
     {"category":"Livability","subcategory":"Marketing","count":0.26},
     {"category":"Livability","subcategory":"Source of Distinctiveness","count":0.26},
     {"category":"Knowledge","subcategory":"Vibrant Tech Companies","count":0.39},
     {"category":"Knowledge","subcategory":"Tech Talent Attraction","count":0.39},
     {"category":"Knowledge","subcategory":"Distinctive Tech Eduction","count":0.39},
     {"category":"Knowledge","subcategory":"Full-Fledge R&D System","count":0.39},
     {"category":"Economy","subcategory":"Business Environment Companiesetitiveness","count":0.39},
     {"category":"Economy","subcategory":"Tourism","count":0.39},
     {"category":"Economy","subcategory":"SME Support","count":0.39},
     {"category":"Economy","subcategory":"Private Sector Incentivization","count":0.39}];
  console.log("nested", nested);
  console.log("nested", data1);
  var g = svg.selectAll(".arc")
      .data(pie(data1))
    .enter().append("g")
      .attr("class", "arc");

  g.append("path")
      .attr("d", arc)
      .style("fill", function(d) { return color(d.data.category); });

  g.append("text")
      .attr("transform", function(d) { return transformLabel(d); })
      .attr("dy", ".35em")
      .text(function(d) { return d.data.subcategory; });

    var g = svg.selectAll(".wedge")
      .data(pie(nested))
    .enter().append("g")
      .attr("class", "wedge");

  g.append("path")
      .attr("d", wedge)
      .style("fill", function(d) { return color(d.data.category); });

  g.append("text")
      .attr("transform", function(d) { return "translate(" + labelWedge.centroid(d) + ")"; })
      .attr("dy", ".35em")
      .text(function(d) { return d.data.category; });

});

function type(d) {
  d.count = +d.count;
  return d;
}
function transformLabel(d){
  [x, y] = arc.centroid(d);
  var rotation = d.endAngle < Math.PI ? (d.startAngle / 2 + d.endAngle / 2) * 180 / Math.PI : (d.startAngle / 2 + d.endAngle / 2 + Math.PI) * 180 / Math.PI;
  let label = "translate(" + [x, y] + ") rotate(-90) rotate(" + rotation + ")";
  return label;
}
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
            x = text.attr("x"),
            y = text.attr("y"),
            dy = 0, //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);
            }
        }
    });
}
</script>

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

...