前文学习了ajax、jsonify、数据库返回结果、echarts柱状图等用法,关于折线图原来想象着没有多困难的事情,结果碰了一大堆钉子,终于得到圆满解决,第一个要解决的是数量未知的折线图如何构造,没办法只能动态构造,第二个要解决的事情是如何构造json文件,第三个要解决的事情是如何生成数据,第四个要解决的事情js如何解析json数据。
千万不要先将内部的对象序列化成字符串,然后再序列化外边的对象。
再复杂的结构都可以表示为一个dict,
而之前不需要做任何序列化操作!!!
经过多轮测试,提前序列化会导致很多解析问题!!!
第一步:准备数据
原始的数据表是个csv文件包括了日期、地区、gdp、进出口和人口情况等等。
第二步:写入结构化数据表中
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)
第三步:测试最简单折线图
@app.route('/echartdemo4')
def echartdemo4():
return render_template('echartdemo4.html')
<!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>
第四步:测试两种数据的折线图
@app.route('/echartdemo5')
def echartdemo5():
return render_template('echartdemo5.html')
<!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,而之前不需要做任何序列化操作!!!经过多轮测试,提前序列化会导致很多解析问题!!!
@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返回有很大关系。
<!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,
而之前不需要做任何序列化操作!!!
经过多轮测试,提前序列化会导致很多解析问题!!!
本文分享自 python与大数据分析 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!