SpringBoot Web前端动态显示柱状图、折线图

it2022-05-05  94

技术背景:

1. SpringBoot + JPA

2. 前端使用Bootstrap

3. 需要将后台数据生成柱状图、折线图 在前台显示

 

问题:

如果将后台数据生成柱状图、折线图在前台显示

 

遇坑:

1. 使用Echart进行图片显示,后台传递数据,前台使用jquery显示

使用这种方法发现,网上大多数教程为静态Echart的显示,不符合需求,动态显示没有研究出来,且这种方法比较具有局限性,由于我做的项目以数据可视化为主,Echart可以表现的图形有限,且作为一个后端开发..前端不擅长

 

解决方法:

1. Java调用Python,传递数据,使用Python绘制图片并进行图片保存,保存至指定路径

2. Java前端每次点击按钮,jquery获取图片路径,在前台进行显示

 

Java调用Python数据并传值:

public void startCharaChange(HttpServletRequest request , Long fileId) throws Exception { String[] arg2 = new String[] { "python", "D:\\\\Software\\\\python3.7\\\\pie3.py", String.valueOf(fileId)}; Process pr2=Runtime.getRuntime().exec(arg2); }

此处值的传递,我使用了数据库保存数据,并向Python程序传递Id, Python再查询数据库中的相关数据,读取后绘制图片(范例为饼图)

Python绘制饼图:

# encoding: utf-8 import pymysql import matplotlib.pyplot as plt import matplotlib import sys def paint(var1): matplotlib.rcParams['font.sans-serif']=['SimHei'] #指定默认字体 SimHei为黑体#连接数据库 db = pymysql.connect("localhost","root","123456","test") db2 = pymysql.connect("localhost","root","123456","test") #使用cursor()方法创建一个游标对象 cursor = db.cursor() sql2="select word,chara from keyword where file_id=%s" c2=[] word=[] cursor.execute(sql2,int(var1)) # 获取所有记录列表 course = cursor.fetchall() for row in course: a=row[0] b=row[1] word.append(a) d=0.0362 if(b[0:1] == 'a'): d = 0.0432 if(b[0:1] == 'n'): d = 0.2666 if(b[0:1] == 'v'): d = 0.0850 if(b[0:1] == 'g'): d = 0.5691 c2.append(d) plt.axes(aspect = 1) plt.pie(x=c2,labels=word,autopct='%.0f%%') plt.savefig('E:\\testDataStore\\pics\\piechara.jpg') #plt.show() #关闭游标和数据库的连接 cursor.close() db.close() print(var1) if __name__ == '__main__': #for i in range(1, len(sys.argv)): paint(sys.argv[1]) #paint(114)

此时已经在Java调用该Python程序后,已经在指定路径输出了图片,所以,在后台点击按钮时也要同时获取该图片:

设置获取方法:

@RequestMapping(value = "/seekPieChara") @ResponseBody public String seekPieChara(HttpServletRequest request, HttpServletResponse response, Model model) { // response.setContentType("image/*"); FileInputStream fis = null; OutputStream os = null; try { fis = new FileInputStream(new File("E:\\testDataStore\\pics\\piechara.jpg")); os = response.getOutputStream(); int count = 0; byte[] buffer = new byte[1024 * 8]; while ((count = fis.read(buffer)) != -1) { os.write(buffer, 0, count); os.flush(); } } catch (Exception e) { e.printStackTrace(); } try { fis.close(); os.close(); } catch (IOException e) { e.printStackTrace(); } return "ok"; }

同时,在jquery中设置点击事件,保证点击后该前端数据源调用上述的图片获取方法,以在前端页面进行显示:

//all $("#allChange").on("click",function () { var data = getData(); console.log(data); $("#loading").showLoading(); $.ajax({ type : 'POST', url : '/formatChange/startAll', data : JSON.stringify({'data' : data}), dataType : "text", contentType : "application/json", success : function (response) { $("#loading").hideLoading(); response = JSON.parse(response); if (response.errorCode !== 0) { toastr.error('转化失败 [' + response.errorInfo + ']'); }else{ $('#piechara').attr('src','../seekPieChara.do') toastr.success('转化成功'); } }, error : function () { $("#loading").hideLoading(); toastr.error('请求发送失败'); } }); });

由此,可以在前端获取后台生成的图像,并进行显示,同时也具有较好的延展性,因为Python的图像绘制更加专业,可以调用wordcloud、matlabplotlib包等。

 

注:

由于生成图片和读图片存在时间差,这里我一般用

Thread.sleep(5000);

来缓和时间差,保证一定可以取到最新图片。

可以根据实际情况设置等待时间,或者有更好地方法也欢迎大家告诉我Thanks♪(・ω・)ノ


最新回复(0)