style: move activity chart to bottom and use vega-lite for better visuals

This commit is contained in:
fujie
2026-02-11 12:46:24 +08:00
parent e1c2261537
commit fc56ea7faa
3 changed files with 111 additions and 52 deletions

View File

@@ -7,7 +7,7 @@ A collection of enhancements, plugins, and prompts for [OpenWebUI](https://githu
<!-- STATS_START -->
## 📊 Community Stats
> 🕐 Auto-updated: 2026-02-11 12:41
> 🕐 Auto-updated: 2026-02-11 12:46
| 👤 Author | 👥 Followers | ⭐ Points | 🏆 Contributions |
| :---: | :---: | :---: | :---: |
@@ -17,8 +17,6 @@ A collection of enhancements, plugins, and prompts for [OpenWebUI](https://githu
| :---: | :---: | :---: | :---: | :---: |
| ![posts](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_posts.json&style=flat) | ![downloads](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_downloads.json&style=flat) | ![views](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_views.json&style=flat) | ![upvotes](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_upvotes.json&style=flat) | ![saves](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_saves.json&style=flat) |
![Downloads Trend](https://kroki.io/mermaid/svg/eNpdzr8KgzAQx_G9T3FkakEhydn82X0EN3FIa6BCUNBA9e17aq9DM3z5EG74rdvzFeZcPmIOF6CXh5wiiGbKIUE9vcc0hX6BZo5jD1dVQR225SaO27UM67BAK6QqtRcF7EDJUAd0KX_QDGRUjDvDMCzDMfwXSjKU6I4l27nkf_Y5Mw1jhFZbJwvQzlqqt74AlEg_qIyjajRUtBX1rjXVGKTa49LZ_cd7uqkUqr1Gdh_PIkZl)
### 🔥 Top 6 Popular Plugins
| Rank | Plugin | Version | Downloads | Views | Updated |
| :---: | :--- | :---: | :---: | :---: | :---: |
@@ -156,6 +154,12 @@ If you have great prompts or plugins to share:
[Contributing](./CONTRIBUTING.md)
<!-- ACTIVITY_CHART_START -->
### 📈 Total Downloads Trend (14 Days)
![Activity](https://kroki.io/vegalite/svg/eNqNk82O2yAQgF_FcnelVmoSgxNs59p9hL1Ve5gYbNNg8AL5U5R3L5A4SoNX6sVmhm9-mTmnL6buWA_pOkk7awezXiz2rIV5y22328y5WlyBoJ0Jbtliv5r_MUqmP5OUMlNrPljuROfhXVkQyZs6SKGAmuRdM0mT72iZvMHJ_PAWB05t59gyy5zUMd521ok4iANQymXr5JWTNlBvW612knrfVoM0AziP1vuplWy4J8_pnrNDOBir1ZY9wxdHw5GbgFDVA_e5NiAMczet5nQULx6lYOHqFsSOeavfZ68MfnGGySxDM1yF6sdCfQFFmTnzGM2zCC2LYhpFEVoV1QSKHf2M5lmeTaM4QhEpp9E8QnFOptFlhObFchpdRegK42mURCgh-TRaRGjxVbPKCC2LLxKIHjavqukOoOhhlyhH0yiKUZJdPvy89aC3Yd7saQhGbmrB44JLFi5qJZT2N9_wiuRsEyZ6VJ7TI3I_5FSn8XDEo8YfsjDlQLlfhvXVL2gfwVg13AZcNY1h9kbfAx46t-9pKOkOoEfgntFH2B0ma3VbYJdX-DacibC_oSeOGcu0rB-UBpE-rmejdA8hy9d-9koDz63wBnInhO8KbJj4dY9PCElD6NNTtHuvH0J-7kA6d2D5nv0T9n9iXC5_AX_keeA=)
<!-- ACTIVITY_CHART_END -->
## Contributors ✨
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):

View File

@@ -6,7 +6,7 @@ OpenWebUI 增强功能集合。包含个人开发与收集的插件、提示词
<!-- STATS_START -->
## 📊 社区统计
> 🕐 自动更新于 2026-02-11 12:41
> 🕐 自动更新于 2026-02-11 12:46
| 👤 作者 | 👥 粉丝 | ⭐ 积分 | 🏆 贡献 |
| :---: | :---: | :---: | :---: |
@@ -16,8 +16,6 @@ OpenWebUI 增强功能集合。包含个人开发与收集的插件、提示词
| :---: | :---: | :---: | :---: | :---: |
| ![posts](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_posts.json&style=flat) | ![downloads](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_downloads.json&style=flat) | ![views](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_views.json&style=flat) | ![upvotes](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_upvotes.json&style=flat) | ![saves](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2FFu-Jie%2Fdb3d95687075a880af6f1fba76d679c6%2Fraw%2Fbadge_saves.json&style=flat) |
![Downloads Trend](https://kroki.io/mermaid/svg/eNo9zr1qAkEQwPHepxi2SuAOdnfO_eh9hHRisTEHOTg80AXPLl1AC59BsLExTZBAkLxMNJe3cO50nOLPj2GKqRfj1zCN6XMeQw9oYhHLHMT57fv3a9Ucj__v67_Pj2a_aQ6r0_IHHlR22u4eRXdcp6EuZjAUUqXaiwRaoGSoDjqVd2gGMjJGn2EYluEY_gYlGUqMuk8W10_EUxVDCYNqPimr8DK7vlkWkxyG2jqZgHbWUr31CaBE2qAyjqrRUNFm1L7WVGOQartLZ9uN93STKVRtjRxdAOxIUHs=)
### 🔥 热门插件 Top 6
| 排名 | 插件 | 版本 | 下载 | 浏览 | 更新日期 |
| :---: | :--- | :---: | :---: | :---: | :---: |
@@ -134,3 +132,9 @@ Open WebUI 的前端增强扩展:
本项目是一个资源集合,无需安装 Python 环境。你只需要下载对应的文件并导入到你的 OpenWebUI 实例中即可。
[贡献指南](./CONTRIBUTING_CN.md) | [更新日志](./CHANGELOG.md)
<!-- ACTIVITY_CHART_START -->
### 📈 总下载量累计趋势 (14天)
![Activity](https://kroki.io/vegalite/svg/eNqNlN2ymyAQx1_ljO2ZaWeaBDCi5raP0ZyLVVBpUKxiPiaTd-9CPiYNnpneILv82D8su56jr2PZyBaizVvUWNuPm9VqL2tY1so2U7FUZnUFvHehlZWrfbL8PZou-vEWCTmWg-qtQhMjbCdO4mI7rSXBMatSsZ1yWlbbKRUMx6wAiqPIcDVhRfX2ja5xlrP8u4t2UMI2GCcjBK1GqrqxaDJv9iCE6mq0E7QKKHf1YKZOOF07QDf2MMjOujil6SrlyHO0V_LgJ6MdzE6-whek4ahGjwjTgnL3qECPElfqQYm7eXGoAAvXsKAn6Xb9Ojunj8sI4wtCFyz3mTGHThsQDmJpRnB7iMYkQLM0nUdpgOZpPoMypF_RmMRkHmUBSnk2j8YBymI-j64DNE7X82gSoAlj8ygPUM7jeTQN0PSzZGUBmqWfHCB42DjP5zNAg4dd05jOozREObl8uHprYdj5erOn3m_CqgWHa9VJv1AabQa38oUlPJaFr-i78xwdKX4ouk73yZHdPW5CfJWDUK4ZNte4MDiF0Zr-VuCmqkZpb_RD8NDgvyDyV3oA9Bl4nOjD947sSnNrYDyXHyslte9fnxNk7te0su3NADp6bs_KDC34U763i3fheWW129BNWrusQCH1z4c-5zzy0qcXtUeunyT_TNBhOLBqL_-R_R-Ny-Uvk9GByw==)
<!-- ACTIVITY_CHART_END -->

View File

@@ -999,39 +999,6 @@ class OpenWebUIStats:
)
lines.append("")
# 插入总下载量趋势图 (仅 README 使用)
history = self.load_history()
if len(history) >= 3:
# 辅助函数Kroki 渲染
def kroki_render(mermaid_code: str) -> str:
try:
compressed = zlib.compress(mermaid_code.encode("utf-8"), level=9)
encoded = base64.urlsafe_b64encode(compressed).decode("utf-8")
return f"https://kroki.io/mermaid/svg/{encoded}"
except:
return ""
data = history[-14:] # 取最近14天
dates = [item["date"][-5:] for item in data]
dates_str = ", ".join([f'"{d}"' for d in dates])
dls = [str(item["total_downloads"]) for item in data]
# 多语言标题
chart_titles = {
"zh": "总下载量累计趋势 (14天)",
"en": "Total Downloads Trend (14 Days)",
}
c_title = chart_titles.get(lang, chart_titles["en"])
mm = f"""xychart-beta
title "{c_title}"
x-axis [{dates_str}]
y-axis "Total Downloads"
line [{', '.join(dls)}]"""
lines.append(f"![Downloads Trend]({kroki_render(mm)})")
lines.append("")
# Top 6 热门插件
lines.append(t["top6_title"])
lines.append(t["top6_header"])
@@ -1077,50 +1044,134 @@ class OpenWebUIStats:
pattern = r"<!-- STATS_START -->.*?<!-- STATS_END -->"
if re.search(pattern, content, re.DOTALL):
# 替换现有区域
new_content = re.sub(pattern, new_stats, content, flags=re.DOTALL)
content = re.sub(pattern, new_stats, content, flags=re.DOTALL)
else:
# 在简介段落之后插入统计区域
# 查找模式:标题 -> 语言切换行 -> 简介段落 -> 插入位置
lines = content.split("\n")
insert_pos = 0
found_intro = False
for i, line in enumerate(lines):
# 跳过标题
if line.startswith("# "):
continue
# 跳过空行
if line.strip() == "":
continue
# 跳过语言切换行 (如 "English | [中文]" 或 "[English] | 中文")
if ("English" in line or "中文" in line) and "|" in line:
continue
# 找到第一个非空、非标题、非语言切换的段落(简介)
if not found_intro:
found_intro = True
# 继续到这个段落结束
continue
# 简介段落后的空行或下一个标题就是插入位置
if line.strip() == "" or line.startswith("#"):
insert_pos = i
break
# 如果没找到合适位置就放在第3行标题和语言切换后
if insert_pos == 0:
insert_pos = 3
# 在适当位置插入
lines.insert(insert_pos, "")
lines.insert(insert_pos + 1, new_stats)
lines.insert(insert_pos + 2, "")
new_content = "\n".join(lines)
content = "\n".join(lines)
# 生成并插入/更新底部趋势图 (Vega-Lite)
activity_chart = self.generate_activity_chart(lang)
if activity_chart:
chart_pattern = (
r"<!-- ACTIVITY_CHART_START -->.*?<!-- ACTIVITY_CHART_END -->"
)
chart_section = f"<!-- ACTIVITY_CHART_START -->\n{activity_chart}\n<!-- ACTIVITY_CHART_END -->"
if re.search(chart_pattern, content, re.DOTALL):
content = re.sub(chart_pattern, chart_section, content, flags=re.DOTALL)
else:
# 尝试插入到 Contributors 之前
contributors_pattern = r"(## .*Contributors.*)"
match = re.search(contributors_pattern, content, re.IGNORECASE)
if match:
content = (
content[: match.start()]
+ f"\n{chart_section}\n\n"
+ content[match.start() :]
)
else:
content += f"\n\n{chart_section}"
# 写回文件
with open(readme_path, "w", encoding="utf-8") as f:
f.write(new_content)
f.write(content)
print(f"✅ README 已更新: {readme_path}")
def generate_activity_chart(self, lang: str = "zh") -> str:
"""生成 Vega-Lite 趋势图 (更美观)"""
history = self.load_history()
if len(history) < 3:
return ""
data = history[-14:]
# 准备数据点
values = []
for item in data:
values.append({"date": item["date"], "downloads": item["total_downloads"]})
title = (
"Total Downloads Trend (14 Days)"
if lang == "en"
else "总下载量累计趋势 (14天)"
)
# Vega-Lite Spec
vl_spec = {
"$schema": "https://vega.github.io/schema/vega-lite/v5.json",
"description": title,
"width": 800,
"height": 200,
"padding": 5,
"background": "transparent",
"config": {
"view": {"stroke": "transparent"},
"axis": {"domain": False, "grid": False},
},
"data": {"values": values},
"mark": {
"type": "area",
"line": {"color": "#2563eb"},
"color": {
"x1": 1,
"y1": 1,
"x2": 1,
"y2": 0,
"gradient": "linear",
"stops": [
{"offset": 0, "color": "white"},
{"offset": 1, "color": "#2563eb"},
],
},
},
"encoding": {
"x": {
"field": "date",
"type": "temporal",
"axis": {"format": "%m-%d", "title": None, "labelColor": "#666"},
},
"y": {
"field": "downloads",
"type": "quantitative",
"axis": {"title": None, "labelColor": "#666"},
},
},
}
try:
# Kroki encoding for Vega-Lite
json_spec = json.dumps(vl_spec)
compressed = zlib.compress(json_spec.encode("utf-8"), level=9)
encoded = base64.urlsafe_b64encode(compressed).decode("utf-8")
url = f"https://kroki.io/vegalite/svg/{encoded}"
return f"### 📈 {title}\n![Activity]({url})"
except Exception:
return ""
def main():
"""主函数"""