`
xiaozhonghua
  • 浏览: 250659 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

瞧咱办公室的拓扑图

阅读更多

前几天的《Swing版小小网管》让我想起前阵子做过的一个企业网管项目。客户是一个工厂,搞生产制造的。人并不多,四、五十人,多数是车间工人。办公室的也就二十多人,网络结构并不复杂:ADSL宽带接入,加上几个AP进行信号扩展;台式机、服务器、笔记本电脑,加上零星的手机上网,仅此而已。大伙知道:做企业网管是比较艰难的,工作量大,吃力不讨好,竞争激烈,卖不了几个钱,不容易啊!但是为了能够在项目中多点筹码,界面还是要做的精益求精才行。

 

先到工厂详细调研了网络结构图,并绘制了一个简单的草图结构(不好意思,写字越来越难看了,还不如我小学时候的水平,都是电脑键盘给害的哈):


 

 

其中ADSL和几个无线AP是网络主干,各个办公室的结构都是星形结构,通过网线进行汇聚,通过AP进行互联。我问工厂的车间主任为啥这样搞,他说使用AP的原因是工厂正在进行改造,几个办公室之间距离较远,隔着一个大院子,网线铺设不便;另外几个车间里头也有电脑需要联网,在嘈杂混乱火星直冒的车间里头,弄网线就更麻烦了。

 

要在网管里面呈现和监控这个网络,对俺来说不算难事。不过我需要一个好看一点的流量监控的图表。首先通过SNMP获取AP中的iftable中的端口,并获取其实时流量,然后放置在拓扑图的link对象中。为了不给网络造成太多负担,网管默认每5秒钟获取一次数值,并存储连续100个数值,多余的抛弃。

 

绘制chart的图并不复杂,整个chart呈一个长矩形状,分为三段(老、中、轻),用不同的颜色进行渲染。

 

 

public void paintIcon(Component c, Graphics g, int x, int y) {
    Graphics2D g2d = (Graphics2D) g;

    Rectangle bounds = getBounds();

    g2d.setColor(background);
    g2d.fill(bounds);

    Point location = bounds.getLocation();
    int startX = location.x;
    int startY = location.y + chartHeight;
    GeneralPath path = new GeneralPath();
    path.moveTo(startX, startY);

    int[] values = getChartDataValues();

    for (int i = 0; i < values.length; i++) {
        path.lineTo(startX + i, startY - values[i]);
    }
    path.lineTo(startX + chartWidth, startY);
    path.closePath();

    g2d.setColor(chartColor1);
    g2d.fill(path);

    //clip center part, paint with color2.
    Shape oldClip = g2d.getClip();
    Rectangle clip = new Rectangle(bounds.x + chartWidth / 4, bounds.y, chartWidth / 2, chartHeight);
    g2d.setClip(clip);
    g2d.setColor(chartColor2);
    g2d.fill(path);
    g2d.setClip(oldClip);

    g2d.setColor(Color.lightGray);
    g2d.draw(bounds);

    g2d.setColor(Color.darkGray);
    g2d.setFont(font);

    int textX = location.x + 5;
    int textY = location.y + chartHeight / 2 + font.getSize() / 2;
    g2d.drawString("Sum", textX, textY);

    int speed = 100;
    if (getElementUI().getElement() instanceof MyLink) {
        speed = ((MyLink) getElementUI().getElement()).getSpeed();
    }
    String text = NumberFormat.getInstance().format(speed) + " kbit/s";
    Rectangle2D textBounds = g2d.getFontMetrics().getStringBounds(text, g2d);
    textX = (int) (location.x + chartWidth - textBounds.getWidth() - 5);
    g2d.drawString(text, textX, textY);
}

 

 显示效果如下:


 

另外,对连线的效果也进行了一些处理。用直线连接无疑太土气了,来点曲线增加一点趣味。曲线用一个对称的抛物线来处理,根据不同的角度进行自动调整:

 

 

public GeneralPath getPath() {
    Point from = this.getFromPoint();
    Point to = this.getToPoint();
    Point middle = new Point((from.x + to.x) / 2, (from.y + to.y) / 2);
    boolean wider = (Math.abs(from.x - to.x) > Math.abs(from.y - to.y));
    GeneralPath myPath = new GeneralPath();
    myPath.moveTo(from.x, from.y);
    if (wider) {
        myPath.quadTo(middle.x, from.y, middle.x, middle.y);
        myPath.quadTo(middle.x, to.y, to.x, to.y);
    } else {
        myPath.quadTo(from.x, middle.y, middle.x, middle.y);
        myPath.quadTo(to.x, middle.y, to.x, to.y);
    }

    return myPath;
}

 

其实我发现,虽然咱写程序的号称数学都必须很非常贼NB,可是真正的几何和数学真的都忘的差不多了,不知道你还能不能随手写下二次方程的根,椭圆的几何方程,或者球体的面积公式?反正我是不行了。
 
不管咋说,俺还是九牛二虎之下整出了几个花里胡哨的path出来。毫无技术含量,你可别被俺忽悠了:

接下来,再把SNMP获得的数据放入link中的chart呈现。为了避免泄密的麻烦,附件的demo俺去掉了这些业务代码,用一个thread模拟代替了:

    Thread thread = new Thread() {

        private Vector links = null;

        private Vector getLinks() {
            if (links == null) {
                links = new Vector();
                Iterator it = network.getDataBox().iterator();
                while (it.hasNext()) {
                    Object o = it.next();
                    if (o instanceof MyLink) {
                        MyLink link = (MyLink) o;
                        links.add(link);
                    }
                }
            }
            return links;
        }

        @Override
        public void run() {
            while (true) {
                Iterator it = getLinks().iterator();
                while (it.hasNext()) {
                    Object o = it.next();
                    if (o instanceof MyLink) {
                        MyLink link = (MyLink) o;
                        createRandomValue(link);
                        if (TWaverUtil.getRandomInt(10) == 1) {
                            link.setSpeed(TWaverUtil.getRandomInt(10000));
                        }
                    }
                }
                try {
                    Thread.sleep(100);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }

        private void createRandomValue(MyLink link) {
            int value = link.getLastChartValue();
            int change = TWaverUtil.getRandomInt(3) - 1;
            value = value + change;

            value = Math.min(value, 100);
            value = Math.max(value, 0);

            link.addChartValue(value);
        }
    };
    thread.start();
}
 
 再到google上物色几个清爽的图标。


对了,在结束之际,突然想起一件事:AP上的晃悠悠的电线丝,可不是icon的一部反,而是咱draw上去的!这个小亮点咱得说说:主要思路就是new一个path,模拟其曲线的路径,然后在Swing的paint时候给附加上去。代码如下:

 

    @Override
    public void paintBody(Graphics2D g2d) {
        super.paintBody(g2d);

        if (((MyNode) getElement()).isWireVisible()) {
            Object oldValue = g2d.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setColor(wireColor);
            g2d.setStroke(TWaverConst.BASIC_STROKE);
            g2d.draw(createWireShape());
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, oldValue);
        }
    }

    private Shape createWireShape() {
        Point point = this.getHotspot();
        int x = point.x - 25;
        int y = point.y + 23;

        GeneralPath path = new GeneralPath();
        path.moveTo(x, y);
        path.curveTo(x + 20, y - 20, x + 50, y - 10, x + 48, y);
        path.curveTo(x + 48, y + 15, x + 10, y + 10, x + 12, y - 5);
        path.curveTo(x + 12, y - 20, x + 50, y - 20, x + 53, y);
        path.quadTo(x + 53, y + 3, x + 51, y + 5);
        return path;
    }

这下终于完整了。看看“晃悠悠的铁丝”效果:




 
接下来,在程序里面整合一下,整个效果就出来了:

 

 


 

为了和大家共同学习和交流,附上的源代码是从项目中抽取了Swing展示部分,去掉了所有业务逻辑,仅仅为了和大家共享Swing的展示能力,以及拓扑图的制作思路。虽然不是惊世骇俗美轮美奂,但是俺比较喜欢这种简洁、清新的风格。

 

老规矩,有代码共享。在这里可以下载全部源代码、可执行文件、图标资源等内容

 

祝大家编程愉快!

  • 大小: 200.9 KB
  • 大小: 689 Bytes
  • 大小: 7.5 KB
  • 大小: 57.2 KB
  • 大小: 121.7 KB
  • 大小: 28.5 KB
分享到:
评论
30 楼 YTT1121 2016-06-14  
楼主,终于找到大神了,求物理网络拓扑发现的源代码,有偿。请联系18932900205,邮箱641251443@qq.com ,学术算法用。谢谢啦。
29 楼 ag_sherry 2011-02-17  
老大,没得源码了,求码。。。
28 楼 zhulin 2010-12-21  
代码好像没有了,现在变成广告了,也太不厚道了
27 楼 rabbitbug 2010-09-02  
不错啊,goooooooooooood
26 楼 xiaozhonghua 2010-09-02  
Now7! 写道
设备之间的曲线连接用自带的3次曲线会更圆滑一些,
private CubicCurve2D.Float createCC2d(float x1, float y1, float x2, float y2)
	{
		CubicCurve2D.Float cc2d = new CubicCurve2D.Float();
		Point2D.Float[] pts = new Point2D.Float[4];
		pts[0] = new Point2D.Float(x1,y1);
		pts[3] = new Point2D.Float(x2,y2);
		pts[1] = new Point2D.Float(x1+(x2-x1)*3/5, y1-(y2-y1)/4);
		pts[2] = new Point2D.Float(x1+(x2-x1)*2/5,y2+(y2-y1)/4);
		cc2d.setCurve(pts, 0);
		return cc2d;
	};

使用的话也是直接draw()就好了:
CubicCurve2D.Float cc2d = createCC2d(160.0f, 30.0f, 30.0f, 120.0f);
g2.draw(cc2d);

哈哈,厉害啊,高手!
25 楼 pior 2010-09-02  
说实在的··还是手绘的漂亮··

24 楼 kingwood2005 2010-09-02  
Nice,看来做的还可以!
23 楼 沈冠军 2010-09-02  
牛,以后可以借鉴一下
22 楼 Now7! 2010-09-01  
设备之间的曲线连接用自带的3次曲线会更圆滑一些,
private CubicCurve2D.Float createCC2d(float x1, float y1, float x2, float y2)
	{
		CubicCurve2D.Float cc2d = new CubicCurve2D.Float();
		Point2D.Float[] pts = new Point2D.Float[4];
		pts[0] = new Point2D.Float(x1,y1);
		pts[3] = new Point2D.Float(x2,y2);
		pts[1] = new Point2D.Float(x1+(x2-x1)*3/5, y1-(y2-y1)/4);
		pts[2] = new Point2D.Float(x1+(x2-x1)*2/5,y2+(y2-y1)/4);
		cc2d.setCurve(pts, 0);
		return cc2d;
	};

使用的话也是直接draw()就好了:
CubicCurve2D.Float cc2d = createCC2d(160.0f, 30.0f, 30.0f, 120.0f);
g2.draw(cc2d);
21 楼 meiowei 2010-09-01  
不会swing,只能来瞅瞅
20 楼 kxys422834 2010-09-01  
xx,真牛叉!!!我也要学!
19 楼 xiaozhonghua 2010-09-01  
幻无极 写道
源代码太隐蔽了,前面没加源代码几个字,不小心就没看到

哈哈确实有这个问题!修改了大字体!
18 楼 xiaozhonghua 2010-09-01  
sulifeng 写道
我这里显示的也不是我的宿舍楼的拓扑图......................呵呵...........

呵呵,很抱歉不少兄弟误会了,意味程序会自动发现拓扑结构,其实这几个类文件不可能这么牛B啦,仅仅是呈现而已;自动发现还是要靠前面的《小小网管》相关的技术来结合才行哈。
17 楼 shuiguozheng 2010-09-01  
qianlei007 写道
太强大了。。

  还行吧,不错!
16 楼 sulifeng 2010-09-01  
我这里显示的也不是我的宿舍楼的拓扑图......................呵呵...........
15 楼 幻无极 2010-08-31  
源代码太隐蔽了,前面没加源代码几个字,不小心就没看到
14 楼 zhoujiansong 2010-08-31  
顶一个!!!
13 楼 runshine 2010-08-31  
老大啊,五体投地啊
PopupMenu要漂亮有什么好的建议没?
是重绘PopupMenu还是干脆用frame模拟一个?
12 楼 晨星★~雨泪 2010-08-31  
仅仅为了和大家共享Swing的展示能力


原来是这样
11 楼 晨星★~雨泪 2010-08-31  
源码找得好辛苦啊

相关推荐

Global site tag (gtag.js) - Google Analytics