diff --git a/src/assets/images/abnormalGroup/abnormal-action-analysis-item-title.png b/src/assets/images/abnormalGroup/abnormal-action-analysis-item-title.png index 39739b9..121bfac 100644 Binary files a/src/assets/images/abnormalGroup/abnormal-action-analysis-item-title.png and b/src/assets/images/abnormalGroup/abnormal-action-analysis-item-title.png differ diff --git a/src/assets/images/abnormalGroup/abnormal-user-group-item-title.png b/src/assets/images/abnormalGroup/abnormal-user-group-item-title.png new file mode 100644 index 0000000..c7bd9af Binary files /dev/null and b/src/assets/images/abnormalGroup/abnormal-user-group-item-title.png differ diff --git a/src/views/GroupEvolution/abnormalGroup/components/groupPanel.vue b/src/views/GroupEvolution/abnormalGroup/components/groupPanel.vue index 42bbc26..ff3b47d 100644 --- a/src/views/GroupEvolution/abnormalGroup/components/groupPanel.vue +++ b/src/views/GroupEvolution/abnormalGroup/components/groupPanel.vue @@ -6,7 +6,7 @@
{{ group.type }}
@@ -68,7 +68,7 @@ const props = defineProps({ .groupPanel-list { width: 100%; height: 470px; - padding: 20px 20px; + padding: 0px 20px; overflow: auto; &::-webkit-scrollbar { width: 3px; /* 垂直滚动条宽度 */ @@ -83,6 +83,7 @@ const props = defineProps({ } .group-item { width: 100%; + padding-top: 20px; padding-bottom: 20px; border-bottom: 0.5px solid rgba(0, 113, 188, 0.5); .group-item-title { diff --git a/src/views/GroupEvolution/component/groupPost.vue b/src/views/GroupEvolution/component/groupPost.vue index b4b1d2c..1ba421b 100644 --- a/src/views/GroupEvolution/component/groupPost.vue +++ b/src/views/GroupEvolution/component/groupPost.vue @@ -321,8 +321,8 @@ onBeforeUnmount(() => { position: relative; .title-text { position: absolute; - top: 0; - left: 0; + top: 2px; + left: 12px; color: #8efbff; font-family: PingFang SC; font-weight: 400; diff --git a/src/views/KeyNodeRecognition2/components/graph/bridgeCommunityGraph.vue b/src/views/KeyNodeRecognition2/components/graph/bridgeCommunityGraph.vue index 05c8bcd..8cd6a65 100644 --- a/src/views/KeyNodeRecognition2/components/graph/bridgeCommunityGraph.vue +++ b/src/views/KeyNodeRecognition2/components/graph/bridgeCommunityGraph.vue @@ -93,7 +93,7 @@ const processData = async() => { id: bridgeNodeId, category: 0, symbol: bridgeNodeImg ? `image://${bridgeNodeImg}` : 'circle', - symbolSize: 100, + symbolSize: 150, originalId: bridgeId // 存储原始ID用于识别 }); addedBridgeNodes.add(bridgeId); @@ -169,11 +169,12 @@ const initChart = async() => { chartInstance = echarts.init(chartDom); + const SERIES_INDEX = 0; + // 添加鼠标悬浮事件监听 chartInstance.on('mouseover', function(params) { if (!params.data) return; - const isBridgeNode = params.data.category === 0; - const isCommunityNode = params.data.category === 1; + /* const isBridgeNode = params.data.category === 0; if (isBridgeNode) { // 如果是桥梁节点 @@ -181,6 +182,28 @@ const initChart = async() => { // 无论当前是否有激活节点,都设置为当前节点 activeNodeId.value = nodeId; updateNodeImage(nodeId, true); + } */ + + if (params.dataType === 'node') { + // 仅节点时触发相邻高亮 + chartInstance.dispatchAction({ + type: 'focusNodeAdjacency', + seriesIndex: SERIES_INDEX, + dataIndex: params.dataIndex + }); + + // 你已有的桥梁节点头像切换逻辑 + const isBridgeNode = params.data.category === 0; + if (isBridgeNode) { + const nodeId = params.data.originalId; + activeNodeId.value = nodeId; + updateNodeImage(nodeId, true); + } + } else if (params.dataType === 'edge') { + // 悬浮在边上:不高亮 + chartInstance.dispatchAction({ type: 'unfocusNodeAdjacency', seriesIndex: SERIES_INDEX }); + chartInstance.dispatchAction({ type: 'downplay', seriesIndex: SERIES_INDEX }); + // 也可以顺手关掉 tooltip(你 formatter 已经返回空字符串,其实也行) } }); @@ -188,9 +211,7 @@ const initChart = async() => { // 添加鼠标离开事件监听 chartInstance.on('mouseout', function(params) { if (!params.data) return; - const isBridgeNode = params.data.category === 0; - const isCommunityNode = params.data.category === 1; - + /* const isBridgeNode = params.data.category === 0; if (isBridgeNode) { // 如果是桥梁节点 const nodeId = params.data.originalId; @@ -198,6 +219,29 @@ const initChart = async() => { activeNodeId.value = null; updateNodeImage(nodeId, false); } + } */ + if (params.dataType === 'node') { + // 仅节点移出时取消相邻高亮 + chartInstance.dispatchAction({ + type: 'unfocusNodeAdjacency', + seriesIndex: SERIES_INDEX + }); + + // 你已有的桥梁节点头像还原逻辑 + const isBridgeNode = params.data.category === 0; + if (isBridgeNode) { + const nodeId = params.data.originalId; + if (activeNodeId.value === nodeId) { + activeNodeId.value = null; + updateNodeImage(nodeId, false); + } + } + } else if (params.dataType === 'edge') { + // 从边移出也确保没有残留高亮 + chartInstance.dispatchAction({ + type: 'unfocusNodeAdjacency', + seriesIndex: SERIES_INDEX + }); } }); @@ -390,13 +434,20 @@ const initChart = async() => { }, animationDurationUpdate: 3500, // 节点移动更平滑 animationEasingUpdate: 'quinticInOut', - emphasis: { // 高亮配置 - focus: 'adjacency', // 高亮相邻节点 - blurScope: 'coordinateSystem', // 失去焦点时取消所有高亮 - lineStyle: { // 高亮时线条样式 - width: 10 // 线条宽度(10) - } + emphasis: { + focus: 'adjacency', // 有了这个,才会触发“其他元素进入 blur 状态” + blurScope: 'series', // 只在本系列里变暗 + scale: false, // 不要把节点放大,避免跳动 + lineStyle: { opacity: 1 }, + itemStyle: { opacity: 1 }, + label: { opacity: 1 } }, + blur: { + // 非相邻元素进入“模糊/暗”状态时的样式(相当于“隐藏”) + lineStyle: { opacity: 0.05 }, + itemStyle: { opacity: 0.1 }, + label: { opacity: 0 } + } } ] }; diff --git a/src/views/KeyNodeRecognition2/components/graph/detailCommunityGraph.vue b/src/views/KeyNodeRecognition2/components/graph/detailCommunityGraph.vue index 6c6bcc1..32afa13 100644 --- a/src/views/KeyNodeRecognition2/components/graph/detailCommunityGraph.vue +++ b/src/views/KeyNodeRecognition2/components/graph/detailCommunityGraph.vue @@ -70,6 +70,52 @@ const initChart = async () => { chart = echarts.init(detailContainer.value); + + const SERIES_INDEX = 0; + +// 仅在节点上触发“相邻高亮”,并把其它元素降为 blur(已由 series.blur 定义) +chart.on('mouseover', 'series.graph', function (params) { + if (!params.data) return; + + if (params.dataType === 'node') { + chart.dispatchAction({ + type: 'focusNodeAdjacency', + seriesIndex: SERIES_INDEX, + dataIndex: params.dataIndex + }); + + // 你的桥梁节点换头像逻辑 + if (params.data.category === 0) { + activeNodeId.value = params.data.originalId; + updateNodeImage(bridgeNodeImages); + } + + } else if (params.dataType === 'edge') { + // 悬浮在“边”上:不做任何强调,立刻撤销 + chart.dispatchAction({ type: 'unfocusNodeAdjacency', seriesIndex: SERIES_INDEX }); + chart.dispatchAction({ type: 'downplay', seriesIndex: SERIES_INDEX }); + } +}); + +chart.on('mouseout', 'series.graph', function (params) { + if (!params.data) return; + + if (params.dataType === 'node') { + chart.dispatchAction({ type: 'unfocusNodeAdjacency', seriesIndex: SERIES_INDEX }); + + if (params.data.category === 0) { + // 还原桥梁节点头像 + if (activeNodeId.value === params.data.originalId) { + activeNodeId.value = ''; + updateNodeImage(bridgeNodeImages); + } + } + + } else if (params.dataType === 'edge') { + chart.dispatchAction({ type: 'unfocusNodeAdjacency', seriesIndex: SERIES_INDEX }); + } +}); + // 点击桥梁节点->弹窗显示桥梁节点的详情 chart.on('click', function(params){ // 如果是桥梁节点 @@ -159,7 +205,7 @@ const initChart = async () => { if (isBridgeNode) { const images = bridgeNodeImages.get(userIdStr); symbol = images.defImg ? `image://${images.defImg}` : 'circle'; - symbolSize = 60; + symbolSize = 150; // 查找对应的leader数据 const leaderData = keyNodeStore2.allLeaderData.find(leader => String(leader.nodeId) === userIdStr); if (leaderData) { @@ -233,6 +279,7 @@ const initChart = async () => { borderWidth: 0, extraCssText: "box-shadow:none;padding:0;", formatter: function (params) { + if (params.dataType === 'edge') return ''; if (params.dataType === "node" && params.data.category === 0) { return `