diff --git a/src/assets/images/abnormalGroup/abnormal-group-legends.png b/src/assets/images/abnormalGroup/abnormal-group-legends.png index 85e6475..a919376 100644 Binary files a/src/assets/images/abnormalGroup/abnormal-group-legends.png and b/src/assets/images/abnormalGroup/abnormal-group-legends.png differ diff --git a/src/assets/images/abnormalGroup/abnormal-node-legend-icon.png b/src/assets/images/abnormalGroup/abnormal-node-legend-icon.png new file mode 100644 index 0000000..89fe87e Binary files /dev/null and b/src/assets/images/abnormalGroup/abnormal-node-legend-icon.png differ diff --git a/src/utils/customePaint.js b/src/utils/customePaint.js index 8868cc0..3aa915e 100644 --- a/src/utils/customePaint.js +++ b/src/utils/customePaint.js @@ -46,7 +46,15 @@ export const paintNodeFunction = (storeId) => { ctx.save() ctx.beginPath() ctx.arc(0, 0, rFill, 0, Math.PI * 2) - ctx.fillStyle = `rgba(${this.fillColor}, ${this.alpha})` + if(this.fillColor == '85, 125, 15'){ + ctx.fillStyle = `rgba(75, 241, 184, ${this.alpha})` + }else if(this.fillColor == '15, 106, 125'){ + ctx.fillStyle = `rgba(69, 192, 242, ${this.alpha})` + }else if(this.fillColor == '125, 114, 15'){ + ctx.fillStyle = `rgba(250, 222, 37, ${this.alpha})` + }else{ + ctx.fillStyle = `rgba(${this.fillColor}, ${this.alpha})` + } ctx.fill() ctx.restore() @@ -63,10 +71,11 @@ export const paintNodeFunction = (storeId) => { }; // 选择配色方案 const fc = (this.fillColor || "").replace(/\s+/g, ""); - const isMint = fc === "75,241,184"; - const isBlue = fc === "69,192,242"; + // const isMint = fc === "85, 125, 15"; + const isMint = fc === "75,241,184" + const isBlue = fc === "69,192,242" const isRed = fc === "255,50,60"; - const isYellow = fc === "250,222,37"; + const isYellow = fc === "250,222,37" // 默认都按照 SVG:每层 0.24 透明度(再乘整体 alpha) const layerAlpha = 0.24 * (this.alpha ?? 1); @@ -76,16 +85,32 @@ export const paintNodeFunction = (storeId) => { if(isMint){ lg.addColorStop(0, '#0FE9BE'); lg.addColorStop(1, '#91FFB2'); + }else if (this.fillColor == '85, 125, 15') { + // lg.addColorStop(0, '#0FE9BE'); + // lg.addColorStop(1, '#91FFB2'); + lg.addColorStop(0, '#FF0000'); + lg.addColorStop(1, '#FF0909'); }else if(isBlue){ lg.addColorStop(0, "#009DFF"); lg.addColorStop(1, "#00FFF2"); + }else if (this.fillColor == '15, 106, 125') { + // lg.addColorStop(0, '#009DFF'); + // lg.addColorStop(1, '#00FFF2'); + lg.addColorStop(0, '#FF0000'); + lg.addColorStop(1, '#FF0909'); }else if(isRed){ lg.addColorStop(0, '#FF0000'); lg.addColorStop(1, '#FF0909'); }else if(isYellow){ lg.addColorStop(0, '#FFDA09'); lg.addColorStop(1, '#FFDA09'); + }else if(this.fillColor == '125, 114, 15'){ + // lg.addColorStop(0, '#FFDA09'); + // lg.addColorStop(1, '#FFDA09'); + lg.addColorStop(0, '#FF0000'); + lg.addColorStop(1, '#FF0909'); } + ctx.globalAlpha = 0.24 * (this.alpha ?? 1); // 与节点整体透明度相乘 ctx.fillStyle = lg; ctx.fill(); @@ -100,10 +125,24 @@ export const paintNodeFunction = (storeId) => { rg.addColorStop(0.0, 'rgba(230,249,255,1)'); // #E6F9FF rg.addColorStop(0.3693,'rgba(190,255,219,0.5)'); // #BEFFDB @ 0.5 rg.addColorStop(1.0, 'rgba(0,0,0,0)'); + }else if(this.fillColor == '85, 125, 15'){ + // rg.addColorStop(0.0, 'rgba(230,249,255,1)'); // #E6F9FF + // rg.addColorStop(0.3693,'rgba(190,255,219,0.5)'); // #BEFFDB @ 0.5 + // rg.addColorStop(1.0, 'rgba(0,0,0,0)'); + rg.addColorStop(0.0, 'rgba(255,255,255,1)'); + rg.addColorStop(0.3693,'rgba(255,200,200,0.5)'); + rg.addColorStop(1.0, 'rgba(0, 0, 0, 0)'); }else if(isBlue){ rg.addColorStop(0.0, 'rgba(229,249,255,1)'); rg.addColorStop(0.3693,'rgba(141,255,253,0.5)'); rg.addColorStop(1.0, 'rgba(0, 0, 0, 0)'); + }else if (this.fillColor == '15, 106, 125') { + // rg.addColorStop(0.0, 'rgba(229,249,255,1)'); + // rg.addColorStop(0.3693,'rgba(141,255,253,0.5)'); + // rg.addColorStop(1.0, 'rgba(0, 0, 0, 0)'); + rg.addColorStop(0.0, 'rgba(255,255,255,1)'); + rg.addColorStop(0.3693,'rgba(255,200,200,0.5)'); + rg.addColorStop(1.0, 'rgba(0, 0, 0, 0)'); }else if(isRed){ rg.addColorStop(0.0, 'rgba(255,255,255,1)'); rg.addColorStop(0.3693,'rgba(255,200,200,0.5)'); @@ -112,6 +151,13 @@ export const paintNodeFunction = (storeId) => { rg.addColorStop(0.0, 'rgba(229,249,255,1)'); rg.addColorStop(0.3693,'rgba(254,255,200,0.5)'); rg.addColorStop(1.0, 'rgba(0, 0, 0, 0)'); + }else if(this.fillColor == '125, 114, 15'){ + // rg.addColorStop(0.0, 'rgba(229,249,255,1)'); + // rg.addColorStop(0.3693,'rgba(254,255,200,0.5)'); + // rg.addColorStop(1.0, 'rgba(0, 0, 0, 0)'); + rg.addColorStop(0.0, 'rgba(255,255,255,1)'); + rg.addColorStop(0.3693,'rgba(255,200,200,0.5)'); + rg.addColorStop(1.0, 'rgba(0, 0, 0, 0)'); } ctx.globalAlpha = 0.24 * (this.alpha ?? 1); ctx.fillStyle = rg; @@ -126,7 +172,16 @@ export const paintNodeFunction = (storeId) => { ctx.lineWidth = dashWidth ctx.setLineDash([dash, gap]) ctx.lineCap = "round" - ctx.strokeStyle = `rgba(${this.fillColor}, ${this.alpha})` + const RED = '220,50,60' + if(this.fillColor == '85, 125, 15'){ + ctx.strokeStyle = `rgba(${RED}, ${this.alpha})` + }else if(this.fillColor == '15, 106, 125'){ + ctx.strokeStyle = `rgba(${RED}, ${this.alpha})` + }else if(this.fillColor == '125, 114, 15'){ + ctx.strokeStyle = `rgba(${RED}, ${this.alpha})` + }else{ + ctx.strokeStyle = `rgba(${this.fillColor}, ${this.alpha})` + } ctx.stroke() ctx.setLineDash([]) // 清理,避免影响后续绘制 ctx.restore() diff --git a/src/views/GroupEvolution/components/groupGraph.vue b/src/views/GroupEvolution/components/groupGraph.vue index db3ed76..f9b030a 100644 --- a/src/views/GroupEvolution/components/groupGraph.vue +++ b/src/views/GroupEvolution/components/groupGraph.vue @@ -2,7 +2,10 @@
-
+
+ +
疑似异常社团
+
{ // 组色(与你现有 colorMap 一致) const GROUP_ALPHA = 0.3 const RED = "220,50,60" + const greenRed = "85, 125, 15" + const blueRed = "15, 106, 125" + const yellowRed = "125, 114, 15" + // 时间门控:达到阈值就把各组异常节点染红 const shouldA = now >= TA const shouldB = now >= TB @@ -190,50 +197,51 @@ const runDiffForceLayout = (layoutConfig, layoutType, isAsync) => { if (shouldA) { graphVis.nodes = graphVis.nodes.map((n) => { if (props.store.graphAbnormalData.groupA.includes(n.id)) { - n.fillColor = RED + // n.fillColor = RED + n.fillColor = greenRed } return n }) - graphVis.addNodesInGroup( + /* graphVis.addNodesInGroup( graphVis.nodes.filter((n) => props.store.graphAbnormalData.groupA.includes(n.id)), { shape: "circle", color: RED, alpha: GROUP_ALPHA } - ) + ) */ } if (shouldB) { graphVis.nodes = graphVis.nodes.map((n) => { if (props.store.graphAbnormalData.groupB.includes(n.id)) { - n.fillColor = RED + n.fillColor = yellowRed } return n }) - graphVis.addNodesInGroup( + /* graphVis.addNodesInGroup( graphVis.nodes.filter((n) => props.store.graphAbnormalData.groupB.includes(n.id)), { shape: "circle", color: RED, alpha: GROUP_ALPHA } - ) + ) */ } if (shouldC) { graphVis.nodes = graphVis.nodes.map((n) => { if (props.store.graphAbnormalData.groupC.includes(n.id)) { - n.fillColor = RED + n.fillColor = blueRed } return n }) - graphVis.addNodesInGroup( + /* graphVis.addNodesInGroup( graphVis.nodes.filter((n) => props.store.graphAbnormalData.groupC.includes(n.id)), { shape: "circle", color: RED, alpha: GROUP_ALPHA } - ) + ) */ } // graphVis.autoGroupLayout(graphVis.nodes) } @@ -355,11 +363,34 @@ watch( } .legends { position: absolute; + display: flex; + align-items: center; + justify-content: center; width: 160px; height: 55px; right: 2%; top: 76%; background-image: url("@/assets/images/abnormalGroup/abnormal-group-legends.png"); + .legend-icon { + position: absolute; + top: 17px; + left: 15px; + width: 30px; + height: 30px; + } + .legend-text { + position: absolute; + top: 12px; + left: 50px; + height: 30px; + line-height: 30px; + font-family: "PingFang SC"; + font-style: normal; + font-weight: 400; + font-size: 16px; + font-weight: 400; + color: #fff; + } } .container { width: 100%; diff --git a/src/views/LinkPrediction/socialGroups/components/graph.vue b/src/views/LinkPrediction/socialGroups/components/graph.vue index 9e6f968..f0a622d 100644 --- a/src/views/LinkPrediction/socialGroups/components/graph.vue +++ b/src/views/LinkPrediction/socialGroups/components/graph.vue @@ -41,7 +41,6 @@ const handleClickNode = async (nodeInfo) => { } const handleClickEdge = async (edgeInfo, groupIdList) => { - console.log("点击边") socialGroupsStore.curComponent = "detailNode" socialGroupsStore.clickEvent = "edge" socialGroupsStore.curRelationId = ""