import tkinter as tk
from tkinter import ttk, messagebox
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

# 设置中文字体（解决中文乱码）
plt.rcParams["font.family"] = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC"]
plt.rcParams["axes.unicode_minus"] = False  # 解决负号显示问题

# 创建主窗口
root = tk.Tk()
root.title("📊 成绩走势图生成器")
root.geometry("900x650")  # 窗口大小

# 存储成绩和科目
subjects = []
scores = []

# ---------------------- 界面函数 ----------------------
def add_score():
    """添加科目和成绩"""
    subject = entry_subject.get().strip()
    score = entry_score.get().strip()
    
    if not subject or not score:
        messagebox.showwarning("提示", "请输入完整的科目和成绩！")
        return
    
    try:
        score = float(score)
        if 0 <= score <= 100:
            subjects.append(subject)
            scores.append(score)
            list_box.insert(tk.END, f"{subject}：{score} 分")
            entry_subject.delete(0, tk.END)
            entry_score.delete(0, tk.END)
        else:
            messagebox.showerror("错误", "成绩必须在 0~100 之间！")
    except ValueError:
        messagebox.showerror("错误", "成绩必须是数字！")

def draw_chart():
    """绘制成绩走势图"""
    if not subjects or not scores:
        messagebox.showwarning("提示", "请先添加成绩数据！")
        return
    
    # 清空画布
    for widget in frame_chart.winfo_children():
        widget.destroy()
    
    # 创建图表
    fig, ax = plt.subplots(figsize=(8, 4), dpi=100)
    
    # 绘制折线+标记点
    ax.plot(subjects, scores, marker='o', linewidth=2, markersize=8, 
            color='#2E86AB', markerfacecolor='#A23B72', label='成绩')
    
    # 图表样式
    ax.set_title('📈 个人成绩走势图', fontsize=16, fontweight='bold', pad=20)
    ax.set_xlabel('考试科目', fontsize=12)
    ax.set_ylabel('成绩（分）', fontsize=12)
    ax.grid(True, alpha=0.3)
    ax.set_ylim(0, 105)  # 成绩范围 0~105

    # ====================== 关键修改 ======================
    # 每个成绩左右间距固定 30 像素
    ax.figure.set_layout_engine('tight')
    ax.set_position([0.1, 0.15, 0.85, 0.75])
    ax.axes.set_xticks(range(len(subjects)))
    ax.axes.set_xticklabels(subjects)
    ax.figure.canvas.draw()
    # 强制每个点间距 30 像素
    ax.spines['left'].set_position(('outward', 30))
    ax.tick_params(axis='x', pad=10)
    plt.setp(ax.get_xticklabels(), ha="center")
    ax.figure.tight_layout(pad=3.0)
    # ======================================================
    
    # 标注每个点的分数
    for i, score in enumerate(scores):
        ax.annotate(f'{score}', (subjects[i], score), 
                    textcoords="offset points", xytext=(0,10), ha='center', fontsize=10)
    
    # 统计信息
    max_score = max(scores)
    min_score = min(scores)
    avg_score = round(sum(scores)/len(scores), 1)
    stats = f'最高分：{max_score}  |  最低分：{min_score}  |  平均分：{avg_score}'
    ax.text(0.5, -0.15, stats, transform=ax.transAxes, ha='center', fontsize=11, bbox=dict(boxstyle="round,pad=0.3", facecolor='lightblue'))
    
    # 将图表嵌入 tkinter 窗口
    canvas = FigureCanvasTkAgg(fig, master=frame_chart)
    canvas.draw()
    canvas.get_tk_widget().pack()

def clear_all():
    """清空所有数据"""
    subjects.clear()
    scores.clear()
    list_box.delete(0, tk.END)
    for widget in frame_chart.winfo_children():
        widget.destroy()
    entry_subject.focus()

# ---------------------- 界面布局 ----------------------
# 输入区域
frame_input = ttk.LabelFrame(root, text="添加成绩")
frame_input.pack(padx=10, pady=5, fill='x')

ttk.Label(frame_input, text="科目：").grid(row=0, column=0, padx=5, pady=5)
entry_subject = ttk.Entry(frame_input, width=15)
entry_subject.grid(row=0, column=1, padx=5, pady=5)

ttk.Label(frame_input, text="成绩：").grid(row=0, column=2, padx=5, pady=5)
entry_score = ttk.Entry(frame_input, width=15)
entry_score.grid(row=0, column=3, padx=5, pady=5)

btn_add = ttk.Button(frame_input, text="添加", command=add_score)
btn_add.grid(row=0, column=4, padx=5, pady=5)

# 数据列表
frame_list = ttk.LabelFrame(root, text="已添加成绩")
frame_list.pack(padx=10, pady=5, fill='both', expand=True)
list_box = tk.Listbox(frame_list, font=('SimHei', 11))
list_box.pack(padx=5, pady=5, fill='both', expand=True)

# 按钮区域
frame_btns = ttk.Frame(root)
frame_btns.pack(padx=10, pady=5)
btn_draw = ttk.Button(frame_btns, text="📊 生成走势图", command=draw_chart)
btn_draw.grid(row=0, column=0, padx=10)
btn_clear = ttk.Button(frame_btns, text="🗑️ 清空数据", command=clear_all)
btn_clear.grid(row=0, column=1, padx=10)

# 图表区域
frame_chart = ttk.LabelFrame(root, text="成绩走势图")
frame_chart.pack(padx=10, pady=5, fill='both', expand=True)

# 启动窗口
root.mainloop()