TWaver初学实战——基于HTML5的交互式地铁图
每天坐地铁,经常看地铁图,有一天突然想到,地铁图不也是一种拓扑结果吗?TWaver到底能与地铁图擦出怎样的火花呢?

我们就以上面这幅地铁图为模版来进行制作。
一、数据整理
1. 数据结构
- {
- "stations":{
- "l01s01":{ },
- …………
- }
- "lines":{
- "l01":{……},
- …………
- }
- "sundrys":{
- "railwaystationshanghai":{……},
- …………
- }
- }
2. 站点数据
- "l01s01":{
- "id":"l01s01",
- "name":"莘庄",
- "loc":{"x":419,"y":1330},
- "label":"bottomright.bottomright",
- },
- …………
3. 线路数据
- "l01":{
- "id":"l01",
- "name":"1号线",
- "color":"#e52035",
- "stations":{
- "l01s01":"l01s01",
- "l01s02":"l01s02",
- ……
- }
- },
- ……
4. 杂项数据
- "airporthongqiao":{
- "sign":"airport",
- "station":"l02s20",
- "name":"虹桥国际机场",
- "offset":{"x":0, "y":-1}
- },
- ……
二、站点创建
1. 文件导入
- function loadJSON(path,callback){
- var xhr = new XMLHttpRequest();
- xhr.onreadystatechange = function(){
- if (xhr.readyState === 4) {
- if (xhr.status === 200) {
- dataJson = JSON.parse(xhr.responseText);
- callback && callback();
- }
- }
- };
- xhr.open("GET", path, true);
- xhr.send();
- }
因为读取文件是一个异步的过程,所以要程序的展开都要放在文件读取函数的内部。
- function init(){
- loadJSON("shanghaiMetro.json", function(){
- initNetwork(dataJson);
- initNode(dataJson);
- });
- }
2. 站点初创
- for(staId in json.stations){
- var station = json.stations[staId];
- staNode = new twaver.Node({
- id: staId,
- name: station.name,
- image:'station',
- });
- staNode.s('label.color','rgba(99,99,99,1)');
- staNode.s('label.font','12px 微软雅黑');
- staNode.s('label.position',station.label);
- staNode.setClient('location',station.loc);
- box.add(staNode);
- }
3. 站点分类
4. 显示站名
5. 站点图标

三、线路设计
1. 连接站点
- for(lineId in json.lines) {
- ……
- for(staSn in line.stations) {
- ……
- var link = new twaver.Link(linkId,prevSta,staNode);
- link.s('link.color', line.color);
- link.s('link.width', linkWidth);
- link.setToolTip(line.name);
- box.add(link);
- }
- }
2. 连线分型




3.智能拐点
- var setTrunType = function(json){
- box.forEach(function (ele) {
- var id = ele.getId();
- if(ele instanceof twaver.Link){
- var link = ele;
- var f = link.getFromNode().getCenterLocation();
- var t = link.getToNode().getCenterLocation();
- if(needAddPoint(f, t)){
- var so=0, os=0;
- if(link.getClient('prevLink')){
- so += byPrevPoint(f,t,link).so;
- os += byPrevPoint(f,t,link).os;
- }
- if(link.getClient('nextLink')){
- os += byNextPoint(f,t,link).os;
- so += byNextPoint(f,t,link).so;
- }
- p = os>so ? obliqueStraight(f, t) : straightOblique(f, t);
- link.setClient('point', p);
- link.setClient('truntype', os>so?'os':'so');
- }
- }
- });
- }
4. 人工拐点
- var createTurnSta = function(line, staSn){
- staTurn = new twaver.Node(staSn);
- staTurn.setImage();
- staTurn.setClient('lineColor',line.color);
- staTurn.setClient('lines',[line.id]);
- var loc = line.stations[staSn];
- staTurn.setClient('location',loc);
- box.add(staTurn);
- return staTurn;
- }
5.接点偏移
- var createFollowSta = function(json, line, staNode, staId){
- staFollow = new twaver.Follower(staId);
- staFollow.setImage();
- staFollow.setClient('lineColor',line.color);
- staFollow.setClient('lines',[line.id]);
- staFollow.setHost(staNode);
- var az = azimuth[staId.substr(6,2)];
- var loc0 = json.stations[staId.substr(0,6)].loc;
- var loc = {x:loc0.x+az.x, y:loc0.y+az.y};
- staFollow.setClient('location',loc);
- box.add(staFollow);
- return staFollow;
- }
- var azimuth = {
- bb: {x: 0, y: linkWidth*zoom/2},
- tt: {x: 0, y: -linkWidth*zoom/2},
- rr: {x: linkWidth*zoom/2, y: 0},
- ll: {x: -linkWidth/2, y: 0},
- br: {x: linkWidth*zoom*0.7/2, y: linkWidth*zoom*0.7/2},
- bl: {x: -linkWidth*zoom*0.7/2, y: linkWidth*zoom*0.7/2},
- tr: {x: linkWidth*zoom*0.7/2, y: -linkWidth*zoom*0.7/2},
- tl: {x: -linkWidth*zoom*0.7/2, y: -linkWidth*zoom*0.7/2},
- BB: {x: 0, y: linkWidth*zoom},
- TT: {x: 0, y: -linkWidth*zoom},
- RR: {x: linkWidth*zoom, y: 0},
- LL: {x: -linkWidth, y: 0},
- BR: {x: linkWidth*zoom*0.7, y: linkWidth*zoom*0.7},
- BL: {x: -linkWidth*zoom*0.7, y: linkWidth*zoom*0.7},
- TR: {x: linkWidth*zoom*0.7, y: -linkWidth*zoom*0.7},
- TL: {x: -linkWidth*zoom*0.7, y: -linkWidth*zoom*0.7}
- };
四、动态显示
1. 文本提示

2. 站点显示
- twaver.Util.registerImage('station',{
- w: linkWidth*1.6,
- h: linkWidth*1.6,
- v: function (data, view) {
- var result = [];
- if(data.getClient('focus')){
- result.push({
- shape: 'circle',
- r: linkWidth*0.7,
- lineColor: data.getClient('lineColor'),
- lineWidth: linkWidth*0.2,
- fill: 'white',
- });
- result.push({
- shape: 'circle',
- r: linkWidth*0.2,
- fill: data.getClient('lineColor'),
- });
- }else{
- result.push({
- shape: 'circle',
- r: linkWidth*0.6,
- lineColor: data.getClient('lineColor'),
- lineWidth: linkWidth*0.2,
- fill: 'white',
- });
- }
- return result;
- }
- });
3. 站点动画
- twaver.Util.registerImage('rotateArrow', {
- w: 124,
- h: 124,
- v: [{
- shape: 'vector',
- name: 'doubleArrow',
- rotate: 360,
- animate: [{
- attr: 'rotate',
- to: 0,
- dur: 2000,
- reverse: false,
- repeat: Number.POSITIVE_INFINITY
- }]
- }]
- });


五、交互功能
1. 拖拽回弹

2. 混合缩放
- network.setZoomManager(new twaver.vector.MixedZoomManager(network));
- network.setMinZoom(0.2);
- network.setMaxZoom(3);
- network.setZoomVisibilityThresholds({
- label : 0.6,
- });
3. 经过路线

4. 路径规划

5. 电子地图
- network.addInteractionListener(function(e){
- if(mapDiv){
- mapDiv.style.display = 'none';
- mapDiv = null;
- dbclickSta = null;
- }
- if(e.kind == 'doubleClickElement' && e.element && e.element.getClassName() == 'twaver.Node' && e.element.getId().length == 6){
- dbclickSta = e.element;
- if(dbclickSta.getClient('coord')){
- coord = dbclickSta.getClient('coord');
- mapDiv = createMap(coord, e.event);
- }else{
- dbclickSta.setClient('dbclick', true);
- var lineName = json.lines[dbclickSta.getId().substr(0,3)].name;
- var stationName = dbclickSta.getName();
- var addr = "上海市地铁" + lineName + stationName;
- var geocoder = new qq.maps.Geocoder();
- geocoder.getLocation(addr);
- geocoder.setComplete(function(result) {
- coord = result.detail.location;
- mapDiv = createMap(coord, e.event);
- dbclickSta.setClient('dbclick', false);
- });
- geocoder.setError(function() {
- var coord = {"lat":31.188,"lng":121.425};
- mapDiv = createMap(coord, e.event);
- });
- }
- }
- });


TWaver初学实战——基于HTML5的交互式地铁图的更多相关文章
- 基于 HTML5 + WebGL 的地铁 3D 可视化系统
前言 工业互联网,物联网,可视化等名词在我们现在信息化的大背景下已经是耳熟能详,日常生活的交通,出行,吃穿等可能都可以用信息化的方式来为我们表达,在传统的可视化监控领域,一般都是基于 Web SCAD ...
- 基于HTML5实现3D热图Heatmap应用
Heatmap热图通过众多数据点信息,汇聚成直观可视化颜色效果,热图已广泛被应用于气象预报.医疗成像.机房温度监控等行业,甚至应用于竞技体育领域的数据分析. http://www.hightopo.c ...
- TWaver初学实战——如何在EasyUI中插入TWaver
TWaver是一款强大的图形界面开发组件,可以很方便地集成到其他开发工具中.今天就用一个小例子来操练如何结合TWaver和EasyUI进行网页开发. 准备工作 俗话说他山之玉可以直接拿来,EasyUI ...
- TWaver初学实战——如何在TWaver属性表中添加日历控件?
在日期输入框中添加日历控件,是一种非常流行和实用的做法.临渊羡鱼不如退而写代码,今天就看看在TWaver中是如何实现的. 资源准备 TWaver的在线使用文档中,就有TWaver Proper ...
- TWaver初学实战——如何在EasyUI中插入TWaver(续)
上次文章虽然简单易懂,但很有些小伙伴不满意:你这TWaver和EasyUI结合,只不过生硬地把TWaver图形插进去了,数据和人家EasyUI没一毛钱关系.嘿嘿,不就是想发生关系嘛,没问题啊!咱就还用 ...
- 基于HTML5 的互联网+地铁行业
前言 近几年,互联网与交通运输的融合,改变了交易模式,影响着运输组织和经营方式,改变了运输主体的市场结构.模糊了运营与非营运的界限,也更好的实现了交通资源的集约共享,同时使得更多依靠外力和企业推动交通 ...
- 基于 HTML5 Canvas 的交互式地铁线路图
前言 前两天在 echarts 上寻找灵感的时候,看到了很多有关地图类似的例子,地图定位等等,但是好像就是没有地铁线路图,就自己花了一些时间捣鼓出来了这个交互式地铁线路图的 Demo,地铁线路上的点是 ...
- 快速开发 HTML5 交互式地铁线路图
前言 前两天在 echarts 上寻找灵感的时候,看到了很多有关地图类似的例子,地图定位等等,但是好像就是没有地铁线路图,就自己花了一些时间捣鼓出来了这个交互式地铁线路图的 Demo,地铁线路上的点是 ...
- 基于HTML5的RDP访问实战
基于HTML5的RDP访问实战 1.安装guacamole 2.下载源码 3.安装服务端 安装报错 错误 参考 http://www.remotespark.com/html5.html ...
随机推荐
- Android IOS WebRTC 音视频开发总结(二六)-- webrtc调用堆栈
本文主要是自己之前研究WebRTC代码结构时的一些资料(包括Android,iOS,PC),文章来自博客园RTC.Blacker,转载请说明出处. 1.WEBRTC模块:音频数据采集.发送.接收.播放 ...
- 软件工程 speedsnail 冲刺7
2015-5-11 完成任务:蜗牛移动的一部分: 遇到问题: 问题1 速度,坐标,角度: 速度分级别设置: 坐标记录功能,方便障碍物检测: 暂定初始45度角: 解决1 未解决上述问题 明日任务: 蜗牛 ...
- Windows 2008 R2 X64 安装WebsitePanel(WSP虚拟主机管理面板)
Windows 2008 R2 X64 安装WebsitePanel(WSP2.0虚拟主机管理面板) 估计很多同学都还不知道WebsitePanel是什么东东吧,Web ...
- windwos异地备份Mysql数据库
@echo off@title Mysqlbackup echo MySQL数据库备份 echo ***********************echo Today %date%echo Time % ...
- 第一部分 CLR基础:第1章 CLR的执行模型
1.1将源代码编译成托管模块
- objective-C运算符和表达式
运算符可以分为以下几种: 算术运算符:+,-,*,/,%,++,—-. 关系运算符:<,>,<=,>=,==,!= 布尔逻辑运算符:!,&&,|| 位运算符:| ...
- source insight用于C语言编程的工具脚本
简单来说,source insight提供的功能功能还不够傻瓜,用起来还不够方便,所以写了此脚本,提高开发效率. 部分source insight提供的功能也包含了进来,主要是因为我不喜欢使用太多的快 ...
- ASP.NET的错误处理机制之一(概念)
对Web应用程序来说,发生不可预知的错误和异常在所难免,我们必须为Web程序提供错误处理机制.当错误发生时,我们必须做好两件事情:一是将错误信息记录日志,发邮件通知网站维护人员,方便技术人员对错误进行 ...
- 【原创】解决鼠标经过子元素触发mouseout,mouseover事件的问题
关键词:父子元素关系 mouseout mouseover 事件 事件冒泡 初期代码: <!DOCTYPE html> <html> <head> < ...
- ASP.NET MVC5学习笔记之Action参数模型绑定基本过程
当我们在Controller中定义一个Action,通常会定义一个或多个参数,每个参数称为一个模型,ASP.NET MVC框架提供了一种机制称为模型绑定,会尝试自动从请求的信息中实例化每一个模型并赋值 ...