refactor: Simplify GraphView component by removing state management and implementing grid-based node positioning for improved layout
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 6m18s
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 6m18s
This commit is contained in:
+28
-56
@@ -1,44 +1,6 @@
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import React from 'react';
|
||||
|
||||
function GraphView({ servers, connections }) {
|
||||
const [positions, setPositions] = useState({});
|
||||
const [dimensions, setDimensions] = useState({ width: 800, height: 500 });
|
||||
const svgRef = useRef(null);
|
||||
|
||||
// Вычисляем позиции узлов
|
||||
useEffect(() => {
|
||||
if (servers.length === 0) return;
|
||||
|
||||
const newPositions = {};
|
||||
const centerX = dimensions.width / 2;
|
||||
const centerY = dimensions.height / 2;
|
||||
const radius = Math.min(dimensions.width, dimensions.height) * 0.3;
|
||||
|
||||
servers.forEach((server, index) => {
|
||||
const angle = (index / servers.length) * 2 * Math.PI;
|
||||
newPositions[server.ip] = {
|
||||
x: centerX + radius * Math.cos(angle),
|
||||
y: centerY + radius * Math.sin(angle)
|
||||
};
|
||||
});
|
||||
|
||||
setPositions(newPositions);
|
||||
}, [servers, dimensions]);
|
||||
|
||||
// Обработчик изменения размера
|
||||
useEffect(() => {
|
||||
const handleResize = () => {
|
||||
if (svgRef.current) {
|
||||
const rect = svgRef.current.getBoundingClientRect();
|
||||
setDimensions({ width: rect.width, height: 500 });
|
||||
}
|
||||
};
|
||||
|
||||
handleResize();
|
||||
window.addEventListener('resize', handleResize);
|
||||
return () => window.removeEventListener('resize', handleResize);
|
||||
}, []);
|
||||
|
||||
if (servers.length === 0) {
|
||||
return (
|
||||
<div className="text-center py-5">
|
||||
@@ -50,21 +12,32 @@ function GraphView({ servers, connections }) {
|
||||
);
|
||||
}
|
||||
|
||||
// Простое позиционирование узлов в сетке
|
||||
const getNodePosition = (index, total) => {
|
||||
const cols = Math.ceil(Math.sqrt(total));
|
||||
const row = Math.floor(index / cols);
|
||||
const col = index % cols;
|
||||
const spacing = 150;
|
||||
return {
|
||||
x: 100 + col * spacing,
|
||||
y: 100 + row * spacing
|
||||
};
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ width: '100%', height: '500px', border: '1px solid #e5e7eb', borderRadius: '8px', overflow: 'hidden' }}>
|
||||
<svg
|
||||
ref={svgRef}
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox={`0 0 ${dimensions.width} ${dimensions.height}`}
|
||||
style={{ background: '#f8fafc' }}
|
||||
>
|
||||
<div style={{ width: '100%', height: '500px', border: '1px solid #e5e7eb', borderRadius: '8px', overflow: 'hidden', background: '#f8fafc' }}>
|
||||
<svg width="100%" height="100%" viewBox="0 0 800 500">
|
||||
{/* Связи */}
|
||||
{connections.map((connection, index) => {
|
||||
const fromPos = positions[connection.from];
|
||||
const toPos = positions[connection.to];
|
||||
const fromServer = servers.find(s => s.ip === connection.from);
|
||||
const toServer = servers.find(s => s.ip === connection.to);
|
||||
|
||||
if (!fromPos || !toPos) return null;
|
||||
if (!fromServer || !toServer) return null;
|
||||
|
||||
const fromIndex = servers.indexOf(fromServer);
|
||||
const toIndex = servers.indexOf(toServer);
|
||||
const fromPos = getNodePosition(fromIndex, servers.length);
|
||||
const toPos = getNodePosition(toIndex, servers.length);
|
||||
|
||||
return (
|
||||
<g key={`link-${index}`}>
|
||||
@@ -104,9 +77,8 @@ function GraphView({ servers, connections }) {
|
||||
})}
|
||||
|
||||
{/* Узлы (серверы) */}
|
||||
{servers.map(server => {
|
||||
const pos = positions[server.ip];
|
||||
if (!pos) return null;
|
||||
{servers.map((server, index) => {
|
||||
const pos = getNodePosition(index, servers.length);
|
||||
|
||||
return (
|
||||
<g key={server.ip}>
|
||||
@@ -114,7 +86,7 @@ function GraphView({ servers, connections }) {
|
||||
<circle
|
||||
cx={pos.x}
|
||||
cy={pos.y}
|
||||
r="25"
|
||||
r="30"
|
||||
fill="#3b82f6"
|
||||
stroke="#1e40af"
|
||||
strokeWidth="2"
|
||||
@@ -123,7 +95,7 @@ function GraphView({ servers, connections }) {
|
||||
{/* DNS имя */}
|
||||
<text
|
||||
x={pos.x}
|
||||
y={pos.y - 5}
|
||||
y={pos.y - 8}
|
||||
textAnchor="middle"
|
||||
fontSize="11"
|
||||
fill="white"
|
||||
@@ -135,7 +107,7 @@ function GraphView({ servers, connections }) {
|
||||
{/* IP адрес */}
|
||||
<text
|
||||
x={pos.x}
|
||||
y={pos.y + 10}
|
||||
y={pos.y + 8}
|
||||
textAnchor="middle"
|
||||
fontSize="10"
|
||||
fill="white"
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
IconChevronDown,
|
||||
IconLink
|
||||
} from '@tabler/icons-react';
|
||||
// import GraphView from './GraphView';
|
||||
import GraphView from './GraphView';
|
||||
|
||||
const API_URL = '/api';
|
||||
|
||||
@@ -668,15 +668,14 @@ function ServerManager() {
|
||||
error={error}
|
||||
/>
|
||||
|
||||
{/* Временно отключаем граф для отладки */}
|
||||
{/* <div className="card w-100 mb-4">
|
||||
<div className="card w-100 mb-4">
|
||||
<div className="card-header">
|
||||
<h3 className="card-title mb-0">Граф связей между серверами</h3>
|
||||
</div>
|
||||
<div className="card-body">
|
||||
<GraphView servers={servers} connections={connections} />
|
||||
</div>
|
||||
</div> */}
|
||||
</div>
|
||||
<div className="card w-100 mb-4">
|
||||
<div className="card-header">
|
||||
<h3 className="card-title mb-0">Добавить связь между серверами</h3>
|
||||
|
||||
Reference in New Issue
Block a user