实训:“长征•人员损失”模块实现
在本实训中,我们继续修改首页的相关内容,添加一个呈现长征中各支红军队伍的人员损失统计信息的 “长征•人员损失” 模块,并利用echarts框架实现数据的图形化展示,具体步骤如下:
- 修改global_data.py (位于项目根目录下的models/子目录内),在文件中原来代码的基础上,声明一个变量cz_loss,并对其赋值(赋值后,cz_loss是一个包含四个元素的列表,每个元素为一个字典对象。关于列表和字典的相关知识将在下一个任务中学习),如图1所示:
cz_loss = [ {"id": "cz-doughnut1", "army": "红一方面军", "loss": 91.9, "color": "#fd5b4e", "description": "1934年10月,中央红军长征出发时,总兵力8.6万余人。1934年11月底至12月初,中央红军渡过湘江后,锐减至3万余人。" "1935年10月,陕甘支队到达陕北吴起镇时,兵力总数约为7000余人."}, {"id": "cz-doughnut2", "army": "红二方面军", "loss": 142.9, "color": "#25bce9", "description": "1934年8月,红6军团奉命西征时,全军团约9700余人。1934年10月,红2、6军团会师时,两军团合计约7700余人。" "1936年10月22日,红一、二方面军会师时,尚有兵力1.1万余人。"}, {"id": "cz-doughnut4", "army": "红四方面军", "loss": 88, "color": "#ffa63e", "description": "1934年5月初,红四方面军长征开始时,总计约10万人。1936年10月,红军三大主力会师时," "红四方面军5个军和直属队共计3.81万人。红四方面军西征后,最后到达陕西的人数约1.2万人左右。"}, {"id": "cz-doughnut25", "army": "红二十五军", "loss": 114.1, "color": "#94eae3", "description": "1934年11月,红25军出发长征时,共2980人。1935年7月,红25军从陕西沣峪口地区出发继续长征时,全军4000余人。" "1935年9月,红25军长征胜利到达延川永坪镇时,全军共有3400余人。"} ]
-
修改cz_main.py (位于项目根目录下), 首先在文件的第3行代码中,添加对cz_loss变量的引用,然后向context变量中添加一个键值对,如图2所示。
from flask import Flask, render_template from models.global_data import v_list,cz_infos,cz_loss from views.cz_profile import profile # 导入cz_profile模块中的profile蓝图 from views.cz_auth import auth # 导入cz_auth模块中的auths蓝图 from views.cz_history import history # 导入cz_history模块中的history蓝图 from views.cz_hero import hero # 导入cz_hero模块中的hero蓝图 from views.cz_video import video # 导入cz_video模块中的video蓝图 from views.cz_battle import battle # 导入cz_battle模块中的battle蓝图 from views.cz_literature import literature # 导入cz_literature模块中的literature蓝图 from views.cz_memorial import memorial # 导入cz_memorial模块中的memorial蓝图 app = Flask(__name__) # 将可能的蓝图路由封装到元组中,以便于下面通过for循环将多个蓝图注册到主应用上 bps = (profile, auth, history, hero, video, battle, literature, memorial) for bp in bps: app.register_blueprint(bp) # 将对应的路由实现蓝图注册到主app应用上 context = { "v_list": v_list, # 用于向图片轮播模块提供数据 "info_list": cz_infos.split("\n"), # 用于向长征·苦难辉煌模块提供数据 "cz_loss": cz_loss # 用于向长征·人员损失模块提供数据 } @app.route("/") def main(): return render_template("/index/cz_index.html", **context) # return render_template("/index/cz_index.html", v_list=v_list, info_list=cz_infos.split("\n")) # \n:回车换行符 if __name__ == "__main__": app.run(port=19901, host="127.0.0.1", debug=True)
-
修改cz_index.html(位于项目根目录下的templates/index/子目录内)文件,在“长征•苦难辉煌”模块后添加一个“长征•人员损失”模块及相关的JavaScript脚本的引用代码,如图3所示。
{% extends "/cz_base.html" %} {% block title %} 长征 {% endblock %} {% block main %} <!-- 长征•图片轮播 --> <section id="myCarousel" class="carousel slide" data-bs-ride="carousel"> <ul class="carousel-indicators"> {% for v in v_list %} {% if loop.first %} <li data-bs-target="#myCarousel" data-bs-slide-to="{{loop.index0}}" class="active" aria-current="true" aria-label="Slide{{loop.index}}"></li> {% else %} <li data-bs-target="#myCarousel" data-bs-slide-to="{{loop.index0}}" aria-label="Slide{{loop.index}}"></li> {% endif %} {% endfor %} </ul> <div class="carousel-inner"> {% for v in v_list %} {% if loop.first %} <div class="carousel-item active"> <img class="d-block w-100" src="{{ url_for('static', filename=v.img_src) }}"> </div> {% else %} <div class="carousel-item"> <img class="d-block w-100" src="{{ url_for('static', filename=v.img_src) }}"> </div> {% endif %} {% endfor %} </div> <ul class="m-0"> <li class="carousel-control-prev" data-bs-target="#myCarousel" data-bs-slide="prev"> <span class="carousel-control-prev-icon" aria-hidden="true"></span> </li> <li class="carousel-control-next" data-bs-target="#myCarousel" data-bs-slide="next"> <span class="carousel-control-next-icon" aria-hidden="true"></span> </li> </ul> </section> <!-- 长征•苦难辉煌 --> <section class="cz-profile mt-1 bg-cz"> <div class="container py-4"> <div class="row"> <div class="block-title-w"> <h2 class="block-title">长征 • 苦难辉煌</h2> <span class="icon-title"> <span></span> <img src="{{ url_for('static', filename='images/star.png') }}" width="30" height="30"> </span> <a href="{{ url_for('profile.profile_page') }}"> <span class="sub-title mt-3"> {% for line in info_list %} {{ line }} {% if loop.index != 1 %} <br> {% endif %} {% endfor %} </span> </a> </div> </div> </div> </section> <!-- 长征·人员损失 --> <section class="cz-loss mt-1 py-4"> <div class="container"> <div class="block-title-w"> <h2 class="block-title">长征 ·人员损失</h2> <span class="icon-title"> <span></span> <img src="{{ url_for('static', filename='images/star.png') }}" width="30" height="30"> </span> <span class="sub-title mt-3 text-primary"> 长达两年的万里征途中,红军队伍付出了极大牺牲,人员由30余万锐减至3万余人。<br> 参考网址:https://wenku.baidu.com/view/a1ce44abb0717fd5360cdc3e.html?rec_flag=default </span> </div> <div class="row"> {%for loss in cz_loss %} <div class="col-md-3 col-sm-6 col-xs-12 text-center"> <div class="cz-loss-doughnut" id="{{loss.id}}"></div> <h2 class="cz-loss-title">{{loss.army}}</h2> <div class="cz-loss-decs"> <p>{{loss.description}}</p> </div> </div> {% endfor %} </div> </div> </section> {% endblock %} {% block jsinclude %} <script type="text/javascript"> let cz_loss={{ cz_loss | tojson | safe }} </script> <script src="{{ url_for('static', filename='js/echarts.min.js') }}"></script> <script src="{{ url_for('static', filename='js/cz_loss_daughnut.js') }}"></script> {% endblock %}
说明:本模块中要利用Echarts框架实现数据的图形化展示,因此要先导入Echarts的JavaScript库及自定义用于绘制甜甜圈图的JavaScript文件cz_loss_daughnut.js,如图3的第102-103行代码所示,引用的JavaScript文件位于项目根目录下static目录下的js子目录中,利用Flask提供的url_for()方法可以正确构造出对应资源的URL路径。另外,在绘制甜甜圈图需要用到从视图函数中传递给模板的cz_loss对象中的相关数据,因此,在图3第100行代码处,将cz_loss对象转换为JSON数据后,赋值给了同名的JavaScript变量。
- 修改cz_loss_daughnut.js文件(位于项目根目录下的static/js/子目录内),添加如图3所示的JavaScript代码:
if(cz_loss){ cz_loss.forEach(function(item) { let doughnut = document.getElementById(item.id); let myChart = echarts.init(doughnut); let gaugeData = [{ value: item.loss, detail: { valueAnimation: true, offsetCenter: ['0%', '0%']} }]; let option = { series: [{ type: 'gauge', startAngle: 90, endAngle: -270, pointer: { show: false }, progress: { show: true, overlap: false, roundCap: false, clip: false, color: 'red'}, axisLine: { lineStyle: { width: 20,} }, splitLine: { show: false }, axisTick: { show: false }, axisLabel: { show: false }, data: gaugeData, color: item.color, detail: { fontSize: 22, color: 'red', formatter: item.loss < 100 ? '{value}%' : (100 - item.loss).toFixed(1) +'%' } }] }; myChart.setOption(option); }); }
-
修改完成后,重新刷新首页页面,应该能看到 “长征•人员损失”模块如图5所示。