完善页面细节
This commit is contained in:
114
uni_modules/charts/EChartsView.uvue
Normal file
114
uni_modules/charts/EChartsView.uvue
Normal file
@@ -0,0 +1,114 @@
|
||||
<template>
|
||||
<view class="ec-wrap">
|
||||
<!-- 使用 ref 来获取容器 -->
|
||||
<view ref="ecCanvas" class="ec-canvas" :style="{ width: '100%', height: '100%' }"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
import { ref, onMounted, onBeforeUnmount, watch, onUnmounted } from 'vue'
|
||||
import * as echarts from 'echarts'
|
||||
|
||||
const props = defineProps({
|
||||
option: { type: Object, default: () => ({}) },
|
||||
theme: { type: String, default: 'light' }
|
||||
})
|
||||
|
||||
const ecCanvas = ref<UniElement | null>(null)
|
||||
let chart: any = null
|
||||
let resizeObserver: any = null
|
||||
|
||||
// 加载并注册中国地图
|
||||
async function loadChinaMap() {
|
||||
try {
|
||||
// 检查是否已注册过
|
||||
if (echarts.getMap('china')) return
|
||||
|
||||
// 尝试从 CDN 加载中国地图
|
||||
const response = await fetch('https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json')
|
||||
if (response.ok) {
|
||||
const geoJson = await response.json()
|
||||
echarts.registerMap('china', geoJson)
|
||||
console.log('[EChartsView] 中国地图载入并注册成功')
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('[EChartsView] 地图加载失败,降级处理', e)
|
||||
}
|
||||
}
|
||||
|
||||
const initChart = async () => {
|
||||
if (!ecCanvas.value) {
|
||||
console.warn('[EChartsView] 找不到 canvas 引用')
|
||||
return
|
||||
}
|
||||
|
||||
// 在 H5 环境下,ecCanvas.value 会表现为 HTML 元素
|
||||
const el = ecCanvas.value as any; // 这里显式作为 any 使用以避开UTS编译器对DOM API的严格限制
|
||||
|
||||
if (chart) {
|
||||
chart.dispose()
|
||||
chart = null
|
||||
}
|
||||
|
||||
// 计算是否需要地图
|
||||
const opt = props.option as any;
|
||||
const needsMap = opt['geo'] != null || (opt['series'] != null && Array.isArray(opt['series']) && (opt['series'] as any[]).some(s => s.type === 'map' && s.map === 'china'))
|
||||
|
||||
if (needsMap) {
|
||||
await loadChinaMap()
|
||||
}
|
||||
|
||||
try {
|
||||
chart = echarts.init(el, props.theme)
|
||||
chart.setOption(props.option)
|
||||
|
||||
// 监听容器尺寸变化实施自适应
|
||||
if (typeof ResizeObserver !== 'undefined') {
|
||||
resizeObserver = new ResizeObserver(() => {
|
||||
if (chart) chart.resize()
|
||||
})
|
||||
resizeObserver.observe(el)
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('[EChartsView] 初始化失败', e)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 渲染后延迟初始化以确保容器宽高已经渲染完毕
|
||||
setTimeout(() => {
|
||||
initChart()
|
||||
}, 100)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
if (chart) {
|
||||
chart.dispose()
|
||||
chart = null
|
||||
}
|
||||
if (resizeObserver) {
|
||||
resizeObserver.disconnect()
|
||||
resizeObserver = null
|
||||
}
|
||||
})
|
||||
|
||||
watch(() => props.option, (newVal) => {
|
||||
if (chart) {
|
||||
chart.setOption(newVal)
|
||||
}
|
||||
}, { deep: true })
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ec-wrap {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.ec-canvas {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user