C3 - 如何将圆环图中的文本居中?

C3 - How to center text in donut chart?

我对 C3 圆环图有疑问 - 它没有在图表内居中放置文本: http://jsfiddle.net/aspirisen/q8h39/83/

c3.generate({
  legend: {
    show: false,
    position: 'right'
  },
  data: {
    columns: [
      ['data1', 50],
      ['data2', 50],
    ],
    type: 'donut',
    onclick: function (d, i) { console.log("onclick", d, i); },
    onmouseover: function (d, i) { console.log("onmouseover", d, i); },
    onmouseout: function (d, i) { console.log("onmouseout", d, i); }
  },
  tooltip: {
    show: false
  },
  donut: {
    width: 26,
    label: {
      format: function (value, ratio, id) {
        return (ratio * 100).toFixed(0).toString()
      }
    }
  }
});

何解决此问题?

谢谢!

您可以尝试一些事情。

  1. 调整您的图表大小 and/or font-size。我认为这是迄今为止最简单的解决方案。

  1. 在图表初始化后手动定位标签(通过 setTimeout 或类似的方式)。 (有关详细信息,请参阅 this Whosebug question。)为此,您需要 select 所有 c3-chart-arc text 元素,然后确定如何放置它们。

    缺点:c3 使用圆弧的质心计算标签位置,我不确定是否有比这更好的定位方法,除非你事先知道你的输出是什么看起来像(例如,只有 2 个弧线,所以将左侧文本定位在左侧,右侧文本定位在右侧)。

咆哮警告 -- 这就是为什么 "helper" 建立在 d3 之上的库如此困扰我的原因。直接创建这个圆环图 d3 的代码量大致相同,您可以完全控制这样的事情。

无论如何,你可以通过 re-computing c3 绘制后的质心和 re-positioning 文本来解决这个问题(调整半径 r 以移动标签):

// find all the labels
d3.selectAll(".c3-chart-arc>text")
  .attr("transform", function(d,i){
    var r = 30, //<-- adjust this to move the labels
        a = (d.startAngle + d.endAngle) / 2 - (Math.PI / 2);
    // compute the new centroid
    return "translate(" + (Math.cos(a) * r) + "," + (Math.sin(a) * r) + ")";
});

完整代码:

c3.generate({
  legend: {
    show: false,
    position: 'right'
  },
  data: {
    columns: [
      ['data1', 32],
      ['data2', 50],
    ],
    type: 'donut',
    onclick: function (d, i) { console.log("onclick", d, i); },
    onmouseover: function (d, i) { console.log("onmouseover", d, i); },
    onmouseout: function (d, i) { console.log("onmouseout", d, i); }
  },
  tooltip: {
    show: false
  },
  donut: {
    width: 26,
    label: {
      format: function (value, ratio, id) {
        return (ratio * 100).toFixed(0).toString()
      }
    }
  }
});

setTimeout(function(){
d3.selectAll(".c3-chart-arc>text")
 .attr("transform", function(d,i){
   var r = 30,
        a = (d.startAngle + d.endAngle) / 2 - (Math.PI / 2);
     console.log("translate(" + (Math.cos(a) * r) + "," + (Math.sin(a) * r) + ")")
    return "translate(" + (Math.cos(a) * r) + "," + (Math.sin(a) * r) + ")";
  });
}, 100);
#chart {
  width: 100px;
  height: 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.js"></script>
<div id="chart"></div>