前言

最近特别忙,承蒙大伙关照,3D机房的项目一个接着一个,领了一帮小弟,搞搞传帮带,乌飞兔走,转眼已经菊黄蟹肥……有个小弟很不错,勤奋好学,很快就把API都摸透了,自己折腾着做了个HTML5的魔都的地铁线路图,能拖能拽的,还和电子地图做了交互。哥决定把小弟的成果纳入“HTML5大数据可视化效果”系列,以示鼓励(P.S. 其实还挺有压力的,后浪推前浪,新人赶旧人。我们这些老鸟也得注意,免得让00后给抢了饭碗)

效果图对比

网上的地铁图还是很多的,小弟选了这张比较新的做参考。想当年哥来魔都打拼时,图上可就一红一绿打个叉……暴露年龄的话不多说,看图:

再来看看小弟做的:

我是一眼看不出区别,但这可不是一张效果图,而是一个新手仅用了几天做出来的东西,而且里面许多美化和调整是通过程序自动完成的,这就不容易了。更重要的是,它并不是一张死图,而是纯矢量、可交互、有动态效果、无失真缩放的拓扑图!我们先简单看一下交互效果,后面可以详细说说代码的实现。

文本提示弹弹弹

首先,把鼠标移到站点、路段、图标等位置,都会有文本提示弹出,这个比较基本,百度家的就有,小弟也就放了比较简单的弹出内容。如果加上基本介绍啊、相关提示啊、周边信息啊……要是加上广告,就可以赚钱了……反正什么都可以加嘛,就是一个setToolTip命令而已。

站点图标变变变

当鼠标移到站点上时,站点图标做了放大效果,这个效果很贴心,看了下百度家,用的是发光效果。

实现的方法也很简便,就是在注册站点矢量图形时,加入了动态判断。以下注册普通站点矢量图形的代码:

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;
}
});

动画效果拽拽拽

从上图还可以看到,在换乘站图标中,除了增加了颜色,还实现了旋转效果。这个就秒杀百度家了。 来看代码:

1.    twaver.Util.registerImage('rotateArrow', {
2. w: 124,
3. h: 124,
4. v: [{
5. shape: 'vector',
6. name: 'doubleArrow',
7. rotate: 360,
8. animate: [{
9. attr: 'rotate',
10. to: 0,
11. dur: 2000,
12. reverse: false,
13. repeat: Number.POSITIVE_INFINITY
14. }]
15. }]
16. });

当然这对于TWaver来说也很容易,只不过对rotate属性进行了动态改变而已。 另外,在单击和双击站点时,还实现了selected和loading的动画效果,值得点赞!

混合缩放炫炫炫

无失真缩放是矢量图的先天优势,小弟也掌握得炉火纯青,把TWaver的混合缩放模式用到极致,还有缩放比例控制、文字自动隐藏等小功能,方便订制。

代码也不复杂:

1.    network.setZoomManager(new twaver.vector.MixedZoomManager(network));
2. network.setMinZoom(0.2);
3. network.setMaxZoom(3);
4. network.setZoomVisibilityThresholds({
5. label : 0.6,
6. });

交互功能用起来

小弟很自豪地给我介绍这个功能:图标可以自由拖动,松开后会自动弹回。哥问小弟这有什么用,他一本正经地说:证明图是活的!

好吧你赢了,虽然是个没什么卵用的功能,但闲的蛋疼的时候可以随便玩上几十分钟我也是信的。

连续单击同一站点

连续单击同一站点(注意不是双击),可以将经过此站点的所有线路突出显示出来。小弟说加入这个功能纯粹因为简单易做,我……竟然表示非常理解,谁年轻时没耍过这类轻松又讨好的小招数呢?

双击站点

双击站点,竟然弹出了本站周边的电子地图!知道引入他山之玉,看来小子可教啊。我发现他的定位方法,有的是用经纬度,有的是关键词查询。小弟狡黠地说,开始是人工查每个站点经纬度的,干了一段儿发现太麻烦,后来改路子了。马大大说的,懒人改变世界,我服!

最后来八一八程序设计的思路吧,小弟是棵好苗子,能做出那么像样的程序,必然是深思熟虑过的。不想再听我啰嗦的朋友,也可以直接发邮件给我,tw-service@servasoft.com,来鉴赏下小弟的成果。

数据文件的整理

数据格式,选择了JavaScript原生支持的json文件,直观方便。 数据结构,按照站点、线路、杂项三大块来组织,结构清晰,利于遍历、查询等操作。

1.    {
2. "stations":{
3. "l01s01":{ },
4. …………
5. }
6. "lines":{
7. "l01":{……},
8. …………
9. }
10. "sundrys":{
11. "railwaystationshanghai":{……},
12. …………
13. }
14. }

命名比较规范,通过名字就可以看出基本信息(例如“l01s01”就是1号线第1个站点),甚至直接利用名字就可以进行查询和遍历。

1.    "l01s01":{
2. "id":"l01s01",
3. "name":"莘庄",
4. "loc":{"x":419,"y":1330},
5. "label":"bottomright.bottomright",
6. },
7. …………

站点路线的创建

首先是读取json文件的数据。

1.    function loadJSON(path,callback){
2. var xhr = new XMLHttpRequest();
3. xhr.onreadystatechange = function(){
4. if (xhr.readyState === 4) {
5. if (xhr.status === 200) {
6. dataJson = JSON.parse(xhr.responseText);
7. callback && callback();
8. }
9. }
10. };
11. xhr.open("GET", path, true);
12. xhr.send();
13. }

因为读取文件是一个异步的过程,所以要程序的展开都要放在文件读取函数的内部。

1.    function init(){
2. loadJSON("shanghaiMetro.json", function(){
3. initNetwork(dataJson);
4. initNode(dataJson);
5. });
6. }

只要通过对站点进行一次遍历,车站的建立就完成了。

1.    for(staId in json.stations){
2. var station = json.stations[staId];
3. staNode = new twaver.Node({
4. id: staId,
5. name: station.name,
6. image:'station',
7. });
8. staNode.s('label.color','rgba(99,99,99,1)');
9. staNode.s('label.font','12px 微软雅黑');
10. staNode.s('label.position',station.label);
11. staNode.setClient('location',station.loc);
12. box.add(staNode);
13. }

再对数据文件中的各条线路下的所有站点进行遍历,在站点间依次创建Link。

1.    for(lineId in json.lines) {
2. ……
3. for(staSn in line.stations) {
4. ……
5. var link = new twaver.Link(linkId,prevSta,staNode);
6. link.s('link.color', line.color);
7. link.s('link.width', linkWidth);
8. link.setToolTip(line.name);
9. box.add(link);
10. }
11. }

再对label位置进行调整,否则站点名称会显示的很乱。小弟是通过在原始数据中手动加入位置信息来实现的,稍显笨了一点,应该可以通过程序自动判断站点周围空间来进行智能调整。 最后再加入图标,一张原始的地铁图就呈现出来了。

路线拐点的添加

基本的示意功能已经具备了,这里,小弟让我很欣赏的一点是没有就此停止,而是进一步做了调整,使线路只保留了横平竖直和正斜的走向,以达到整齐美观的效果。可能看起来与参考图稍稍有些不同,主要因为各路段基本只添加了一个拐点,这样做既大大简化了程序,又基本保证了图形的美观度。想远一点,做多一点,是块做产品的好料子。

当然为了提高程序的灵活性,应对必须添加两个或以上拐点的情况,也使用了人工拐点的手段。不过这里人工拐点被设成一个隐形的节点,可能利于智能拐点的判断,但也有可能在路线操作时造成混乱。如何处理更好还可以进一步推敲。

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;
}

接点位置的调整

大家可以看到,并不是所有路段都直接连入站点中心,在许多情况下必须要进行偏移。

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;
}

小弟采取了虚拟节点的办法,就是在站点的旁边,添加一个Follower(但并不显示出来),让并行的不同线路连接到不同的Follower上。通过调整Follower的位置,来实现线路与站点连接点的控制。

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}
};

介绍到这里就结束了,虽然是个小例子,实在是但美观性和实用性都还过得去,小弟花了心思去做,其实稍加改造就可以做出高铁图、公交图、运行图等应用。设想一下,如果能用在轨道交通列控中心大屏监控里,是多么炫酷。说到这,又想起了前段时间云栖大会上刚看到的杭州城市数据大脑,不知何时,哥也能参与一把那样的项目呢?可视化,哥的强项…… 最后,想要看程序,或者想玩“地铁拖拖乐”的各位,都可以给我留言和发邮件:tw-service@servasoft.com。

HTML5大数据可视化效果(二)可交互地铁线路图的更多相关文章

  1. HTML5大数据可视化效果(一)彩虹爆炸图

    前言 25年过去了,Brooks博士著名的“没有银弹”的论断依旧没有被打破.HTML5也是一样.但这并不妨碍HTML5是一个越来越有威力的“炸蛋”:发展迅速.势不可挡.随着HTML5技术的普及,用HT ...

  2. 13个可实现超棒数据可视化效果的Javascript框架

    随着商业及其相关需求的发展,数据成为越来越重要的元素之一,为了更加直观和明显的展示商业潜在的趋势和内在的特性,我们需要使用图表和图形的方式来直观动态的展示数据内在秘密,在今天的这篇文章中我们推荐12款 ...

  3. BI工具数据可视化效果哪家强?我选这款!

    BI工具是商业智能(Business Intelligence)软件的英文缩写.目前,商业智能通常被理解为将企业中现有的数据转化为知识,帮助企业做出明智的业务经营决策的工具. 企业经常会为如何选择BI ...

  4. CentOS6安装各种大数据软件 第九章:Hue大数据可视化工具安装和配置

    相关文章链接 CentOS6安装各种大数据软件 第一章:各个软件版本介绍 CentOS6安装各种大数据软件 第二章:Linux各个软件启动命令 CentOS6安装各种大数据软件 第三章:Linux基础 ...

  5. 2021年都要过去啦,你还在用Excel做数据可视化效果吗?

    2021年都要过去啦,你还在用Excel做数据可视化效果吗?古语有云,"工欲善其事,必先利其器",没有专业的工具,前期准备的再好也是白搭.现在运用数据可视化工具于经营活动中的企业是 ...

  6. 高速基于echarts的大数据可视化

    [Author]: kwu 高速基于echarts的大数据可视化,echarts纯粹的js实现的图表工具.高速开发的过程例如以下: 1.引入echarts的依赖js库 <script type= ...

  7. 大数据可视化呈现工具LightningChart的用法

    LightningChart (LightningChart Ultimate) 软件开发工具包是微软VisualStudio 的一个插件,专攻大数据可视化呈现问题,用于WPF(WindowsPres ...

  8. 基于 HTML5 WebGL 与 GIS 的智慧机场大数据可视化分析

    前言:大数据,人工智能,工业物联网,5G 已经或者正在潜移默化地改变着我们的生活.在信息技术快速发展的时代,谁能抓住数据的核心,利用有效的方法对数据做数据挖掘和数据分析,从数据中发现趋势,谁就能做到精 ...

  9. 基于 HTML5 WebGL 与 GIS 的智慧机场大数据可视化分析【转载】

    前言:大数据,人工智能,工业物联网,5G 已经或者正在潜移默化地改变着我们的生活.在信息技术快速发展的时代,谁能抓住数据的核心,利用有效的方法对数据做数据挖掘和数据分析,从数据中发现趋势,谁就能做到精 ...

随机推荐

  1. 隐藏路由器的WIFI信号,防蹭网

    进入路由器的管理界面 最后别忘了 现在信号隐藏了,现在说一下如何用手机连接隐藏的路由器

  2. IOS开发-图片尺寸

    在这篇文章当中,不会讲述关于具体px pt,分辨率,像素的问题,在这篇文章中,只会谈及到一些展现的问题 如果想了解更多关于pt,px之间的关系可以自行到百度查找相关的答案,或者到以下地址阅读更多相关的 ...

  3. Head First Design Patterns

    From Head First Design Patterns. Design Principle: Idnetify the aspects of your application that var ...

  4. C# .net中获取台式电脑中串口设备的名称

    来源:http://www.cnblogs.com/hshuzhao/p/4028856.html?utm_source=tuicool&utm_medium=referral .情境: 做项 ...

  5. C#中的串口通信

    关于串行接口 串行接口(Serial port)又称“串口”,主要用于串行式逐位数据传输.常见的有一般电脑应用的RS-232(使用 25 针或 9 针连接器)和工业电脑应用的半双工RS-485与全双工 ...

  6. C# 标签(条码)的打印与设计(一)

    C# 标签(条码)的打印与设计(一) C# 标签(条码)的打印与设计(二) 总结:自定义设计条码器.

  7. raspberry pi 如何汉化显示中文

    1 树莓派初装系统之后,首次启动会出现“raspi-config”工具,如下图:(若不是初次启动,在命令模式下,请输入 sudo raspi-config 命令,即可调出此界面.若在图形桌面下,打开桌 ...

  8. 在线视频转gif动画工具 在线视频转gif动画工具下载

    在线视频转gif动画工具 在线视频转gif动画工具下载 http://www.leawo.cn/space-1723875-do-thread-id-60715.html http://www.lea ...

  9. android 页面跳转,数据回传

    package com.example.firstpg.firstpg; import android.support.v7.app.ActionBarActivity; import android ...

  10. mysql中You can’t specify target table for update in FROM clause错误解决方法

    mysql中You can't specify target table for update in FROM clause错误的意思是说,不能先select出同一表中的某些值,再update这个表( ...