SocialNetworks_duan/src/views/LinkPrediction/components/communityNode.vue

229 lines
6.6 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="communityNode-component">
<div class="graph-container" id="container"></div>
</div>
</template>
<script setup>
import { defineProps, onMounted, ref, defineEmits } from "vue"
import * as echarts from "echarts"
import nodeHoverImg from "@/assets/images/nodeHover.png"
import { inject } from "vue"
let chart = null
const emit = defineEmits(["click:node"])
const initChart = async () => {
chart = echarts.init(document.getElementById("container"))
//处理社团节点
const nodes = Object.values(inject("communityNodeList") ?? []).map((item) => ({
id: parseInt(item.id),
name: parseInt(item.id),
isIncludePredictNodes: item.isIncludePredictNodes,
nodesNum: item.nodesNum
}))
const links = [] //待处理
const data = { nodes, links }
const categories = [
{ name: "普通社团", category: 0 },
{ name: "含预测节点社团", category: 1 },
{ name: "互动隐关系", category: 2 }
]
const option = {
//图例配置
legend: [
{
data: categories.map((c) => ({
name: c.name,
itemStyle: {
color:
c.category === 0
? new echarts.graphic.LinearGradient(1, 0, 0, 0, [
{ offset: 1, color: "#1a3860" }, // 深蓝渐变
{ offset: 0.5, color: "#38546b" },
{ offset: 0, color: "#5fb3b3" }
])
: c.category === 1
? new echarts.graphic.LinearGradient(1, 0, 0, 0, [
{ offset: 0, color: "#9eec9c" }, // 绿色渐变
{ offset: 0.37, color: "#aef295" },
{ offset: 1, color: "#c2f989" }
])
: new echarts.graphic.LinearGradient(1, 0, 0, 0, [
{ offset: 0, color: "#ff9a9e" }, // 红色渐变(用于 category === 2
{ offset: 0.5, color: "#fad0c4" },
{ offset: 1, color: "#fbc2eb" }
])
}
})),
right: 21,
bottom: 70,
icon: "circle",
orient: "vertical",
itemWidth: 16,
itemHeight: 16,
itemGap: 12,
backgroundColor: "rgba(0,67,125,0.56)", // 半透明深蓝
borderRadius: 8, // 圆角
borderColor: "#c2f2ff", // 淡蓝色边框
borderWidth: 0.3,
padding: [12, 20, 12, 20], // 上右下左
textStyle: {
color: "#fff",
fontSize: 16,
fontWeight: "normal"
}
}
],
//hover上去的窗口
tooltip: {
trigger: "item",
backgroundColor: "rgba(0,0,0,0)", // 透明背景
borderColor: "rgba(0,0,0,0)", // 透明边框
borderWidth: 0,
extraCssText: "box-shadow:none;padding:0;",
formatter: function (params) {
if (params.dataType === "node") {
return `<div
style="
width: 107px;
height: 68px;
border-radius: 4px;
background: url('${nodeHoverImg}');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
">
<div style="color:#fff;letter-spacing: 0.14px;">
<div >节点数:${params.data.nodesNum}</div>
</div>
</div>`
}
return ""
}
},
//权值设置样式
// edgeLabel: {
// show: false,
// position: "middle",
// formatter: function (params) {
// return params.data.edge
// },
// fontSize: 14
// },
emphasis: {
edgeLabel: {
show: true,
color: "#fff",
fontSize: 18,
textShadowColor: "#fff",
textShadowBlur: 0,
textShadowOffsetX: 0,
textShadowOffsetY: 0
}
},
series: [
{
type: "graph",
layout: "force",
animation: false,
draggable: true,
roam: true,
zoom: 0.4,
categories: categories,
force: {
edgeLength: 2000,
repulsion: 4000,
gravity: 0.4,
friction: 0.02,
coolingFactor: 0.1
},
animationDurationUpdate: 3500, // 节点移动更平滑
data: data.nodes.map((node) => ({
...node,
symbolSize: node.nodesNum / 40 < 30 ? 40 : node.nodesNum / 40,
itemStyle: {
color:
node.isIncludePredictNodes === false
? new echarts.graphic.RadialGradient(0.98, 0.38, 0.9, [
{ offset: 1, color: "#1a3860" }, // 最左侧
{ offset: 0.5, color: "#38546b" }, // 中间
{ offset: 0, color: "#5fb3b3" } // 最右侧
])
: new echarts.graphic.RadialGradient(0.98, 0.38, 0.9, [
// anchorCount为1的节点渐变原配色
{ offset: 0, color: "#9eec9c" },
{ offset: 0.37, color: "#aef295" },
{ offset: 1, color: "#c2f989" }
]),
opacity: 1,
borderColor: "#46C6AD",
borderWidth: 1,
shadowBlur: 4,
borderType: "dashed",
shadowColor: "rgba(19, 27, 114, 0.25)"
},
emphasis: {
itemStyle: {
shadowBlur: 20,
shadowColor: "#c4a651",
borderColor: "#fcd267",
borderWidth: node.isIncludePredictNodes == false ? 1 : 5,
borderType: "solid"
}
}
})),
links: data.links,
lineStyle: {
color: "#37ACD7",
width: 1
},
emphasis: {
// 高亮配置
focus: "adjacency", // 高亮相邻节点
lineStyle: {
// 高亮时线条样式
width: 10 // 线条宽度(10)
}
}
}
]
}
chart.setOption(option)
}
const handleClickNode = () => {
chart.on("click", function (params) {
//params.data.name才是社团id
if (params.dataType === "node") {
emit("click:node", params.data)
}
})
}
onMounted(async () => {
await initChart()
handleClickNode()
})
</script>
<style scoped lang="less">
.communityNode-component {
width: 100%;
height: 100%;
position: relative;
.graph-container {
width: 100%;
height: 93%;
}
}
</style>