在项目中遇到这样的场景,在使用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力布图绘制--节点间的多条关系连接线的方法(转)的更多相关文章

  1. D3力布图绘制--节点自己连自己的实现

    案例分析 先看下实现的效果图 实现方法 本篇是在之前写的博文 D3力布图绘制--节点间的多条关系连接线的方法 基础上加修改的,这里放上修改的代码,其他的一样 // DATA var nodes = [ ...

  2. D3力布图绘制--节点跑掉,单曲线弯曲问题记录

    D3力布图绘制中遇到的交互问题,频繁操作数据后,会出现节点跑掉和单曲线弯曲的问题 问题描述 在id指向都正常的情况下出现以下2种状况: 单曲线弯曲 节点跑掉 经排查,是数据重复导致的问题 线条也是一样 ...

  3. d3力导图绘制节点间多条关系平行线的方法

    之前用d3做了多条线之间的绘图是曲线表示的,现在产品要求改成平行线的样式,经过在网上的调研和自己的尝试,实践出一个可用的方法,分享给大家,先展示下结果: 事先声明,本方法是在以下参考网站上进行的结合和 ...

  4. D3力布图绘制--基本方法

    本文主要结合案例记录使用D3.js绘制力布图的基本方法 样例显示 基本配置 this.force = d3.layout .force() .size([this.width, this.height ...

  5. D3力布图绘制--在曲线路径上添加文本标记

    今天遇到一个在曲线路径上标识文本标记的问题,找到一个比较好的解决思路,在这里分享下: 使用d3建立的Force Layout,加上自定义的箭头形状,将多条连接线线改成弧线(https://www.cn ...

  6. d3力导向图聚焦

    效果描述 双击节点,节点以及节点一度关联的节点保持高亮状态,其余节点变灰,半径变小,文字消失,并且向内收缩. 效果展示 正常状态 聚焦效果 关键代码 节点变化 激活节点保持高亮的样式,其余节点应用no ...

  7. Vue和d3.js(v4)力导向图force结合使用,v3版本升级v4【一】

    前段时间因为参与项目涉密,所以一直没有更新博客,有些博友给我私信或者留言要部分博文的源码,因为我的电脑更换,demo的源码没有备份 所以无法提供.大家可针对具体问题问我,有空我定会回复的.另外转发文章 ...

  8. 使用百度Echarts制作力导向图

    最近项目需求制作一个力导向图来展示企业的画像等关系信息,故想到了百度Echarts的关系图,在这使用Echarts3.0版本来实现.先上效果图,再看代吗 哎,本来想整个工程扔出来,发现好像没地方上传附 ...

  9. D3.js力导向图中新增节点及新增关系连线示例

    大家在使用D3.js中的力导向图时,基本都会遇到动态增加节点及连线的需求,这里记录一下我的实现方式. 话不多说,先放代码: <!DOCTYPE html> <html lang=&q ...

随机推荐

  1. IT兄弟连 HTML5教程 了解HTML5的主流应用3

    5  基于HTML5的移动APP开发 不同的操作系统中,需要安装用不同技术开发的APP,移动端的操作系统有很多种,但最主要有两大分支,一种在苹果iOS操作系统中使用Objective-C语言开发APP ...

  2. 【Java线程与内存分析工具】VisualVM与MAT简明教程

    目录 前言 VisualVM 安装与配置 本地使用 远程监控 MAT 使用场景 安装与配置 获得堆转储文件 分析堆转储文件 窥探对象内存值 堆转储文件对比分析 总结 前言 本文将简要介绍Java线程与 ...

  3. jsp页面科学计数法显示问题的解决办法

    在JSP页面中返回的double类型的数值,如果数值过大,就会被显示成科学计数法. 这个问题通常出现在表单填写的input中,因此是必须要解决的问题. JSTL提供了标准的数值格式化标签,使用上非常简 ...

  4. MySQL GROUP BY 的问题

    拿 employee 示例数据库为例,当进行如下操作时会报错. mysql> SELECT * FROM employees GROUP BY gender; ERROR 1055 (42000 ...

  5. VS2017安装使用Easyx时出现的问题及解决方法

    EasyX 是针对 Visual C++ 的绘图库,在初学 C 语言实现图形和游戏编程.图形学.分形学等需要绘图实践的领域有一定应用. EasyX 库在 Visual C++ 中模拟了 Turbo C ...

  6. PHP面试题2019年百度工程师面试题及答案解析

    一.单选题(共10题,每题5分) 1.以下代码输出的结果是? ​​​ A.[0,1,2,3] B.[1,3,5,7,5] C.[1,2,3,4,5] D.[0,1,2,3,5] 参考答案:D 答案解析 ...

  7. 异步和多线程Thread

    刚接触线程的时候,感觉这个东西好神奇.虽然不是很明白,就感觉它很牛逼. 参考了一些大佬写的文章: https://www.cnblogs.com/yilezhu/p/10555849.html这个大佬 ...

  8. 高强度学习训练第十三天总结:使用Netty实现一个http服务器

    Netty入门 Netty的重要性不言而喻.那么今天就来学习一下Netty. 整个项目基于Gradle搭建. Build如下所示: plugins { id 'java' } group 'cn.ba ...

  9. webUploader上传大视频文件相关web.config配置

    在webuploader上传大文件时必须配置一下,不然请求后台处理程序时,会请求超时.出现404! <system.web> <httpRuntime maxRequestLengt ...

  10. 【JavaWeb】EL表达式

    EL表达式 EL表达式语言,用于简化JSP的输出: EL表达式的基本语法:${表达式}: 示例:<h1>学生姓名:${student.name}</h1> 作用域对象 忽略书写 ...