'use client' import React from 'react' interface ChartDataPoint { value: number label?: string color?: string } interface BarChartProps { className?: string data?: ChartDataPoint[] } const BarChart: React.FC = ({ className = '', data }) => { const width = 635 const height = 280 const margin = { top: 20, right: 30, bottom: 50, left: 60 } const plotWidth = width - margin.left - margin.right const plotHeight = height - margin.top - margin.bottom const baselineY = margin.top + plotHeight const barData = (Array.isArray(data) && data.length > 0) ? data.map(d => ({ value: d.value, label: d.label || '', color: d.color || 'rgb(37, 99, 235)' })) : Array.from({ length: 12 }, (_, i) => ({ value: 0, label: `${i + 1}`, color: 'rgb(37, 99, 235)' })) const maxVal = Math.max(...barData.map(b => b.value || 0), 1) // Генерируем Y-оси метки const ySteps = 4 const yLabels = Array.from({ length: ySteps + 1 }, (_, i) => { const value = (maxVal / ySteps) * (ySteps - i) const y = margin.top + (i * plotHeight) / ySteps return { value: value.toFixed(1), y } }) // Генерируем X-оси метки (показываем каждую 2-ю или 3-ю) const xLabelStep = Math.ceil(barData.length / 8) const xLabels = barData .map((d, i) => { const barWidth = Math.max(30, plotWidth / barData.length - 8) const barSpacing = (plotWidth - barWidth * barData.length) / (barData.length - 1 || 1) const x = margin.left + i * (barWidth + barSpacing) + barWidth / 2 return { label: d.label || `${i + 1}`, x, index: i } }) .filter((_, i) => i % xLabelStep === 0 || i === barData.length - 1) return (
{/* Сетка Y */} {yLabels.map((label, i) => ( ))} {/* Ось X */} {/* Ось Y */} {/* Y-оси метки и подписи */} {yLabels.map((label, i) => ( {label.value} ))} {/* X-оси метки и подписи */} {xLabels.map((label, i) => ( {typeof label.label === 'string' ? label.label.substring(0, 8) : `${label.index + 1}`} ))} {/* Подпись оси Y */} Значение {/* Подпись оси X */} Период {/* Столбцы */} {barData.map((bar, index) => { const barWidth = Math.max(30, plotWidth / barData.length - 8) const barSpacing = (plotWidth - barWidth * barData.length) / (barData.length - 1 || 1) const x = margin.left + index * (barWidth + barSpacing) const barHeight = (bar.value / maxVal) * plotHeight const y = baselineY - barHeight return ( {/* Тень для глубины */} ) })}
) } export default BarChart