• Jsp网络拓扑图--用java实现网络拓扑图 (2013-03-21 18:04:47) 转载▼ 标签: 网络拓扑 网络拓扑图 动态绘制 java jsp   Web网络拓扑图动态绘制的实现 引 言 基于Web的网络管理...

    Jsp网络拓扑图--用java实现网络拓扑图

    (2013-03-21 18:04:47)

    Web网络拓扑图动态绘制的实现

     

    基于Web的网络管理体系融合了Web功能和网管技术允许网管人员通过任何一种浏览器在网络的任何节点方便迅速地访问计算机网络。Web方式的网络拓扑显示是基于Web的网络管理体系中重要的组成部分,使管理员可以直观地监控网络设备的通断状态、网络流量以及整个网络的拓扑结构及时准确地发现网络故障点,从而更好地保障用户借助网络进行学习和工作。

    多比图形控件是一款基于Web(VML和SVG技术)的矢量图形控件, 类似于网页上的Visio控件,可应用于电力、军工、煤炭、化工、科研、能源等各种监控软件。和其他技术相比,它的显著特征是:类似Visio的操作界面,同时支持矢量图和位图,用户可自定义数据,Jsp网络拓扑图--用java实现网络拓扑图好的交互能力以及强大的脚本语言等。 多比控件易于和ASP。NET和Java技术集成, 在界面上和其他DOM结构交互能力非常强,还可以利用Extjs、jQuery等三方包,实现更加强大的功能。

     

    多比图形控件是一款基于Web(VMLSVG技术)的矢量图形控件, 类似于网页上的Visio控件,可广泛应用于包括:电力、军工、煤炭、化工、科研、能源等各种监控软件、web工作流设计器、asp.net工作流设计器、电力、化工、煤炭、工控组态软件、仿真、地理信息系统、工作流、复杂报表 工业SCADA系统、ERP流程设计系统、图形管理、图形拓扑分析、GIS地理信息系统系统、工程制图等领域。

     

    多比的绘图机制

    多比画图的机制是将图元定义为一个个不同的图元, 每个图元可以Jsp网络拓扑图--用java实现网络拓扑图是一个节点或连线。节点可以有邻接的节点,他们通过连线相联系,边联接的两个端点称为目标和源,每个目标或者源是一个节点。 节点和节点可以分散和组合, 组合后的节点可以当作一个图元使用。

     

    设计与实现

    本文将定时扫描采集的网络信息存储在SQL SERVER2005数据库中。为了避免数据量过大时影响程序处理速度和网站访问速度,采用每天生成一个独立的库,以日期格式yyyy_MM_dd命名,每次扫描结果生成一个数据表,以时间格式HH_mm_ss命名另外在每个数据库中还有一个数据表是随着新数据表的生成而更新的它存储了当天生成的所有数据表名。

    绘制拓扑图时访问的数据表有存储数据表名的表TableName、当前最新生成的表HH_mm_ss和存储设备之间连接关系的表DeviceInfoTableName中包含的主要字段有表名( Name)、Jsp网络拓扑图--用java实现网络拓扑图创建时间( CreateTime)HH_mm_ss中包含的主要字段有设备地址( IP)、通断状态( Ping)、入口流量百分比( InPercent)、出口流量百分比( OutPercent)、上联口(UpPort)Devi

    ceInfo中包含的主要字段有设备地址( IP)、型号(Model)、制造商(Manufacturer)、安装位置( Location)、父IP( ParentIP)、根IP( RootIP)、级别( SwitchType)

    绘制拓扑图流程

    布局每层的网络设备都需要按照一下的步骤来进行:

    ( 1) yyyy_MM_dd的格式获取当前日期作为数据库名,Jsp网络拓扑图--用java实现网络拓扑图连接数据库。

    ( 2) 查询TableName中最新生成的表作为以下查询网络设备信息的来源。

     

    ( 3) DeviceInfo中读取SwitchType= 1IPRootIP, 即核心层的父设备及其子设备并将子设备IP存储到集合ArrayList同时赋值给size子设备的数目。汇聚层的父设备IP是从核心层某设备的链接传递来的接入层的父设备IP是从汇聚层某设备的链接传递来的。

    ( 4) 查询父设备的通断状态( Ping), 在圆心坐标处画Jsp网络拓扑图--用java实现网络拓扑图父设备并根据Ping值着色。

    ( 5) 循环画子设备查询它们的通断状态和其子设备的通断状态根据结果给设备着色。对于接入层,只需要查询设备本身的通断状态。

    Jsp网络拓扑图--用java实现网络拓扑图




    ( 6) 循环连接父设备与子设备,并查询对应设备的出口和入口流量百分比分别标于连接的两端。

    三层的Web页面都是定时刷新的以便显示最新的网络信息,并且通过对节点着色反映本层设备及其子设备的状态,保证网管人员能够及时准确地发现故障点。


    Jsp网络拓扑图--用java实现网络拓扑图

     

    展开全文
  • java拓扑图

    2010-03-20 09:41:51
    今天心情不错,公司终于签下了一个综合业务监控系统的大单。到底有多大我也不知道,反正连软件带硬件不算小。按照销售的说法,拿下这个项目一个重要的因素就是要提供一个吸引眼球的demo,而我们做的不错!...

    今天心情不错,公司终于签下了一个综合业务监控系统的大单。到底有多大我也不知道,反正连软件带硬件不算小。按照销售的说法,拿下这个项目一个重要的因素就是要提供一个吸引眼球的demo,而我们做的不错!今天和大家分享一下喜悦和经验!

     

    这个项目是一个省级电信运营商的综合业务监控系统。公司跟了好长时间了。由于是一个综合的业务监控系统,涉及的管理资源非常多,又要提供大屏幕显示,所以对系统的呈现效果要求非常高(“政绩工程”么)。前前后后提了很多“无礼”要求,陆续提过的有3D电子地图、3D机房监控、场景仿真、全动画、Google Earth、全Flash等等....弄的我们晕头转向、焦头烂额。其实很多时候,用户自己也不知道想要什么,反正对厂商的要求就是一个字:“炫”,两个字“好看”,三个字:“一定好好看!”(不对,好像是四个字哦)。

     

    言归正传,项目跟踪过程中,商务始终告诉我们研发一定要做好一件事:如何做好呈现,尤其是综合的业务监控和呈现,这是获得项目的关键,一定要“出彩”。这个“综合呈现”说起来容易,做起来难。作为省级的电信运营商,内部的各种软硬件系统无数,要监控从上到下、从软到硬,真是烦不胜烦:

    • 基础设施层:主要是网络上的硬件设备,包括交换机、路由器、防火墙、各种主机设备服务器等等;
    • 软件层:这一层主要是主机上面运行的操作系统和各类业务软件系统,例如操作系统(Windows、AIX/HP-UX/LINUX/SOLARIS)、各种中间件(WebLogic、JBoss、IIS、WebSphere等)、数据库(Oracle、Sybase、MySQL)等;
    • 应用层:这一层是指运行在软件层内部的一些细粒度资源,包括一些关键的软件进程、数据库表空间、业务连接、消息队列等等。这一层数量繁杂、数量众多。不过这些资源的状态直接会影响其上层支撑的业务。
    • 业务层:业务层是最顶层,由以上底层资源所共同支撑起来的面向用户的各种业务。对业务最容易理解的描述就是电信提供给客户的具体“服务”。例如视频业务、短信业务、WAP业务、专网业务等等。这些业务才是用户最终关心的东西,因为这些业务才是客户的核心资产,是拿来卖钱的最终产品。一旦出问题,将直接影响money!

    此外,还有一大堆机房环境监控的要求,什么配电柜供电、开关状态、UPS、蓄电池、空调、适度温度漏水效仿通风门禁视频.........一大堆。所以,要对业务进行监控,就必须对业务所支撑的各个底层资源进行监控。另外,还要能够对这些资源的关系进行连接和定义,一旦发生故障和问题,能够从上到下迅速定位故障起源,在最短时间内发现问题、解决问题。如何呈现这些依赖关系,并对故障和告警进行纵向定位,是软件呈现的一个核心问题,也是用户最关心的一个问题。

     

    用户要求我们先制作一个demo程序,看我们将如何呈现“综合监控”的效果。在充分了解了用户需求之后,经过讨论,我们想做一个完全图形化的分层、跨层的综合监控界面。界面要美观,有动画效果,能够清晰的显示资源依赖关系和告警传播定位。

    需要监控和管理的资源

     


     接下来要写代码了。肯定先用我熟悉的TWaver试试。研究了一下,TWaver中有一个平行四边形的Group对象,适合做上图中的“层”的概念。先如下封装并设置属性:

    Java代码 复制代码
    1. package demo;   
    2.   
    3. import java.awt.Color;   
    4. import twaver.Group;   
    5. import twaver.TWaverConst;   
    6.   
    7. public class LayerGroup extends Group {   
    8.   
    9.     public LayerGroup() {   
    10.         init();   
    11.     }   
    12.   
    13.     public LayerGroup(Object id) {   
    14.         super(id);   
    15.         init();   
    16.     }   
    17.   
    18.     private void init() {   
    19.         this.setGroupType(TWaverConst.GROUP_TYPE_PARALLELOGRAM);   
    20.         this.putGroupAngle(45);   
    21.   
    22.         this.putGroup3D(true);   
    23.         this.putGroupDeep(10);   
    24.         this.putGroupOutline(false);   
    25.         this.putGroupFillColor(Color.green.darker());   
    26.         this.putGroupGradient(true);   
    27.         this.putGroupGradientFactory(TWaverConst.GRADIENT_LINE_E);   
    28.         this.putGroupHandlerVisible(false);   
    29.         this.putGroupDoubleClickEnabled(false);   
    30.         this.putBorderColor(Color.white);   
    31.         this.putBorderInsets(3);   
    32.         this.putBorderAntialias(true);   
    33.         this.putBorderStroke(TWaverConst.STROKE_SOLID_4);   
    34.         this.putBorderVisible(false);   
    35.         this.putLabelHighlightable(false);   
    36.   
    37.         this.setEnableAlarmPropagationFromChildren(false);   
    38.     }   
    39. }  
    package demo;
    
    import java.awt.Color;
    import twaver.Group;
    import twaver.TWaverConst;
    
    public class LayerGroup extends Group {
    
        public LayerGroup() {
            init();
        }
    
        public LayerGroup(Object id) {
            super(id);
            init();
        }
    
        private void init() {
            this.setGroupType(TWaverConst.GROUP_TYPE_PARALLELOGRAM);
            this.putGroupAngle(45);
    
            this.putGroup3D(true);
            this.putGroupDeep(10);
            this.putGroupOutline(false);
            this.putGroupFillColor(Color.green.darker());
            this.putGroupGradient(true);
            this.putGroupGradientFactory(TWaverConst.GRADIENT_LINE_E);
            this.putGroupHandlerVisible(false);
            this.putGroupDoubleClickEnabled(false);
            this.putBorderColor(Color.white);
            this.putBorderInsets(3);
            this.putBorderAntialias(true);
            this.putBorderStroke(TWaverConst.STROKE_SOLID_4);
            this.putBorderVisible(false);
            this.putLabelHighlightable(false);
    
            this.setEnableAlarmPropagationFromChildren(false);
        }
    }
    

     通过这个简单的封装,再往Group里头放几个节点和连线,显示效果如下:

     

    用Group制作的“层”效果

     

    怎么样,有点意思吧?开头不错,继续改进!再依次排列4个Group,用不同颜色,试试效果:

    Java代码 复制代码
    1. createLayer(Color.orange, 50010"7.png""<html><center>软件<br>业务层</center></html>");   
    2. createLayer(Color.green.darker(),18020015"8.png""<html><center>技术<br>应用层</center></html>");   
    3. createLayer(Color.magenta.darker(),2803505"5.png""<html><center>技术<br>软件层</center></html>");   
    4. createLayer(Color.cyan.darker(),4005707"1.png""<html><center>基础<br>设施层</center></html>");  
    createLayer(Color.orange, 50, 0, 10, "7.png", "<html><center>软件<br>业务层</center></html>");
    createLayer(Color.green.darker(),180, 200, 15, "8.png", "<html><center>技术<br>应用层</center></html>");
    createLayer(Color.magenta.darker(),280, 350, 5, "5.png", "<html><center>技术<br>软件层</center></html>");
    createLayer(Color.cyan.darker(),400, 570, 7, "1.png", "<html><center>基础<br>设施层</center></html>");

    以上代码封装了创建一个层的函数,给定颜色、坐标位置、内部节点数量、图标、文字等等。上面代码中的HTML风格字符串是为了在TWaver中(好像Swing中也是这样的)显示换行的标签。每一个层作为容器包含了很多不同类型的资源。显示效果如下图:

     

    四层拓扑图显示效果

     

    注意其中的连线有下垂的弯曲效果。这是我以前在做项目封装过的一个TWaver技巧:通过重写twaver的Link的UI类,重新指定path走向实现的。其实也很简单,首先获得link的from点和to点,取值中间点,再把y纵向增加20,把这个点作为quadTo的控制点画曲线即可。对TWaver熟悉的朋友可以看一下这段代码(其实这个效果也是从TWaver Java的demo源代码中学习到的):

    Java代码 复制代码
    1. package demo;   
    2.   
    3. import java.awt.Point;   
    4. import java.awt.geom.GeneralPath;   
    5. import twaver.network.TNetwork;   
    6. import twaver.network.ui.LinkUI;   
    7.   
    8. public class InnerLinkUI extends LinkUI {   
    9.   
    10.     public InnerLinkUI(TNetwork network, InnerLink link) {   
    11.         super(network, link);   
    12.     }   
    13.   
    14.     @Override  
    15.     public GeneralPath getPath() {   
    16.         GeneralPath customPath = new GeneralPath();   
    17.         Point p1 = this.getFromPoint();   
    18.         Point p2 = this.getToPoint();   
    19.         customPath.moveTo(p1.x, p1.y);   
    20.         int offset = 20;   
    21.         customPath.quadTo((p1.x + p2.x) / 2, (p1.y + p2.y) / 2 + offset, p2.x, p2.y);   
    22.         return customPath;   
    23.     }   
    24. }  
    package demo;
    
    import java.awt.Point;
    import java.awt.geom.GeneralPath;
    import twaver.network.TNetwork;
    import twaver.network.ui.LinkUI;
    
    public class InnerLinkUI extends LinkUI {
    
        public InnerLinkUI(TNetwork network, InnerLink link) {
            super(network, link);
        }
    
        @Override
        public GeneralPath getPath() {
            GeneralPath customPath = new GeneralPath();
            Point p1 = this.getFromPoint();
            Point p2 = this.getToPoint();
            customPath.moveTo(p1.x, p1.y);
            int offset = 20;
            customPath.quadTo((p1.x + p2.x) / 2, (p1.y + p2.y) / 2 + offset, p2.x, p2.y);
            return customPath;
        }
    }
    

     用这种link做出的拓扑图比较生动美观。多加几个节点连线就能看出来了:

     

    四层复杂拓扑图显示效果

     

    不过发现平行四边形Group一个问题:当两个Layer叠加后,下面的节点会被完全覆盖,看不见了。用户说:能不能也能看见?(晕,盖住了也要看见。谁让人家是甲方呢?)于是询问TWaver的人,一个哥们说Group有透明属性。于是试了一下,效果不还错:

    Java代码 复制代码
    1. this.putGroupOpaque(false);  
    this.putGroupOpaque(false);

     

    层的透明与覆盖

     

    下一步,关键了:要增加层与层之间资源的“依赖关系”。例如一个Oracle跑在一台主机上,而Oracle中的一个关键表空间需要重点监控,它决定了上层一个视频点播业务是否能够正常。为了体现这个依赖关系,在跨层的节点中间建立link。这个link和层内部link显示上应当有所区别:

    Java代码 复制代码
    1. package demo;   
    2.   
    3. import java.awt.Color;   
    4. import twaver.Link;   
    5. import twaver.Node;   
    6. import twaver.TWaverConst;   
    7. import twaver.base.OrthogonalLinkDirectionType;   
    8.   
    9. public class LayerLink extends Link {   
    10.     public LayerLink(Node from, Node to) {   
    11.         super(from, to);   
    12.         init();   
    13.     }   
    14.   
    15.     public LayerLink(Object id, Node from, Node to) {   
    16.         super(id, from, to);   
    17.         init();   
    18.     }   
    19.   
    20.     private void init() {   
    21.         this.putLink3D(true);   
    22.         this.putLinkWidth(4);   
    23.         this.putLinkOutlineWidth(0);   
    24.         this.putLinkColor(Color.lightGray);   
    25.         this.putLinkAntialias(false);   
    26.         this.setLinkType(TWaverConst.LINK_TYPE_ORTHOGONAL);   
    27.     }   
    28. }  
    package demo;
    
    import java.awt.Color;
    import twaver.Link;
    import twaver.Node;
    import twaver.TWaverConst;
    import twaver.base.OrthogonalLinkDirectionType;
    
    public class LayerLink extends Link {
        public LayerLink(Node from, Node to) {
            super(from, to);
            init();
        }
    
        public LayerLink(Object id, Node from, Node to) {
            super(id, from, to);
            init();
        }
    
        private void init() {
            this.putLink3D(true);
            this.putLinkWidth(4);
            this.putLinkOutlineWidth(0);
            this.putLinkColor(Color.lightGray);
            this.putLinkAntialias(false);
            this.setLinkType(TWaverConst.LINK_TYPE_ORTHOGONAL);
        }
    }
    

     显示出来后,效果并不理想,有点乱。主要是没有“跨层”的立体感。

     

    跨层连线效果

     

    图中跨层的link没有呈现出“穿透层”的感觉,多了以后反而破坏了整个拓扑图的立体感和生动感,需要再改进。最好能够显示“穿层而过”的效果。需求变态么?不弄点猛药还想拿单子么,程序员就是要与各种“不可能”说“不”嘛!经过反复研究和实验,终于做出了一个更好的效果,如下图:

    连线的跨层穿透效果

    注意观察其中穿层效果,不知大家是否喜欢?



     

    连线的透明穿透

     

    怎么做到的呢?其实也简单,一点就破,我就不点破了吧,卖个关子先。大家可以先猜猜看,源代码里头也能看到答案。接下来,可以增加一些跨层连线了!看看下图效果:

     

    跨层连线的综合效果图

    效果还不错吧?销售看过后非常满意,连说有新意。不过还有最后一个很头大的问题:需要显示告警及其传播路线,也就是告警发生后,要从底层一直沿着依赖关系传播到上层。于是开始研究TWaver的AlarmPropagator告警传播器。通过研究发现,其实告警传播也不复杂,主要原理是当告警发生后,它会根据AlarmPropagator的“指示”和定义的规则,沿着一个特定的“路径”进行告警传播。被传播过的地方,会显示一个有告警颜色的外框,标志其告警状态。

     

    但是问题是,TWaver的告警传播器是按照“父子关系”进行传播的。也就是默认情况下,告警总是从孩子传给父亲,一直到没有parent为止。按照这个规则,这个demo中一个节点发生告警后,会传播给平行四边形这个层对象,这显然是没有意义的,不符合我的要求。我们需要告警沿着层的“依赖关系”进行跨层传播。于是重写AlarmPropagator!也不难,调试了几个小时,用一个递归法总算搞定了。代码如下:

    Java代码 复制代码
    1. package demo;   
    2.   
    3. import java.util.Collection;   
    4. import java.util.Iterator;   
    5. import twaver.AlarmSeverity;   
    6. import twaver.Element;   
    7. import twaver.Node;   
    8.   
    9. public class DemoPropagator {   
    10.   
    11.     public void propagate(Element element) {   
    12.         AlarmSeverity severity = element.getAlarmState().getHighestNativeAlarmSeverity();   
    13.         if (element instanceof Node) {   
    14.             Node node = (Node) element;   
    15.   
    16.             Collection links = node.getAllLinks();   
    17.             if (links != null && !links.isEmpty()) {   
    18.                 Iterator it = links.iterator();   
    19.                 while (it.hasNext()) {   
    20.                     Object o = it.next();   
    21.                     if (o instanceof LayerLink) {   
    22.                         LayerLink link = (LayerLink) o;   
    23.                         if (link.getAlarmState().isEmpty()) {   
    24.                             link.getAlarmState().addAcknowledgedAlarm(severity);   
    25.   
    26.                             Node anotherNode = link.getFrom();   
    27.   
    28.                             if (anotherNode.getAlarmState().isEmpty()) {   
    29.                                 anotherNode.getAlarmState().addAcknowledgedAlarm(severity);   
    30.                                 if (anotherNode != node) {   
    31.                                     propagate(anotherNode);//这里递归!   
    32.                      }   
    33.                             }   
    34.                         }   
    35.                     }   
    36.                 }   
    37.             }   
    38.         }   
    39.     }   
    40. }  
    package demo;
    
    import java.util.Collection;
    import java.util.Iterator;
    import twaver.AlarmSeverity;
    import twaver.Element;
    import twaver.Node;
    
    public class DemoPropagator {
    
        public void propagate(Element element) {
            AlarmSeverity severity = element.getAlarmState().getHighestNativeAlarmSeverity();
            if (element instanceof Node) {
                Node node = (Node) element;
    
                Collection links = node.getAllLinks();
                if (links != null && !links.isEmpty()) {
                    Iterator it = links.iterator();
                    while (it.hasNext()) {
                        Object o = it.next();
                        if (o instanceof LayerLink) {
                            LayerLink link = (LayerLink) o;
                            if (link.getAlarmState().isEmpty()) {
                                link.getAlarmState().addAcknowledgedAlarm(severity);
    
                                Node anotherNode = link.getFrom();
    
                                if (anotherNode.getAlarmState().isEmpty()) {
                                    anotherNode.getAlarmState().addAcknowledgedAlarm(severity);
                                    if (anotherNode != node) {
                                        propagate(anotherNode);//这里递归!
                         }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    

     

    这里代码的逻辑主要是判断是不是跨层link,如果是就沿着它进行传播。噢吼!上面代码好像泄露了上面“穿透Layer”的秘密了,呵呵。最后,再来一个“告警模拟器”来模拟随机、随时发生告警,也就是用一个单独的线程在里面sleep然后生成Alarm并发送到拓扑图的节点上。直接上代码:

    Java代码 复制代码
    1. package demo;   
    2.   
    3. import java.util.Iterator;   
    4. import javax.swing.SwingUtilities;   
    5. import twaver.AlarmSeverity;   
    6. import twaver.Element;   
    7. import twaver.TDataBox;   
    8. import twaver.TWaverUtil;   
    9.   
    10. public class AlarmMocker extends Thread {   
    11.   
    12.     private TDataBox box = null;   
    13.     private DemoPropagator propagator = new DemoPropagator();   
    14.   
    15.     public AlarmMocker(TDataBox box) {   
    16.         this.box = box;   
    17.     }   
    18.   
    19.     @Override  
    20.     public void run() {   
    21.         while (true) {   
    22.             try {   
    23.                 Thread.sleep(1 * 1000);   
    24.             } catch (InterruptedException ex) {   
    25.                 ex.printStackTrace();   
    26.             }   
    27.   
    28.             SwingUtilities.invokeLater(new Runnable() {   
    29.   
    30.                 public void run() {   
    31.   
    32.                     if (TWaverUtil.getRandomInt(5) == 1) {   
    33.                         //clear all alarm and propagation.   
    34.                         Iterator it = box.iterator();   
    35.                         while (it.hasNext()) {   
    36.                             Element e = (Element) it.next();   
    37.                             e.getAlarmState().clear();   
    38.                         }   
    39.                     }   
    40.   
    41.                     Element element = box.getElementByID("4." + TWaverUtil.getRandomInt(10));   
    42.                     if (element != null) {   
    43.                         element.getAlarmState().addNewAlarm(AlarmSeverity.getRandomSeverity());   
    44.                         propagator.propagate(element);   
    45.                     }   
    46.                 }   
    47.             });   
    48.         }   
    49.     }   
    50. }  
    package demo;
    
    import java.util.Iterator;
    import javax.swing.SwingUtilities;
    import twaver.AlarmSeverity;
    import twaver.Element;
    import twaver.TDataBox;
    import twaver.TWaverUtil;
    
    public class AlarmMocker extends Thread {
    
        private TDataBox box = null;
        private DemoPropagator propagator = new DemoPropagator();
    
        public AlarmMocker(TDataBox box) {
            this.box = box;
        }
    
        @Override
        public void run() {
            while (true) {
                try {
                    Thread.sleep(1 * 1000);
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
    
                SwingUtilities.invokeLater(new Runnable() {
    
                    public void run() {
    
                        if (TWaverUtil.getRandomInt(5) == 1) {
                            //clear all alarm and propagation.
                            Iterator it = box.iterator();
                            while (it.hasNext()) {
                                Element e = (Element) it.next();
                                e.getAlarmState().clear();
                            }
                        }
    
                        Element element = box.getElementByID("4." + TWaverUtil.getRandomInt(10));
                        if (element != null) {
                            element.getAlarmState().addNewAlarm(AlarmSeverity.getRandomSeverity());
                            propagator.propagate(element);
                        }
                    }
                });
            }
        }
    }
    

     

    告警模拟器把最底层的里面的节点随机产生告警,再随机的清除,模拟现实网络的监控状态。然后运行demo,观察其告警传播的路线是否符合预期,也就是沿着层进行传播。

     

    注意一个细节:由于上面告警模拟器在一个单独的Thread线程中运行,在产生告警并更改界面时候,需要用SwingUtilities.invokeLater进行代码封装调用,保证它在Swing线程中执行,避免屏幕和界面“花”或不可预知的显示结果。唉,谁让Swing是单线程而且是线程不安全呢?这是个古老话题,就不罗嗦了。

     

    废话不多说,直接上最终效果图:

     

     

    demo最终效果图

     

    双击层动画旋转并放大

     

    看到告警跨层传播的效果了吗?最后,根据客户的要求,又增加了一些动画效果:双击平行四边形后,平行四边形会动画变成矩形、动画飞到屏幕中间,然后动画放大内部拓扑图,供用户查看细节;再次双击,平行四边形快速旋转缩小并回到原来位置。demo程序交付并演示后,获得客户高度评价。用我们商务人员的话来说就是:“我们的demo最出彩!”作为程序员,自己做的东西能为公司创造价值和利润就是最大的肯定和成就感!

     

    由于demo掺杂了不少公司的代码,我会花一点时间整理一下,弄出一个干净的demo代码贴出来,请感兴趣的朋友留意。我这里也有可以直接运行的jar包,感兴趣的朋友可以留下邮箱。对了,以上信息仅供技术交流之用,请勿用于其它商业用途。

    展开全文
  • 以上创建网络图元、设置图元连线关系、配置图元风格属性、进行图元布局摆放就是构建拓扑图的几个基本步骤,其实熟悉了 HT 分分钟就能开发出像模像样的 HTML5 网络拓扑图应用,如果需要数据存储可参考《HT for Web ...

    采用 HT 开发网络拓扑图非常容易,例如《入门手册》的第一个小例子麻雀虽小五脏俱全:http://www.hightopo.com/guide/guide/core/beginners/examples/example_overview.html

    该例子展示了如何构建两个节点、一条连线、以及一个 Group 的组合效果。结合 《数百个 HTML5 例子学习 HT 图形组件 – 拓扑图篇》可以容易理解构建一个拓扑界面基本上就是操作 DataModel 数据模型,以下为构建上图界面效果的模型代码部分:

    // init data model
    hello = new ht.Node();
    hello.setPosition(60, 140);             
    hello.setName('Hello');
    hello.setStyle('note', 'I love HT');
    hello.setStyle('note.background', '#FFA000');
    dataModel.add(hello);
    
    world = new ht.Node();
    world.setPosition(260, 80);
    world.setName('World');
    world.setStyle('note', 'HT for your imagination');
    world.setStyle('note.expanded', false);  
    world.setStyle('border.color', 'red');                
    dataModel.add(world);
    
    edge = new ht.Edge(hello, world);
    edge.setName('Hello World\nwww.hightopo.com');
    edge.setStyle('label.color', 'white');
    edge.setStyle('label.background', '#3498DB');                
    dataModel.add(edge);  
    
    group = new ht.Group();
    group.setName('HT for Web ' + ht.Default.getVersion());
    group.addChild(hello);
    group.addChild(world);
    group.addChild(edge);
    dataModel.add(group);

    当然真实的系统不会像上述代码这样写死内容,一般用户通过后台数据查询,然后再根据后台数据动态创建拓扑节点、连线、组、子网等图元内容,并填充如图元名字、连线颜色、告警内容等属性信息,而因为 HT 技术基于 HTML5,因此大部分工业控制 Web SCADA 客户都采用了 WebSocket 的实时通讯方式,关于 WebSocket 的使用可参考这篇文章:3D拓扑自动布局之Node.js篇

    构建模型就是上面这样简单,剩下工作就是设置相应的图元属性达到信息展示和美观的效果,关于图元甚至整体 HT 图形组件风格的自定义,可参考《HT for Web 风格手册》,这里我举个简单的小细节,可人有人留意到上面设置 label 的代码有点特别:

    edge.setName('Hello World\nwww.hightopo.com');

    这里 \n 顾名思义就是换行的意思,当然除了换行外,还可以有垂直布局等等花哨的展示形态,可参考《网络拓扑图上文本的巧妙应用》一文的介绍:

    var list = [], node;
    for (var i = 0; i < 4; i++) {
        node = new ht.Node();
        node.setImage('station');
        node.p(100 + i * 100, 100);
        dm.add(node);
    
        list.push(node);
    }
    node = list[0];
    node.s({
        'label': '厦门',
        'label.font': '22px arial, sans-serif',
        'label2': 'Xiamen',
        'label2.position': 31,
        'label2.offset.y': 23
    });
    
    node = list[1];
    node.s({
        'label': '图\n扑',
        'label.position': 14,
        'label.font': '22px arial, sans-serif',
        'label2': 'Hightopo',
        'label2.position': 14,
        'label2.offset.x': -7,
        'label2.rotation': -Math.PI / 2
    });
    
    node = list[2];
    node.s({
        'label': '上\n海',
        'label.position': 20,
        'label.font': '22px arial, sans-serif',
        'label2': 'Shanghai',
        'label2.position': 20,
        'label2.offset.x': 6,
        'label2.rotation': -Math.PI / 2
    });
    
    node = list[3];
    node.s({
        'label': '北京',
        'label.position': 3,
        'label.font': '22px arial, sans-serif',
        'label2': 'Beijing',
        'label2.position': 3,
        'label2.offset.y': -23
    });

    当然也可以达到动态旋转文字的效果,拖拽下面这个红色圆球达到动态旋转文字的效果:http://www.hightopo.com/guide/guide/core/beginners/examples/example_label.html

    从上面例子可以参考光光一个文字还有设置颜色、背景、字体、最大长度等等参数,如果加上 Position 的布局 3D 的布局那几乎可以基于文字独立写篇文章了,这里就不一而足了,有兴趣的可以玩玩位置手册的各种例子:http://www.hightopo.com/guide/guide/core/position/ht-position-guide.html

    构建完图元连线关系,设置完图元风格属性,接下来主要就是图元摆放问题,对于工业控制领域的图元摆放一般是手工进行,所以 Web SCADA 工业控制领域一般会构建一套针对自己产品的 HMI 人机界面绘图工具,可参考《基于HT for Web的Web SCADA工控移动应用》文章:

    对于电信网管拓扑应用,由于网络拓扑图元数据量往往常常非常巨大,虽然 HT 拓扑图组件性能非常强劲,承载好几甚至上十万的网络拓扑矢量图元都毫无压力,但如何实现这么多数据量图元的布局是个问题,如果是规规矩矩的自然比较容易,写两个 for 循环就能实现网格布局,可参考 http://www.hightopo.com/demo/fan/index.html 这个数千个风机的例子,这种例子一般用于能源行业控制系统,通过采用 HT 的矢量格式,可动态控制风机的转速、颜色等参数,来直观形象的表达该风机的运行状态。

    这个例子 http://www.hightopo.com/demo/fan/index.html 并没有针对手机做特别优化,但我特意用 iOS Safari 来跑,不得不说 Safari 10 还是配得上 HT 的这个例子,苹果还是不断努力在提升 HTML5 在其产品线中的性能,并且 Safari 10 号称已经 100% 支持 ES6 标准了,https://developer.apple.com/library/prerelease/content/releasenotes/General/WhatsNewInSafari/Articles/Safari_10_0.html

    The ECMAScript 2015 standard, also known as ES6, is completely supported, bringing this major JavaScript evolution to Safari on macOS and iOS.

    不过更多的电信网管拓扑图应用会采用 HT 的自动布局功能,可参考《HT for Web 自动布局手册》和 《HT for Web 弹力布手册》,利用好自动布局功能可以大大减少项目上线的实施工作量,且电信设备往往需要自动发现动态变化,几乎无法用手工完成这些事情。如果结合华为任正非老大最近的言论 http://finance.sina.com.cn/chanjing/gsnews/2016-09-26/doc-ifxwevmf2247492.shtml ,可以想象将来华为的电信网管拓扑,应该利用其独有的行业网络数据,依靠人工智能来提供自动布局算法布局,好吧,我扯远了刹车回主题。

    其实自动布局无法提供算法进行图元摆放,以便达到业务展示的需求,可参考《电信网络拓扑图自动布局 - 曲线布局》和《电信网络拓扑图自动布局 - 总线布局》,这两篇文章详细分析了如果自定义出总线和沿着任意曲线布局的案例:

    以上创建网络图元、设置图元连线关系、配置图元风格属性、进行图元布局摆放就是构建拓扑图的几个基本步骤,其实熟悉了 HT 分分钟就能开发出像模像样的 HTML5 网络拓扑图应用,如果需要数据存储可参考《HT for Web 序列化手册》,用户可将整个拓扑图序列化成字符串的 JSON 格式内容,这样你可以保存到后台数据库,或者后台服务器文件皆可,HT 只是前端的图形组件,不介入后台通讯和存储,反正控制权在你,不收任何约束,可以随心所欲的设计你的网络拓扑图整体系统架构。

    更多 HTML5 拓扑图例子可参考:http://www.hightopo.com/demos/index.html

    展开全文
  • java学习路线 共勉

    2019-02-06 23:02:10
    下面是从网上找的三幅图片,比较好的说明了作为一个Java程序员的学习路线,我放在这里作为一种自我提醒的工具,不时看看,并且会赶紧修补自己的知识树! 1:Java的知识体系结构 2:JavaWeb开发的基本学习路线 ...

    下面是从网上找的三幅图片,比较好的说明了作为一个Java程序员的学习路线图,我放在这里作为一种自我提醒的工具,不时看看,并且会赶紧修补自己的知识树!
    1:Java的知识体系结构

    在这里插入图片描述

    2:JavaWeb开发的基本学习路线图
    在这里插入图片描述

    3:JavaWeb开发的成长路线图
    在这里插入图片描述

    展开全文
  • 我们学习eclipse 的zest来画拓扑图的入门案例网上有很多,但是它们的特点是,它们的shell的布局都是shell.setLayout(new FillLayout()),而且都是一张拓扑图就占用了整个shell,这显然难以满足我们多样化的需求,比如...

             我们学习eclipse 的zest来画拓扑图的入门案例网上有很多,但是它们的特点是,它们的shell的布局都是shell.setLayout(new FillLayout()),而且都是一张拓扑图就占用了整个shell,这显然难以满足我们多样化的需求,比如我们要用表格布局,并且一个shell上有多个控件,比如有表格、按钮等等,这时候我们显然不能再像入门案例那样将shell的布局设置成shell.setLayout(new FillLayout),而应该将其设置成shell.setLayout(new GridLayout()),在这个布局下,graph.setLayoutAlgorithm(new SpringLayoutAlgorithm(LayoutStyles.NO_LAYOUT_NODE_RESIZING), true)这个容器的布局并没有发挥作用,发现生成的拓扑图都重合到一块儿了,这时要想让生成的拓扑图自动展开,需要在生成所有的node和connection之后调用下这句:graph.applyLayout();这样就可以实现拓扑图按照容器设定的展开模式进行展开了!

     

    展开全文
  • ———————————————————————————————————————————————————— 面试题 第一套 1.hadoop运行原理 包括HDFS和Mapreduce两部分。 1)HDFS自动保存多个副本,移动...
  • 刚接触画拓扑图时没法下手,看个demo吧,让你时半功倍! 使用说明与源代码都在附件里,你也可以到js官网去下载demo,如果不想再找,送点分我,嘎嘎!
  • 我们在绘制流程图时同常会有一种对比心理,,这种心理是一种促进... 虽然使用是没有问题,但是总是感觉人家是大学水平,而我就是小写水平,这样大的反差之下,我决定认真钻研绘制网络拓扑图的绘制方法,在无数此尝...
  • 网络拓扑图本来已经整理有一段时间了,一次项目会议写集中边界监控系统的时候上级要求使用可以在系统中画网络拓扑图,没办法当时找不到现有的程序来参考 只能硬着头皮,顶着风险来完成[当然来边界安全的,当然要安全...
  • 拓扑排序是数据结构的一种操作,他可以表示一些事情可以按照一定的先后顺序执行的算法。在这种中,需要边是有方向的,就是它构成的就是有向,在有向中,顶点只能沿着指定的方向移动,如下所示,就是一个...
  • 课程表就是很常规的那种Java学习的简单路线,首先下就是Java课程学习的一个拓扑顺序: 上面这张图是什么意思呢?黑色的字就代表要学习的课程,而红色的箭头就代表课程学习的拓扑顺序,课程之间是有依赖的,...
  • HT 是啥:Everything you need to create cutting-edge 2D and 3D visualization. 这口号是当年心目中的产品方向,接着就朝这个方向慢慢打磨,如今 HT 算是达到了这样的效果,谈不上用尽洪荒之力,但我们对产品...
  • cut操作是一种布尔操作,cut操作符...下给了例子: 用java操作cut如下: //This creates an instance of the cut operator. //创建cut操作的句柄 OperatorCut opCut = OperatorCut.local(); /* * considerT
  • 流程 1.定义:流程是对过程、算法、流程的一种图像表示,在技术设计、交流及商业简报等领域有广泛的应用。 2.案例3.计算机语言只是一种工具。光学习语言的规则还不够,最重要的是学会针对各种类型的问题,拟定出...
  •  你是否曾经有过类似实现网络拓扑图的需求,网上搜索相关的资源后。要么简单数语概括下大体结构,要么就是成熟的收费商业产品。而少数为学习开源的几个也大都是基于IE浏览器的。因此笔者就产生了写一个能够兼容主流...
  • 拓扑排序Java实现

    2018-07-29 14:29:57
    概念:拓扑排序概念 原文:简短介绍及原始代码 本文对比原文,对其代码增加了更多注释。 package com.qf.greaph; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import ...
1 2 3 4 5 ... 20
收藏数 8,417
精华内容 3,366