首先看一下节点的数据内容:
nodes: [
{id: 1, name: '刘备', type: '皇上'},
{id: 2, name: '关羽', type: '将军'},
{id: 3, name: '张飞', type: '将军'},
{id: 4, name: '诸葛亮', type: '丞相'},
{id: 5, name: '小兵1', type: '士兵'},
{id: 6, name: '小兵2', type: '士兵'},
],
links: [
{source: 1, target: 2, relate: '将军'},
{source: 1, target: 3, relate: '将军'},
{source: 1, target: 4, relate: '丞相'},
{source: 2, target: 5, relate: '下属'},
{source: 2, target: 6, relate: '下属'},
{source: 3, target: 5, relate: '下属'},
],
节点颜色分类实现
根据节点的type属性进行分类,d3.scaleOrdinal(d3.schemeCategory10): 这一部分使用 D3 中的 scaleOrdinal 函数创建了一个序数比例尺,并使用 d3.schemeCategory10 作为颜色方案,通常我们会使用 scale.domain() 来指定比例尺的输入范围
this.colorScale = d3.scaleOrdinal(d3.schemeCategory10)
.domain(this.nodes.map(d => d.type));
node.append('circle')
.attr('r', 18)
.attr('fill', 'steelblue')
.style('fill', d => this.colorScale(d.type))
实现效果如下
节点点击事件处理
点击节点的时候显示节点信息,鼠标移开后不再显示;读者也可实现自定义处理逻辑
//创建节点
const node = g.selectAll('.node')
.data(data.nodes)
.enter()
.append('g')
.attr('class', 'node')
.style('fill', 'black')
.on('click', // 鼠标点击事件处理函数
function handleMouseOver(event,d) {
d3.select(this).selectAll('.tooltip-text').remove(); // 移除旧的 tooltip 文本
const tooltip = d3.select(this).append('text')
.attr('class', 'tooltip-text')
.attr('x', 0)
.attr('y', -20) // 将 tooltip 放置在节点上方
.text(`${d.name} (${d.type})`)
.style('font-size', '12px')
.style('fill', '#712')
.style('text-anchor', 'middle');
})
.on('mouseout', // 鼠标离开事件处理函数
function handleMouseOut(d) {
d3.select(this).selectAll('.tooltip-text').remove(); // 清除 tooltip 文本
});