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 `