getEchartsData.py
python
from app.utils import getPublicData
# 从 app 应用的 utils 包中导入 getPublicData 模块
# getPublicData 是一个公共数据模块,提供了获取景点数据、用户数据等函数
import datetime
# 导入 Python 的 datetime 模块,用于处理日期和时间
# 这里主要用于将日期字符串转换为时间戳进行排序
travelInfoList = getPublicData.getAllTravelInfoMapData()
# 调用 getPublicData 模块中的 getAllTravelInfoMapData 函数
# 获取所有景点的完整数据,返回经过处理的景点对象列表
# 这个列表在全局范围内加载,供本模块的所有函数使用,避免重复查询数据库
# ============================================================================
# 城市和景点等级分析相关函数
# ============================================================================
def cityCharDataOne():
# 定义获取城市分布数据(按省份统计)的函数
# 用于生成柱状图或饼图,展示各省份的景点数量
cityDic = {}
# 初始化一个空字典,用于统计各省份的景点数量
# 键是省份名称,值是该省份的景点数量
for travel in travelInfoList:
# 遍历所有景点对象
if cityDic.get(travel.province, -1) == -1:
# 检查当前景点所在的省份是否已经在字典中
# dict.get(key, default) 方法:如果键存在返回对应的值,否则返回默认值 -1
# 如果返回 -1,说明这个省份还没有被记录过
cityDic[travel.province] = 1
# 将这个省份加入字典,并设置数量为 1
else:
cityDic[travel.province] += 1
# 如果省份已经存在,将其对应的数量加 1
return list(cityDic.keys()), list(cityDic.values())
# 返回两个列表:
# keys():省份名称列表,如 ['北京', '上海', '广东', ...]
# values():对应的景点数量列表,如 [15, 8, 23, ...]
# 这种格式适合前端图表库(如 ECharts)直接使用
def cityCharDataTwo():
# 定义获取城市分布数据(按景点等级统计)的函数
# 用于展示不同等级景区(5A、4A等)的数量分布
cityDic = {}
# 初始化空字典,用于统计各等级景点的数量
# 键是景点等级(如 '5A景区', '4A景区', '未评级'),值是该等级的数量
for travel in travelInfoList:
# 遍历所有景点对象
if cityDic.get(travel.level, -1) == -1:
# 检查当前景点的等级是否已经在字典中
cityDic[travel.level] = 1
# 如果不存在,加入字典并计数为 1
else:
cityDic[travel.level] += 1
# 如果已存在,计数加 1
resultData = []
# 初始化结果列表
for key, value in cityDic.items():
# 遍历统计好的字典
# key 是等级名称,value 是该等级的景点数量
resultData.append({
'name': key,
'value': value
})
# 转换成 {name: '5A景区', value: 25} 的格式
# 这种格式适合前端图表库的饼图、环形图等
return resultData
# 返回处理后的数据
# ============================================================================
# 评分情况分析相关函数
# ============================================================================
def getRateCharDataOne(travelList):
# 定义获取评分分布数据(按星级统计)的函数
# 参数 travelList 是景点对象列表(可能是筛选后的)
# 统计各星级(如 45星、40星等)的景点数量
startDic = {}
# 初始化空字典,注意变量名拼写:startDic 应该是 starDic(星级字典)
for travel in travelList:
# 遍历传入的景点列表
if startDic.get(travel.star, -1) == -1:
# 检查当前景点的星级是否已经在字典中
# travel.star 是星级评分,如 45 表示 4.5星
startDic[travel.star] = 1
# 如果不存在,加入字典并计数为 1
else:
startDic[travel.star] += 1
# 如果已存在,计数加 1
resultData = []
# 初始化结果列表
for key, value in startDic.items():
# 遍历统计好的字典
resultData.append({
'name': key,
'value': value
})
# 转换成 {name: '45', value: 12} 的格式
return resultData
# 返回星级分布数据
def getRateCharDataTwo(travelList):
# 定义获取评分分布数据(按具体分数统计)的函数
# 参数 travelList 是景点对象列表
# 统计各分数(如 5.0、4.5、4.0等)的景点数量
startDic = {}
# 初始化空字典(同样有拼写问题,应该是 starDic)
for travel in travelList:
# 遍历所有景点
if startDic.get(travel.score, -1) == -1:
# 检查当前景点的分数是否已经在字典中
# travel.score 是具体分数,如 '5.0'、'4.5' 等
startDic[travel.score] = 1
# 如果不存在,加入字典并计数为 1
else:
startDic[travel.score] += 1
# 如果已存在,计数加 1
resultData = []
# 初始化结果列表
for key, value in startDic.items():
# 遍历统计好的字典
resultData.append({
'name': key,
'value': value
})
# 转换成 {name: '5.0', value: 8} 的格式
return resultData
# 返回分数分布数据
# ============================================================================
# 价格销量分析相关函数
# ============================================================================
def getPriceCharDataOne(traveList):
# 定义获取价格分布数据的函数
# 函数注释:景点价格趋势分析
# 将景点按价格区间分组统计
xData = ['免费', '100元以内', '200元以内', '300元以内', '400元以内', '500元以内', '500元以外']
# 定义价格区间的标签列表
# 注意:第一个区间是'免费',但后面判断用的是 price <= 10,逻辑上应该是价格<=10元的视为免费
yData = [0 for x in range(len(xData))]
# 初始化一个与 xData 长度相同的零列表,用于存储各价格区间的景点数量
# 列表推导式生成 [0, 0, 0, 0, 0, 0, 0]
for travel in traveList:
# 遍历所有景点
price = float(travel.price)
# 将景点的价格字段(字符串)转换为浮点数
# 因为价格可能包含小数,所以使用 float()
if price <= 10:
# 如果价格小于等于 10 元,视为免费
# 这里逻辑可能有问题:免费应该是 price == 0,但有些景点可能只收几元管理费
yData[0] += 1
# 第一个区间(免费)计数加 1
elif price <= 100:
# 如果价格在 10-100 元之间(包含100)
yData[1] += 1
# 第二个区间(100元以内)计数加 1
elif price <= 200:
# 如果价格在 100-200 元之间
yData[2] += 1
elif price <= 300:
# 如果价格在 200-300 元之间
yData[3] += 1
elif price <= 400:
# 如果价格在 300-400 元之间
yData[4] += 1
elif price <= 500:
# 如果价格在 400-500 元之间
yData[5] += 1
elif price > 500:
# 如果价格大于 500 元
yData[6] += 1
return xData, yData
# 返回两个列表:价格区间标签和对应的景点数量
def getPriceCharDataTwo(traveList):
# 定义获取销量分布数据的函数
# 函数注释:景点销量分析
# 将景点按销量区间分组统计
xData = [str(x * 300) + '份以内' for x in range(1, 15)]
# 生成销量区间标签
# 列表推导式:x 从 1 到 14,生成标签如:
# '300份以内', '600份以内', '900份以内', ... '4200份以内'
yData = [0 for x in range(len(xData))]
# 初始化一个与 xData 长度相同的零列表,用于存储各销量区间的景点数量
for travel in traveList:
# 遍历所有景点
saleCount = float(travel.saleCount)
# 将景点的销量字段(字符串)转换为浮点数
for x in range(1, 15):
# 循环遍历 1 到 14
count = x * 300
# 计算当前区间的上限,如 300、600、900...
if saleCount <= count:
# 如果当前景点的销量小于等于当前区间上限
yData[x - 1] += 1
# 对应区间计数加 1
# 因为列表索引从 0 开始,而 x 从 1 开始,所以用 x-1
break
# 找到所属区间后跳出内层循环,避免重复计数
return xData, yData
# 返回销量区间标签和对应的景点数量
def getPriceCharDataThree(travelList):
# 定义获取折扣分布数据的函数
# 统计各种折扣类型的景点数量
startDic = {}
# 初始化空字典(变量名 startDic 应该是 discountDic)
for travel in travelList:
# 遍历所有景点
if startDic.get(travel.discount, -1) == -1:
# 检查当前景点的折扣类型是否已经在字典中
# travel.discount 是折扣信息,如 '8折'、'学生票半价' 等
startDic[travel.discount] = 1
# 如果不存在,加入字典并计数为 1
else:
startDic[travel.discount] += 1
# 如果已存在,计数加 1
resultData = []
# 初始化结果列表
for key, value in startDic.items():
# 遍历统计好的字典
resultData.append({
'name': key,
'value': value
})
# 转换成 {name: '8折', value: 15} 的格式
return resultData
# 返回折扣分布数据
# ============================================================================
# 评论分析相关函数
# ============================================================================
def getCommentsCharDataOne():
# 定义获取评论时间分布数据的函数
# 统计每天有多少条评论,用于展示评论的时间趋势
commentsList = getPublicData.getAllCommentsData()
# 调用公共模块中的函数,获取所有景点的所有评论
# 返回一个包含所有评论的列表,每个评论是一个字典
xData = []
# 初始化 xData 列表,用于存储评论日期
def get_list(date):
# 定义一个内部辅助函数,用于将日期字符串转换为时间戳
# 参数 date 是日期字符串,格式如 '2024-03-19'
return datetime.datetime.strptime(date, '%Y-%m-%d').timestamp()
# datetime.strptime() 将字符串解析为 datetime 对象
# 指定格式 '%Y-%m-%d' 表示年-月-日
# timestamp() 将 datetime 对象转换为 Unix 时间戳(浮点数)
# 时间戳可以方便地进行日期比较和排序
for comment in commentsList:
# 遍历所有评论
xData.append(comment['date'])
# 将每条评论的日期添加到 xData 列表
xData = list(set(xData))
# set() 将列表转换为集合,自动去重
# 因为很多评论可能是同一天的,这里只保留唯一的日期
xData = list(sorted(xData, key=lambda x: get_list(x), reverse=True))
# sorted() 对 xData 进行排序
# key=lambda x: get_list(x) 指定按日期的时间戳排序
# reverse=True 表示降序排列,最新的日期在前
yData = [0 for x in range(len(xData))]
# 初始化与 xData 长度相同的零列表,用于存储每天的评论数量
for comment in commentsList:
# 再次遍历所有评论
for index, date in enumerate(xData):
# 遍历已排序的唯一日期列表
# enumerate 同时获取索引(index)和日期值(date)
if comment['date'] == date:
# 如果当前评论的日期等于当前遍历到的日期
yData[index] += 1
# 对应日期的评论计数加 1
return xData, yData
# 返回两个列表:日期列表和对应的评论数量列表
def getCommentsCharDataTwo():
# 定义获取评论评分分布数据的函数
# 统计不同评分(1-5分)的评论数量
commentsList = getPublicData.getAllCommentsData()
# 获取所有评论列表
startDic = {}
# 初始化空字典(变量名应该是 scoreDic)
for travel in commentsList:
# 遍历所有评论
# 注意变量名 travel 实际是 comment,容易引起误解
if startDic.get(travel['score'], -1) == -1:
# 检查当前评论的评分是否已经在字典中
# travel['score'] 是这条评论的评分
startDic[travel['score']] = 1
# 如果不存在,加入字典并计数为 1
else:
startDic[travel['score']] += 1
# 如果已存在,计数加 1
resultData = []
# 初始化结果列表
for key, value in startDic.items():
# 遍历统计好的字典
resultData.append({
'name': key,
'value': value
})
# 转换成 {name: '5', value: 128} 的格式
return resultData
# 返回评论评分分布数据
def getCommentsCharDataThree():
# 定义获取评论数量分布数据的函数
# 统计景点按评论数量分组的分布情况
travelList = getPublicData.getAllTravelInfoMapData()
# 获取所有景点列表
xData = [str(x * 1000) + '条以内' for x in range(1, 20)]
# 生成评论数量区间标签
# x 从 1 到 19,生成标签如:
# '1000条以内', '2000条以内', '3000条以内', ... '19000条以内'
yData = [0 for x in range(len(xData))]
# 初始化与 xData 长度相同的零列表,用于存储各区间的景点数量
for travel in travelList:
# 遍历所有景点
saleCount = int(travel.commentsLen)
# 将景点的评论数字段(字符串)转换为整数
for x in range(1, 20):
# 循环遍历 1 到 19
count = x * 1000
# 计算当前区间的上限,如 1000、2000、3000...
if saleCount <= count:
# 如果当前景点的评论数小于等于当前区间上限
yData[x - 1] += 1
# 对应区间计数加 1
break
# 找到所属区间后跳出内层循环
return xData, yData
# 返回评论数量区间标签和对应的景点数量
函数功能总结
| 函数 | 功能 | 返回数据 |
|---|---|---|
| cityCharDataOne | 统计各省份景点数量 | 省份列表、对应数量列表 |
| cityCharDataTwo | 统计各等级景点数量 | 等级分布字典列表 |
| getRateCharDataOne | 统计各星级景点数量 | 星级分布字典列表 |
| getRateCharDataTwo | 统计各分数景点数量 | 分数分布字典列表 |
| getPriceCharDataOne | 价格区间分布统计 | 价格区间标签、对应数量 |
| getPriceCharDataTwo | 销量区间分布统计 | 销量区间标签、对应数量 |
| getPriceCharDataThree | 折扣类型分布统计 | 折扣分布字典列表 |
| getCommentsCharDataOne | 评论时间趋势统计 | 日期列表、对应评论数量 |
| getCommentsCharDataTwo | 评论评分分布统计 | 评分分布字典列表 |
| getCommentsCharDataThree | 景点评论数量分布 | 评论数区间标签、对应数量 |
这个模块是数据可视化的核心,负责将原始数据加工成各种图表所需的格式,为前端图表展示提供数据支持。