This commit is contained in:
qumeng039@126.com 2025-08-01 14:48:58 +08:00
commit 925020aad0
8 changed files with 175 additions and 7 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@ -469,6 +469,7 @@ export const useSocialGroupsStore = defineStore("socialGroups", {
customStatisticsObj.hiddenInteractionCount == null customStatisticsObj.hiddenInteractionCount == null
) { ) {
customStatisticsObj.hiddenInteractionCount = 1 customStatisticsObj.hiddenInteractionCount = 1
customStatisticsObj.groupCount = ids[0] === ids[1] ? 1 : 3 customStatisticsObj.groupCount = ids[0] === ids[1] ? 1 : 3
} }

View File

@ -18,6 +18,7 @@ import nodeHoverImg from "@/assets/images/nodeHover.png"
let chart = null let chart = null
let linkList = null let linkList = null
let nodeList = null
const emit = defineEmits(["click:node", "click:edge"]) const emit = defineEmits(["click:node", "click:edge"])
const statisticsList = inject("statisticsList"); const statisticsList = inject("statisticsList");
const communityNodeList = inject("communityNodeList"); const communityNodeList = inject("communityNodeList");
@ -34,7 +35,7 @@ const initChart = async () => {
neighbors: item.neighbors.map((nei) => ({ ...nei, name: parseInt(nei.id) })), neighbors: item.neighbors.map((nei) => ({ ...nei, name: parseInt(nei.id) })),
category: item.isIncludePredictNodes ? 1 : 0, category: item.isIncludePredictNodes ? 1 : 0,
selfIncludeImplicitRelationship: selfIncludeImplicitRelationship:
item.neighbors.map((nei) => nei.id).includes(item.id) && //id item.neighbors.map((nei) => nei.id).includes(item.id) && //id
item.neighbors.find((nei) => nei.id == item.id).isHidden item.neighbors.find((nei) => nei.id == item.id).isHidden
})) }))
@ -60,6 +61,7 @@ const initChart = async () => {
}) })
}) })
linkList = links linkList = links
nodeList = nodes
const data = { nodes, links } const data = { nodes, links }
const categories = [ const categories = [
@ -211,7 +213,7 @@ const initChart = async () => {
shadowBlur: 20, shadowBlur: 20,
shadowColor: "#c4a651", shadowColor: "#c4a651",
borderColor: "#fcd267", borderColor: "#fcd267",
borderWidth: node.isIncludePredictNodes == false ? 1 : 5, borderWidth: 5,
borderType: "solid" borderType: "solid"
} }
} }
@ -280,6 +282,7 @@ const handleClickNode = () => {
onMounted(async () => { onMounted(async () => {
await initChart() await initChart()
handleClickNode() handleClickNode()
console.log("nodeList", nodeList);
}) })
onUnmounted(() => { onUnmounted(() => {

View File

@ -85,7 +85,7 @@ const { clickEvent } = storeToRefs(socialGroupsStore)
const chartsData = ref({}) const chartsData = ref({})
const emit = defineEmits(["click:goback"]) const emit = defineEmits(["click:goback", "click:openDialog"])
const handleGoback = () => { const handleGoback = () => {
pause() pause()
emit("click:goback", "CommunityNode") emit("click:goback", "CommunityNode")
@ -318,9 +318,23 @@ const initChart = async () => {
nodes.push({ nodes.push({
id: item.userId, id: item.userId,
name: item.userName, name: item.userName,
//
avatarData: item.avatarData,
//
fans: item.fans,
symbolSize: 40, symbolSize: 40,
//
postNum: item.postNum, postNum: item.postNum,
fancy: item.fans //
postFreqPerDay: item.postFreqPerDay,
//
interactionNum: item.interactionNum,
//
interactionFreqPerDay: item.interactionFreqPerDay,
//
interactedNum: item.interactedNum,
//
recentActiveTime: item.recentActiveTime,
}) })
}) })
Object.entries(socialGroupsStore.communityDetailNodeList).forEach(([parentId, children]) => { Object.entries(socialGroupsStore.communityDetailNodeList).forEach(([parentId, children]) => {
@ -597,6 +611,15 @@ const highLightUserNodes = (newHiglightUserIdList) => {
}, 1000) }, 1000)
} }
const handleClickNode = () => {
chart.on("click", function (params) {
if (params.dataType == "node" && curHighlightUserIdList.value.includes(params.data.id)) {
console.log("detail点击点",params.data)
emit("click:openDialog", params.data)
}
})
}
onMounted(() => { onMounted(() => {
initChart() initChart()
chart.on("legendselectchanged", function (params) { chart.on("legendselectchanged", function (params) {
@ -607,6 +630,7 @@ onMounted(() => {
}) })
highLightUserNodes() highLightUserNodes()
play() play()
handleClickNode()
}) })
</script> </script>

View File

@ -10,12 +10,13 @@
<DetailNode <DetailNode
v-else v-else
@click:goback="handleClickGoBack" @click:goback="handleClickGoBack"
@click:openDialog="handleClickOpenDialog"
></DetailNode> ></DetailNode>
</div> </div>
</template> </template>
<script setup> <script setup>
import { defineProps } from "vue" import { defineProps, defineEmits } from "vue"
import CommunityNode from "./communityNode.vue" import CommunityNode from "./communityNode.vue"
import DetailNode from "./detailNode.vue" import DetailNode from "./detailNode.vue"
import { useSocialGroupsStore } from "@/store/llinkPrediction/index" import { useSocialGroupsStore } from "@/store/llinkPrediction/index"
@ -26,6 +27,12 @@ const props = defineProps({
default: "" default: ""
} }
}) })
const emit = defineEmits(["click:openUserInfoDialog"])
const handleClickOpenDialog = (userInfo) => {
if(userInfo) {
emit("click:openUserInfoDialog", {userInfoDialog: true, curSelectedUser: userInfo})
}
}
const handleClickNode = async (nodeInfo) => { const handleClickNode = async (nodeInfo) => {
// //

View File

@ -59,10 +59,11 @@ const props = defineProps({
default: 480 default: 480
} }
}); });
// ssss
const handleUserItem = (index, group = {}) => { const handleUserItem = (index, group = {}) => {
curUserGroupIndex.value = index; curUserGroupIndex.value = index;
// id // id
console.log("打印用户列表:",props.userList)
socialGroupsStore.curHighlightUserIdList = group.list.map((item)=>item.userId) socialGroupsStore.curHighlightUserIdList = group.list.map((item)=>item.userId)
emit("click:selectedGroup", group); emit("click:selectedGroup", group);
}; };

View File

@ -14,7 +14,10 @@
</div> </div>
<div class="middle-container"> <div class="middle-container">
<div class="graph"> <div class="graph">
<Graph :title="graphTitleImg"></Graph> <Graph
:title="graphTitleImg"
@click:openUserInfoDialog="handleOpenUserInfoDialog"
></Graph>
</div> </div>
<div class="postList"> <div class="postList">
<PostList <PostList
@ -56,10 +59,69 @@
</div> </div>
</div> </div>
</el-dialog> </el-dialog>
<el-dialog v-model="userInfoDialog" width="640" align-center class="custom-dialog">
<img src="@/assets/images/linkPrediction/title/user-info-title.png" alt="" class="userInfoTitle" />
<div class="user-dialog-content">
<div class="user-basic-info">
<img :src="curSelectedUser.avatarData ? getAvatarUrl(curSelectedUser.avatarData) : defaultAvatar" alt="" class="avatar">
<div class="info-detail">
<div class="username">
{{ curSelectedUser.name }}
</div>
<div class="info-fans-posts">
<div class="fans">粉丝量&nbsp;&nbsp;<p>{{ curSelectedUser.fans }}</p></div>
<div class="posts">发帖数&nbsp;&nbsp;<p>{{ curSelectedUser.postNum }}</p></div>
</div>
</div>
</div>
<div class="info-group">
<div class="info-item">
<img src="@/assets/images/linkPrediction/icon/user-info-group-icon.png" alt="">
<div class="info-item-content">
发帖总数&nbsp;&nbsp;<p>{{ curSelectedUser.postNum }}</p>
</div>
</div>
<div class="info-item">
<img src="@/assets/images/linkPrediction/icon/user-info-group-icon.png" alt="">
<div class="info-item-content">
发帖频率&nbsp;&nbsp;<p>{{ curSelectedUser.postFreqPerDay }}</p>
</div>
</div>
<div class="info-item">
<img src="@/assets/images/linkPrediction/icon/user-info-group-icon.png" alt="">
<div class="info-item-content">
参与互动次数&nbsp;&nbsp;<p>{{ curSelectedUser.interactionNum }}</p>
</div>
</div>
<div class="info-item">
<img src="@/assets/images/linkPrediction/icon/user-info-group-icon.png" alt="">
<div class="info-item-content">
参与互动频率&nbsp;&nbsp;<p>{{ curSelectedUser.interactionFreqPerDay }}</p>
</div>
</div>
<div class="info-item">
<img src="@/assets/images/linkPrediction/icon/user-info-group-icon.png" alt="">
<div class="info-item-content">
帖文被互动次数&nbsp;&nbsp;<p>{{ curSelectedUser.interactedNum }}</p>
</div>
</div>
<div class="info-item">
<img src="@/assets/images/linkPrediction/icon/user-info-group-icon.png" alt="">
<div class="info-item-content">
最近活跃时间&nbsp;&nbsp;<p>{{ curSelectedUser.recentActiveTime }}</p>
</div>
</div>
</div>
</div>
</el-dialog>
</div> </div>
</template> </template>
<script setup> <script setup>
import defaultAvatar from "@/assets/images/avatar/default.png";
import { onMounted, provide, ref } from "vue"; import { onMounted, provide, ref } 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";
@ -73,11 +135,16 @@ import userPanelTitleImg from "@/assets/images/linkPrediction/title/user-title.p
import userChartTitleImg from "@/assets/images/linkPrediction/title/interaction-strenth-title.png"; import userChartTitleImg from "@/assets/images/linkPrediction/title/interaction-strenth-title.png";
import graphTitleImg from "@/assets/images/linkPrediction/title/graph1-title.png"; import graphTitleImg from "@/assets/images/linkPrediction/title/graph1-title.png";
import analysisTitleImg from "@/assets/images/linkPrediction/title/analysis-title.png"; import analysisTitleImg from "@/assets/images/linkPrediction/title/analysis-title.png";
import { getAvatarUrl } from "@/utils/transform"
const socialGroupsStore = useSocialGroupsStore(); const socialGroupsStore = useSocialGroupsStore();
// //
const postDialog = ref(false); const postDialog = ref(false);
//
const userInfoDialog = ref(false);
const curSelectedUser = ref(null)
// //
const currentPostPost = ref(null); const currentPostPost = ref(null);
@ -93,6 +160,12 @@ const handleSelectedUserGroup = (group) => {
socialGroupsStore.getSocialGroupPostListByRelationId(group.relationId) socialGroupsStore.getSocialGroupPostListByRelationId(group.relationId)
}; };
const handleOpenUserInfoDialog = (params) => {
userInfoDialog.value = params.userInfoDialog
curSelectedUser.value = params.curSelectedUser
console.log("index.vue打印当前选中的用户",curSelectedUser.value)
}
onMounted(() => { onMounted(() => {
socialGroupsStore.initGroupList(); socialGroupsStore.initGroupList();
socialGroupsStore.initPostList("212431"); socialGroupsStore.initPostList("212431");
@ -123,11 +196,70 @@ provide("statisticsList", socialGroupsStore.statisticsList);
margin-top: -24px; margin-top: -24px;
margin-left: -2px; margin-left: -2px;
} }
:deep(.custom-dialog) .userInfoTitle {
margin-top: -24px;
margin-left: -2px;
}
:deep(.custom-dialog) .dialog-content { :deep(.custom-dialog) .dialog-content {
width: 100%; width: 100%;
padding: 25px 20px; padding: 25px 20px;
} }
:deep(.custom-dialog) .user-dialog-content {
width: 100%;
padding: 30px;
.user-basic-info {
width: 428px;
display: flex;
justify-content: start;
align-items: center;
.avatar {
width: 70px;
height: 70px;
border-radius: 5px;
}
.info-detail {
height: 70px;
padding: 0 24px;
color: #fff;
display: flex;
flex-direction: column;
justify-content: space-around;
.info-fans-posts {
display: flex;
justify-content: start;
.fans {
margin-right: 63px;
display: flex;
justify-content: start;
}
.posts {
display: flex;
justify-content: start;
}
}
}
}
.info-group {
margin-top: 32px;
margin-left: -10px;
display: grid;
grid-template-columns: 1fr 1fr;
row-gap: 15px;
color: #fff;
font-size: 16px;
.info-item {
display: flex;
justify-content: start;
align-items: center;
.info-item-content {
display: flex;
justify-content: start;
}
}
}
}
:deep(.custom-dialog) .dialog-content .content { :deep(.custom-dialog) .dialog-content .content {
color: rgba(255, 255, 255, 0.8); color: rgba(255, 255, 255, 0.8);
font-family: "PingFang SC"; font-family: "PingFang SC";