使用d3.js移动饼图的切片

5q4ezhmt  于 2023-05-07  发布在  其他
关注(0)|答案(2)|浏览(120)

在下面的代码中,创建了一个简单的饼图,但是在选中时,我无法向图表的外侧移动一个切片。
我希望单个(元素)切片位于饼图外部,其余饼图元素(切片)位于其通常位置,如下所示:

下面是我的代码:

<!DOCTYPE html>

<body>
  <script src="https://d3js.org/d3.v4.min.js"></script>
  <script>
    var data = [35, 20, 45];

    var width = 300,
      height = 300,
      radius = 150;

    var arc = d3.arc()
      .outerRadius(130);

    var arcLabel = d3.arc()
      .outerRadius(radius - 30)
      .innerRadius(radius - 20);

    var pie = d3.pie()
      .value(function(d) {
        return d;
      });

    var svg = d3.select("body").append("svg")
      .attr("width", width)
      .attr("height", height)
      .append("g")
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

    var emptyPies = svg.selectAll(".arc")
      .data(pie(data))
      .enter()
      .append("g")
      .attr("class", "arc")


    emptyPies.append("path")
      .attr("d", arc)
      .style("fill", function(d, i) {
        return color[i];
      })

    emptyPies.append("text")
      .attr("transform", function(d) {
        return "translate(" + arcLabel.centroid(d) + ")";
      })
      .text(function(d) {
        return d.data;
      });

  </script>
kq4fsx7k

kq4fsx7k1#

一个简单的解决方案是创建一个不同的电弧发生器:

var arc2 = d3.arc()
    .outerRadius(radius)
    .innerRadius(60);

并且,在设置"d"属性时,选择要使用的电弧发生器。例如,移动红色切片:

emptyPies.append("path")
    .attr("d", function(d,i){
        return i != 1 ? arc(d) : arc2(d);
})

下面是修改后的代码:

<!DOCTYPE html>
<style>
  .arc text {
    text-anchor: middle;
  }
  
  .arc path {
    stroke: white;
  }

</style>

<body>
  <script src="https://d3js.org/d3.v4.min.js"></script>
  <script>
    var data = [35, 20, 45];

    var width = 300,
      height = 300,
      radius = Math.min(width, height) / 2;


    var color = ["brown", "red", "blue"];

    var arc = d3.arc()
      .outerRadius(radius - 10)
      .innerRadius(50);
      
    var arc2 = d3.arc()
      .outerRadius(radius)
      .innerRadius(60);

    var arcLabel = d3.arc()
      .outerRadius(radius - 30)
      .innerRadius(radius - 20);


    var pie = d3.pie()
      .value(function(d) {
        return d;
      });


    var svg = d3.select("body").append("svg")
      .attr("width", width)
      .attr("height", height)
      .append("g")
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");


    var emptyPies = svg.selectAll(".arc")
      .data(pie(data))
      .enter()
      .append("g")
      .attr("class", "arc")



    emptyPies.append("path")
      .attr("d", function(d,i){
      return i != 1 ? arc(d) : arc2(d);})
      .style("fill", function(d, i) {
        return color[i];
      })


    emptyPies.append("text")
      .attr("transform", function(d) {
        return "translate(" + arcLabel.centroid(d) + ")";
      })
      .text(function(d) {
        return d.data;
      });

  </script>
wnvonmuf

wnvonmuf2#

一个简单的解决方案是使用multiple arc(),但要进行切片,我们可以使用第二个弧的arc.centroid()。下面的代码将在v5中工作。

function onDrawPieChart() {
    var data = [35, 20, 45];
    var color = d3.schemeCategory10;
    var width = 600;
    var height = 600;
    var radius = 100;

    var pie = d3.pie().value((d) => d);
    var arc = d3.arc().innerRadius(0).outerRadius(130);
    var arc2 = d3.arc().innerRadius(0).outerRadius(20);
    var slicedIndex = 1;
    var pieData = pie(data);
    var centroid = arc2.centroid(pieData[slicedIndex]);
    var svg = d3
      .select("body")
      .append("svg")
      .attr("viewBox", [-width / 2, -height / 2, width, height].join(" "))
      .attr("width", width)
      .attr("height", height)
      .append("g");

    svg
      .selectAll("path")
      .data(pieData)
      .join("path")
      .attr("fill", (d, i) => color[i])
      .attr("d", (d) => arc(d))
      .attr("transform", (d, i) => {
        if (i === slicedIndex) {
          var [x, y] = centroid;
          return "translate(" + x + ", " + y + ")";
        }
      });
  }

相关问题