D3 饼图未返回正确数据

D3 Pie Chart Not Returning Correct Data

我一直在制作饼图(圆环图),该图汇集了 2021 年 15 个最大的 GDP。除了一个方面,它基本上在所有方面都运行良好。将鼠标悬停在上方时,我似乎无法显示正确的国家/地区。每一张图表 returns 墨西哥。我知道可能有一种比我采用的 'if/else if' 方法更不业余但更有效的方法。任何帮助将不胜感激。

您可以查看here以供参考。它不是英文的,但代码是可以理解的。

注意:最后的 'else' 声明 returns 墨西哥,这就是为什么他们都 return 墨西哥。

有问题的代码是:

var country = [];
  
  var countryCorrespond = d3.selectAll(piePiece).datum.value;
    
    if (countryCorrespond === 22675271) {
      country.push('米国')
    } else if (countryCorrespond === 16642318) {
      country.push('中国')
    } else if (countryCorrespond === 5378136) {
      country.push('日本')
    } else if (countryCorrespond === 4319286) {
      country.push('ドイツ')
    } else if (countryCorrespond === 3124650) {
      country.push('イギリス')
    } else if (countryCorrespond === 3049704) {
      country.push('インド')
    } else if (countryCorrespond === 2938271) {
      country.push('フランス')
    } else if (countryCorrespond === 2106287) {
      country.push('イタリア')
    } else if (countryCorrespond === 1883487) {
      country.push('カナダ')
    } else if (countryCorrespond === 1806707) {
      country.push('韓国')
    } else if (countryCorrespond === 1710734) {
      country.push('ロシア')
    } else if (countryCorrespond === 1491772) {
      country.push('ブラジル')
    } else if (countryCorrespond === 1461552) {
      country.push('スペイン')
    } else {
      country.push('メキシコ')
    }

整个代码为:

const DATASET = [
  {'COUNTRY': '米国', 'GDP': 22675271},
  {'COUNTRY': '中国', 'GDP': 16642318},
  {'COUNTRY': '日本', 'GDP': 5378136},
  {'COUNTRY': 'ドイツ', 'GDP': 4319286},
  {'COUNTRY': 'イギリス', 'GDP': 3124650},
  {'COUNTRY': 'インド', 'GDP': 3049704},
  {'COUNTRY': 'フランス', 'GDP': 2938271},
  {'COUNTRY': 'イタリア', 'GDP': 2106287},
  {'COUNTRY': 'カナダ', 'GDP': 1883487},
  {'COUNTRY': '韓国', 'GDP': 1806707},
  {'COUNTRY': 'ロシア', 'GDP': 1710734},
  {'COUNTRY': 'オーストラリア', 'GDP': 1617543},
  {'COUNTRY': 'ブラジル', 'GDP': 1491772},
  {'COUNTRY': 'スペイン', 'GDP': 1461552},
  {'COUNTRY': 'メキシコ', 'GDP': 1192480}
];

var root = d3
    .hierarchy(DATASET)
    .eachBefore(function(val) {
         val.data.value = (val.parent ? val.parent.data.value + '.' : '')
    });

var colorScheme = d3
.scaleOrdinal()
.domain([DATASET.COUNTRY])
.range(['#33a02c', '#1f78b4', '#fdbf6f', '#A03363', '#ffff99', '#e31a1c', '#b2df8a', '#ff7f00', '#cab2d6', '#EDBC34', '#fb9a99', '#b15928', '#8DF7C9', '#a6cee3', '#6a3d9a']);

var height = 1000,
    width = 1000,
    margin = 50;

var radius = Math.min(width, height) / 2 - margin;

var svg = d3
  .select('.donut-chart')
  .append('svg')
  .attr('height', height)
  .attr('width', width)
  .append('g')
  .attr('transform', `translate(${width/2},${height/2})`);

var tooltip = d3
  .select('body')
  .append('div')
  .attr('class', 'tooltip');

var pie = d3.pie(root)
  .value(d => d[1]);

var GDPval = pie(Object.entries(DATASET.map(d => d.GDP)));

  svg
    .selectAll('path')
    .data(GDPval)
    .join('path')
    .attr('d', d3.arc()
         .innerRadius(160)
         .outerRadius(radius))
    .attr('fill', d => colorScheme(d))
    .attr('stroke', '#122B16')
    .attr('stroke-width', 2.5 + 'px')
    .style('opacity', 0.65);

var piePiece = 
    svg
      .selectAll('path')
      .selectAll('piece')
      .data(pie)
      .enter()
      .append('g')
      .attr('class', 'piece')

// console.log(piePiece);

var centralText = svg
  .append('text')
  .attr('dy', 0.35 + 'em')
  .attr('class', 'central-text')
  .attr('y', -10)
  .style('text-anchor', 'middle')
  .style('font-size', 50 + 'px')
  .text('GDP')

d3.selectAll('path')
  .on('mouseover', function(event, d) {
    d3.select(this)
      .style('opacity', 1)

  var country = [];
  
  var countryCorrespond = d3.selectAll(piePiece).datum.value;
    
    if (countryCorrespond === 22675271) {
      country.push('米国')
    } else if (countryCorrespond === 16642318) {
      country.push('中国')
    } else if (countryCorrespond === 5378136) {
      country.push('日本')
    } else if (countryCorrespond === 4319286) {
      country.push('ドイツ')
    } else if (countryCorrespond === 3124650) {
      country.push('イギリス')
    } else if (countryCorrespond === 3049704) {
      country.push('インド')
    } else if (countryCorrespond === 2938271) {
      country.push('フランス')
    } else if (countryCorrespond === 2106287) {
      country.push('イタリア')
    } else if (countryCorrespond === 1883487) {
      country.push('カナダ')
    } else if (countryCorrespond === 1806707) {
      country.push('韓国')
    } else if (countryCorrespond === 1710734) {
      country.push('ロシア')
    } else if (countryCorrespond === 1491772) {
      country.push('ブラジル')
    } else if (countryCorrespond === 1461552) {
      country.push('スペイン')
    } else {
      country.push('メキシコ')
    }
  
  centralText
      .text(country)
      .attr("y", -10);
    
    console.log(country)
  // }
   
  tooltip
    .text('$' + 
          d3.select(this).datum().value)
    .html(tooltip.text().replace(/\B(?=(\d{3})+(?!\d))/g, ","));
          
  tooltip
    .style('visibility', 'visible')
    .style('left', event.pageX + 28 + 'px')
    .style('top', event.pageY - 28 + 'px')
  })
.on("mousemove", function(d) {
      tooltip
    .style("left", event.pageX + 28 + "px")
    .style("top", event.pageY - 28 + "px");
    })
 .on('mouseout', function() {
    tooltip
      .style('visibility', 'hidden')
      d3.select(this)
      .style('opacity', 0.65);
  
    centralText.text('GDP');
});

  d3
    .select('.source-info')
    .append('text')
.text("https://eleminist.com/article/1679 による")

感谢您的帮助!

不是只用 GDP 值生成饼图值,而是使用整个数据集对象。这样 d3.pie() 生成的数据将在 .data 中包含您的原始数据,并且每个项目都绑定到相应的 path,因此您可以在 mouseover 上访问它,使其成为易于使用该数据在工具提示和中央文本中显示它。

感兴趣的代码如下。使用所有代码 here.

var pies = d3.pie().value(d => d.GDP)(DATASET)

svg
  .selectAll('path')
  .data(pies)
  .join('path')
  .attr(
    'd',
    d3.arc().innerRadius(160).outerRadius(radius),
  )
 .on('mouseover', (event, d) => {
    tooltip
      .text('$' + d.data.GDP)
      .html(tooltip.text().replace(/\B(?=(\d{3})+(?!\d))/g, ','))

    tooltip
      .style('visibility', 'visible')
      .style('left', event.pageX + 28 + 'px')
      .style('top', event.pageY - 28 + 'px')

    centralText.text(d.data.COUNTRY)
  })