概述

上个版本简单的连线在一些复杂场景,尤其层级比较多,连线跨层级比较多的情况下,会出现线条会穿过矩形的情况,这一讲就是在这个基础上,去优化这个连线。

场景分析

在下面几种情况下,简单版本的画法已经没法办规避障碍节点了。

这种情况,由于简单版本,我们只在整条路径上添加了2个拐点,这种画法,当出现上述情况,线条就会被B挡住,实际的需求,我们要规避这种节点,绕开。

应该是下面这种情况:

再复杂一点的场景如下

这时候有2个节点挡住了。我们要做的就是按照图示,绕开节点。

思路分析

观察分析,我们要想绕开,一些障碍节点,我们先要知道哪些节点会挡住,才可以绕开。有两个已经明确数据是,每一层的节点的坐标我们是知道,起点p1, 终点是p6。 我们可以模拟这个过程:

  1. 如果p1 所在直线没有被最近的下一层挡住,也就是图中D,E,F节点挡住的话,那就说明,起点可以先画到p2
  2. 画到p2 之后,继续判断第三层节点,由于B节点会挡住从p2 往下画的竖线,所以绕开B节点,由于P6终点再p2 左侧,所以,在B的左侧找一个空白的地方,即p3
  3. 现在画到p3了,这时候起点编程p3了, 问题转换成画p1的场景了
  4. 一直循环,直到到终点这一层,把这个路径上的所有的折点记录下来,就是我们的路径

具体实现

function drawLine(startX, startY, endX, endY, color, sourceNodeName, targetNodeName, endLayer, startLayer, lineNodes) {
var points = []; // 保存路径上的折点
var sx = startX;
var ex = endX;
for (var layer = startLayer + 1; layer < endLayer; layer++) {
// 判断当前这一层有没有节点挡住
var coverRectIndex = -1;
for(var i = 0; i < lineNodes[layer].length; i++){
if(lineNodes[layer][i].x < sx && (sx - lineNodes[layer][i].x) < config.rect.width){
coverRectIndex = i;
break;
}
}
if(coverRectIndex === -1){
// 如果没有挡住,检查下一层
continue;
}else{
// 如果有挡住,则需要根据起点和目标节点相对位置,决定往左边绕还是后边绕 var midY = lineNodes[layer][coverRectIndex].y - 40; // 计算是左边的空隙还是右边的空隙
var midX = lineNodes[layer][coverRectIndex].x;
midX += sx > ex? -(config.rect.space / 2 + config.rect.width) : (config.rect.space / 2 + config.rect.width);
while (true) {
var flag = false;
if (nodeLines[layer]) {
for (var i = 0; i < nodeLines[layer].length; i++) {
var line = nodeLines[layer][i];
if (line.startY === midY) {
if (checkCross(sx, midX, line.startX, line.endX)) {
flag = true;
}
}
if (flag) break;
}
} else {
nodeLines[layer] = [];
}
if (!flag) break;
midY -= lineDis;
}
if (sx !== midX) {
nodeLines[layer].push({
startX: sx,
startY: midY,
endX: midX,
endY: midY
})
}
// 存储路径上点
points.push({ x: sx, y: midY });
points.push({ x: midX, y: midY });
sx = midX;
}
} // 单独处理最后一层的场景
var midY = lineNodes[endLayer][0].y - 40;
while (true) {
var flag = false;
if (nodeLines[endLayer]) {
for (var i = 0; i < nodeLines[endLayer].length; i++) {
var line = nodeLines[endLayer][i];
if (line.startY === midY) {
if (checkCross(sx, ex, line.startX, line.endX)) {
flag = true;
}
}
if (flag) break;
}
} else {
nodeLines[endLayer] = [];
}
if (!flag) break;
midY -= lineDis;
}
if (sx !== ex) {
nodeLines[layer].push({
startX: sx,
startY: midY,
endX: ex,
endY: midY
})
}
points.push({ x: sx, y: midY });
points.push({ x: ex, y: midY });
return points;
}

总结

这里是在原来的基础上进行优化的,实现了规避障碍节点的功能。一开始,我想到是 A*算法去搜索,但是像素点太多,算法复杂度Hold不住,后面卡在缩点的环节上,经过同事的指点,才实现了当前的这种优化,还是要多学习,多总结!

本文由华为云发布。

从零开始画自己的DAG作业依赖图(四)--节点连线优化版的更多相关文章

  1. bug终结者 团队作业第四、五周

    bug终结者 团队作业第四.五周 博客编辑者:20162322朱娅霖 本周学习任务: 团队协作完成<需求规格说明书> 工作流程 第四周 团队成员各自完成蓝墨云班课中<需求规格说明书& ...

  2. 从零开始用 Flask 搭建一个网站(四)

    前言 从零开始用 Flask 搭建一个网站(三) 介绍了网页前端与后端.前端与前端之间数据的交流.本节主要介绍一下如何应用 Flask-OAuthlib, 使用 Flask-OAuthlib 就可以轻 ...

  3. 学习OpenStack之(5):在Mac上部署Juno版本OpenStack 四节点环境

    0. 前沿 经过一段时间的折腾,终于在自己的Mac上装好了Juno版本的四节点环境.这过程中,花了大量的时间,碰到了许多问题,学到不少知识,折腾过不少其实不需要折腾的东西,本文试着来对这过程做个总结. ...

  4. Spring的第四天AOP之注解版

    Spring的第四天AOP之注解版 ssm框架 spring  在上一篇博客中,介绍了Spring的AOP的xml版本的使用,在这篇博客中,我将介绍一下,注解版的使用. 常用注解 注解 通知 @Aft ...

  5. TKE 用户故事 | 作业帮 Kubernetes 原生调度器优化实践

    作者 吕亚霖,2019年加入作业帮,作业帮架构研发负责人,在作业帮期间主导了云原生架构演进.推动实施容器化改造.服务治理.GO微服务框架.DevOps的落地实践. 简介 调度系统的本质是为计算服务/任 ...

  6. 北航oo作业第四单元小结

    1.总结本单元两次作业的架构设计 在我动手开始总结我的设计之前,我看了其他同学已经提交在班级群里的博客,不禁汗颜,我是真的偷懒.其他同学大多使用了新建一个类,用以储存每一个UMLelemet元素的具体 ...

  7. oo作业总结(四)

    测试与正确性论证 测试是通过构造一系列测试数据,通过对比程序的实际运行结果和预期输出结果来判断程序是否有bug的一种手段.同时,在测试的时候是默认看不到程序的具体实现的,即进行黑盒测试,例如每次OO作 ...

  8. oo作业第四单元总结暨结课总结

    目录 一.第四单元作业架构设计 1.第一次UML作业架构设计 2.第二次UML作业架构设计 二.架构设计和OO方法理解演进 三.测试理解与实践的演进 四.课程收获总结 五.三个具体改进建议 一.第四单 ...

  9. OO第四次博客作业--第四单元总结及课程总结

    一.总结第四单元两次作业的架构设计 1.1 第一次作业 类图如下: 为了突出类.接口.方法.属性.和参数之间的层次结构关系,我为 Class 和 Interface 和 Operation 分别建立了 ...

随机推荐

  1. Zabbix使用python批量添加主机及主机资产信息-从零到无

    - - 时间:2020年11月10日 - - 作者:飞翔的小胖猪 前言: 使用zabbix作为基础环境的监控系统时,面对现网在用的2000+台把这些主机添加到zabbix监控中是一个问题,当然zabb ...

  2. strtok:This function or variable may be unsafe.

    https://jingyan.baidu.com/article/49711c616b8a1ffa441b7cdc.html

  3. LeetCode-082-删除排序链表中的重复元素 II

    删除排序链表中的重复元素 II 题目描述:存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除链表中所有存在数字重复情况的节点,只保留原始链表中 没有重复出现 的数字. 返回同样按升序 ...

  4. think php 多条件检索+自带分页+多条件搜索标红分页

    //视图<form action="/homework/homework/index" method="get"> <input type=& ...

  5. laravel 返回值

    先理解几个概念: StdClass 对象 => 基础的对象 Eloquent 模型对象 (Model 对象) => 和模型相关的类对象 Eloquent 集合 => 可以简单理解为对 ...

  6. 一比一还原axios源码(零)—— 概要

    从vue2版本开始,vue-resource就不再被vue所维护和支持,官方也推荐使用axios,所以,从我使用axios至今,差不多有四五年了,这四五年的时间只能算是熟练应用,很多内部的实现和原理不 ...

  7. CF594D题解

    我不会数据结构/kk 我想题意应该十分清楚了. 我们知道 \(\varphi(p^k)=p^{k-1}(p-1)\),那么我们考虑将一个询问下放到右端点,然后往右移动右端点并更新每个左端点到右端点的答 ...

  8. 《前端运维》一、Linux基础--04Shell变量

    这一篇文章,我们就要开始学习正式的Shell语言部分的内容.那在开始之前,我们回忆一下,javascript语言,大体都包含了哪些内容?比如数据类型(对象.字符串.数值),数据结构(对象.数组).运算 ...

  9. ArcMap操作随记(14)

    1.ArcMap中模型转为Python脚本 [模型]→右键→[编辑]→[模型]→[导出]→[至Python脚本] 2.一般来说,植被指数NDVI,-1<=NDVI<=1. 3.用lands ...

  10. 做一个能对标阿里云的前端APM工具(上)

    APM 全称是 Application Performance Monitor,即性能监控 这篇文章有三个前提: 从产品形态上看这肯定不是一个能够媲美阿里产品的竞品,所以抱歉我碰瓷了.你可以把这里的阿 ...