Heatmap heat map 3D application based on HTML5

Heatmap heatmap gathers information from many data points into an intuitive visual color effect. Heatmap has been widely used in weather forecasting, medical imaging, computer room temperature monitoring and other industries, and even data analysis in the field of competitive sports.

Viz Libero heat map

There have been many articles sharing the principle of generating Heatmap heatmaps. You can refer to " How to make heat maps " and " How to make heat maps in Flex ". This article will introduce the implementation method based on HTML5 technology, mainly based on Cavans and WebGL. The application of HTML5 2D and 3D technology, first the interface effect and operation video realized by the final example :

IMG_1036


The most famous open source js library for implementing Heatmap is  heatmapjs  . This framework has been developed for more than 2 years. The author Patrick Wied recently decided to provide paid commercial support services on the basis of maintaining open source. This is a good thing. Most of the open source projects on earth After the author made a barely usable primary version, it has not been updated for many years, and the products that can actually be used online do not need continuous improvement, enhance scalability and provide special customized services, considering that the author has been free for the past two years. I have invested so much ( Over the last 2 years, I devoted  more than 500 hours  of work to improving heatmap.js to make it a truly great library.  ), I hope this article can also help the author to promote his role in China.

The 2D rendering method of Canvas adopted by heatmapjs  is implemented. This CPU-based rendering method is suitable for hundreds of thousands of points, but if you need to calculate the effect of thousands of nodes in real time, you still have to rely on the GPU method with more powerful concurrency. , if you use HTML5, it can only be a WebGL solution. Fortunately, Florian Boesch provided a heatmap method based on WebGL in the " High Performance JS heatmaps " blog, and made it open source at https://github.com/pyalot/webgl-heatmap   The quality of these two open source libraries is not bad. One is based on Canvas and the other is based on WebGL. The latter has higher performance, but requires a browser that supports WebGL. The documentation examples of heatmapjs  are relatively comprehensive, but the interfaces of both are very simple. It is easy to learn, and the code is only a few hundred lines. You can choose or even optimize the code according to the project situation.

Going back to the example we want to implement, I will use heatmapjs to calculate the heat map in real time in memory, combined with hightopo 's HT for Web 3D engine, a 3D network topology map with a bunch of node connections, where nodes represent heat sources, The closer it is to the ground, the higher the ground temperature. In this way, the xz surface coordinate information of each node is used as the xy two-dimensional coordinate information of the point to be passed to heatmapjs, and the elevation of the three-dimensional node is the y-axis information, which is used as the distance information from the ground. , the larger the distance, the smaller the value to be passed to heatmapjs, and finally the 3D topology automatic layout elastic algorithm of HT for Web is started , so that the temperature heat map of the floor can be visually observed when the primitive nodes change dynamically in different spatial positions. change effect.

The core of the code is to overload the forceLayout.onRelaxed function. In each automatic layout process, the information of all heat source nodes is constructed into the data required by the heatmap, and at the same time, ht.Default.setImage('hm-bottom', heatmap._renderer.canvas) ;Register the canvas of the heat map as an HT image, and the floor element of the floor is bound to the registered 'hm-bottom' image, so that the canvas can be drawn in memory, and then the 3D engine of HT for Web uses Cavnas as a texture The information is dynamically presented to the effect of the 3D scene.

The entire implementation code is less than 100 lines as follows. You can also use the WebGL method of https://github.com/pyalot/webgl-heatmap  to implement it. This is an interesting process from 3D to 2D and then to 3D. This is what HTML5 technology can do without The charm of seam fusion of various schemes!

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


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324536900&siteId=291194637