d3.js 复制D3可缩放朝阳(可观察)的纯JS版本

u7up0aaq  于 2022-11-12  发布在  其他
关注(0)|答案(1)|浏览(142)

我一直在尝试在纯JS中复制https://beta.observablehq.com/@mbostock/d3-zoomable-sunburst this,以便在我的一个项目中使用它。我正在使用PHP和 AJAX 在JavaScript中加载动态数据。我认为Observable链接中的代码不是纯JS中的,而是Node或其他代码。
我是一个脚本新手,所以对我来说理解编写的代码变得非常困难。我知道一个纯JS需要特定格式的数据(flare.json),这将生成预期的输出。我可以从后端控制JSON结构,但我无法生成像链接这样的输出。
我在网上看过多个例子:
https://bl.ocks.org/mbostock/4348373
在d3版本4中也是如此(这与v5非常相似,在可观测的例子中使用):
https://bl.ocks.org/maybelinot/5552606564ef37b5de7e47ed2b7dc099
我一直在尝试将Observable Zoomable朝阳转换为JS函数,但是我无法让它工作。我有完全相同的flare.json文件,并试图重新创建与Observable中的函数完全相同的函数。但是它仍然不工作。
我正在附加我的作品。我如何才能让它工作?
Sample Work
我也试着在Google Groups上为d3-js寻求帮助,但我也没有从那里得到任何帮助。
到目前为止,我所获得的最接近的可能输出如下:
第一个

wi3ka0sx

wi3ka0sx1#

编写的代码是纯javascript坚韧无论您从 AJAX 获得什么数据,您只需要在这里传递相同的端点,
我在这里运行的示例意味着同样的方法也可以在您的项目中使用,您可以在此行中传递Json,而不是调用 AJAX

d3.json("https://gist.githubusercontent.com/mbostock/4348373/raw/85f18ac90409caa5529b32156aa6e71cf985263f/flare.json", function(error, root)
<!DOCTYPE html>
<meta charset="utf-8">
<style>
  path {
    stroke: #fff;
  }
</style>

<body>
  <script src="https://d3js.org/d3.v4.min.js"></script>
  <script>
    var width = 960,
      height = 700,
      radius = (Math.min(width, height) / 2) - 10;

    var formatNumber = d3.format(",d");

    var x = d3.scaleLinear()
      .range([0, 2 * Math.PI]);

    var y = d3.scaleSqrt()
      .range([0, radius]);

    var color = d3.scaleOrdinal(d3.schemeCategory20);

    var partition = d3.partition();

    var arc = d3.arc()
      .startAngle(function(d) {
        return Math.max(0, Math.min(2 * Math.PI, x(d.x0)));
      })
      .endAngle(function(d) {
        return Math.max(0, Math.min(2 * Math.PI, x(d.x1)));
      })
      .innerRadius(function(d) {
        return Math.max(0, y(d.y0));
      })
      .outerRadius(function(d) {
        return Math.max(0, y(d.y1));
      });

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

    d3.json("https://gist.githubusercontent.com/mbostock/4348373/raw/85f18ac90409caa5529b32156aa6e71cf985263f/flare.json", function(error, root) {
      if (error) throw error;

      root = d3.hierarchy(root);
      root.sum(function(d) {
        return d.size;
      });

      svg.selectAll("path")
        .data(partition(root).descendants())
        .enter().append("path")
        .attr("d", arc)
        .style("fill", function(d) {
          return color((d.children ? d : d.parent).data.name);
        })
        .on("click", click)
        .append("title")
        .text(function(d) {
          return d.data.name + "\n" + formatNumber(d.value);
        });

      function labelVisible(d) {
        return d.y1 <= 3 && d.y0 >= 1 && (d.y1 - d.y0) * (d.x1 - d.x0) > 0.03;
      }

      function labelTransform(d) {
        const x = (d.x0 + d.x1) / 2 * 180 / Math.PI;
        const y = (d.y0 + d.y1) / 2 * radius;
        return `rotate(${x - 90}) translate(${y},0) rotate(${x < 180 ? 0 : 180})`;
      }

      svg.selectAll("text")
        .attr("dy", "0.35em")
        .attr("pointer-events", "none")
        .attr("text-anchor", "middle")
        .style("user-select", "none")
        .attr("fill-opacity", d => +labelVisible(d.current))
        .attr("transform", d => labelTransform(d.current))
        .data(root.descendants().slice(1))
        .enter().append("text")
        .text(d => d.data.name);

    });

    function click(d) {
      svg.transition()
        .duration(750)
        .tween("scale", function() {
          var xd = d3.interpolate(x.domain(), [d.x0, d.x1]),
            yd = d3.interpolate(y.domain(), [d.y0, 1]),
            yr = d3.interpolate(y.range(), [d.y0 ? 20 : 0, radius]);
          return function(t) {
            x.domain(xd(t));
            y.domain(yd(t)).range(yr(t));
          };
        })
        .selectAll("path")
        .attrTween("d", function(d) {
          return function() {
            return arc(d);
          };
        });
    }

    d3.select(self.frameElement).style("height", height + "px");
  </script>

相关问题