该项目利用 Flask
框架结合echarts
将MySQL
数据库中的相关数据进行可视化大屏展示,其中MySQL
数据采用虚拟实时更新数据
效果如下:
解析:
前端 JavaScript
通过 AJAX
调用 Flask
应用的路由获取数据库数据;Flask
应用向数据库操作模块请求并处理数据,这些数据来自于 MySQL
数据库。用户访问Flask
应用的主页,前端 JavaScript
在页面加载后自动请求数据,这些数据由 Flask
应用动态生成并从数据库中取出,然后显示在网页上。即从数据库获取数据,在后台处理,然后通过前端展现给用户,实现了前后端的有效分离和交互
环境准备:
echarts.min.js:
https://github.com/apache/echarts/tree/5.5.1/dist
jquery-3.5.1.min.js:
https://jquery.com/download/
image.jps:
背景图可以根据自己喜欢的样式自行查找MySQL数据来源有以下表
其中表有一些初始数据,可以创建一个sql文件使用source命令将数据导入
ex: flask_and_charts.sql
/*
Navicat Premium Data Transfer
Source Server : localhost
Source Server Type : MySQL
Source Server Version : 80030
Source Host : localhost:3306
Source Schema : flask_and_charts
Target Server Type : MySQL
Target Server Version : 80030
File Encoding : 65001
Date: 27/08/2024 18:23:58
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for proportion_of_canteen_diners
-- ----------------------------
DROP TABLE IF EXISTS `proportion_of_canteen_diners`;
CREATE TABLE `proportion_of_canteen_diners` (
`Place_of_con` char(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL,
`num_of_meals` int(0) NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of proportion_of_canteen_diners
-- ----------------------------
INSERT INTO `proportion_of_canteen_diners` VALUES ('第三食堂', 838);
INSERT INTO `proportion_of_canteen_diners` VALUES ('第四食堂', 968);
INSERT INTO `proportion_of_canteen_diners` VALUES ('第五食堂', 950);
INSERT INTO `proportion_of_canteen_diners` VALUES ('第二食堂', 972);
INSERT INTO `proportion_of_canteen_diners` VALUES ('第一食堂', 598);
INSERT INTO `proportion_of_canteen_diners` VALUES ('第六食堂', 721);
-- ----------------------------
-- Table structure for solarterms
-- ----------------------------
DROP TABLE IF EXISTS `solarterms`;
CREATE TABLE `solarterms` (
`Term` varchar(20) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
`Rainfall` int(0) NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of solarterms
-- ----------------------------
INSERT INTO `solarterms` VALUES ('立春', 169);
INSERT INTO `solarterms` VALUES ('雨水', 126);
INSERT INTO `solarterms` VALUES ('惊蛰', 160);
INSERT INTO `solarterms` VALUES ('春分', 251);
INSERT INTO `solarterms` VALUES ('清明', 201);
INSERT INTO `solarterms` VALUES ('谷雨', 106);
INSERT INTO `solarterms` VALUES ('立夏', 128);
INSERT INTO `solarterms` VALUES ('小满', 111);
INSERT INTO `solarterms` VALUES ('芒种', 91);
INSERT INTO `solarterms` VALUES ('夏至', 143);
INSERT INTO `solarterms` VALUES ('小暑', 150);
INSERT INTO `solarterms` VALUES ('大暑', 107);
INSERT INTO `solarterms` VALUES ('立秋', 102);
INSERT INTO `solarterms` VALUES ('处暑', 271);
INSERT INTO `solarterms` VALUES ('白露', 296);
INSERT INTO `solarterms` VALUES ('秋分', 123);
INSERT INTO `solarterms` VALUES ('寒露', 203);
INSERT INTO `solarterms` VALUES ('霜降', 244);
INSERT INTO `solarterms` VALUES ('立冬', 259);
INSERT INTO `solarterms` VALUES ('小雪', 58);
INSERT INTO `solarterms` VALUES ('大雪', 265);
INSERT INTO `solarterms` VALUES ('冬至', 174);
INSERT INTO `solarterms` VALUES ('小寒', 106);
INSERT INTO `solarterms` VALUES ('大寒', 256);
-- ----------------------------
-- Table structure for weekdayspending
-- ----------------------------
DROP TABLE IF EXISTS `weekdayspending`;
CREATE TABLE `weekdayspending` (
`Con_time` char(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL,
`Num_of_Con` int(0) NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of weekdayspending
-- ----------------------------
INSERT INTO `weekdayspending` VALUES ('0', 19316);
INSERT INTO `weekdayspending` VALUES ('1', 9593);
INSERT INTO `weekdayspending` VALUES ('2', 4729);
INSERT INTO `weekdayspending` VALUES ('3', 4723);
INSERT INTO `weekdayspending` VALUES ('4', 7187);
INSERT INTO `weekdayspending` VALUES ('5', 10866);
INSERT INTO `weekdayspending` VALUES ('6', 17697);
INSERT INTO `weekdayspending` VALUES ('7', 14591);
INSERT INTO `weekdayspending` VALUES ('8', 19423);
INSERT INTO `weekdayspending` VALUES ('9', 17243);
INSERT INTO `weekdayspending` VALUES ('10', 6242);
INSERT INTO `weekdayspending` VALUES ('11', 14059);
INSERT INTO `weekdayspending` VALUES ('12', 4906);
INSERT INTO `weekdayspending` VALUES ('13', 4512);
INSERT INTO `weekdayspending` VALUES ('14', 19653);
INSERT INTO `weekdayspending` VALUES ('15', 1076);
INSERT INTO `weekdayspending` VALUES ('16', 10672);
INSERT INTO `weekdayspending` VALUES ('17', 1865);
INSERT INTO `weekdayspending` VALUES ('18', 12185);
INSERT INTO `weekdayspending` VALUES ('19', 5886);
INSERT INTO `weekdayspending` VALUES ('20', 4200);
INSERT INTO `weekdayspending` VALUES ('21', 13343);
INSERT INTO `weekdayspending` VALUES ('22', 2839);
INSERT INTO `weekdayspending` VALUES ('23', 16634);
SET FOREIGN_KEY_CHECKS = 1;
导入后检查一下:
充当 web 服务器,处理用户请求并返回相应的数据或者页面。它包含多个路由,负责从后端数据库获取数据并以 JSON 格式返回给前端。
from flask import Flask, render_template
import json
import utils
app = Flask(__name__)
@app.route('/')
def index():
return render_template('main.html')
#TODO 左一路由
@app.route('/datal1')
def l1_data():
data_list = []
for key in utils.get_l1_data():
name = key[0]
# 将Decimal转换为float
value = float(key[1])
data_list.append({"name": name, "value": value})
json_data = json.dumps(data_list, ensure_ascii=False) # ensure_ascii=False参数用于正确显示中文字符
return json_data
#TODO 左二路由
@app.route('/datal2')
def l2_data():
data_list = []
for key in utils.get_l2_data():
name = key[0]
# 将Decimal转换为float
value = float(key[1])
data_list.append({"name": name, "value": value})
json_data = json.dumps(data_list, ensure_ascii=False) # ensure_ascii=False参数用于正确显示中文字符
return json_data
#TODO 右一路由
@app.route('/datar1')
def r1_data():
data_list = []
for key in utils.get_r1_data():
name = key[0]
# 将Decimal转换为float
value = float(key[1])
data_list.append({"name": name, "value": value})
json_data = json.dumps(data_list, ensure_ascii=False) # ensure_ascii=False参数用于正确显示中文字符
return json_data
#TODO 右二路由
@app.route('/datar2')
def r2_data():
data_list = []
for key in utils.get_r2_data():
name = key[0]
# 将Decimal转换为float
value = float(key[1])
data_list.append({"name": name, "value": value})
json_data = json.dumps(data_list, ensure_ascii=False) # ensure_ascii=False参数用于正确显示中文字符
return json_data
#TODO 中二路由
@app.route('/datac2')
def c2_data():
data_list = []
for key in utils.get_c2_data():
name = key[0]
# 将Decimal转换为float
value = float(key[1])
data_list.append({"name": name, "value": value})
json_data = json.dumps(data_list, ensure_ascii=False) # ensure_ascii=False参数用于正确显示中文字符
return json_data
#TODO 中一路由01
@app.route('/datac101')
def c1_data_01():
return utils.get_c1_data01()[0][0]
#TODO 中一路由02
@app.route('/datac102')
def c1_data_02():
return utils.get_c1_data02()[0][0]
if __name__ == '__main__':
app.run(debug=True)
主要用于封装数据库连接和查询逻辑。通过 pymysql 库与 MySQL 数据库进行交互,包括打开/关闭数据库连接,执行 SQL 查询等
import pymysql
def get_db_connection():
conn = pymysql.connect(host='localhost',
database='Flask_And_Charts',
user='root',
password='123456',
port=3306)
curses = conn.cursor()
return conn, curses
def close_conn(conn, cursor):
cursor.close()
conn.close()
def query(sql, *args):
conn, cursor = get_db_connection()
try:
cursor.execute(sql, args)
res = cursor.fetchall() # 尝试获取查询结果
conn.commit()
return res if res else [] # 如果res不为空,则返回res,否则返回空列表
except Exception as e:
print(f"Error executing query: {e}")
conn.rollback() # 发生错误时回滚
return [] # 发生异常时返回空列表
finally:
close_conn(conn, cursor)
#TODO 左一数据源
def get_l1_data():
sql = "SELECT Place_of_con, SUM(num_of_meals) FROM proportion_of_canteen_diners GROUP BY Place_of_con;"
res = query(sql)
return res
#TODO 左二数据源
def get_l2_data():
sql = "SELECT * FROM weekdayspending;"
res = query(sql)
return res
#TODO 右一数据源
def get_r1_data():
sql = "SELECT * FROM weekdayspending;"
res = query(sql)
return res
#TODO 左一数据源
def get_r2_data():
sql = "SELECT Place_of_con, SUM(num_of_meals) FROM proportion_of_canteen_diners GROUP BY Place_of_con;"
res = query(sql)
return res
#TODO 中二数据源
def get_c2_data():
sql = "SELECT * FROM SolarTerms;"
res = query(sql)
return res
#TODO 中一数据源01
def get_c1_data01():
sql = "SELECT Con_time FROM weekdayspending WHERE Num_of_Con = (SELECT MAX(Num_of_Con) FROM weekdayspending);"
res = query(sql)
return res
#TODO 中一数据源02
def get_c1_data02():
sql = "SELECT Place_of_con FROM proportion_of_canteen_diners WHERE num_of_meals = (SELECT MAX(num_of_meals) FROM proportion_of_canteen_diners);"
res = query(sql)
return res
通过 AJAX 请求获取 Flask 服务器提供的数据,并使用这些数据来动态更新图表或页面内容
// 左一数据更新
// 定义一个名为 get_l1_data01 的 JavaScript 函数
function get_l1_data01() {
// 使用 jQuery 的 AJAX 方法进行异步请求
$.ajax({
// 设置请求的 URL 地址,这里是 "/datal1",此为服务器端的数据接口
url: "/datal1",
// 设置请求类型为 GET
type: "GET",
// 设置预期从服务器返回的数据类型为 JSON
dataType: "json",
// 请求成功时的回调函数,data 参数包含了从服务器返回的数据
success: function(data) {
// 调用 drawPieChart 函数,并将从服务器获取到的数据传递给它
drawPieChart(data);
},
// 请求失败时的回调函数,xhr 包含了 XMLHttpRequest 对象,type 是错误类型,errorThrown 是错误信息
error: function(xhr, type, errorThrown) {
// 在控制台打印错误信息
console.error("Error in Ajax request: ", type);
}
});
}
// 左二数据更新
function get_l2_data01() {
$.ajax({
url: "/datal2",
type: "GET",
dataType: "json",
success: function(data) {
drawLineChart(data);
},
error: function(xhr, type, errorThrown) {
console.error("Error in Ajax request: ", type);
}
});
}
// 右一数据更新
function get_r1_data01() {
$.ajax({
url: "/datar1",
type: "GET",
dataType: "json",
success: function(data) {
drawScatterChart(data);
},
error: function(xhr, type, errorThrown) {
console.error("Error in Ajax request: ", type);
}
});
}
// 右二数据更新
function get_r2_data01() {
$.ajax({
url: "/datar2",
type: "GET",
dataType: "json",
success: function(data) {
drawBarChart(data);
},
error: function(xhr, type, errorThrown) {
console.error("Error in Ajax request: ", type);
}
});
}
// 右一数据更新
function get_c2_data01() {
$.ajax({
url: "/datac2",
type: "GET",
dataType: "json",
success: function(data) {
drawPolarLineChart(data);
},
error: function(xhr, type, errorThrown) {
console.error("Error in Ajax request: ", type);
}
});
}
// 右一数据更新
function get_c2_data01() {
$.ajax({
url: "/datac2",
type: "GET",
dataType: "json",
success: function(data) {
drawPolarLineChart(data);
},
error: function(xhr, type, errorThrown) {
console.error("Error in Ajax request: ", type);
}
});
}
// 中一数据01更新
function get_c1_data01() {
$.ajax({
url: "/datac101",
type: "GET",
dataType: "TEXT",
success: function(data) {
$('#c1_01_02').text(data);
},
error: function(xhr, type, errorThrown) {
console.error("Error in Ajax request: ", type);
}
});
}
// 中一数据02更新
function get_c1_data02() {
$.ajax({
url: "/datac102",
type: "GET",
dataType: "TEXT",
success: function(data) {
$('#c1_02_02').text(data);
},
error: function(xhr, type, errorThrown) {
console.error("Error in Ajax request: ", type);
}
});
}
function updateAllData() {
get_l1_data01();
get_l2_data01();
get_r1_data01();
get_r2_data01();
get_c2_data01();
get_c1_data01();
get_c1_data02();
}
document.addEventListener('DOMContentLoaded', function() {
updateAllData(); // 初次加载时立即更新一次数据
setInterval(updateAllData, 1000); // 每1000毫秒(即每秒)更新一次数据
});
该程序主要是对MySQL数据进行实时更新
import utils
import random
import time
#TODO list_Place_of_con
sql = "SELECT Place_of_con FROM proportion_of_canteen_diners;"
res = utils.query(sql)
list_Place_of_con = []
for i in res:
list_Place_of_con.append(i[0])
print(list_Place_of_con)
#TODO list_Term
sql = "SELECT Term FROM solarterms;"
Term = utils.query(sql)
list_Term = []
for i in Term:
list_Term.append(i[0])
print(list_Term)
#TODO Con_time
sql = "SELECT Con_time FROM weekdayspending;"
Con_time = utils.query(sql)
list_Con_time = []
for i in Con_time:
list_Con_time.append(i[0])
print(list_Con_time)
while True:
# 使用之前查询得到的 list_Place_of_con 更新 proportion_of_canteen_diners 表
for place in list_Place_of_con:
num_of_meals_change = random.randint(200, 1000)
update_query = f"UPDATE proportion_of_canteen_diners SET num_of_meals = {num_of_meals_change} WHERE Place_of_con = %s;"
utils.query(update_query, (place,))
print(f"更新 {place} 的 num_of_meals 为 {num_of_meals_change}")
# 使用之前查询得到的 list_Term 更新 solarterms 表
for term in list_Term:
rainfall_change = random.randint(50, 300)
update_query = f"UPDATE solarterms SET Rainfall = {rainfall_change} WHERE Term = %s;"
utils.query(update_query, (term,))
print(f"更新 {term} 的 Rainfall 为 {rainfall_change}")
# 使用之前查询得到的 list_Con_time 更新 weekdayspending 表
for con_time in list_Con_time:
num_of_con_change = random.randint(500, 20000)
update_query = f"UPDATE weekdayspending SET Num_of_Con = {num_of_con_change} WHERE Con_time = %s;"
utils.query(update_query, (con_time,))
print(f"更新消费时段 {con_time} 的 Num_of_Con 为 {num_of_con_change}")
# 可以加入一些延迟避免过于频繁的更新
time.sleep(2)
主要用于显示前端页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>可视化大屏</title>
<link href="../static/main.css" rel="stylesheet" />
<script src="../static/jquery-3.5.1.min.js"></script>
<script src="../static/echarts.min.js"></script>
</head>
<body>
<div id="title">Python数据可视化大屏</div>
<div id="time">时间</div>
<div id="l1"></div>
<div id="l2"></div>
<div id="c1">
<div id="c1_01">
<div id="c1_01_01">最高消费时段</div>
<div id="c1_01_02"></div>
</div>
<div id="c1_02">
<div id="c1_02_01">消费最高食堂</div>
<div id="c1_02_02"></div>
</div>
</div>
<div id="c2"></div>
<div id="r1"></div>
<div id="r2"></div>
<!-- 左一饼图 -->
<script src="../static/pietest.js"></script>
<!-- 左二柱状图 -->
<script src="../static/LineCharttest.js"></script>
<!-- 右一散点图 -->
<script src="../static/scattertest.js"></script>
<!-- 右二柱状图 -->
<script src="../static/histogramtest.js"></script>
<!-- 中二图 -->
<script src="../static/Coordinatesystemtest.js"></script>
<!-- 前端数据刷新 -->
<script src="../static/controller.js"></script>
<script>
function updateTime() {
var now = new Date();
var year = now.getFullYear();
var month = now.getMonth() + 1; // getMonth() 返回的月份是从0开始的
var day = now.getDate();
var hours = now.getHours();
var minutes = now.getMinutes();
var seconds = now.getSeconds();
// 补零操作
month = month < 10 ? '0' + month : month;
day = day < 10 ? '0' + day : day;
minutes = minutes < 10 ? '0' + minutes : minutes;
seconds = seconds < 10 ? '0' + seconds : seconds;
var formattedTime = year + '-' + month + '-' + day + ' ' + hours + ":" + minutes + ":" + seconds;
document.getElementById('time').innerHTML = formattedTime;
}
// 页面加载时立即更新时间
updateTime();
// 每秒钟更新一次时间
setInterval(updateTime, 1000);
</script>
</body>
</html>
主要用于修饰main.html的内容
* {
font-family: KaiTi, Arial, sans-serif;
}
body {
margin: 0;
background-image: url('./image.jpg');
background-size: cover;
background-position: center;
background-repeat: no-repeat;
background-attachment: fixed; /* 背景固定,不随内容滚动 */
}
#alldiv {
height: 100%;
width: 100%;
top: 0%;
left: 0%;
}
#title {
position: absolute;
height: 10%;
width: 50%;
left: 25%;
top: 0%;
color: aqua;
font-size: 50px;
font-weight: bold;
display: flex;
align-items: center;
justify-content: center;
}
#time {
position: absolute;
height: 10%;
width: 25%;
left: 75%;
top: 0%;
color: aqua;
font-size: 25px;
display: flex;
align-items: center;
justify-content: center;
}
#l1 {
position: absolute;
height: 45%;
width: 30%;
left: 0%;
top: 10%;
display: flex;
align-items: center;
justify-content: center;
}
#l2 {
position: absolute;
height: 45%;
width: 30%;
left: 0%;
top: 55%;
}
#r1 {
position: absolute;
height: 45%;
width: 30%;
left: 70%;
top: 10%;
}
#r2 {
position: absolute;
height: 45%;
width: 30%;
left: 70%;
top: 55%;
}
#c1 {
position: absolute;
height: 30%;
width: 40%;
left: 30%;
top: 10%;
}
#c2 {
position: absolute;
height: 60%;
width: 40%;
left: 30%;
top: 40%;
}
#c1_01 {
position: absolute;
height: 100%;
width: 50%;
left: 0%;
top: 0%;
}
#c1_02 {
position: absolute;
height: 100%;
width: 50%;
left: 50%;
top: 0%;
}
#c1_01_01 {
height: 60%;
width: auto;
font-size: 40px;
font-weight: bold;
display: flex;
align-items: center;
justify-content: center;
color: aqua;
}
#c1_01_02 {
height: 40%;
width: auto;
font-size: 25px;
font-weight: bold;
display: flex;
align-items: top;
justify-content: center;
color: aqua;
}
#c1_02_01 {
height: 60%;
width: auto;
font-size: 40px;
font-weight: bold;
display: flex;
align-items: center;
justify-content: center;
color: aqua;
}
#c1_02_02 {
height: 40%;
width: auto;
font-size: 25px;
font-weight: bold;
display: flex;
align-items: top;
justify-content: center;
color: aqua;
}
function drawPolarLineChart(data) {
var myChart = echarts.init(document.getElementById('c2'));
var option = {
title: {
text: '24节气雨量',
left: 'center',
textStyle: {
color: 'aqua' // 修改标题颜色为aqua
}
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
}
},
angleAxis: {
type: 'category',
data: data.map(item => item.name),
boundaryGap: false,
splitLine: {
show: true,
lineStyle: {
type: 'dashed'
}
},
axisLine: {
lineStyle: {
color: 'aqua' // 修改角度轴线颜色为aqua
}
},
axisLabel: {
color: 'aqua' // 修改角度轴标签颜色为aqua
}
},
radiusAxis: {
axisLine: {
lineStyle: {
color: 'aqua' // 修改半径轴线颜色为aqua
}
},
axisLabel: {
color: 'aqua' // 修改半径轴标签颜色为aqua
}
},
polar: {
},
series: [
{
name: '雨量',
type: 'line',
data: data.map(item => item.value),
coordinateSystem: 'polar',
smooth: true,
lineStyle: {
color: 'red' // 指定线条颜色为aqua
}
}
]
};
myChart.setOption(option);
}
function drawBarChart(data) {
var myChart = echarts.init(document.getElementById('r2'));
var option = {
title: {
text: '2023年食堂就餐占比',
left: 'center',
textStyle: {
color: 'aqua' // 修改标题字体颜色
}
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {
data: ['就餐占比'],
left: 'right',
textStyle: {
color: 'aqua' // 修改图例字体颜色
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
data: data.map(item => item.name),
axisLine: {
lineStyle: {
color: 'aqua' // 修改x轴线颜色
}
},
axisLabel: {
color: 'aqua' // 修改x轴标签字体颜色
}
},
yAxis: {
type: 'value',
axisLine: {
lineStyle: {
color: 'aqua' // 修改y轴线颜色
}
},
axisLabel: {
color: 'aqua' // 修改y轴标签字体颜色
}
},
series: [{
name: '就餐占比',
type: 'bar',
data: data.map(item => item.value),
markPoint: {
data: [
{type: 'max', name: '最大值'},
{type: 'min', name: '最小值'}
]
},
markLine: {
data: [{type: 'average', name: '平均值'}]
},
itemStyle: {
// 设置柱状图颜色为浅绿色
color: 'rgba(102, 204, 153, 1)',
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}]
};
myChart.setOption(option);
}
function drawLineChart(data) {
var myChart = echarts.init(document.getElementById('l2'));
var option = {
title: {
text: '24小时消费次数',
left: 'center',
textStyle: {
color: 'aqua' // 修改标题颜色为aqua
}
},
tooltip: {
trigger: 'axis'
},
legend: {
data: ['消费次数'],
left: 'left',
textStyle: {
color: 'aqua' // 修改图例文字颜色为aqua
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: data.map(item => item.name), // 使用 name 作为 X 轴的数据
axisLabel: {
color: 'aqua' // 修改x轴标签颜色为aqua
},
axisLine: {
lineStyle: {
color: 'aqua' // 修改x轴线颜色为aqua
}
}
},
yAxis: {
type: 'value',
axisLabel: {
color: 'aqua' // 修改y轴标签颜色为aqua
},
axisLine: {
lineStyle: {
color: 'aqua' // 修改y轴线颜色为aqua
}
}
},
series: [
{
name: '消费次数',
type: 'line',
data: data.map(item => item.value), // 使用 value 作为 Y 轴的数据
lineStyle: {
color: 'yellow' // 线条颜色,不改动
},
symbol: 'star', // 数据点样式,不改动
itemStyle: {
color: 'purple', // 数据点颜色,不改动
borderColor: 'purple' // 数据点边框颜色,不改动
}
}
]
};
myChart.setOption(option);
}
function drawScatterChart(data) {
var myChart = echarts.init(document.getElementById('r1'));
var option = {
title: {
text: '24小时点击次数',
left: 'center',
textStyle: {
color: 'aqua' // 已设置为aqua
}
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
color: 'aqua' // 修改交叉轴指示器标签颜色为aqua
}
}
},
legend: {
data: ['点击次数'],
left: 'left',
textStyle: {
color: 'aqua' // 已设置为aqua
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: true,
data: data.map(item => item.name),
axisLabel: {
color: 'aqua' // 修改x轴标签颜色为aqua
},
axisLine: {
lineStyle: {
color: 'aqua' // 修改x轴线颜色为aqua
}
}
},
yAxis: {
type: 'value',
axisLabel: {
color: 'aqua' // 修改y轴标签颜色为aqua
},
axisLine: {
lineStyle: {
color: 'aqua' // 修改y轴线颜色为aqua
}
}
},
series: [
{
name: '消费次数',
type: 'scatter',
data: data.map(item => [item.name, item.value]),
symbolSize: function (data) {
return Math.sqrt(data[1]) / 2;
},
itemStyle: {
color: function (params) {
// 这里控制散点的颜色,不影响字体,故不修改
var colorList = [
'#ff6b6b', // 亮红色
'#f783ac', // 浅玫瑰色
'#da77f2', // 淡紫色
'#9775fa', // 淡蓝紫色
'#748ffc', // 淡蓝色
'#4dabf7', // 天蓝色
'#3bc9db', // 明亮青色
'#38d9a9', // 薄荷绿
'#63e6be', // 浅绿色
'#8ce99a', // 柔和绿色
'#c0eb75', // 浅橙绿色
'#ffe066', // 亮黄色
'#fcc419', // 金黄色
'#ff922b', // 橙色
'#ff6b6b', // 深橙色
'#fa5252', // 水红色
'#e64980', // 玫瑰红色
'#be4bdb', // 鲜紫色
'#7950f2', // 纯蓝紫色
'#4c6ef5', // 宝石蓝色
'#228be6', // 宝石蓝色
'#15aabf', // 青蓝色
'#12b886', // 青绿色
'#40c057', // 森林绿色
];
var index = params.dataIndex % colorList.length;
return colorList[index];
}
},
emphasis: {
focus: 'series',
label: {
show: true,
position: 'top',
color: 'aqua', // 修改强调时标签的字体颜色为aqua
formatter: function (param) {
return param.data[1];
}
}
},
}
]
};
myChart.setOption(option);
}
function drawPieChart(data) {
var myChart = echarts.init(document.getElementById('l1'));
var option = {
title: {
text: '2023年食堂就餐占比',
left: 'center',
textStyle: {
color: 'aqua' // 修改标题颜色
}
},
tooltip: {
trigger: 'item',
textStyle: {
color: 'aqua' // 修改提示框字体颜色
}
},
legend: {
orient: 'vertical',
left: 'left',
textStyle: {
color: 'aqua' // 修改图例文字颜色
}
},
series: [
{
name: '就餐占比',
type: 'pie',
radius: '45%',
roseType: 'radius',
data: data.map(item => ({
value: item.value,
name: item.name
})),
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
},
label: {
color: 'aqua' // 修改数据标签的字体颜色
}
}
]
};
myChart.setOption(option);
}
运行mysqlData.py
文件和flaskTest.py
文件,,浏览器打开该地址即可查看图表
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。