179 lines
4.5 KiB
Vue
179 lines
4.5 KiB
Vue
<template>
|
|
<div class="data-card" :id="id"></div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import {ref, onMounted, reactive} from 'vue'
|
|
import * as echarts from 'echarts'
|
|
import {getXqqy} from "../../dashboard/Analysis/api";
|
|
// import { Info } from '@element-plus/icons-vue'
|
|
const props = defineProps({
|
|
id: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
data: {
|
|
type: String
|
|
}
|
|
});
|
|
let quCn = ref([
|
|
]);
|
|
let quWeight = ref([]);
|
|
let myChart = reactive({});
|
|
function tid(data) {
|
|
quCn.value = [];
|
|
quWeight.value = [];
|
|
data.forEach((item, idx) => {
|
|
quCn.value.push({
|
|
name: item.housingestateName,
|
|
value: item.cn,
|
|
symbolSize: item.cn / 10,
|
|
count: item.cn,
|
|
weight: item.weight
|
|
});
|
|
|
|
quWeight.value.push({
|
|
source: '中心节点',
|
|
target: item.housingestateName,
|
|
value: item.weight,
|
|
lineStyle: {
|
|
width: item.weight / 20,
|
|
color: `rgba(100, 255, 218, ${item.weight / 3000 + 0.1})`
|
|
}
|
|
});
|
|
});
|
|
const chartDom = document.getElementById(props.id);
|
|
myChart = echarts.init(chartDom);
|
|
|
|
// 科技风格配色
|
|
const colors = {
|
|
primary: 'rgba(66, 165, 245, 0.9)', // 主色调:科技蓝
|
|
secondary: 'rgba(100, 255, 218, 0.9)', // 辅助色:科技青
|
|
accent: 'rgba(255, 102, 102, 0.9)', // 强调色:科技红
|
|
gridLine: 'rgba(100, 150, 255, 0.1)', // 网格线
|
|
axisLine: 'rgba(100, 150, 255, 0.3)', // 坐标轴
|
|
textColor: '#a8b2d1', // 文本
|
|
tooltipBg: 'rgba(10, 25, 47, 0.8)', // 提示框背景
|
|
};
|
|
|
|
|
|
// 图表配置
|
|
// 图表配置
|
|
const option = {
|
|
backgroundColor: 'transparent',
|
|
tooltip: {
|
|
trigger: 'item',
|
|
formatter: function (params) {
|
|
if (params.dataType === 'edge') {
|
|
return `
|
|
<div style="color:#64ffda;font-weight:bold">连接</div>
|
|
<div>投递重量(T): ${params.data.value}</div>
|
|
<div>${params.data.source} → ${params.data.target}</div>
|
|
`;
|
|
}
|
|
return `
|
|
<div style="color:#64ffda;font-weight:bold">${params.data.name}</div>
|
|
<div>投递重量(T): ${params.data.weight}</div>
|
|
<div>投递次数: ${params.data.count}</div>
|
|
|
|
`;
|
|
},
|
|
backgroundColor: colors.tooltipBg,
|
|
borderColor: 'rgba(100, 150, 255, 0.3)',
|
|
borderWidth: 1,
|
|
textStyle: { color: '#e6f1ff' }
|
|
},
|
|
series: [
|
|
{
|
|
type: 'graph',
|
|
layout: 'force',
|
|
data: quCn.value,
|
|
links: quWeight.value,
|
|
roam: true,
|
|
focusNodeAdjacency: true,
|
|
draggable: true,
|
|
force: {
|
|
repulsion: 100,
|
|
edgeLength: [40, 100]
|
|
},
|
|
label: {
|
|
show: true,
|
|
position: 'right',
|
|
color: colors.textColor
|
|
},
|
|
lineStyle: {
|
|
color: 'source',
|
|
curveness: 0.1
|
|
},
|
|
emphasis: {
|
|
lineStyle: {
|
|
width: function (edge) {
|
|
return edge.value / 120;
|
|
}
|
|
}
|
|
},
|
|
itemStyle: {
|
|
color: function (params) {
|
|
if (params.data.category === 0) {
|
|
return colors.primary;
|
|
}
|
|
// 根据次数调整颜色透明度
|
|
return `rgba(${params.data.count *0.15}, ${params.data.count *0.4}, ${params.data.count * 0.75}, ${params.data.count / 300 + 0.9})`;
|
|
},
|
|
shadowBlur: 50,
|
|
shadowColor: function (params) {
|
|
if (params.data.category === 0) {
|
|
return 'rgba(100, 255, 218, 0.7)';
|
|
}
|
|
return 'rgba(66, 165, 245, 0.5)';
|
|
}
|
|
},
|
|
animationDuration: 500,
|
|
animationEasing: 'elasticOut',
|
|
animationDelay: function (idx) {
|
|
return idx * 100;
|
|
}
|
|
}
|
|
]
|
|
};
|
|
|
|
|
|
// 设置配置项并渲染
|
|
myChart.setOption(option);
|
|
}
|
|
|
|
// 小区清运
|
|
async function loadXqqy(){
|
|
const resData = await getXqqy({});
|
|
const res = resData.result;
|
|
let Qy = [];
|
|
for (let i = 0; i < res.length; i++) {
|
|
Qy.push({
|
|
housingestateName: res[i].housingestateName,
|
|
cn: res[i].cn,
|
|
weight: res[i].weight,
|
|
});
|
|
}
|
|
tid(Qy);
|
|
}
|
|
|
|
setInterval(function() {
|
|
loadXqqy();
|
|
}, 30*60*1000);
|
|
|
|
// 响应窗口大小变化
|
|
onMounted(() => {
|
|
window.addEventListener('resize', () => {
|
|
myChart.resize();
|
|
});
|
|
loadXqqy();
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
.data-card {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
</style>
|