добавлен фильтр количеста вывода записей на странице История тревог

This commit is contained in:
2026-02-03 21:46:20 +03:00
parent 5e58f6ef76
commit 79e4845870
10 changed files with 1209 additions and 89 deletions

View File

@@ -3,7 +3,8 @@
import React from 'react'
interface ChartDataPoint {
value: number
critical?: number
warning?: number
label?: string
timestamp?: string
}
@@ -23,19 +24,30 @@ const AreaChart: React.FC<AreaChartProps> = ({ className = '', data }) => {
const safeData = (Array.isArray(data) && data.length > 0)
? data
: Array.from({ length: 7 }, () => ({ value: 0 }))
: Array.from({ length: 7 }, () => ({ critical: 0, warning: 0 }))
const maxVal = Math.max(...safeData.map(d => d.value || 0), 1)
const maxVal = Math.max(...safeData.map(d => Math.max(d.critical || 0, d.warning || 0)), 1)
const stepX = safeData.length > 1 ? plotWidth / (safeData.length - 1) : plotWidth
const points = safeData.map((d, i) => {
// Точки для критических событий (красная линия)
const criticalPoints = safeData.map((d, i) => {
const x = margin.left + i * stepX
const y = baselineY - (Math.min(d.value || 0, maxVal) / maxVal) * plotHeight
const y = baselineY - (Math.min(d.critical || 0, maxVal) / maxVal) * plotHeight
return { x, y }
})
const linePath = points.map((p, i) => `${i === 0 ? 'M' : 'L'}${p.x},${p.y}`).join(' ')
const areaPath = `${linePath} L${width - margin.right},${baselineY} L${margin.left},${baselineY} Z`
// Точки для предупреждений (оранжевая линия)
const warningPoints = safeData.map((d, i) => {
const x = margin.left + i * stepX
const y = baselineY - (Math.min(d.warning || 0, maxVal) / maxVal) * plotHeight
return { x, y }
})
const criticalLinePath = criticalPoints.map((p, i) => `${i === 0 ? 'M' : 'L'}${p.x},${p.y}`).join(' ')
const criticalAreaPath = `${criticalLinePath} L${width - margin.right},${baselineY} L${margin.left},${baselineY} Z`
const warningLinePath = warningPoints.map((p, i) => `${i === 0 ? 'M' : 'L'}${p.x},${p.y}`).join(' ')
const warningAreaPath = `${warningLinePath} L${width - margin.right},${baselineY} L${margin.left},${baselineY} Z`
// Генерируем Y-оси метки
const ySteps = 4
@@ -59,9 +71,13 @@ const AreaChart: React.FC<AreaChartProps> = ({ className = '', data }) => {
<div className={`w-full h-full ${className}`}>
<svg className="w-full h-full" viewBox={`0 0 ${width} ${height}`}>
<defs>
<linearGradient id="areaGradient" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stopColor="rgb(37, 99, 235)" stopOpacity="0.3" />
<stop offset="100%" stopColor="rgb(37, 99, 235)" stopOpacity="0" />
<linearGradient id="criticalGradient" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stopColor="#ef4444" stopOpacity="0.3" />
<stop offset="100%" stopColor="#ef4444" stopOpacity="0" />
</linearGradient>
<linearGradient id="warningGradient" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stopColor="#fb923c" stopOpacity="0.3" />
<stop offset="100%" stopColor="#fb923c" stopOpacity="0" />
</linearGradient>
</defs>
@@ -157,7 +173,7 @@ const AreaChart: React.FC<AreaChartProps> = ({ className = '', data }) => {
fontFamily="Arial, sans-serif"
transform={`rotate(-90, 20, ${margin.top + plotHeight / 2})`}
>
Значение
Количество
</text>
{/* Подпись оси X */}
@@ -172,22 +188,52 @@ const AreaChart: React.FC<AreaChartProps> = ({ className = '', data }) => {
Время
</text>
{/* График */}
<path d={areaPath} fill="url(#areaGradient)" />
<path d={linePath} stroke="rgb(37, 99, 235)" strokeWidth="2.5" fill="none" />
{/* График предупреждений (оранжевый) - рисуем первым чтобы был на заднем плане */}
<path d={warningAreaPath} fill="url(#warningGradient)" />
<path d={warningLinePath} stroke="#fb923c" strokeWidth="2.5" fill="none" />
{/* Точки данных */}
{points.map((p, i) => (
{/* Точки данных для предупреждений */}
{warningPoints.map((p, i) => (
<circle
key={i}
key={`warning-${i}`}
cx={p.x}
cy={p.y}
r="4"
fill="rgb(37, 99, 235)"
fill="#fb923c"
stroke="rgb(15, 23, 42)"
strokeWidth="2"
/>
))}
{/* График критических событий (красный) - рисуем поверх */}
<path d={criticalAreaPath} fill="url(#criticalGradient)" />
<path d={criticalLinePath} stroke="#ef4444" strokeWidth="2.5" fill="none" />
{/* Точки данных для критических */}
{criticalPoints.map((p, i) => (
<circle
key={`critical-${i}`}
cx={p.x}
cy={p.y}
r="4"
fill="#ef4444"
stroke="rgb(15, 23, 42)"
strokeWidth="2"
/>
))}
{/* Легенда */}
<g transform={`translate(${width - margin.right - 120}, ${margin.top})`}>
<circle cx="6" cy="6" r="4" fill="#ef4444" stroke="rgb(15, 23, 42)" strokeWidth="2" />
<text x="18" y="10" fontSize="11" fill="rgb(148, 163, 184)" fontFamily="Arial, sans-serif">
Критические
</text>
<circle cx="6" cy="24" r="4" fill="#fb923c" stroke="rgb(15, 23, 42)" strokeWidth="2" />
<text x="18" y="28" fontSize="11" fill="rgb(148, 163, 184)" fontFamily="Arial, sans-serif">
Предупреждения
</text>
</g>
</svg>
</div>
)