HTML5绘制上海地铁线路图-html5绘图功能

某市政项目用到地铁图展示,展示地铁站点以及相关信息流,使用Qunee组件可以很好的解决这类需求,做出优美的展现,下面以上海2012地铁图为例,效果如下: 示例讲解 首先需要解决数据问题,可以从维基百科或者上海地铁官网中获取,不过也免不了人工,要达到良

某市政项目用到地铁图展示,展示地铁站点以及相关信息流,使用Qunee组件可以很好的解决这类需求,做出优美的展现,下面以上海2012地铁图为例,效果如下:
 

HTML5绘制上海地铁线路图-【科e互联】

 

示例讲解

首先需要解决数据问题,可以从维基百科或者上海地铁官网中获取,不过也免不了人工,要达到良好的显示效果,需要不只要记录站点的位置,还需要设置文本标签的理想位置,有时为了避免文字叠加,需要设置旋转角度……总之事在人为,想想办法,最终解决了数据问题,再加上Qunee图形组件的强大展示效果,做出来可以交互的在线地铁图

 

数据格式

采用JSON格式数据,分三种类型:文本标签、站点、地铁线
总的结构如下:

{
"labels" : [  ... ],
"stations" : [ ... ],
"lines" : [ ... ]
}

 

文本标签数据

包含坐标和文字信息,如果文字需要旋转,则会增加”rotate”属性,下面是“莘庄”文本标签信息

{
"text" : "莘庄",
"x" : 883.591,
"y" : 1625.695
}

文字与节点旋转效果
 

HTML5绘制上海地铁线路图-【科e互联】

 

站点数据

包含坐标、旋转角度以及编号信息,下面是“莘庄”站的信息

{
"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]
}

地铁共线效果
 

HTML5绘制上海地铁线路图-【科e互联】

创建图元

数据需要转换成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://demo.qunee.com/#Shanghai Metro Map 2012

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

1、htmlshiv.js Remy开发的HTML5shiv工具能利用JavaScript在老式IE里创建main,header,footer等HTML5元素。也就是说使用JavaScript能创建这些本来不存在的HTML5新元素。这是什么原理?你可能花几天也想不明白,但谁在意呢!这个脚本几乎是所有正式网站必用
HTML5 火的正热,最近有个想法也是要用到HTML的相关功能,所以也要好好学习一把。 好好看了一下Canvas的功能,感觉HTML5在客户端交互的功能性越来越强了,今天看了一下Canvas绘图,下边是几个实例,记下以备后用。 1、使用Canvas绘制直线: !doctype html ht
响应式布局,理想状态是,对PC/移动各种终端进行响应。媒体查询的支持程度是IE9+以及其他现代的浏览器,但是IE8在市场当中仍然占据了比较大量的市场份额,使我们不得不进行IE低端浏览器的考虑。那么如何在IE6~8浏览器中兼容响应式布局呢?这里我们需要借助这
近日,微软宣布开源Chakra的核心组件。Chakra是微软新一代浏览器 Microsoft Edge的JavaScript引擎。相关代码将于2016年1月上传到微软的GitHub账号,项目名称为 ChakraCore,遵循MIT许可协议。 ...,HTML5中国,中国最大的HTML5中文门户。
这篇文章报道的不是“新闻”,因为W3C早已开始着手CSS变量方面的工作。至于Google,则要追溯到11月初,当时该公司主要开发人员之一的Addy Osmani宣布了率先在Chrome Canary中引入对CSS变量的支持。 ...,HTML5中国,中国最大的HTML5中文门户。
25年后,你发的编程知识经验还会增加,但薪水却不加了;25年后,如果你还热爱编程便不会选择转行去当管理人员;25年后,你想和好友去玩耍,而经理却让你加班;那么你是否想过这25年之间做出另一种选择呢? ...,HTML5中国,中国最大的HTML5中文门户。