lcny-vue3-antd-admin/src/views/visualization/components/Map.vue

415 lines
14 KiB
Vue

<template>
<div class="relative h-full overflow-hidden">
<div
v-if="isBack"
@click="onBack"
class="absolute left-25px top-25px z-999 text-white border rounded-2px px-30px py-6px text-12px cursor-pointer"
>返回</div
>
<div class="absolute left-0 w-full top-0 h-full flex items-center justify-center">
<img
class="opacity-30 w-600px h-600px map1"
src="../../../assets/images/lbx.png"
alt=""
srcset=""
/>
</div>
<div class="absolute left-0 w-full top-0 h-full flex items-center justify-center">
<img
class="opacity-30 w-600px h-600px map"
src="../../../assets/images/jt.png"
alt=""
srcset=""
/>
</div>
<div ref="chartRef" class="w-full h-full z-99 absolute"> </div>
</div>
</template>
<script lang="ts">
import { defineComponent, ref, Ref, onMounted, watch } from 'vue'
import { useECharts } from '/@/hooks/web/useECharts'
import { registerMap } from 'echarts'
import { deepMerge } from '/@/utils'
import { useVContext } from '../useVContext'
import { getAgriculturalBasic } from '/@/api/sys/other'
import { useVisualizationStore } from '/@/store/modules/visualization'
const domImg = document.createElement('img')
domImg.style.height = '8px'
domImg.src =
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAANCAYAAABy6+R8AAAAAXNSR0IArs4c6QAAAOlJREFUKFPFkN9qwjAUh09OkzRN0lrbOllhIOxd9h678a0HwkbFWmtsq17I2pE6iuKNbIOdqx/nD+fjI8nL6xxsISPQnrpzRgJte507JP2MtB0ZjvrOfTUchcns0RSLJYADfjhNapMVlHtciEA11WrrqbFGpM6+Xu9+9+k+sPPW8CmePD9t1m/vVsIoTCe78iPnrnKFF+jKLDeejnwHGbWo/4AXPczSMl9kvb1omtRlVnCmXK60bIy1F2tE/BN7DgB8fku8zLdeBxF+lPZIFk8GcXiockOpYExIcWzK2pUjiQTxuN82P7L3BSnVXLvzcNTUAAAAAElFTkSuQmCC'
const domImgHover = document.createElement('img')
domImgHover.style.height = '8px'
domImgHover.src =
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAIAAAAmKNuZAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyNpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTQ4IDc5LjE2NDAzNiwgMjAxOS8wOC8xMy0wMTowNjo1NyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIDIxLjAgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkFDQ0Q2RjYyQTdDRDExRUI4ODUxRDIxRjkzMEExNzg2IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkFDQ0Q2RjYzQTdDRDExRUI4ODUxRDIxRjkzMEExNzg2Ij4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6QUNDRDZGNjBBN0NEMTFFQjg4NTFEMjFGOTMwQTE3ODYiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6QUNDRDZGNjFBN0NEMTFFQjg4NTFEMjFGOTMwQTE3ODYiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz6FboimAAAASklEQVR42mIUnL9XtHsDAzXA69IARjWtXJYX7+FCfyQEKeEyMVAVDG7jWCB+RhaihAsybjQqRqNiNCpGo2I0KoZZVDBSt9oGCDAAhYNrvRu3DWEAAAAASUVORK5CYII='
const img2 = 'image://https://www.makeapie.cn/asset/get/s/data-1619318279159-o6ZbTGoO0.png'
export default defineComponent({
setup() {
const visualizationStore = useVisualizationStore()
const chartRef = ref<HTMLDivElement | null>(null)
const isBack = ref<boolean>(false)
const { setOptions, getInstance } = useECharts(chartRef as Ref<HTMLDivElement>)
const mapJSON = ref()
const tempMapJSON = ref()
let options: any = null
const { rootEmitter } = useVContext()
const baseData = ref([])
function onBack() {
visualizationStore.setAddressId(null)
rootEmitter.emit('map:back')
isBack.value = false
tempMapJSON.value = deepMerge(mapJSON.value)
mapInit()
}
function mapInit() {
const mapData: any = []
// baseData.value.map(({ name, address_lng, address_lat, areas, id }) => {
baseData.value.map((e: any) => {
// mapData.push({
// name: name,
// value: [address_lng, address_lat],
// datas: areas,
// id: id,
// img: 'image://https://www.makeapie.cn/asset/get/s/data-1619059442567-s5l7-f8Eu9.png',
// })
mapData.push({
...e,
value: [e.address_lng, e.address_lat],
datas: e.areas,
img: 'image://https://www.makeapie.cn/asset/get/s/data-1619059442567-s5l7-f8Eu9.png',
})
})
registerMap('lcxz', tempMapJSON.value)
options = {
backgroundColor: 'transparent',
stateAnimation: {
duration: 100,
},
// tooltip: {
// trigger: 'item',
// },
geo: {
map: 'lcxz',
aspectScale: 0.75,
layoutCenter: ['50%', '50.5%'],
layoutSize: '100%',
silent: true,
roam: false,
z: 0,
label: {
color: '#fff',
show: false,
},
itemStyle: {
areaColor: 'rgba(0, 15, 40, 0.0)',
shadowColor: 'rgba(0, 0, 0, 1)',
shadowBlur: 0,
shadowOffsetX: 0,
shadowOffsetY: 5,
borderColor: '#fff',
borderWidth: 0.1,
},
emphasis: {
itemStyle: {
areaColor: '#2AB8FF',
borderWidth: 1,
color: 'green',
},
label: {
show: false,
},
},
},
series: [
{
type: 'map',
zoom: 1.1,
roam: false,
map: 'lcxz',
select: {
disabled: true,
},
label: {
show: false,
color: '#fff',
},
itemStyle: {
// areaColor: {
// image: domImg,
// repeat: 'repeat',
// },
borderColor: 'rgba(147, 235, 248, 1)',
borderWidth: 1,
areaColor: 'rgb(30,54,80 , 0.8)',
// shadowColor: 'rgba(128, 217, 248, 1)',
// shadowOffsetX: -2,
// shadowOffsetY: 2,
// shadowBlur: 10,
},
emphasis: {
label: {
show: true,
color: '#fff',
},
itemStyle: {
// areaColor: {
// image: domImg,
// repeat: 'repeat',
// },
areaColor: 'rgb(30,54,80 , 0.8)',
borderColor: 'rgba(147, 235, 248, 1)',
borderWidth: 1,
shadowColor: 'rgba(0, 255, 255, 1)',
shadowBlur: 10,
shadowOffsetX: 0,
shadowOffsetY: 1,
},
},
},
{
tooltip: {
show: false,
},
type: 'effectScatter',
coordinateSystem: 'geo',
rippleEffect: {
scale: 10,
brushType: 'stroke',
},
showEffectOn: 'render',
symbol: 'circle',
zlevel: 1,
symbolSize: [10, 5],
itemStyle: {
color: (params): any => {
var colorList = [
{
type: 'linear',
x: 1,
y: 0,
x2: 0,
y2: 0,
colorStops: [
{
offset: 0,
color: '#64fbc5',
},
{
offset: 1,
color: '#018ace',
},
],
global: false,
},
{
type: 'linear',
x: 1,
y: 0,
x2: 0,
y2: 0,
colorStops: [
{
offset: 0,
color: '#61c0f1 ',
},
{
offset: 1,
color: '#6f2eb6',
},
],
global: false,
},
]
return colorList[params.dataIndex % colorList.length]
},
},
data: mapData,
},
{
type: 'scatter',
coordinateSystem: 'geo',
tooltip: {
trigger: 'item',
show: true,
},
symbol: (_, params) => {
return mapData[params.dataIndex].img
},
symbolSize: [21, 30],
symbolOffset: [0, -20],
z: 9999,
data: mapData,
},
{
type: 'scatter',
coordinateSystem: 'geo',
// stateAnimation: {
// duration: 300,
// easing: 'bounceOut',
// },
label: {
show: true,
align: 'center',
formatter: function (params) {
var name = params.name
// var value = mapData[params.dataIndex].datas
var text = `{tline|${name}}`
return text
},
color: '#fff',
rich: {
fline: {
padding: [0, 25],
color: '#fff',
textShadowColor: '#030615',
textShadowOffsetX: 1,
textShadowOffsetY: 1,
fontSize: 14,
fontWeight: 400,
},
tline: {
padding: [0, 27],
color: '#ABF8FF',
fontSize: 12,
},
},
},
itemStyle: {
color: '#00FFF6',
},
symbol: img2,
symbolSize: [100, 34],
symbolOffset: [0, -46],
z: 999,
// data: mapData,
data: [],
},
],
}
setOptions(options)
}
async function getBase() {
try {
const resData = await getAgriculturalBasic({
parent: visualizationStore.getAddresId,
type: 1,
})
baseData.value = resData ?? []
} finally {
mapInit()
}
}
async function getData() {
const _resData = await getAgriculturalBasic({ type: 2 })
const _mapData = (await (await import('./lcxz1.json')).default) as any
_mapData.features.reduce((p, c) => {
const item = _resData.find((e) => e.name == c.properties.name)
if (item) {
p.push(Object.assign(c, { properties: item }))
}
return p
}, [])
mapJSON.value = _mapData
tempMapJSON.value = deepMerge(mapJSON.value)
getBase()
}
let tempName: any = null
onMounted(async () => {
await getData()
getInstance()?.on('mousemove', (e) => {
// const arr = options.series[3].data
// if (e.seriesType == 'map' && arr.length) {
// console.log('=====清除')
// options.series[3].data = []
// getInstance()?.setOption({ series: options.series }, false)
// }
if (tempName == e.name && e.seriesType == 'scatter') return
if (e.seriesType == 'scatter') {
tempName = e.name
options.series[3].data = [e.data]
getInstance()?.setOption({ series: options.series }, false)
}
// if (tempName == e.name) return
// tempName = e.name
// if (e.componentSubType == 'scatter') {
// options.series[3].data = [e.data]
// getInstance()?.setOption({ series: options.series }, false)
// } else {
// options.series[3].data = [e.data]
// getInstance()?.setOption({ series: options.series }, false)
// }
})
getInstance()?.on('click', (e) => {
if (e.seriesType == 'effectScatter' || e.seriesType == 'scatter') {
rootEmitter.emit('base:click', e.data)
}
if (e.seriesType == 'map') {
const temp = mapJSON.value.features.filter((obj) => obj.properties.name == e.name)
visualizationStore.setAddressId(temp[0].properties?.id)
rootEmitter.emit('map:click', deepMerge(temp[0].properties))
if (temp) {
isBack.value = true
tempMapJSON.value = deepMerge({
type: 'FeatureCollection',
features: temp,
})
// mapInit()
}
}
})
})
watch(
() => visualizationStore.getAddresId,
() => {
getBase()
},
)
return { chartRef, isBack, onBack }
},
})
</script>
<style>
.map1 {
z-index: 2;
animation: myfirst2 15s infinite linear;
}
@keyframes myfirst2 {
from {
transform: rotate(0deg);
}
to {
transform: rotate(359deg);
}
}
.map {
z-index: 2;
animation: myfirst 15s infinite linear;
}
@keyframes myfirst {
from {
transform: rotate(0deg);
}
to {
transform: rotate(-359deg);
}
}
</style>