文档章节

百度地图、ECharts整合HT for Web网络拓扑图应用

xhload3d
 xhload3d
发布于 2015/03/23 01:32
字数 1665
阅读 6138
收藏 92

前一篇谈及到了ECharts整合HT for Web网络拓扑图应用,后来在EChartsDemo中看到了有关空气质量的相关报表应用,就想将百度地图、EChartsHT for Web三者结合起来也做一个类似空气质量报告的报表+拓扑图应用,于是有了下面的Demo

在这个Demo中,将GraphView拓扑图组件添加到百度地图组件中,覆盖在百度地图组件之上,并且在百度地图组件上和GraphView拓扑图组件上分别添加事件监听,相互同步经纬度和屏幕位置信息,从而来控制拓扑图上的组件位置固定在地图上,并在节点和节点之间的连线上加上了流动属性。右下角的图标框是采用HT for WebPanel面板组件结合ECharts图表组件完成的。

接下来我们来看看具体的代码实现:

1. 百度地图是如何与HT for Web组件结合的;

map = new BMap.Map("map");
var view = graphView.getView();
view.className = 'graphView';
var mapDiv = document.getElementById('map');
mapDiv.firstChild.firstChild.appendChild(view);

首先需要在body中存在id为map的div,再通过百度地图的api来创建一个map地图对象,然后创建GraphView拓扑图组件,并获取GraphView组件中的view,最后将view添加到id为map的div的第二代孩子节点中。这时候问题就来了,为什么要将view添加到map的第二代孩子节点中呢,当你审查元素时你会发现这个div是百度地图的遮罩层,将view添加到上面,会使view会是在地图的顶层可见,不会被地图所遮挡。

2. 百度地图和GraphView的事件监听;

map.addEventListener('moveend', function(e){
   resetPosition();
});
map.addEventListener('dragend', function(e){
   resetPosition();
});                                
map.addEventListener('zoomend', function(e){
	resetPosition();
});

graphView.handleScroll = function(){};
graphView.handlePinch = function(){};

function resetPosition(e){
	graphView.tx(0);
	graphView.ty(0);
	dataModel.each(function(data){
		var lonLat, position;
		if(data instanceof ht.HtmlNode){
			if(data.getId() != 'chartTotal') {
				position = data.getHost().getPosition();
				position = {x: position.x + 168, y: position.y + 158};
				data.setPosition(position.x, position.y);
			}
		} else if(data instanceof ht.Node){
			lonLat = data.lonLat;
			position = map.pointToPixel(lonLat);
			data.setPosition(position.x,position.y);
		}
	});
}

首先监听map的三个事件:moveend、 dragend、 zoomend,这三个事件做了同一件事--修改DataModel中所有data的position属性,让其在屏幕上的坐标与地图同步,然后将GraphView的Scroll和Pinch两个事件的执行函数设置为空函数,就是当监听到Scroll或者Pinch事件时不做任何的处理,将这两个事件交给map来处理。

resetPosition函数中,做的事情很简单:遍历DataModel中的data,根据它们各自在地图上的经纬度来换算成屏幕坐标,并将坐标设置到相应的data中,从而达到GraphView中的节点能够固定在地图上的效果。

3. 创建右下角的图表组件:

ht.Chart = function(option){
	var self = this,
			view = self._view = document.createElement('div');
	view.style.position = 'absolute';
	view.style.setProperty('box-sizing', 'border-box', null);
	self._option = option;
	self._chart = echarts.init(self.getView());
	if(option)
		self._chart.setOption(option);
	self._FIRST = true;
};
ht.Default.def('ht.Chart', Object, {
	ms_v: 1,
	ms_fire: 1,
	ms_ac: ['chart', 'option', 'isFirst', 'view'],
	validateImpl: function(){
		var self = this,
				chart = self._chart;
		chart.resize();
		if(self._FIRST){
			self._FIRST = false;
			chart.restore();
		}
	},
	setSize: function(w, h){
		var view = this._view;
		view.style.width = w + 'px';
		view.style.height = h + 'px';
	}
});

function createPanel(title, width, height){
	chart = new ht.Chart(option);
	var c = chart.getChart();
	c.on(echarts.config.EVENT.LEGEND_SELECTED, legendSelectedFun);
	var chartPanel = new ht.widget.Panel({
		title: title,
		restoreToolTip: "Overview",
		width: width,
		contentHeight: height,
		narrowWhenCollapse: true,
		content: chart,
		expanded: true
	});
	chartPanel.setPositionRelativeTo("rightBottom");
	chartPanel.setPosition(0, 0);
	chartPanel.getView().style.margin = '10px';

	document.body.appendChild(chartPanel.getView());
}

首先定义了ht.Chart类,并实现了validateImpl方法,方法中处理的逻辑也很简单:在每次方法执行的时候调用图表的reset方法重新设定图标的展示大小,如果该方法是第一次执行的话,就调用图表的restore方法将图表还原为最原始的状态。会有这样的设计是因为ht.Chart类中的view是动态创建的,在没有添加到dom之前将一直存在于内存中,在内存中因为并没有浏览器宽高信息,所以div的实际宽高均为0,因此chartoption内容绘制在宽高为0div中,即使你resizechart,如果没用重置图表状态的话,图表状态将无法在图表上正常显示。

接下来就是创建panel图表组件了,这是HT for Web的Panel组件的基本用法,其中content属性的值可以是HT for Web的任何组件或div元素,如果是HT fro Web组件的话,该组件必须实现了validateImpl方法,因为在panel的属性变化后将会调用content对应组件的validateImpl方法来重新布局组件内容。

4. EChartsGraphView拓扑图组件的交互:

legendSelectedFun = function(param) {
	if(chart._legendSelect){
		delete chart._legendSelect;
		return;
	}
	console.info(param);
	var id = nodeMap[param.target],
			dm = graphView.dm(),
			data = dm.getDataById(id),
			sm = dm.sm(),
			selection = sm.getSelection();

	if(param.selected[param.target]) {
		sm.appendSelection([data]);
		if(selectionData.indexOf(param.target) < 0){
			selectionData.push(param.target);
		}
	}else {
		sm.removeSelection([data]);
		var index = selectionData.indexOf(param.target);
		if(index >= 0){
			selectionData.splice(index, 1);
		}
	}
	sm.setSelection(selection.toArray());
};

graphView.mi(function(e){
	console.info(e.kind, e.data);
	var c = chart.getChart(),
			legend = c.component.legend,
			selectedMap = legend.getSelectedMap();

	if(e.kind === 'endRectSelect'){
		chart._legendSelect = true;
		for(var name in notes){
			legend.setSelected(name, false);
		}
		notes = {};
		graphView.dm().sm().each(function(data){
			var note = data.s('note');
			if(note)
				notes[note] = 1;
		});
		for(var name in notes){
			legend.setSelected(name, true);
		}
	} else if(e.kind === 'clickData'){
		chart._legendSelect = true;
		var data = e.data;
		if(data instanceof ht.Node){
			var note = data.s('note');

			if(note){
				var selected = legend.isSelected(note);
				if(selected){
					graphView.dm().sm().removeSelection([data]);
				}
				legend.setSelected(note, !selected);
			}
		}
	}
});

legendSelectedFun函数是EChart图表的legend插件选中事件监听,其中处理的逻辑是:当legend插件中的某个节点被选中了,也选中在GraphView拓扑图中对应的节点,当取消选中是,也取消选中GraphView拓扑图中对应的节点。

GraphView中添加交互监听,如果在GraphView中做了框选操作,在框选结束后,将原本legend插件上被选中的节点取消选中,然后再获取被选中节点,并在legend插件上选中对应节点;当GraphView上的节点被选中,则根据legend插件中对应节点选中情况来决定legend插件中的节点和graphView上的节点是否选中。

在GraphView交互中,我往chart实例中添加了_legendSelect变量,该变量的设定是为了阻止在GraphView交互中修改legend插件的节点属性后回调legendSelectedFun回调函数做修改GraphView中节点属性操作。

今天就写到这吧,希望这篇文章能够帮到那些有地图、拓扑图、图表相结合需求的朋友,在设计上可能想法还不够成熟,希望大家不吝赐教。

© 著作权归作者所有

共有 人打赏支持
xhload3d
粉丝 182
博文 156
码字总数 318723
作品 0
崇明
私信 提问
加载中

评论(6)

xhload3d
xhload3d
可参考文档 http://www.hightopo.com/guide/guide/core/beginners/ht-beginners-guide.html
xhload3d
xhload3d

引用来自“山哥”的评论

是纬度,不是维度。
谢谢指正!
山哥
山哥
是纬度,不是维度。
min3278
min3278

引用来自“min3278”的评论

ECharts,在IE8下兼容性有问题,你那边是否也有类似问题?

引用来自“xhload3d”的评论

这倒是没注意,因为我们需要使用HT for Web做网络拓扑图,而HT for Web需要HTML5的支持,因此没考虑过IE8的情况
你可以在IE8下试一下,ECharts的那些点在IE8下显示不出来的。另外怎么联系你,交个朋友吧!
xhload3d
xhload3d

引用来自“min3278”的评论

ECharts,在IE8下兼容性有问题,你那边是否也有类似问题?
这倒是没注意,因为我们需要使用HT for Web做网络拓扑图,而HT for Web需要HTML5的支持,因此没考虑过IE8的情况
min3278
min3278
ECharts,在IE8下兼容性有问题,你那边是否也有类似问题?
ECharts整合HT for Web的网络拓扑图应用

ECharts图形组件在1.0发布的时候我就已经有所关注,今天在做项目的时候遇到了图标的需求,在HT for Web上也有图形组件的功能,但是在尝试了下具体实现后,发现HT for Web的图形组件是以矢量的...

xhload3d
2015/03/16
0
0
ECharts:国内数据可视化领域的新秀

不久前,专业大数据可视化公司Tableau在纽交所成功上市,当日收盘涨幅64%,至50.75美元,共募集资金2.542亿美元,成为今年美国最大一笔科技业IPO。Tableau Software正是一家做大数据的公司,...

Kener-林峰
2013/08/06
94
0
ECharts 3.1.2 发布,JavaScript 图表库

Echarts 3.1.2 发布了,下载地址: https://github.com/ecomfe/echarts/releases/tag/3.1.2 @Kener-林峰 改进记录呢,改进记录在哪里??? ECharts开源来自百度商业前端数据可视化团队,基于...

oschina
2016/03/02
3.6K
5
ECharts 3.1.1 发布,JavaScript 图表库

Echarts 3.1.1 发布,该版本主要是为了满足 npm 使用的要求。没有其他额外的改进。 下载地址:https://github.com/ecomfe/echarts/releases/tag/3.1.1 ECharts开源来自百度商业前端数据可视化...

oschina
2016/02/23
3.4K
18
ECharts 2.2.2 发布,JavaScript 图表库

ECharts 2.2.2 发布,此版本主要有以下更新: Add Venn chart. See example Venn Add Treemap. See example Treemap Add logarithmic axis. See example line9 Release ECharts online build......

oschina
2015/04/30
3K
25

没有更多内容

加载失败,请刷新页面

加载更多

深入理解Spring MVC 思想

目录 一、前言 二、spring mvc 核心类与接口 三、spring mvc 核心流程图 四、spring mvc DispatcherServlet说明 五、spring mvc 父子上下文的说明 六、springMVC-mvc.xml 配置文件片段讲解 ...

呵呵哒灬
今天
3
0
数据库技术-Mysql主从复制与数据备份

数据库技术-Mysql 主从复制的原理: MySQL中数据复制的基础是二进制日志文件(binary log file)。一台MySQL数据库一旦启用二进制日志后,其作为master,它的数据库中所有操作都会以“事件”...

须臾之余
昨天
12
0
Git远程仓库——GitHub的使用(一)

Git远程仓库——GitHub的使用(一) 一 、 Git远程仓库 由于你的本地仓库和GitHub仓库之间的传输是通过SSH加密的,所以需要一下设置: 步骤一、 创建SSH key 在用户主目录下,看看有没有.ss...

lwenhao
昨天
4
0
SpringBoot 整合

springBoot 整合模板引擎 SpringBoot 整合Mybatis SpringBoot 整合redis SpringBoot 整合定时任务 SpringBoot 整合拦截器...

细节探索者
昨天
1
0
第二个JAVA应用

第二个JAVA应用 方法一:配置文件: # cd /usr/local/tomcat/conf/# vim server.xml</Host> <Host name="www.wangzb.cc" appBase="/data/wwwroot/www.wangzb.cc" //引用所......

wzb88
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部