锁定老帖子 主题:瞧咱办公室的拓扑图
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2010-08-31
最后修改:2010-09-01
前几天的《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的展示能力,以及拓扑图的制作思路。虽然不是惊世骇俗美轮美奂,但是俺比较喜欢这种简洁、清新的风格。
老规矩,有代码共享。在这里可以下载全部源代码、可执行文件、图标资源等内容。
祝大家编程愉快! 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-08-31
思路不错,呵呵,借用一下放到项目中,多谢
|
|
返回顶楼 | |
发表时间:2010-08-31
很好,怎么显示的不是我办公室的拓扑图
|
|
返回顶楼 | |
发表时间:2010-08-31
来看看, 呵呵, 关注小中华, 关注swing。
|
|
返回顶楼 | |
发表时间:2010-08-31
好思路,清晰简洁
|
|
返回顶楼 | |
发表时间:2010-08-31
3eee 写道 很好,怎么显示的不是我办公室的拓扑图
我这里显示的也不是我办公室的拓扑图 |
|
返回顶楼 | |
发表时间:2010-08-31
艹。太崇拜lz了
|
|
返回顶楼 | |
发表时间:2010-08-31
很强打。。。。。。
|
|
返回顶楼 | |
发表时间:2010-08-31
太强大了。。
|
|
返回顶楼 | |
发表时间:2010-08-31
我的也没有显示我的网络图
|
|
返回顶楼 | |