渲染 地图

This commit is contained in:
GGJ
2023-12-29 16:25:26 +08:00
parent f8768b5f33
commit 2ba7cf7dce
3 changed files with 203 additions and 74 deletions

View File

@@ -11,7 +11,7 @@ const chartRef = ref<HTMLDivElement>()
const props = defineProps(['options']) const props = defineProps(['options'])
let chart: echarts.ECharts | null = null let chart: echarts.ECharts | null = null
const resizeHandler = () => { const resizeHandler = () => {
chart?.resize() chart?.resize()
} }
const initChart = () => { const initChart = () => {
chart?.dispose() chart?.dispose()
@@ -19,15 +19,14 @@ const initChart = () => {
chart = echarts.init(chartRef.value as HTMLDivElement) chart = echarts.init(chartRef.value as HTMLDivElement)
chart.setOption({ chart.setOption({
title: { title: {
...props.options.title,
left: 'center', left: 'center',
textStyle: { textStyle: {
color: '#000', color: '#000',
fontSize: 18 fontSize: 18
} },
...props.options.title
}, },
tooltip: { tooltip: {
...(props.options.tooltip || null),
trigger: 'axis', trigger: 'axis',
axisPointer: { axisPointer: {
@@ -44,10 +43,10 @@ const initChart = () => {
fontSize: 14 fontSize: 14
}, },
backgroundColor: 'rgba(0,0,0,0.35)', backgroundColor: 'rgba(0,0,0,0.35)',
borderWidth: 0 borderWidth: 0,
...(props.options.tooltip || null)
}, },
legend: { legend: {
...(props.options.xAxis.legend || null),
right: 20, right: 20,
top: 0, top: 0,
itemGap: 10, itemGap: 10,
@@ -57,7 +56,8 @@ const initChart = () => {
padding: [2, 0, 0, 0] //[上、右、下、左] padding: [2, 0, 0, 0] //[上、右、下、左]
}, },
itemWidth: 15, itemWidth: 15,
itemHeight: 10 itemHeight: 10,
...(props.options.legend || null)
}, },
grid: { grid: {
@@ -65,12 +65,10 @@ const initChart = () => {
left: '10px', left: '10px',
right: '40px', right: '40px',
bottom: '40px', bottom: '40px',
containLabel: true containLabel: true
}, },
xAxis: [ xAxis: [
{ {
...(props.options.xAxis || null),
type: 'category', type: 'category',
axisTick: { show: false }, axisTick: { show: false },
axisLine: { axisLine: {
@@ -84,12 +82,13 @@ const initChart = () => {
color: '#000', color: '#000',
fontSize: '12' fontSize: '12'
} }
} },
...(props.options.xAxis || null)
} }
], ],
yAxis: [ yAxis: [
{ {
...(props.options.yAxis || null),
type: 'value', type: 'value',
nameTextStyle: { nameTextStyle: {
@@ -113,7 +112,8 @@ const initChart = () => {
type: 'dashed', type: 'dashed',
opacity: 0.5 opacity: 0.5
} }
} },
...(props.options.yAxis || null),
} }
], ],
dataZoom: [ dataZoom: [

View File

@@ -1,25 +1,18 @@
<!-- 地图组件 --> <!-- 地图组件 -->
<template> <template>
<div class="bars_w" ref="chartMap" id="chartMap"></div> <div style="position: relative">
<div class="bars_w" ref="chartMap" id="chartMap"></div>
<span @click="circle" v-show="showCircle" class="iconfont icon-back" style="color: #003078"></span>
</div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { onBeforeUnmount, ref, nextTick, onMounted, defineEmits } from 'vue' import { onBeforeUnmount, ref, watch, onMounted, defineEmits } from 'vue'
import * as echarts from 'echarts' import * as echarts from 'echarts'
import chinaJson from '@/assets/map/zh.json' const props = defineProps(['options'])
import axios from 'axios'
const props = defineProps({
datas: {
type: Array,
required: true
}
})
const myCharts = ref() const myCharts = ref()
const showCircle = ref(false)
const mapJson = ref()
const fetchConfig = async (name: string) => { const fetchConfig = async (name: string) => {
const res = await import(`../../assets/map/${name}.json`) const res = await import(`../../assets/map/${name}.json`)
@@ -29,19 +22,63 @@ const fetchConfig = async (name: string) => {
// fetchConfig() // fetchConfig()
const emit = defineEmits(['getRegionByRegionId']) const emit = defineEmits(['getRegionByRegionId'])
onMounted(() => { onMounted(() => {})
GetEchar('中国')
})
const GetEchar = async (name:string) => { const GetEchar = async (name: string) => {
let chartDom = document.getElementById('chartMap') let chartDom = document.getElementById('chartMap')
myCharts.value?.resize()
myCharts.value = echarts.init(chartDom) myCharts.value = echarts.init(chartDom)
echarts.registerMap('china', await fetchConfig(name)) //注册可用的地图 echarts.registerMap('china', await fetchConfig(name)) //注册可用的地图
var option = { let option = {
title: {
left: 'center',
top: '3%',
...props.options.title
},
tooltip: {
trigger: 'item',
axisPointer: {
type: 'shadow',
label: {
color: '#fff',
fontSize: 16
}
},
textStyle: {
color: '#fff',
fontStyle: 'normal',
opacity: 0.35,
fontSize: 14
},
backgroundColor: 'rgba(0,0,0,0.35)',
...(props.options.tooltip || null)
},
legend: {
orient: 'vertical',
left: 26,
bottom: 40,
itemWidth: 16,
itemHeight: 16,
...(props.options.legend || null)
},
color: [
...(props.options.color || ''),
'#07CCCA ',
'#00BFF5',
'#FFBF00',
'#77DA63',
'#D5FF6B',
'#Ff6600',
'#FF9100',
'#5B6E96',
'#66FFCC',
'#B3B3B3'
],
geo: { geo: {
map: 'china', map: 'china',
zoom: 1, zoom: 1,
roam: true, roam: true,
label: { label: {
normal: { normal: {
@@ -100,53 +137,29 @@ const GetEchar = async (name:string) => {
} }
} }
] ]
} },
...props.options.options
} }
myCharts.value.setOption(option) myCharts.value.setOption(option)
window.addEventListener('resize', resizeHandler) window.addEventListener('resize', resizeHandler)
//设置默认选中高亮部分
let index = 11
myCharts.value.dispatchAction({
type: 'highlight',
seriesIndex: 0,
dataIndex: index
})
// 点击事件 // 点击事件
myCharts.value.on('click', e => { myCharts.value.off('click')
console.log('🚀 ~ file: MyEchartMap.vue:139 ~ GetEchar ~ e:', e.name) myCharts.value.on('click', (e: any) => {
GetEchar(e.name) if (name == '中国' && e.componentIndex == 0) {
emit('getRegionByRegionId', e.data) GetEchar(e.name)
myCharts.value.dispatchAction({ showCircle.value = true
type: 'downplay',
seriesIndex: 0,
dataIndex: 0
})
if (e.dataIndex != index) {
myCharts.value.dispatchAction({
type: 'downplay',
seriesIndex: 0,
dataIndex: index
})
} }
myCharts.value.dispatchAction({
type: 'highlight', emit('getRegionByRegionId', e)
seriesIndex: 0,
dataIndex: e.dataIndex
})
index = e.dataIndex
})
// 当鼠标离开时
myCharts.value.on('mouseout', function (e) {
myCharts.value.dispatchAction({
type: 'highlight',
seriesIndex: 0,
dataIndex: index
})
}) })
} }
// 返回
const circle = () => {
GetEchar('中国')
showCircle.value = false
}
const resizeHandler = () => { const resizeHandler = () => {
myCharts.value?.resize() myCharts.value?.resize()
} }
@@ -154,6 +167,13 @@ onBeforeUnmount(() => {
window.removeEventListener('resize', resizeHandler) window.removeEventListener('resize', resizeHandler)
myCharts.value?.dispose() myCharts.value?.dispose()
}) })
watch(
() => props.options,
(newVal, oldVal) => {
GetEchar('中国')
}
)
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@@ -161,4 +181,12 @@ onBeforeUnmount(() => {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.iconfont {
cursor: pointer;
position: absolute;
top: 10px;
left: 10px;
z-index: 2;
font-size: 20px;
}
</style> </style>

View File

@@ -23,7 +23,7 @@
<div> <div>
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<MyEchartMap class="map" :datas="[]" /> <MyEchartMap :options="echartList" class="map" />
</el-col> </el-col>
<el-col :span="12">1231</el-col> <el-col :span="12">1231</el-col>
</el-row> </el-row>
@@ -36,7 +36,9 @@ import { useDictData } from '@/stores/dictData'
import MyEchartMap from '@/components/echarts/MyEchartMap.vue' import MyEchartMap from '@/components/echarts/MyEchartMap.vue'
import { ref, reactive, onMounted, provide } from 'vue' import { ref, reactive, onMounted, provide } from 'vue'
const options = ref<object[]>([]) const options = ref<object[]>([])
const echartList = ref({})
const deptIndex = ref<string>('') const deptIndex = ref<string>('')
const DictData = useDictData() const DictData = useDictData()
const formInline = reactive({ const formInline = reactive({
deptIndex: '5699e5916a18a6381e1ac92da5bd2628', deptIndex: '5699e5916a18a6381e1ac92da5bd2628',
@@ -51,9 +53,108 @@ const info = () => {
} }
const onSubmit = () => { const onSubmit = () => {
getAreaLineDetail(formInline) getAreaLineDetail(formInline).then(res => {
.then(res => {}) echartList.value = {
.catch(err => {}) title: {
text: '监测网分布' //+ "(" + _this.titles + ")",
},
tooltip: {
formatter: function (params: any) {
//console.log(params)
var tips = ''
if (params.value == 0) {
tips = "<font style='color: #000'>暂无数据</font><br/>"
} else {
tips +=
"<font style='color: #000'> " +
params.name +
'</font><br/>区域暂降评估' +
"<font style='color: #000'>:" +
params.value +
'</font><br/>'
}
return tips
}
},
color: ['green', 'red'],
legend: {
data: [
{
name: '正常'
},
{
name: '中断'
}
]
},
options: {
series: []
}
}
let mapList = [[], [], []]
if (res.data.substationDetailVOList != null) {
res.data.substationDetailVOList.forEach((item: any) => {
if (item.color == 'green') {
mapList[0].push(item)
} else if (item.color == 'red') {
mapList[1].push(item)
}
})
}
mapList.forEach((item, ind) => {
echartList.value.options.series.push({
type: 'scatter',
mapName: 'china',
name: ind == 0 ? '正常' : ind == 1 ? '中断' : '变电站',
coordinateSystem: 'geo',
geoIndex: 0,
animation: false, //坐标点是否显示动画
roam: true,
symbol: 'pin',
symbolSize: function () {
//坐标点大小
return 30
},
label: {
normal: {
show: false
},
emphasis: {
show: false
}
},
data: item.map(function (itemOpt: any) {
// console.log(itemOpt);
return {
name: itemOpt.srbName,
value: [
parseFloat(itemOpt.coordY), //经度
parseFloat(itemOpt.coordX) //维度
],
itemStyle: {
//地图区域的多边形
normal: {
color: itemOpt.color, //坐标点颜色
shadowBlur: 0, // 图形阴影的模糊大小
shadowOffsetX: 0 // 阴影水平方向上的偏移距离。
}
},
tooltip: {
//仅在 options中最外层的 tooltip.trigger 为 'item'时有效
position: 'bottom', //提示框位置,仅在 options中最外层的 tooltip.trigger 为 'item'时有效
formatter: function (params: any, ticket: any, callback: any) {
var strHtml = '<div>变电站:' + itemOpt.subName + '<br/>' + '监测点:' + itemOpt.srbName
strHtml += '</div>'
return strHtml
}
}
}
})
})
})
})
} }
onMounted(() => { onMounted(() => {