90 lines
3.2 KiB
JavaScript
Executable File
90 lines
3.2 KiB
JavaScript
Executable File
import React, { useState } from 'react';
|
|
import { LineChart, XAxis, YAxis, CartesianGrid, Tooltip, Legend, Line, ResponsiveContainer } from 'recharts';
|
|
|
|
const LineChartComponent = ({ chartData, metricName, colors, description, onRangeSelect, filteredData }) => {
|
|
const [selectionStart, setSelectionStart] = useState(null);
|
|
const [selectionEnd, setSelectionEnd] = useState(null);
|
|
|
|
// Создаем массив уникальных временных меток
|
|
const allTimes = Object.values(chartData)
|
|
.flat()
|
|
.map(point => point.time)
|
|
.filter((time, index, self) => self.indexOf(time) === index);
|
|
|
|
// Формируем данные для графика
|
|
const data = allTimes.map(time => {
|
|
const point = { time };
|
|
Object.keys(chartData).forEach(key => {
|
|
const instanceData = chartData[key].find(p => p.time === time);
|
|
point[key] = instanceData ? instanceData.value : null;
|
|
});
|
|
return point;
|
|
});
|
|
|
|
// Используем отфильтрованные данные, если они есть
|
|
const displayData = filteredData || data;
|
|
|
|
// Обработчик клика на графике
|
|
const handleClick = (e) => {
|
|
if (!e || !e.activeLabel) return;
|
|
|
|
const clickedTime = e.activeLabel;
|
|
|
|
if (!selectionStart) {
|
|
setSelectionStart(clickedTime);
|
|
} else if (!selectionEnd) {
|
|
setSelectionEnd(clickedTime);
|
|
|
|
const startIndex = data.findIndex(point => point.time === selectionStart);
|
|
const endIndex = data.findIndex(point => point.time === clickedTime);
|
|
|
|
onRangeSelect({ startIndex, endIndex });
|
|
|
|
setSelectionStart(null);
|
|
setSelectionEnd(null);
|
|
}
|
|
};
|
|
|
|
// Кастомный Tooltip для отображения значения
|
|
const CustomTooltip = ({ active, payload, label }) => {
|
|
if (active && payload && payload.length) {
|
|
return (
|
|
<div className="custom-tooltip" style={{ padding: '10px' }}>
|
|
<p>{`Время: ${label}`}</p>
|
|
{payload.map((entry, index) => (
|
|
<p key={index} style={{}}>
|
|
{`Значение: ${entry.value}`}
|
|
</p>
|
|
))}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return null;
|
|
};
|
|
|
|
return (
|
|
<div>
|
|
<ResponsiveContainer width="100%" height={400}>
|
|
<LineChart data={displayData} onClick={handleClick}>
|
|
<CartesianGrid strokeDasharray="3 3" />
|
|
<XAxis dataKey="time" />
|
|
<YAxis />
|
|
<Tooltip content={<CustomTooltip />} />
|
|
<Legend />
|
|
{Object.keys(chartData).map((key, index) => (
|
|
<Line
|
|
key={key}
|
|
type="monotone"
|
|
dataKey={key}
|
|
stroke={colors[index % colors.length]}
|
|
name={key}
|
|
/>
|
|
))}
|
|
</LineChart>
|
|
</ResponsiveContainer>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default LineChartComponent; |