d3.js实现力导向图--添加箭头标记,边的点击事件

首先看一下节点的数据内容

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: '下属'},
      ],

添加箭头标记

先定义箭头标记,再在创建边的时候添加箭头标记(.attr(‘marker-end’, ‘url(#arrow)’))

// 定义箭头标记
      svg.append('defs').append('marker')
        .attr('id', 'arrow')
        .attr('viewBox', '0 -5 10 10')
        .attr('refX', 25)
        .attr('refY', 0)
        .attr('markerWidth', 6)
        .attr('markerHeight', 6)
        .attr('orient', 'auto')
        .append('path')
        .attr('d', 'M0,-5L10,0L0,5')
        .attr('fill', 'black');
// 创建边
      const link = g.selectAll('line')
        .data(data.links)
        .enter()
        .append('line') 
        .attr('stroke', '#999')
        .attr('stroke-width', 2)
        .attr('marker-end', 'url(#arrow)') // 添加箭头标记

实现的效果

在这里插入图片描述

边的点击事件,点击边的时候显示相关的节点和边,鼠标移开后恢复原来的效果

const link = g.selectAll('line')
        .data(data.links)
        .enter()
        .append('line') // 更改为 path 以便于后续添加箭头
        .attr('stroke', '#999')
        .attr('stroke-width', 2)
        .attr('marker-end', 'url(#arrow)') // 添加箭头标记
        .style('opacity', 1) // 设置初始不透明度
        .on('click', function (event, d) {
          // 当点击一条边时,高亮显示与之关联的节点和边
          const relatedNodes = data.nodes.filter(node => node.id === d.source.id || node.id === d.target.id);
          const relatedLinks = data.links.filter(link => link.source.id === d.source.id || link.source.id === d.target.id || link.target.id === d.source.id || link.target.id === d.target.id);

          // 高亮显示相关节点
          node.filter(function (node) {
            return relatedNodes.some(relatedNode => relatedNode.id === node.id);
          }).style('fill', 'orange');

          // 高亮显示相关边
          link.filter(function (link) {
            return relatedLinks.some(relatedLink => relatedLink.source.id === link.source.id && relatedLink.target.id === link.target.id);
          }).style('stroke', 'orange')
            .style('stroke-width', 4)
            .style('opacity', 1);

          // 淡化其他节点和边
          node.filter(function (node) {
            return !relatedNodes.some(relatedNode => relatedNode.id === node.id);
          }).style('fill', 'lightgray');

          link.filter(function (link) {
            return !relatedLinks.some(relatedLink => relatedLink.source.id === link.source.id && relatedLink.target.id === link.target.id);
          }).style('stroke', 'lightgray')
            .style('stroke-width', 1)
            .style('opacity', 0.5);
        })
        .on('mouseout', function (event, d) {
          // 当鼠标移出边时,恢复所有节点和边的原始状态
          link.style('stroke', '#999') // 恢复边的颜色
            .style('stroke-width', 2) // 恢复边的宽度
            .style('opacity', 1); // 恢复边的不透明度
        });

实现的效果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

emo哥老白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值