完善页面细节

This commit is contained in:
2026-02-25 11:39:54 +08:00
parent 92d6e8144d
commit 8ec05b331b
131 changed files with 5273 additions and 585 deletions

View 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>