如何显示"饼图不可用"饼图中所有数据为0时的消息?

时间:2016-12-25 18:03:14

标签: d3.js

所以我在d3中制作了这个饼图,似乎工作得很好。但是当数据集具有全部0值时,我需要显示一条消息。  我试图对所有数据集值求和,如果值为0,则附加带有文本消息的div。我无法做到对。 有更好的方法吗?需要洞察力。

Here's the link to my codepen

angular.module('myApp', []).
directive('barsChart', function () {
var directiveDefinitionObject = {
    restrict: 'E',
    replace: false,
     scope: {data: '=chartData'},
     link: function (scope, element, attrs) {
    var data =  [
    {label:"Category 1", value:0}, 
    {label:"Category 2", value:0}, 
    {label:"Category 3", value:0}
    ];

   var colorRange = d3.scale.category20();
  var color = d3.scale.ordinal()
                     .range(colorRange.range()); 
  var width = 150;
    var height = 150;
  var radius = Math.min(height,width)/2;
  var labelr = radius + 10;
    var pie = d3.layout.pie()
              .sort(null)
              .value(function(d) {
                      return d.value;
                  });
    var arc = d3.svg.arc()
      .outerRadius(width / 2 * 0.9)
      .innerRadius(0);

  var outerArc = d3.svg.arc()
  .innerRadius(0)
  .outerRadius(Math.min(width, height) / 2 * 0.9);

       var legendRectSize = (radius * 0.05);
   var legendSpacing = radius * 0.02;

    var svg = d3.select(element[0]).append('svg')
      .attr({width: width, height: height})
      .append('g');
  var div = d3.select("body").append("div").attr("class", "toolTip");

            data.forEach(function (d) {
                if(d.value == undefined || d.value == NaN){
                    d.value = 0;
                }

            });

        svg.attr('transform', 'translate(' + 200 + ',' + height / 2 + ')');
       svg.append("g")
      .attr("class", "slices");
      svg.append("g")
     .attr("class", "labelName");
      svg.append("g")
     .attr("class", "labelValue");
      svg.append("g")
     .attr("class", "lines");


       var slice = svg.select(".slices").selectAll("path.slice")
    .data(pie(data), function(d){ 

    return d.data.label });

slice.enter()
    .insert("path")
    .style("fill", function(d) { return color(d.data.label); })
    .attr("class", "slice");

slice
    .transition().duration(1000)
    .attrTween("d", function(d) {
        this._current = this._current || d;
        var interpolate = d3.interpolate(this._current, d);
        this._current = interpolate(0);
        return function(t) {
            return arc(interpolate(t));
        };
    })
slice
    .on("mousemove", function(d){
        div.style("left", d3.event.pageX+10+"px");
        div.style("top", d3.event.pageY-25+"px");
        div.style("display", "inline-block");
        div.html((d.data.label)+"<br>"+(d.data.value)+"%");
    });
slice
    .on("mouseout", function(d){
        div.style("display", "none");
    });

slice.exit()
    .remove();

       var legend = svg.selectAll('.legend')
    .data(color.domain())
    .enter()
    .append('g')
    .attr('class', 'legend')
    .attr('transform', function(d, i) {
        var height = legendRectSize + legendSpacing;
        var offset =  height * color.domain().length / 2;
        var horz = -3 * legendRectSize;
        var vert = i * height - offset;
        return 'translate(' + horz/2 + ',' + 90 + ')';
    });

/*legend.append('rect')
    .attr('width', legendRectSize)
    .attr('height', legendRectSize)
    .style('fill', color)
    .style('stroke', color);

legend.append('text')
    .attr('x', legendRectSize + legendSpacing)
    .attr('y', legendRectSize - legendSpacing)
    .text(function(d) { return d; });

------- TEXT LABELS -------*/

var text = svg.select(".labelName").selectAll("text")
    .data(pie(data));
text.enter()
    .append("text")
    .attr("dy", ".35em")
    .text(function(d) {
        return (d.value+"%");
    });

 function midAngle(d){
    return d.startAngle + (d.endAngle - d.startAngle)/2;
 }
 text
    .transition().duration(1000)
    .attrTween("transform", function(d) {
        this._current = this._current || d;
        var interpolate = d3.interpolate(this._current, d);
        this._current = interpolate(0);
        return function(t) {
            var d2 = interpolate(t);
            var pos = outerArc.centroid(d2),
                x = pos[0],
                y = pos[1],
                h = Math.sqrt(x*x + y*y);
           return "translate(" + (x/h * labelr) +  ',' +
       (y/h * labelr) +  ")";
        };
    })
    .styleTween("text-anchor", function(d){
        this._current = this._current || d;
        var interpolate = d3.interpolate(this._current, d);
        this._current = interpolate(0);
        return function(t) {
            var d2 = interpolate(t);
            return (d2.endAngle + d2.startAngle)/2 > Math.PI ?
        "end" : "start";
        };
    })
    .text(function(d) {
        return (d.value+"%");
    });
  text.exit()
    .remove();
    } 
   };
   return directiveDefinitionObject;
    });

1 个答案:

答案 0 :(得分:1)

要简单地显示文本,请创建一个变量以显示文本:

var message = svg.append("text");

并检查值的总和是否为零:

if (!d3.sum(data, d => d.value)) {
    message.text("Pie Chart unavailable")
}

如果要创建<div>而不是SVG文本元素,请更改文本变量以附加div(SVG上的任何>,您无法追加divs到SVG),并保留if语句。

这是您更新的CodePen:http://codepen.io/anon/pen/qqGLLb?editors=0010