3D-Earth/Three/Gio

2,292 阅读6分钟

@[TOC]

最近在学习3dEarth+3dScatter+3dBar在网上找到了一些例子汇总了下,和大家分享。

Earth

  • 3D地球
    • Echarts
    • Three
    • Gio.js

Echarts

github.com/i1520/echar…

所需素材:world.jpg、starfield.jpg、pisa.hdr --- www.echartsjs.com/zh/download…

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>
	<body>
		<div id="earth" style="width: 100%; height: 600px"></div>
		<script src="../js/lib/echarts.min.js"></script>
		<script src="../js/lib/echarts-gl.min.js"></script>
		<script src="../js/lib/world.js"></script>
		<script>
		var dom = document.getElementById("earth")
		var myChart = echarts.init(dom);
		option = {
			  backgroundColor: "#000",
			  globe:{
			    baseTexture: "../img/world.jpg",
			    heightTexture: "../img/world.jpg",
			     displacementScale: 0.04,
			    environment: "../img/starfield.jpg",
			    shading:"realistic",
			    realisticMaterial: {
		            roughness: 0.9
		        },
			    postEffect: {
		            enable: true
		        },
		        light: {
		            main: {
		                intensity: 5,
		                shadow: true
		            },
		            ambientCubemap: {
		                texture: "../img/pisa.hdr",
		                diffuseIntensity: 0.2
		            }
		        }
			  }
		 
		};
		if (option && typeof option === "object") {
		  myChart.setOption(option, true);
		}
		</script>
	</body>
</html>

效果图:

img

配合散点图可以实现位置和部分效果

3d地球+3D Scatter+3D Lines做攻击趋势

//vue 装依赖后直接引入,其他的话官网下载文件,3d需要gl支持,具体属性含义详见echarts Api
var echarts = require('echarts');
require('echarts-gl');
var worldfightchart = echarts.init(document.getElementById('globefight'));
var canvas = document.createElement('canvas');
var mapChart = echarts.init(canvas, null, {
             width: 2048,
             height: 1024
         });
         mapChart.setOption({
             geo: {
             type: 'map',
             map: 'world',
             top: 0,
             left: 0,
             right: 0,
             bottom: 0,
             boundingCoords: [[-180, 90], [180, -90]],
             silent: true,
             itemStyle: {
                 normal: {
                     borderColor: 'rgb(50, 50, 150)',
                     areaColor: 'transparent'
                 }
             },
             label: {
                 normal: {
                     textStyle: {
                         color: '#fff',
                         fontSize: 40
                     }
                 }
             }
         }
     });        
var series= [{ 
          type: 'lines3D',
          name: 'map',
          effect: {
                 show: true,
                 period: 2,
                 trailWidth: 2.5,
                 trailLength: 0.3,
                 trailOpacity: 3,
                 trailColor: 'red'
             },
             lineStyle: {
                width: 2,
                color: 'red',
                // color: 'rgb(118, 233, 241)',
                opacity: 0.1
             },
             blendMode: 'lighter',
             data:linesData
             // data: [{ 
                 //            二维数组里两个相对应形成路径图连线,第一个起始坐标第二个终点坐标
                    //     coords:[[-75.6971931, 45.4215296],[116.407, 39.9042]],
                    //            meta暂时没用,本来想做formatter的移入展示信息,后来发现lines3D 还不支持
                    //     meta: { 
                    //             from: "地球",
                    //             name: "10-21 15:53:55发现攻击",
                    //             to: "月球",
                    //             value: 1 
                           },
                    //     fromName:'地球',
                    //     toName:'月球'
                    // }]
                }];
            series.push({
                type: 'scatter3D',
                coordinateSystem: 'globe',
                blendMode: 'lighter',
                label: {
                     show: false,
                     emphasis: {
                show: false
                }
                     },
                symbolSize: 3,
                itemStyle: {
                    color: 'yellow',
                    opacity: 0.7
                },
                data:arrFrom
                // data: [
                //          scatter3D同样是二维数组,第一个起点,第二个终点,meta做formatter的移入展示信息scatter3D支持
                //          [-75.6971931, 45.4215296,{
                //                 meta:  { from: "地球",
                //                 name: "10-21 15:53:55发现攻击行为",
                //                 to: "月球",
                //                 value: 1 }, 
                //                  }
                //          ],
                //            [116.407, 39.9042,{meta:  { from: "地球",
                //                 name: "10-21 15:53:55发现攻击行为",
                //                 to: "月球",
                //                 value: 1 }, }]]
            });
            worldfightchart.setOption({
                 tooltip: {
                            trigger: 'item',
                            formatter: function (params) {
                                // console.log(params)
                                if (params.data[2] && params.data[2].meta) {
                                    const meta = params.data[2].meta;
                                    if (meta.from && meta.to) {
                                        return `${meta.from}->${meta.to}<br>${meta.name}: ${meta.value}`;
                                    } else {
                                        return `${meta.name}: ${meta.value}`;
                                    }
                                } else {
                                    return ``;
                                }
                            }
                        },
                // legend: {
                //     selectedMode: 'single',
                //     left: 'left',
                //     data: Object.keys(routesGroupByAirline),
                //     orient: 'vertical',
                //     textStyle: {
                //         color: '#fff'
                //     }
                // },
                //  backgroundColor:'rgba(128, 128, 128, 0)',
                globe: {
                    globeRadius: 80,
                    baseTexture: '/static/img/earth.jpg',
                    //environment: 'asset/world.topo.bathy.200401.jpg',
                    heightTexture: '/static/img/elev_bump_4k.jpg',
                    environment: 'none',
                    displacementScale: 0.04,
                    //displacementQuality: 'high',

                    //baseColor: '#000',

                    shading: 'realistic',
                    realisticMaterial: {
                        roughness: 0.2,
                        metalness: 0
                    },

                    postEffect: {
                        enable: true,
                        depthOfField: {
                            enable: false,
                            focalDistance: 150
                        }
                    },
                    temporalSuperSampling: {
                        enable: true
                    },
                    light: {
                        ambient: {
                            intensity: 0.5
                        },
                        main: {
                            intensity: 0.5,
                            shadow: false
                        }
                        // ambientCubemap: {
                        //     // texture: '/static/img/pisa.hdr',
                        //     exposure: 2,
                        //     diffuseIntensity: 0.1,
                        //     specularIntensity: 1
                        // }
                    },
                    viewControl: {
                        //autoRotate: false//控制是否自己旋转
                    },
                    layers: [{
                        type: 'blend',
                        blendTo: 'albedo',
                        texture: mapChart
                    }, {
                        type: 'blend',
                        blendTo: 'emission',
                        texture: '/static/img/night.jpg'
                    }, {
                        type: 'overlay',
                        texture: '/static/img/clouds.png',
                        shading: 'lambert',
                        distance: 10
                    }],
                    //图形是否不响应和触发鼠标事件,默认为 false,即响应和触发鼠标事件
                    silent: true
                },
                series: series
            });
        }

效果图:

imgscatter属性详解---blog.csdn.net/GJ454221763…

//Income:Z轴;Life Expectancy:Y轴;Country:X轴
//井深:Z轴;Y坐标:Y轴;X坐标:X轴
var jsonData=[["井深","Y坐标","人口密度","X坐标","Year"],
              [10,14,11,2014],
              [11,25,22,2015],
              [12,36,33,2016],
              [13,47,40,2017]
             ];
var myChart = echarts.init(document.getElementById('main'));
function setOption(datas,x_min,x_max,y_min,y_max,xuanzhuan){
var myChart = echarts.init(document.getElementById('main'));
option = {
     grid3D:  {
	 boxWidth:  60,						//图件宽
	 boxHeight: 122,						//图件高
	 boxDepth:  60,						//图件长
	 height: '100%',						//容器高
	 width: '100%',						//容器宽
	 bottom: 'auto',						//3D图与下容器的距离
	 top:'auto',			   				//3D图与上容器的距离
	axisLine:{
	   		lineStyle:{
	      			color:'yellow' 				//坐标轴轴线颜色
	       		}
	       	},
		    splitLine:{
		    	lineStyle:{
	       			color:'#222'  				//分割线颜色
	       		}
			},
			axisPointer:{
				lineStyle:{
	       			color:'#efe' 				//鼠标滑过分割线颜色
	       		}
			},
			environment: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
				  offset: 0, color: '#00aaff' 	// 天空颜色
				}, {
				  offset: 0.7, color: '#998866' // 地面颜色
				}, {
				  offset: 1, color: '#998866' 	// 地面颜色
				}], false),
			postEffect:{
				enable:false					//开启特效
			},
			viewControl:{
				projection: 'perspective',		//默认为透视投影'perspective',也支持设置为正交投影'orthographic'
				autoRotate: true,				//自动旋转
				autoRotateDirection: 'ccw',     //默认是 'cw' 从上往下看是顺时针 也可以取 'ccw'逆时针
				autoRotateSpeed: 4,				//默认10 自转速度
				autoRotateAfterStill: 5,		//默认3秒 鼠标静止操作后恢复自动旋转的时间间隔
				damping: 0.8,					//鼠标进行旋转,缩放等操作时的迟滞因子,在大于 0 的时候鼠标在停止操作后,视角仍会因为一定的惯性继续运动(旋转和缩放)
				animation: true,				//是否开启动画
				animationDurationUpdate: 1000,	//过渡动画的时长
				animationEasingUpdate: 'cubicInOut' //过渡动画的缓动效果
			},
			postEffect:{
				enable:false					//是否开启后处理特效,默认关闭 不能开  浏览器会卡
			}
	       },
	       xAxis3D: {
	      		show: true,
	      		name: '南北-X',
	      		nameTextStyle:{
	      			color: 'lime',
		       		fontWeight: 'normal'
	       		},
	       		min:x_min,
	       		max:x_max
	        },
	        yAxis3D: {
	        	show: true,
	       		name: '东西-Y',
	       		nameTextStyle:{
	       			color: 'lime',
	       			fontWeight: 'normal'
	       		},
	       		min:y_min,
	       		max:x_max
	        },
	        zAxis3D: {
	        	show: true,
	       		name: '井深-Z',
	       		nameTextStyle:{
	       			color: 'lime',
	        		fontWeight: 'normal'
	       		}
	        },
	        dataset: {
	            dimensions: [
	                '井深',
	                'Y坐标',
	                'X坐标',
	                {name: '井名', type: 'ordinal'}
	            ],
	            source: datas
	        },
	        series: [
	            {
	                type: 'scatter3D',				//3D类型
	                name: '测试',				    //名字
	                //coordinateSystem: 'grid3D',	//使用地球三维地理坐标系
	                //grid3DIndex: 0,				//坐标轴使用的 geo3D 组件的索引
	                symbol:'diamond',				//点形状 'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin', 'arrow', 'none'
	                symbolSize: 3.5,  				//点大小
	                itemStyle: {
	                	color:'white',		   		//点颜色
	                	borderColor: 'green',  		//点边框颜色
	                	opacity: 1,            		//点的透明度 1不透明
	                	borderWidth: 0.5       		//图形描边宽度
	                },
	                label:{
	                	show:false, 				//是否显示点上面的标签,默认false
	                	distance: 15,				//标签与点的距离
	                	position:'left',      		//标签位置
	                	textStyle:{
	                	    color:'black', 			//文字颜色
	                    	borderWidth:0,  		//标签上边框宽度
	                    	borderColor:'white',   	//边框颜色
	                    	fontFamily:'宋体',		//标签字体
	                    	fontSize:14,			//字体大小
	                    	fontWeight:'normal'		//是否加粗 
	                    }
	                },
	                emphasis:{
		               	itemStyle:{
		               		color:'green',			//鼠标移到点上的颜色变化
		               		opacity:1,				//不透明度
		               		borderWidth:0,			//图像描边宽度
		               		borderColor:'#fff' 		//图形描边颜色
		               	},
		               	label:{
		               		show:true,				//鼠标移动到点上是否显示标签
		               		distance: 15,			//标签与点的距离
		                   	position:'left',      	//标签位置
		                  	textStyle:{
		                   	    color:'black', 		//文字颜色
		                       	borderWidth:0,  	//标签上边框宽度
		                       	borderColor:'white',//边框颜色
		                       	fontFamily:'宋体',	//标签字体
		                       	fontSize:14,		//字体大小
		                       	fontWeight:'normal'	//是否加粗 
		                       }
		               	}
		               },
		           	blendMode:'lighter',			//混合模式默认使用的'source-over'是通过 alpha 混合,而'lighter'是叠加模式,该模式可以让数据集中的区域因为叠加而产生高亮的效果。
		           	silent:false,					//图形是否不响应和触发鼠标事件,默认为 false,即响应和触发鼠标事件。
		           	animation:true,					//是否开启动画
		           	animationDurationUpdate:500,	//过渡动画的时长
		           	animationEasingUpdate:'cubicOut',//过渡动画的缓动效果
		               encode: {
		                   x: 'X坐标',
		                   y: 'Y坐标',
		                   z: '井深',
		                   tooltip: [0, 1, 2, 3, 4]
		               }
		           }
		       ]
		   };
		myChart.setOption(option);
	    } 

Three

three多需要地球纹理图,如下图

如果需要更详细或更细节的地球则需要更多细节性图片(表面贴图,凹凸贴图,高光贴图,云层贴图......诸如此类)

表面贴图↓

.jpg

凹凸贴图↓

img

高光贴图↓

img

img

Gio.js

原文地址:juejin.cn/post/684490…

Gio.js 是一个基于 Three.js 的 web 3D 地球数据可视化的开源组件库。使用 Gio.js 的网页应用开发者,可以快速地以申明的方式创建自定义的 Web3D 数据可视化模型,添加数据,并且将其作为一个组件整合到自己的应用中

Gio.js 具有以下的特点:

  • 易用性 -- 仅使用 4 行 Javascript 即可创建 3D 地球数据可视化模型

  • 定制化 -- 使用 Gio.js 提供的丰富的 API 来创建自定义样式的 3D 地球

  • 现代化 -- 基于 Gio.js 构建高交互、跨平台、自适应的现代化 3D 前端应用

    基本使用:通过 NPM 或者 YARN 安装 giojs

    npm install giojs --save || yarn add giojs
    

    在 HTML 页面中添加了 Threejs 和 Giojs 依赖之后,就可以基于 Giojs 开发应用了。展示如何创建一个具有基础样式的 Gio 地球。

    <!DOCTYPE HTML>
    <html>
    <head>
    
      <!-- 引入 three.js -->
      <script src="three.min.js"></script>
    
      <!-- 引入 Gio.js -->
      <script src="gio.min.js"></script>
    
    </head>
    <body>
    
      <!-- 创建一个 div 作为 Gio 的绘制容器 -->
      <div id="globalArea"></div>
    
    </body>
    </html>
    

    在页面中添加以下 Javascript 代码来初始化 Gio 地球:

    <script>
    
        // 获得用来承载 Gio 地球的容器
        var container = document.getElementById( "globalArea" );
    
        // 创建 Gio 控制器
        var controller = new GIO.Controller( container );
    
        // 添加数据
        controller.addData( data );
    
        // 初始化并渲染地球
        controller.init();
    
    </script>
    

中文官网:giojs.org/index_zh.ht…

github地址:github.com/syt123450/g…

Giojs globe effect preview

在线例子:Jump