(十一)VUE3中实现Cesium,EChart,vue3-draggable-resizable的使用

先上图

一、数据准备

国家省界图来自天地图:天地图 服务中心 (tianditu.gov.cn),该地图下好就是GeoJSON格式,这方便了直接在Cesium中使用。当然里面是没有人口数据的,数据可以根据自己需要在GIS软件修改,比如QGIS,修改属性表的字段和值即可。我这里是添加的人口数据作为演示。

二、加载数据以及拉伸

这里的拉伸数据,参看前面的加载GeoJSON笔记,原理是一样的,只是这里增加了随机渲染颜色。

该部分代码

 const dataSources = await Cesium.GeoJsonDataSource.load('src/assets/geojson/ceshi4.geojson')
        // if (!viewer) return
        viewer.dataSources.add(dataSources)  
        const entities = dataSources.entities.values
        const colorHash = {}
        for (let i = 0; i < entities.length; i++) {
            const entity = entities[i]
            const name = entity.properties.name
            const totalPeople = entity.properties.total
            const manNumber = entity.properties.man
            const womanNumber = entity.properties.woman
            const sexRatio = entity.properties.SexRatio
            if (!peopleData.some(item => item.name._value === name._value)) {
                peopleData.push({
                    name,
                    total: totalPeople,
                    man: manNumber,
                    woman: womanNumber,
                    SexRatio: sexRatio,
                })
            }

            let color = colorHash[name]
            if (!color) {
                color = Cesium.Color.fromRandom({ alpha: 1.0 })
                colorHash[name] = color
            }
            entity.polygon.material = color
            entity.polygon.outline = false
            entity.polygon.extrudedHeight = totalPeople / 200.0
        }
        viewer.zoomTo(dataSources)

三、鼠标移动到GeoJSON上时显示数据

//JS部分
const handleMouseMove = (event) => {
    const pickedFeatureLocal = viewer.scene.pick(event.endPosition)
    if (Cesium.defined(pickedFeatureLocal)) {
        pickedFeature.value = pickedFeatureLocal.id
        showNameOverlay.value = true
        const nameOverlay = document.querySelector('.backdrop')
        if (nameOverlay) {
            nameOverlay.style.display = "block";
            nameOverlay.style.bottom = `${viewer.canvas.clientHeight - event.endPosition.y}px`
            nameOverlay.style.left = `${event.endPosition.x}px`
        }
    } else {
        showNameOverlay.value = false
    }

}

const initViewerEvents = () => {
    if (!viewer) return
    const screenSpaceEventHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
    screenSpaceEventHandler.setInputAction(handleMouseMove, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
}


//HTML部分
 <!-- 鼠标悬停显示信息的容器 -->
    <div v-if="showNameOverlay" class="backdrop" :style="{ display: showNameOverlay ? 'block' : 'none' }">
        <!-- 鼠标悬停显示信息的内容 -->
        <div>
            <div>
                <strong>{{ pickedFeature.properties.name._value }}</strong>
            </div>
            <div>
                <span>总人口(人):{{ pickedFeature.properties.total._value }}</span>
                <br>
                <span>男性总人口(人):{{ pickedFeature.properties.man._value }}</span>
                <br>
                <span>女性总人口(人):{{ pickedFeature.properties.woman._value }}</span>
                <br>
                <span>性别比:{{ pickedFeature.properties.SexRatio._value }}</span>
            </div>
        </div>
    </div>

注意:这里要将它的position设置为absolute

四、EChart显示和拖拽

拖拽是用了现成的轮子:vue3-draggable-resizablevue3-draggable-resizable/docs/document_zh.md at main · a7650/vue3-draggable-resizable (github.com)

//HTML部分    
<Vue3DraggableResizable :initH="500" :initW="600" :minW="400" :minH="400" v-model:x="x" v-model:y="y"
        :resizable="true">
        <div class="chart-title">统计图</div>
        <el-tabs type="border-card" class="demo-tabs">
            <el-tab-pane>
                <template #label>
                    <span class="custom-tabs-label">
                        <img src="@/assets/icon/pie.svg" style="width: 20px; height: 20px; margin-left: 4px;" />
                    </span>
                </template>
                <v-chart class="chart" :option="pieOption" autoresize> </v-chart>
            </el-tab-pane>
            <el-tab-pane>
                <template #label>
                    <span class="custom-tabs-label">
                        <img src="@/assets/icon/line.svg" style="width: 20px; height: 20px; margin-left: 4px;" />
                    </span>
                </template>
                <v-chart class="chart" :option="lineOption" autoresize> </v-chart>
            </el-tab-pane>
            <el-tab-pane>
                <template #label>
                    <span class="custom-tabs-label">
                        <img src="@/assets/icon/column.svg" style="width: 20px; height: 20px; margin-left: 4px;" />
                    </span>
                </template>
                <v-chart class="chart" :option="barOption" autoresize> </v-chart>
            </el-tab-pane>
        </el-tabs>
    </Vue3DraggableResizable>

//JS部分,这里只展示一个表,因为基本类似
//柱状图配置
const barOption = ref({})
const barEchart = (data) => {
    barOption.value = {
        title: {
            text: '人口数量'
        },
        tooltip: {
            trigger: 'axis',
            axisPointer: {
                type: 'shadow'
            }
        },
        grid: {
            left: '3%',
            right: '4%',
            bottom: '3%',
            containLabel: true
        },
        xAxis: [
            {
                type: 'category',
                data: data.map(item => item.name),
                axisTick: {
                    alignWithLabel: true
                },
                axisLabel: {
                    rotate:-90
                }
            }
        ],
        yAxis: [
            {
                type: 'value'
            }
        ],
        series: [
            {
                name: '人口数',
                type: 'bar',
                barWidth: '60%',
                data:data
            }
        ]
    }
  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值