Twaver demo

TWaver中有一个平行四边形的Group对象,适合做上图中的“层”的概念。先如下封装并设置属性:

  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.     }  


通过这个简单的封装,再往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>");  

以上代码封装了创建一个层的函数,给定颜色、坐标位置、内部节点数量、图标、文字等等。上面代码中的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. }  

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

 

四层复杂拓扑图显示效果

 

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

Java代码   收藏代码
  1. 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. }  

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

 

跨层连线效果

 

图中跨层的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. }  

 

这里代码的逻辑主要是判断是不是跨层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. }  

 

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

 

猜你喜欢

转载自435870628.iteye.com/blog/1626037
今日推荐