import React, { useState, useEffect, useRef } from "react"; import { ArrowDownTrayIcon, ArrowUpTrayIcon } from "@heroicons/react/24/outline"; import * as d3 from "d3"; export default function NetworkMonitor(args) { const [selectedTab, setSelectedTab] = useState("interfaces"); const [SelectedNode, setSelectedNode] = useState({}); const tabs = [ { id: "interfaces", label: "Интерфейсы" }, { id: "topology", label: "Топология сети" }, ]; const handleTabClick = (tabId) => { setSelectedTab(tabId); }; const NetworkDiagram = () => { const svgRef = useRef(null); useEffect(() => { const width = 600; const height = 700; const nodes = [ { id: "192.168.2.55", color: "green", shape: "circle" }, // pc { id: "192.168.2.1", color: "red", shape: "polygon" }, // router { id: "192.168.2.40", color: "gray", shape: "circle" }, // existing pc { id: "192.168.2.41", color: "gray", shape: "circle" }, { id: "192.168.2.42", color: "green", shape: "circle" }, { id: "192.168.2.43", color: "green", shape: "circle" }, { id: "192.168.2.44", color: "green", shape: "circle" }, { id: "192.168.2.45", color: "green", shape: "circle" }, { id: "192.168.2.46", color: "green", shape: "circle" }, { id: "192.168.2.47", color: "green", shape: "circle" }, { id: "192.168.2.48", color: "green", shape: "circle" } ]; const links = [ { source: "192.168.2.55", target: "192.168.2.1" }, { source: "192.168.2.1", target: "192.168.2.40" }, { source: "192.168.2.1", target: "192.168.2.41" }, { source: "192.168.2.1", target: "192.168.2.42" }, { source: "192.168.2.1", target: "192.168.2.43" }, { source: "192.168.2.1", target: "192.168.2.44" }, { source: "192.168.2.1", target: "192.168.2.45" }, { source: "192.168.2.1", target: "192.168.2.46" }, { source: "192.168.2.1", target: "192.168.2.47" }, { source: "192.168.2.1", target: "192.168.2.48" } ]; // Set initial positions for circular layout const centralNodeId = "192.168.2.1"; const radius = 225; // Matches the link distance const centerX = width / 2; const centerY = height / 2; // Find nodes connected to the central node const connectedNodes = links .filter(link => link.source === centralNodeId || link.target === centralNodeId) .map(link => link.source === centralNodeId ? link.target : link.source); // Set central node position nodes.forEach(node => { if (node.id === centralNodeId) { node.x = centerX; node.y = centerY; } }); // Set connected nodes in a circle around the central node connectedNodes.forEach((nodeId, index) => { const angle = (2 * Math.PI * index) / connectedNodes.length; const node = nodes.find(n => n.id === nodeId); if (node) { node.x = centerX + radius * Math.cos(angle); node.y = centerY + radius * Math.sin(angle); } }); const svg = d3.select(svgRef.current) .attr("width", "100%") .attr("height", height) .attr("viewBox", [0, 0, width, height]); // Adding shadow filter const defs = svg.append("defs"); const filter = defs.append("filter") .attr("id", "shadow") .attr("height", "150%") .attr("width", "150%"); filter.append("feGaussianBlur") .attr("in", "SourceAlpha") .attr("stdDeviation", 3) .attr("result", "blur"); filter.append("feOffset") .attr("in", "blur") .attr("dx", 3) .attr("dy", 3) .attr("result", "offsetBlur"); const feComponentTransfer = filter.append("feComponentTransfer"); nodes.forEach(node => { feComponentTransfer.append("feFuncR") .attr("type", "linear") .attr("slope", node.color === "red" ? 1 : 0); feComponentTransfer.append("feFuncG") .attr("type", "linear") .attr("slope", node.color === "green" ? 1 : 0); feComponentTransfer.append("feFuncB") .attr("type", "linear") .attr("slope", node.color === "gray" ? 0.5 : 0); }); const feMerge = filter.append("feMerge"); feMerge.append("feMergeNode").attr("in", "offsetBlur"); feMerge.append("feMergeNode").attr("in", "SourceGraphic"); const simulation = d3.forceSimulation(nodes) .force("link", d3.forceLink(links).id(d => d.id).distance(200)) .force("charge", d3.forceManyBody().strength(-200)) .force("center", d3.forceCenter(width / 2, height / 2)); const link = svg.append("g") .selectAll(".link") .data(links) .enter() .append("line") .attr("class", "topology_link"); const node = svg.append("g") .selectAll(".node") .data(nodes) .enter() .append("g") .attr("class", "topology_node") .call(d3.drag() .on("start", dragStart) .on("drag", dragged) .on("end", dragEnd)) .on("click", (event, d) => { console.log("Clicked node:", d); }); node.each(function (d) { const group = d3.select(this); group.append("circle") .attr("r", 25) .attr("fill", "none") .attr("class", "topology_circle_" + d.color); if (d.shape === "polygon") { group.append("polygon") .attr("points", () => { const radius = 22; const points = []; for (let i = 0; i < 6; i++) { const angle = (Math.PI * 2 * i) / 6; const x = radius * Math.cos(angle); const y = radius * Math.sin(angle); points.push(`${x},${y}`); } return points.join(" "); }) .attr("fill", "#202020"); } else { group.append("polygon") .attr("points", () => { const radius = 22; const points = []; for (let i = 0; i < 4; i++) { const angle = (Math.PI * 2 * i) / 4 + Math.PI / 4; const x = radius * Math.cos(angle); const y = radius * Math.sin(angle); points.push(`${x},${y}`); } return points.join(" "); }) .attr("fill", "#202020") .attr("class", "square"); } }); node.append("text") .attr("class", "topology_label") .attr("dy", -35) .text(d => d.id); simulation.on("tick", () => { link .attr("x1", d => d.source.x) .attr("y1", d => d.source.y) .attr("x2", d => d.target.x) .attr("y2", d => d.target.y); node .attr("transform", d => `translate(${d.x},${d.y})`); }); // Drag functions function dragStart(event, d) { if (!event.active) simulation.alphaTarget(0.3).restart(); d.fx = d.x; d.fy = d.y; } function dragged(event, d) { d.fx = event.x; d.fy = event.y; } function dragEnd(event, d) { if (!event.active) simulation.alphaTarget(0); d.fx = null; d.fy = null; } }, []); return ( ); }; const [NetIfaces, setNetIfaces] = useState( [ { name: "Ethernet 6", wireless: false, mac: "FF-FF-FF-FF-FF-FF", ip: "192.168.2.5", mask: "255.255.255.0", mtu: 1500, speed_mbit: 2500, status: true, trafic_down_mb: 100, trafic_up_mb: 1000, }, { name: "Wireles Adapter 1", wireless: true, mac: "F1-FF-0F-FF-1F-F0", ip: "192.168.1.5", mask: "255.255.255.0", mtu: 1500, speed_mbit: 0, status: false, trafic_down_mb: 35, trafic_up_mb: 2, } ] ); return ( <>