人物互动隐关系预测图一级界面,二级界面数据处理完成

This commit is contained in:
qumeng039@126.com 2025-07-28 15:59:40 +08:00
parent 924830e18d
commit 159966c580
12 changed files with 440 additions and 101 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 347 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 B

View File

@ -14,6 +14,11 @@ export function getInteractionCommunityNodes() {
export function getInteractionCommunityDetailNodes(ids) { export function getInteractionCommunityDetailNodes(ids) {
return http.get(`linkPrediction/interaction/community_detail?groupIds=${ids}`) return http.get(`linkPrediction/interaction/community_detail?groupIds=${ids}`)
} }
//人物互动隐关系预测的社团统计
export function getInteractionCommunityStatistics() {
return http.get(`linkPrediction/interaction/community_statistics`)
}
//社交紧密团体识别的用户组列表 //社交紧密团体识别的用户组列表
export function getGroupUserListFromTriangle() { export function getGroupUserListFromTriangle() {
return http.get("/linkPrediction/triangle/group_list") return http.get("/linkPrediction/triangle/group_list")

View File

@ -541,7 +541,7 @@ export const useKeyNodeRecognitionStore = defineStore("keyNodeRecognition", {
backimg: high3Img, backimg: high3Img,
riskType: "低风险", riskType: "低风险",
chart: { chart: {
predictedData: [12000, 12690, 12108, 10790, 9004, 8006, 7890, 11878], predictedData: [12000, 12690, 12108, 10790, 9004, 5000, 4890, 3300],
realityData: [8959, 7460, 8334, 7902, 5753, 3070, "-", "-"] realityData: [8959, 7460, 8334, 7902, 5753, 3070, "-", "-"]
} }
} }

View File

@ -7,10 +7,14 @@ import {
getSocialPostList, getSocialPostList,
getInteractionHiddenPostList, getInteractionHiddenPostList,
getInteractionCommunityNodes, getInteractionCommunityNodes,
getInteractionCommunityDetailNodes getInteractionCommunityDetailNodes,
getInteractionCommunityStatistics
} from "@/service/api/linkPrediction" } from "@/service/api/linkPrediction"
import defaultAvatar from "@/assets/images/avatar/default.png" import defaultAvatar from "@/assets/images/avatar/default.png"
import nodePrefix from "@/assets/images/linkPrediction/icon/node-count-prefix.png"
import communityPrefix from "@/assets/images/linkPrediction/icon/community-count-prefix.png"
import hiddenPrefix from "@/assets/images/linkPrediction/icon/hidden-count-prefix.png"
export const useCharacterInteractionStore = defineStore("characterInteraction", { export const useCharacterInteractionStore = defineStore("characterInteraction", {
state: () => ({ state: () => ({
@ -128,6 +132,12 @@ export const useCharacterInteractionStore = defineStore("characterInteraction",
{ text: "领土", top: 57.5, left: 72.5, width: 49, height: 19, fontSize: 12, opacity: 0.6 }, { text: "领土", top: 57.5, left: 72.5, width: 49, height: 19, fontSize: 12, opacity: 0.6 },
{ text: "原则", top: 77.5, left: 264.5, width: 49, height: 19, fontSize: 12, opacity: 0.7 }, { text: "原则", top: 77.5, left: 264.5, width: 49, height: 19, fontSize: 12, opacity: 0.7 },
{ text: "台湾", top: 195.5, left: 287.5, width: 49, height: 19, fontSize: 12, opacity: 0.8 } { text: "台湾", top: 195.5, left: 287.5, width: 49, height: 19, fontSize: 12, opacity: 0.8 }
],
statisticsList: [
{ id: 1, icon: nodePrefix, name: "节点数", key: "nodesCount" },
{ id: 2, icon: communityPrefix, name: "社团数", key: "groupCount" },
{ id: 3, icon: hiddenPrefix, name: "隐关系数", key: "hiddenInteractionCount" }
] ]
}), }),
actions: { actions: {
@ -158,7 +168,15 @@ export const useCharacterInteractionStore = defineStore("characterInteraction",
}, },
async initGraphCommunityDetailNode(ids) { async initGraphCommunityDetailNode(ids) {
const res = await getInteractionCommunityDetailNodes(ids) const res = await getInteractionCommunityDetailNodes(ids)
console.log(res) if (res.code != 200) return
return res.data
},
async initGraphStatistics() {
const res = await getInteractionCommunityStatistics()
this.statisticsList = this.statisticsList.map((item) => ({
...item,
count: res.data[item.key]
}))
} }
}, },
persist: true // 开启持久化 persist: true // 开启持久化

View File

@ -99,8 +99,10 @@ onMounted(() => {
interactionStore.initGroupList() interactionStore.initGroupList()
interactionStore.initInteractionPostList(1) interactionStore.initInteractionPostList(1)
interactionStore.initGraphCommunityNode() interactionStore.initGraphCommunityNode()
interactionStore.initGraphStatistics()
}) })
provide("communityNodeList", interactionStore.communityNodeList) // provide("communityNodeList", interactionStore.communityNodeList) //
provide("statisticsList", interactionStore.statisticsList)
</script> </script>
<style scoped lang="less"> <style scoped lang="less">

View File

@ -1,6 +1,13 @@
<template> <template>
<div class="communityNode-component"> <div class="communityNode-component">
<div class="graph-container" id="container"></div> <div class="graph-container" id="container"></div>
<div class="statistic-container">
<div class="statistics-item" v-for="item in statisticsList" :key="item.id">
<img :src="item.icon" class="icon" />
<div class="name">{{ item.name }}:&nbsp;</div>
<div class="count">{{ item.count }}</div>
</div>
</div>
</div> </div>
</template> </template>
@ -10,6 +17,7 @@ import * as echarts from "echarts"
import nodeHoverImg from "@/assets/images/nodeHover.png" import nodeHoverImg from "@/assets/images/nodeHover.png"
let chart = null let chart = null
const emit = defineEmits(["click:node", "click:edge"]) const emit = defineEmits(["click:node", "click:edge"])
const statisticsList = inject("statisticsList")
const initChart = async () => { const initChart = async () => {
chart = echarts.init(document.getElementById("container")) chart = echarts.init(document.getElementById("container"))
@ -21,7 +29,10 @@ const initChart = async () => {
isIncludePredictNodes: item.isIncludePredictNodes, isIncludePredictNodes: item.isIncludePredictNodes,
nodesNum: item.nodesNum, nodesNum: item.nodesNum,
neighbors: item.neighbors.map((item) => ({ ...item, name: parseInt(item.id) })), neighbors: item.neighbors.map((item) => ({ ...item, name: parseInt(item.id) })),
category: item.isIncludePredictNodes ? 1 : 0 category: item.isIncludePredictNodes ? 1 : 0,
selfIncludeImplicitRelationship:
item.neighbors.map((nei) => nei.id).includes(item.id) && //id
item.neighbors.find((nei) => nei.id == item.id).isHidden
})) }))
// //
@ -80,8 +91,8 @@ const initChart = async () => {
]) ])
} }
})), })),
right: 21, right: 15,
bottom: 70, bottom: 10,
icon: "circle", icon: "circle",
orient: "vertical", orient: "vertical",
itemWidth: 16, itemWidth: 16,
@ -158,7 +169,6 @@ const initChart = async () => {
roam: true, roam: true,
zoom: 0.3, zoom: 0.3,
categories: categories, categories: categories,
force: { force: {
edgeLength: 2500, edgeLength: 2500,
repulsion: 4000, repulsion: 4000,
@ -187,8 +197,8 @@ const initChart = async () => {
]), ]),
opacity: 1, opacity: 1,
borderColor: "#46C6AD", borderColor: node.selfIncludeImplicitRelationship ? "#f8bf38" : "#46C6AD",
borderWidth: 1, borderWidth: node.selfIncludeImplicitRelationship ? 3 : 1,
shadowBlur: 4, shadowBlur: 4,
borderType: "dashed", borderType: "dashed",
shadowColor: "rgba(19, 27, 114, 0.25)" shadowColor: "rgba(19, 27, 114, 0.25)"
@ -250,5 +260,49 @@ onMounted(async () => {
width: 100%; width: 100%;
height: 93%; height: 93%;
} }
.statistic-container {
width: 378px;
height: 42px;
flex-shrink: 0;
border-radius: 4px;
border: 1px solid #3aa1f8;
background: linear-gradient(270deg, rgba(0, 82, 125, 0.48) 0%, rgba(0, 200, 255, 0.23) 100%);
backdrop-filter: blur(3px);
position: absolute;
bottom: 48px;
left: 15px;
display: flex;
justify-content: space-between;
.statistics-item {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
.icon {
width: 14px;
height: 14px;
}
.name {
color: rgba(255, 255, 255, 0.76);
text-align: center;
font-family: OPPOSans;
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: normal;
margin-left: 3px;
}
.count {
color: #fff;
font-family: D-DIN;
font-size: 15px;
font-style: normal;
font-weight: 700;
line-height: normal;
margin-bottom: 2px;
}
}
}
} }
</style> </style>

View File

@ -2,22 +2,232 @@
<div class="detailNode-component"> <div class="detailNode-component">
<img src="@/assets/images/icon/goback.png" alt="" class="goback" @click="handleGoback" /> <img src="@/assets/images/icon/goback.png" alt="" class="goback" @click="handleGoback" />
<div class="graph-container" id="container"></div> <div class="graph-container" id="container"></div>
<div class="statistic-container">
<div class="statistics-item" v-for="item in statisticsList" :key="item.id">
<img :src="item.icon" class="icon" />
<div class="name">{{ item.name }}:&nbsp;</div>
<div class="count">{{ item.count }}</div>
</div>
</div>
<div class="time-axis"></div>
</div> </div>
</template> </template>
<script setup> <script setup>
import { defineProps, defineEmits } from "vue" import nodePrefix from "@/assets/images/linkPrediction/icon/node-count-prefix.png"
import communityPrefix from "@/assets/images/linkPrediction/icon/community-count-prefix.png"
import hiddenPrefix from "@/assets/images/linkPrediction/icon/hidden-count-prefix.png"
import { defineProps, defineEmits, onMounted, ref } from "vue"
import nodeHoverImg from "@/assets/images/nodeHover.png"
import * as echarts from "echarts"
const statisticsList = [
{ id: 1, icon: nodePrefix, name: "节点数", key: "nodesCount", count: 3000 },
{ id: 2, icon: communityPrefix, name: "社团数", key: "groupCount", count: 1000 },
{ id: 3, icon: hiddenPrefix, name: "隐关系数", key: "hiddenInteractionCount", count: 1000 }
]
const props = defineProps({ const props = defineProps({
detailNode: { detailNode: {
type: Array, type: Array,
default: () => [] default: () => []
} }
}) })
const curDetailNode = ref(props.detailNode)
const emit = defineEmits(["click:goback"]) const emit = defineEmits(["click:goback"])
const handleGoback = () => { const handleGoback = () => {
emit("click:goback", "CommunityNode") emit("click:goback", "CommunityNode")
} }
let chart = null
const initChart = async () => {
chart = echarts.init(document.getElementById("container"))
const links = []
const nodes = []
if (!Object.keys(curDetailNode.value).length) return
Object.entries(curDetailNode.value).forEach(([parentId, children]) => {
nodes.push({
id: `parent_${parentId}`,
name: parentId
})
children.forEach((child) => {
if (!nodes.some((n) => n.id === child.id)) {
nodes.push(child)
}
links.push({
source: `parent_${parentId}`,
target: child.id,
edge: child.isHidden ? 1 : 0,
interactionTimes: child.interactionTime
})
})
})
const data = { links, nodes }
const categories = [
{ name: "事件活跃者", category: 0 },
{ name: "信息发布者", category: 1 },
{ name: "互动关系", category: 2 },
{ name: "互动隐关系", category: 3 }
]
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="
padding:10px 15px;
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 >用户ID${params.data.id}</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.3,
categories: categories,
force: {
edgeLength: 2500,
repulsion: 4000,
gravity: 0.4,
friction: 0.02,
coolingFactor: 0.1
},
animationDurationUpdate: 3500, //
data: data.nodes.map((node) => ({
...node,
symbolSize: 40,
itemStyle: {
color: new echarts.graphic.RadialGradient(0.98, 0.38, 0.9, [
{ offset: 1, color: "#1a3860" }, //
{ offset: 0.5, color: "#38546b" }, //
{ offset: 0, color: "#5fb3b3" } //
]),
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: 1,
borderType: "solid"
}
}
})),
links: data.links,
lineStyle: {
color: "#37ACD7",
width: 1
}
}
]
}
chart.setOption(option)
}
onMounted(() => {
initChart()
})
</script> </script>
<style scoped lang="less"> <style scoped lang="less">
@ -27,7 +237,7 @@ const handleGoback = () => {
position: relative; position: relative;
.goback { .goback {
position: absolute; position: absolute;
top: 10px; top: -25px;
left: 20px; left: 20px;
cursor: pointer; cursor: pointer;
} }
@ -35,5 +245,60 @@ const handleGoback = () => {
width: 100%; width: 100%;
height: 93%; height: 93%;
} }
.statistic-container {
width: 378px;
height: 42px;
flex-shrink: 0;
border-radius: 4px;
border: 1px solid #3aa1f8;
background: linear-gradient(270deg, rgba(0, 82, 125, 0.48) 0%, rgba(0, 200, 255, 0.23) 100%);
backdrop-filter: blur(3px);
position: absolute;
bottom: 105px;
left: 21px;
display: flex;
justify-content: space-between;
.statistics-item {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
.icon {
width: 14px;
height: 14px;
}
.name {
color: rgba(255, 255, 255, 0.76);
text-align: center;
font-family: OPPOSans;
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: normal;
margin-left: 3px;
}
.count {
color: #fff;
font-family: D-DIN;
font-size: 15px;
font-style: normal;
font-weight: 700;
line-height: normal;
margin-bottom: 2px;
}
}
}
.time-axis {
width: 95%;
height: 42px;
border: 1px solid #3aa1f8;
background: linear-gradient(270deg, rgba(0, 82, 125, 0.48) 0%, rgba(0, 200, 255, 0.23) 100%);
backdrop-filter: blur(3px);
position: absolute;
left: 20px;
bottom: 50px;
border-radius: 4px;
z-index: 1;
}
} }
</style> </style>

View File

@ -7,19 +7,22 @@
@click:node="handleClickNode" @click:node="handleClickNode"
@click:edge="handleClickEdge" @click:edge="handleClickEdge"
></CommunityNode> ></CommunityNode>
<DetailNode v-else @click:goback="handleClickGoBack"></DetailNode> <DetailNode
v-else
<div class="time-axis"></div> @click:goback="handleClickGoBack"
:detailNode="curSelectedGroup"
></DetailNode>
</div> </div>
</template> </template>
<script setup> <script setup>
import { defineProps, onMounted, ref } from "vue" import { defineProps, ref } from "vue"
import CommunityNode from "./communityNode.vue" import CommunityNode from "./communityNode.vue"
import DetailNode from "./detailNode.vue" import DetailNode from "./detailNode.vue"
import { useCharacterInteractionStore } from "@/store/llinkPrediction/index" import { useCharacterInteractionStore } from "@/store/llinkPrediction/index"
const interactionStore = useCharacterInteractionStore() const interactionStore = useCharacterInteractionStore()
const curComponent = ref("CommunityNode") const curComponent = ref("CommunityNode")
const curSelectedGroup = ref(null)
const props = defineProps({ const props = defineProps({
title: { title: {
type: String, type: String,
@ -27,19 +30,24 @@ const props = defineProps({
} }
}) })
const handleClickNode = (nodeInfo) => { const handleClickNode = async (nodeInfo) => {
interactionStore.initGraphCommunityDetailNode([nodeInfo.id]) const data = await interactionStore.initGraphCommunityDetailNode([nodeInfo.id])
console.log(nodeInfo) curSelectedGroup.value = data
curComponent.value = "detailNode"
} }
const handleClickEdge = (edgeInfo) => { const handleClickEdge = async (edgeInfo) => {
curComponent.value = "detailNode" curComponent.value = "detailNode"
const ids = [edgeInfo.source, edgeInfo.target] const data = await interactionStore.initGraphCommunityDetailNode([
console.log(ids) edgeInfo.source,
edgeInfo.target
])
curSelectedGroup.value = data
} }
const handleClickGoBack = (currentComponentName) => { const handleClickGoBack = (currentComponentName) => {
curComponent.value = currentComponentName curComponent.value = currentComponentName
console.log(currentComponentName)
} }
</script> </script>
@ -55,18 +63,5 @@ const handleClickGoBack = (currentComponentName) => {
width: 100%; width: 100%;
height: 93%; height: 93%;
} }
.time-axis {
width: 95%;
height: 42px;
border: 1px solid #3aa1f8;
background: linear-gradient(270deg, rgba(0, 82, 125, 0.48) 0%, rgba(0, 200, 255, 0.23) 100%);
backdrop-filter: blur(3px);
position: absolute;
bottom: 0;
left: 20px;
bottom: 20px;
border-radius: 4px;
z-index: 1;
}
} }
</style> </style>

View File

@ -203,111 +203,111 @@
</template> </template>
<script setup> <script setup>
import { computed, ref, watch, nextTick } from "vue"; import { computed, ref, watch, nextTick } from "vue"
import UserPanel from "./components/userPanel.vue"; import UserPanel from "./components/userPanel.vue"
import UserChart from "./components/userChart.vue"; import UserChart from "./components/userChart.vue"
import AnchorGraph from "./components/anchorGraph.vue"; import AnchorGraph from "./components/anchorGraph.vue"
import AnchorPost from "./components/anchorPost.vue"; import AnchorPost from "./components/anchorPost.vue"
import AttentionTopic from "./components/attentionTopic.vue"; import AttentionTopic from "./components/attentionTopic.vue"
import Monitoring from "./components/monitoring.vue"; import Monitoring from "./components/monitoring.vue"
import { Icon } from "@iconify/vue"; import { Icon } from "@iconify/vue"
import * as echarts from "echarts"; import * as echarts from "echarts"
import { useKeyNodeRecognitionStore } from "@/store/keyNodeRecognition/index"; import { useKeyNodeRecognitionStore } from "@/store/keyNodeRecognition/index"
const KeyNodeOneStore = useKeyNodeRecognitionStore(); const KeyNodeOneStore = useKeyNodeRecognitionStore()
// //
const postDialog = ref(false); const postDialog = ref(false)
const topicDialog = ref(false); const topicDialog = ref(false)
const anchorDialog = ref(false); const anchorDialog = ref(false)
// //
const currentPostPost = ref(null); const currentPostPost = ref(null)
// //
const currentTopic = ref(null); const currentTopic = ref(null)
// //
const currentSelectedAnchorItem = ref(null); const currentSelectedAnchorItem = ref(null)
//tabs //tabs
const filterShowUserList = computed(() => { const filterShowUserList = computed(() => {
if (KeyNodeOneStore.currentTabType == "全部") { if (KeyNodeOneStore.currentTabType == "全部") {
return KeyNodeOneStore.mediaData; return KeyNodeOneStore.mediaData
} else { } else {
return KeyNodeOneStore.mediaData.filter((item) => item.type === KeyNodeOneStore.currentTabType); return KeyNodeOneStore.mediaData.filter((item) => item.type === KeyNodeOneStore.currentTabType)
} }
}); })
const contentType = computed(() => { const contentType = computed(() => {
return (content) => { return (content) => {
if (content.startsWith("//@")) return "转发"; if (content.startsWith("//@")) return "转发"
return "原发"; return "原发"
}; }
}); })
// //
const cutOutTheFirstTwo = computed(() => { const cutOutTheFirstTwo = computed(() => {
return (keyUserString) => { return (keyUserString) => {
return keyUserString.split(",").slice(0, 2).join(","); return keyUserString.split(",").slice(0, 2).join(",")
}; }
}); })
watch(filterShowUserList, (newList) => { watch(filterShowUserList, (newList) => {
if (!newList?.length) return; if (!newList?.length) return
const { anchorChartInfoList } = KeyNodeOneStore; const { anchorChartInfoList } = KeyNodeOneStore
const find = (name) => anchorChartInfoList.find((item) => item.name === name); const find = (name) => anchorChartInfoList.find((item) => item.name === name)
// //
const safeNumber = (val) => (isNaN(+val) ? 0 : +val); const safeNumber = (val) => (isNaN(+val) ? 0 : +val)
// //
find("锚点数量").number = newList.length; find("锚点数量").number = newList.length
find("平均粉丝数量").number = `${( find("平均粉丝数量").number = `${(
newList.reduce((acc, cur) => acc + safeNumber(cur.number?.replace("w", "")), 0) / newList.length newList.reduce((acc, cur) => acc + safeNumber(cur.number?.replace("w", "")), 0) / newList.length
).toFixed(1)}w`; ).toFixed(1)}w`
find("平均发帖频率").number = `${Math.round( find("平均发帖频率").number = `${Math.round(
newList.reduce((acc, cur) => acc + safeNumber(cur.transmit?.replace("h/1次", "")), 0) / newList.reduce((acc, cur) => acc + safeNumber(cur.transmit?.replace("h/1次", "")), 0) /
newList.length newList.length
)}h/1`; )}h/1`
find("平均参与互动次数").number = Math.floor( find("平均参与互动次数").number = Math.floor(
newList.reduce((acc, cur) => acc + safeNumber(cur.interaction), 0) / newList.length newList.reduce((acc, cur) => acc + safeNumber(cur.interaction), 0) / newList.length
); )
}); })
const handleSwitchTab = (tabName) => { const handleSwitchTab = (tabName) => {
KeyNodeOneStore.currentTabType = tabName; KeyNodeOneStore.currentTabType = tabName
}; }
const handleSwitchChartTab = (tabName) => { const handleSwitchChartTab = (tabName) => {
KeyNodeOneStore.currentChartTabType = tabName; KeyNodeOneStore.currentChartTabType = tabName
}; }
const handlePostDialog = (post) => { const handlePostDialog = (post) => {
postDialog.value = true; postDialog.value = true
currentPostPost.value = post; currentPostPost.value = post
console.log(post); console.log(post)
}; }
const handleGotTopicDialog = (topic) => { const handleGotTopicDialog = (topic) => {
topicDialog.value = true; topicDialog.value = true
currentTopic.value = topic; currentTopic.value = topic
console.log(topic); console.log(topic)
}; }
let hotChartInstance = null; let hotChartInstance = null
const renderHotChart = () => { const renderHotChart = () => {
nextTick(() => { nextTick(() => {
const chartDom = document.getElementById("hotChart"); const chartDom = document.getElementById("hotChart")
if (!chartDom) return; if (!chartDom) return
if (hotChartInstance) { if (hotChartInstance) {
hotChartInstance.dispose(); hotChartInstance.dispose()
} }
hotChartInstance = echarts.init(chartDom); hotChartInstance = echarts.init(chartDom)
const option = { const option = {
backgroundColor: "transparent", backgroundColor: "transparent",
tooltip: { trigger: "axis" }, tooltip: { trigger: "axis" },
@ -324,7 +324,7 @@ const renderHotChart = () => {
axisLine: { show: false }, axisLine: { show: false },
axisTick: { show: false }, axisTick: { show: false },
axisLabel: { color: "#B6D6F7", fontSize: 13 }, axisLabel: { color: "#B6D6F7", fontSize: 13 },
data: ["7.18", "7.19", "7.20", "7.21", "7.22", "7.23", "7.24", "7.25"] data: ["6.25", "6.26", "6.27", "6.28", "6.29", "6.30", "7.1", "7.2"]
}, },
yAxis: { yAxis: {
type: "value", type: "value",
@ -370,26 +370,26 @@ const renderHotChart = () => {
padding: [0, 0, 0, 30] padding: [0, 0, 0, 30]
} }
] ]
}; }
hotChartInstance.setOption(option); hotChartInstance.setOption(option)
}); })
}; }
const handleOpenAnchorDialog = (params) => { const handleOpenAnchorDialog = (params) => {
anchorDialog.value = params.anchorDialog; anchorDialog.value = params.anchorDialog
currentSelectedAnchorItem.value = params.currentSelectAnchorNode; currentSelectedAnchorItem.value = params.currentSelectAnchorNode
console.log(currentSelectedAnchorItem.value); console.log(currentSelectedAnchorItem.value)
}; }
watch(topicDialog, (val) => { watch(topicDialog, (val) => {
if (val) { if (val) {
renderHotChart(); renderHotChart()
} else { } else {
if (hotChartInstance) { if (hotChartInstance) {
hotChartInstance.dispose(); hotChartInstance.dispose()
hotChartInstance = null; hotChartInstance = null
} }
} }
}); })
</script> </script>
<style scoped lang="less"> <style scoped lang="less">