基于Flask+Echarts的中药材价格分析与可视化项目

embedded/2024/10/18 11:57:28/

🎈 博主:一只程序猿子

🎈 博客主页:一只程序猿子 博客主页

🎈 个人介绍:爱好(bushi)编程!

🎈 创作不易:喜欢的话麻烦您点个👍和

🎈 欢迎访问我的主页(点我直达)

🎈 除此之外您还可以通过个人名片联系我

额滴名片儿

目录

1.介绍

2.技术选型

(1)Flask

(2)Echarts

3.数据收集

4.项目结构

 5.项目开发

(1)后端开发(Flask)

(2)前端开发(Echarts)

 6.项目运行与展示

(1)运行项目

(2)接口展示

(3)效果展示


1.介绍

         在上篇文章中,我们已经成功利用Python爬虫技术从中药材天地网捕获了丰富的中药材市场价格数据,包括几种关键中药材的历史价格变动信息。经过精心的数据清洗和整理后,这些宝贵的数据被妥善地存储到了MySQL数据库中,为后续的分析与可视化工作奠定了坚实的基础。在本篇文章中,我们将借助Flask框架构建后端服务,并结合Echarts的强大可视化功能,对这些数据进行深入分析,并以直观、生动的图表形式进行展示,从而帮助读者更好地理解中药材市场的价格变动趋势和规律。

2.技术选型

(1)Flask

Flask是一个轻量级的Web应用框架,它设计简单且易于扩展,非常适合快速构建Web应用。Flask的特点在于其灵活性和可扩展性,它不会强制用户使用特定的库或工具,而是提供了足够的自由度让开发者根据自己的需求来选择最适合的组件。此外,Flask拥有庞大的社区支持和丰富的文档资源,使得开发者在遇到问题时能够迅速找到解决方案。

选择Flask作为后端框架的原因主要有以下几点:首先,Flask的轻量级特性使得项目可以快速启动和部署,降低了开发成本。其次,Flask的灵活性使得我们可以根据项目需求自由定制功能,而不会被框架本身所限制。最后,Flask的社区支持和文档资源为我们在开发过程中提供了强大的后盾。

(2)Echarts

Echarts是一个使用JavaScript实现的开源可视化库,它提供了直观、生动且交互性强的数据可视化图表。Echarts拥有丰富的图表类型,如折线图、柱状图、饼图等,能够满足各种数据可视化需求。此外,Echarts还支持丰富的配置项,允许用户根据自己的需求定制图表的样式和行为。

选择Echarts作为前端可视化工具的原因主要有以下几点:首先,Echarts的图表类型丰富,能够直观地展示中药材价格数据的各种特征。其次,Echarts的交互性强,用户可以通过鼠标悬停、点击等操作与图表进行互动,获取更多信息。最后,Echarts的开源特性使得我们可以免费使用并对其进行定制,以满足项目的特定需求。

综上所述,Flask和Echarts分别在后端框架和前端可视化工具方面具有显著的优势,它们的结合使得我们能够高效地构建出功能强大且界面美观的中药材价格分析与可视化平台。

3.数据收集

        在上一篇文章中我们已经完成了数据收集:

Python爬虫爬取中药材价格数据-CSDN博客 

4.项目结构

 

 5.项目开发

(1)后端开发(Flask)

app.py(部分):

python">import jsonfrom flask_cors import *
from flask import Flask, render_template, Response
from DBhelper import DBHelper
from SQLdesign import *# 创建一个 Flask web 应用实例,命名为 app。
app = Flask(__name__)# 如果需要前后端分离或者在其他地方使用异步请求的时,需要加上这一行,解决跨域问题。
CORS(app, supports_credentials=True)# 使用 app.route() 装饰器来定义一个路由。
# 当用户访问应用的根 URL('/')时,会调用下面的 index() 函数。
@app.route('/')
# 定义一个名为 index 的函数,它返回一个响应。
def index():# 使用 render_template 函数来渲染一个名为 'index.html' 的模板文件,# 并将其作为响应返回给客户端。这通常是一个 HTML 文件,用于显示网页内容。return render_template('index.html')'''市场价格Top20'''
# 使用 Flask 的 app.route() 装饰器定义一个新的路由,当用户访问 '/priceTop20' URL 时,将执行下面的 priceTop20() 函数。
@app.route('/priceTop20')
# 定义一个名为 priceTop20 的函数,它用于处理 '/priceTop20' 路由的请求。
def priceTop20():# 创建一个 DBHelper 类的实例,并调用其 select_db 方法来从数据库中选取价格前20名的数据。# SelectPrice_top20 是一个用于查询的 SQL 语句。data = DBHelper().select_db(SelectPrice_top20)# 初始化两个空列表,用于存储从数据库中获取的商品名称和最近价格。names = []recentprices = []# 初始化一个空字典,用于存储结果。results = {}# 遍历从数据库中获取的数据。for i in data:# 将每条数据的 'name' 字段添加到 names 列表中。names.append(i['name'])# 将每条数据的 'recentprice' 字段添加到 recentprices 列表中。recentprices.append(i['recentprice'])# 将 names 列表添加到 results 字典的 'names' 键中。results['names'] = names# 将 recentprices 列表添加到 results 字典的 'recentprices' 键中。results['recentprices'] = recentprices# 使用 Flask 的 Response 对象来创建一个 JSON 格式的响应。# 使用 json.dumps() 将 results 字典转换为 JSON 格式的字符串。# 设置响应的 mimetype 为 'application/json',表示返回的是 JSON 数据。return Response(json.dumps(results), mimetype='application/json')

(2)前端开发(Echarts)

index.html:

<!DOCTYPE html>
<html style="height: 100%;width:100%"><head><meta charset="utf-8"><title>中药材价格可视化大屏</title><link rel="stylesheet" href="/static/css/index.css"></head>
<body><div class="container"><div id="title">中药材价格可视化大屏</div><div id="top"></div><div class="bottom-container"><div class="bottom-container-left"><div class="select"><select id="select_1"><option value="1" class="active">白术</option><option value="2">麦冬</option><option value="3">川芎</option><option value="4">白芍</option></select></div><div id="left"></div></div><div class="bottom-container-right"><div class="select"><select id="select_2"><option value="1" class="active">年涨幅</option><option value="2">月涨幅</option><option value="3">周涨幅</option></select></div><div id="right"></div></div></div></div><script type="text/javascript" src="/static/js/echarts.min.js"></script><script type="text/javascript" src="/static/js/jquery-3.5.1.min.js"></script><script type="text/javascript" src="/static/js/top.js"></script><script type="text/javascript" src="/static/js/left.js"></script><script type="text/javascript" src="/static/js/right.js"></script>
</body>
</html>

 top.js:

$.ajax({type: 'GET',url: "http://127.0.0.1:5000/priceTop20",dataType: 'json',success: function(data) {console.log(data);//html原本的js代码var dom = document.getElementById("top");var myChart = echarts.init(dom);var option;// var app ={};option = {title: {text: '市场价格Top20', // 标题文本内容// left: 'center', // 标题的水平位置,可选值包括 'left'、'center'、'right' 或者具体的像素值textStyle: { // 标题文本的样式color: '#333', // 字体颜色fontWeight: 'bold', // 字体粗细fontSize: 20 // 字体大小}},tooltip: {show: true},grid: {left: 30,top: 30,bottom: 20,right: 70,containLabel: true},xAxis: {type: 'value',name: '元/Kg',boundaryGap: false,max: data["recentprices"][0] + 500, // Math.ceil(max / 4) * 5 || 10axisLine: {show: true,lineStyle: {color: '#c78686'}},axisTick: {show: false},axisLabel: {color: '#2d2d2d'},splitLine: {lineStyle: {color: ['#CEEDFF'],type: [5, 8],dashOffset: 3}},},yAxis: {type: 'category',data: data["names"],name: "药材名称",axisLine: {show: true,lineStyle: {color: '#c78686'}},axisTick: {length: 3},axisLabel: {fontSize: 14,color: '#666',margin: 16,padding: 0},inverse: true,},series: [{type: 'bar',showBackground: true,backgroundStyle: {color: 'rgba(82, 168, 255, 0.1)',borderRadius: [0, 8, 8, 0]},itemStyle: {color: '#52A8FF',normal: {borderRadius: [0, 8, 8, 0],color: function(params) {// 定义一个颜色集合let colorList = ['#52A8FF','#00B389','#FFA940','#FF5A57','#29EFC4','#F8AEA4','#FFC53D','#009982','#C099FC','#F5855F','#52A8FF','#00B389','#FFA940','#FF5A57','#29EFC4','#F8AEA4','#FFC53D','#009982','#C099FC','#F5855F',];// 对每个bar显示一种颜色return colorList[params.dataIndex];},},},barMaxWidth: 16,label: {show: true,position: 'right',offset: [-5, 2],color: '#65de67'},data: data["recentprices"],}, ],};if (option && typeof option === 'object') {myChart.setOption(option);}// 监听窗口的resize事件window.addEventListener('resize', function() {myChart.resize(); // 调用图表的resize方法});}
});

jquery-3.5.1.min.jsecharts.min.js很容易从网上下载到。

注意:由于篇幅有限,并未在此给出完整源码,完整源码可通过文章底部个人名片获取!

 6.项目运行与展示

(1)运行项目

(2)接口展示

/priceTop20:

/fluctuationTop10:

/historicalprice:

 

(3)效果展示


http://www.ppmy.cn/embedded/20790.html

相关文章

记录不熟悉的函数用法(C++)——insert

2. insert 记录起因&#xff1a;接上一篇的例子&#xff0c;不知道为什么使用insert进行插入之前要先执行clear操作&#xff0c;非得这么做吗&#xff1f;我可以认为这个clear操作是对应于为空字符串的&#xff0c;可是仍然纠结insert它具体插入的位置&#xff0c;在后面追加还…

Linux---为什么会有粘滞位?

在前面已经讲过目录的rwx权限&#xff1a; 可读权限(r): 如果目录没有可读权限, 则无法用ls等命令查看目录中的文件内容. 有可写权限(w):如果目录没有可写权限&#xff0c;则无法在目录中创建文件, 也无法在目录中删除文件.可执行权限(x): 如果目录没有可执行权限, 则无法cd到…

【C++】6-11 停车场收费问题 分数 20

6-11 停车场收费问题 分数 20 全屏浏览 切换布局 作者 徐婉珍 单位 广东东软学院 在停车场收费系统中&#xff0c;收费者会根据车型的不同按不同的单价和计费方式收取不同的停车费&#xff0c;其中&#xff1a; 轿车Car&#xff1a;每小时8元&#xff0c;超过30分钟按一小时…

BootStrap详解

Bootstrap简介 什么是BootStrap&#xff1f; BootStrap来自Twitter&#xff0c;是目前最受欢迎的响应式前端框Bootstrap是基于HTML、CSS、JavaScript的&#xff0c;它简洁灵活&#xff0c;使得Web开发更加快捷 为什么使用Bootstrap&#xff1f; 移动设备优先&#xff1a;自…

vue3学习笔记-快速上手

创建第一个vue3的应用 之前看书学习vue,书籍对应的版本是vue2,今天群里看小伙伴聊天&#xff0c;觉得他们说得对 &#xff0c;反正是从零开始学&#xff0c;而且vue2都不维护了&#xff0c;那为什么不直接学习vue3呢&#xff0c;于是乎&#xff0c;又开启了从0学vue3之路。 参考…

elasticsearch Docker启动Device or resource busy异常

问题 在基于Docker进行elasticsearch部署启动时&#xff0c;指定了elasticsearch.yml配置文件&#xff0c;但在启动时报如下异常&#xff1a; Exception in thread "main" java.nio.file.FileSystemException: /usr/share/elasticsearch/config/elasticsearch.yml.…

IDEA启动项目弹框提示:Lombok requires enabled annotation processing

问题现象 IDEA启动项目弹框提示如下图&#xff1a; 原因分析 由弹窗内容分析&#xff0c;首先确认我的IDEA中已经安装了Lombok插件&#xff0c;其次去settings中查找annotation processing配置&#xff0c;发现确实有这个配置并且未勾选启动 如何解决 修改配置

求三个字符数组最大者(C语言)

一、N-S流程图&#xff1b; 二、运行结果&#xff1b; 三、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h> # include <string.h>int main() {//初始化变量值&#xff1b;int i 0;char str[3][20];char string[20];//循环输入3个字符…