[tr][td]
某市政项目要用到地铁图,展示上海地铁站点以及相关信息流,尝试使用HTML5技术来实现,自己折腾有点慢,找到一个HTML5的图形组件-Qunee for HTML5,简单学习一下,就可以很好的解决这类需求,做出优美的展现,下面以上海2012地铁图为例,效果如下: 图片:0918172tut4g4s42gymuwh.jpg 示例讲解 首先需要解决数据问题,可以从维基百科或者上海地铁官网中获取,不过也免不了人工,要达到良好的显示效果,需要不只要记录站点的位置,还需要设置文本标签的理想位置,有时为了避免文字叠加,需要设置旋转角度……总之事在人为,想想办法,最终解决了数据问题,再加上Qunee图形组件的强大展示效果,做出来可以交互的在线地铁图 数据格式 采用JSON格式数据,分三种类型:文本标签、站点、地铁线 总的结构如下: [*]{ [*]"labels" : [ ... ], [*]"stations" : [ ... ], [*]"lines" : [ ... ] [*]} 复制代码 文本标签数据 包含坐标和文字信息,如果文字需要旋转,则会增加”rotate”属性,下面是“莘庄”文本标签信息 [*]{ [*]"text" : "莘庄", [*]"x" : 883.591, [*]"y" : 1625.695 [*]} 复制代码 文字与节点旋转效果 图片:0918172tut4g4s42gymuwh.jpg 站点数据 包含坐标、旋转角度以及编号信息,下面是“莘庄”站的信息 [*]{ [*]"id" : 5, [*]"x" : 869.8513512641732, [*]"y" : 1597.6559686949402, [*]"rotate" : 0.7853981633974483 [*]} 复制代码 地铁线数据 包含名称,颜色,以及经过的站点编号 [*]{ [*]"name" : "1", [*]"color" : "#e52035", [*]"stations" : [64, 70, 67, 71, 72, 65, 69, 73, 66, 68, 63, 62, 22, 61, 60, {"id": 21, "yOffset": 0.5}, 59, {"id": 18, "yOffset": -0.5}, 17, 58, 14, 7, 57, 6, [*]56, 44, 47, 5] [*]} 复制代码 对于特殊情况,比如两条地铁线共用一条线路的情况,会出现两条线重合,为了避免这种情况,还可以指定站点横向偏移量,比如上面一号线中的如下数据 [*]{"id": 21, "yOffset": 0.5} 复制代码 因为上海地铁三号线与四号线共用线路较多,所以这种处理更加明显 三号线数据 [*]{ [*]"name" : "3", [*]"color" : "#f9d300", [*]"stations" : [6, 95, 96, 97, {"id":12,"yOffset":0.5}, {"id":11,"yOffset":0.5}, {"id":8,"yOffset":0.5}, {"id":9,"yOffset":0.5}, [*]{"id":10,"yOffset":0.5}, {"id":25,"yOffset":0.5}, {"id":26,"yOffset":0.5}, {"id":238,"yOffset":0.5}, {"id":22,"yOffset":-0.5}, {"id":27,"yOffset":-0.5}, [*]98, 99, 100, 101, 104, 105, 107, 108, 109, 106, 110, 111] [*]} 复制代码 地铁共线效果 图片:0918172tut4g4s42gymuwh.jpg 创建图元 数据需要转换成qunee图元对象,三种类型分别对应三个创建函数 创建文本标签 [*]function createText(name, x, y, rotate){ [*] var text = graph.createNode(name, x, y); [*] if(rotate){ [*] text.rotate = rotate; [*] } [*] text.zIndex = 20; [*] text.image = null; [*] text.setStyle(Q.Styles.BACKGROUND_COLOR, Q.toColor(0x88FFFFFF)); [*] text.setStyle(Q.Styles.LABEL_ANCHOR_POSITION, Q.Position.LEFT_BOTTOM); [*] text.setStyle(Q.Styles.LABEL_POSITION, Q.Position.CENTER_MIDDLE); [*] text.setStyle(Q.Styles.LABEL_PADDING, PADDING); [*] return text; [*]} 复制代码 创建站点 [*]function createStation(station){ [*] var node = graph.createNode(null/**station.name*/, station.x, station.y); [*] node.stationId = station.id; [*] node.setStyle(Q.Styles.LABEL_FONT_SIZE, 10); [*] node.setStyle(Q.Styles.LABEL_ANCHOR_POSITION, Q.Position.CENTER_MIDDLE); [*] node.setStyle(Q.Styles.LABEL_POSITION, Q.Position.CENTER_MIDDLE); [*] node.zIndex = 10; [*] if(station.rotate){ [*] node.image = roundRect; [*] node.rotate = station.rotate; [*] }else{ [*] node.image = circle; [*] } [*] node.setStyle(Q.Styles.SHAPE_FILL_COLOR, "#FFF"); [*] node.setStyle(Q.Styles.SHAPE_STROKE_STYLE, "#000"); [*] return node; [*]} 复制代码 创建地铁线 createLine(…)函数用于创建地铁线,使用了节点类型图元,并设置节点主体为路径,函数updateLine(…)用于从站点信息自动生成线路路径 [*]function createLine(line){ [*] var stations = line.stations; [*] [*] var node = graph.createNode(line.name); [*] node.stations = stations; [*] node.movable = false; [*] node.setStyle(Q.Styles.LABEL_FONT_SIZE, 50); [*] node.setStyle(Q.Styles.LABEL_COLOR, line.color); [*] node.setStyle(Q.Styles.LABEL_ANCHOR_POSITION, Q.Position.LEFT_BOTTOM); [*] node.setStyle(Q.Styles.LABEL_POSITION, Q.Position.LEFT_TOP); [*] node.setStyle(Q.Styles.LAYOUT_BY_PATH, true); [*] node.anchorPosition = null; [*] node.setStyle(Q.Styles.SHAPE_STROKE, size); [*] node.setStyle(Q.Styles.SHAPE_STROKE_STYLE, line.color); [*] [*] updateLine(node, true); [*] return node; [*]} 复制代码 [*]function updateLine(line, addListener){ [*] var path = new Q.Path(); [*] line.image = path; [*] [*] var stations = line.stations; [*] var first = true; [*] Q.forEach(stations, function(s){ [*] var station = getStation(s.id || s); [*] if(!station){ [*] return; [*] } [*] if(addListener){ [*] addLocationChangeListener(station.stationId, line); [*] } [*] var location = station.location; [*] var x = location.x, y = location.y; [*] if(s.yOffset){ [*] var offset = s.yOffset * size; [*] var rotate = station.rotate || 0; [*] var sin = Math.sin(rotate); [*] var cos = Math.cos(rotate); [*] x += cos * offset; [*] y += sin * offset; [*] } [*] if(first){ [*] first = false; [*] path.moveTo(x, y); [*] }else{ [*] path.lineTo(x, y); [*] } [*] }) [*]} 复制代码 交互处理 增加交互处理,监听站点拖动事件,保持地铁路线跟随站点位置变化 [*]graph.interactionDispatcher.addListener(function(evt){ [*] if(evt.kind != Q.InteractionEvent.ELEMENT_MOVING){ [*] return; [*] } [*] var datas = evt.datas; [*] [*] Q.forEach(datas, function(data){ [*] if(!data.stationId){ [*] return; [*] } [*] var listeners = stationLocationChangeListeners[data.stationId]; [*] if(listeners){ [*] for(var l in listeners){ [*] updateLine(listeners[l]); [*] } [*] } [*] }); [*]}); 复制代码 在线示例 来源:http://blog.chinaunix.net/uid-29563534-id-4171575.html [/td][/tr] |
|