diff --git a/src/Charts/Components/LineChartComponent.jsx b/src/Charts/Components/LineChartComponent.jsx
index 53d859f..1973bac 100755
--- a/src/Charts/Components/LineChartComponent.jsx
+++ b/src/Charts/Components/LineChartComponent.jsx
@@ -13,24 +13,33 @@ const LineChartComponent = ({
const chartRef = useRef(null);
const containerRef = useRef(null);
- const allTimes = Object.values(chartData)
+ const allTimestamps = Object.values(chartData)
.flat()
- .map(point => point.time)
- .filter((time, index, self) => self.indexOf(time) === index);
+ .map(point => point.timestamp)
+ .filter((timestamp, index, self) => self.indexOf(timestamp) === index)
+ .sort((a, b) => a - b);
+
+ const data = allTimestamps.map(timestamp => {
+ const point = { timestamp };
+
+ const firstPoint = Object.values(chartData)
+ .flat()
+ .find(p => p.timestamp === timestamp);
+
+ if (firstPoint) {
+ point.time = firstPoint.time;
+ point.fullTime = firstPoint.fullTime;
+ }
- const data = allTimes.map(time => {
- const point = { time };
Object.keys(chartData).forEach(key => {
- const instanceData = chartData[key].find(p => p.time === time);
+ const instanceData = chartData[key].find(p => p.timestamp === timestamp);
point[key] = instanceData ? instanceData.value : null;
});
+
return point;
- }).sort((a, b) => {
- const timeA = chartData[Object.keys(chartData)[0]].find(d => d.time === a.time)?.timestamp;
- const timeB = chartData[Object.keys(chartData)[0]].find(d => d.time === b.time)?.timestamp;
- return timeA - timeB;
});
+
const displayData = filteredData || data;
useEffect(() => {
@@ -47,7 +56,7 @@ const LineChartComponent = ({
const handleMouseDown = (e) => {
if (!e || !e.activeLabel) return;
setIsSelecting(true);
- setSelectionArea({ start: e.activeLabel, end: null });
+ setSelectionArea({ start: e.activeLabel, end: null }); // activeLabel — это timestamp
};
const handleMouseMove = (e) => {
@@ -63,8 +72,8 @@ const LineChartComponent = ({
return;
}
- const startIndex = data.findIndex(point => point.time === selectionArea.start);
- const endIndex = data.findIndex(point => point.time === selectionArea.end);
+ const startIndex = data.findIndex(point => point.timestamp === selectionArea.start);
+ const endIndex = data.findIndex(point => point.timestamp === selectionArea.end);
if (startIndex >= 0 && endIndex >= 0) {
onRangeSelect({
@@ -78,6 +87,9 @@ const LineChartComponent = ({
const CustomTooltip = ({ active, payload, label }) => {
if (active && payload && payload.length) {
+ const currentPoint = data.find(point => point.timestamp === label);
+ const displayTime = currentPoint?.fullTime || new Date(label).toLocaleString();
+
return (
-
{`${label}`}
+
{displayTime}
{payload.map((item, index) => (
{`Значение: ${item.value}`}
@@ -98,6 +110,7 @@ const LineChartComponent = ({
return null;
};
+
if (!data.length) {
return
Нет данных для отображения
;
}
@@ -128,9 +141,21 @@ const LineChartComponent = ({
>
{
+ const point = data.find(p => p.timestamp === timestamp);
+ return point?.fullTime || new Date(timestamp).toLocaleString('ru-RU', {
+ day: '2-digit',
+ month: '2-digit',
+ hour: '2-digit',
+ minute: '2-digit'
+ });
+ }}
/>
+
} />
{Object.keys(chartData).map((instance, index) => (
@@ -152,6 +177,7 @@ const LineChartComponent = ({
fill="#4a6baf"
/>
)}
+
diff --git a/src/Charts/PrometheusChart.jsx b/src/Charts/PrometheusChart.jsx
index ab30858..dce480d 100755
--- a/src/Charts/PrometheusChart.jsx
+++ b/src/Charts/PrometheusChart.jsx
@@ -22,20 +22,21 @@ const PrometheusChart = ({ metricName }) => {
const formatTime = useCallback((timestamp, rangeSeconds) => {
const date = new Date(timestamp);
- if (rangeSeconds > 86400) {
- return {
- display: date.toLocaleString([], {
- day: '2-digit',
- month: '2-digit',
- year: '2-digit',
- hour: '2-digit',
- minute: '2-digit'
- }),
- timestamp: timestamp
- };
- }
+ const showDate = rangeSeconds > 86400; // Показывать дату если диапазон > 24 часов
+
return {
- display: date.toLocaleTimeString([], {
+ display: date.toLocaleString([], {
+
+ month: showDate ? '2-digit' : undefined,
+ day: showDate ? '2-digit' : undefined,
+ hour: '2-digit',
+ minute: '2-digit',
+ second: '2-digit'
+ }),
+ fullDisplay: date.toLocaleString([], {
+
+ month: '2-digit',
+ day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
@@ -53,9 +54,9 @@ const PrometheusChart = ({ metricName }) => {
}, []);
const fetchData = useCallback(() => {
-
+
if (isSelectingRange) return;
-
+
const now = Math.floor(Date.now() / 1000);
const start = now - selectedRange.value;
const end = now;
@@ -70,7 +71,7 @@ const PrometheusChart = ({ metricName }) => {
_t: Date.now()
});
}
- }, [metricName, selectedRange.value, isSelectingRange]);
+ }, [metricName, selectedRange.value, isSelectingRange]);
const groupBySecond = (points) => {
const grouped = [];
@@ -106,10 +107,21 @@ const PrometheusChart = ({ metricName }) => {
const timestamp = item.timestamp > 1e12 ? item.timestamp : item.timestamp * 1000;
const value = parseFloat(item.value);
+ const formattedTime = formatTime(timestamp, selectedRange.value);
- if (!newData[instance].some(p => p.timestamp === timestamp)) {
+ const existingPointIndex = newData[instance].findIndex(p => p.timestamp === timestamp);
+
+ if (existingPointIndex >= 0) {
+ newData[instance][existingPointIndex] = {
+ time: formattedTime.display,
+ fullTime: formattedTime.fullDisplay,
+ value: value,
+ timestamp: timestamp
+ };
+ } else {
newData[instance].push({
- time: formatTime(timestamp, selectedRange.value).display,
+ time: formattedTime.display,
+ fullTime: formattedTime.fullDisplay,
value: value,
timestamp: timestamp
});
@@ -117,7 +129,7 @@ const PrometheusChart = ({ metricName }) => {
});
Object.keys(newData).forEach(instance => {
- newData[instance] = groupBySecond(newData[instance])
+ newData[instance] = newData[instance]
.sort((a, b) => a.timestamp - b.timestamp)
.slice(-1000);
});
@@ -179,7 +191,7 @@ const PrometheusChart = ({ metricName }) => {
const start = Math.floor(startDate.getTime() / 1000);
const end = Math.floor(endDate.getTime() / 1000);
const step = calculateStep(start, end);
-
+
try {
const response = await axios.get(`${import.meta.env.VITE_BACK_URL}/metrics`, {
params: {
@@ -189,7 +201,7 @@ const PrometheusChart = ({ metricName }) => {
step
}
});
-
+
if (response.data) { // Изменили условие, так как бэкенд возвращает массив напрямую
processMetricsData({
metric: metricName,
@@ -209,17 +221,17 @@ const PrometheusChart = ({ metricName }) => {
const handleRangeChange = useCallback((event) => {
const selectedValue = event.target.value;
const range = TIME_RANGES.find(r => r.value === parseInt(selectedValue, 10));
-
+
setSelectedRange(range);
setUseCustomRange(false);
setChartData(null);
setSelectedGraphRange(null);
setFilteredData(null);
-
+
const now = new Date();
setEndDate(now);
setStartDate(new Date(now.getTime() - range.value * 1000));
-
+
// Переподключение сокета при возврате к стандартным диапазонам
if (!socketRef.current?.connected) {
socketRef.current?.connect();
@@ -236,7 +248,7 @@ const PrometheusChart = ({ metricName }) => {
const handleResetZoom = useCallback(() => {
setSelectedGraphRange(null);
setFilteredData(null);
- setIsSelectingRange(false);
+ setIsSelectingRange(false);
fetchData();
}, [fetchData]);
@@ -245,7 +257,7 @@ const PrometheusChart = ({ metricName }) => {
// Начало выделения - останавливаем обновления
setIsSelectingRange(true);
setSelectedGraphRange(range);
-
+
// Отключаем сокет
if (socketRef.current?.connected) {
socketRef.current.disconnect();
@@ -258,7 +270,7 @@ const PrometheusChart = ({ metricName }) => {
} else {
// Окончание выделения - возобновляем соединение
setIsSelectingRange(false);
-
+
if (!useCustomRange && socketRef.current && !socketRef.current.connected) {
socketRef.current.connect();
}
@@ -274,16 +286,8 @@ const PrometheusChart = ({ metricName }) => {
}, [setupWebSocket]);
useEffect(() => {
- if (useCustomRange) {
- if (socketRef.current?.connected) {
- socketRef.current.disconnect();
- }
- fetchCustomRangeData();
- return;
- }
-
- if (!socketRef.current?.connected || isSelectingRange) return;
-
+ if (useCustomRange || isSelectingRange) return;
+
const fetchDataWrapper = () => {
try {
fetchData();
@@ -291,17 +295,22 @@ const PrometheusChart = ({ metricName }) => {
console.error('Error in interval fetch:', error);
}
};
-
+
+ // Очищаем предыдущий интервал
+ if (intervalRef.current) {
+ clearInterval(intervalRef.current);
+ }
+
+ // Запускаем сразу и затем по интервалу
fetchDataWrapper();
intervalRef.current = setInterval(fetchDataWrapper, selectedRange.interval);
-
+
return () => {
if (intervalRef.current) {
clearInterval(intervalRef.current);
- intervalRef.current = null;
}
};
- }, [fetchData, fetchCustomRangeData, selectedRange.interval, useCustomRange, isSelectingRange]);
+ }, [fetchData, selectedRange.interval, useCustomRange, isSelectingRange]);
useEffect(() => {
if (!chartData || !selectedGraphRange) {