圆环图的标签太长

时间:2015-05-13 07:04:14

标签: 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; });

感谢!!!

1 个答案:

答案 0 :(得分:0)



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>
&#13;
&#13;
&#13;

做了大量的工作后。我懂了。 希望这能满足您的需求。

我所做的只是, 将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);
          }
        }
    })