变红动画
This commit is contained in:
		
							parent
							
								
									879c87e88c
								
							
						
					
					
						commit
						6d2c1eff7d
					
				| 
						 | 
				
			
			@ -95,7 +95,6 @@ export function getAbnormalGroupInteractionChart() {
 | 
			
		|||
}
 | 
			
		||||
// 4.4异常行为分析
 | 
			
		||||
export function getAbnormalGroupBehaviorPosts(time) {
 | 
			
		||||
  console.log(time)
 | 
			
		||||
  return http.get(`/groupEvolution/groupException/posts?date=${time}`)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -712,11 +712,18 @@ export const useGroupMemberStore = defineStore("groupMember", {
 | 
			
		|||
            type: node.groupId
 | 
			
		||||
          }
 | 
			
		||||
        })
 | 
			
		||||
        console.log(this.graph);
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  persist: true // 开启持久化
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
// —— 时间门槛 —— 
 | 
			
		||||
const T0 = "2024-06-19T07:57:46Z";  // 默认渲染出全部节点
 | 
			
		||||
const TA = "2024-06-19T08:57:55Z"; // A 组异常开始
 | 
			
		||||
const TB = "2024-06-19T10:58:03Z"; // B 组异常开始
 | 
			
		||||
const TC = "2024-06-19T12:58:04Z"; // C 组异常开始
 | 
			
		||||
 | 
			
		||||
export const useAnomalousGroup = defineStore("anomalousGroup", {
 | 
			
		||||
  state: () => ({
 | 
			
		||||
    groupList: [],
 | 
			
		||||
| 
						 | 
				
			
			@ -856,7 +863,145 @@ export const useAnomalousGroup = defineStore("anomalousGroup", {
 | 
			
		|||
        CUSUM: 5.0,
 | 
			
		||||
        KS: 0.02
 | 
			
		||||
      }
 | 
			
		||||
    ]
 | 
			
		||||
    ],
 | 
			
		||||
    currentUtc: T0,
 | 
			
		||||
    graphData: {
 | 
			
		||||
      nodes: [
 | 
			
		||||
        { id: "G01_A", type: "0", isAnomaly: false, label: "G01" },
 | 
			
		||||
        { id: "G02_A", type: "0", isAnomaly: true,  label: "G02" },
 | 
			
		||||
        { id: "G03_A", type: "0", isAnomaly: false, label: "G03" },
 | 
			
		||||
        { id: "G04_A", type: "0", isAnomaly: false, label: "G04" },
 | 
			
		||||
        { id: "G05_A", type: "0", isAnomaly: false, label: "G05" },
 | 
			
		||||
        { id: "G06_A", type: "0", isAnomaly: false, label: "G06" },
 | 
			
		||||
        { id: "G07_A", type: "0", isAnomaly: true,  label: "G07" },
 | 
			
		||||
        { id: "G08_A", type: "0", isAnomaly: false, label: "G08" },
 | 
			
		||||
        { id: "G09_A", type: "0", isAnomaly: false, label: "G09" },
 | 
			
		||||
        { id: "G10_A", type: "0", isAnomaly: false, label: "G10" },
 | 
			
		||||
        { id: "G11_A", type: "0", isAnomaly: false, label: "G11" },
 | 
			
		||||
        { id: "G12_A", type: "0", isAnomaly: false, label: "G12" },
 | 
			
		||||
    
 | 
			
		||||
        { id: "G01_B", type: "1", isAnomaly: false, label: "G01" },
 | 
			
		||||
        { id: "G02_B", type: "1", isAnomaly: false, label: "G02" },
 | 
			
		||||
        { id: "G03_B", type: "1", isAnomaly: false, label: "G03" },
 | 
			
		||||
        { id: "G04_B", type: "1", isAnomaly: true,  label: "G04" },
 | 
			
		||||
        { id: "G05_B", type: "1", isAnomaly: false, label: "G05" },
 | 
			
		||||
        { id: "G06_B", type: "1", isAnomaly: false, label: "G06" },
 | 
			
		||||
        { id: "G07_B", type: "1", isAnomaly: false, label: "G07" },
 | 
			
		||||
        { id: "G08_B", type: "1", isAnomaly: true,  label: "G08" },
 | 
			
		||||
        { id: "G09_B", type: "1", isAnomaly: false, label: "G09" },
 | 
			
		||||
        { id: "G10_B", type: "1", isAnomaly: false, label: "G10" },
 | 
			
		||||
        { id: "G11_B", type: "1", isAnomaly: false, label: "G11" },
 | 
			
		||||
        { id: "G12_B", type: "1", isAnomaly: false, label: "G12" },
 | 
			
		||||
    
 | 
			
		||||
        { id: "G01_C", type: "6", isAnomaly: false, label: "G01" },
 | 
			
		||||
        { id: "G02_C", type: "6", isAnomaly: false, label: "G02" },
 | 
			
		||||
        { id: "G03_C", type: "6", isAnomaly: true,  label: "G03" },
 | 
			
		||||
        { id: "G04_C", type: "6", isAnomaly: false, label: "G04" },
 | 
			
		||||
        { id: "G05_C", type: "6", isAnomaly: false, label: "G05" },
 | 
			
		||||
        { id: "G06_C", type: "6", isAnomaly: true,  label: "G06" },
 | 
			
		||||
        { id: "G07_C", type: "6", isAnomaly: false, label: "G07" },
 | 
			
		||||
        { id: "G08_C", type: "6", isAnomaly: false, label: "G08" },
 | 
			
		||||
        { id: "G09_C", type: "6", isAnomaly: false, label: "G09" },
 | 
			
		||||
        { id: "G10_C", type: "6", isAnomaly: false, label: "G10" },
 | 
			
		||||
        { id: "G11_C", type: "6", isAnomaly: false, label: "G11" },
 | 
			
		||||
        { id: "G12_C", type: "6", isAnomaly: false, label: "G12" }
 | 
			
		||||
      ],
 | 
			
		||||
      links: [
 | 
			
		||||
        /* —— 组内:A 环 —— */
 | 
			
		||||
        { source: "G01_A", target: "G02_A", type: "0" },
 | 
			
		||||
        { source: "G02_A", target: "G03_A", type: "0" },
 | 
			
		||||
        { source: "G03_A", target: "G04_A", type: "0" },
 | 
			
		||||
        { source: "G04_A", target: "G05_A", type: "0" },
 | 
			
		||||
        { source: "G05_A", target: "G06_A", type: "0" },
 | 
			
		||||
        { source: "G06_A", target: "G07_A", type: "0" },
 | 
			
		||||
        { source: "G07_A", target: "G08_A", type: "0" },
 | 
			
		||||
        { source: "G08_A", target: "G09_A", type: "0" },
 | 
			
		||||
        { source: "G09_A", target: "G10_A", type: "0" },
 | 
			
		||||
        { source: "G10_A", target: "G11_A", type: "0" },
 | 
			
		||||
        { source: "G11_A", target: "G12_A", type: "0" },
 | 
			
		||||
        { source: "G12_A", target: "G01_A", type: "0" },
 | 
			
		||||
        /* —— A 组:异常节点额外连边(突出)—— */
 | 
			
		||||
        { source: "G02_A", target: "G05_A", type: "0" },
 | 
			
		||||
        { source: "G02_A", target: "G08_A", type: "0" },
 | 
			
		||||
        { source: "G02_A", target: "G11_A", type: "0" },
 | 
			
		||||
        { source: "G07_A", target: "G10_A", type: "0" },
 | 
			
		||||
        { source: "G07_A", target: "G01_A", type: "0" },
 | 
			
		||||
        { source: "G07_A", target: "G04_A", type: "0" },
 | 
			
		||||
    
 | 
			
		||||
        /* —— 组内:B 环 —— */
 | 
			
		||||
        { source: "G01_B", target: "G02_B", type: "1" },
 | 
			
		||||
        { source: "G02_B", target: "G03_B", type: "1" },
 | 
			
		||||
        { source: "G03_B", target: "G04_B", type: "1" },
 | 
			
		||||
        { source: "G04_B", target: "G05_B", type: "1" },
 | 
			
		||||
        { source: "G05_B", target: "G06_B", type: "1" },
 | 
			
		||||
        { source: "G06_B", target: "G07_B", type: "1" },
 | 
			
		||||
        { source: "G07_B", target: "G08_B", type: "1" },
 | 
			
		||||
        { source: "G08_B", target: "G09_B", type: "1" },
 | 
			
		||||
        { source: "G09_B", target: "G10_B", type: "1" },
 | 
			
		||||
        { source: "G10_B", target: "G11_B", type: "1" },
 | 
			
		||||
        { source: "G11_B", target: "G12_B", type: "1" },
 | 
			
		||||
        { source: "G12_B", target: "G01_B", type: "1" },
 | 
			
		||||
        /* —— B 组:异常节点额外连边 —— */
 | 
			
		||||
        { source: "G04_B", target: "G07_B", type: "1" },
 | 
			
		||||
        { source: "G04_B", target: "G10_B", type: "1" },
 | 
			
		||||
        { source: "G04_B", target: "G01_B", type: "1" },
 | 
			
		||||
        { source: "G08_B", target: "G11_B", type: "1" },
 | 
			
		||||
        { source: "G08_B", target: "G02_B", type: "1" },
 | 
			
		||||
        { source: "G08_B", target: "G05_B", type: "1" },
 | 
			
		||||
    
 | 
			
		||||
        /* —— 组内:C 环 —— */
 | 
			
		||||
        { source: "G01_C", target: "G02_C", type: "6" },
 | 
			
		||||
        { source: "G02_C", target: "G03_C", type: "6" },
 | 
			
		||||
        { source: "G03_C", target: "G04_C", type: "6" },
 | 
			
		||||
        { source: "G04_C", target: "G05_C", type: "6" },
 | 
			
		||||
        { source: "G05_C", target: "G06_C", type: "6" },
 | 
			
		||||
        { source: "G06_C", target: "G07_C", type: "6" },
 | 
			
		||||
        { source: "G07_C", target: "G08_C", type: "6" },
 | 
			
		||||
        { source: "G08_C", target: "G09_C", type: "6" },
 | 
			
		||||
        { source: "G09_C", target: "G10_C", type: "6" },
 | 
			
		||||
        { source: "G10_C", target: "G11_C", type: "6" },
 | 
			
		||||
        { source: "G11_C", target: "G12_C", type: "6" },
 | 
			
		||||
        { source: "G12_C", target: "G01_C", type: "6" },
 | 
			
		||||
        /* —— C 组:异常节点额外连边 —— */
 | 
			
		||||
        { source: "G03_C", target: "G06_C", type: "6" },
 | 
			
		||||
        { source: "G03_C", target: "G09_C", type: "6" },
 | 
			
		||||
        { source: "G03_C", target: "G12_C", type: "6" },
 | 
			
		||||
        { source: "G06_C", target: "G09_C", type: "6" },
 | 
			
		||||
        { source: "G06_C", target: "G12_C", type: "6" },
 | 
			
		||||
        { source: "G06_C", target: "G03_C", type: "6" },
 | 
			
		||||
    
 | 
			
		||||
        /* —— 跨组连边 —— */
 | 
			
		||||
        { source: "G02_A", target: "G04_B", type: "0" },
 | 
			
		||||
        { source: "G07_A", target: "G08_B", type: "0" },
 | 
			
		||||
        { source: "G01_A", target: "G05_B", type: "0" },
 | 
			
		||||
        { source: "G05_A", target: "G10_B", type: "0" },
 | 
			
		||||
    
 | 
			
		||||
        { source: "G04_B", target: "G03_C", type: "1" },
 | 
			
		||||
        { source: "G08_B", target: "G06_C", type: "1" },
 | 
			
		||||
        { source: "G02_B", target: "G09_C", type: "1" },
 | 
			
		||||
        { source: "G11_B", target: "G01_C", type: "1" },
 | 
			
		||||
    
 | 
			
		||||
        { source: "G03_C", target: "G02_A", type: "6" },
 | 
			
		||||
        { source: "G06_C", target: "G07_A", type: "6" },
 | 
			
		||||
        { source: "G04_C", target: "G09_A", type: "6" },
 | 
			
		||||
        { source: "G12_C", target: "G06_A", type: "6" }
 | 
			
		||||
      ],
 | 
			
		||||
      meta: {
 | 
			
		||||
        groups: [
 | 
			
		||||
          { id: "A", anomalies: ["G02_A", "G07_A"] },
 | 
			
		||||
          { id: "B", anomalies: ["G04_B", "G08_B"] },
 | 
			
		||||
          { id: "C", anomalies: ["G03_C", "G06_C"] }
 | 
			
		||||
        ]
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    graphAbnormalData: {
 | 
			
		||||
       groupA: ["G02_A", "G07_A"],
 | 
			
		||||
       groupB: ["G04_B", "G08_B"],
 | 
			
		||||
       groupC: ["G03_C", "G06_C"],
 | 
			
		||||
       abnormalNodesT1: ["G02_A", "G07_A"],
 | 
			
		||||
       abnormalNodesT2: ["G04_B", "G08_B"],
 | 
			
		||||
       abnormalNodesT3: ["G02_A", "G07_A", "G04_B", "G08_B", "G03_C", "G06_C"]
 | 
			
		||||
    }
 | 
			
		||||
  }),
 | 
			
		||||
  actions: {
 | 
			
		||||
    // 获取时间轴数据-中间时间轴
 | 
			
		||||
| 
						 | 
				
			
			@ -919,6 +1064,38 @@ export const useAnomalousGroup = defineStore("anomalousGroup", {
 | 
			
		|||
      if (res.code === 200) {
 | 
			
		||||
        this.abnormalContentList = res.data
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    // 用于画中间组件的圆
 | 
			
		||||
    async initialGraphByUtcTime(utcIso) {
 | 
			
		||||
      this.currentUtc = utcIso;
 | 
			
		||||
      // 1) 复制 nodes 并上色
 | 
			
		||||
      const nodes = this.graphData.nodes.map(n => {
 | 
			
		||||
        return {
 | 
			
		||||
          id: n.id,
 | 
			
		||||
          label: n.label,
 | 
			
		||||
          type: n.type, // 0=A, 1=B, 6=C(组件里 colorMap 已按这三个上色/分组)
 | 
			
		||||
          isAnomaly: n.isAnomaly
 | 
			
		||||
        };
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      this.graph["nodes"] = nodes
 | 
			
		||||
 | 
			
		||||
      const setColor = (type) => {
 | 
			
		||||
        const colorMap = {
 | 
			
		||||
          0: "50,141,120",
 | 
			
		||||
          1: "133,129,48",
 | 
			
		||||
          6: "12,112,144"
 | 
			
		||||
        }
 | 
			
		||||
        return colorMap[type]
 | 
			
		||||
      }
 | 
			
		||||
 
 | 
			
		||||
      const links = this.graphData.links.map(l => ({
 | 
			
		||||
        source: l.source,
 | 
			
		||||
        target: l.target,
 | 
			
		||||
        color: setColor(l.type), 
 | 
			
		||||
      }))
 | 
			
		||||
      this.graph["links"] = links
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  persist: true // 开启持久化
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -90,6 +90,7 @@ const handleChangeXAxis = (utcTime) => {
 | 
			
		|||
  // 根据时间轴变化更改群体结构演化分析的群体演化信息-中下-随时间轴变化
 | 
			
		||||
  anomalousGroupStore.initializeAbnormalGroupPosts(utcTime)
 | 
			
		||||
  anomalousGroupStore.initializeAbnormalGroupInteractionDetail(utcTime)
 | 
			
		||||
   anomalousGroupStore.currentUtc = utcTime; // ★ 关键:触发上面的 watcher
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//控制弹窗
 | 
			
		||||
| 
						 | 
				
			
			@ -109,6 +110,7 @@ onMounted(async () => {
 | 
			
		|||
  await anomalousGroupStore.initializeAbnormalGroupPosts()
 | 
			
		||||
  await anomalousGroupStore.initializeAbnormalGroupInteractionDetail()
 | 
			
		||||
  await anomalousGroupStore.initializeAbnormalGroupInteractionChart()
 | 
			
		||||
  await anomalousGroupStore.initialGraphByUtcTime("2024-06-19T07:57:46Z")
 | 
			
		||||
 | 
			
		||||
})
 | 
			
		||||
</script>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,6 +23,7 @@ import { convertToUtcIsoString } from "@/utils/transform"
 | 
			
		|||
import { paintNodeFunction, paintLineFunction } from "@/utils/customePaint"
 | 
			
		||||
import TimeAxis from "@/components/timeAxis.vue"
 | 
			
		||||
import GraphVis from "@/assets/package/graphvis.esm.min.js"
 | 
			
		||||
 | 
			
		||||
const props = defineProps({
 | 
			
		||||
  store: {
 | 
			
		||||
    required: true
 | 
			
		||||
| 
						 | 
				
			
			@ -155,7 +156,7 @@ const clusterAnalyze = () => {
 | 
			
		|||
    }
 | 
			
		||||
    clusterNodesMap.get(cluster).push(node)
 | 
			
		||||
  })
 | 
			
		||||
  const colorMap = {
 | 
			
		||||
  let colorMap = {
 | 
			
		||||
    0: "50,141,120", // 绿色
 | 
			
		||||
    1: "133,129,48", // 黄色
 | 
			
		||||
    6: "12,112,144" // 蓝色
 | 
			
		||||
| 
						 | 
				
			
			@ -189,6 +190,72 @@ const clusterAnalyze = () => {
 | 
			
		|||
 | 
			
		||||
  function handleAnomalousGroup() {
 | 
			
		||||
    console.log(storeId)
 | 
			
		||||
 | 
			
		||||
    // 当前时间从 store 取;没有就用 T0
 | 
			
		||||
    const now = (props.store.currentUtc);
 | 
			
		||||
 | 
			
		||||
    const TA = "2024-06-19T08:57:55Z"; // A
 | 
			
		||||
    const TB = "2024-06-19T10:58:03Z"; // B
 | 
			
		||||
    const TC = "2024-06-19T12:58:04Z"; // C
 | 
			
		||||
 | 
			
		||||
    // 组色(与你现有 colorMap 一致)
 | 
			
		||||
    const GROUP_COLOR = { 0: "12,112,144", 1: "180,150,20", 6: "50,141,120" };
 | 
			
		||||
    const GROUP_ALPHA = 0.30;
 | 
			
		||||
 | 
			
		||||
    const RED = "220,50,60";
 | 
			
		||||
 | 
			
		||||
    // 覆盖画三大组大圆(蓝/黄/绿透明)
 | 
			
		||||
/*     const buckets = new Map();
 | 
			
		||||
    graphVis.nodes.forEach(n => {
 | 
			
		||||
      const t = parseInt(n.type);           // "0"|"1"|"6" → 0/1/6
 | 
			
		||||
      if (!buckets.has(t)) buckets.set(t, []);
 | 
			
		||||
      buckets.get(t).push(n);
 | 
			
		||||
    });
 | 
			
		||||
    buckets.forEach((nodes, t) => {
 | 
			
		||||
      const color = GROUP_COLOR[t] || "120,120,120";
 | 
			
		||||
      const g = graphVis.addNodesInGroup(nodes, { shape: "circle", color, alpha: GROUP_ALPHA });
 | 
			
		||||
      g.smoothPath = false;
 | 
			
		||||
    }); */
 | 
			
		||||
 | 
			
		||||
    // 时间门控:达到阈值就把各组异常节点染红 + 加红圈
 | 
			
		||||
    const shouldA = now >= TA;
 | 
			
		||||
    const shouldB = now >= TB;
 | 
			
		||||
    const shouldC = now >= TC;
 | 
			
		||||
 | 
			
		||||
    if(shouldA) {
 | 
			
		||||
      console.log("A异常")
 | 
			
		||||
 | 
			
		||||
      graphVis.nodes = graphVis.nodes.map(n => {
 | 
			
		||||
        if(props.store.graphAbnormalData.groupA.includes(n.id)) {
 | 
			
		||||
          n.fillColor = RED;
 | 
			
		||||
        }
 | 
			
		||||
        return n;
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
    if(shouldB) {
 | 
			
		||||
      console.log("B异常")
 | 
			
		||||
      graphVis.nodes = graphVis.nodes.map(n => {
 | 
			
		||||
        if(props.store.graphAbnormalData.groupB.includes(n.id)) {
 | 
			
		||||
          n.fillColor = RED;
 | 
			
		||||
        }
 | 
			
		||||
        return n;
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
    if(shouldC) {
 | 
			
		||||
      console.log("C异常")
 | 
			
		||||
 | 
			
		||||
      graphVis.nodes = graphVis.nodes.map(n => {
 | 
			
		||||
        if(props.store.graphAbnormalData.groupC.includes(n.id)) {
 | 
			
		||||
          n.fillColor = RED;
 | 
			
		||||
        }
 | 
			
		||||
        return n;
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    graphVis.autoGroupLayout(graphVis.nodes);
 | 
			
		||||
    graphVis.zoomFit(); // 没有 refresh;这两个就够
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  new Map([
 | 
			
		||||
| 
						 | 
				
			
			@ -200,6 +267,20 @@ const clusterAnalyze = () => {
 | 
			
		|||
  // graphVis.selectedEdge(graphVis.links[0])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 仅对“异常群体模块”生效:时间变化时强制重绘一次
 | 
			
		||||
if (storeId === 'anomalousGroup') {
 | 
			
		||||
  watch(
 | 
			
		||||
    () => props.store.currentUtc,
 | 
			
		||||
    () => {
 | 
			
		||||
      // 不改 graph 数据结构,直接用当前 graph 强制走一遍:addGraph → clusterAnalyze → runForceLayout
 | 
			
		||||
      if (graphVis) {
 | 
			
		||||
        updateChart(toRaw(graph.value));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 实例化 GraphVis、注册自定义绘制/事件
 | 
			
		||||
const createGraph = () => {
 | 
			
		||||
  if (!graphVis) {
 | 
			
		||||
    graphVis = new GraphVis({
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user