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

This commit is contained in:
2025-07-15 22:01:09 +07:00
parent a104cc7a3f
commit bbf143dee7
2 changed files with 31 additions and 60 deletions
+28 -56
View File
@@ -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"
+3 -4
View File
@@ -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>