3

I am not able to show labels properly for the cases where group values are very close together so the labels tend to overlap. I have tried minAngleForLabel. What else can be done here? The code for the pie chart is:

  var types = xf.dimension(function(d) { return d.txntype; });
  var typesSum = types.group().reduceSum(function(d) { return d.txnamount; });
  var pieChart = dc.pieChart("#pie-row-chart",groupname)
      .width(370)
      .height(309)
      .slicesCap(4)
      .innerRadius(70)
      .colors(d3.scaleOrdinal(d3.schemeSet1))
      .drawPaths(true)
      .externalRadiusPadding(60)
      .minAngleForLabel(5)
      .externalLabels(40)
      .dimension(types)
      .group(typesSum)
      .title(function(d) {
          return d.key + ': ' +  Math.round((d.value * 100)/100) + ' BDT';
      })
      .on('pretransition', function(pieChart) {
          pieChart.selectAll('text.pie-slice').text(function(d) {
              return d.data.key + ' ' + dc.utils.printSingleValue((d.endAngle - d.startAngle) / (2*Math.PI) * 100) + '%';
          })
      });

Gordon
  • 19,811
  • 4
  • 36
  • 74
  • 1
    Please use the [dc.js] tag for questions about the charting library. [dc] is a classic unix calculator utility. – Gordon May 02 '19 at 13:08
  • Hmm, that setting should actually remove all the labels (!), since `minAngleForLabel` is specified in radians... I missed this question because of the wrong tag, did you figure it out yet? – Gordon May 03 '19 at 11:03
  • You're right Gordon. But the labels are still there! I didn't solve it yet unfortunately. I can't figure out why the minAngleForLabel doesn't work. – Shaibal Ahmed May 05 '19 at 05:50

1 Answers1

2

I suspect what is happening is that the chart set the label to the empty string when there is no data, and then you are setting it back in your pretransition handler.

The chart has

function sliceTooSmall (d) {
    var angle = (d.endAngle - d.startAngle);
    return isNaN(angle) || angle < _minAngleForLabel;
}

source

    labels
        .text(function (d) {
            var data = d.data;
            if ((sliceHasNoData(data) || sliceTooSmall(d)) && !isSelectedSlice(d)) {
                return '';
            }
            return _chart.label()(d.data);
    });

source

You can detect in your pretransition handler if the chart has decided not to display text, with d3.select(this).text():

  .on('pretransition', function(pieChart) {
      pieChart.selectAll('text.pie-slice').text(function(d) {
          return d3.select(this).text() && (d.data.key + ' ' + 
            dc.utils.printSingleValue((d.endAngle - d.startAngle) /
            (2*Math.PI) * 100) + '%');
      })
  });

Once you do that, you'll probably want to set minAngleForLabel a bit lower, since it's specified in radians.

Gordon
  • 19,811
  • 4
  • 36
  • 74