注:以下仅为可视化示例,适合初学者学习或有相关功能需求的小白借鉴。Cesium绘制几何实体以及Echarts绘制图表的功能非常强大,大家可以根据需要自行调整:
Cesium官方API文档https://www.vvpstk.com/public/Cesium/Documentation/Apache ECharts官方使用手册
https://echarts.apache.org/handbook/zh/how-to/chart-types/bar/basic-bar
(一)问题描述
对某全球性指标进行计算,计算结果可视化,要求包括:
1. 以点符号标识国家或地区,点符号的大小与指标大小成比例,即指标大的国家或地区其点符号也更大,反之更小;
2. 用柱状图列出排名前10位的国家或地区及其指标值;
最终效果如下:
(二)解决步骤
1. 数据格式
- points:存放国家或地区代码及其数值的字典数组,其中元素格式为{‘0’:国家或地区三字码,’1‘:指标值},例如{’0‘:’CHN‘,’1‘:10.899999}
- code3Coord:存放国家或地区代码及其经纬度字典,其格式为{'国家或地区三字码‘:[经度,维度]},例如{’ABW‘:[-69.9669,12.50291667]}
国家或地区三字码对照表https://www.gdeltproject.org/data/lookups/CAMEO.country.txt
2. Cesium绘制点
(1)在<head>中引入Cesium及其样式文件
<!--引入Cesium-->
<script src="https://cesium.com/downloads/cesiumjs/releases/1.105/Build/Cesium/Cesium.js"></script>
<!--引入Cesium CSS-->
<link href="https://cesium.com/downloads/cesiumjs/releases/1.105/Build/Cesium/Widgets/widgets.css"rel="stylesheet"/>
注:Cesium引入支持CDN、NPM安装、下载CesiumJS包并引入三种方式,详细可参考:
官方文档CesiumJS Quickstarthttps://cesium.com/learn/cesiumjs-learn/cesiumjs-quickstart/(2)创建viewer并初始化
<body>
<!-- Cesium 容器 -->
<div id="cesiumContainer"></div>
<body>
<script>
//这里要在官网中进行注册,换成自己的Token
//https://ion.cesium.com/signin/tokens
Cesium.Ion.defaultAccessToken = "XXX";
// 初始化Viewer
var viewer = new Cesium.Viewer("cesiumContainer", {
animation: false,
timeline: false,
baseLayerPicker: false
});
//显示中心在中国
let china={
destination:Cesium.Cartesian3.fromDegrees(105,34.5,17850000.0),
orientation:{
heading:Cesium.Math.toRadians(0,0),
pitch:Cesium.Math.toRadians(-90),
roll:0.0
}
}
viewer.camera.setView(china);
//home键对应中国位置
viewer.homeButton.viewModel.command.beforeExecute.addEventListener(function(e){
e.cancel=true;
viewer.camera.flyTo(china);
})
</script>
注:以下部分都属于<script>内容,在这一部分viewer初始化之后,</script>标签之前
(2)根据数值对points进行排序,找出其中的最大值,用来计算点要素的大小
points.sort(function(a,b){
//按权重降序排序
return b[1]-a[1]
})
var maxWeight=points[1][1]
(2)遍历points,创建点要素并添加进viewer
points.forEach((point) => {
//从code3Coord中取出当前点坐标
let coord = code3ToCoord[point[0]];
if (!coord) return;
//国家代码
const country=point[0]
//指标值
const degree=point[1]
//Cesium绘制点要素
//创建一个点实体(point),并把它加入当前视图(viewer)
viewer.entities.add({
//创建的点实体的名字,选中该点要素时会显示这个名字,这里我用的是“国家代码=指标值”
name: `${country} degree=${degree}`,
//点坐标
position:Cesium.Cartesian3.fromDegrees(coord[0],coord[1]),
//点样式配置
point:{
//根据指标值计算点要素大小
pixelSize:100*point[1]/maxWeight,
color:Cesium.Color.RED.withAlpha(0.5),
//点大小随缩放(camera距离)变化
scaleByDistance: new Cesium.NearFarScalar(1500, 1, 20000, 0.7),
//2000-20000000m距离范围之外的点不显示,保持界面整洁美观
distanceDisplayCondition: new Cesium.DistanceDisplayCondition(2000, 20000000)
},
});
这里对点样式的配置做几点说明:
a)这里指标值数值偏大,如果直接用来计算点要素大小会导致点很大,所以才会用除以最大值再乘以100的方式来调整大小至合适的范围;
b)颜色加上withAlpha(0.5)调整透明度至50%,看起来更美观一些;
c)scaleByDistance:new Cesium.NearFarScalar(1500, 1, 20000, 0.7)
含义:从1500米到20000米,随着距离拉远,缩放比例由1插值变成0.7
- 0-1500米,缩放比固定为1
- 1500-20000米,缩放比随着距离变大,由1插值变成0.7
- 20000米以上,缩放比固定为0.7
如果不加上这一项,点符号大小不会随camera距离改变,可以理解成缩放时地球变大或变小,但点不变,就像这样:
d)distanceDisplayCondition: new Cesium.DistanceDisplayCondition(2000, 20000000)
超过2000-20000m这个范围的地物不显示。如果不加这一项,地球背面的点符号可能会露出,看起来像鼓个大包,不美观:
样式调整后的效果:
3. Echarts绘制柱状图
(1)在<head>中引入echarts
<script src="./tools/echarts/echarts.min.js"></script>
注:echarts的安装和引入方式也包括CDN引入、npm安装、下载echarts包并引入三种方式,详细可参考官方文档
获取 ECharts - 入门篇 - 使用手册 - Apache EChartshttps://echarts.apache.org/handbook/zh/basics/download(2)创建echarts容器并绘制柱状图
<body>
<!--echarts容器-->
<div id="barMap" style="width: 600px;height:300px;" ></div>
</body>
<script>
//初始化echarts图
var myChart = echarts.init(document.getElementById("barMap"));
var option;
//添加配置信息
option = {
//鼠标悬浮时,在柱顶部显示数值
emphasis: { label: { show: true ,position:'top'} },
xAxis: {
type: 'category',//x轴代表的数值类型
data: xdata, //x轴的数据(刻度标签)
},
yAxis: {
type: 'value',//y轴代表的数值类型
//这里类型是value(值),y轴刻度就代表指标值
},
//柱状图数据
series: [
{
data: ydata,//柱状图要展示的值列表(柱的高度)
type: 'bar',//图表类型:柱状图
}
]
};
option && myChart.setOption(option);
</script>
4. CSS简单调整一下页面布局
<style>
html,
body,
#cesiumContainer {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#barMap{
background-color: white;
position:fixed;
bottom:20px;
right:20px;
border-radius: 25px;
padding-left:40px;
}
</style>