前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于flask入门教程-ajax+echarts实现数量未知的折线图

关于flask入门教程-ajax+echarts实现数量未知的折线图

作者头像
python与大数据分析
发布2022-03-11 17:16:51
7380
发布2022-03-11 17:16:51
举报
文章被收录于专栏:python与大数据分析

前文学习了ajax、jsonify、数据库返回结果、echarts柱状图等用法,关于折线图原来想象着没有多困难的事情,结果碰了一大堆钉子,终于得到圆满解决,第一个要解决的是数量未知的折线图如何构造,没办法只能动态构造,第二个要解决的事情是如何构造json文件,第三个要解决的事情是如何生成数据,第四个要解决的事情js如何解析json数据。

千万不要先将内部的对象序列化成字符串,然后再序列化外边的对象。

再复杂的结构都可以表示为一个dict,

而之前不需要做任何序列化操作!!!

经过多轮测试,提前序列化会导致很多解析问题!!!

第一步:准备数据

原始的数据表是个csv文件包括了日期、地区、gdp、进出口和人口情况等等。

第二步:写入结构化数据表中

代码语言:javascript
复制
import csv
sql = "insert into economyinfo (year,areano,region,GDP,avgGDP,primaryGDP,secondGDP,thirdGDP," \
      "importexportvolume,exportvolume,population,birthrate,mortality,growthrate) " \
      "values(:year,:areano,:region,:GDP,:avgGDP,:primaryGDP,:secondGDP,:thirdGDP," \
      ":importexportvolume,:exportvolume,:population,:birthrate,:mortality,:growthrate)"
args=[]
with open('C:\\Python\\Pycharm\\supermarket\\chinaeconomy.csv','r',encoding='utf-8') as f:
   reader = csv.reader(f)
   if reader != None:
      for i in reader:
         args.append(i)
cursor = cur.executemany(sql,args)
conn.commit()

sql="select * from economyinfo"
cursor=cur.execute(sql)
print('sql=')
for row in cursor:
   print(row)

第三步:测试最简单折线图

代码语言:javascript
复制
@app.route('/echartdemo4')
def echartdemo4():
    return render_template('echartdemo4.html')
代码语言:javascript
复制
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <!-- 引入刚刚下载的 ECharts 文件 -->
    <!--script src="..\static\js\echarts.min.js"></script-->
    <script src="/static/js/echarts.min.js"></script>
    <script src="/static/js/jquery.js"></script>
  </head>
  <body>
    <!-- 为 ECharts 准备一个定义了宽高的 DOM -->
    <div id="main" style="width: 600px;height:400px;"></div>
    <script type="text/javascript">
      // 基于准备好的dom,初始化echarts实例
      
      var myChart = echarts.init(document.getElementById('main'));
      // 指定图表的配置项和数据
      myChart.option = {
     xAxis: {
       type: 'category',
       data: []
     },
     yAxis: {
       type: 'value'
     },
     series: [
       {
         data: [],
         type: 'line'
       }
     ]
      };
   
      // 使用刚指定的配置项和数据显示图表。
      myChart.showLoading();
      
      $.ajax({
       url:'/getjson3',
       result:{},
       type:'GET',
       dataType:'json',
       success:function(result){
         myChart.hideLoading();
          // 填入数据
          myChart.setOption({
              legend:{
                data:['类型1']
              },
              xAxis: {
                type: 'category',
                boundaryGap: false,
                data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
              },
              yAxis: {
                type: 'value'
              },
              series: [
                {
                  name:'类型1',
                  data: [150, 230, 224, 218, 135, 147, 260],
                  type: 'line',
                  smooth: true
                }
              ]
          })
       },
       error:function (msg) {
         console.log(msg);
                   alert('系统发生错误');
            }
      })
      
      
    </script>
 </body>
 </html>

第四步:测试两种数据的折线图

代码语言:javascript
复制
@app.route('/echartdemo5')
def echartdemo5():
    return render_template('echartdemo5.html')
代码语言:javascript
复制
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <!-- 引入刚刚下载的 ECharts 文件 -->
    <!--script src="..\static\js\echarts.min.js"></script-->
    <script src="/static/js/echarts.min.js"></script>
    <script src="/static/js/jquery.js"></script>
  </head>
  <body>
    <!-- 为 ECharts 准备一个定义了宽高的 DOM -->
    <div id="main" style="width: 600px;height:400px;"></div>
    <script type="text/javascript">
      // 基于准备好的dom,初始化echarts实例
      
      var myChart = echarts.init(document.getElementById('main'));
      // 指定图表的配置项和数据
      myChart.option = {
     xAxis: {
       type: 'category',
       data: []
     },
     yAxis: {
       type: 'value'
     },
     series: [
       {
         data: [],
         type: 'line'
       }
     ]
      };
   
      // 使用刚指定的配置项和数据显示图表。
      myChart.showLoading();
      
      $.ajax({
       url:'/getjson3',
       result:{},
       type:'GET',
       dataType:'json',
       success:function(result){
         myChart.hideLoading();
          // 填入数据
          myChart.setOption({
              legend:{
                data:['类型1','类型2']
              },
              xAxis: {
                type: 'category',
                boundaryGap: false,
                data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
              },
              yAxis: {
                type: 'value'
              },
              series: [
                {
                  name:'类型1',
                  data: [150, 230, 224, 218, 135, 147, 260],
                  type: 'line',
                  smooth: true
                },
                {
                  name:'类型2',
                  data: [250, 330, 124, 318, 35, 87, 360],
                  type: 'line',
                  smooth: true
                }
              ]
          })
       },
       error:function (msg) {
         console.log(msg);
                   alert('系统发生错误');
            }
      })
      
      
    </script>
 </body>
 </html>

第五步:比较麻烦,最重要的也在这边

通过pandas对数据集进行行列转换,毕竟后台转换要比前台转换容易一些,难点在于列是不固定的,通过pandas.pivot进行转换,分别构造前台所需的year列表,region列表和gdp数据,难者不会,会者不难,主要是选择合适的格式返回数据。当然走了不少弯路。千万不要先将内部的对象序列化成字符串,然后再序列化外边的对象。再复杂的结构都可以表示为一个dict,而之前不需要做任何序列化操作!!!经过多轮测试,提前序列化会导致很多解析问题!!!

代码语言:javascript
复制
@app.route('/getjson6', methods=['GET'])
def getjson6():
    # 千万不要先将内部的对象序列化成字符串,然后再序列化外边的对象。
    # 再复杂的结构都可以表示为一个dict,
    # 而之前不需要做任何序列化操作!!!
    # 经过多轮测试,提前序列化会导致很多解析问题!!!
    sql = "select year,region,GDP from economyinfo "
    sql_data = pd.DataFrame(db.session.execute(sql).fetchall())
    sql_data.columns = [i[0] for i in db.session.execute(sql).cursor.description]
    #       year    region       GDP
    # 0     1950       北京市    -95.00
    # 1     1950       天津市    -95.00
    # 2     1950       河北省    -95.00
    # 3     1950       山西省    -95.00
    tt = sql_data.pivot(index='year', columns='region', values='GDP')
    # year       1950   1951     1952  ...        2008        2009        2010
    # region                           ...
    # 上海市      -95.00 -95.00  36.6600  ...  14069.8700  15046.4500  17165.9800
    # 云南省      -95.00 -95.00  11.7800  ...   5692.1200   6169.7500   7224.1800
    # 内蒙古自治区   -95.00 -95.00  12.1600  ...   8496.1953   9740.2525  11672.0000
    # reset_index表示重新设置索引后将原索引作为新的一列并入DataFrame
    # orient =‘dict’,是函数默认的,转化后的字典形式:{column(列名) : {index(行名) : value(值) )}};
    # orient =‘list’ ,转化后的字典形式:{column(列名) :{[ values ](值)}};
    # orient =‘series’ ,转化后的字典形式:{column(列名) : Series (values) (值)};
    # orient =‘split’ ,转化后的字典形式:{‘index’ : [index],‘columns’ :[columns],’data‘ : [values]};
    # orient =‘records’ ,转化后是 list形式:[{column(列名) : value(值)}…{column:value}];
    # orient =‘index’ ,转化后的字典形式:{index(值) : {column(列名) : value(值)}};
    # datadict = tt.reset_index().to_dict('dict')
    datadict = tt.to_dict('dict')
    # datadict= {'上海市': {'1950': -95.0, '1951': -95.0,..., '2009': 15046.45, '2010': 17165.98},
    # '云南省': {'1950': -95.0, '1951': -95.0, ..., '2009': 6169.75, '2010': 7224.18},
    # ....
    # '上海市:{'1950': -95.0, '1951': -95.0, ..., '2009': 15046.45, '2010': 17165.98}
    # datalist = tt.reset_index().to_dict('list')
    # datajson = tt.reset_index().to_json(orient='records')
    datalist = tt.to_dict('list')

    year = db.session.execute('select distinct year from economyinfo').fetchall()
    # yearjson = json.dumps({'year': [x['year'] for x in year]}, ensure_ascii=True)
    # yearjsonify = jsonify(year=[x['year'] for x in year])
    yearlist = [x['year'] for x in year]

    region = db.session.execute('select distinct region from economyinfo').fetchall()
    # regionjsonify = jsonify(region=[x['region'] for x in region])
    # regionjson = json.dumps({'region':[x['region'] for x in region]},ensure_ascii=True)
    regionlist = [x['region'] for x in region]

    gdpdata = {}
    gdpdata['region'] = regionlist
    gdpdata['year'] = yearlist
    gdpdata['data'] = datalist

    # gdp数据用列表方式
    # 通过json.dumps 输出格式为<str>,不可直接解析
    # 通过json.loads转换为json格式
    jsondumps = json.dumps(gdpdata)
    jsonloads = json.loads(jsondumps)
    # {
    # 'region': ['北京市', '天津市', '河北省', '山西省', '内蒙古自治区', '辽宁省', '吉林省', '黑龙江省',...],
    # 'year': ['1950', '1951', '1952', '1953', '1954', '1955', '1956', '1957', '1958', '1959', '1960',...],
    # 'data':
    #   {
    #       '上海市': [-95.0, -95.0, 36.66, 51.71, 54.7, 53.64, 63.61, 69.6, 95.61, 128.49, 158.39, 101.78,... ]
    #       '内蒙古自治区': [-95.0, -95.0, 12.16, 15.57, 19.46, 17.49, 24.6, 21.27, 28.1, 35.76, 36.56, 25.... ]
    #       '青海省': [-95.0, -95.0, 1.63, 1.74, 2.35, 2.93, 3.81, 3.95, 4.87, 6.94, 7.68, 5.4, 4.59, 4.86,... ]
    #   }
    # }
    # gdp数据用字典方式
    # 通过json.dumps 输出格式为<str>,不可直接解析
    # 通过json.loads转换为json格式
    # gdpdata['data'] = datadict
    jsondumps = json.dumps(gdpdata, ensure_ascii=False)
    jsonloads = json.loads(jsondumps)
    # {
    # 'region': ['北京市', '天津市', '河北省', '山西省', '内蒙古自治区', '辽宁省', '吉林省', '黑龙江省',...],
    # 'year': ['1950', '1951', '1952', '1953', '1954', '1955', '1956', '1957', '1958', '1959', '1960',...],
    # 'data':
    #   {
    #       {'上海市':{'1950': -95.0, '1951': -95.0, ..., '2009': 15046.45, '2010': 17165.98},
    #        '云南省':{'1950': -95.0, '1951': -95.0, ..., '2009': 6169.75, '2010': 7224.18},
    #         ....
    #        '上海市':{'1950': -95.0, '1951': -95.0, ..., '2009': 15046.45, '2010': 17165.98}
    #   }
    # }
    # print('a[year]=', jsonloads['year'])
    # ['1950', '1951', '1952', '1953', '1954', '1955', '1956', '1957', '1958', '1959', '1960',
    # '1961', '1962', '1963', '1964', '1965', '1966', '1967', '1968', '1969', '1970',
    # '1971', '1972', '1973', '1974', '1975', '1976', '1977', '1978', '1979', '1980',
    # '1981', '1982', '1983', '1984', '1985', '1986', '1987', '1988', '1989', '1990',
    # '1991', '1992', '1993', '1994', '1995', '1996', '1997', '1998', '1999', '2000',
    # '2001', '2002', '2003', '2004', '2005', '2006', '2007', '2008', '2009', '2010']
    # print('a[region]=', jsonloads['region'])
    # a[region]= ['北京市', '天津市', '河北省', '山西省', '内蒙古自治区', '辽宁省', '吉林省',
    # '黑龙江省', '上海市', '江苏省', '浙江省', '安徽省', '福建省', '江西省', '山东省', '河南省',
    # '湖北省', '湖南省', '广东省', '广西壮族自治区', '海南省', '重庆市', '四川省', '贵州省',
    # '云南省', '西藏自治区', '陕西省', '甘肃省', '青海省', '宁夏回族自治区', '新疆维吾尔自治区']
    # print('a[data]=', jsonloads['data'])
    #   {
    #       {'上海市':{'1950': -95.0, '1951': -95.0, ..., '2009': 15046.45, '2010': 17165.98},
    #        '云南省':{'1950': -95.0, '1951': -95.0, ..., '2009': 6169.75, '2010': 7224.18},
    #         ....
    #        '上海市':{'1950': -95.0, '1951': -95.0, ..., '2009': 15046.45, '2010': 17165.98}
    #   }
    # for regionname, gdpdata in jsonloads['data'].items():
    #     print(regionname + ':' + str(gdpdata))
    #     # 北京市:{'1950': -95.0, '1951': -95.0, '1952': 7.88, '1953': 19.28, ..., '2010': 14113.6}
    #     for year, gdp in gdpdata.items():
    #         print(year + ':' + str(gdp))
    #         # 1950:-95.0
    #         # 1951:-95.0
    # 将字典直接通过jsonify转换为json格式
    response = jsonify(gdpdata)
    response.status_code = 200  # or 400 or whatever
    return jsonify(gdpdata)


@app.route('/echartdemo6')
def echartdemo6():
    return render_template('echartdemo6.html')

第六步:在前台进行json数据的处理,生成动态序列,这个的调试过程和json返回有很大关系。

代码语言:javascript
复制
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <!-- 引入刚刚下载的 ECharts 文件 -->
    <!--script src="..\static\js\echarts.min.js"></script-->
    <script src="/static/js/echarts.min.js"></script>
    <script src="/static/js/jquery.js"></script>
  </head>
  <body>
    <!-- 为 ECharts 准备一个定义了宽高的 DOM -->
    <div id="main" style="width: 600px;height:400px;"></div>
    <script type="text/javascript">
      // 基于准备好的dom,初始化echarts实例
      
      var myChart = echarts.init(document.getElementById('main'));
      // 指定图表的配置项和数据
      myChart.option = {
     xAxis: {
       type: 'category',
       data: []
     },
     yAxis: {
       type: 'value'
     },
     series: [
       {
         data: [],
         type: 'line'
       }
     ]
      };
   
      // 使用刚指定的配置项和数据显示图表。
      myChart.showLoading();
      
      $.ajax({
       url:'/getjson6',
       result:{},
       type:'GET',
       dataType:'json',
       success:function(result){
          gdpdata=result.data
          var gdpseries = [];
          //result.year=['1950', '1951', '1952', '1953', '1954', '1955', '1956', '1957', '1958', '1959', '1960',...]
          //year.region=['北京市', '天津市', '河北省', '山西省', '内蒙古自治区', '辽宁省', '吉林省', '黑龙江省',...]
          //year.data=
         // {
         //       '上海市': [-95.0, -95.0, 36.66, 51.71, 54.7, 53.64, 63.61, 69.6, 95.61, 128.49, 158.39, 101.78,... ]
         //       '内蒙古自治区': [-95.0, -95.0, 12.16, 15.57, 19.46, 17.49, 24.6, 21.27, 28.1, 35.76, 36.56, 25.... ]
         //       '青海省': [-95.0, -95.0, 1.63, 1.74, 2.35, 2.93, 3.81, 3.95, 4.87, 6.94, 7.68, 5.4, 4.59, 4.86,... ]
         //   }
         $.each(gdpdata, function(key, val){
            var item = {
               name: key, //上海市
               type: 'line',
               data: val, //[-95.0, -95.0, 36.66, 51.71, 54.7, 53.64, 63.61, 69.6, 95.61, 128.49, 158.39, 101.78,... ]
                  smooth: true
                }
         gdpseries.push(item);
         });
         alert(gdpseries);
         myChart.hideLoading();
          // 填入数据
          myChart.setOption({
              legend:{
                data:result.region
              },
              xAxis: {
                type: 'category',
                boundaryGap: false,
                data: result.year
              },
              yAxis: {
                type: 'value'
              },
              series: gdpseries
          })
       },
       error:function (msg) {
         console.log(msg);
                   alert('系统发生错误');
            }
      })
      
      
    </script>
 </body>
 </html>

再强调一下!千万不要先将内部的对象序列化成字符串,然后再序列化外边的对象。

再复杂的结构都可以表示为一个dict,

而之前不需要做任何序列化操作!!!

经过多轮测试,提前序列化会导致很多解析问题!!!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-02-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 python与大数据分析 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档