diff --git a/src/Charts/Components/LineChartComponent.jsx b/src/Charts/Components/LineChartComponent.jsx
index f607307..37d76da 100644
--- a/src/Charts/Components/LineChartComponent.jsx
+++ b/src/Charts/Components/LineChartComponent.jsx
@@ -1,5 +1,5 @@
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, description }) => {
// Создаем массив уникальных временных меток
@@ -55,6 +55,13 @@ const LineChartComponent = ({ chartData, metricName, metricType, colors, descrip
name={key}
/>
))}
+
diff --git a/src/Charts/PrometheusChart.jsx b/src/Charts/PrometheusChart.jsx
index 159afba..d91f9cc 100644
--- a/src/Charts/PrometheusChart.jsx
+++ b/src/Charts/PrometheusChart.jsx
@@ -1,5 +1,7 @@
import React, { useEffect, useState, useRef } from 'react';
import axios from 'axios';
+import DatePicker from 'react-datepicker';
+import 'react-datepicker/dist/react-datepicker.css';
import LineChartComponent from './Components/LineChartComponent';
const MAX_POINTS = 20; // Ограничение точек на графике
@@ -29,23 +31,37 @@ const PrometheusChart = ({ metricName }) => {
const [metricType, setMetricType] = useState('');
const [metricDescription, setMetricDescription] = useState('');
const [selectedRange, setSelectedRange] = useState(TIME_RANGES[0]); // По умолчанию 1 минута
+ const [startDate, setStartDate] = useState(new Date()); // Начальная дата для кастомного диапазона
+ const [endDate, setEndDate] = useState(new Date()); // Конечная дата для кастомного диапазона
+ const [useCustomRange, setUseCustomRange] = useState(false); // Флаг для выбора кастомного диапазона
+ const [brushRange, setBrushRange] = useState({ startIndex: 0, endIndex: 0 }); // Состояние Brush
const intervalRef = useRef(null);
const fetchData = async () => {
try {
- const end = Math.floor(Date.now() / 1000);
- const start = end - selectedRange.value;
+ let start, end;
+
+ if (useCustomRange) {
+ // Используем кастомный диапазон
+ start = Math.floor(startDate.getTime() / 1000);
+ end = Math.floor(endDate.getTime() / 1000);
+ } else {
+ // Используем предустановленный диапазон
+ end = Math.floor(Date.now() / 1000);
+ start = end - selectedRange.value;
+ }
// Динамический шаг (чем больше диапазон, тем больше шаг)
let step;
- if (selectedRange.value <= 3600) step = 5; // 1 час и меньше → 5 сек
- else if (selectedRange.value <= 21600) step = 30; // 1-6 часов → 30 сек
- else if (selectedRange.value <= 86400) step = 120; // 6-24 часа → 2 минуты
- else step = 300; // > 24 часов → 5 минут
+ const range = end - start;
+ if (range <= 3600) step = 5; // 1 час и меньше → 5 сек
+ else if (range <= 21600) step = 30; // 1-6 часов → 30 сек
+ else if (range <= 86400) step = 120; // 6-24 часа → 2 минуты
+ else step = 300; // > 24 часов → 5 минут
console.log(`Запрашиваем данные с шагом ${step} сек`);
- const response = await axios.get(`http://192.168.2.39:3000/metrics`, {
+ const response = await axios.get('http://192.168.2.39:3000/metrics', {
params: { metric: metricName, start, end, step },
});
@@ -61,7 +77,7 @@ const PrometheusChart = ({ metricName }) => {
const timePoints = [];
for (let t = start; t <= end; t += step) {
const date = new Date(t * 1000);
- const formattedTime = selectedRange.value > 86400
+ const formattedTime = range > 86400
? date.toLocaleString([], { day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit' })
: date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' });
@@ -72,7 +88,7 @@ const PrometheusChart = ({ metricName }) => {
const updatedData = {};
metrics.forEach(m => {
const date = new Date(m.timestamp);
- const formattedTime = selectedRange.value > 86400
+ const formattedTime = range > 86400
? date.toLocaleString([], { day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit' })
: date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' });
@@ -91,12 +107,17 @@ const PrometheusChart = ({ metricName }) => {
});
setChartData(chartData);
+
+ // Устанавливаем Brush на весь диапазон
+ setBrushRange({
+ startIndex: 0,
+ endIndex: timePoints.length - 1,
+ });
} catch (error) {
console.error('Ошибка при загрузке метрик:', error);
}
};
-
useEffect(() => {
fetchData(); // Первоначальная загрузка данных
@@ -109,12 +130,17 @@ const PrometheusChart = ({ metricName }) => {
clearInterval(intervalRef.current); // Очищаем интервал при размонтировании
}
};
- }, [metricName, selectedRange]); // Зависимость от metricName и selectedRange
+ }, [metricName, selectedRange, useCustomRange, startDate, endDate]); // Зависимость от metricName, selectedRange, useCustomRange, startDate и endDate
const handleRangeChange = (event) => {
const selectedValue = event.target.value;
const range = TIME_RANGES.find(range => range.value === parseInt(selectedValue, 10));
setSelectedRange(range);
+ setUseCustomRange(false); // Переключаемся на предустановленный диапазон
+ };
+
+ const handleCustomRangeChange = () => {
+ setUseCustomRange(true); // Переключаемся на кастомный диапазон
};
if (!Object.keys(chartData).length) return
Loading...
;
@@ -129,12 +155,40 @@ const PrometheusChart = ({ metricName }) => {
))}
+
+
+
+
+ setStartDate(date)}
+ showTimeSelect
+ timeFormat="HH:mm"
+ timeIntervals={15}
+ dateFormat="yyyy-MM-dd HH:mm"
+ />
+
+
+
+ setEndDate(date)}
+ showTimeSelect
+ timeFormat="HH:mm"
+ timeIntervals={15}
+ dateFormat="yyyy-MM-dd HH:mm"
+ />
+
+
+
);