bonus-ui/src/views/screen/wsScreen/components/center/index-old.vue

414 lines
11 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="middle-warp">
<div class="top-btns">
<div class="btn" :class="{ active: btnIndex == 1 }" @click="handleBtn(1)">总价值数</div>
<div class="btn" :class="{ active: btnIndex == 2 }" @click="handleBtn(2)">在库装备数</div>
<div class="btn" :class="{ active: btnIndex == 3 }" @click="handleBtn(3)">机械化率</div>
</div>
<!-- 外层容器用于加阴影 -->
<div class="map-wrapper">
<!-- 倾斜层实现 3D 倾斜效果 -->
<div class="map-tilt">
<div ref="mapChart" class="map-container"></div>
</div>
</div>
<!-- 点击城市显示详情 -->
<div v-if="selectedCity && btnIndex == 1" class="city-tooltip">
<div class="city-name">{{ selectedCity.cityName }}</div>
<div
>装备价值: <span class="num">{{ selectedCity.totalValue }}</span
><span class="unit"> 元</span></div
>
<div
>装备数量: <span class="num">{{ selectedCity.totalEquipmentQuantity }}</span
><span class="unit"> 台</span></div
>
<div
>配置率: <span class="num">{{ selectedCity.configRate || 0 }}</span
><span class="unit"> %</span></div
>
<div
>线路数量: <span class="num">{{ selectedCity.lineNum }}</span
><span class="unit"> 台</span></div
>
<div
>变电数量: <span class="num">{{ selectedCity.substationNum }}</span
><span class="unit"> 台</span></div
>
<div
>电缆数量: <span class="num">{{ selectedCity.cableNum }}</span
><span class="unit"> </span></div
>
</div>
</div>
</template>
<script>
import * as echarts from 'echarts'
import anhuiMapJson from '../anhui.json'
import labelBg from '../../img/value-bg.png'
import { getUnitEquipmentConfigurationApi, getEquipmentNumberApi, getMechanizationRateApi } from '@/api/wsScreen'
export default {
data() {
return {
btnIndex: 1,
myChart: null,
selectedCity: null,
cityData: [
// 假数据
{
deptName: '合肥市',
cityName: '合肥市',
value: [117.227239, 31.820586, 100],
totalValue: 100,
totalEquipmentQuantity: 100,
configRate: 100,
lineNum: 100,
substationNum: 100,
cableNum: 100,
},
{
deptName: '芜湖市',
cityName: '芜湖市',
value: [118.62807, 31.68005, 100],
totalValue: 100,
totalEquipmentQuantity: 100,
configRate: 100,
lineNum: 100,
substationNum: 100,
cableNum: 100,
},
],
}
},
created() {
// this.getInfo()
setTimeout(() => {
console.log('🚀 ~ 地图数据 ~ this.cityData:', this.cityData)
this.initMap()
}, 300)
},
methods: {
handleBtn(index) {
this.btnIndex = index
this.cityData = []
// this.getInfo()
},
async getInfo() {
try {
let res = null
if (this.btnIndex == 1) {
res = await getUnitEquipmentConfigurationApi()
if (!res.data) return
this.cityData = res.data.map((item) => {
let value = item.location.split(',')
value.push(item.totalValue)
// console.log('🚀 ~ getInfo ~ value:', value)
return {
...item,
value,
}
})
} else if (this.btnIndex == 2) {
res = await getEquipmentNumberApi()
this.cityData = res.data.map((item) => {
let value = item.location.split(',')
value.push(item.num)
// console.log('🚀 ~ getInfo ~ value:', value)
return {
...item,
value,
deptName: item.name,
}
})
} else if (this.btnIndex == 3) {
// res = await getMechanizationRateApi()
}
setTimeout(() => {
console.log('🚀 ~ 地图数据 ~ this.cityData:', this.cityData)
this.initMap()
}, 300)
console.log('🚀 ~ 地图数据 ~ res:', res)
} catch (error) {
console.log('🚀 ~ 地图数据 ~ error:', error)
// this.initMap()
}
},
initMap() {
echarts.registerMap('anhui', anhuiMapJson)
this.myChart = echarts.init(this.$refs.mapChart)
const seriesData = this.cityData
const option = {
backgroundColor: 'transparent',
geo: {
map: 'anhui',
roam: false,
zoom: 1.1,
aspectScale: 1.5,
center: [117.227239, 31.820586],
label: { show: false },
itemStyle: {
areaColor: '#1B3452',
borderColor: '#5A9BD9',
borderWidth: 1.5,
},
emphasis: {
itemStyle: { areaColor: '#4C7DBF' },
},
},
series: [
// ******** 阴影层伪3D底座 ********
...[1, 2, 3].map((i) => ({
type: 'map',
map: 'anhui',
roam: false,
silent: true,
zoom: 1.1,
aspectScale: 1.5,
center: [117.227239 + i * 0.05, 31.820586 - i * 0.05], // 👈 每层轻微错位
itemStyle: {
areaColor: `rgba(27,52,82,${0.6 - i * 0.15})`, // 从深到浅
borderColor: 'rgba(0,0,0,0.2)',
borderWidth: 1,
},
z: 1, // 比主层低
})),
// ******** 主地图层(顶部亮色) ********
{
type: 'map',
map: 'anhui',
roam: false,
zoom: 1.1,
aspectScale: 1.5,
center: [117.227239, 31.820586],
itemStyle: {
areaColor: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#3a8bd6' },
{ offset: 1, color: '#142b44' },
]),
borderColor: '#5A9BD9',
borderWidth: 2,
shadowColor: 'rgba(0,0,0,0.6)',
shadowBlur: 15,
},
emphasis: {
itemStyle: {
areaColor: '#4C7DBF',
},
},
z: 5,
},
// ******** 城市散点 ********
{
type: 'scatter',
coordinateSystem: 'geo',
data: seriesData,
symbol: 'circle',
symbolSize: 16,
label: {
show: true,
color: '#fff',
fontSize: 15,
textShadowColor: '#000',
textShadowBlur: 2,
formatter: (params) => {
const val = params.data.value || []
let unit = ''
if (this.btnIndex === 1) unit = '亿'
else if (this.btnIndex === 2) unit = '台'
else if (this.btnIndex === 3) unit = '%'
return val.length
? `{val|${val[2]} ${unit}}\n{name|${params.data.deptName}}`
: `{name|${params.data.deptName}}`
},
rich: {
val: {
backgroundColor: { image: labelBg },
height: 28,
minWidth: 70,
lineHeight: 28,
padding: [0, 10],
align: 'center',
verticalAlign: 'middle',
color: '#fff',
fontSize: 18,
},
name: {
color: '#fff',
fontFamily: 'DS-TITLE',
fontSize: 16,
padding: [6, 0, 0, 0],
},
},
},
z: 10,
},
],
}
this.myChart.setOption(option)
this.myChart.on('click', (params) => {
console.log('🚀 ~ initMap ~ params:', params)
// params.name去掉 市
let city = null
if (params.seriesType === 'scatter' && params.data) {
city =
params.data.deptName == '安徽送变电工程有限公司' ? '安徽送变电' : params.data.cityName.replace(/市$/, '')
} else {
city = params.name.replace(/市$/, '')
}
this.$router.push({
path: '/screen/cityScreen',
query: {
cityName: city,
},
})
})
// 鼠标移入时展示
this.myChart.on('mouseover', (params) => {
// console.log('🚀 ~ initMap ~ params:', params)
let city = null
if (params.seriesType === 'scatter' && params.data) {
// console.log('🚀 ~ 当前坐标点信息 ~ params.data:', params.data)
city = params.data
} else {
this.selectedCity = null
city = this.cityData.find((c) => c.cityName === params.name)
}
this.selectedCity = city || null
})
// 鼠标移出时隐藏
this.myChart.on('mouseout', () => {
this.selectedCity = null
})
window.addEventListener('resize', () => {
this.myChart.resize()
})
},
},
beforeDestroy() {
if (this.myChart) {
this.myChart.dispose()
this.myChart = null
}
},
}
</script>
<style lang="scss" scoped>
.middle-warp {
margin-top: 80px;
position: relative;
padding-top: 20px;
border-radius: 8px;
overflow: hidden;
}
.top-btns {
margin-left: -80px;
display: flex;
justify-content: center;
.btn:not(:last-child) {
margin-right: 80px;
}
.btn {
font-size: 28px;
text-align: center;
padding: 10px 20px;
font-family: DS-TITLE;
color: #ccc;
background-image: url('../../img/btn.png');
background-size: 100% 100%;
cursor: pointer;
}
.active {
background-image: url('../../img/btn-active.png');
background-size: 100% 100%;
}
}
// 外层容器:添加底部阴影
.map-wrapper {
margin-top: -21px;
position: relative;
filter: drop-shadow(0 20px 20px rgba(0, 0, 0, 0.3)); // 20px 柔和阴影
transform: translateZ(0); // 启用硬件加速
}
// 倾斜层:实现 15 度倾斜的 3D 效果
.map-tilt {
transform: rotateX(18deg); // 默认就有角度
transform-origin: bottom center;
perspective: 1600px; // 加大景深
transition: transform 0.3s ease;
pointer-events: none;
height: 900px;
display: flex;
justify-content: center;
}
// 鼠标悬停时轻微动态效果(可选)
.middle-warp:hover .map-tilt {
transform: rotateX(15deg); // hover 时轻微调整,显得有呼吸感
}
// 实际图表容器
.map-container {
width: 100%;
height: 900px;
background: transparent;
pointer-events: auto; // 图表本身可交互
display: flex;
align-items: center;
justify-content: center;
}
.city-tooltip {
position: absolute;
top: 20px;
right: 80px;
width: 288px;
height: 288px;
color: #fdfdfd;
padding: 12px;
border-radius: 6px;
font-size: 17px;
background-image: url('../../img/dialog.png');
background-size: 100% 100%;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
z-index: 10;
.city-name {
font-size: 25px;
font-family: DS-TITLE;
margin: -5px 0 10px;
}
div {
padding-bottom: 5px;
}
// 除了第一个和最后一个外,添加一个浅下边框
div:not(:first-child):not(:last-child) {
margin-bottom: 10px;
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
}
.num {
font-weight: 900;
}
.unit {
font-size: 12px;
color: #ccc;
}
}
</style>