之前用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. C#设计模式之22-模板方法模式

    模板方法模式(Template Method Pattern) 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/429 访 ...

  2. C#算法设计排序篇之08-计数排序(附带动画演示程序)

    计数排序(Counting Sort) 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/689 访问. 计数排序是一个非基 ...

  3. run as --> Maven clean 可以清除旧的jar包

    run as --> Maven clean 可以清除旧的jar包

  4. MySQL 偶尔抽风,性能突然下降

    有时会碰到这样的情况,一条 SQL 在平时执行没问题,很快.但是突然某个时间执行的就会很慢,而且这种场景并不能复现,只能随机发送的. SQL 执行突然变慢的原因 在之前讲解 MySQL Redo lo ...

  5. java应用中的日志介绍

    日志在应用程序中是非常非常重要的,好的日志信息能有助于我们在程序出现 BUG 时能快速进行定位,并能找出其中的原因. 但是,很多介绍 AOP 的地方都采用日志来作为介绍,实际上日志要采用切面的话是极其 ...

  6. 1.Oracle数据库简介

    Oracle数据库简介 Oracle Database,又名Oracle RDBMS,或简称Oracle.是甲骨文公司的一款关系数据库管理系统.它是在数据库领域一直处于领先地位的产品.可以说Oracl ...

  7. 操作系统-进程(3)Linux下的进程相关命令

    操作系统给予这个内存中的单元一个标识符(PID)依据登入者的UID/GID(/etc/passwd) 衍生出的其它程序(子程序),一般情况也,也会沿用这个程序(父程序)的相关权限 ParentID(P ...

  8. NeoVIM安装使用

    1.What's Neovim Bram Moolenaar 在写 Vim 时还是 90 年代初,至今已经 20 多年 过去了.其中,不仅包含了大量的遗留代码,而且程序的维护.Bug 的 修复.以及新 ...

  9. centos6.8上安装部署 jhipster-registry

    必备环境:jdk8,git,maven 1.安装nodejs #由于采用编译的方式很容易出现一些意外的惊喜,所以我们这儿直接用yum命令安装 #1.查看nodejs版本(命令中不要加 -y 如果版本不 ...

  10. 3点带你快速学会Selenium工具的使用

    (一)Selenium IDE Firefox的一个插件,有助于我们理解测试框架.在附加组件里搜索下载,一般搜的结果里前几个都不是,得点那个查看更多才行,找到这个: 安装以后浏览器工具栏会有: 安装好 ...