文档章节

基于HTML5实现的Heatmap热图3D应用

xhload3d
 xhload3d
发布于 2014/09/12 00:06
字数 1318
阅读 6378
收藏 136

Heatmap热图通过众多数据点信息,汇聚成直观可视化颜色效果,热图已广泛被应用于气象预报、医疗成像、机房温度监控等行业,甚至应用于竞技体育领域的数据分析。

Viz Libero heat map

已有众多文章分享了生成Heatmap热图原理,可参考《How to make heat maps》和《How to make heat maps in Flex》,本文将介绍基于HTML5技术的实现方式,主要基于Cavans和WebGL这两种HTML5的2D和3D技术的应用,先上最终例子实现的界面效果和操作视频

IMG_1036


实现Heatmap的开源js库比较出名的就是 heatmapjs ,该框架发展了2年多,作者Patrick Wied最近决定在保持开源的基础上,提供有偿的商业支持服务,这是好事,地球上绝大部分开源项目作者搞个barely可用的初级版本后,就多年不见更新了,而真正能实际上线使用的产品哪有不需要持续完善、增强可扩展性以及提供特殊定制服务的,考虑到作者这两年已无偿投了这么多(Over the last 2 years, I devoted more than 500 hours of work to improving heatmap.js to make it a truly great library. ),希望此文也能帮作者在国内起点宣传作用。

heatmapjs 采用的Canvas的2D绘制方式实现,这种基于CPU的绘制方式对于几百几千的点还凑合,但如果需要实时运算成千上万节点效果的,还是得依靠并发性更强大的GPU方式,采用HTML5的话只能是WebGL方案,还好Florian Boesch在《High Performance JS heatmaps》博客中提供了基于WebGL实现的heatmap方式,并将其开源在https://github.com/pyalot/webgl-heatmap  上,这两个开源库质量都还不错,一个基于Canvas实现,一个基于WebGL实现,后者性能高点,但需要支持WebGL的浏览器,heatmapjs 的文档例子比较全面,但两者接口都非常简单易学,代码也都就几百行,你完全可以根据项目情况选择甚至进行代码改造优化。

回到我们要实现的例子,我将采用heatmapjs在内存中实时运算出热图,结合hightopoHT for Web的3D引擎,以一堆节点连线关系的3D的网络拓扑图,其中节点代表热源,其越接近地面则地面温度越高,这样每个节点的xz面坐标信息作为要传入给heatmapjs的点xy二维坐标信息,三维节点的elevation也就是y轴信息,则作为离地面的距离信息,距离越大转成要传入heatmapjs的value值越小,最后启动HT for Web的三维拓扑自动布局弹力算法,这样可直观的观察图元节点在不同的空间位置动态变化时地板的温度热图变化效果。

代码核心就在重载forceLayout.onRelaxed函数,在每次自动布局过程将所有热源节点的信息构建成heatmap需要的数据,同时通过ht.Default.setImage(‘hm-bottom’, heatmap._renderer.canvas);将热图的canvas注册成HT的图片,而floor的地板图元绑定了注册的’hm-bottom’图片,这样就实现了内存绘制canvas,然后通过HT for Web的3D引擎将Cavnas作为贴图信息动态呈现到3D场景的效果。

整个实现代码如下不到百行,你也可以采用https://github.com/pyalot/webgl-heatmap 的WebGL方式来实现,这样就是3D到2D再到3D的有趣过程,这就是HTML5技术可无缝融合各种方案的魅力!

MAX = 500;
WIDTH = 1024;
HEIGHT = 512;        
function init() {                           
	dataModel = new ht.DataModel();            
	g3d = new ht.graph3d.Graph3dView(dataModel);                            
	g3d.getMoveMode = function(e){ return 'xyz'; };                        
	view = g3d.getView();            
	view.className = 'main';
	document.body.appendChild(view);    
	window.addEventListener('resize', function (e) { g3d.invalidate(); }, false);            
	heatmap = h337.create({ width: WIDTH, height: HEIGHT });                                   
	ht.Default.setImage('hm-bottom', heatmap._renderer.canvas);            
	var floor = new ht.Node();
	floor.s3(WIDTH, 1, HEIGHT);
	floor.s({
		'3d.selectable': false,
		'layoutable': false,
		'all.visible': false,
		'top.visible': true,
		'top.image': 'hm-bottom',
		'top.reverse.flip': true,
		'bottom.visible': true,
		'bottom.transparent': true,
		'bottom.opacity': 0.5,
		'bottom.reverse.flip': true                
	});
	dataModel.add(floor);            
	var root = createNode();                   
	for (var i = 0; i < 3; i++) {
		var iNode = createNode();                       
		createEdge(root, iNode);
		for (var j = 0; j < 3; j++) {
			var jNode = createNode();                            
			createEdge(iNode, jNode);                                                         
		}
	}                   
	forceLayout = new ht.layout.Force3dLayout(g3d);  
	forceLayout.start();
	forceLayout.onRelaxed = function(){
		var points = [];
		dataModel.each(function(data){
			if(data instanceof ht.Node && data !== floor){
				var p3 = data.p3();
				if(p3[1] > MAX){
					p3[1] = MAX;
					data.setElevation(MAX);
				}
				else if(p3[1] < -MAX){
					p3[1] = -MAX;
					data.setElevation(-MAX);
				}                        
				points.push({
					x: p3[0] + WIDTH/2,
					y: p3[2] + HEIGHT/2,
					value: MAX - Math.abs(p3[1])
				});
			}
		});
		heatmap.setData({data: points, min: 0, max: MAX});
	};
}
function createNode(){
	var node = new ht.Node();             
	node.s({
		'shape3d': 'sphere',
		'shape3d.color': '#E74C3C',
		'shape3d.opacity': 0.8,
		'shape3d.transparent': true,
		'shape3d.reverse.cull': true
	});
	node.s3(20, 20, 20);
	dataModel.add(node);
	return node;
}
function createEdge(sourceNode, targetNode){
	var edge = new ht.Edge(sourceNode, targetNode);
	edge.s({
		'edge.width': 3,
		'edge.offset': 10,                
		'shape3d': 'cylinder',
		'shape3d.opacity': 0.7,
		'shape3d.transparent': true,
		'shape3d.reverse.cull': true
	});
	dataModel.add(edge);
	return edge;
}


© 著作权归作者所有

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

评论(35)

笑莫问
笑莫问
wrean2013
wrean2013
haahahahahaha
我叫金正恩
我叫金正恩
firefoxmmx
firefoxmmx
TonyJian
TonyJian
淘淘我的小宝宝
淘淘我的小宝宝
强子1985
强子1985
sun
Eeqlee
Eeqlee
Liuxd
Liuxd
叫我蝴蝶吧
叫我蝴蝶吧
基于HTML5实现3D热图Heatmap应用

Heatmap热图通过众多数据点信息,汇聚成直观可视化颜色效果,热图已广泛被应用于气象预报、医疗成像、机房温度监控等行业,甚至应用于竞技体育领域的数据分析。 http://www.hightopo.com/gu...

xhload3d
2015/10/13
322
0
推荐六款炫酷的HTML5效果插件

1. HTML5 3D图片阴影翻转动画 效果很酷 分享一款很酷的HTML5 3D动画特效,这款3D特效可以为你的图片增加阴影的效果,而且可以让图片在鼠标滑过的时候出现3D翻转的动画效果。这和HTML5 3D动画...

tower1229
06/26
0
0
炫酷实用 7款jQuery/HTML5图片应用

jQuery非常强大,我们这里有很多关于jQuery焦点图的插件,今天我们精选了7款利用jQuery和HTML5实现的超炫酷图片特效应用,有些也是焦点图插件,一起来看看吧。 1、HTML5 3D衣服摆动特效 超酷...

老鸟的空间
2014/07/05
0
0
9款超绚丽的HTML5/CSS3应用和动画特效

HTML5 现在已经不是很前卫的东西了,越来越多的网站和移动应用都在不断地尝试使用HTML5来更好地优化用户体验。今天我们要分享9款超绚丽的HTML5/CSS3应用和动画特效,这里面有菜单、按钮、图片...

切切歆语
2017/10/23
0
0
基于HTML5技术的电力3D监控应用(二)

上篇介绍了我们电力项目的基本情况,我们选用HTML5技术还是顶着很大压力,毕竟HTML5技术性能行不行,浏览器兼容性会不会有问题,这些在项目选型阶段还是充满疑惑,项目做到现在终于快收尾了我...

xhload3d
2013/12/15
0
1

没有更多内容

加载失败,请刷新页面

加载更多

当程序员有了中年危机 你会发现你就是个屁

前言 程序员是一个怎样的存在?引用一句鸡汤的名言来说:你以为你用双手改变了世界,实际上是苍老了自己。为什么我今天会抛出这个话题,其实我也是一个懵懂的少年,我也曾经为了成为一名程序...

架构师springboot
21分钟前
1
0
大型网站B2C商城项目实战+MongoDB+Redis+zookeeper+MySQL

本文列出了当今计算机软件开发和应用领域最关键部分,如果你想保证你现在以及未来的几年不失业,那么你最好跟上这些技术的发展。虽然你不必对这十种技术样样精通,但至少应该对它们非常熟悉。...

java知识分子
21分钟前
2
0
大型企业网络系统集成方案如何设计?

网络系统集成是企业实现无纸化办公和即时通讯办公的基础建设,在以生产效率为核心竞争力的市场中,企业想要快速获取信息并有效提高企业工作效率及业务能力,企业网络系统集成是必不可少的,由...

Java干货分享
22分钟前
1
0
Spring应用学习——IOC

1. Spring简介 1. Spring的出现是为了取代EJB(Enterprise JavaBean)的臃肿、低效、脱离现实的缺点。Spring致力于J2EE应用的各层(表现层、业务层、持久层)的解决方案,Spring是企业应用开...

江左煤郎
23分钟前
1
0
用Redis轻松实现秒杀系统

导论 曾经被问过好多次怎样实现秒杀系统的问题。昨天又在CSDN架构师微信群被问到了。因此这里把我设想的实现秒杀系统的价格设计分享出来。供大家参考。 秒杀系统的架构设计 秒杀系统,是典型...

James-
31分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部