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 ...
随机推荐
- Python之路【第五篇】:面向对象及相关
Python之路[第五篇]:面向对象及相关 面向对象基础 基础内容介绍详见一下两篇博文: 面向对象初级篇 面向对象进阶篇 其他相关 一.isinstance(obj, cls) 检查是否obj是否 ...
- 卡通风格的连连看ios游戏源码
卡通风格的连连看游戏源码,该游戏是一款韩国人做的卡通风格的ios连连看游戏源码,源码设计的效果非常漂亮的,而且运行起来感觉也很好.1.游戏采用倒计时模式2.该游戏是一款社交游戏,需要通过faceboo ...
- 必须会的SQL语句(二) 创建表、修改表结构、删除表
1.创建数据库表 --使用哪个数据库,如果不写这一句是默认的数据库,也可以用鼠标选当前数据库 use testDB --创建表 Create Table tablename ( ...
- 【SMS】移动短信网关返回信息状态代码说明【China Mobile】
1 由SMSC返回的一般结果状态报告 含义 说明 处理建议DELIVRD 消息发送成功 用户成功接收到短信 ??EXPIRED 因为用户长时间关机或者不在服务区等导致的短消息超时没有递交到用户手机上 ...
- HUE 忘记密码
解决方法: 启动HUE的Shell /opt/cloudera/parcels/CDH/lib/hue/build/env/bin/hue shell from django.contrib.auth ...
- 有关c#装箱和拆箱知识整理
c#装箱和拆箱知识,装箱和拆箱是一个抽象的概念. 1.装箱和拆箱是一个抽象的概念 2.装箱是将值类型转换为引用类型 : 拆箱是将引用类型转换为值类型 利用装箱和拆箱功能,可通过允许值类型的任何值与O ...
- ubuntu下svn使用指南
ubuntu下安装subversion客户端: sudo apt-get install subversion subversion-tools 详细请看 http://www.subversion. ...
- PHPExcel导出导入excel、csv等格式数据
<?php if(!defined('BASEPATH')) exit('No direct script access allowed'); //物资发料单明细 class Read_writ ...
- openSUSE13.1安装时要注意的问题(未完待续)
1.最好用官方给的imageWriter来写镜像,不要用UltraISO来写镜像,会导致安装Kaffein包错误(:)可能也会有别的错误),后来我用imageWriter写了之后就没有在安装时报错了
- IE8中JSON.stringify方法对自动转换unicode字符的解决方案
IE8内置了JSON对象,用以处理JSON数据.与标准方法的不同,IE8的JSON.stringify会把utf-8字符转码: var str = "我是程序员" var json ...