我想知道如何在d3.js甜甜圈图中创建etc组

问题描述

我想知道如何在d3.js甜甜圈图中创建etc组。

data = {{result|safe}}

      var text = "";

      var width = 1450;
      var height = 500;
      var thickness = 40;
      var duration = 750;

      var radius = Math.min(width,height) / 2;
      var color = d3.scaleOrdinal(d3.schemeCategory20);

      var svg = d3.select("#donutchart")
      .append('svg')
      .attr('class','pie')
      .attr('width',width)
      .attr('height',height);

      var g = svg.append('g')
      .attr('transform','translate(' + (width/2) + ',' + (height/2) + ')');

      var arc = d3.arc()
      .innerRadius(radius - thickness)
      .outerRadius(radius);

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

      var path = g.selectAll('path')
      .data(pie(data))
      .enter()
      .append("g")
      .on("mouSEOver",function(d) {
            let g = d3.select(this)
              .style("cursor","pointer")
              .style("fill","black")
              .append("g")
              .attr("class","text-group");
       
            g.append("text")
              .attr("class","name-text")
              .text(`${d.data.word}`)
              .attr('text-anchor','middle')
              .attr('dy','-1.2em');
        
            g.append("text")
              .attr("class","value-text")
              .text(`${d.data.count}`)
              .attr('text-anchor','.6em');
          })
        .on("mouSEOut",function(d) {
            d3.select(this)
              .style("cursor","none")  
              .style("fill",color(this._current))
              .select(".text-group").remove();
          })
        .append('path')
        .attr('d',arc)
        .attr('fill',(d,i) => color(i))
        .on("mouSEOver",function(d) {
            d3.select(this)     
              .style("cursor","black");
          })
        .on("mouSEOut",color(this._current));
          })
        .each(function(d,i) { this._current = i; });


      g.append('text')
        .attr('text-anchor','middle')
        .attr('dy','.35em')
        .text(text);

当数据的字数少于100时,是否可以通过将其划分为etc组来显示图表?它必须由服务器处理吗?

或者是否有办法仅显示前8个数据并将其放入etc组?

enter image description here

解决方法

让我们假装数据是具有“名称”和“值”的对象数组:

[
  {
    "name": "a","value": 198
  },{
    "name": "b","value": 100
  },{
    "name": "c","value": 50
  },// ...
]

我们还将假设它已排序(您可以这样做):

var data = data.sort((a,b) => d3.descending(a.value,b.value))

让我们采用8个最大的值,然后将其余所有值都放在“ etc”标签中:

let newData = data.slice(0,8)
const etcSliceAmount = data.slice(8,data.length-1)
  .map(d => d.value)
  .reduce((acc,x) => acc + x)
newData.push({
  name: "etc",value: etcSliceAmount,})

etcSliceAmount中,我们首先获得除前八个之外的所有项目。我们使用reduce将它们加起来。最后,我们可以在数据末尾附加这个新分区。由于没有排序,因此在代码中使用sort(null)禁用了d3,它将按顺序排列切片。

// random array of 100 values from [0-200],sorted
const data = d3.range(100).map(() => ({
  name: "a",value: Math.floor(d3.randomUniform(0,200)())
})).sort((a,b.value))

let newData = data.slice(0,data.length-1).map(d => d.value).reduce((acc,})

console.log(newData)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>