d3.js向饼图添加元素

时间:2016-05-07 08:44:37

标签: javascript d3.js ember.js charts pie-chart

我尝试使用可以显示更多或更少元素的新数据和新值来更新饼图。删除弧和更新值(使用相同数量的元素)是可以的。

问题在于添加新弧时:饼图过渡但是它会留下新弧应该出现的空白并在饼图外部绘制一些弧。

以下是我如何创建饼图(省略arcTween函数,鼠标悬停,点击等)

    svg.attr('width', width).attr('height', height);

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

    let arc = d3.svg.arc()
            .innerRadius(innRadius)
            .outerRadius(outRadius);

    svg.append('g')
         .attr('class', 'donut-chart')
         .attr('transform', 'translate(' + (width / 2) + ',' + (height / 1.75) +')');

    svg.select('.donut-chart')
         .selectAll('.donut-arc')
         .data(pie(values))
         .enter()
         .append('g')
         .attr('class', 'donut-arc _selected_');

    svg.selectAll('.donut-arc')
         .append('path')
         .attr('fill', function(d, i) { 
            if ( scale === 'linear') return color(d.value);
            return color(labels[i]); 
         })
         .attr('d', arc)
         .each(function(d) { this._current = d; });

    svg.selectAll('.donut-arc')
        .append('text')
        .attr('class', 'labelText')
        .attr("x", function(d) {
          var a = d.startAngle + (d.endAngle - d.startAngle)/2 - Math.PI/2;
          d.cx = Math.cos(a) * (outRadius + 75);
         return d.x = Math.cos(a) * (outRadius + 30);
        })
      .attr("y", function(d) {
          var a = d.startAngle + (d.endAngle - d.startAngle)/2 - Math.PI/2;
          d.cy = Math.sin(a) * (outRadius + 75);
          return d.y = Math.sin(a) * (outRadius + 20);
      })
      .text(function(d, i) {
          return labels[i];
      })
      .style("text-anchor", function(d) {
        var rads = ((d.endAngle - d.startAngle) / 2) + d.startAngle + 10;
        if ( (rads > 7 * Math.PI / 4 && rads < Math.PI / 4) || (rads > 3 * Math.PI / 4 && rads < 5 * Math.PI / 4) ) {
          return "middle";
        } else if (rads >= Math.PI / 4 && rads <= 3 * Math.PI / 4) {
            return "start";
        } else if (rads >= 5 * Math.PI / 4 && rads <= 7 * Math.PI / 4) {
            return "end";
        } else {
            return "middle";
        }
      });

    svg.selectAll('path').transition().attrTween("d", arcTween);

这是我如何更新馅饼

    let paths = svg.datum(values).selectAll('path').data(pie);
    let textLabels = svg.selectAll('.labelText').data(pie(values));

    paths.enter()
        .append('path')
        .attr('fill', function(d, i) { 
            if ( scale === 'linear') return color(d.value);
            return color(labels[i]); 
         })
         .attr('d', arc)
         .each(function(d) { this._current = d; });

    textLabels.enter()
        .append('text');

    paths.transition()
        .duration(1000)
        .attrTween('d', arcTween);

    textLabels.transition()
        .duration(1250)
      .attr("x", function(d) {
          var a = d.startAngle + (d.endAngle - d.startAngle)/2 - Math.PI/2;
          d.cx = Math.cos(a) * (outRadius + 75);
          return d.x = Math.cos(a) * (outRadius + 30);
      })
      .attr("y", function(d) {
          var a = d.startAngle + (d.endAngle - d.startAngle)/2 - Math.PI/2;
          d.cy = Math.sin(a) * (outRadius + 75);
          return d.y = Math.sin(a) * (outRadius + 20);
      })
      .style("text-anchor", function(d) {
        var rads = ((d.endAngle - d.startAngle) / 2) + d.startAngle + 10;
        if ( (rads > 7 * Math.PI / 4 && rads < Math.PI / 4) || (rads > 3 * Math.PI / 4 && rads < 5 * Math.PI / 4) ) {
          return "middle";
        } else if (rads >= Math.PI / 4 && rads <= 3 * Math.PI / 4) {
            return "start";
        } else if (rads >= 5 * Math.PI / 4 && rads <= 7 * Math.PI / 4) {
            return "end";
        } else {
            return "middle";
        }
       })
       .text(function(d, i) {
          return labels[i];
       });

  paths.exit().remove();
  textLabels.exit().remove();

  svg.transition().attr({width: width, height: height});

我做错了什么?

此饼图是一个Ember组件,其完整代码可以找到here

here您可以找到有效的应用。单击任何区域以显示饼图。

1 个答案:

答案 0 :(得分:0)

我已经找到了解决方案!

我错过了一个变换,找到了出现在馅饼中的新弧的中心。我也没有选择合适的元素。例如:selectAll(&#39; .labelText&#39;)错误。您最好选择selectAll(&#39; text&#39;)来输入新数据。

感谢您的所有答案!