D3.js将饼图转换为频谱显示的方法

时间:2019-06-12 07:21:23

标签: javascript d3.js

我正在尝试为频谱显示创建d3模板,主要用于定性数据。想象这样的事情:

enter image description here

我已经达到半圈了

var margins = {top:250, bottom:300, left:250, right:100};

var height = 600;
var width = 900;

var totalWidth = width+margins.left+margins.right;
var totalHeight = height+margins.top+margins.bottom;

var svg = d3.select('body')
    .append('svg')
    .attr('width', totalWidth)
    .attr('height', totalHeight);

var graphGroup = svg.append('g')
    .attr('transform', "translate("+margins.left+","+margins.top+")");

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

var outerRadius = (400 / 2);
var innerRadius = 100;

var arc = d3.arc()
  .innerRadius(innerRadius)
  .outerRadius(outerRadius)
  .startAngle(0)
  .endAngle(Math.PI);

var arcLine = d3.arc()
  .innerRadius(innerRadius)
  .outerRadius(outerRadius);

/*
var pieG = graphGroup.selectAll(".arc")
    .data(pie(data))
  .enter().append("g")
    .attr("class", "arc");
*/

var path = graphGroup.append('path')
  .attr("d", arc)
  .attr("transform", 'rotate(-90)')
  .style('stroke','#000')
  .style('stroke-width',"2px")
  .style('fill', "none");
  
/*
var semicircle = pieG.append("path")
   .attr("fill","white")
   .attr("d", d3.arc()
     .endAngle(Math.PI)
     .startAngle(percentage * Math.PI)
     .outerRadius(radius - 10)
     .innerRadius(radius - 70));
*/
   <script src="https://d3js.org/d3.v5.min.js"></script>

然后它突然降临在我身上;如果要重新使用此模板,则必须从头开始计算“段”。假设我有6个类别(如上图),那么我必须每30度进行一次迭代。而且我不确定该如何运作-如下尝试:

var segmentLines = graphGroup.append('line')
    .attr('x1',???)
    .attr('x2',???)
    .attr('y1',???)
    .attr('y2',???);

即使我算出正确的xs和ys,也只能是1行-而且我总共需要5条频谱显示6个类别。天堂禁止我有20个类别-我找不到一种方法来扩展它。

问题

d3是否有任何专用方法可用于频谱显示?如果不是,我的饼图方法是否是下一个最好的选择?会是scalabe吗?为了说明起见,假设我们有一个像这样的变量:

var categories = 6;

根据此数字,饼图/甜甜圈图将被切成这么多块。 (因此是模板式图形)。

1 个答案:

答案 0 :(得分:2)

您需要的只是一个饼图生成器...

var pie = d3.pie()
    .startAngle(-Math.PI/2)
    .endAngle(Math.PI/2);

...,根据您的categories向其传递数据数组:

var data = d3.range(categories).map(()=>1);

这是一个演示:

var height = 300;
var width = 500;

var categories = 6;
var data = d3.range(categories).map(()=>1);

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

var graphGroup = svg.append('g')
  .attr('transform', "translate(250,250)");

var pie = d3.pie()
	.startAngle(-Math.PI/2)
  .endAngle(Math.PI/2);

var outerRadius = (150);
var innerRadius = 100;

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

var path = graphGroup.selectAll(null)
  .data(pie(data))
  .enter()
.append('path')
  .attr("d", arc)
  .style('stroke', '#000')
  .style('stroke-width', "2px")
  .style('fill', "none");
  
  var path2 = graphGroup.selectAll(null)
  .data(pie(data))
  .enter()
.append('path')
  .attr("d", function(d){
    return arc.innerRadius(150)
      .outerRadius(200)(d)
  })
  .style('stroke', '#000')
  .style('stroke-width', "2px")
  .style('fill', "none");
<script src="https://d3js.org/d3.v5.min.js"></script>