• Flask框架:如何运用Ajax轮询动态绘图


    摘要:Ajax是异步JavaScript和XML可用于前后端交互。

    本文分享自华为云社区《Flask框架:运用Ajax轮询动态绘图》,作者:LyShark。

    Ajax是异步JavaScript和XML可用于前后端交互,在之前《Flask 框架:运用Ajax实现数据交互》简单实现了前后端交互,本章将通过Ajax轮询获取后端的数据,前台使用echart绘图库进行图形的生成与展示,后台通过render_template方法返回一串JSON数据集,前台收到后将其应用到绘图库上,实现动态监控内存利用率的这个功能。

    首先LyShark先来演示一下前端如何运用AJAX实现交互,通过$.ajax定义ajax开始标志,并指定url,type,datetype等信息,通过setInterval设置一个1000毫秒的定时器,每隔一段时间则去后端取数据。

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <script type="text/javascript" src="https://cdn.lyshark.com/javascript/jquery/3.5.1/jquery.min.js">script>
    6. <script type="text/javascript" src="https://cdn.lyshark.com/javascript/echarts/5.3.0/echarts.min.js">script>
    7. head>
    8. <body>
    9. <script type="text/javascript">
    10. $(
    11. function () {
    12. fetchData();
    13. setInterval(fetchData, 1000);
    14. }
    15. );
    16. function fetchData(){
    17. $.ajax({
    18. url:"/",
    19. type:"POST",
    20. dataType: 'json',
    21. success:function (recv) {
    22. console.log("[lyshark.com] 获取到时间:" + recv.response[0]);
    23. console.log("[lyshark.com] 获取到数据:" + recv.response[1]);
    24. }
    25. })
    26. }
    27. script>
    28. body>

    后端只需要根据前端需要的格式返回系统中的CPU利用率(此处模拟),并使用json.dumps({"response":[times,data]})推送到前端即可。

    1. # 署名权
    2. # right to sign one's name on a piece of work
    3. # PowerBy: LyShark
    4. # Email: me@lyshark.com
    5. from flask import Flask,render_template,request
    6. import json,time,random
    7. async_mode = None
    8. app = Flask(import_name=__name__,
    9. static_url_path='/python', # 配置静态文件的访问url前缀
    10. static_folder='static', # 配置静态文件的文件夹
    11. template_folder='templates') # 配置模板文件的文件夹
    12. @app.route('/',methods=['POST','GET'])
    13. def index():
    14. if request.method == "GET":
    15. return render_template("index.html")
    16. elif request.method == "POST":
    17. times = time.strftime("%M:%S", time.localtime())
    18. data = [random.randint(1,100)]
    19. return json.dumps({"response":[times,data]})
    20. if __name__ == '__main__':
    21. app.run()

    运行这段代码,然后打开控制台,则可以看到如下数据,前台会每隔一秒向后端请求数据;

    如果上方绘制可以被正确执行,那么想要实现轮询绘图只需要封装实现一个update()自定义绘图函数,该函数内将得到的数据统一放入到数组内,并调用封装好的display()函数,将数据绘制到前台。

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <script type="text/javascript" src="https://cdn.lyshark.com/javascript/jquery/3.5.1/jquery.min.js">script>
    6. <script type="text/javascript" src="https://cdn.lyshark.com/javascript/echarts/5.3.0/echarts.min.js">script>
    7. head>
    8. <body>
    9. <div id="main" style="height:300px;width:80%;border:1px solid #eecc11;padding:10px;">div>
    10. <script type="text/javascript" charset="UTF-8">
    11. var display = function(time,cpu) {
    12. var main = echarts.init(document.getElementById(("main")));
    13. var option = {
    14. xAxis: {
    15. boundaryGap:false,
    16. boundaryGap:false,
    17. type: 'category',
    18. data: time
    19. },
    20. yAxis: {
    21. type: 'value'
    22. },
    23. series: [{
    24. type: 'line',
    25. areaStyle:{},
    26. data: cpu
    27. }]
    28. };
    29. main.setOption(option,true);
    30. };
    31. script>
    32. <script type="text/javascript" charset="UTF-8">
    33. // 负责对参数的解析
    34. var time =["","","","","","","","","",""];
    35. var cpu = [0,0,0,0,0,0,0,0,0,0];
    36. var update = function(recv){
    37. time.push(recv.response[0]);
    38. cpu.push(parseFloat(recv.response[1]));
    39. if(time.length >=10){
    40. time.shift();
    41. cpu.shift();
    42. console.log("处理后的时间数据:" + time);
    43. console.log("处理后的CPU数据:" + cpu);
    44. display(time,cpu) // 调用绘图函数
    45. }
    46. };
    47. script>
    48. <script type="text/javascript">
    49. $(
    50. function () {
    51. fetchData();
    52. setInterval(fetchData, 1000);
    53. }
    54. );
    55. function fetchData(){
    56. $.ajax({
    57. url:"/",
    58. type:"POST",
    59. dataType: 'json',
    60. success:function (recv) {
    61. console.log("获取到时间:" + recv.response[0]);
    62. console.log("获取到数据:" + recv.response[1]);
    63. // 传递给处理函数
    64. update(recv)
    65. }
    66. })
    67. }
    68. script>
    69. body>

    对于后台来说,我们不需要做任何变更,因为只要我们遵循返回JSON的格式即可,运行替换后的程序,我们可以看到控制台会出现以下参数;

    这就标志着接收的数据是正确的,我们来看下最终绘制效果;

    当然有时候我们需要返回多个图形,而不是一个,运用轮询同样可以实现,如下案例中将两个仪表盘合并在了一起,并通过一个接口实现了数据的轮询,相比上方代码变化并不大。

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <script type="text/javascript" src="https://cdn.lyshark.com/javascript/jquery/3.5.1/jquery.min.js">script>
    6. <script type="text/javascript" src="https://cdn.lyshark.com/javascript/echarts/5.3.0/echarts.min.js">script>
    7. head>
    8. <body>
    9. <div id="cpuChart" style="width: 20%; height: 300px; border: 1px solid #dddddd; float:left; margin-right: 8px;">div>
    10. <div id="memChart" style="width: 20%; height: 300px; border: 1px solid #dddddd; float:left; margin-right: 8px;">div>
    11. <script type="text/javascript" charset="UTF-8">
    12. var display = function(cpu,mem)
    13. {
    14. var cpuChart = echarts.init(document.getElementById("cpuChart"));
    15. var option = {
    16. series: [
    17. {
    18. name: 'Pressure',
    19. type: 'gauge',
    20. progress: {
    21. show: true
    22. },
    23. detail: {formatter: '{value} %',fontSize: 12},
    24. data: [{value: cpu, name: 'CPU负载'}]
    25. }
    26. ]
    27. };cpuChart.setOption(option, true);
    28. var memChart = echarts.init(document.getElementById("memChart"));
    29. var option = {
    30. series: [
    31. {
    32. name: 'Pressure',
    33. type: 'gauge',
    34. progress: {
    35. show: true
    36. },
    37. detail: {formatter: '{value} %',fontSize: 12},
    38. data: [{value: mem, name: '内存利用率'}]
    39. }
    40. ]
    41. };memChart.setOption(option, true);
    42. };
    43. script>
    44. <script type="text/javascript">
    45. $(
    46. function () {
    47. fetchData();
    48. setInterval(fetchData, 100);
    49. }
    50. );
    51. function fetchData(){
    52. $.ajax({
    53. url:"/",
    54. type:"POST",
    55. dataType: 'json',
    56. success:function (recv) {
    57. display(recv.response[0],recv.response[1]);
    58. }
    59. })
    60. }
    61. script>
    62. body>

    后端部分只需要稍微小改一下,将json.dumps({"response":[cpu,mem]})返回时指定两个参数即可。

    1. # 署名权
    2. # right to sign one's name on a piece of work
    3. # PowerBy: LyShark
    4. # Email: me@lyshark.com
    5. from flask import Flask,render_template,request
    6. import json,time,random
    7. async_mode = None
    8. app = Flask(import_name=__name__,
    9. static_url_path='/python', # 配置静态文件的访问url前缀
    10. static_folder='static', # 配置静态文件的文件夹
    11. template_folder='templates') # 配置模板文件的文件夹
    12. @app.route('/',methods=['POST','GET'])
    13. def index():
    14. if request.method == "GET":
    15. return render_template("index.html")
    16. elif request.method == "POST":
    17. times = time.strftime("%M:%S", time.localtime())
    18. mem = random.randint(1,100)
    19. cpu = random.randint(1,100)
    20. return json.dumps({"response":[cpu,mem]})
    21. if __name__ == '__main__':
    22. app.run()

    框架运行后,在前端可以看到两个仪表盘分别显示不同的参数;

    点击关注,第一时间了解华为云新鲜技术~

     

  • 相关阅读:
    面向过程 VS 面向对象
    [附源码]java毕业设计果蔬网络销售平台
    探秘C语言数组:解锁高效数据管理与多维空间编程技巧"
    使用深度神经网络预测股票价格
    paddlespeech on centos7
    编写 bzt 脚本的正确姿势
    并查集原理
    前端拿到url地址拼接的参数
    rust输入输出
    vue项目中使用vant轮播图组件(桌面端)
  • 原文地址:https://blog.csdn.net/devcloud/article/details/127842373