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

事先声明,本方法是在以下参考网站上进行的结合和更改:

d3力导图节点间多条线的绘图方法

d3.js Force Layout: drawing multiple straight, parallel links between two nodes

force layout with multiple links between nodes

如果图示的样式是你想要的,那么直接粘贴代码看吧!代码可直接运行。


<!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>
<style>
body {
margin: 0;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
} path {
fill: none;
stroke-width: 3;
} circle {
stroke: white;
stroke-width: 2;
}
</style>
</head> <body>
<script> // DATA
var nodes = [{}, {}];
var links = [ // links 可更改,自己改数量显示不同的条数
{ source: 0, target: 1 },
{ source: 0, target: 1 },
{ source: 0, target: 1 },
{ source: 0, target: 1 },
{ source: 0, target: 1 } ]; _.each(links, function (link) {
var same = _.filter(links, {
source: link.source,
target: link.target
});
var sameAlt = _.filter(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);
});
}); var maxSame = _.chain(links)
.sortBy(function (x) {
return x.sameTotal;
})
.last()
.value().sameTotal; _.each(links, function (link) {
link.maxSameHalf = Math.floor(maxSame / 3);
}); // FORCE var width = 960,
height = 500; var force = d3.layout.force()
.nodes(nodes)
.links(links)
.size([width, height])
.linkDistance(400)
.charge(-2000)
.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", 30)
.call(force.drag); // TICK function tick(d) {
circle.attr("transform", function (d) {
return "translate(" + d.x + "," + d.y + ")";
});
path.attr("d", linkArc);
} function calcTranslationExact(targetDistance, source, target) { var x1_x0 = target.x - source.x,
y1_y0 = target.y - source.y,
x2_x0, y2_y0;
if (y1_y0 === 0) {
x2_x0 = 0;
y2_y0 = targetDistance;
} else {
let angle = Math.atan((x1_x0) / (y1_y0));
x2_x0 = -targetDistance * Math.cos(angle);
y2_y0 = targetDistance * Math.sin(angle);
}
return {
dx: x2_x0,
dy: y2_y0
};
}
// some more info: http://stackoverflow.com/questions/11368339/drawing-multiple-edges-between-two-nodes-with-d3
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),
arc = 0; // 上下不一样的间隔
let dis1 = calcTranslationExact(d.sameIndex * 12, d.source, d.target)
let dis2 = calcTranslationExact(-(d.sameIndex - Math.ceil(d.sameTotalHalf)) * 12, d.source, d.target) let dx1 = dis1.dx;
let dy1 = dis1.dy let dx2 = dis2.dx;
let dy2 = dis2.dy // 表示奇数的时候,中间的那条
if (Math.ceil(d.sameTotalHalf) === d.sameIndex && d.sameUneven === true) {
dx1 = 0;
dx2 = 0;
dy1 = 0;
dy2 = 0;
} if (d.sameArcDirection === 0) {
return "M" + (d.source.x + dx1) + "," + (d.source.y + dy1) + "A" + arc + "," + arc + " 0 0," + 0 + " " + (d.target.x + dx1) + "," + (d.target.y + dy1);
} else {
return "M" + (d.source.x + dx2) + "," + (d.source.y + dy2) + "A" + arc + "," + arc + " 0 0," + 0 + " " + (d.target.x + dx2) + "," + (d.target.y + dy2);
}
}
</script>
</body>

d3力导图绘制节点间多条关系平行线的方法的更多相关文章

  1. D3力布图绘制--节点间的多条关系连接线的方法(转)

    在项目中遇到这样的场景,在使用D3.js绘制力布图的过程中,需要在2个节点间绘制多条连接线,找到一个不错的算法,在此分享下. 效果图: HTML中要连接 <!DOCTYPE html> & ...

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

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

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

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

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

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

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

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

  6. JavaScript---网络编程(7)-Dom模型(节点间的层次关系,节点的增、删、改)

    利用节点间的层次关系获取节点: 上一节讲了3中获取的方式: * ※※一.绝对获取,获取元素的3种方式:-Element * 1.getElementById(): 通过标签中的id属性值获来取该标签对 ...

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

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

  8. d3力导向图聚焦

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

  9. Javascript 思维导图 绘制基础内容(值得一看)

    来源于:http://www.cnblogs.com/coco1s/p/3953653.html javascript变量 javascript运算符 javascript数组 javascript流 ...

随机推荐

  1. Probabilistic PCA、Kernel PCA以及t-SNE

    Probabilistic PCA 在之前的文章PCA与LDA介绍中介绍了PCA的基本原理,这一部分主要在此基础上进行扩展,在PCA中引入概率的元素,具体思路是对每个数据$\vec{x}_i$,假设$ ...

  2. Java多线程编程(6)--线程间通信(下)

      因为本文的内容大部分是以生产者/消费者模式来进行讲解和举例的,所以在开始学习本文介绍的几种线程间的通信方式之前,我们先来熟悉一下生产者/消费者模式.   在实际的软件开发过程中,经常会碰到如下场景 ...

  3. mysql的ATM存取款机系统

    ##建库 CREATE DATABASE bankDB; ##客户信息表 CREATE TABLE userInfo ( customerID INT PRIMARY KEY AUTO_INCREME ...

  4. 简述python中`functools.wrapper()

    简述python中functools.wrapper() 首先对于最简单的函数: def a(): pass if __name__ == '__main__': print(a.__name__) ...

  5. golang 递归自己,输出自己的源代码

    问题: [2min 大家自己想想] 一个程序P运行后能否输出自己的源代码?并且格式保持一致(换行.空格等) 思考: 这个问题的本质是一个递归问题,设有P运行后生成G 既P->G &&am ...

  6. 虚拟化技术之kvm管理工具virsh常用基础命令(二)

    上一篇博客我们主要聊了下virsh 管理kvm虚拟机的命令相关用法和说明,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/13508231.html:今天我们来继 ...

  7. 准确率99.9%的离线IP地址定位库

    Ip2region是什么? ip2region - 准确率99.9%的离线IP地址定位库,0.0x毫秒级查询,ip2region.db数据库只有数MB,提供了java,php,c,python,nod ...

  8. anaconda下载包时网络连接错误的解决方法(CondaHTTPError:HTTP 000 connection failed for url)

    继上一篇<在WSL上搭载python编程环境>之后,下载软件和创建新环境的过程非常艰辛,下载太慢,以至于常常中断. 不论用conda安装一些python的包,还是创新独立的编程环境时,出现 ...

  9. discuz论坛替换logo之后不显示该怎么办

    http://www.wocaoseo.com/thread-2-1-1.html 这个虽然不算是seo的问题,但是在平时的操作之中经常性的遇到,常常是我用FTP已经上传替换了原来的logo,但是前台 ...

  10. 借助FRP反向代理实现内网穿透

    一.frp 是什么? frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP.UDP.HTTP.HTTPS 等多种协议.可以将内网服务以安全.便捷的方式通过具有公网 IP 节点的中转暴露到公 ...