前一篇谈及到了ECharts整合HT for Web的网络拓扑图应用,后来在ECharts的Demo中看到了有关空气质量的相关报表应用,就想将百度地图、ECharts和HT for Web三者结合起来也做一个类似空气质量报告的报表+拓扑图应用,于是有了下面的Demo:http://www.hightopo.com/demo/blog_baidu_20150928/ht-baidu.html
在这个Demo中,将GraphView拓扑图组件添加到百度地图组件中,覆盖在百度地图组件之上,并且在百度地图组件上和GraphView拓扑图组件上分别添加事件监听,相互同步经纬度和屏幕位置信息,从而来控制拓扑图上的组件位置固定在地图上,并在节点和节点之间的连线上加上了流动属性。右下角的图标框是采用HT for Web的Panel面板组件结合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,因此chart将option内容绘制在宽高为0的div中,即使你resize了chart,如果没用重置图表状态的话,图表状态将无法在图表上正常显示。
接下来就是创建panel图表组件了,这是HT for Web的Panel组件的基本用法,其中content属性的值可以是HT for Web的任何组件或div元素,如果是HT fro Web组件的话,该组件必须实现了validateImpl方法,因为在panel的属性变化后将会调用content对应组件的validateImpl方法来重新布局组件内容。
4.ECharts和GraphView拓扑图组件的交互:
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中节点属性操作。
今天就写到这吧,希望这篇文章能够帮到那些有地图、拓扑图、图表相结合需求的朋友,在设计上可能想法还不够成熟,希望大家不吝赐教。
相关推荐
1. 前后端分离:前端 Echarts JavaScript BootStrap; 后端Python Flask; 2. 数据动态更新:服务端触发数据源的变化,前端AJAX自动获取最新数据并渲染到Echarts图表上; 3. 数据格式:JSON; 更多Python&Echarts版...
ECharts是一个由百度开发的开源JavaScript图表库,支持折线图、柱状图、饼图、散点图等多种图表类型,并且可以自定义各种交互行为。它的优点在于配置灵活、性能优异,且兼容多种浏览器。要使用ECharts,我们需要在...
把几种精炼的代码组合成的。 ActionBarSherlock下载地址:https://github.com/JakeWharton/ActionBarSherlock SlidingMenu下载地址:...BaiduMap最新下载地址:http://developer.baidu.com/map/sdkandev-download.htm
MySQL是一款关系型数据库管理系统,广泛应用于Web应用。在这个疫情打卡系统中,MySQL可能用于存储用户信息、打卡记录、地理位置等关键数据。 1. **用户表**:存储用户的个人信息,如ID、姓名、手机号等。 2. **打卡...
在这个项目中,我们将使用Python编程语言结合网络爬虫技术来抓取并处理全国城市的信息。同时,我们会利用百度地图的API接口,将这些地理信息与地图服务相结合,实现一个实用的数据获取系统。 【描述】: 1. Python...
总的来说,百度离线版地图baidumap_apiV2_offline.zip为开发者提供了一种在无网络环境下使用百度地图和Echarts进行数据可视化的解决方案,尤其适用于对地图展示有离线需求的项目。通过合理使用和配置,可以实现富有...
基于spark+echarts实现的互联网行业数据大屏分析源码+项目说明(数据来源于前程无忧).zip 基于spark+echarts实现的互联网行业数据大屏分析源码+项目说明(数据来源于前程无忧).zip 基于spark+echarts实现的互联网行业...
在GIS(地理信息系统)领域,OpenLayers是一个广泛使用的开源JavaScript库,用于在Web浏览器中创建交互式的地图应用。本示例“baiduMap_openlayer”是关于如何利用OpenLayers加载和展示百度地图与高德地图的教程。这...
总的来说,这个“baiduMap相关.rar”压缩包提供了开发百度地图应用的基础数据,包括城市的经纬度坐标和Echarts地图展示所需的JavaScript数据。通过学习和运用这些资源,开发者可以创建出具有丰富功能和美观视觉效果...
本压缩包“BaiduMap.zip”包含了在Android应用中整合百度地图API的示例代码,主要针对Java语言编写,名为“BaiduMapsApiDemo”。通过这个项目,开发者可以学习如何在自己的应用中实现地图展示、定位、路线规划等功能...
本文将围绕“baidumap.zip_baiduMap_地图测距_百度地图_百度地图测距”这一主题,详细介绍百度地图1.5版的应用实例,以及如何利用API进行地图测距。 首先,我们需要了解百度地图API的核心概念。百度地图API是一组...
《BaiduMap Demo详解——构建高效地图应用》 在移动应用开发中,地图功能是不可或缺的一部分,尤其是在Android平台上。BaiduMap Demo是一个专门为开发者提供的示例项目,它涵盖了使用百度地图API在Android应用中...
【百度地图BaiduMap】是基于百度地图API开发的一个应用示例,主要展示了如何在Android平台上集成和使用百度地图服务。这个应用的核心是通过引入`baidumapapi_v3_5_0.jar`框架库和`libBaiduMapSDK_v3_5_0_31.so`库...
在本项目中,我们主要关注的是“BaiduMap.zip”这个压缩包,它包含了与百度地图相关的功能,如地图查询、附近的地点搜索、路径规划以及经纬度转换。下面将详细阐述这些功能及其在实际应用中的重要性。 首先,我们要...
互联网行业分析,数据源于前程无忧招聘网站,数据分析基于spark平台,数据大屏基于echarts 数据源 各个城市的精度data/BaiduMap_cityCenter.txt来源于百度地图开放平台,crawler/cityInfo.py含爬取前程无忧各个城市...
1. **地图展示**:BaiduMap API允许开发者在Android应用中集成百度地图,展示实时的卫星图、地形图、交通图等多种地图模式。用户可以通过缩放、平移、旋转等操作查看地图细节。 2. **定位服务**:利用GPS、WiFi、...
BaiduMap_AndroidSDK提供了显示地图的功能,包括卫星图、地形图、普通地图等多种地图样式,开发者可以通过API调整地图的缩放级别、平移、旋转等操作,实现地图的动态展示。此外,SDK还支持自定义地图样式,允许...
ECharts 是一个基于 JavaScript 的数据可视化库,广泛用于创建交互式的图表和地图。...开发者可以按照指南逐步学习,掌握如何将这些地图数据与百度地图 API 结合,从而开发出具有专业地图功能的 Web 应用。
《全面解析BaiduMap Android SDK v3.5.0:集成与应用》 在移动应用开发领域,百度地图SDK(Software Development Kit)是开发者们常用的一款工具,它为Android平台提供了丰富的地图功能,如定位、路线规划、地理...
1. **百度地图Android SDK**:这是一个由百度公司提供的开发套件,允许开发者在Android应用中集成百度地图,实现地图展示、地理编码、反地理编码、自定义图层、标注、覆盖物、热力图等功能。该SDK支持离线地图、实时...