d3.js - 圆环图标签太长

标签 d3.js label donut-chart

我的问题是圆环图的标签太长。当它超过 svg 的宽度或高度时,它会丢失。

我不知道我必须如何将它剪成 2 行或更多行。我尝试在标签文本之外添加标签 div,但这是错误的。谁能给我一个解决方案。这是我的代码:

var tooltip = d3.select('#chart')
                .append('div')
                .attr('class', 'tooltips');

        tooltip.append('div')
                .attr('class', 'label');

        var data = [
            {country: "UNITED KINGDOMhhhhhhhhhhhhhhhhhhhhhhhhh hhhhhhhhhhhhhhhhh", val: 86.68},
            {country: "HONG KONGggggggggggggggggggggg g g g gg g g g g gg  gg g g ", val: 9.23},
            {country: "OTHERS", val: 4.09}
        ];

        var w = 600,
                h = 600,
                r = Math.min(w, h) / 2 - 100,
                labelr = r + 30, // radius for label anchor
                color = d3.scale.category20(),
                donut = d3.layout.pie(),
                arc = d3.svg.arc().innerRadius(r * .6).outerRadius(r);

        var vis = d3.select("#chart")
                .append("svg:svg")
                .data([data])
                .attr("width", w + 150)
                .attr("height", h);

        var arcs = vis.selectAll("g.arc")
                .data(donut.value(function(d) { return d.val }))
                .enter().append("svg:g")
                .attr("class", "arc")
                .attr("transform", "translate(" + (r + 200) + "," + (r+100) + ")");

        var arcOver = d3.svg.arc()
                .innerRadius(r * .57)
                .outerRadius(r + 5);

        arcs.append("path")
                .attr("fill", function(d, i) { return color(i); })
                .attr("d", arc)
                .on("mouseover",function(d){
                    d3.select(this).transition()
                      .duration(50)
                      .attr("d", arcOver);
                    tooltip.select('.label').html(d.value + "%");
                    tooltip.style('display', 'block');
                })
                .on('mouseout', function() {
                    d3.select(this).transition()
                            .duration(50)
                            .attr("d", arc);
                    tooltip.style('display', 'none');
                })
                .on('mousemove', function(d) {
                    tooltip.style('top', (d3.event.pageY - 80) + 'px')
                            .style('left', (d3.event.pageX + 10) + 'px');
                });

        arcs.append("text")
                .attr("transform", function(d) {
                    var c = arc.centroid(d),
                            x = c[0],
                            y = c[1],
                    // pythagorean theorem for hypotenuse
                            h = Math.sqrt(x*x + y*y);
                    return "translate(" + (x/h * labelr) +  ',' +
                            (y/h * labelr) +  ")";
                })
                .attr("dy", ".35em")
                .attr("text-anchor", function(d) {
                    // are we past the center?
                    return (d.endAngle + d.startAngle)/2 > Math.PI ?
                            "end" : "start";
                })
                .text(function(d) { return d.data.country; });

谢谢!!!

最佳答案

var tooltip = d3.select('#chart')
                .append('div')
                .attr('class', 'tooltips');

        tooltip.append('div')
                .attr('class', 'label');

        var data = [
            {country: "UNITED KINGDOMhhhhhhhhhhhhhhhhhhhhhhhhh hhhhhhhhhhhhhhhhh", val: 86.68},
            {country: "HONG KONGggggggggggggggggggggg g g g gg g g g g gg  gg g g ", val: 9.23},
            {country: "OTHERS", val: 4.09}
        ];

        var w = 600,
                h = 600,
                r = Math.min(w, h) / 2 - 100,
                labelr = r + 30, // radius for label anchor
                color = d3.scale.category20(),
                donut = d3.layout.pie(),
                arc = d3.svg.arc().innerRadius(r * .6).outerRadius(r);

        var vis = d3.select("#chart")
                .append("svg:svg")
                .data([data])
                .attr("width", w + 150)
                .attr("height", h);

        var arcs = vis.selectAll("g.arc")
                .data(donut.value(function(d) { return d.val }))
                .enter().append("svg:g")
                .attr("class", "arc")
                .attr("transform", "translate(" + (r + 200) + "," + (r+100) + ")");

        var arcOver = d3.svg.arc()
                .innerRadius(r * .57)
                .outerRadius(r + 5);

        arcs.append("path")
                .attr("fill", function(d, i) { return color(i); })
                .attr("d", arc)
                .on("mouseover",function(d){
                    d3.select(this).transition()
                      .duration(50)
                      .attr("d", arcOver);
                    tooltip.select('.label').html(d.value + "%");
                    tooltip.style('display', 'block');
                })
                .on('mouseout', function() {
                    d3.select(this).transition()
                            .duration(50)
                            .attr("d", arc);
                    tooltip.style('display', 'none');
                })
                .on('mousemove', function(d) {
                    tooltip.style('top', (d3.event.pageY - 80) + 'px')
                            .style('left', (d3.event.pageX + 10) + 'px');
                });

       var text =  arcs.append("text")
                .attr("transform", function(d) {
                    var c = arc.centroid(d),
                            x = c[0],
                            y = c[1],
                    // pythagorean theorem for hypotenuse
                            h = Math.sqrt(x*x + y*y);
                    return "translate(" + (x/h * labelr) +  ',' +
                            (y/h * labelr) +  ")";
                })
                .attr("dy", ".35em")
                .attr("text-anchor", function(d) {
                    // are we past the center?
                    return (d.endAngle + d.startAngle)/2 > Math.PI ?
                            "end" : "start";
                });/*
                .text(function(d) {
          return d.data.country; 
        });*/
text.each(function(d){
    var text = d3.select(this),
        words = d.data.country.split(/\s+/).reverse(),
        word,
        line = [],
        lineNumber = 0,
        lineHeight = 0.22, // 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() > 10) {
        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/3.4.11/d3.min.js"></script>
<div id='chart'></div>


在做了大量的工作之后。我懂了。
希望这将满足您的需要/要求。

我所做的只是,
将 tspan 元素添加到文本元素。观察下面的代码。 text 是一个 var 请参见上面的代码。它包含我们想要添加到每个 g 的所有文本元素
text.each(function(d){
        var text = d3.select(this),//selecting current text element
            words = d.data.country.split(/\s+/).reverse(),//splitting the country name by using space, if you want you can change.
            word,//to store one one word
            line = [],
            lineNumber = 0,
            lineHeight = 0.22, // ems, you can increase for more gaps vise versa
            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() > 10) {//here I'm checking the length of the text
            line.pop();
            tspan.text(line.join(" "));
            line = [word];
            tspan = text.append("tspan")
            .attr("x", 0)
            .attr("y", y)
            .attr("dy", ++lineNumber * lineHeight + dy + "em")//setting the gap between the label line gaps.
            .text(word);
          }
        }
    })

关于d3.js - 圆环图标签太长,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30207847/

相关文章:

javascript - 在 D3.js 中子级转换结束后删除父级

java - Graphics类型变量绘制的线在为其制作标签时消失

filter - 从 Gmail 过滤和标签系统中排除已发送的电子邮件

wpf - 更改标签的行为以支持在 WPF 中通过单击进行切换

r - 如何仅在 geom_label_repel() 中更改文本颜色而不是线条颜色

mapping - Cartojs4 - 多值圆环图标记

javascript - 如何在 y 轴上移动 d3 刻度

javascript - d3 map鼠标悬停事件响应慢

javascript - 将标题文本添加到 d3 中的路径中心

google-visualization - 如果只有一项 = 100%,则 Google donut chart 不会显示正文中的数字