60, 'itemWidth' => 100, 'itemHeight' => 80, 'colorStops' => [ ['offset' => 0, 'color' => '#ef4444', 'name' => '薄弱'], ['offset' => 0.5, 'color' => '#f59e0b', 'name' => '一般'], ['offset' => 0.7, 'color' => '#10b981', 'name' => '良好'], ['offset' => 1, 'color' => '#3b82f6', 'name' => '掌握'], ] ]; public function mount(string $studentId): void { $this->studentId = $studentId; $this->loadHeatmapData(); } public function loadHeatmapData(): void { $this->isLoading = true; $this->errorMessage = ''; try { $service = new LearningAnalyticsService(); $masteryList = $service->getStudentMasteryList($this->studentId); if ($masteryList && isset($masteryList['data'])) { $this->heatmapData = $this->processHeatmapData($masteryList['data']); } else { $this->heatmapData = []; } } catch (\Exception $e) { $this->errorMessage = '加载热力图数据失败:' . $e->getMessage(); $this->heatmapData = []; } finally { $this->isLoading = false; } } /** * 处理热力图数据 */ private function processHeatmapData(array $masteryList): array { $processedData = []; $categories = []; // 知识分类 foreach ($masteryList as $mastery) { $kpCode = $mastery['kp_code']; $masteryLevel = $mastery['mastery_level']; $trend = $mastery['mastery_trend']; // 根据知识点编码提取分类 $category = $this->extractCategory($kpCode); if (!in_array($category, $categories)) { $categories[] = $category; } // 确定颜色 $color = $this->getMasteryColor($masteryLevel); $borderColor = $this->getTrendColor($trend); $processedData[] = [ 'kp_code' => $kpCode, 'category' => $category, 'mastery_level' => $masteryLevel, 'accuracy_rate' => $mastery['accuracy_rate'], 'total_attempts' => $mastery['total_attempts'], 'trend' => $trend, 'color' => $color, 'border_color' => $borderColor, 'text_color' => $masteryLevel > 0.5 ? '#ffffff' : '#000000', ]; } // 按分类排序 usort($categories, fn($a, $b) => $a <=> $b); return [ 'data' => $processedData, 'categories' => $categories, ]; } /** * 根据知识点编码提取分类 */ private function extractCategory(string $kpCode): string { // 简单的分类逻辑,实际应根据知识点体系进行分类 if (strpos($kpCode, 'KP') === 0) { $number = (int) substr($kpCode, 2); if ($number >= 100 && $number < 200) { return '基础概念'; } elseif ($number >= 200 && $number < 300) { return '基础技能'; } elseif ($number >= 300 && $number < 400) { return '综合应用'; } elseif ($number >= 400 && $number < 500) { return '高级技巧'; } else { return '其他'; } } return '未分类'; } /** * 根据掌握度获取颜色 */ private function getMasteryColor(float $masteryLevel): string { if ($masteryLevel < 0.3) { return '#ef4444'; // 红色 - 薄弱 } elseif ($masteryLevel < 0.5) { return '#f97316'; // 橙色 - 需要改进 } elseif ($masteryLevel < 0.7) { return '#eab308'; // 黄色 - 一般 } elseif ($masteryLevel < 0.85) { return '#22c55e'; // 绿色 - 良好 } else { return '#3b82f6'; // 蓝色 - 掌握 } } /** * 根据趋势获取边框颜色 */ private function getTrendColor(string $trend): string { return match ($trend) { 'improving' => '#10b981', // 绿色上升箭头 'stable' => '#6b7280', // 灰色横线 'declining' => '#ef4444', // 红色下降箭头 'insufficient' => '#d1d5db', // 灰色虚线 default => '#9ca3af', }; } /** * 获取掌握度等级名称 */ public function getMasteryLevelName(float $masteryLevel): string { if ($masteryLevel < 0.3) { return '薄弱'; } elseif ($masteryLevel < 0.5) { return '入门'; } elseif ($masteryLevel < 0.7) { return '进阶'; } elseif ($masteryLevel < 0.85) { return '熟练'; } else { return '精通'; } } /** * 获取趋势图标 */ public function getTrendIcon(string $trend): string { return match ($trend) { 'improving' => '↗', 'stable' => '→', 'declining' => '↘', 'insufficient' => '⋯', default => '?', }; } public function render() { return view('livewire.mastery-heatmap'); } }