我正在使用建立在D3版本3上的代码,并试图更新它.我做了所有更明显的更新-

  • d3.layout.pie()=>d3.pie()
  • d3.svg.arc()=>d3.arc()
  • d3.scale.ordinal()=>d3.scaleOrdinal()

但是我最终得到了一个带有空白路径的SVG <path class="slice" style="fill: rgb(0, 128, 0);"></path>

以下是JS:

const width = 350, height = 200, radius = Math.min(width, height) / 2;

const svg = d3.select(".donut")
    .append("svg")
    .append("g")

svg.append("g")
    .attr("class", "slices");

const pie = d3.pie()
    .sort(null)
    .value((d) => d.value);

const arc = d3.arc()
    .outerRadius(radius * .9)
    .innerRadius(radius * 0.6);

svg.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

const key = (d) => d.data.label;

const color = d3.scaleOrdinal()
    .domain(['a','b','c'])
    .range(["#FF0000", "#FFF000", "#008000"]);

const generate = (data) => {
    const dataSum = d3.sum(data, (d) => d.value);

    /* ------- PIE SLICES -------*/
    const slice = svg.select(".slices").selectAll("path.slice")
    .data(pie(data), key);

    slice.enter()
        .insert("path")
        .style("fill", (d) => color(d.data.label))
        .attr("class", "slice");

    slice       
        .transition().duration(1000)
        .attrTween("d", function(d) {
            this._current = this._current || d;
            const interpolate = d3.interpolate(this._current, d);
            this._current = interpolate(0);
            return function(t) {
                return arc(interpolate(t));
            };
        })

    slice.exit()
        .remove();
};

const donutData = [
    {label: 'a', value: 80},
    {label: 'b', value: 10},
    {label: 'c', value: 10},
];

generate(donutData);

Css非常简单,shouldn't个就是问题:

.donut { 
  width: 960px;
  height: 500px;
}

svg {
  width: 100%;
  height: 100%;
}
    
path.slice{
  stroke-width:2px;
}

我的印象是,slice.enter()部分有问题(漏掉了.merge()?),或者更有可能的是,在退出之前的整个interpolate()部分有问题.不幸的是,文件中没有任何东西,或者至少是我对它的解释,都没有帮助.您可以在CodePen上查看当前(旧的,版本3)代码.

此外,如果有更好的方法从不使用D3的数据生成三节甜甜圈图,我也愿意接受这些建议.谢谢!

推荐答案

我已重写您的分区切片.请输入()(添加合并):

      slice.enter()
          .insert("path")
          .style("fill", (d) => color(d.data.label))
          .attr("class", "slice")
          .merge(slice)
          .transition().duration(1000)
          .attrTween("d", function (d) {
              const interpolate = d3.interpolate(this._current, d);
              this._current = interpolate(0);
              return function (t) {
                  return arc(interpolate(t));
              };
          });

      const width = 350,
          height = 200,
          radius = Math.min(width, height) / 2;

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

      svg.append("g")
          .attr("class", "slices");

      const pie = d3.pie()
          .sort(null)
          .value((d) => d.value);

      const arc = d3.arc()
          .outerRadius(radius * 0.9)
          .innerRadius(radius * 0.6);

      const key = (d) => d.data.label;

      const color = d3.scaleOrdinal()
          .domain(['a', 'b', 'c'])
          .range(["#FF0000", "#FFF000", "#008000"]);

      const generate = (data) => {
          const dataSum = d3.sum(data, (d) => d.value);

          const slice = svg.select(".slices").selectAll("path.slice")
              .data(pie(data), key);

          slice.enter()
              .insert("path")
              .style("fill", (d) => color(d.data.label))
              .attr("class", "slice")
              .merge(slice)
              .transition().duration(1000)
              .attrTween("d", function (d) {
                  const interpolate = d3.interpolate(this._current, d);
                  this._current = interpolate(0);
                  return function (t) {
                      return arc(interpolate(t));
                  };
              });

          slice.exit()
              .remove();
      };

      const donutData = [
          { label: 'a', value: 80 },
          { label: 'b', value: 10 },
          { label: 'c', value: 10 },
      ];

      generate(donutData);
      .donut {
          width: 960px;
          height: 500px;
      }

      svg {
          width: 100%;
          height: 100%;
      }

      path.slice {
          stroke-width: 2px;
      }
    <div class="donut"></div>

  
  <!-- === Vendor JS Files ================================= -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.5/d3.min.js"></script>

Javascript相关问答推荐

可以的.是否可以在不预编译的情况下使用嵌套 Select 器?

D3多线图显示1线而不是3线

显示图—如何在图例项上添加删除线效果?

为什么useState触发具有相同值的呈现

单个HTML中的多个HTML文件

覆盖TypeScrip中的Lit-Element子类的属性类型

在HTML语言中调用外部JavaScript文件中的函数

本地库中的chartjs-4.4.2和chartjs-plugin-注解

为什么客户端没有收到来自服务器的响应消息?

使用带有HostBinding的Angular 信号来更新样式?

在D3条形图中对具有相同X值的多条记录进行分组

使用jQuery find()获取元素的属性

使用API调用的VUE 3键盘输入同步问题

如何让SVG图标在被点击和访问后改变 colored颜色 ,并在被访问后取消点击时恢复到原来的 colored颜色 ?

ReferenceError:无法在初始化之前访问setData

如何使用puppeteer操作所有选项

有角粘桌盒阴影

在传单的图像覆盖中重新着色特定 colored颜色 的所有像素

在执行console.log(new X())时记录一个字符串

如何在预览中显示html+css与数据URL?