javascript - 如何在饼图上正确绘制文本?

标签 javascript d3.js

我创建了一个饼图,它显示得很好。

只是,我注意到一些文本被饼图切片隐藏了。通过仔细观察,我注意到每个文本都可以与下一个切片一起绘制。

所以渲染顺序是这样的:切片 1、文本 1、切片 2、文本 2、切片 3、文本 3 等...

如何才能使渲染顺序为切片 1、切片 2、切片 3...切片 n。 然后文本 1、文本 2、文本 3...文本 n

然后文本将始终显示,因为它将绘制在饼图的每个切片的顶部。

谢谢,这是我的代码

  function createChart(dom, newData, title) {

      d3.select(dom).selectAll("*").remove();

      // Define size & radius of donut pie chart
      var width = 450,
        height = 800,
        radius = Math.min(width, height) / 2;

      // Define arc colours
      var colour = d3.scale.category20();

      // Define arc ranges
      var arcText = d3.scale.ordinal()
              .rangeRoundBands([0, width], .1, .3);

      // Determine size of arcs
      var arc = d3.svg.arc()
        .innerRadius(radius - 130)
        .outerRadius(radius - 10);

      // Create the donut pie chart layout
      var pie = d3.layout.pie()
          .value(function (d) { return d.count; })
        .sort(null);

      // Append SVG attributes and append g to the SVG
      var mySvg = d3.select(dom).append("svg")
        .attr("width", width)
        .attr("height", height);

      var svg = mySvg
          .append("g")
          .attr("transform", "translate(" + radius + "," + radius + ")");

      var svgText = mySvg
          .append("g")
          .attr("transform", "translate(" + radius + "," + radius + ")");

      // Define inner circle
      svg.append("circle")
        .attr("cx", 0)
        .attr("cy", 0)
        .attr("r", 100)
        .attr("fill", "#fff") ;

      // Calculate SVG paths and fill in the colours
      var g = svg.selectAll(".arc")
              .data(pie(newData))
              .enter().append("g")
              .attr("class", "arc");

          // Append the path to each g
          g.append("path")
          .attr("d", arc)
          //.attr("data-legend", function(d, i){ return parseInt(newData[i].count) + ' ' + newData[i].emote; })
          .attr("fill", function(d, i) {
              return colour(i);
          });

          // Append text labels to each arc
          g.append("text")
          .attr("transform", function(d) {
              return "translate(" + arc.centroid(d) + ")";
          })
          .attr("dy", ".35em")
          .style("text-anchor", "middle")
          .attr("fill", "#fff")
              .text(function(d,i) { return newData[i].count > 0 ? newData[i].emote : ''; })

          // Append text to the inner circle
          svg.append("text")
            .style("text-anchor", "middle")
              .attr("fill", "#36454f")
            .text(function(d) { return title; })
            .style("font-size","16px")
            .style("font-weight", "bold");
  }

最佳答案

最简单的方法是为 text 标签提供自己的 g 并重新绑定(bind)数据:

// there own g
var textG = svg.selectAll(".labels")
  .data(pie(newData))
  .enter().append("g")
  .attr("class", "labels");

// Append text labels to each arc
textG.append("text")
  .attr("transform", function(d) {
    return "translate(" + arc.centroid(d) + ")";
  })
  .attr("dy", ".35em")
  .style("text-anchor", "middle")
  .attr("fill", "#fff")
  .text(function(d, i) {
    return d.data.count > 0 ? d.data.emote : ''; // you can use d.data instead of indexing
  });

完整示例:

<!DOCTYPE html>
<html>

<head>
  <script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
</head>

<body>
  <script>
    var newData = [{
        count: 1,
        emote: "OneTwoThree"
      }, {
        count: 1,
        emote: "FourFiveSix"
      }, {
        count: 1,
        emote: "SevenEightNine"
      }, {
        count: 15,
        emote: "TenElevenTwelve"
      },

    ]

    // Define size & radius of donut pie chart
    var width = 450,
      height = 800,
      radius = Math.min(width, height) / 2;

    // Define arc colours
    var colour = d3.scale.category20();

    // Define arc ranges
    var arcText = d3.scale.ordinal()
      .rangeRoundBands([0, width], .1, .3);

    // Determine size of arcs
    var arc = d3.svg.arc()
      .innerRadius(radius - 130)
      .outerRadius(radius - 10);

    // Create the donut pie chart layout
    var pie = d3.layout.pie()
      .value(function(d) {
        return d.count;
      })
      .sort(null);

    // Append SVG attributes and append g to the SVG
    var mySvg = d3.select('body').append("svg")
      .attr("width", width)
      .attr("height", height);

    var svg = mySvg
      .append("g")
      .attr("transform", "translate(" + radius + "," + radius + ")");

    var svgText = mySvg
      .append("g")
      .attr("transform", "translate(" + radius + "," + radius + ")");

    // Define inner circle
    svg.append("circle")
      .attr("cx", 0)
      .attr("cy", 0)
      .attr("r", 100)
      .attr("fill", "#fff");

    // Calculate SVG paths and fill in the colours
    var g = svg.selectAll(".arc")
      .data(pie(newData))
      .enter().append("g")
      .attr("class", "arc");

    // Append the path to each g
    g.append("path")
      .attr("d", arc)
      //.attr("data-legend", function(d, i){ return parseInt(newData[i].count) + ' ' + newData[i].emote; })
      .attr("fill", function(d, i) {
        return colour(i);
      });

    var textG = svg.selectAll(".labels")
      .data(pie(newData))
      .enter().append("g")
      .attr("class", "labels");

    // Append text labels to each arc
    textG.append("text")
      .attr("transform", function(d) {
        return "translate(" + arc.centroid(d) + ")";
      })
      .attr("dy", ".35em")
      .style("text-anchor", "middle")
      .attr("fill", "#fff")
      .text(function(d, i) {
        return d.data.count > 0 ? d.data.emote : '';
      });
  </script>
</body>

</html>

关于javascript - 如何在饼图上正确绘制文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32293513/

相关文章:

javascript - 未捕获的语法错误 : Unexpected end of JSON input error when i try to take data from mysql

javascript - 如何仅在特定条件下限制 jQuery,否则立即执行?

javascript - 将事件监听器添加到 d3 画笔

d3.js - 如何用D3JS渲染一个通用的点阵?

javascript - JQuery 发现不适用于 tr 元素?

javascript - 对当前 URL 的 XMLHttpRequest POST 请求的有效 URL 字符串

asp.net - 有关可移动组件资源的提示

d3.js - 如何使用 d3 获取输入元素的动态值?

css - 如何自动删除/禁用宽度 100%?

javascript - 使用 d3.layout.stack() 堆叠多个指标的干法