Files
YunNanProject/Model/RuYuanZaiYuanCount.py
2025-09-10 16:51:41 +08:00

186 lines
7.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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