'commit'
This commit is contained in:
@@ -0,0 +1,133 @@
|
|||||||
|
import json
|
||||||
|
import os
|
||||||
|
from pyecharts import options as opts
|
||||||
|
from pyecharts.charts import Bar, Line
|
||||||
|
from pyecharts.globals import CurrentConfig
|
||||||
|
|
||||||
|
# 配置使用自定义的ECharts路径
|
||||||
|
CurrentConfig.ONLINE_HOST = "https://gcore.jsdelivr.net/npm/echarts@6.0.0/dist/"
|
||||||
|
|
||||||
|
class RenkouModel:
|
||||||
|
@staticmethod
|
||||||
|
def load_population_data():
|
||||||
|
try:
|
||||||
|
# 获取当前文件所在目录的父目录,然后找到Data文件夹
|
||||||
|
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
project_root = os.path.dirname(current_dir) # 修正路径计算,只需要上一级目录
|
||||||
|
data_path = os.path.join(project_root, "Data", "RenKou.json")
|
||||||
|
|
||||||
|
with open(data_path, "r", encoding="utf-8") as f:
|
||||||
|
data = json.load(f)
|
||||||
|
return data
|
||||||
|
except Exception as e:
|
||||||
|
print(f"读取人口数据出错: {e}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def generate_population_chart_config(year="2024"):
|
||||||
|
# 加载人口数据
|
||||||
|
population_data = RenkouModel.load_population_data()
|
||||||
|
|
||||||
|
# 筛选出州市级数据
|
||||||
|
cities = [item for item in population_data if len(item["area_code"]) == 9 and item["area_code"].endswith("000") and item["area_code"][4:6] == "00" and item["area_code"][2:8] != "000000"]
|
||||||
|
|
||||||
|
# 提取城市名称和人口数据
|
||||||
|
city_names = [city["area_name"] for city in cities]
|
||||||
|
total_populations = [city["total_population"].get(year, 0) for city in cities]
|
||||||
|
urban_populations = [city["urban_population"].get(year, 0) for city in cities]
|
||||||
|
rural_populations = [city["rural_population"].get(year, 0) for city in cities]
|
||||||
|
|
||||||
|
# 创建柱状图
|
||||||
|
c = (
|
||||||
|
Bar()
|
||||||
|
.add_xaxis(city_names)
|
||||||
|
.add_yaxis("总人口", total_populations, stack="stack1")
|
||||||
|
.add_yaxis("城镇人口", urban_populations, stack="stack1")
|
||||||
|
.add_yaxis("农村人口", rural_populations, stack="stack1")
|
||||||
|
.set_global_opts(
|
||||||
|
title_opts=opts.TitleOpts(
|
||||||
|
title=f"云南省各州市人口分布图({year}年)",
|
||||||
|
pos_top="1%",
|
||||||
|
pos_left="center"
|
||||||
|
),
|
||||||
|
tooltip_opts=opts.TooltipOpts(
|
||||||
|
trigger="axis",
|
||||||
|
axis_pointer_type="shadow"
|
||||||
|
),
|
||||||
|
legend_opts=opts.LegendOpts(
|
||||||
|
pos_top="8%",
|
||||||
|
pos_right="5%"
|
||||||
|
),
|
||||||
|
datazoom_opts=[opts.DataZoomOpts()],
|
||||||
|
xaxis_opts=opts.AxisOpts(
|
||||||
|
axislabel_opts=opts.LabelOpts(rotate=45)
|
||||||
|
),
|
||||||
|
yaxis_opts=opts.AxisOpts(
|
||||||
|
name="人口数量(万人)",
|
||||||
|
name_location="middle",
|
||||||
|
name_gap=40
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.set_series_opts(
|
||||||
|
label_opts=opts.LabelOpts(is_show=False),
|
||||||
|
markline_opts=opts.MarkLineOpts(
|
||||||
|
data=[opts.MarkLineItem(type_="average", name="平均值")]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# 获取图表的选项配置
|
||||||
|
options_str = c.dump_options_with_quotes()
|
||||||
|
return json.loads(options_str)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def generate_urbanization_rate_chart_config():
|
||||||
|
# 加载人口数据
|
||||||
|
population_data = RenkouModel.load_population_data()
|
||||||
|
|
||||||
|
# 筛选出州市级数据
|
||||||
|
cities = [item for item in population_data if len(item["area_code"]) == 9 and item["area_code"].endswith("000") and item["area_code"][4:6] == "00" and item["area_code"][2:8] != "000000"]
|
||||||
|
|
||||||
|
# 提取城市名称
|
||||||
|
city_names = [city["area_name"] for city in cities]
|
||||||
|
|
||||||
|
# 创建折线图
|
||||||
|
line = (
|
||||||
|
Line()
|
||||||
|
.add_xaxis(city_names)
|
||||||
|
)
|
||||||
|
|
||||||
|
# 添加各年份的城镇化率数据
|
||||||
|
years = ["2020", "2021", "2022", "2023", "2024"]
|
||||||
|
for year in years:
|
||||||
|
urbanization_rates = [city["urbanization_rate"].get(year, 0) for city in cities]
|
||||||
|
line.add_yaxis(f"{year}年", urbanization_rates,
|
||||||
|
markpoint_opts=opts.MarkPointOpts(data=[opts.MarkPointItem(type_="max")]))
|
||||||
|
|
||||||
|
line.set_global_opts(
|
||||||
|
title_opts=opts.TitleOpts(
|
||||||
|
title="云南省各州市城镇化率变化趋势",
|
||||||
|
pos_top="1%",
|
||||||
|
pos_left="center"
|
||||||
|
),
|
||||||
|
tooltip_opts=opts.TooltipOpts(trigger="axis"),
|
||||||
|
legend_opts=opts.LegendOpts(
|
||||||
|
pos_top="8%",
|
||||||
|
pos_right="5%"
|
||||||
|
),
|
||||||
|
datazoom_opts=[opts.DataZoomOpts()],
|
||||||
|
xaxis_opts=opts.AxisOpts(
|
||||||
|
axislabel_opts=opts.LabelOpts(rotate=45)
|
||||||
|
),
|
||||||
|
yaxis_opts=opts.AxisOpts(
|
||||||
|
name="城镇化率(%)",
|
||||||
|
name_location="middle",
|
||||||
|
name_gap=40,
|
||||||
|
min_=0,
|
||||||
|
max_=100
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# 获取图表的选项配置
|
||||||
|
options_str = line.dump_options_with_quotes()
|
||||||
|
return json.loads(options_str)
|
BIN
Model/__pycache__/RenkouModel.cpython-310.pyc
Normal file
BIN
Model/__pycache__/RenkouModel.cpython-310.pyc
Normal file
Binary file not shown.
BIN
Model/__pycache__/__init__.cpython-310.pyc
Normal file
BIN
Model/__pycache__/__init__.cpython-310.pyc
Normal file
Binary file not shown.
@@ -1,213 +1,27 @@
|
|||||||
from fastapi import APIRouter
|
from fastapi import APIRouter
|
||||||
import pyecharts
|
|
||||||
from pyecharts import options as opts
|
|
||||||
from pyecharts.charts import Bar, Line
|
|
||||||
from pyecharts.faker import Faker
|
|
||||||
from pyecharts.globals import CurrentConfig
|
|
||||||
import json
|
import json
|
||||||
import os
|
from Model.RenkouModel import RenkouModel
|
||||||
|
|
||||||
# 创建APIRouter实例
|
# 创建APIRouter实例
|
||||||
router = APIRouter(prefix="/bigscreen", tags=["大屏展示"])
|
router = APIRouter(prefix="/bigscreen", tags=["大屏展示"])
|
||||||
|
|
||||||
# 配置使用自定义的 ECharts 路径
|
# 定义路由
|
||||||
CurrentConfig.ONLINE_HOST = "https://gcore.jsdelivr.net/npm/echarts@6.0.0/dist/"
|
|
||||||
|
|
||||||
# 定义一个 helloWorld 路由
|
|
||||||
@router.get("/")
|
@router.get("/")
|
||||||
async def root():
|
async def root():
|
||||||
return {"message": "Welcome to YunNan Education World!"}
|
return {"message": "Welcome to YunNan Education World!"}
|
||||||
|
|
||||||
# 生成图表配置的函数
|
|
||||||
def generate_bar_chart_config():
|
|
||||||
c = (
|
|
||||||
Bar()
|
|
||||||
.add_xaxis(Faker.choose())
|
|
||||||
.add_yaxis("商家A", Faker.values())
|
|
||||||
.add_yaxis("商家B", Faker.values())
|
|
||||||
.set_global_opts(title_opts=opts.TitleOpts(title="Bar-MarkLine(自定义)"))
|
|
||||||
.set_series_opts(
|
|
||||||
label_opts=opts.LabelOpts(is_show=False),
|
|
||||||
markline_opts=opts.MarkLineOpts(
|
|
||||||
data=[opts.MarkLineItem(y=50, name="yAxis=50")]
|
|
||||||
),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
# 获取图表的选项配置,使用 dump_options_with_quotes 方法获取可以直接序列化的选项
|
|
||||||
options_str = c.dump_options_with_quotes()
|
|
||||||
|
|
||||||
# 将字符串转换为 JSON 对象
|
|
||||||
options_json = json.loads(options_str)
|
|
||||||
|
|
||||||
return options_json
|
|
||||||
|
|
||||||
# 定义一个返回图表配置的路由
|
|
||||||
@router.get("/chart/bar")
|
@router.get("/chart/bar")
|
||||||
async def get_bar_chart_config():
|
async def get_bar_chart_config():
|
||||||
"""
|
return RenkouModel.generate_population_chart_config()
|
||||||
获取柱状图配置
|
|
||||||
"""
|
|
||||||
chart_config = generate_bar_chart_config()
|
|
||||||
return chart_config
|
|
||||||
|
|
||||||
# 读取人口数据
|
|
||||||
def load_population_data():
|
|
||||||
try:
|
|
||||||
# 获取当前文件所在目录的父目录,然后找到Data文件夹
|
|
||||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
|
||||||
project_root = os.path.dirname(current_dir)
|
|
||||||
data_path = os.path.join(project_root, "Data", "RenKou.json")
|
|
||||||
|
|
||||||
with open(data_path, "r", encoding="utf-8") as f:
|
|
||||||
data = json.load(f)
|
|
||||||
return data
|
|
||||||
except Exception as e:
|
|
||||||
print(f"读取人口数据出错: {e}")
|
|
||||||
return []
|
|
||||||
|
|
||||||
# 生成人口数据图表配置
|
|
||||||
def generate_population_chart_config(year="2024"):
|
|
||||||
# 加载人口数据
|
|
||||||
population_data = load_population_data()
|
|
||||||
|
|
||||||
# 筛选出州市级数据(排除县级数据)
|
|
||||||
# 正确的格式是9位数字,以000结尾且第5-6位为00(表示州市级)
|
|
||||||
cities = [item for item in population_data if len(item["area_code"]) == 9 and item["area_code"].endswith("000") and item["area_code"][4:6] == "00"]
|
|
||||||
|
|
||||||
# 提取城市名称和人口数据
|
|
||||||
city_names = [city["area_name"] for city in cities]
|
|
||||||
total_populations = [city["total_population"].get(year, 0) for city in cities]
|
|
||||||
urban_populations = [city["urban_population"].get(year, 0) for city in cities]
|
|
||||||
rural_populations = [city["rural_population"].get(year, 0) for city in cities]
|
|
||||||
|
|
||||||
# 创建柱状图
|
|
||||||
c = (
|
|
||||||
Bar()
|
|
||||||
.add_xaxis(city_names)
|
|
||||||
.add_yaxis("总人口", total_populations, stack="stack1")
|
|
||||||
.add_yaxis("城镇人口", urban_populations, stack="stack1")
|
|
||||||
.add_yaxis("农村人口", rural_populations, stack="stack1")
|
|
||||||
.set_global_opts(
|
|
||||||
title_opts=opts.TitleOpts(
|
|
||||||
title=f"云南省各州市人口分布图({year}年)",
|
|
||||||
pos_top="1%", # 调整标题位置到顶部1%
|
|
||||||
pos_left="center"
|
|
||||||
),
|
|
||||||
tooltip_opts=opts.TooltipOpts(
|
|
||||||
trigger="axis",
|
|
||||||
axis_pointer_type="shadow"
|
|
||||||
),
|
|
||||||
legend_opts=opts.LegendOpts(
|
|
||||||
pos_top="8%", # 调整图例位置到标题下方
|
|
||||||
pos_right="5%"
|
|
||||||
),
|
|
||||||
datazoom_opts=[opts.DataZoomOpts()],
|
|
||||||
xaxis_opts=opts.AxisOpts(
|
|
||||||
axislabel_opts=opts.LabelOpts(rotate=45)
|
|
||||||
),
|
|
||||||
yaxis_opts=opts.AxisOpts(
|
|
||||||
name="人口数量(万人)",
|
|
||||||
name_location="middle",
|
|
||||||
name_gap=40
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.set_series_opts(
|
|
||||||
label_opts=opts.LabelOpts(is_show=False),
|
|
||||||
markline_opts=opts.MarkLineOpts(
|
|
||||||
data=[opts.MarkLineItem(type_="average", name="平均值")]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
# 获取图表的选项配置
|
|
||||||
options_str = c.dump_options_with_quotes()
|
|
||||||
|
|
||||||
# 将字符串转换为 JSON 对象
|
|
||||||
options_json = json.loads(options_str)
|
|
||||||
|
|
||||||
return options_json
|
|
||||||
|
|
||||||
# 生成城镇化率图表配置
|
|
||||||
def generate_urbanization_rate_chart_config():
|
|
||||||
# 加载人口数据
|
|
||||||
population_data = load_population_data()
|
|
||||||
|
|
||||||
# 筛选出州市级数据(排除县级数据)
|
|
||||||
# 排除省级数据(如云南省530000000)和县级数据,只保留州市级数据
|
|
||||||
cities = [item for item in population_data if len(item["area_code"]) == 9 and item["area_code"].endswith("000") and item["area_code"][4:6] == "00" and item["area_code"][2:8] != "000000"]
|
|
||||||
|
|
||||||
# 提取城市名称和城镇化率数据
|
|
||||||
city_names = [city["area_name"] for city in cities]
|
|
||||||
|
|
||||||
# 创建折线图
|
|
||||||
line = (
|
|
||||||
Line()
|
|
||||||
.add_xaxis(city_names)
|
|
||||||
)
|
|
||||||
|
|
||||||
# 添加各年份的城镇化率数据
|
|
||||||
years = ["2020", "2021", "2022", "2023", "2024"]
|
|
||||||
for year in years:
|
|
||||||
urbanization_rates = [city["urbanization_rate"].get(year, 0) for city in cities]
|
|
||||||
line.add_yaxis(f"{year}年", urbanization_rates,
|
|
||||||
markpoint_opts=opts.MarkPointOpts(data=[opts.MarkPointItem(type_="max")]))
|
|
||||||
|
|
||||||
line.set_global_opts(
|
|
||||||
title_opts=opts.TitleOpts(
|
|
||||||
title="云南省各州市城镇化率变化趋势",
|
|
||||||
pos_top="1%", # 调整标题位置到顶部1%
|
|
||||||
pos_left="center"
|
|
||||||
),
|
|
||||||
tooltip_opts=opts.TooltipOpts(trigger="axis"),
|
|
||||||
legend_opts=opts.LegendOpts(
|
|
||||||
pos_top="8%", # 调整图例位置到标题下方
|
|
||||||
pos_right="5%"
|
|
||||||
),
|
|
||||||
datazoom_opts=[opts.DataZoomOpts()],
|
|
||||||
xaxis_opts=opts.AxisOpts(
|
|
||||||
axislabel_opts=opts.LabelOpts(rotate=45)
|
|
||||||
),
|
|
||||||
yaxis_opts=opts.AxisOpts(
|
|
||||||
name="城镇化率(%)",
|
|
||||||
name_location="middle",
|
|
||||||
name_gap=40,
|
|
||||||
min_=0,
|
|
||||||
max_=100
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
# 获取图表的选项配置
|
|
||||||
options_str = line.dump_options_with_quotes()
|
|
||||||
|
|
||||||
# 将字符串转换为 JSON 对象
|
|
||||||
options_json = json.loads(options_str)
|
|
||||||
|
|
||||||
return options_json
|
|
||||||
|
|
||||||
# 定义一个返回人口数据图表配置的路由
|
|
||||||
@router.get("/population/chart/{year}")
|
@router.get("/population/chart/{year}")
|
||||||
async def get_population_chart_config(year: str = "2024"):
|
async def get_population_chart_config(year: str = "2024"):
|
||||||
"""
|
return RenkouModel.generate_population_chart_config(year)
|
||||||
获取人口数据图表配置
|
|
||||||
"""
|
|
||||||
chart_config = generate_population_chart_config(year)
|
|
||||||
return chart_config
|
|
||||||
|
|
||||||
# 定义一个返回城镇化率图表配置的路由
|
|
||||||
@router.get("/population/urbanization")
|
@router.get("/population/urbanization")
|
||||||
async def get_urbanization_rate_chart_config():
|
async def get_urbanization_rate_chart_config():
|
||||||
"""
|
return RenkouModel.generate_urbanization_rate_chart_config()
|
||||||
获取城镇化率图表配置
|
|
||||||
"""
|
|
||||||
chart_config = generate_urbanization_rate_chart_config()
|
|
||||||
return chart_config
|
|
||||||
|
|
||||||
# 定义一个返回人口数据原始数据的路由
|
|
||||||
@router.get("/population/data")
|
@router.get("/population/data")
|
||||||
async def get_population_data():
|
async def get_population_data():
|
||||||
"""
|
return {"data": RenkouModel.load_population_data()}
|
||||||
获取人口数据原始数据
|
|
||||||
"""
|
|
||||||
population_data = load_population_data()
|
|
||||||
return {"data": population_data}
|
|
||||||
|
Binary file not shown.
@@ -30,19 +30,15 @@
|
|||||||
<option value="2023">2023年</option>
|
<option value="2023">2023年</option>
|
||||||
<option value="2024" selected>2024年</option>
|
<option value="2024" selected>2024年</option>
|
||||||
</select>
|
</select>
|
||||||
<button id="loadPopulationChart">加载图表</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div id="populationChart" class="chart"></div>
|
<div id="populationChart" class="chart"></div>
|
||||||
<!-- <div class="message" id="populationMessage">点击"加载图表"按钮获取数据</div>-->
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="tab-content" id="urbanization-tab">
|
<div class="tab-content" id="urbanization-tab">
|
||||||
<h2>云南省各州市城镇化率变化趋势</h2>
|
<h2>云南省各州市城镇化率变化趋势</h2>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<button id="loadUrbanizationChart">加载图表</button>
|
|
||||||
</div>
|
</div>
|
||||||
<div id="urbanizationChart" class="chart"></div>
|
<div id="urbanizationChart" class="chart"></div>
|
||||||
<div class="message" id="urbanizationMessage">点击"加载图表"按钮获取数据</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user