import json from pyecharts import options as opts from pyecharts.charts import Bar, Line from pyecharts.globals import CurrentConfig from Config.Config import ONLINE_HOST CurrentConfig.ONLINE_HOST = ONLINE_HOST class RuYuanZaiYuanModel: @staticmethod def load_student_data(): try: # 加载招生数据(入园人数) with open("./Data/ZhaoShengCount.json", "r", encoding="utf-8") as f: enrollment_data = json.load(f) # 加载在校生数据(在园人数) with open("./Data/ZaiXiaoShengCount.json", "r", encoding="utf-8") as f: in_school_data = json.load(f) return enrollment_data, in_school_data except Exception as e: print(f"读取学生数据出错: {e}") return [], [] @staticmethod def generate_preschool_education_config(): # 获取学前教育相关数据 enrollment_data, in_school_data = RuYuanZaiYuanModel.load_student_data() # 提取云南省级数据 yunnan_enroll = next((item for item in enrollment_data if item["area_name"] == "云南省"), None) if not yunnan_enroll: return {} # 提取年份数据(2015-2024) years = [str(year) for year in range(2015, 2025)] # 构建学前教育数据 urban_data = [] # 城区数据 town_data = [] # 镇区数据 rural_data = [] # 乡村数据 total_enroll = [] # 总入园数 for year in years: enroll_data = yunnan_enroll["education_data"]["preschool"].get(year, {}) urban_data.append(enroll_data.get("urban", 0) / 10000) # 转换为万人 town_data.append(enroll_data.get("town", 0) / 10000) # 转换为万人 rural_data.append(enroll_data.get("rural", 0) / 10000) # 转换为万人 # 计算总和作为总入园数,而非使用文件中的total字段 calculated_total = enroll_data.get("urban", 0) + enroll_data.get("town", 0) + enroll_data.get("rural", 0) total_enroll.append(calculated_total / 10000) # 转换为万人 # 构建ECharts配置 option = { # "title": { # "text": "云南省学前教育人数统计", # "left": "center", # "textStyle": {"color": "#333"} # }, "tooltip": { "trigger": "axis", "axisPointer": { "type": "cross", "crossStyle": {"color": "#999"} }, "textStyle": {"color": "#333"}, "backgroundColor": "rgba(255, 255, 255, 0.8)", "borderColor": "rgba(0, 0, 0, 0.2)", "borderWidth": 1 }, "legend": { "data": ["城区", "镇区", "乡村", "总入园数"], "top": 30, "textStyle": {"color": "#333"}, "icon": "roundRect", "itemWidth": 12, "itemHeight": 12 }, "xAxis": [ { "type": "category", "data": years, "axisPointer": {"type": "shadow"}, "axisLabel": {"color": "#333"}, "axisLine": {"lineStyle": {"color": "#333"}} } ], "yAxis": [ { "type": "value", "name": "人数", "min": 0, "max": 100, "interval": 20, "axisLabel": { "formatter": "{value} 万人", "color": "#333" }, "axisLine": {"lineStyle": {"color": "#333"}}, "splitLine": {"lineStyle": {"color": "rgba(0,0,0,0.1)"}} }, { "type": "value", "name": "总入园数", "min": 0, "max": "auto", "interval": "auto", # 自动计算间隔 "position": "right", # 显示在右侧 "axisLabel": { "formatter": "{value} 万人", # 确保数值格式正确 "color": "#ee6666" }, "axisLine": {"show": True, "lineStyle": {"color": "#ee6666"}}, "axisTick": {"show": True}, "color": "#333" }, { "type": "value", "name": "总入园数", "min": 0, "max": "auto", # 修改为自动适应数据最大值 "interval": 8, "axisLabel": { "formatter": "{value} 万人", "color": "#333" }, "axisLine": {"lineStyle": {"color": "#333"}}, "splitLine": {"show": False} } ], "series": [ { "name": "城区", "type": "bar", "data": urban_data, "itemStyle": { "color": "#5470c6", "borderRadius": [6, 6, 0, 0] }, "barWidth": "25%", # 增加柱子宽度 "barGap": "-10%" # 设置负数让柱子重叠以减少空隙 }, { "name": "镇区", "type": "bar", "data": town_data, "itemStyle": { "color": "#91cc75", "borderRadius": [6, 6, 0, 0] }, "barWidth": "25%", # 增加柱子宽度 "barGap": "-10%" # 设置负数让柱子重叠以减少空隙 }, { "name": "乡村", "type": "bar", "data": rural_data, "itemStyle": { "color": "#fac858", "borderRadius": [6, 6, 0, 0] }, "barWidth": "25%", # 增加柱子宽度 "barGap": "-10%" # 设置负数让柱子重叠以减少空隙 }, { "name": "总入园数", "type": "line", "yAxisIndex": 1, "data": total_enroll, "lineStyle": {"color": "#ee6666", "width": 3}, "symbol": "circle", "symbolSize": 8, "itemStyle": {"color": "#ee6666"} } ], "grid": { "left": "3%", "right": "4%", "bottom": "3%", "containLabel": True } } return option