弹窗分两类,一类是随地球转动或移动而动态变化的,另外一种是不随之发生变化的。如下图所示
创建弹窗类的基本思路:传入弹窗位置、标题、标签数组和标签值数组
1、创建窗口
//创建dom
createDom() {
this.container = document.createElement("div");
this.container.innerHTML =
` <div class="Window-container" v-if="show">
<div class="Window-header">
<span class="Window-title"> ` + this.title + `</span>
<span class="Window-close" title="关闭" >×</span>
</div>
<div class="Window-body">
//在此处添加弹出窗口的body内容
</div>
</div>`
}
然后把创建的弹窗添加到cesium窗口画布上去
viewer.cesiumWidget.container.appendChild(this.container); //将字符串模板生成的内容添加到DOM上
2、在创建的窗口中添加一些自定义的内容
//添加自定义的部分,即body部分
initDom() {
for (let i = 0; i < this.values.length; i++) {
let item = document.createElement("div");
item.classList.add("Window-info-item");
let span = document.createElement("span");
span.classList.add("Window-info-label");
span.innerHTML = this.fields[i] + ":"
item.appendChild(span);
span = document.createElement("span");
span.classList.add("Window-info-text");
span.innerHTML = this.values[i];
item.appendChild(span);
this.container.getElementsByClassName("Window-body")[0].appendChild(item);
}
}
3、为弹出窗口添加事件
//点击关闭
initEvent() {
this.container.getElementsByClassName("Window-close")[0]
.onclick = e => {
this.container.remove(); //删除dom
this.viewer.scene.postRender.removeEventListener(this.postRender, this); //移除事件监听
}
}
其中的 this.postRender 为在球上添加的渲染事件
4、如果是随地球移动的窗口,则添加场景渲染事件,实时更新窗口位置
//添加场景事件
addPostRender() {
this.viewer.scene.postRender.addEventListener(this.postRender, this);
}
//场景渲染事件 实时更新标签的位置 使其与笛卡尔坐标一致
postRender() {
if (!this.container || !this.container.style) return;
const canvasHeight = this.viewer.scene.canvas.height;
const WindowPosition = new Cesium.Cartesian2();
Cesium.SceneTransforms.wgs84ToWindowCoordinates(this.viewer.scene, this.position, WindowPosition);
this.container.style.position = "absolute";
this.container.style.bottom = canvasHeight - WindowPosition.y + 80 + "px";
const elWidth = this.container.scrollWidth;
this.container.style.left = WindowPosition.x - (elWidth / 2) + "px";
}
如果是不随地球移动的弹窗则在样式"style.css"中调整好位置即可
.Window-container {
position: absolute;
left: 5%;
bottom: 2%;
min-width: 80%;
min-height: 30%;
color: white;
}
添加好后需要在窗口下方添加一个类似箭头的东西如下图黄框所示,这个标志一般用样式css文件做,只需要添加如下代码:
.Window-container::before {
position: absolute;
content: "";
top: 100%;
left: calc(50% - 20px);
border: 20px solid transparent;
border-top: 40px solid rgba(30, 33, 42, 0.5);
}
二、有时候我们添加的echarts图需要与球上的数据进行联动,但是如果想实现跳转,就得有经纬度坐标,所以得想办法把echarts表中的数据和经纬度数据联系起来
俺这里画echarts图的数据中就包含经纬度高度,只是画图的时候用了高度和点位里程,所以点击某点的时候,只需要根据剖面图所属的圩区和点的里程就可以确定唯一的点,跳转到对应经纬度即可
var zr = this.myChart.getZr()
var charts = this.myChart;
var title = this.title;
var viewer = this.viewer;
//注释的功能,是判断点击折线图的拐点。
zr.on('click', function (param) {
const pointInPixel = [param.offsetX, param.offsetY]
let pointInGrid = charts.convertFromPixel({ seriesIndex: 0 }, pointInPixel)
// 所点击点的X轴坐标点所在X轴data的下标
let Index = pointInGrid[0];
// 使用getOption() 获取图表的option
let op = charts.getOption();
// 点击点的X轴对应坐标的名称
var xValue = op.xAxis[0].data[Index];
for (let i=0;i<features.length;i++) {
if (features[i].properties.polder == title & features[i].properties.mileage == xValue){
// console.log("匹配成功")
viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(features[i].properties.longitude, features[i].properties.latitude, 50), // 经度,纬度,高度
duration: 1,
})
break;
}
}
});
注意:获取放图表的div初始化时,好像只能用
var chartDom = document.getElementById("Window-body")