前一篇谈及到了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中节点属性操作。

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

ECharts+BaiduMap+HT for Web网络拓扑图应用的更多相关文章

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

    前一篇谈及到了ECharts整合HT for Web的网络拓扑图应用,后来在ECharts的Demo中看到了有关空气质量的相关报表应用,就想将百度地图.ECharts和HT for Web三者结合起来 ...

  2. ECharts整合HT for Web的网络拓扑图应用

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

  3. HTML5 网络拓扑图整合 OpenLayers 实现 GIS 地图应用

    在前面<百度地图.ECharts整合HT for Web网络拓扑图应用>我们有介绍百度地图和 HT for Web 的整合,我们今天来谈谈 OpenLayers 和 HT for Web  ...

  4. 自绘制HT For Web ComboBox下拉框组件

    传统的HTML5的下拉框select只能实现简单的文字下拉列表,而HTforWeb通用组件中ComboBox不仅能够实现传统HTML5下拉框效果,而且可以在文本框和下拉列表中添加自定义的小图标,让整个 ...

  5. 由于抽签HT For Web ComboBox下拉框组件

    传统HTML5的下拉框select仅仅能实现简单的文字下拉列表,而HT for Web通用组件中ComboBox不仅可以实现传统HTML5下拉框效果,并且可以在文本框和下拉列表中加入自己定义的小图标, ...

  6. ECharts整合HT&#160;for&#160;Web的网络拓扑图应用

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

  7. 扩展HT for Web之HTML5表格组件的Renderer和Editor

    在HT for Web提供了一下几种常用的Editor,分别是: slider:拉条 color picker:颜色选择器 enum:枚举类型 boolean:真假编辑器 string:普通的文本编辑 ...

  8. 矢量Chart图表嵌入HTML5网络拓扑图的应用

    使用 HT for Web (以下简称 HT)开发HTML5网络拓扑图的开发者有 Chart 需求的项目的时候,感觉很痛苦,HT 集成的 Chart 组件中,并不包含有坐标,在展现方面不是很直观,但是 ...

  9. 快速开发基于 HTML5 网络拓扑图应用1

    今天开始我们就从最基础解析如何构建 HTML5 Canvas 拓扑图应用,HT 内部封装了一个拓扑图形组件 ht.graph.GraphView(以下简称 GraphView)是 HT 框架中 2D ...

随机推荐

  1. Courier-MTA 0.72 发布,电子邮件系统

    Courier-MTA 0.72 增加了 ratefilter,用来限制速率的邮件过滤器. Courier 是一个优秀的电子信件系统,功能上它远比 Qmail. Postfix 等我们已经熟知的系统完 ...

  2. TableLayout表格布局详解

    一.Tablelayout简介 Tablelayout类以行和列的形式对控件进行管理,每一行为一个TableRow对象,或一个View控件.当为TableRow对象时,可在TableRow下添加子控件 ...

  3. C#动态调用WCF

    public class WcfChannelFactory { public WcfChannelFactory() { } /// <summary> /// 执行方法 WSHttpB ...

  4. EntityFunctions.AsNonUnicode

    http://blog.csdn.net/zzx3q/article/details/7863797 使用工具VS2010 凡是调用FindAll的地方,如果传入参数是String类型的变量(数字类型 ...

  5. 一个App完成入门篇(一)-从Hello world开始

    程序员学习新技术都是通过Hello World开始的,我们也不例外.第一课我们简单了解利用do平台开发App的基本流程,能了解到的知识点是: 开发环境搭建 创建开发者账号 新建项目 拖拽一个组件 修改 ...

  6. WCF基础教程之开篇:创建、测试和调用WCF

    一转眼,又半个月没有更新博客了.说实话,最近确实是有点忙.不过即使再忙忙,也要抽空来学习一些东西.最近用WCF比较多,就来跟大家分享一下关于WCF的知识吧!为了让大家都能看懂,照顾一些没有学过WCF的 ...

  7. 在MVVM模式中,按钮Click事件的绑定方法

    在MVVM模式中,我们将Button的方法写到ViewModel中,然后绑定到前端界面.通常的做法是写一个类,继承ICommand接口,然而如果按钮比较多的话,就需要写很多的类,对于后期维护造成很大的 ...

  8. [异常解决] ubuntu上安采用sudo启动的firefox,ibus输入法失效问题解决

    采用sudo启动的应用是root权限的应用, ibus失效是因为ibus的初始配置采用user权限: 而root下运行的firefox输入法的配置还是停留在默认情况~ 解决方案是在shell下以roo ...

  9. 学习Scala第一篇-从hello World开始

    最近开始系统性的学习scala.其实之前使用过scala的,比如我在用Gatling这款性能测试工具的时候就接触到了scala了.Gatling本身就是用Scala写的,而且Gatling的性能测试配 ...

  10. MVC5:使用Ajax和HTML5实现文件上传功能

    引言 在实际编程中,经常遇到实现文件上传并显示上传进度的功能,基于此目的,本文就为大家介绍不使用flash 或任何上传文件的插件来实现带有进度显示的文件上传功能. 基本功能:实现带有进度条的文件上传功 ...