D3力布图绘制--节点间的多条关系连接线的方法(转)
在项目中遇到这样的场景,在使用D3.js绘制力布图的过程中,需要在2个节点间绘制多条连接线,找到一个不错的算法,在此分享下。
效果图:

HTML中要连接
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.min.js"></script>
<script src="https://d3js.org/d3.v3.min.js"></script>
</head>
<body>
</body>
// 下面是JS部分的代码,使用前请连接`https://d3js.org/d3.v3.min.js` 和 `https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.min.js`
var nodes = [{}, {}, {}, {}, {}, {}];
var links = [
// one link
{ source: 0, target: 1 },
// two links
{ source: 2, target: 1 },
{ source: 1, target: 2 },
//three links
{ source: 3, target: 2 },
{ source: 2, target: 3 },
{ source: 2, target: 3 },
// four links
{ source: 3, target: 4 },
{ source: 3, target: 4 },
{ source: 3, target: 4 },
{ source: 3, target: 4 },
// five links
{ source: 4, target: 5 },
{ source: 4, target: 5 },
{ source: 4, target: 5 },
{ source: 4, target: 5 },
{ source: 4, target: 5 }
];
// DATA FORMATTING
_.each(links, function(link) {
var same = _.where(links, {
'source': link.source,
'target': link.target
});
var sameAlt = _.where(links, {
'source': link.target,
'target': link.source
});
var sameAll = same.concat(sameAlt);
_.each(sameAll, function(s, i) {
s.sameIndex = (i + 1);
s.sameTotal = sameAll.length;
s.sameTotalHalf = (s.sameTotal / 2);
s.sameUneven = ((s.sameTotal % 2) !== 0);
s.sameMiddleLink = ((s.sameUneven === true) && (Math.ceil(s.sameTotalHalf) === s.sameIndex));
s.sameLowerHalf = (s.sameIndex <= s.sameTotalHalf);
s.sameArcDirection = s.sameLowerHalf ? 0 : 1;
s.sameIndexCorrected = s.sameLowerHalf ? s.sameIndex : (s.sameIndex - Math.ceil(s.sameTotalHalf));
});
let sameStandard = sameAll[0];
let sourceStandard = sameStandard.source;
let targetStandard = sameStandard.target;
_.each(sameAll,function(s,i){
if(s.source === targetStandard && s.target === sourceStandard && s.sameTotal > 1){
s.sameArcDirection = s.sameArcDirection === 0 ? 1 : 0
}
})
});
var maxSame = _.chain(links)
.sortBy(function(x) {
return x.sameTotal;
})
.last()
.value().sameTotal;
_.each(links, function(link) {
link.maxSameHalf = Math.floor(maxSame / 2);
});
var width = 960,
height = 500;
var force = d3.layout.force()
.nodes(nodes)
.links(links)
.size([width, height])
.linkDistance(100)
.charge(-200)
.on('tick', tick)
.start();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var path = svg.append("g").selectAll("path")
.data(force.links())
.enter().append("path")
.style("stroke", function(d) {
return d3.scale.category20().range()[d.sameIndex - 1];
});
var circle = svg.append("g").selectAll("circle")
.data(force.nodes())
.enter().append("circle")
.attr("r", 8)
.call(force.drag);
function tick(d) {
circle.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
path.attr("d", linkArc);
}
function linkArc(d) {
var dx = (d.target.x - d.source.x),
dy = (d.target.y - d.source.y),
dr = Math.sqrt(dx * dx + dy * dy),
unevenCorrection = (d.sameUneven ? 0 : 0.5),
arc = ((dr * d.maxSameHalf) / (d.sameIndexCorrected - unevenCorrection));
if (d.sameMiddleLink) {
arc = 0;
}
return "M" + d.source.x + "," + d.source.y + "A" + arc + "," + arc + " 0 0," + d.sameArcDirection + " " + d.target.x + "," + d.target.y;
}
本文转自: http://bl.ocks.org/thomasdobber/9b78824119136778052f64a967c070e0
D3力布图绘制--节点间的多条关系连接线的方法(转)的更多相关文章
- D3力布图绘制--节点自己连自己的实现
案例分析 先看下实现的效果图 实现方法 本篇是在之前写的博文 D3力布图绘制--节点间的多条关系连接线的方法 基础上加修改的,这里放上修改的代码,其他的一样 // DATA var nodes = [ ...
- D3力布图绘制--节点跑掉,单曲线弯曲问题记录
D3力布图绘制中遇到的交互问题,频繁操作数据后,会出现节点跑掉和单曲线弯曲的问题 问题描述 在id指向都正常的情况下出现以下2种状况: 单曲线弯曲 节点跑掉 经排查,是数据重复导致的问题 线条也是一样 ...
- d3力导图绘制节点间多条关系平行线的方法
之前用d3做了多条线之间的绘图是曲线表示的,现在产品要求改成平行线的样式,经过在网上的调研和自己的尝试,实践出一个可用的方法,分享给大家,先展示下结果: 事先声明,本方法是在以下参考网站上进行的结合和 ...
- D3力布图绘制--基本方法
本文主要结合案例记录使用D3.js绘制力布图的基本方法 样例显示 基本配置 this.force = d3.layout .force() .size([this.width, this.height ...
- D3力布图绘制--在曲线路径上添加文本标记
今天遇到一个在曲线路径上标识文本标记的问题,找到一个比较好的解决思路,在这里分享下: 使用d3建立的Force Layout,加上自定义的箭头形状,将多条连接线线改成弧线(https://www.cn ...
- d3力导向图聚焦
效果描述 双击节点,节点以及节点一度关联的节点保持高亮状态,其余节点变灰,半径变小,文字消失,并且向内收缩. 效果展示 正常状态 聚焦效果 关键代码 节点变化 激活节点保持高亮的样式,其余节点应用no ...
- Vue和d3.js(v4)力导向图force结合使用,v3版本升级v4【一】
前段时间因为参与项目涉密,所以一直没有更新博客,有些博友给我私信或者留言要部分博文的源码,因为我的电脑更换,demo的源码没有备份 所以无法提供.大家可针对具体问题问我,有空我定会回复的.另外转发文章 ...
- 使用百度Echarts制作力导向图
最近项目需求制作一个力导向图来展示企业的画像等关系信息,故想到了百度Echarts的关系图,在这使用Echarts3.0版本来实现.先上效果图,再看代吗 哎,本来想整个工程扔出来,发现好像没地方上传附 ...
- D3.js力导向图中新增节点及新增关系连线示例
大家在使用D3.js中的力导向图时,基本都会遇到动态增加节点及连线的需求,这里记录一下我的实现方式. 话不多说,先放代码: <!DOCTYPE html> <html lang=&q ...
随机推荐
- javascript在数组的循环中删除元素
在开发JavaScript应用的过程中,经常会遇到在循环中移除指定元素的需求. 按照常规的思路,就是对数组进行一个for循环,然后在循环里面进行if判断,在判断中删除掉指定元素即可. 但是实际情况往往 ...
- 基于bert的命名实体识别,pytorch实现,支持中文/英文【源学计划】
声明:为了帮助初学者快速入门和上手,开始源学计划,即通过源代码进行学习.该计划收取少量费用,提供有质量保证的源码,以及详细的使用说明. 第一个项目是基于bert的命名实体识别(name entity ...
- oracle中decode函数用法及应用
用法 1.decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值) 相当于if else 那种方式. 2.decode(字段或字段的运算,值1,值2,值3) 当字段或字段的运 ...
- Netty — 心跳检测和断线重连
一.前言 由于在通信层的网络连接的不可靠性,比如:网络闪断,网络抖动等,经常会出现连接断开.这样对于使用长连接的应用而言,当突然高流量冲击势必会造成进行网络连接,从而产生网络堵塞,应用响应速度下降,延 ...
- MongoDB for OPS 03:分片 shard 集群
写在前面的话 上一节的复制集也就是主从能够解决我们高可用和数据安全性问题,但是无法解决我们的性能瓶颈问题.所以针对性能瓶颈,我们需要采用分布式架构,也就是分片集群,sharding cluster! ...
- Zabbix 数据清理
目录 Zabbix 数据清理的一系列操作 一.问题 二.解决办法 Zabbix 数据清理的一系列操作 基本信息: Zabbix 版本 4.0.9 MySQL 版本 5.5 一.问题 我们将 Zabbi ...
- java.lang.ClassNotFoundException: XXX (no security manager: RMI class loader disabled)
在搞RMI远程发布,consumer去获取rmi远程服务的代理对象的时候出现了如下的错误 问题发现: 由于我发布的对象的包路径和获取的对象的包路径不一致,导致了这样的问题 解决方案: 包路径改为一致就 ...
- 简单解决 VMWare “无法打开内核设备:\\Global\\vmx86”错误
在“服务”后右击选择使用管理员打开.然后在一大串服务中找到vm开头的服务项,全部都启动.重新启动vm就ok了(vm需要以管理员身份打开).
- java基础(12):构造方法、this、super
1. 构造方法 我们对封装已经有了基本的了解,接下来我们来看一个新的问题,依然以Person为例,由于Person中的属性都被private了,外界无法直接访问属性,必须对外提供相应的set和get方 ...
- 解决iOS地图持续定位耗电问题
地图位置刷新的代理didUpdateLocations会持续调用,手机非常耗电 但是在实际开发中,有一些APP确实需要用到持续定位的功能,比如:运动类, 导航类, 天气类等等 如何进行持续定位呢?保证 ...