| 679 | } |
| 680 | |
| 681 | def calculate_overall_score(evaluation: Dict) -> Dict: |
| 682 | # Visual Structure Alignment scores (0-2 scale) |
| 683 | visual_structure = evaluation.get('visual_structure_alignment', {}) |
| 684 | visual_structure_scores = { |
| 685 | 'chart_type_consistency': visual_structure.get('chart_type_consistency', {}).get('score', 0), |
| 686 | 'spatial_layout_consistency': visual_structure.get('spatial_layout_consistency', {}).get('score', 0), |
| 687 | 'text_element_consistency': visual_structure.get('text_element_consistency', {}).get('score', 0), |
| 688 | 'axis_configuration_consistency': visual_structure.get('axis_configuration_consistency', {}).get('score', 0), |
| 689 | 'color_scheme_consistency': visual_structure.get('color_scheme_consistency', {}).get('score', 0), |
| 690 | 'style_and_format_consistency': visual_structure.get('style_and_format_consistency', {}).get('score', 0), |
| 691 | 'component_completeness': visual_structure.get('component_completeness', {}).get('score', 0) |
| 692 | } |
| 693 | |
| 694 | # Execution Quality scores (0-2 scale) |
| 695 | execution_quality = evaluation.get('execution_quality', {}) |
| 696 | execution_scores = { |
| 697 | 'visual_clarity': execution_quality.get('visual_clarity', {}).get('score', 0), |
| 698 | 'compositional_balance': execution_quality.get('compositional_balance', {}).get('score', 0), |
| 699 | 'data_integrity': execution_quality.get('data_integrity', {}).get('score', 0) |
| 700 | } |
| 701 | |
| 702 | # Data Alignment score (0-2 scale) |
| 703 | data_alignment_score = evaluation.get('data_alignment', {}).get('score', 0) |
| 704 | |
| 705 | # Calculate totals |
| 706 | visual_structure_total = sum(visual_structure_scores.values()) |
| 707 | execution_total = sum(execution_scores.values()) |
| 708 | data_alignment_total = data_alignment_score |
| 709 | |
| 710 | # Overall scoring |
| 711 | total_possible_visual_structure = len(visual_structure_scores) * 2 # 16 points max (0-2 scale) |
| 712 | total_possible_execution = len(execution_scores) * 2 # 6 points max (0-2 scale) |
| 713 | total_possible_data_alignment = 2 # 2 points max (0-2 scale) |
| 714 | |
| 715 | total_score = visual_structure_total + execution_total + data_alignment_total |
| 716 | total_possible = total_possible_visual_structure + total_possible_execution + total_possible_data_alignment |
| 717 | |
| 718 | return { |
| 719 | 'visual_structure_scores': visual_structure_scores, |
| 720 | 'execution_quality_scores': execution_scores, |
| 721 | 'data_alignment_score': data_alignment_score, |
| 722 | 'visual_structure_total': visual_structure_total, |
| 723 | 'visual_structure_max': total_possible_visual_structure, |
| 724 | 'execution_quality_total': execution_total, |
| 725 | 'execution_quality_max': total_possible_execution, |
| 726 | 'data_alignment_total': data_alignment_total, |
| 727 | 'data_alignment_max': total_possible_data_alignment, |
| 728 | 'overall_total_score': total_score, |
| 729 | 'overall_max_score': total_possible, |
| 730 | 'visual_structure_rate': visual_structure_total / total_possible_visual_structure if total_possible_visual_structure > 0 else 0, |
| 731 | 'execution_quality_avg': execution_total / len(execution_scores) if execution_scores else 0, |
| 732 | 'data_alignment_rate': data_alignment_total / total_possible_data_alignment if total_possible_data_alignment > 0 else 0, |
| 733 | 'overall_percentage': total_score / total_possible if total_possible > 0 else 0 |
| 734 | } |
| 735 | |
| 736 | |
| 737 | def save_score_result(task_info: Dict, evaluation: Dict, raw_response: str, plot_file: Path, |