From 90d6565a5a54be3ff871d9076e2f764996256625 Mon Sep 17 00:00:00 2001 From: DmitriyA Date: Wed, 5 Mar 2025 12:55:50 -0500 Subject: [PATCH] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B8=D0=BB=20?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D1=8E,=20=D1=83=D0=BB=D1=83=D1=87=D1=88?= =?UTF-8?q?=D0=B8=D0=BB=20=D0=BD=D0=B0=D0=BF=D0=BE=D0=BB=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=B2=D0=BA=D0=BB=D0=B0=D0=B4=D0=BE=D0=BA,=20?= =?UTF-8?q?=D1=83=D0=BB=D1=83=D1=87=D1=88=D0=B8=D0=BB=20=D0=B3=D1=80=D0=B0?= =?UTF-8?q?=D1=84=D0=B8=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 3 +- src/App.css | 30 ++ src/Charts/Components/LineChartComponent.jsx | 32 +- src/Charts/PrometheusChart.jsx | 267 ++++++++---- src/Charts/PrometheusChart2.jsx | 83 ---- src/Charts/TestCharts2.jsx | 95 ----- src/Components/Layout/Dashboard.jsx | 17 +- src/Components/TreeChart/TreeChart.jsx | 118 +++--- src/Components/TreeChart/dataUtils.jsx | 2 +- src/Components/TreeChart/menuData.json | 416 ++++++++++++++++++- src/Components/TreeChart/menuData2.json | 382 +++++++++++++++++ src/Components/TreeChart/menuData3.json | 117 ------ src/Components/TreeChart/tabContent.jsx | 164 ++++---- src/Components/TreeChart/tabContent2.jsx | 96 +++++ src/Components/TreeChart/tabContent3.jsx | 31 -- src/Components/UI/Tabs.jsx | 1 + src/Components/UI/TreeTable.jsx | 2 +- src/Style/Dashboard.css | 6 +- src/Style/DatePicker.css | 60 +++ src/index.css | 24 ++ 20 files changed, 1363 insertions(+), 583 deletions(-) delete mode 100644 src/Charts/PrometheusChart2.jsx delete mode 100644 src/Charts/TestCharts2.jsx create mode 100644 src/Components/TreeChart/menuData2.json delete mode 100644 src/Components/TreeChart/menuData3.json create mode 100644 src/Components/TreeChart/tabContent2.jsx delete mode 100644 src/Components/TreeChart/tabContent3.jsx create mode 100644 src/Style/DatePicker.css diff --git a/package.json b/package.json index 3ab7c61..9d0c2c7 100755 --- a/package.json +++ b/package.json @@ -18,7 +18,8 @@ "chart.js": "^4.0.0", "chartjs-chart-box-and-violin-plot": "^4.0.0", "react-chartjs-2": "^5.0.0", - "axios": "^1.7.9" + "axios": "^1.7.9", + "react-datepicker": "^8.1.0" }, "devDependencies": { "@eslint/js": "^9.17.0", diff --git a/src/App.css b/src/App.css index 9c7629a..40842f6 100755 --- a/src/App.css +++ b/src/App.css @@ -42,4 +42,34 @@ .read-the-docs { color: #888; +} + +/* Глобальный стиль для WebKit-браузеров (Chrome, Edge, Safari) */ +::-webkit-scrollbar { + width: 10px; /* Толщина вертикального скролла */ + height: 10px; /* Толщина горизонтального скролла */ +} + +/* Фон скроллбара */ +::-webkit-scrollbar-track { + background: #f1f1f1; /* Цвет фона */ + border-radius: 10px; /* Скругление углов */ +} + +/* Ползунок */ +::-webkit-scrollbar-thumb { + background: #3d74c7; /* Основной цвет */ + border-radius: 10px; /* Скругляем края */ + border: 2px solid #f1f1f1; /* Белая обводка */ +} + +/* Эффект при наведении */ +::-webkit-scrollbar-thumb:hover { + background: #2b5aa5; /* Чуть темнее при наведении */ +} + +/* Глобальный стиль для Firefox */ +* { + scrollbar-width: thin; /* Делаем тонким */ + scrollbar-color: #3d74c7 #f1f1f1; /* Ползунок + фон */ } \ No newline at end of file diff --git a/src/Charts/Components/LineChartComponent.jsx b/src/Charts/Components/LineChartComponent.jsx index 1ded03c..23ae6da 100644 --- a/src/Charts/Components/LineChartComponent.jsx +++ b/src/Charts/Components/LineChartComponent.jsx @@ -1,7 +1,7 @@ import React from 'react'; -import { LineChart, XAxis, YAxis, CartesianGrid, Tooltip, Legend, Line, ResponsiveContainer } from 'recharts'; +import { LineChart, XAxis, YAxis, CartesianGrid, Tooltip, Legend, Line, ResponsiveContainer, Brush } from 'recharts'; -const LineChartComponent = ({ chartData, metricName, metricType, colors }) => { +const LineChartComponent = ({ chartData, metricName, metricType, colors, description, isLongRange }) => { // Создаем массив уникальных временных меток const allTimes = Object.values(chartData) .flat() @@ -20,25 +20,47 @@ const LineChartComponent = ({ chartData, metricName, metricType, colors }) => { console.log('Processed Data:', data); // Логируем данные для графика + // Кастомный Tooltip для отображения значения + const CustomTooltip = ({ active, payload, label }) => { + if (active && payload && payload.length) { + return ( +
+

{`${payload[0].value}`}

+
+ ); + } + + return null; + }; + return (
-

{metricName} ({metricType})

+

{description}

- + } /> {Object.keys(chartData).map((key, index) => ( ))} + {isLongRange && ( // Добавляем Brush только для длительных периодов + + )}
diff --git a/src/Charts/PrometheusChart.jsx b/src/Charts/PrometheusChart.jsx index ddfe219..a5fc8e5 100644 --- a/src/Charts/PrometheusChart.jsx +++ b/src/Charts/PrometheusChart.jsx @@ -1,95 +1,204 @@ -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useState, useRef } from 'react'; import axios from 'axios'; import LineChartComponent from './Components/LineChartComponent'; import BarChartComponent from './Components/BarChartComponent'; import ScatterChartComponent from './Components/ScatterChartComponent'; +import DatePicker from 'react-datepicker'; +import '../Style/DatePicker.css'; const MAX_POINTS = 20; // Ограничение точек на графике const COLORS = ['#3e95cd', '#8e5ea2', '#3cba9f', '#e8c3b9', '#c45850']; // Фиксированные цвета для линий +// Компонент для выбора временного диапазона +const TimeRangeSelector = ({ onRangeChange }) => { + return ( +
+ + + +
+ ); +}; + +// Компонент для выбора произвольного диапазона дат +const DateRangeSelector = ({ onDateChange }) => { + const [startDate, setStartDate] = useState(new Date()); + const [endDate, setEndDate] = useState(new Date()); + + const handleDateChange = (dates) => { + const [start, end] = dates; + setStartDate(start); + setEndDate(end); + onDateChange({ start, end }); + }; + + return ( +
+ +
+ ); +}; + const PrometheusChart = ({ metricName }) => { const [chartData, setChartData] = useState({}); const [metricType, setMetricType] = useState(''); + const [metricDescription, setMetricDescription] = useState(''); + const [timeRange, setTimeRange] = useState('24h'); // По умолчанию выбран диапазон "24 часа" + const [customRange, setCustomRange] = useState({ start: null, end: null }); + const intervalRef = useRef(null); + + const isLongRange = (range) => { + return range === '2w' || range === 'custom'; // "2w" — две недели, "custom" — кастомный диапазон + }; + + const fetchData = async (range, customStart, customEnd) => { + try { + const end = customEnd ? Math.floor(customEnd.getTime() / 1000) : Math.floor(Date.now() / 1000); + let start; + + if (customStart) { + start = Math.floor(customStart.getTime() / 1000); + } else { + switch (range) { + case '1h': + start = end - 60 * 60; // 1 час назад + break; + case '24h': + start = end - 24 * 60 * 60; // 24 часа назад + break; + case '2w': + start = end - 14 * 24 * 60 * 60; // 2 недели назад + break; + default: + start = end - 24 * 60 * 60; // По умолчанию 24 часа + } + } + + const step = range === '2w' ? 3600 : 60; // Для двух недель увеличиваем шаг до 1 часа + + const response = await axios.get(`http://192.168.2.39:3000/metrics`, { + params: { + metric: metricName, + start, + end, + step, + }, + }); + + const result = response.data; + + // Проверяем структуру данных + let metrics; + if (Array.isArray(result)) { + metrics = result; + } else if (result.data && Array.isArray(result.data)) { + metrics = result.data; + } else { + throw new Error('Invalid data format'); + } + + if (!Array.isArray(metrics) || metrics.length === 0) { + throw new Error('No metrics data available'); + } + + const type = metrics[0].type; + setMetricType(type); + + // Устанавливаем описание метрики + setMetricDescription(metrics[0].description); + + // Очищаем предыдущие данные + setChartData({}); + + if (type === 'summary') { + // Обработка данных для summary + const newData = metrics.map(m => ({ + instance: m.instance, + quantile: m.quantile, + value: m.value + })); + + // Группируем данные по instance + const groupedData = newData.reduce((acc, point) => { + if (!acc[point.instance]) { + acc[point.instance] = []; + } + acc[point.instance].push(point); + return acc; + }, {}); + + setChartData(groupedData); + } else { + // Обработка данных для counter, gauge, unknown + const newDataPoints = metrics.map(m => ({ + time: new Date(m.timestamp).toLocaleTimeString(), + value: m.value, + instance: m.instance, + device: m.device || m.scrape_job, // Используем device или scrape_job + })); + + // Группируем данные по instance и device/scrape_job + const updatedData = {}; + + newDataPoints.forEach(point => { + const key = `${point.instance}-${point.device}`; // Уникальный ключ + if (!updatedData[key]) { + updatedData[key] = []; + } + updatedData[key].push({ + time: point.time, + value: point.value, + }); + + // Ограничиваем количество точек до MAX_POINTS + if (updatedData[key].length > MAX_POINTS) { + updatedData[key] = updatedData[key].slice(-MAX_POINTS); // Оставляем последние MAX_POINTS точек + } + }); + + setChartData(updatedData); + } + } catch (error) { + console.error('Error fetching metrics:', error); + } + }; useEffect(() => { - const fetchData = async () => { - try { - const response = await axios.get(`http://192.168.2.39:3000/metrics?metric=zvks_apiforsnmp_cpurawsystem`); - const result = response.data; + fetchData(timeRange, customRange.start, customRange.end); // Первоначальная загрузка данных - // Проверяем структуру данных - let metrics; - if (Array.isArray(result)) { - // Если данные пришли в виде массива - metrics = result; - } else if (result.data && Array.isArray(result.data)) { - // Если данные пришли в виде объекта с ключом data - metrics = result.data; - } else { - throw new Error('Invalid data format'); - } + if (!isLongRange(timeRange)) { // Обновляем только для коротких диапазонов + intervalRef.current = setInterval(() => { + fetchData(timeRange, customRange.start, customRange.end); + }, 5000); // Обновляем каждые 5 секунд + } - if (!Array.isArray(metrics) || metrics.length === 0) { - throw new Error('No metrics data available'); - } - - const type = metrics[0].type; - setMetricType(type); - - if (type === 'summary') { - // Обработка данных для summary - const newData = metrics.map(m => ({ - instance: m.instance, - quantile: m.quantile, - value: m.value - })); - - // Группируем данные по instance - const groupedData = newData.reduce((acc, point) => { - if (!acc[point.instance]) { - acc[point.instance] = []; - } - acc[point.instance].push(point); - return acc; - }, {}); - - setChartData(groupedData); - } else { - // Обработка данных для counter, gauge, unknown - const newDataPoints = metrics.map(m => ({ - time: new Date(m.timestamp).toLocaleTimeString(), - value: m.value, - instance: m.instance, - device: m.device || m.scrape_job, // Используем device или scrape_job - })); - - // Группируем данные по instance и device/scrape_job - setChartData(prevData => { - const updatedData = { ...prevData }; - - newDataPoints.forEach(point => { - const key = `${point.instance}-${point.device}`; // Уникальный ключ - if (!updatedData[key]) { - updatedData[key] = []; - } - updatedData[key].push({ - time: point.time, - value: point.value, - }); - }); - - return updatedData; - }); - } - } catch (error) { - console.error('Error fetching metrics:', error); + return () => { + if (intervalRef.current) { + clearInterval(intervalRef.current); // Очищаем интервал при размонтировании } }; + }, [metricName, timeRange, customRange]); - fetchData(); // Вызываем сразу при монтировании - const interval = setInterval(fetchData, 5000); // Обновляем каждые 5 секунд - return () => clearInterval(interval); // Очищаем интервал при размонтировании - }, [metricName]); + const handleRangeChange = (range) => { + setTimeRange(range); + setCustomRange({ start: null, end: null }); + + if (!isLongRange(range)) { + clearInterval(intervalRef.current); // Останавливаем обновление + } + }; + + const handleDateChange = ({ start, end }) => { + setCustomRange({ start, end }); + setTimeRange('custom'); // Устанавливаем кастомный диапазон + }; if (!Object.keys(chartData).length) return

Loading...

; @@ -103,6 +212,8 @@ const PrometheusChart = ({ metricName }) => { metricName={metricName} metricType={metricType} colors={COLORS} + description={metricDescription} + isLongRange={isLongRange(timeRange)} // Передаем флаг /> ); case 'summary': @@ -128,7 +239,13 @@ const PrometheusChart = ({ metricName }) => { } }; - return renderChart(); + return ( +
+ + + {renderChart()} +
+ ); }; export default PrometheusChart; \ No newline at end of file diff --git a/src/Charts/PrometheusChart2.jsx b/src/Charts/PrometheusChart2.jsx deleted file mode 100644 index eb1046a..0000000 --- a/src/Charts/PrometheusChart2.jsx +++ /dev/null @@ -1,83 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import axios from 'axios'; -import { LineChart, XAxis, YAxis, CartesianGrid, Tooltip, Legend, Line, ResponsiveContainer } from 'recharts'; - -const MAX_POINTS = 20; // Ограничение точек на графике -const COLORS = ['#3e95cd', '#8e5ea2', '#3cba9f', '#e8c3b9', '#c45850']; // Фиксированные цвета для линий - -const PrometheusChart2 = ({ metricName }) => { - const [chartData, setChartData] = useState({}); - const [metricType, setMetricType] = useState(''); - - useEffect(() => { - const fetchData = async () => { - try { - const response = await axios.get(`http://192.168.2.33:3000/metrics?metric=node_network_iface_link`); - const metrics = response.data; - if (!Array.isArray(metrics) || metrics.length === 0) { - throw new Error('No metrics data available'); - } - - const type = metrics[0].type; - setMetricType(type); - - // Обработка данных для counter, gauge, unknown - const newDataPoints = metrics.map(m => ({ - time: new Date(m.timestamp).toLocaleTimeString(), - value: m.value, - instance: m.instance // Добавляем идентификатор инстанса - })); - - // Обновляем данные для каждого инстанса - setChartData(prevData => { - const updatedData = { ...prevData }; - - newDataPoints.forEach(point => { - if (!updatedData[point.instance]) { - updatedData[point.instance] = []; - } - // Добавляем новую точку и ограничиваем количество точек - updatedData[point.instance] = [...updatedData[point.instance], point].slice(-MAX_POINTS); - }); - - return updatedData; - }); - } catch (error) { - console.error('Error fetching metrics:', error); - } - }; - - fetchData(); // Вызываем сразу при монтировании - const interval = setInterval(fetchData, 5000); // Обновляем каждые 5 секунд - return () => clearInterval(interval); // Очищаем интервал при размонтировании - }, [metricName]); - - if (!Object.keys(chartData).length) return

Loading...

; - - return ( -
-

{metricName} ({metricType})

- - - - - - - - {Object.keys(chartData).map((instance, index) => ( - - ))} - - -
- ); -}; - -export default PrometheusChart2; \ No newline at end of file diff --git a/src/Charts/TestCharts2.jsx b/src/Charts/TestCharts2.jsx deleted file mode 100644 index 931e22b..0000000 --- a/src/Charts/TestCharts2.jsx +++ /dev/null @@ -1,95 +0,0 @@ -import React, { useEffect, useState, useRef } from 'react'; -import axios from 'axios'; -import { Line } from 'react-chartjs-2'; -import { - Chart as ChartJS, - CategoryScale, - LinearScale, - PointElement, - LineElement, - Title, - Tooltip, - Legend, - TimeScale, -} from 'chart.js'; -import 'chartjs-adapter-date-fns'; - -ChartJS.register( - CategoryScale, - LinearScale, - PointElement, - LineElement, - Title, - Tooltip, - Legend, - TimeScale -); - -const MAX_DATA_POINTS = 50; - -const NetworkSpeedChart2 = () => { - const [chartData, setChartData] = useState({ labels: [], datasets: [] }); - - const fetchData = async () => { - try { - const response = await axios.get('http://192.168.2.33:3000/metrics?metric=node_time_seconds'); - const newData = response.data; - - setChartData((prevChartData) => { - const newGroupedData = newData.reduce((acc, entry) => { - if (!acc[entry.device]) acc[entry.device] = []; - acc[entry.device].push({ x: new Date(entry.timestamp), y: entry.value }); - return acc; - }, {}); - - const newDatasets = Object.keys(newGroupedData).map((device, index) => { - const existingDataset = prevChartData.datasets.find((d) => d.label === `Device: ${device}`); - const updatedData = existingDataset ? [...existingDataset.data, ...newGroupedData[device]] : newGroupedData[device]; - - return { - label: `Device: ${device}`, - data: updatedData.slice(-MAX_DATA_POINTS), - borderColor: `hsl(${(index * 360) / Object.keys(newGroupedData).length}, 70%, 50%)`, - backgroundColor: `hsla(${(index * 360) / Object.keys(newGroupedData).length}, 70%, 50%, 0.2)`, - tension: 0.2, - }; - }); - - return { labels: newDatasets[0]?.data.map((d) => d.x) || [], datasets: newDatasets }; - }); - } catch (error) { - console.error('Ошибка при загрузке метрик:', error); - } - }; - - useEffect(() => { - fetchData(); - const interval = setInterval(fetchData, 5000); - return () => clearInterval(interval); - }, []); - - const options = { - responsive: true, - plugins: { - legend: { position: 'top' }, - title: { display: true, text: 'node_time_seconds' }, - }, - scales: { - x: { - type: 'time', - time: { unit: 'second', displayFormats: { second: 'HH:mm:ss' } }, - title: { display: true, text: 'Time' }, - }, - y: { title: { display: true, text: 'Value' } }, - }, - animation: { duration: 1000, easing: 'linear' }, - }; - - return ( -
- -
- ); -}; - -export default NetworkSpeedChart2; diff --git a/src/Components/Layout/Dashboard.jsx b/src/Components/Layout/Dashboard.jsx index fd733a7..ce9c706 100644 --- a/src/Components/Layout/Dashboard.jsx +++ b/src/Components/Layout/Dashboard.jsx @@ -3,25 +3,29 @@ import SidebarMenu from "./SidebarMenu"; import TreeChart from "../TreeChart/TreeChart"; import "../../Style/Dashboard.css"; import ErrorIndicator from "../UI/ErrorIndicator"; -import tabContentData from "../TreeChart/tabContent"; import Tabs from "../UI/Tabs"; -import menuData from "../TreeChart/menuData.json"; // Исходные данные меню +import menuData from "../TreeChart/menuData.json"; // Импортируем JSON-данные import TreeTable from "../UI/TreeTable"; import { updateStatuses } from "../TreeChart/dataUtils"; // Функция обновления статусов +import generateTabContent from "../TreeChart/tabContent"; // Импортируем функцию generateTabContent const Dashboard = () => { const [tabs, setTabs] = useState([]); const [activeTab, setActiveTab] = useState("Главная"); - const [tabContent, setTabContent] = useState({}); + const [tabContent, setTabContent] = useState({}); // Состояние для контента вкладок const [treeData, setTreeData] = useState(menuData); // Загружаем меню в state const [sidebarWidth, setSidebarWidth] = useState(250); // Начальная ширина сайдбара const [isResizing, setIsResizing] = useState(false); // Состояние перетаскивания const sidebarRef = useRef(null); // Референс на сайдбар + // Генерация контента для вкладок на основе menuData + useEffect(() => { + const generatedTabContent = generateTabContent(menuData); + setTabContent(generatedTabContent); + }, []); + // Обновление treeData каждые 30 секунд useEffect(() => { - setTabContent(tabContentData); - const interval = setInterval(() => { setTreeData((prevData) => { const updatedData = JSON.parse(JSON.stringify(prevData)); // Клонируем данные @@ -92,7 +96,6 @@ const Dashboard = () => {

Общий мониторинг

{/* Используем актуальные данные */} - ); } else if (activeTab === "Визуализация") { @@ -133,4 +136,4 @@ const Dashboard = () => { ); }; -export default Dashboard; +export default Dashboard; \ No newline at end of file diff --git a/src/Components/TreeChart/TreeChart.jsx b/src/Components/TreeChart/TreeChart.jsx index 260854b..37705e8 100644 --- a/src/Components/TreeChart/TreeChart.jsx +++ b/src/Components/TreeChart/TreeChart.jsx @@ -5,12 +5,32 @@ import { getStatusColor } from "./dataUtils"; const TreeChart = ({ data, onNodeClick }) => { const chartRef = useRef(); const simulationRef = useRef(null); + const nodePositions = useRef(new Map()); const { root, nodes, links } = useMemo(() => { if (!data || !data.items) return { root: null, nodes: [], links: [] }; + const root = d3.hierarchy(data, (d) => d.items); - const links = root.links(); const nodes = root.descendants(); + const links = root.links(); + + // Применяем сохраненные позиции к узлам + nodes.forEach((node) => { + const prev = nodePositions.current.get(node.data.id); + if (prev) { + node.x = prev.x; + node.y = prev.y; + node.fx = prev.fx ?? null; // Если фиксированные координаты были, сохраняем + node.fy = prev.fy ?? null; + } else { + // Если узел новый, задаем ему позицию рядом с родителем + const parent = node.parent; + node.x = parent ? parent.x + Math.random() * 50 - 25 : Math.random() * 1000; + node.y = parent ? parent.y + Math.random() * 50 - 25 : Math.random() * 1000; + } + nodePositions.current.set(node.data.id, { x: node.x, y: node.y, fx: node.fx, fy: node.fy }); + }); + return { root, nodes, links }; }, [data]); @@ -22,25 +42,52 @@ const TreeChart = ({ data, onNodeClick }) => { .attr("height", 1000) .attr("viewBox", [-500, -500, 1000, 1000]) .attr("style", "max-width: 100%; height: auto;"); + + svg.append("g").attr("class", "links"); + svg.append("g").attr("class", "nodes"); + svg.append("g").attr("class", "labels"); + + // Инициализация симуляции + simulationRef.current = d3.forceSimulation() + .force("link", d3.forceLink().id((d) => d.data.id).distance(80).strength(1)) + .force("charge", d3.forceManyBody().strength(-200)) + .force("center", d3.forceCenter(0, 0)) + .force("collision", d3.forceCollide().radius(20)) + .force("x", d3.forceX(0).strength(0.05)) // Ограничиваем разлет по X + .force("y", d3.forceY(0).strength(0.05)) // Ограничиваем разлет по Y + .force("radial", d3.forceRadial(200, 0, 0).strength(0.02)) // Держим узлы ближе к центру + .alphaDecay(0.02) // Замедляем затухание + .alphaTarget(0.1); + + // Запускаем симуляцию на 15 секунд, затем отключаем + setTimeout(() => { + simulationRef.current.stop(); // Останавливаем симуляцию + nodes.forEach((node) => { + node.fx = node.x; // Фиксируем текущие позиции узлов + node.fy = node.y; + }); + }, 15000); // 15 секунд + }, []); useEffect(() => { if (!root || !chartRef.current) return; const svg = d3.select(chartRef.current); + const linkGroup = svg.select(".links"); + const nodeGroup = svg.select(".nodes"); + const labelGroup = svg.select(".labels"); - if (simulationRef.current) { - simulationRef.current.stop(); - } - - const link = svg.select(".links") + // Обновляем связи + const link = linkGroup .selectAll("line") .data(links, (d) => `${d.source.data.id}-${d.target.data.id}`) .join("line") .attr("stroke", "#999") .attr("stroke-opacity", 0.6); - const node = svg.select(".nodes") + // Обновляем узлы + const node = nodeGroup .selectAll("circle") .data(nodes, (d) => d.data.id) .join("circle") @@ -55,7 +102,8 @@ const TreeChart = ({ data, onNodeClick }) => { } }); - const text = svg.select(".labels") + // Обновляем текстовые метки + const text = labelGroup .selectAll("text") .data(nodes, (d) => d.data.id) .join("text") @@ -63,39 +111,12 @@ const TreeChart = ({ data, onNodeClick }) => { .attr("dx", 12) .attr("dy", 4); - node.each(function (d) { - if (d.data.status === "red") { - d3.select(this) - .transition() - .duration(500) - .ease(d3.easeLinear) - .style("opacity", 0.3) - .transition() - .duration(500) - .ease(d3.easeLinear) - .style("opacity", 1) - .on("end", function repeat() { - d3.select(this) - .transition() - .duration(500) - .ease(d3.easeLinear) - .style("opacity", 0.3) - .transition() - .duration(500) - .ease(d3.easeLinear) - .style("opacity", 1) - .on("end", repeat); - }); - } - }); + // Обновляем симуляцию + simulationRef.current.nodes(nodes); + simulationRef.current.force("link").links(links); + simulationRef.current.alphaTarget(0.1).restart(); - const simulation = d3.forceSimulation(nodes) - .force("link", d3.forceLink(links).id((d) => d.data.id).distance(80).strength(1)) - .force("charge", d3.forceManyBody().strength(-500)) - .force("x", d3.forceX()) - .force("y", d3.forceY()); - - simulation.on("tick", () => { + simulationRef.current.on("tick", () => { link .attr("x1", (d) => d.source.x) .attr("y1", (d) => d.source.y) @@ -111,9 +132,6 @@ const TreeChart = ({ data, onNodeClick }) => { .attr("y", (d) => d.y + 4); }); - simulationRef.current = simulation; - - return () => simulation.stop(); }, [root, links, nodes, onNodeClick]); const drag = () => { @@ -130,21 +148,13 @@ const TreeChart = ({ data, onNodeClick }) => { function dragended(event, d) { if (!event.active) simulationRef.current.alphaTarget(0); - d.fx = d.x; - d.fy = d.y; + nodePositions.current.set(d.data.id, { x: d.x, y: d.y, fx: d.fx, fy: d.fy }); } return d3.drag().on("start", dragstarted).on("drag", dragged).on("end", dragended); }; - return ( - - - - - - ); + return ; }; -export default TreeChart; - +export default TreeChart; \ No newline at end of file diff --git a/src/Components/TreeChart/dataUtils.jsx b/src/Components/TreeChart/dataUtils.jsx index 85b5217..fa67130 100644 --- a/src/Components/TreeChart/dataUtils.jsx +++ b/src/Components/TreeChart/dataUtils.jsx @@ -46,7 +46,7 @@ const getStatusColor = (status) => { case "red": return "#F44336"; // Красный default: - return "#3d74c7"; // Синий (или любой другой стандартный цвет) + return "#4CAF50"; // Синий (или любой другой стандартный цвет) } }; diff --git a/src/Components/TreeChart/menuData.json b/src/Components/TreeChart/menuData.json index 9e9a2e8..4cdcaff 100644 --- a/src/Components/TreeChart/menuData.json +++ b/src/Components/TreeChart/menuData.json @@ -1,5 +1,6 @@ { - "title": "Сервис ВКС", + "title": "Сервер ЗВКС", + "id": "1", "items": [ { "title": "Функциональные задачи", @@ -27,47 +28,422 @@ ] }, { - "title": "Медиа сервер", + "id": "18", + "title": "Graviton S2082I (device$18)", "items": [ { - "title": "Аппаратное обеспечение", + "id": "4", + "title": "OS Linux (module$4) АО", "items": [ { - "id": "media_system_software_1", - "title": "Центральный процессор" + "id": "188", + "title": "Наименование" }, { - "id": "media_system_software_2", - "title": "Оперативная память" + "id": "189", + "title": "Время работы" }, { - "id": "media_system_software_3", - "title": "Жесткий диск" + "id": "190", + "title": "Загрузка процессора за 1 минуту" }, { - "id": "media_system_software_4", - "title": "Сетевые адаптеры" + "id": "191", + "title": "Загрузка процессора за 5 минут" + }, + { + "id": "192", + "title": "Загрузка процессора за 15 минут" + }, + { + "id": "197", + "title": "Общий объем SWAP-файла" + }, + { + "id": "198", + "title": "Используемый объем SWAP-файла" + }, + { + "id": "199", + "title": "Общий объем физической оперативной памяти" + }, + { + "id": "200", + "title": "Доступный объем физической оперативной памяти" + }, + { + "id": "201", + "title": "Свободный объем физической и виртуальной оперативной памяти" + }, + { + "id": "202", + "title": "Буферизованный объем оперативной памяти" + }, + { + "id": "203", + "title": "Кэшированый объем оперативной памяти" + }, + { + "id": "274", + "title": "Используемый объем SWAP-файла" + }, + { + "id": "275", + "title": "Время затраченное процессором на процессы с пониженным приоритетом" + }, + { + "id": "276", + "title": "Время затраченное процессором на процессы ядра ОС" + }, + { + "id": "277", + "title": "Время простоя процессора" + }, + { + "id": "278", + "title": "Общая емкость жестких дисков" + }, + { + "id": "279", + "title": "Доступная емкость жестких дисков" } ] }, { - "title": "Программное обеспечение", + "id": "5", + "title": "Vinteo (module$5) ПО", "items": [ { - "id": "media_software_1", - "title": "ПО" + "id": "31", + "title": "Общее количество участников" }, { - "id": "media_software_2", - "title": "ПО" + "id": "32", + "title": "Ожидание соединения" }, { - "id": "media_software_3", - "title": "ПО" + "id": "33", + "title": "Зарегистрированные абоненты" }, { - "id": "media_software_4", - "title": "ПО" + "id": "34", + "title": "Количество пользоватей HLS" + }, + { + "id": "35", + "title": "Общее количество P2P комнат" + }, + { + "id": "36", + "title": "Общее количество конференций" + }, + { + "id": "37", + "title": "Общее количество активных конференций" + }, + { + "id": "38", + "title": "Статус записи" + }, + { + "id": "39", + "title": "Общее количество сохранённых записей" + } + ] + }, + { + "id": "261", + "title": "Сетевой адаптер №1 (port$261) Eth_1", + "items": [ + { + "id": "206", + "title": "Наименование порта Eth_1" + }, + { + "id": "207", + "title": "Скорость порта Eth_1" + }, + { + "id": "208", + "title": "Физический адрес порта Eth_1" + }, + { + "id": "209", + "title": "Административное состояние порта Eth_1" + }, + { + "id": "210", + "title": "Оперативное состояние порта Eth_1" + }, + { + "id": "211", + "title": "Общее количество отправленных октетов Eth_1" + }, + { + "id": "212", + "title": "Количество входящих Multicast пакетов Eth_1" + }, + { + "id": "213", + "title": "Количество иcходящих Multiicast пакетов Eth_1" + }, + { + "id": "214", + "title": "Количество входящих Broadcast пакетов Eth_1" + }, + { + "id": "215", + "title": "Количество иcходящих Broadcast пакетов Eth_1" + }, + { + "id": "216", + "title": "Количество входящих Unicast пакетов Eth_1" + }, + { + "id": "217", + "title": "Количество иcходящих Unicast пакетов Eth_1" + }, + { + "id": "218", + "title": "Количество входящих пакетов помеченные как отброшенные Eth_1" + }, + { + "id": "219", + "title": "Количество иcходящих пакетов помеченные как отброшенные Eth_1" + }, + { + "id": "220", + "title": "Количество входящих пакетов с ошибкой Eth_1" + }, + { + "id": "221", + "title": "Количество исходящих пакетов с ошибкой Eth_1" + }, + { + "id": "222", + "title": "Количество входящих пакетов с неизвестным или неподдерживаемым протоколом Eth_1" + } + ] + }, + { + "id": "262", + "title": "Сетевой адаптер №2 (port$262) Eth_2", + "items": [ + { + "id": "223", + "title": "Наименование порта Eth_2" + }, + { + "id": "224", + "title": "Скорость порта Eth_2" + }, + { + "id": "225", + "title": "Физический адрес порта Eth_2" + }, + { + "id": "226", + "title": "Административное состояние порта Eth_2" + }, + { + "id": "227", + "title": "Оперативное состояние порта Eth_2" + }, + { + "id": "228", + "title": "Общее количество отправленных октетов Eth_2" + }, + { + "id": "229", + "title": "Количество входящих Multicast пакетов Eth_2" + }, + { + "id": "230", + "title": "Количество иcходящих Multiicast пакетов Eth_2" + }, + { + "id": "231", + "title": "Количество входящих Broadcast пакетов Eth_2" + }, + { + "id": "232", + "title": "Количество иcходящих Broadcast пакетов Eth_2" + }, + { + "id": "233", + "title": "Количество входящих Unicast пакетов Eth_2" + }, + { + "id": "234", + "title": "Количество иcходящих Unicast пакетов Eth_2" + }, + { + "id": "235", + "title": "Количество входящих пакетов помеченные как отброшенные Eth_2" + }, + { + "id": "236", + "title": "Количество иcходящих пакетов помеченные как отброшенные Eth_2" + }, + { + "id": "237", + "title": "Количество входящих пакетов с ошибкой Eth_2" + }, + { + "id": "238", + "title": "Количество исходящих пакетов с ошибкой Eth_2" + }, + { + "id": "239", + "title": "Количество входящих пакетов с неизвестным или неподдерживаемым протоколом Eth_2" + } + ] + }, + { + "id": "263", + "title": "Сетевой адаптер №3 (port$263) Eth_3", + "items": [ + { + "id": "240", + "title": "Наименование порта Eth_3" + }, + { + "id": "241", + "title": "Скорость порта Eth_3" + }, + { + "id": "242", + "title": "Физический адрес порта Eth_3" + }, + { + "id": "243", + "title": "Административное состояние порта Eth_3" + }, + { + "id": "244", + "title": "Оперативное состояние порта Eth_3" + }, + { + "id": "245", + "title": "Общее количество отправленных октетов Eth_3" + }, + { + "id": "246", + "title": "Количество входящих Multicast пакетов Eth_3" + }, + { + "id": "247", + "title": "Количество иcходящих Multiicast пакетов Eth_3" + }, + { + "id": "248", + "title": "Количество входящих Broadcast пакетов Eth_3" + }, + { + "id": "249", + "title": "Количество иcходящих Broadcast пакетов Eth_3" + }, + { + "id": "250", + "title": "Количество входящих Unicast пакетов Eth_3" + }, + { + "id": "251", + "title": "Количество иcходящих Unicast пакетов Eth_3" + }, + { + "id": "252", + "title": "Количество входящих пакетов помеченные как отброшенные Eth_3" + }, + { + "id": "253", + "title": "Количество иcходящих пакетов помеченные как отброшенные Eth_3" + }, + { + "id": "254", + "title": "Количество входящих пакетов с ошибкой Eth_3" + }, + { + "id": "255", + "title": "Количество исходящих пакетов с ошибкой Eth_3" + }, + { + "id": "256", + "title": "Количество входящих пакетов с неизвестным или неподдерживаемым протоколом Eth_3" + } + ] + }, + { + "id": "264", + "title": "Сетевой адаптер №4 (port$264) Eth_4", + "items": [ + { + "id": "257", + "title": "Наименование порта Eth_4" + }, + { + "id": "258", + "title": "Скорость порта Eth_4" + }, + { + "id": "259", + "title": "Физический адрес порта Eth_4" + }, + { + "id": "260", + "title": "Административное состояние порта Eth_4" + }, + { + "id": "261", + "title": "Оперативное состояние порта Eth_4" + }, + { + "id": "262", + "title": "Общее количество отправленных октетов Eth_4" + }, + { + "id": "263", + "title": "Количество входящих Multicast пакетов Eth_4" + }, + { + "id": "264", + "title": "Количество иcходящих Multiicast пакетов Eth_4" + }, + { + "id": "265", + "title": "Количество входящих Broadcast пакетов Eth_4" + }, + { + "id": "266", + "title": "Количество иcходящих Broadcast пакетов Eth_4" + }, + { + "id": "267", + "title": "Количество входящих Unicast пакетов Eth_4" + }, + { + "id": "268", + "title": "Количество иcходящих Unicast пакетов Eth_4" + }, + { + "id": "269", + "title": "Количество входящих пакетов помеченные как отброшенные Eth_4" + }, + { + "id": "270", + "title": "Количество иcходящих пакетов помеченные как отброшенные Eth_4" + }, + { + "id": "271", + "title": "Количество входящих пакетов с ошибкой Eth_4" + }, + { + "id": "272", + "title": "Количество исходящих пакетов с ошибкой Eth_4" + }, + { + "id": "273", + "title": "Количество входящих пакетов с неизвестным или неподдерживаемым протоколом Eth_4" } ] } diff --git a/src/Components/TreeChart/menuData2.json b/src/Components/TreeChart/menuData2.json new file mode 100644 index 0000000..645a8ef --- /dev/null +++ b/src/Components/TreeChart/menuData2.json @@ -0,0 +1,382 @@ +{ + "title": "Сервис ВКС", + "id":"service_VKS", + "items": [ + { + "title": "Функциональные задачи", + "id":"functions", + "items": [ + { + "id": "system_control", + "title": "Контроль системы" + }, + { + "id": "system_management", + "title": "Система управления" + }, + { + "id": "conference", + "title": "Проведение ВКС" + }, + { + "id": "backup", + "title": "Резервное копирование" + }, + { + "id": "relay_info", + "title": "Ретрансляция информации" + } + ] + }, + { + "title": "Медиа сервер", + "id":"media_server_1", + "items": [ + { + "title": "Аппаратное обеспечение", + "id":"system_software_1", + "items": [ + { + "id": "media_system_software_1", + "title": "Центральный процессор" + }, + { + "id": "media_system_software_2", + "title": "Оперативная память" + }, + { + "id": "media_system_software_3", + "title": "Жесткий диск" + }, + { + "id": "media_system_software_4", + "title": "Сетевые адаптеры" + } + ] + }, + { + "title": "Программное обеспечение", + "id":"software_1", + "items": [ + { + "id": "media_software_1", + "title": "ПО" + }, + { + "id": "media_software_2", + "title": "ПО" + }, + { + "id": "media_software_3", + "title": "ПО" + }, + { + "id": "media_software_4", + "title": "ПО" + } + ] + } + ] + }, + { + "title": "Медиа сервер", + "id":"media_server_2", + "items": [ + { + "title": "Аппаратное обеспечение", + "id":"system_software_2", + "items": [ + { + "id": "media_system_software_1_2", + "title": "Центральный процессор" + }, + { + "id": "media_system_software_2_2", + "title": "Оперативная память" + }, + { + "id": "media_system_software_3_2", + "title": "Жесткий диск" + }, + { + "id": "media_system_software_4_2", + "title": "Сетевые адаптеры" + } + ] + }, + { + "title": "Программное обеспечение", + "id":"software_2", + "items": [ + { + "id": "media_software_1_2", + "title": "ПО" + }, + { + "id": "media_software_2_2", + "title": "ПО" + }, + { + "id": "media_software_3_2", + "title": "ПО" + }, + { + "id": "media_software_4_2", + "title": "ПО" + } + ] + } + ] + }, + { + "title": "Медиа сервер", + "id":"media_server_3", + "items": [ + { + "title": "Аппаратное обеспечение", + "id":"system_software_3", + "items": [ + { + "id": "media_system_software_1_3", + "title": "Центральный процессор" + }, + { + "id": "media_system_software_2_3", + "title": "Оперативная память" + }, + { + "id": "media_system_software_3_3", + "title": "Жесткий диск" + }, + { + "id": "media_system_software_4_3", + "title": "Сетевые адаптеры" + } + ] + }, + { + "title": "Программное обеспечение", + "id":"software_3", + "items": [ + { + "id": "media_software_1_3", + "title": "ПО" + }, + { + "id": "media_software_2_3", + "title": "ПО" + }, + { + "id": "media_software_3_3", + "title": "ПО" + }, + { + "id": "media_software_4_3", + "title": "ПО" + } + ] + } + ] + }, + { + "title": "Медиа сервер", + "id":"media_server_4", + "items": [ + { + "title": "Аппаратное обеспечение", + "id":"system_software_4", + "items": [ + { + "id": "media_system_software_1_4", + "title": "Центральный процессор" + }, + { + "id": "media_system_software_2_4", + "title": "Оперативная память" + }, + { + "id": "media_system_software_3_4", + "title": "Жесткий диск" + }, + { + "id": "media_system_software_4_4", + "title": "Сетевые адаптеры" + } + ] + }, + { + "title": "Программное обеспечение", + "id":"software_4", + "items": [ + { + "id": "media_software_1_4", + "title": "ПО" + }, + { + "id": "media_software_2_4", + "title": "ПО" + }, + { + "id": "media_software_3_4", + "title": "ПО" + }, + { + "id": "media_software_4_4", + "title": "ПО" + } + ] + } + ] + }, + { + "title": "Медиа сервер", + "id":"media_server_5", + "items": [ + { + "title": "Аппаратное обеспечение", + "id":"system_software_5", + "items": [ + { + "id": "media_system_software_1_5", + "title": "Центральный процессор" + }, + { + "id": "media_system_software_2_5", + "title": "Оперативная память" + }, + { + "id": "media_system_software_3_5", + "title": "Жесткий диск" + }, + { + "id": "media_system_software_4_5", + "title": "Сетевые адаптеры" + } + ] + }, + { + "title": "Программное обеспечение", + "id":"software_5", + "items": [ + { + "id": "media_software_1_5", + "title": "ПО" + }, + { + "id": "media_software_2_5", + "title": "ПО" + }, + { + "id": "media_software_3_5", + "title": "ПО" + }, + { + "id": "media_software_4_5", + "title": "ПО" + } + ] + } + ] + }, + { + "title": "Сервер систем", + "id":"system_server_1", + "items": [ + { + "title": "Аппаратное обеспечение", + "id":"system_software_6", + "items": [ + { + "id": "copy_system_software_1", + "title": "Центральный процессор" + }, + { + "id": "copy_system_software_2", + "title": "Оперативная память" + }, + { + "id": "copy_system_software_3", + "title": "Жесткий диск" + }, + { + "id": "copy_system_software_4", + "title": "Сетевые адаптеры" + } + ] + }, + { + "title": "Программное обеспечение", + "id":"software_6", + "items": [ + { + "id": "copy_software_1", + "title": "ПО" + }, + { + "id": "copy_software_2", + "title": "ПО" + }, + { + "id": "copy_software_3", + "title": "ПО" + }, + { + "id": "copy_software_4", + "title": "ПО" + } + ] + } + ] + }, + { + "title": "Сервер систем", + "id":"system_server_2", + "items": [ + { + "title": "Аппаратное обеспечение", + "id":"system_software_7", + "items": [ + { + "id": "control_system_software_1", + "title": "Центральный процессор" + }, + { + "id": "control_system_software_2", + "title": "Оперативная память" + }, + { + "id": "control_system_software_3", + "title": "Жесткий диск" + }, + { + "id": "control_system_software_4", + "title": "Сетевые адаптеры" + } + ] + }, + { + "title": "Программное обеспечение", + "id":"software_7", + "items": [ + { + "id": "control_software_1", + "title": "ПО" + }, + { + "id": "control_software_2", + "title": "ПО" + }, + { + "id": "control_software_3", + "title": "ПО" + }, + { + "id": "control_software_4", + "title": "ПО" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/src/Components/TreeChart/menuData3.json b/src/Components/TreeChart/menuData3.json deleted file mode 100644 index 1c0eeda..0000000 --- a/src/Components/TreeChart/menuData3.json +++ /dev/null @@ -1,117 +0,0 @@ -{ - "title": "Сервис ВКС", - "items": [ - { - "title": "Функциональные задачи", - "items": [ - { - "title": "Тест", - "items": [ - { - "id": "test1", - "title": "тест2" - }, - { - "id": "test2", - "title": "Тест3" - } - ] - }, - { - "id": "system_control", - "title": "Контроль системы" - }, - { - "id": "system_management", - "title": "Система управления" - }, - { - "id": "conference", - "title": "Проведение ВКС" - }, - { - "id": "backup", - "title": "Резервное копирование" - }, - { - "id": "relay_info", - "title": "Ретрансляция информации" - } - ] - }, - { - "title": "Аппаратное обеспечение", - "items": [ - { - "id": "hardware_software_1", - "title": "Сервер системы управления" - }, - { - "id": "hardware_software_2", - "title": "Сервер системы управления" - }, - { - "id": "hardware_software_3", - "title": "Медиа-сервер" - }, - { - "id": "hardware_software_4", - "title": "Медиа-сервер" - }, - { - "id": "hardware_software_5", - "title": "Медиа-сервер" - }, - { - "id": "hardware_software_6", - "title": "Медиа-сервер" - }, - { - "id": "hardware_software_7", - "title": "Сервер резервного копирования" - }, - { - "id": "hardware_software_8", - "title": "Сервер сбора и ретрансляции информации" - } - ] - }, - { - "title": "Программное обеспечение", - "items": [ - { - "id": "software_1", - "title": "БП/ППО" - }, - { - "id": "software_2", - "title": "БП/ППО" - }, - { - "id": "software_3", - "title": "БП/ППО" - }, - { - "id": "software_4", - "title": "БП/ППО" - }, - { - "id": "software_5", - "title": "БП/ППО" - }, - { - "id": "software_6", - "title": "БП/ППО" - }, - { - "id": "software_7", - "title": "БП/ППО" - }, - { - "id": "software_8", - "title": "БП/ППО" - } - ] - } - ] -} \ No newline at end of file diff --git a/src/Components/TreeChart/tabContent.jsx b/src/Components/TreeChart/tabContent.jsx index 47dc890..eecfcc2 100644 --- a/src/Components/TreeChart/tabContent.jsx +++ b/src/Components/TreeChart/tabContent.jsx @@ -1,96 +1,78 @@ -import React from "react"; -import PrometheusChart from '../../Charts/PrometheusChart'; +import React, { lazy, Suspense } from "react"; -const tabContent = { - // Сервис ВКС - service1: { title: "Сервис ВКС", content:

Сервис ВКС

}, +const PrometheusChart = lazy(() => import('../../Charts/PrometheusChart')); - // Функциональные задачи - system_control: { title: "Контроль системы", content:

Контроль системы

Описание контроля.

}, - system_management: { title: "Система управления", content:

Система управления

Описание системы управления.

}, - conference: { title: "Проведение ВКС", content:

Проведение ВКС

Информация о проведении ВКС.

}, - backup: { title: "Резервное копирование", content:

Резервное копирование

Процесс резервного копирования.

}, - relay_info: { title: "Ретрансляция информации", content:

Ретрансляция информации

Детали ретрансляции.

}, +// Вкладки, для которых нужно отобразить график +const tabsWithCharts = ["188", "189"]; - // Медиа сервер 1 - media_system_software_1: { title: "Центральный процессор", content:

Центральный процессор

Описание центрального процессора медиа сервера.

}, - media_system_software_2: { title: "Оперативная память", content:

Оперативная память

Описание оперативной памяти медиа сервера.

}, - media_system_software_3: { title: "Жесткий диск", content:

Жесткий диск

Описание жесткого диска медиа сервера.

}, - media_system_software_4: { title: "Сетевые адаптеры", content:

Сетевые адаптеры

Описание сетевых адаптеров медиа сервера.

}, - media_software_1: { title: "ПО", content:

Программное обеспечение медиа сервера

}, - media_software_2: { title: "ПО", content:

Программное обеспечение медиа сервера

Описание ПО медиа сервера.

}, - media_software_3: { title: "ПО", content:

Программное обеспечение медиа сервера

Описание ПО медиа сервера.

}, - media_software_4: { title: "ПО", content:

Программное обеспечение медиа сервера

Описание ПО медиа сервера.

}, - - // Медиа сервер 2 - media_system_software_1_2: { title: "Центральный процессор", content:

Центральный процессор

Описание центрального процессора медиа сервера.

}, - media_system_software_2_2: { title: "Оперативная память", content:

Оперативная память

Описание оперативной памяти медиа сервера.

}, - media_system_software_3_2: { title: "Жесткий диск", content:

Жесткий диск

Описание жесткого диска медиа сервера.

}, - media_system_software_4_2: { title: "Сетевые адаптеры", content:

Сетевые адаптеры

Описание сетевых адаптеров медиа сервера.

}, - media_software_1_2: { title: "ПО", content:

Программное обеспечение медиа сервера

}, - media_software_2_2: { title: "ПО", content:

Программное обеспечение медиа сервера

Описание ПО медиа сервера.

}, - media_software_3_2: { title: "ПО", content:

Программное обеспечение медиа сервера

Описание ПО медиа сервера.

}, - media_software_4_2: { title: "ПО", content:

Программное обеспечение медиа сервера

Описание ПО медиа сервера.

}, - - // Медиа сервер 3 - media_system_software_1_3: { title: "Центральный процессор", content:

Центральный процессор

Описание центрального процессора медиа сервера.

}, - media_system_software_2_3: { title: "Оперативная память", content:

Оперативная память

Описание оперативной памяти медиа сервера.

}, - media_system_software_3_3: { title: "Жесткий диск", content:

Жесткий диск

Описание жесткого диска медиа сервера.

}, - media_system_software_4_3: { title: "Сетевые адаптеры", content:

Сетевые адаптеры

Описание сетевых адаптеров медиа сервера.

}, - media_software_1_3: { title: "ПО", content:

Программное обеспечение медиа сервера

}, - media_software_2_3: { title: "ПО", content:

Программное обеспечение медиа сервера

Описание ПО медиа сервера.

}, - media_software_3_3: { title: "ПО", content:

Программное обеспечение медиа сервера

Описание ПО медиа сервера.

}, - media_software_4_3: { title: "ПО", content:

Программное обеспечение медиа сервера

Описание ПО медиа сервера.

}, - - // Медиа сервер 4 - media_system_software_1_4: { title: "Центральный процессор", content:

Центральный процессор

Описание центрального процессора медиа сервера.

}, - media_system_software_2_4: { title: "Оперативная память", content:

Оперативная память

Описание оперативной памяти медиа сервера.

}, - media_system_software_3_4: { title: "Жесткий диск", content:

Жесткий диск

Описание жесткого диска медиа сервера.

}, - media_system_software_4_4: { title: "Сетевые адаптеры", content:

Сетевые адаптеры

Описание сетевых адаптеров медиа сервера.

}, - media_software_1_4: { title: "ПО", content:

Программное обеспечение медиа сервера

}, - media_software_2_4: { title: "ПО", content:

Программное обеспечение медиа сервера

Описание ПО медиа сервера.

}, - media_software_3_4: { title: "ПО", content:

Программное обеспечение медиа сервера

Описание ПО медиа сервера.

}, - media_software_4_4: { title: "ПО", content:

Программное обеспечение медиа сервера

Описание ПО медиа сервера.

}, - - // Медиа сервер 5 - media_system_software_1_5: { title: "Центральный процессор", content:

Центральный процессор

Описание центрального процессора медиа сервера.

}, - media_system_software_2_5: { title: "Оперативная память", content:

Оперативная память

Описание оперативной памяти медиа сервера.

}, - media_system_software_3_5: { title: "Жесткий диск", content:

Жесткий диск

Описание жесткого диска медиа сервера.

}, - media_system_software_4_5: { title: "Сетевые адаптеры", content:

Сетевые адаптеры

Описание сетевых адаптеров медиа сервера.

}, - media_software_1_5: { title: "ПО", content:

Программное обеспечение медиа сервера

}, - media_software_2_5: { title: "ПО", content:

Программное обеспечение медиа сервера

Описание ПО медиа сервера.

}, - media_software_3_5: { title: "ПО", content:

Программное обеспечение медиа сервера

Описание ПО медиа сервера.

}, - media_software_4_5: { title: "ПО", content:

Программное обеспечение медиа сервера

Описание ПО медиа сервера.

}, - - // Сервер резервного копирования - copy_system_software_1: { title: "Центральный процессор", content:

Центральный процессор

Описание центрального процессора сервера резервного копирования.

}, - copy_system_software_2: { title: "Оперативная память", content:

Оперативная память

Описание оперативной памяти сервера резервного копирования.

}, - copy_system_software_3: { title: "Жесткий диск", content:

Жесткий диск

Описание жесткого диска сервера резервного копирования.

}, - copy_system_software_4: { title: "Сетевые адаптеры", content:

Сетевые адаптеры

Описание сетевых адаптеров сервера резервного копирования.

}, - copy_software_1: { title: "ПО", content:

Программное обеспечение сервера резервного копирования

Описание ПО сервера резервного копирования.

}, - copy_software_2: { title: "ПО", content:

Программное обеспечение сервера резервного копирования

Описание ПО сервера резервного копирования.

}, - copy_software_3: { title: "ПО", content:

Программное обеспечение сервера резервного копирования

Описание ПО сервера резервного копирования.

}, - copy_software_4: { title: "ПО", content:

Программное обеспечение сервера резервного копирования

Описание ПО сервера резервного копирования.

}, - - // Сервер системы управления - control_system_software_1: { title: "Центральный процессор", content:

Центральный процессор

Описание центрального процессора сервера системы управления.

}, - control_system_software_2: { title: "Оперативная память", content:

Оперативная память

Описание оперативной памяти сервера системы управления.

}, - control_system_software_3: { title: "Жесткий диск", content:

Жесткий диск

Описание жесткого диска сервера системы управления.

}, - control_system_software_4: { title: "Сетевые адаптеры", content:

Сетевые адаптеры

Описание сетевых адаптеров сервера системы управления.

}, - control_software_1: { title: "ПО", content:

Программное обеспечение сервера системы управления

Описание ПО сервера системы управления.

}, - control_software_2: { title: "ПО", content:

Программное обеспечение сервера системы управления

Описание ПО сервера системы управления.

}, - control_software_3: { title: "ПО", content:

Программное обеспечение сервера системы управления

Описание ПО сервера системы управления.

}, - control_software_4: { title: "ПО", content:

Программное обеспечение сервера системы управления

Описание ПО сервера системы управления.

}, - - // Сервер сбора и ретрансляции информации - system_software_1: { title: "Центральный процессор", content:

Центральный процессор

Описание центрального процессора сервера сбора и ретрансляции информации.

}, - system_software_2: { title: "Оперативная память", content:

Оперативная память

Описание оперативной памяти сервера сбора и ретрансляции информации.

}, - system_software_3: { title: "Жесткий диск", content:

Жесткий диск

Описание жесткого диска сервера сбора и ретрансляции информации.

}, - system_software_4: { title: "Сетевые адаптеры", content:

Сетевые адаптеры

Описание сетевых адаптеров сервера сбора и ретрансляции информации.

}, - software_1: { title: "ПО", content:

Программное обеспечение сервера сбора и ретрансляции информации

Описание ПО сервера сбора и ретрансляции информации.

}, - software_2: { title: "ПО", content:

Программное обеспечение сервера сбора и ретрансляции информации

Описание ПО сервера сбора и ретрансляции информации.

}, - software_3: { title: "ПО", content:

Программное обеспечение сервера сбора и ретрансляции информации

Описание ПО сервера сбора и ретрансляции информации.

}, - software_4: { title: "ПО", content:

Программное обеспечение сервера сбора и ретрансляции информации

Описание ПО сервера сбора и ретрансляции информации.

}, +// Маппинг id на метрики +const metricMapping = { + 188: "zvks_apiforsnmp_measure_277", + 189: "zvks_apiforsnmp_measure_36", }; -export default tabContent; \ No newline at end of file +const generateTabContent = (data) => { + const tabContent = {}; + + console.log("jsonData:", data); + console.log("jsonData.items:", data.items); + + const generateContent = (nodes) => { + nodes.forEach((node) => { + console.log("Обрабатываем узел:", node); + + // Если у узла есть вложенные элементы, рекурсивно обрабатываем их + if (node.items && node.items.length > 0) { + console.log("Идём вглубь:", node.items); + generateContent(node.items); + } + + // Если у узла есть id, добавляем его в tabContent + if (node.id) { + console.log("Добавляем в tabContent:", node.id); + + let content = ( +
+

{node.title}

+

Контент для {node.title}.

+
+ ); + + // Если id узла есть в списке tabsWithCharts, добавляем график + if (tabsWithCharts.includes(node.id)) { + console.log("Добавляем график для:", node.id); + + // Получаем метрику для текущего id + const metricName = metricMapping[node.id]; + + content = ( +
+

{node.title}

+

Контент для {node.title}.

+ Загрузка графика...
}> + + + + ); + } + + // Сохраняем контент для текущего id + tabContent[node.id] = { + title: node.title, + content: content, + }; + } + }); + }; + + // Начинаем обработку с корневого уровня + if (data.items && data.items.length > 0) { + generateContent(data.items); + } else { + console.warn("Данные отсутствуют или массив items пуст"); + } + + return tabContent; +}; + +export default generateTabContent; // Экспортируем только функцию \ No newline at end of file diff --git a/src/Components/TreeChart/tabContent2.jsx b/src/Components/TreeChart/tabContent2.jsx new file mode 100644 index 0000000..47dc890 --- /dev/null +++ b/src/Components/TreeChart/tabContent2.jsx @@ -0,0 +1,96 @@ +import React from "react"; +import PrometheusChart from '../../Charts/PrometheusChart'; + +const tabContent = { + // Сервис ВКС + service1: { title: "Сервис ВКС", content:

Сервис ВКС

}, + + // Функциональные задачи + system_control: { title: "Контроль системы", content:

Контроль системы

Описание контроля.

}, + system_management: { title: "Система управления", content:

Система управления

Описание системы управления.

}, + conference: { title: "Проведение ВКС", content:

Проведение ВКС

Информация о проведении ВКС.

}, + backup: { title: "Резервное копирование", content:

Резервное копирование

Процесс резервного копирования.

}, + relay_info: { title: "Ретрансляция информации", content:

Ретрансляция информации

Детали ретрансляции.

}, + + // Медиа сервер 1 + media_system_software_1: { title: "Центральный процессор", content:

Центральный процессор

Описание центрального процессора медиа сервера.

}, + media_system_software_2: { title: "Оперативная память", content:

Оперативная память

Описание оперативной памяти медиа сервера.

}, + media_system_software_3: { title: "Жесткий диск", content:

Жесткий диск

Описание жесткого диска медиа сервера.

}, + media_system_software_4: { title: "Сетевые адаптеры", content:

Сетевые адаптеры

Описание сетевых адаптеров медиа сервера.

}, + media_software_1: { title: "ПО", content:

Программное обеспечение медиа сервера

}, + media_software_2: { title: "ПО", content:

Программное обеспечение медиа сервера

Описание ПО медиа сервера.

}, + media_software_3: { title: "ПО", content:

Программное обеспечение медиа сервера

Описание ПО медиа сервера.

}, + media_software_4: { title: "ПО", content:

Программное обеспечение медиа сервера

Описание ПО медиа сервера.

}, + + // Медиа сервер 2 + media_system_software_1_2: { title: "Центральный процессор", content:

Центральный процессор

Описание центрального процессора медиа сервера.

}, + media_system_software_2_2: { title: "Оперативная память", content:

Оперативная память

Описание оперативной памяти медиа сервера.

}, + media_system_software_3_2: { title: "Жесткий диск", content:

Жесткий диск

Описание жесткого диска медиа сервера.

}, + media_system_software_4_2: { title: "Сетевые адаптеры", content:

Сетевые адаптеры

Описание сетевых адаптеров медиа сервера.

}, + media_software_1_2: { title: "ПО", content:

Программное обеспечение медиа сервера

}, + media_software_2_2: { title: "ПО", content:

Программное обеспечение медиа сервера

Описание ПО медиа сервера.

}, + media_software_3_2: { title: "ПО", content:

Программное обеспечение медиа сервера

Описание ПО медиа сервера.

}, + media_software_4_2: { title: "ПО", content:

Программное обеспечение медиа сервера

Описание ПО медиа сервера.

}, + + // Медиа сервер 3 + media_system_software_1_3: { title: "Центральный процессор", content:

Центральный процессор

Описание центрального процессора медиа сервера.

}, + media_system_software_2_3: { title: "Оперативная память", content:

Оперативная память

Описание оперативной памяти медиа сервера.

}, + media_system_software_3_3: { title: "Жесткий диск", content:

Жесткий диск

Описание жесткого диска медиа сервера.

}, + media_system_software_4_3: { title: "Сетевые адаптеры", content:

Сетевые адаптеры

Описание сетевых адаптеров медиа сервера.

}, + media_software_1_3: { title: "ПО", content:

Программное обеспечение медиа сервера

}, + media_software_2_3: { title: "ПО", content:

Программное обеспечение медиа сервера

Описание ПО медиа сервера.

}, + media_software_3_3: { title: "ПО", content:

Программное обеспечение медиа сервера

Описание ПО медиа сервера.

}, + media_software_4_3: { title: "ПО", content:

Программное обеспечение медиа сервера

Описание ПО медиа сервера.

}, + + // Медиа сервер 4 + media_system_software_1_4: { title: "Центральный процессор", content:

Центральный процессор

Описание центрального процессора медиа сервера.

}, + media_system_software_2_4: { title: "Оперативная память", content:

Оперативная память

Описание оперативной памяти медиа сервера.

}, + media_system_software_3_4: { title: "Жесткий диск", content:

Жесткий диск

Описание жесткого диска медиа сервера.

}, + media_system_software_4_4: { title: "Сетевые адаптеры", content:

Сетевые адаптеры

Описание сетевых адаптеров медиа сервера.

}, + media_software_1_4: { title: "ПО", content:

Программное обеспечение медиа сервера

}, + media_software_2_4: { title: "ПО", content:

Программное обеспечение медиа сервера

Описание ПО медиа сервера.

}, + media_software_3_4: { title: "ПО", content:

Программное обеспечение медиа сервера

Описание ПО медиа сервера.

}, + media_software_4_4: { title: "ПО", content:

Программное обеспечение медиа сервера

Описание ПО медиа сервера.

}, + + // Медиа сервер 5 + media_system_software_1_5: { title: "Центральный процессор", content:

Центральный процессор

Описание центрального процессора медиа сервера.

}, + media_system_software_2_5: { title: "Оперативная память", content:

Оперативная память

Описание оперативной памяти медиа сервера.

}, + media_system_software_3_5: { title: "Жесткий диск", content:

Жесткий диск

Описание жесткого диска медиа сервера.

}, + media_system_software_4_5: { title: "Сетевые адаптеры", content:

Сетевые адаптеры

Описание сетевых адаптеров медиа сервера.

}, + media_software_1_5: { title: "ПО", content:

Программное обеспечение медиа сервера

}, + media_software_2_5: { title: "ПО", content:

Программное обеспечение медиа сервера

Описание ПО медиа сервера.

}, + media_software_3_5: { title: "ПО", content:

Программное обеспечение медиа сервера

Описание ПО медиа сервера.

}, + media_software_4_5: { title: "ПО", content:

Программное обеспечение медиа сервера

Описание ПО медиа сервера.

}, + + // Сервер резервного копирования + copy_system_software_1: { title: "Центральный процессор", content:

Центральный процессор

Описание центрального процессора сервера резервного копирования.

}, + copy_system_software_2: { title: "Оперативная память", content:

Оперативная память

Описание оперативной памяти сервера резервного копирования.

}, + copy_system_software_3: { title: "Жесткий диск", content:

Жесткий диск

Описание жесткого диска сервера резервного копирования.

}, + copy_system_software_4: { title: "Сетевые адаптеры", content:

Сетевые адаптеры

Описание сетевых адаптеров сервера резервного копирования.

}, + copy_software_1: { title: "ПО", content:

Программное обеспечение сервера резервного копирования

Описание ПО сервера резервного копирования.

}, + copy_software_2: { title: "ПО", content:

Программное обеспечение сервера резервного копирования

Описание ПО сервера резервного копирования.

}, + copy_software_3: { title: "ПО", content:

Программное обеспечение сервера резервного копирования

Описание ПО сервера резервного копирования.

}, + copy_software_4: { title: "ПО", content:

Программное обеспечение сервера резервного копирования

Описание ПО сервера резервного копирования.

}, + + // Сервер системы управления + control_system_software_1: { title: "Центральный процессор", content:

Центральный процессор

Описание центрального процессора сервера системы управления.

}, + control_system_software_2: { title: "Оперативная память", content:

Оперативная память

Описание оперативной памяти сервера системы управления.

}, + control_system_software_3: { title: "Жесткий диск", content:

Жесткий диск

Описание жесткого диска сервера системы управления.

}, + control_system_software_4: { title: "Сетевые адаптеры", content:

Сетевые адаптеры

Описание сетевых адаптеров сервера системы управления.

}, + control_software_1: { title: "ПО", content:

Программное обеспечение сервера системы управления

Описание ПО сервера системы управления.

}, + control_software_2: { title: "ПО", content:

Программное обеспечение сервера системы управления

Описание ПО сервера системы управления.

}, + control_software_3: { title: "ПО", content:

Программное обеспечение сервера системы управления

Описание ПО сервера системы управления.

}, + control_software_4: { title: "ПО", content:

Программное обеспечение сервера системы управления

Описание ПО сервера системы управления.

}, + + // Сервер сбора и ретрансляции информации + system_software_1: { title: "Центральный процессор", content:

Центральный процессор

Описание центрального процессора сервера сбора и ретрансляции информации.

}, + system_software_2: { title: "Оперативная память", content:

Оперативная память

Описание оперативной памяти сервера сбора и ретрансляции информации.

}, + system_software_3: { title: "Жесткий диск", content:

Жесткий диск

Описание жесткого диска сервера сбора и ретрансляции информации.

}, + system_software_4: { title: "Сетевые адаптеры", content:

Сетевые адаптеры

Описание сетевых адаптеров сервера сбора и ретрансляции информации.

}, + software_1: { title: "ПО", content:

Программное обеспечение сервера сбора и ретрансляции информации

Описание ПО сервера сбора и ретрансляции информации.

}, + software_2: { title: "ПО", content:

Программное обеспечение сервера сбора и ретрансляции информации

Описание ПО сервера сбора и ретрансляции информации.

}, + software_3: { title: "ПО", content:

Программное обеспечение сервера сбора и ретрансляции информации

Описание ПО сервера сбора и ретрансляции информации.

}, + software_4: { title: "ПО", content:

Программное обеспечение сервера сбора и ретрансляции информации

Описание ПО сервера сбора и ретрансляции информации.

}, +}; + +export default tabContent; \ No newline at end of file diff --git a/src/Components/TreeChart/tabContent3.jsx b/src/Components/TreeChart/tabContent3.jsx deleted file mode 100644 index 4124a32..0000000 --- a/src/Components/TreeChart/tabContent3.jsx +++ /dev/null @@ -1,31 +0,0 @@ -import React from "react"; -import NetworkSpeedChart2 from '../../Charts/TestCharts2'; -import PrometheusChart from '../../Charts/PrometheusChart'; -import PrometheusChart2 from '../../Charts/PrometheusChart2'; - -const tabContent = { - service1: { title: "Сервис ВКС", content:

Сервис ВКС

}, - system_control: { title: "Контроль системы", content:

Контроль системы

Описание контроля.

}, - system_management: { title: "Система управления", content:

Система управления

Описание системы управления.

}, - conference: { title: "Проведение ВКС", content:

Проведение ВКС

Информация о проведении ВКС.

}, - backup: { title: "Резервное копирование", content:

Резервное копирование

Процесс резервного копирования.

}, - relay_info: { title: "Ретрансляция информации", content:

Ретрансляция информации

Детали ретрансляции.

}, - hardware_software_1: { title: "Сервер системы управления", content:

Сервер системы управления

}, - hardware_software_2: { title: "Сервер системы управления", content:

Сервер системы управления

}, - hardware_software_3: { title: "Медиа-сервер", content:

Медиа-сервер

}, - hardware_software_4: { title: "Медиа-сервер", content:

Медиа-сервер

}, - hardware_software_5: { title: "Медиа-сервер", content:

Медиа-сервер

}, - hardware_software_6: { title: "Медиа-сервер", content:

Медиа-сервер

}, - hardware_software_7: { title: "Сервер резервного копирования", content:

Сервер резервного копирования

}, - hardware_software_8: { title: "Сервер сбора и ретрансляции информации", content:

Сервер сбора и ретрансляции информации

}, - software_1: { title: "БП/ППО", content:

БП/ППО

}, - software_2: { title: "БП/ППО", content:

БП/ППО

}, - software_3: { title: "БП/ППО", content:

БП/ППО

}, - software_4: { title: "БП/ППО", content:

БП/ППО

}, - software_5: { title: "БП/ППО", content:

БП/ППО

}, - software_6: { title: "БП/ППО", content:

БП/ППО

}, - software_7: { title: "БП/ППО", content:

БП/ППО

}, - software_8: { title: "БП/ППО", content:

БП/ППО

}, -}; - -export default tabContent; \ No newline at end of file diff --git a/src/Components/UI/Tabs.jsx b/src/Components/UI/Tabs.jsx index c8c18bb..78ec099 100644 --- a/src/Components/UI/Tabs.jsx +++ b/src/Components/UI/Tabs.jsx @@ -9,6 +9,7 @@ const Tabs = ({ tabs, activeTab, onTabClick, onCloseTab }) => { onCloseTab(id); // Закрываем вкладку } }; + return (
diff --git a/src/Components/UI/TreeTable.jsx b/src/Components/UI/TreeTable.jsx index 9f392d4..8a4618e 100644 --- a/src/Components/UI/TreeTable.jsx +++ b/src/Components/UI/TreeTable.jsx @@ -34,7 +34,7 @@ const TreeTable = ({ data }) => { {/* Третий уровень: Вложенные элементы "АО" и "ПО" */} - {/*renderRows(filteredData)*/} + {renderRows(filteredData)}
diff --git a/src/Style/Dashboard.css b/src/Style/Dashboard.css index d1f7b33..537a8ca 100644 --- a/src/Style/Dashboard.css +++ b/src/Style/Dashboard.css @@ -2,7 +2,7 @@ .dashboard-container { display: flex; height: 100vh; - width: 98vw; + width: calc(100vw - 20px); /* Учитываем отступ */ overflow: hidden; margin-left: 20px; } @@ -50,7 +50,7 @@ padding: 20px; margin-left: 50px; transition: margin-left 0.2s ease; - /* Плавное изменение отступа */ + overflow: auto; /* Позволяет прокручивать контент, если он не влезает */ } /* Контент */ @@ -59,6 +59,8 @@ padding: 20px; border-radius: 10px; box-shadow: 0 2px 5px rgba(29, 1, 1, 0.521); + max-width: 100%; /* Гарантируем, что контент не выйдет за границы */ + overflow: auto; /* Включаем скролл, если нужно */ } /* Заголовки */ diff --git a/src/Style/DatePicker.css b/src/Style/DatePicker.css new file mode 100644 index 0000000..94a43f5 --- /dev/null +++ b/src/Style/DatePicker.css @@ -0,0 +1,60 @@ +.react-datepicker-wrapper { + width: 100%; +} + +.react-datepicker { + position: absolute !important; + z-index: 1000 !important; + width: auto; + max-width: 300px; + background-color: white; + border: 1px solid #ccc; + border-radius: 4px; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); +} + +.react-datepicker__header { + background-color: #f0f0f0; + border-bottom: 1px solid #ccc; + border-radius: 4px 4px 0 0; + padding: 8px; +} + +.react-datepicker__current-month { + font-size: 1.1em; + font-weight: bold; +} + +.react-datepicker__day { + padding: 5px; + margin: 2px; + border-radius: 4px; +} + +.react-datepicker__day--selected, +.react-datepicker__day--keyboard-selected { + background-color: #3e95cd; + color: white; +} + +.react-datepicker__day:hover { + background-color: #f0f0f0; +} + +.react-datepicker__navigation { + top: 10px; +} + +.react-datepicker__navigation--previous { + border-right-color: #333; +} + +.react-datepicker__navigation--next { + border-left-color: #333; +} + +/* Исправление странного появления в центре экрана */ +.react-datepicker-popper { + z-index: 9999 !important; + transform: translate3d(0px, 0px, 0px) !important; +} diff --git a/src/index.css b/src/index.css index 5a6ad3e..6c94c43 100755 --- a/src/index.css +++ b/src/index.css @@ -71,4 +71,28 @@ button:focus-visible { button { background-color: #f9f9f9; } +} + +/* Глобальный стиль для WebKit-браузеров (Chrome, Edge, Safari) */ +::-webkit-scrollbar { + width: 10px; /* Толщина вертикального скролла */ + height: 10px; /* Толщина горизонтального скролла */ +} + +/* Фон скроллбара */ +::-webkit-scrollbar-track { + background: #f1f1f1; /* Цвет фона */ + border-radius: 10px; /* Скругление углов */ +} + +/* Ползунок */ +::-webkit-scrollbar-thumb { + background: #3d74c7; /* Основной цвет */ + border-radius: 10px; /* Скругляем края */ + border: 1px solid #1c36c9; /* Белая обводка */ +} + +/* Эффект при наведении */ +::-webkit-scrollbar-thumb:hover { + background: #2b5aa5; /* Чуть темнее при наведении */ } \ No newline at end of file