8

两个月前(是的,两个月过去了,岁月如梭),哥帮小弟做的“HTML5魔都地铁拖拖乐”打了下广告,没想到一炮而红,好评如潮。现在的年轻人,还是很上进的,一被表扬,动力无穷。年底虽然忙得眼底发黑,小弟硬是忙里偷闲又做了一个帝都的版本。

这个版本,不光是换成了帝都的地铁图,还增加了很多听起来就很能“变现”的功能:线路规划、站点告警展示、站点内部电路图、站点三维呈现……在这个信息过剩的年代,多数人都是涉猎很广却学而不精,小弟这种对问题进行深度挖掘的精神,哥真的很佩服。

------------------------------------------------下面进入正题-----------------------------------------------------------

一些基本功能这里不再赘述,大家可以查看上一篇有关魔都地铁图的文章。哥今天主要给大家介绍新增功能。

我们先来看一下小弟做的帝都地铁图的效果,基本上是参照baidu的地铁图来复现的:

图片描述

依然是纯矢量、可交互、有动态效果、无失真缩放的拓扑图:
图片描述

可视化效果具体就不展开了,拿到过拖拖乐的兄弟们都了解。下面主要还是说说这次新增的功能点,怎么形容呢?杀很大噢~

选中线路会发光

鼠标点击某条地铁线路,选中的线路会以发光的形式突出显示出来。

图片描述

小弟说之所以要增加这个功能,是因为现在的地铁线路太多了,想查看单条线路的时候经常会看串……也是,虽然交通部门在设计地铁线路图的时候已经尽量用不同的颜色去标注每条线路,但是挡不住地铁十几二十条地往上加,要想查看单条线路还真是费劲。有了这个功能,顿时清爽了很多有木有? 哥必须为这个功能点个赞……

实现代码其实很简单:

function changeAlpha(lineNumber,alpha){
        alpha = alpha || 1;
        var list = lines[lineNumber];
        list.forEach(function(li){
            li.setStyle('whole.alpha',alpha);
            li.s('outer.style', alpha < 1 ? 'none':'glow');
            li.s('label.shadowable', alpha >= 1 );
        });
        list = stations[lineNumber];
        list.forEach(function(li){
            li.setStyle('whole.alpha',alpha);
            li.s('outer.style', alpha < 1 ? 'none':'glow');
            li.s('label.shadowable', alpha >= 1 );
        });
    }

为啥这么好的想法,地图厂商都不提供呢?如果你对仍然体会不是很深刻的话,看看下面这张图,相信你会觉得这个功能是多么赏心悦目……

图片描述

高亮显示两站点间的路线

用鼠标右键点击同一条线路上的两个站点,这两个站点之间的路线会高亮显示。小弟说,从用户角度来说,这个功能可以用来进行路线的规划。不过一般我们不会在前端做路线规划,只需要把计算好的路线结果显示出来就可以了。小弟做这个功能的另一个目的是为了方便运维人员查看某一段线路上的告警站点。

图片描述

告警站点一目了然

说到告警,才进入了这次的重点。

地铁因运量大、速度快、无堵车等优点,已经成为众多上班族的首选出行方式。一旦地铁发生故障,会导致大量乘客滞留。因此,对于地铁运维人员来说,能够快速发现故障站点并及时排除故障就显得尤为重要。

我们可以看到,小弟做的这张帝都地铁图,与普通地铁图最大的不同是上面增加了许多五颜六色的告警标识,告警站点一目了然,上面还标明了告警的数量以及告警级别。这样,地铁运维人员就可以快速掌握各地铁站点的告警情况,合理安排故障排查的优先级。

图片描述

因为我们公司是做企业应用的嘛,这个功能是很容易放上去的,代码也不复杂。

Util.addAlarm("alarm" + p['-sid'], n, twaver.AlarmSeverity.severities.get(random), box.getAlarmBox(),random);
addAlarm: function (alarmID, staNode, alarmSeverity, alarmBox,random) {
  var alarm = new twaver.Alarm(alarmID, staNode.getId(), alarmSeverity);
  alarm.setClient("MAPPINGID",this.alarmCode[random]);
  alarm.setClient("raisedTime",new Date());
  alarm.setClient("platform",staNode.getName());
  alarm.setAcked(Math.random()* 10 > 5? true:false);
  alarmBox.add(alarm);
}                             

轨线告警数据展示

双击一条线路,会弹出该线路的所有告警数据,包括告警站台、告警级别、告警发生时间等详细信息。这里用的是现成的表格组件。

图片描述

实现也很简单,首先两行代码将表格和DataBox关联:

var table = new twaver.controls.Table(box.getAlarmBox());
var tablePane = new twaver.controls.TablePane(table);

然后用以下代码实现:

    var alarmSeverity = {
        Critical: "严重",
        Major:'主要',
        WARNING:'警告',
    } 
    table.onCellRendered = function (params) {
        if (params.column.getName() === '告警级别') {
            params.div.style.backgroundColor = params.data.getAlarmSeverity().color;
        }
    };
    var column = createColumn(table, '站台', 'platform', 'client', 'string',100,40);
    column.setHorizontalAlign('center');
    var column = createColumn(table, '告警级别', 'alarmSeverity', 'accessor', 'string', true);
    column.setWidth(80);
    column.setHorizontalAlign('center');
    var setValue = column.setValue;
    column.setValue = function (data, value, view) {
        value = twaver.AlarmSeverity.getByName(value);
        setValue.call(column, data, value, view);
    };
    column.setEnumInfo(twaver.AlarmSeverity.severities.toArray());
    var column = createColumn(this.table, '告警码', 'MAPPINGID', 'client','string',166);
    column.setHorizontalAlign('center');
    var column = createColumn(this.table, '告警问题', 'alarmque', 'client');
    column.setHorizontalAlign('center');
    var timeColumn = createColumn(table, '告警发生时间', 'raisedTime', 'client');
    timeColumn.setWidth(167);
    timeColumn.setHorizontalAlign('center');
    timeColumn.renderCell = function (params) {
        var span = document.createElement('span');
        span.innerHTML = formatDate(params.value, 'yyyy-MM-dd hh:mm:ss');
        span.style.whiteSpace = 'nowrap';
        params.div.appendChild(span);
    }
}

站点信息展示

单击站点,会弹出一个功能菜单,现在有展示、告警、电路等模块。小弟说还可以根据需要,定制更多功能模块,全方位展示站点信息。我们一一来看几个菜单都展示了些啥。

图片描述

单个站点告警

点击“告警”,弹出站点告警数据,还可以查看该站点的历史告警数据。

小弟说,前几天他去看了一个很高大上的轨道交通技术展会,了解到每个站点内就有大量的设备,像电力设备、环控设备、屏蔽门设备、电梯设备、门禁设备、广播和闭路电视设备、通讯设备等等。因此,每个站点也必须要有集中的告警展示。当然,现在做的还比较简单,如果有真实数据,就能做得更好看了,反正菜单定义都很方便。

图片描述

站点内部拓扑图展示

地铁里的通信系统还是比较复杂的,据我了解,除了有专用的通信系统外,还要提供民用的通信系统,以及专用的电源管理、广播、视频监控等等子系统。这就必须要咱们擅长的拓扑图上场了。

图片描述

点击“图纸”按钮,弹出站点内部设备的拓扑图。所有的图元都可以拖拽、缩放,告警、分组这些该有的功能都有,如果拓扑图有多个层级,不停往下加layer就好了。

代码稍复杂:


button.onclick = function (e) {
    var dialog = document.getElementById(id);
    dialog && document.body.removeChild(dialog);
    var box2 = new twaver.ElementBox();
    var network2 = new twaver.vector.Network(box2);
    var view = network2.getView();
    var autoLayouter = new twaver.layout.AutoLayouter(box2);
        // network2.setZoomManager(new twaver.vector.MixedZoomManager(network2,false));
        var items = Util.topo_data;
        var i,item;
        for(i = 0;i < items.length; i++){
            item = items[i];
            Util.createElement(box2, item);
        }
        var self = this;
        var hGap=80;
        autoLayouter.getDimension=function (node) {
            if (node instanceof twaver.Group && node.getChildrenSize() > 0) {
                var rect = null;
                for (var i = 0, n = node.getChildrenSize(); i < n; i++) {
                    var child = node.getChildAt(i);
                    if (child instanceof twaver.Node) {
                        if (rect) {
                            rect = _twaver.math.unionRect(rect, child.getRect());
                        } else {
                            rect = child.getRect();
                        }
                    }
                }
                if (rect) {
                    return { width: rect.width+hGap, height: rect.height };
                } else {
                    return null;
                }
            } else {
                return { width: node.getWidth()+hGap, height: node.getHeight() };
            }
        },
        autoLayouter.doLayout('hierarchic', function(){
            network2.zoomOverview();
        });
        var left = e.clientX, top = e.clientY;
        var width = 760, height = 360;
        Util.showTopo('dialog_topo',element,network2,width+"px",height+"px",'260px','0px','图纸');
        Util.changeState();
        $('#dialog_topo').animate({
            top:'100px',
        },'normal','swing',function(){
        });
    }

站点三维展示

这个功能可谓是很赶时髦的,点击“展示”模块,跳出当前站点的三维展示图,重点标识了几个出口的位置。

图片描述

小弟说现在地铁站的出口示意图一般都是平面图,或者是假3D图,身边有些妹子经常表示看不太懂,尤其在一些比较复杂的换乘站点,所以整了个3D示意图,还可以任意角度旋转、缩放什么的。整个过程我的注意力就被“妹子”吸引了,不得不说为了妹子,小弟的这个地铁站可是像模像样的。

模型内部也可以进入,用来展示一些消防用具的位置。不过这地铁内部,我越看越觉得像某部丧尸片呢……

图片描述

电路展示

最后,点击“电路”模块,弹出站点内部电路图。如果对接上地铁的供配电系统,那还是这个展示平台上相当不错的一个亮点。

图片描述

功能介绍到这里就基本结束了。

总结一下,上次小弟主要是在可视化方面下了功夫,而这次是从乘客、监控和运维的角度去设计的功能。尽管很多功能只是点到为止,但真要在实际项目中用起来,相信又是一个亮点工程了。

2016总结

看到今天sfgg有2016总结活动呢,那哥也来总结一把。

还得先说2015年,哥初来sfgg,斗胆发了几篇文章,认识了不少朋友,也给了不少建议。2016年,项目进展顺利,很多精力都投入在非技术领域,自然文章也写的不勤快了。除了一篇3D机房的文章,后来就开始沾我小弟的光了。不过这也没啥,江山代有小弟出,团队就怕缺牛人。从技术走向管理的路,大多也是如此吧。

最后祝大家:

<!DOCTYPE html> 
<html> 
<head> 
<title></title> 
<body> 
<p>Happy New Year!</p> 
</body> 
</html> 

索取代码照旧:tw-service@servasoft.com


MonoLog
2.9k 声望727 粉丝

专注UI,最近关注HTML5,以及webGL 3D,欢迎一起探讨。