d3 v5版本绘制力导向图,点击节点绘制环形菜单,如下图所示

TIM图片20200606011201.jpg### 问题描述

问题出现的环境背景及自己尝试过哪些方法

相关代码

粘贴代码文本(请勿用截图)

你期待的结果是什么?实际看到的错误信息又是什么?

阅读 3k
2 个回答
新手上路,请多包涵

我是这样实现的
function toggleCircle(current, d) {

var currentD = d
if (d.clickFlag) {
  removeSingle()
  document.getElementById('xxx').innerText = ''
}
d.clickFlag = true
document.getElementById('xxx').innerText = d.name
var data = [{
  population: 30,
  value: 'X',
  type: 'delete'
}, {
  population: 30,
  value: '收起',
  type: 'showOn'
}, {
  population: 30,
  value: '展开',
  type: 'showOff'
}]
var sum = d3.sum(data.map(function (d) {
  return d.population
}))
for (i in data) {
  data[i].Percentage = (data[i].population / sum * 100).toFixed(0) + "%";
}
var width = 300,
  height = 300,
  margin = { "left": 30, "top": 30, "right": 30, "bottom": 30 },
  svg_width = width + margin.left + margin.right,
  svg_height = height + margin.top + margin.bottom,
  font_size = 15;
var g = current
  .append("g")
  .attr('class', 'singleCircle')
  .attr("width", width)
  .attr("height", height)
var Pie = g.append("g")
// .attr("transform","translate("+width/4+","+height/4+")")

var arc_generator = d3.arc()
  .innerRadius(width / 6.5)
  .outerRadius(width / 4)
var angle_data = d3.pie()
  .value(function (d) {
    return d.population;
  })
var pieData = angle_data(data)
var pieAngle = pieData.map(function (p) {
  return (p.startAngle + p.endAngle) / 2 / Math.PI * 180;
});

// var color=d3.schemeCategory10;

//生成内部圆环
Pie.selectAll("path")
  .data(angle_data(data))
  .enter()
  .append("path")
  .attr("d", arc_generator)
  .style("fill", function (d, i) {
    return 'grey';
  })
  .style('stroke', 'black')
  .attr("class", "path")
  .attr('type', function (d) {
    return d.data.type
  })
  .on('click', function (d) {
    if (d.data.type === 'delete') {
      deleteNode(currentD)
    } else if (d.data.type === 'showOn') {
      deleteNextNodes(currentD)
    } else {
      showMyList()
    }
    d3.event.stopPropagation()
  })
var arc_label = d3.arc()
  .innerRadius(width / 4)
  .outerRadius(width / 2)

Pie.selectAll(".arc_label")
  .data(angle_data(data))
  .enter()
  .append("path")
  .attr("d", arc_label)
  .attr("class", "arc_label")
  .style("fill", "none")
const labelFontSize = 12;
const labelValRadius = (170 * 0.35 - labelFontSize * 0.35); // 计算正确半径 文字位置
const labelValRadius1 = (170 * 0.35 + labelFontSize * 0.35);


const labelsVals = current.select('.singleCircle').append('g')
  .classed('labelsvals', true);

// 定义两条路径以使标签的方向正确
labelsVals.append('def')
  .append('path')
  .attr('id', 'label-path-1')
  .attr('d', `m0 ${-labelValRadius} a${labelValRadius} ${labelValRadius} 0 1,1 -0.01 0`);
labelsVals.append('def')
  .append('path')
  .attr('id', 'label-path-2')
  .attr('d', `m0 ${-labelValRadius1} a${labelValRadius1} ${labelValRadius1} 0 1,0 0.01 0`);

labelsVals.selectAll('text')
  .data(data)
  .enter()
  .append('text')
  .style('font-size', labelFontSize)
  .style('fill', 'black')
  .style('font-weight', "bold")
  .style('text-anchor', 'middle')
  .append('textPath')
  .attr('href', function (d, i) {
    const p = pieData[i];
    const angle = pieAngle[i];
    if (angle > 90 && angle <= 270) { // 根据角度选择路径
      return '#label-path-2';
    } else {
      return '#label-path-1';
    }
  })
  .attr('startOffset', function (d, i) {
    const p = pieData[i];
    const angle = pieAngle[i];
    let percent = (p.startAngle + p.endAngle) / 2 / 2 / Math.PI * 100;
    if (angle > 90 && angle <= 270) { // 分别计算每条路径的正确百分比
      return 100 - percent + "%";
    }
    return percent + "%";
  })
  .text(function (d) {
    return d.value;
  })
  .on('click', function (d) {
    if (d.type === 'delete') {
      deleteNode(currentD)
    } else if (d.type === 'showOn') {
      deleteNextNodes(currentD)
    } else {
      showMyList()
    }
    d3.event.stopPropagation()
  }, true)

}

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题