import React from 'react' import { Chart as ChartJS, CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend, Filler } from 'chart.js' import { Line } from 'react-chartjs-2' import WeekProgressChart from './WeekProgressChart' import { getAllProjectsSorted, getProjectColor, sortProjectsLikeCurrentWeek } from '../utils/projectUtils' // Экспортируем для обратной совместимости (если используется в других местах) export { getProjectColorByIndex } from '../utils/projectUtils' const parseWeekKey = (weekKey) => { const [yearStr, weekStr] = weekKey.split('-W') return { year: Number(yearStr), week: Number(weekStr) } } const compareWeekKeys = (a, b) => { const [yearA, weekA] = a.split('-W').map(Number) const [yearB, weekB] = b.split('-W').map(Number) if (yearA !== yearB) { return yearA - yearB } return weekA - weekB } ChartJS.register( CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend, Filler ) function FullStatistics({ selectedProject, onClearSelection, data, loading, error, onRetry, currentWeekData, onNavigate }) { const processData = () => { if (!data || data.length === 0) return null // Группируем данные по проектам const projectsMap = {} data.forEach(item => { const projectName = item.project_name const weekKey = `${item.report_year}-W${item.report_week.toString().padStart(2, '0')}` if (!projectsMap[projectName]) { projectsMap[projectName] = {} } projectsMap[projectName][weekKey] = parseFloat(item.total_score) }) // Собираем все уникальные недели и сортируем их по году и неделе const allWeeks = new Set() Object.values(projectsMap).forEach(weeks => { Object.keys(weeks).forEach(week => allWeeks.add(week)) }) const sortedWeeks = Array.from(allWeeks).sort(compareWeekKeys) // Получаем отсортированный список всех проектов для синхронизации цветов const allProjectNames = getAllProjectsSorted(data) // Фильтруем по выбранному проекту, если он указан let projectNames = allProjectNames.filter(name => projectsMap[name]) // Сортируем проекты так же, как на экране списка проектов (по priority и min_goal_score) if (currentWeekData) { projectNames = sortProjectsLikeCurrentWeek(projectNames, currentWeekData) } if (selectedProject) { projectNames = projectNames.filter(name => name === selectedProject) } const datasets = projectNames.map((projectName) => { let cumulativeSum = 0 const values = sortedWeeks.map(week => { const score = projectsMap[projectName]?.[week] || 0 cumulativeSum += score return cumulativeSum }) // Генерируем цвет для линии на основе индекса в полном списке проектов const color = getProjectColor(projectName, allProjectNames) return { label: projectName, data: values, borderColor: color, backgroundColor: color.replace('50%)', '20%)'), fill: false, tension: 0.4, pointRadius: 4, pointHoverRadius: 6, } }) return { labels: sortedWeeks, datasets: datasets, } } const chartData = processData() // Показываем loading только если данных нет и идет загрузка if (loading && !chartData) { return (