main
黄海 5 months ago
parent 42d9b7f10a
commit 3c570b7432

@ -3,6 +3,97 @@ import platform
from Text2Sql.Util.Text2SqlUtil import *
from Text2Sql.Util.PostgreSQLUtil import PostgreSQLUtil
from Text2Sql.Util.SaveToExcel import save_to_excel
from pyecharts.charts import Bar
from pyecharts import options as opts
from pyecharts.commons.utils import JsCode
import pandas as pd
import webbrowser
def process_data(raw_data):
"""
处理原始数据
1. 过滤无效行政区
2. 按上传数量降序排序
3. 取前10名
"""
df = pd.DataFrame(raw_data)
df = df[df['行政区划名称'].notna() & (df['行政区划名称'] != '')]
df = df.sort_values('上传课程数量', ascending=False).head(10)
return df
def create_top10_chart(data):
# 准备数据
schools = data['学校名称'].tolist()
counts = data['上传课程数量'].tolist()
districts = data['行政区划名称'].tolist()
# 生成颜色渐变(从深到浅)
colors = [f"rgb({75 + i * 15}, {115 - i * 10}, {220 - i * 20})" for i in range(10)]
# 创建图表
bar = Bar(init_opts=opts.InitOpts(width='1200px', height='600px'))
bar.add_xaxis(schools)
bar.add_yaxis(
series_name="上传数量",
y_axis=counts,
itemstyle_opts=opts.ItemStyleOpts(color=JsCode(
"function(params){"
f" return {colors}[params.dataIndex];"
"}"
)),
label_opts=opts.LabelOpts(
position="right",
formatter=JsCode(
"function(params){"
" return params.value + ' (' + params.name.split('').join('\\n') + ')';"
"}"
)
)
)
# 全局配置
bar.set_global_opts(
title_opts=opts.TitleOpts(
title="上传资源数量TOP10学校排名",
subtitle="数据来源:课程资源管理系统"
),
tooltip_opts=opts.TooltipOpts(
formatter=JsCode(
"""function(params){
return params.name + '<br/>'
+ '所属行政区:' + %s[params.dataIndex] + '<br/>'
+ '上传数量:<b style="color:#5470C6">' + params.value + '</b>'
}""" % districts
)
),
xaxis_opts=opts.AxisOpts(
axislabel_opts=opts.LabelOpts(
rotate=30,
formatter=JsCode(
"function(value){"
" return value.length > 6 ? value.substring(0,6)+'...' : value;"
"}"
)
)
),
yaxis_opts=opts.AxisOpts(name="上传数量(件)"),
datazoom_opts=[opts.DataZoomOpts(type_="inside")],
visualmap_opts=opts.VisualMapOpts(
min_=min(counts),
max_=max(counts),
orient="horizontal",
pos_left="center",
range_color=["#91CC75", "#5470C6"]
)
)
# 反转Y轴使降序排列
bar.reversal_axis()
return bar
if __name__ == "__main__":
vn = DeepSeekVanna()
@ -20,6 +111,8 @@ if __name__ == "__main__":
# 自然语言提问
question = '''
查询每个区每个校都上传了多少课程数量需要返回行政区名称学校名称上传课程数量等属性.
字段名行政区划名称学校名称上传课程数量,
行政区划为NULL 或者是空字符的不参加统计工作
先按行政区划排序再按课程数量由高到低排序'''
# ,只要行政区划是二道区的
@ -40,13 +133,14 @@ if __name__ == "__main__":
sample_data = db.execute_query(sql)
filename = "d:/导出信息.xlsx"
save_to_excel(sample_data, filename)
# 在代码最后添加自动打开逻辑
if platform.system() == "Windows":
try:
full_path = os.path.abspath(filename)
print(f"\n✅ 文件已保存到:{full_path}")
os.startfile(full_path) # 关键代码
except Exception as e:
print(f"\n⚠️ 自动打开失败: {str(e)},请手动打开文件")
# 用WINDOWS打开这个xlsx
if platform.system() == 'Windows':
os.startfile(filename)
else:
print("\n⚠️ 非Windows系统请手动打开文件")
# 对于其他系统,使用默认程序打开文件
os.system(f'open "{filename}"')
# 生成统计图
processed_data = process_data(sample_data)
chart = create_top10_chart(processed_data)
chart.render("top10_chart.html")
webbrowser.open("top10_chart.html")

@ -0,0 +1,67 @@
from pyecharts.charts import Bar
from pyecharts import options as opts
import pandas as pd
def process_data(raw_data):
"""
数据处理流程
1. 转换为DataFrame
2. 过滤无效行政区
3. 按上传量降序排序
4. 取前10条记录
"""
df = pd.DataFrame(raw_data)
# 过滤空值包括NaN和空字符串
df = df[(df['行政区划名称'].notna()) & (df['行政区划名称'] != '')]
# 按上传量排序并保留前10
return df.sort_values('上传课程数量', ascending=False).head(10)
def create_horizontal_barchart(data):
# 提取数据
schools = data['学校名称'].tolist()
counts = data['上传课程数量'].tolist()
# 创建图表对象
bar = Bar(init_opts=opts.InitOpts(width='1200px', height='600px'))
# 添加数据(横向柱状图需要反转坐标系)
bar.add_xaxis(counts)
bar.add_yaxis(
series_name="上传数量",
y_axis=schools,
itemstyle_opts=opts.ItemStyleOpts(color="#5470c6"),
label_opts=opts.LabelOpts(
position="right",
formatter="{b}: {c}"
)
)
# 配置图表选项
bar.set_global_opts(
title_opts=opts.TitleOpts(
title="课程资源上传量TOP10学校排名"
#subtitle="数据来源:课程资源管理系统"
),
tooltip_opts=opts.TooltipOpts(
formatter=opts.TooltipItemOptsFormatter(
# 显示学校、行政区和数量
"行政区:{a}<br/>"
"上传量:<b>{c}</b>"
)
),
yaxis_opts=opts.AxisOpts(
name="学校名称",
axislabel_opts=opts.LabelOpts(
font_size=12,
formatter=lambda name: name[:6] + "..." if len(name) > 6 else name
)
),
xaxis_opts=opts.AxisOpts(name="上传数量(件)"),
datazoom_opts=[opts.DataZoomOpts(type_="inside")],
)
# 反转坐标系实现横向显示
# bar.reversal_axis()
return bar

@ -0,0 +1,273 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Awesome-pyecharts</title>
<script type="text/javascript" src="https://assets.pyecharts.org/assets/v5/echarts.min.js"></script>
</head>
<body >
<div id="f0dc5418f1844bb99ff48a343422c11f" class="chart-container" style="width:1200px; height:600px; "></div>
<script>
var chart_f0dc5418f1844bb99ff48a343422c11f = echarts.init(
document.getElementById('f0dc5418f1844bb99ff48a343422c11f'), 'white', {renderer: 'canvas'});
var option_f0dc5418f1844bb99ff48a343422c11f = {
"animation": true,
"animationThreshold": 2000,
"animationDuration": 1000,
"animationEasing": "cubicOut",
"animationDelay": 0,
"animationDurationUpdate": 300,
"animationEasingUpdate": "cubicOut",
"animationDelayUpdate": 0,
"aria": {
"enabled": false
},
"color": [
"#5470c6",
"#91cc75",
"#fac858",
"#ee6666",
"#73c0de",
"#3ba272",
"#fc8452",
"#9a60b4",
"#ea7ccc"
],
"series": [
{
"type": "bar",
"name": "\u4e0a\u4f20\u6570\u91cf",
"legendHoverLink": true,
"data": [
323,
302,
279,
276,
241,
239,
183,
143,
136,
134
],
"realtimeSort": false,
"showBackground": false,
"stackStrategy": "samesign",
"cursor": "pointer",
"barMinHeight": 0,
"barCategoryGap": "20%",
"barGap": "30%",
"large": false,
"largeThreshold": 400,
"seriesLayoutBy": "column",
"datasetIndex": 0,
"clip": true,
"zlevel": 0,
"z": 2,
"label": {
"show": true,
"position": "right",
"margin": 8,
"formatter": function(params){ return params.value + ' (' + params.name.split('').join('\n') + ')';},
"valueAnimation": false
},
"itemStyle": {
"color": function(params){ return ['rgb(75, 115, 220)', 'rgb(90, 105, 200)', 'rgb(105, 95, 180)', 'rgb(120, 85, 160)', 'rgb(135, 75, 140)', 'rgb(150, 65, 120)', 'rgb(165, 55, 100)', 'rgb(180, 45, 80)', 'rgb(195, 35, 60)', 'rgb(210, 25, 40)'][params.dataIndex];}
}
}
],
"legend": [
{
"data": [
"\u4e0a\u4f20\u6570\u91cf"
],
"selected": {},
"show": true,
"padding": 5,
"itemGap": 10,
"itemWidth": 25,
"itemHeight": 14,
"backgroundColor": "transparent",
"borderColor": "#ccc",
"borderRadius": 0,
"pageButtonItemGap": 5,
"pageButtonPosition": "end",
"pageFormatter": "{current}/{total}",
"pageIconColor": "#2f4554",
"pageIconInactiveColor": "#aaa",
"pageIconSize": 15,
"animationDurationUpdate": 800,
"selector": false,
"selectorPosition": "auto",
"selectorItemGap": 7,
"selectorButtonGap": 10
}
],
"tooltip": {
"show": true,
"trigger": "item",
"triggerOn": "mousemove|click",
"axisPointer": {
"type": "line"
},
"showContent": true,
"alwaysShowContent": false,
"showDelay": 0,
"hideDelay": 100,
"enterable": false,
"confine": false,
"appendToBody": false,
"transitionDuration": 0.4,
"formatter": function(params){ return params.name + '<br/>' + '\u6240\u5c5e\u884c\u653f\u533a\uff1a' + ['\u7701\u5c5e\u4ee3\u7ba1', '\u7701\u5c5e\u4ee3\u7ba1', '\u4e8c\u9053\u533a', '\u7701\u5c5e\u4ee3\u7ba1', '\u76f4\u5c5e\u4ee3\u7ba1', '\u76f4\u5c5e\u4ee3\u7ba1', '\u76f4\u5c5e\u4ee3\u7ba1', '\u76f4\u5c5e\u4ee3\u7ba1', '\u76f4\u5c5e\u4ee3\u7ba1', '\u65b0\u533a\u4ee3\u7ba1'][params.dataIndex] + '<br/>' + '\u4e0a\u4f20\u6570\u91cf\uff1a<b style=\"color:#5470C6\">' + params.value + '</b>' },
"textStyle": {
"fontSize": 14
},
"borderWidth": 0,
"padding": 5,
"order": "seriesAsc"
},
"xAxis": [
{
"show": true,
"scale": false,
"nameLocation": "end",
"nameGap": 15,
"gridIndex": 0,
"axisLabel": {
"show": true,
"rotate": 30,
"margin": 8,
"formatter": function(value){ return value.length > 6 ? value.substring(0,6)+'...' : value;},
"valueAnimation": false
},
"inverse": false,
"offset": 0,
"splitNumber": 5,
"minInterval": 0,
"splitLine": {
"show": true,
"lineStyle": {
"show": true,
"width": 1,
"opacity": 1,
"curveness": 0,
"type": "solid"
}
},
"animation": true,
"animationThreshold": 2000,
"animationDuration": 1000,
"animationEasing": "cubicOut",
"animationDelay": 0,
"animationDurationUpdate": 300,
"animationEasingUpdate": "cubicOut",
"animationDelayUpdate": 0
}
],
"yAxis": [
{
"name": "\u4e0a\u4f20\u6570\u91cf\uff08\u4ef6\uff09",
"show": true,
"scale": false,
"nameLocation": "end",
"nameGap": 15,
"gridIndex": 0,
"inverse": false,
"offset": 0,
"splitNumber": 5,
"minInterval": 0,
"splitLine": {
"show": true,
"lineStyle": {
"show": true,
"width": 1,
"opacity": 1,
"curveness": 0,
"type": "solid"
}
},
"animation": true,
"animationThreshold": 2000,
"animationDuration": 1000,
"animationEasing": "cubicOut",
"animationDelay": 0,
"animationDurationUpdate": 300,
"animationEasingUpdate": "cubicOut",
"animationDelayUpdate": 0,
"data": [
"\u4e1c\u5317\u5e08\u8303\u5927\u5b66\u9644\u5c5e\u4e2d\u5b66",
"\u5409\u6797\u7701\u5b9e\u9a8c\u4e2d\u5b66",
"\u957f\u6625\u4e94\u5341\u4e8c\u4e2d\u8d6b\u884c\u5b9e\u9a8c\u5b66\u6821",
"\u4e1c\u5317\u5e08\u8303\u5927\u5b66\u9644\u5c5e\u5b9e\u9a8c\u5b66\u6821",
"\u957f\u6625\u5e02\u7b2c\u4e8c\u5b9e\u9a8c\u4e2d\u5b66",
"\u957f\u6625\u5e02\u5341\u4e00\u9ad8\u4e2d",
"\u957f\u6625\u5e02\u5b9e\u9a8c\u4e2d\u5b66",
"\u957f\u6625\u5e02\u7b2c\u4e00\u5b9e\u9a8c\u94f6\u6cb3\u5c0f\u5b66",
"\u957f\u6625\u5e02\u7b2c\u4e8c\u4e2d\u5b66",
"\u5409\u6797\u7701\u7b2c\u4e8c\u5b9e\u9a8c\u9ad8\u65b0\u5b66\u6821"
]
}
],
"title": [
{
"show": true,
"text": "\u4e0a\u4f20\u8d44\u6e90\u6570\u91cfTOP10\u5b66\u6821\u6392\u540d",
"target": "blank",
"subtext": "\u6570\u636e\u6765\u6e90\uff1a\u8bfe\u7a0b\u8d44\u6e90\u7ba1\u7406\u7cfb\u7edf",
"subtarget": "blank",
"padding": 5,
"itemGap": 10,
"textAlign": "auto",
"textVerticalAlign": "auto",
"triggerEvent": false
}
],
"visualMap": {
"show": true,
"type": "continuous",
"min": 134,
"max": 323,
"inRange": {
"color": [
"#91CC75",
"#5470C6"
]
},
"calculable": true,
"inverse": false,
"splitNumber": 5,
"hoverLink": true,
"orient": "horizontal",
"left": "center",
"padding": 5,
"showLabel": true,
"itemWidth": 20,
"itemHeight": 140,
"borderWidth": 0
},
"dataZoom": [
{
"show": true,
"type": "inside",
"showDetail": true,
"showDataShadow": true,
"realtime": true,
"start": 20,
"end": 80,
"orient": "horizontal",
"zoomLock": false,
"filterMode": "filter",
"disabled": false,
"zoomOnMouseWheel": true,
"moveOnMouseMove": true,
"moveOnMouseWheel": true,
"preventDefaultMouseMove": true
}
]
};
chart_f0dc5418f1844bb99ff48a343422c11f.setOption(option_f0dc5418f1844bb99ff48a343422c11f);
</script>
</body>
</html>
Loading…
Cancel
Save