0

所以我又是这个 d3js 馅饼。

我已经设法在单选按钮检查上设置了带有切片(弧)和百分比文本变化的饼图。您可以在以下链接中看到一个示例:http: //jsfiddle.net/fBwEe/

因此,在那之后,我注意到较小的弧线及其标签存在问题。它们出现在弧线的中间,并且由于它们比弧线宽度更宽,因此它们似乎被切掉了。

所以我试图过滤掉那些较小的弧线,并将它们的标签放在更靠近圆心的位置,这样它们就在弧线之外但在它之下。

我用过 d3js.filter()功能。我的问题出现了。它们在渲染过程中的某个地方混合在一起,特别是在使用单选按钮更改显示数据时,甚至显示数据为空(如 MG 数据集)标签也会显示。我很困惑,因为我在控制台中没有任何错误,但显然有问题。您可以在jsfiddle中对其进行测试,代码如下:

var data_1 = [
              {"ASS": 50, "PR": 70, "BPR":3, "MA": 1, "MG": 30},
              {"ASS": 3, "PR": 2, "BPR":4, "MA": 40, "MG": 70 },
              {"ASS": 20, "PR": 5, "BPR":6, "MA": 2, "MG": ""},
              {"ASS": 25, "PR": 2, "BPR":2, "MA": 55, "MG": ""},
              {"ASS": 2, "PR": 2, "BPR":2, "MA": 3, "MG": ""},
             ]

var dataN_1 = [
                {"naslov":"Landkreis Starnberg", "total":"23.610", "id":"32829456"}

              ]

var width_1 = $(".pie_container_1").width();
    height_1 = $(".pie_container_1").height();


var svg_1 = d3.select(".pie_container_1").append("svg")
    .attr("width", width_1)
    .attr("height", height_1)
    .attr("id","canvasPie_1")
    .attr("preserveAspectRatio","xMinYMid")
  .append("g")
    .attr("transform", "translate(" + width_1 / 2 + "," + height_1 / 2 + ")");

var canvasPie_1 = $("#canvasPie_1"),
            aspect = canvasPie_1.width() / canvasPie_1.height(),
            containerd3_1 = canvasPie_1.parent();

var targetWidth_1 = containerd3_1.width();
var targetHeight_1 = containerd3_1.height();
    canvasPie_1.attr("width", targetWidth_1);
    canvasPie_1.attr("height", targetHeight_1);

var radius_1 = Math.min(targetWidth_1, targetHeight_1) / 2;

// var color_1 = d3.scale.category20c();

var color_1 = d3.scale.linear().domain([0,1,2,3,4,5]).range(['#c6dbef','#8cb2e0','#548cd3','#16355b','#0f233d']);

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

var arc_1 = d3.svg.arc()
    .innerRadius(radius_1 - 40)
    .outerRadius(radius_1);

var path_1 = svg_1.datum(data_1).selectAll("path")
      .data(pie_1)
    .enter().append("g")
      .attr("class", "slice")
      .append("path")
      .attr("fill", function(d, i) { return color_1(i); })
      .attr("d", arc_1)
      .each(function(d) { this._current = d; }); // store the initial angles


svg_1.selectAll(".slice").filter(function(d) { return d.endAngle - d.startAngle > .2; })
    .append("text")
    .attr("class","val")
    .attr("transform", function(d) {
                d.innerRadius = 0;
                d.outerRadius = radius_1;
                return "translate(" + arc_1.centroid(d) + ")";
            })
    .style("text-anchor", "middle")
    .attr("fill","#FFFFFF")
    .style("font-weight","600")
    .data(data_1)
    .text(function(d) { return d.ASS + "%"; });

svg_1.selectAll(".slice").filter(function(d) { return d.endAngle - d.startAngle < .2; })
    .append("text")
    .attr("class","valS")
    .attr("transform", function(d) {
                d.innerRadius = 0;
                d.outerRadius = radius_1;
                return "translate(" + arc_1.centroid(d)[0] + "," +  (arc_1.centroid(d)[1]+7)*0.6  + ")";
            })
    .style("text-anchor", "middle")
    .attr("fill","#777")
    .style("font-weight","600")
    .data(data_1)
.text(function(d) { return d.ASS + "%"; });

d3.selectAll(".pie_change_1")
  .on("change", change_1);



function change_1() {
   var value_1 = this.value;

svg_1.selectAll(".val").remove();
svg_1.selectAll(".valS").remove();

// clearTimeout(timeout_1);   
pie_1.value(function(d) { return d[value_1]; }); // change the value function

path_1 = path_1.data(pie_1); // compute the new angles

path_1.transition().duration(750).attrTween("d", arcTween_1); // redraw the arcs

svg_1.selectAll(".slice").data(pie_1).filter(function(d) { return d.endAngle - d.startAngle > .2; })
.append("text")
.attr("class","val")
.attr("transform", function(d) {
            d.innerRadius = 0;
            d.outerRadius = radius_1;
            return "translate(" + arc_1.centroid(d) + ")";
        })
.style("text-anchor", "middle")
.attr("fill","#FFFFFF")
.style("font-weight","600")
.data(data_1)
.text(function(d) { 
                     if( value_1 == "MG" && d.MG != "" ){ return d.MG + "%"; }
                     if( value_1 == "MA" ){ return d.MA + "%"; }
                     if( value_1 == "BPR" ){ return d.BPR + "%"; }
                    if( value_1 == "PR" ){ return d.PR + "%"; }
                     if( value_1 == "ASS" ){ return d.ASS + "%"; }

                 });


svg_1.selectAll(".slice").data(pie_1).filter(function(d) { return d.endAngle - d.startAngle < .2; })
.append("text")
.attr("class","valS")
.attr("transform", function(d) {
            d.innerRadius = 0;
            d.outerRadius = radius_1;
            return "translate(" + arc_1.centroid(d)[0] + "," +  (arc_1.centroid(d)[1]+7)*0.6  + ")";
        })
.style("text-anchor", "middle")
.attr("fill","#777")
.style("font-weight","600").data(pie_1).filter(function(d) { return d.endAngle - d.startAngle < .2; })
.data(data_1)
.text(function(d) { 
                     if( value_1 == "MG" && d.MG != "" ){ return d.MG + "%"; }
                     if( value_1 == "MA" ){ return d.MA + "%"; }
                     if( value_1 == "BPR" ){ return d.BPR + "%"; }
                    if( value_1 == "PR" ){ return d.PR + "%"; }
                     if( value_1 == "ASS" ){ return d.ASS + "%"; }

                 });


}


function arcTween_1(a) {
  var i = d3.interpolate(this._current, a);
  this._current = i(0);
  return function(t) {
    return arc_1(i(t));
  };
}

function angle(d) {
    var a = (d.startAngle + d.endAngle) * 90 / Math.PI - 90;
    return a > 90 ? a - 180 : a;
  }

欢迎任何帮助或建议...

4

1 回答 1

0

问题在于arc_1布局助手的定义。

如果你想让你的方案奏效,你必须对accessorsfor更有创意:innerRadiusouterRadius

var arc_1 = d3.svg.arc()
    .innerRadius(function (d) { 
         return isDef(d.innerRadius) ? d.innerRadius : radius_1 - 40; 
    })
    .outerRadius(function (d) { 
         return isDef(d.outerRadius) ? d.outerRadius : radius_1;
    });

然后,当您尝试放置label来计算质心时,请执行以下操作:

    .attr("transform", function(d) {
                // Use $.extend here, if you are using jQuery
                // This is poor man's way of cloning an object.
                var d2 = JSON.parse(JSON.stringify(d));
                d2.innerRadius = 0;
                d2.outerRadius = radius_1;
                return "translate(" + arc_1.centroid(d2) + ")";
            })

工作演示:演示


但是,您会发现这不是一个非常令人满意的方案,因为标签仍然被遮挡。

此外,标签的遮挡是一个很常见的问题,我之前至少提出了另外两种解决方案:

  1. 如果有足够的空间,D3 将弧形标签放在饼图中
  2. 防止 D3 中的文本剪辑(Javascript 图表)防止 D3 饼图中的文本重叠
于 2013-11-15T20:50:26.510 回答