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

本文介绍了如何使用d3.js v5版本创建力导向图,并在点击节点时显示环形菜单。菜单包含删除、收起和展开等操作,通过计算每个菜单项的占比并动态调整其在圆环上的位置。点击菜单项可以触发相应的功能,如删除节点或切换节点状态。
摘要由CSDN通过智能技术生成

我是这样实现的

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)

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值