复杂的圆图

JNP*_*Per 4 javascript svg d3.js

我花了很多时间尝试在SVG/D3.js中复制附图.我最接近的是使用附加的代码.我已经探索过使用树函数,但只能创建一个圆圈.

附加代码的问题是,通过手动键入每个圆圈必须坐的像素坐标,很难使其看起来平滑和智能.

有关信息,数据集只会为这些圆圈着色,因此在形状方面它可以完全是静态的.代码只需要生成形状,然后我可以根据数据集驱动颜色.

我想要创建的图像:

在此输入图像描述

这是我的代码:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <title>D3 Test</title>
  <style type="text/css">

  </style>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
</head>

<body>
  <script type="text/javascript">
    //Width and height
    var w = 1000;
    var h = 1000;
    var dataset = [6, 2, 5, 4, 5, 5, 5, 5, 3, 4, 5, 6];
    var svg = d3.select("body")
      .append("svg")
      .attr("width", w)
      .attr("height", h);
    var circles = svg.selectAll("circle")
      .data(dataset)
      .enter()
      .append("circle");


    circles.attr("cx", function(d, i) {
      var Xaxis;
      if (i === 0) {
        Xaxis = "500";
      } else if (i === 1) {
        Xaxis = "400";
      } else if (i === 2) {
        Xaxis = "420";
      } else if (i === 3) {
        Xaxis = "452.5";
      } else if (i === 4) {
        Xaxis = "485";
      } else if (i === 5) {
        Xaxis = "515";
      } else if (i === 6) {
        Xaxis = "547.5";
      } else if (i === 7) {
        Xaxis = "580";
      } else if (i === 8) {
        Xaxis = "600";
      } else if (i === 9) {
        Xaxis = "600";
      } else if (i === 10) {
        Xaxis = "650";
      } else if (i === 11) {
        Xaxis = "700";
      } else if (i === 12) {
        Xaxis = "750";
      } else if (i === 13) {
        Xaxis = "750";
      } else if (i === 14) {
        Xaxis = "750";
      } else if (i === 15) {
        Xaxis = "750";
      } else if (i === 16) {
        Xaxis = "750";
      }
      return Xaxis;
    })
    circles.attr("cy", function(d, i) {
        var Yaxis;
        if (i === 0) {
          Yaxis = "500";
        } else if (i === 1) {
          Yaxis = "500";
        } else if (i === 2) {
          Yaxis = "535";
        } else if (i === 3) {
          Yaxis = "560";
        } else if (i === 4) {
          Yaxis = "585";
        } else if (i === 5) {
          Yaxis = "585";
        } else if (i === 6) {
          Yaxis = "560";
        } else if (i === 7) {
          Yaxis = "535";
        } else if (i === 8) {
          Yaxis = "500";
        } else if (i === 9) {
          Yaxis = "600";
        } else if (i === 10) {
          Yaxis = "550";
        } else if (i === 11) {
          Yaxis = "500";
        } else if (i === 12) {
          Yaxis = "450";
        } else if (i === 13) {
          Yaxis = "600";
        } else if (i === 14) {
          Yaxis = "550";
        } else if (i === 15) {
          Yaxis = "500";
        } else if (i === 16) {
          Yaxis = "450";
        }
        return Yaxis;
      })
      .attr("r", function(d, i) {
        var size;
        if (i === 0) {
          size = "30";
        } else if (i > 0) {
          size = "20";
        }
        return size;
      })
      .attr("fill", function(d, i) {
        var returnColor;
        if (d === 1) {
          returnColor = "green";
        } else if (d === 2) {
          returnColor = "lightgreen";
        } else if (d === 3) {
          returnColor = "gold";
        } else if (d === 4) {
          returnColor = "darkorange";
        } else if (d === 5) {
          returnColor = "red";
        } else if (d === 6) {
          returnColor = "lightgrey";
        }
        return returnColor;
      });
  </script>

</body>

</html>
Run Code Online (Sandbox Code Playgroud)

Ger*_*ado 7

您可以使用一些三角法来定位您的圆圈.这就是你需要的:

要将圆定位在x轴上:

x中心+(距离*sin(角度))

并将其定位在y轴上:

y中心+(距离*cos(角度))

distance圆与中心的距离在哪里,是以angle弧度表示的角度.要计算它,请使用:

rad = deg * Math.PI/180;
Run Code Online (Sandbox Code Playgroud)

在下面的代码片段中,我使用组绘制圆圈图层,并使用每个组中圆圈的索引计算角度.我正在设置使用的圆圈d3.range()数量和设置距中心距离的同一阵列中的图层数量.核实:

var width = height = 500;
var svg = d3.select("body")
  .append("svg")
  .attr("width", width)
  .attr("height", height);

var color = d3.scaleOrdinal(d3.schemeCategory10)
  .domain(d3.range(16));

var data1 = d3.range(16);
var dataRadius = [70, 110, 150, 190, 230];

svg.append("circle").attr("cx", width / 2)
  .attr("cy", height / 2)
  .attr("r", 20)
  .attr("fill", "yellow");

var groups = svg.selectAll(".groups")
  .data(dataRadius)
  .enter()
  .append("g");

var circles = groups.selectAll(".circles")
  .data(data1)
  .enter()
  .append("circle");

circles.attr("cx", function(d, i) {
    var radius = this.parentNode.__data__;
    return width / 2 + (radius * Math.sin(i * (360 / (data1.length) * Math.PI / 180)))
  })
  .attr("cy", function(d, i) {
    var radius = this.parentNode.__data__;
    return height / 2 + (radius * Math.cos(i * (360 / (data1.length) * Math.PI / 180)))
  })
  .attr("r", function() {
    return this.parentNode.__data__ == 230 ? 24 : 14
  })
  .attr("fill", function(d, i) {
    return i == 13 || i == 14 ? color(i - 2) : "#ccc"
  });
Run Code Online (Sandbox Code Playgroud)
<script src="https://d3js.org/d3.v4.min.js"></script>
Run Code Online (Sandbox Code Playgroud)