mirror of
https://github.com/Nezumi-2711/astrbot_plugin_qq_group_daily_analysis.git
synced 2026-09-22 13:38:43 +00:00
[v4.5.0] 添加新的模板主题 retro_futurism, 灵感来源明日方舟 孤星 未来复古主义主题;添加模板调试工具 scripts/debug_render.py,方便用户在不启动 AstrBot 的情况下调试模板效果 (@Saramanda9988)
This commit is contained in:
@@ -108,6 +108,9 @@ simple 模板效果图(用于展示贡献指南)
|
|||||||
<details>
|
<details>
|
||||||
<summary>📋 点击展开查看完整更新日志</summary>
|
<summary>📋 点击展开查看完整更新日志</summary>
|
||||||
|
|
||||||
|
### v4.5.0
|
||||||
|
- 添加新的模板主题 retro_futurism, 灵感来源明日方舟 孤星 未来复古主义主题;添加模板调试工具 scripts/debug_render.py,方便用户在不启动 AstrBot 的情况下调试模板效果 (@Saramanda9988)
|
||||||
|
|
||||||
### v4.4.0
|
### v4.4.0
|
||||||
- 修复可能的图片生成成功但是发送失败的情况,增加 Fallback 的 BASE64 编码的图片发送方式(@Heximiao)
|
- 修复可能的图片生成成功但是发送失败的情况,增加 Fallback 的 BASE64 编码的图片发送方式(@Heximiao)
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.6 MiB |
+1
-1
@@ -14,6 +14,6 @@ help: | # 插件的帮助信息
|
|||||||
命令:
|
命令:
|
||||||
/群分析 [天数] - 分析群聊活动
|
/群分析 [天数] - 分析群聊活动
|
||||||
/分析设置 [操作] - 管理设置(enable/disable/status/test)
|
/分析设置 [操作] - 管理设置(enable/disable/status/test)
|
||||||
version: v4.4.0 # 插件版本号。格式:v1.1.1 或者 v1.1
|
version: v4.5.0 # 插件版本号。格式:v1.1.1 或者 v1.1
|
||||||
author: SXP-Simon # 作者
|
author: SXP-Simon # 作者
|
||||||
repo: https://github.com/SXP-Simon/astrbot-qq-group-daily-analysis # 插件的仓库地址
|
repo: https://github.com/SXP-Simon/astrbot-qq-group-daily-analysis # 插件的仓库地址
|
||||||
|
|||||||
@@ -1,562 +0,0 @@
|
|||||||
<!--
|
|
||||||
@name: 复古未来主义报告
|
|
||||||
@description: 结合复古工业与未来终端风格的统计报告
|
|
||||||
@author: LunaRain_079
|
|
||||||
@version: 1.0.0
|
|
||||||
-->
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="zh-CN">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>LUNABOX TERMINAL REPORT</title>
|
|
||||||
<!-- Chart.js CDN -->
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js"></script>
|
|
||||||
|
|
||||||
<!-- Fonts - Using system fonts as fallback for export compatibility -->
|
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
||||||
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&family=Oswald:wght@400;700&family=Noto+Sans+SC:wght@400;700&display=swap" rel="stylesheet">
|
|
||||||
|
|
||||||
<style>
|
|
||||||
/* Embedded font fallbacks for export */
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Oswald-Fallback';
|
|
||||||
src: local('Impact'), local('Arial Black'), local('Helvetica Neue Bold');
|
|
||||||
font-weight: 400 700;
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: 'JetBrains-Fallback';
|
|
||||||
src: local('Consolas'), local('Monaco'), local('Courier New');
|
|
||||||
font-weight: 400 700;
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: 'NotoSans-Fallback';
|
|
||||||
src: local('Microsoft YaHei'), local('PingFang SC'), local('Hiragino Sans GB'), local('SimHei');
|
|
||||||
font-weight: 400 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
:root {
|
|
||||||
/* Palette */
|
|
||||||
--c-bg: #F5EDDC;
|
|
||||||
--c-text: #181818;
|
|
||||||
--c-accent: #B2653B; /* Orange */
|
|
||||||
|
|
||||||
--c-dec-1: #5C7F71; /* Green */
|
|
||||||
--c-dec-2: #802520; /* Red */
|
|
||||||
--c-dec-3: #BA8530; /* Gold */
|
|
||||||
|
|
||||||
--c-grid: rgba(24, 24, 24, 0.1);
|
|
||||||
|
|
||||||
/* Fonts - with system fallbacks for export */
|
|
||||||
--font-display: 'Oswald', 'Oswald-Fallback', Impact, 'Arial Black', sans-serif;
|
|
||||||
--font-mono: 'JetBrains Mono', 'JetBrains-Fallback', Consolas, Monaco, 'Courier New', monospace;
|
|
||||||
--font-body: 'Noto Sans SC', 'NotoSans-Fallback', 'Microsoft YaHei', 'PingFang SC', sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
* {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
background-color: var(--c-bg);
|
|
||||||
color: var(--c-text);
|
|
||||||
font-family: var(--font-body);
|
|
||||||
/* Grid Background */
|
|
||||||
background-image:
|
|
||||||
linear-gradient(var(--c-grid) 1px, transparent 1px),
|
|
||||||
linear-gradient(90deg, var(--c-grid) 1px, transparent 1px);
|
|
||||||
background-size: 40px 40px;
|
|
||||||
min-height: 100vh;
|
|
||||||
overflow-x: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Layout Container */
|
|
||||||
.layout {
|
|
||||||
max-width: 1200px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 60px 40px;
|
|
||||||
position: relative;
|
|
||||||
border-left: 1px solid var(--c-text);
|
|
||||||
border-right: 1px solid var(--c-text);
|
|
||||||
background:
|
|
||||||
linear-gradient(90deg, transparent 0%, transparent 98%, var(--c-accent) 98%, var(--c-accent) 100%);
|
|
||||||
background-size: 100% 100%;
|
|
||||||
min-height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Decorative Color Bar */
|
|
||||||
.color-bar {
|
|
||||||
position: absolute;
|
|
||||||
top: 60px;
|
|
||||||
left: -20px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 0;
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
.c-block {
|
|
||||||
width: 60px;
|
|
||||||
height: 12px;
|
|
||||||
}
|
|
||||||
.cb-1 { background: var(--c-dec-1); }
|
|
||||||
.cb-2 { background: var(--c-dec-2); }
|
|
||||||
.cb-3 { background: var(--c-dec-3); }
|
|
||||||
|
|
||||||
/* Header */
|
|
||||||
header {
|
|
||||||
margin-bottom: 80px;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header-meta {
|
|
||||||
font-family: var(--font-mono);
|
|
||||||
font-size: 0.8rem;
|
|
||||||
color: var(--c-text);
|
|
||||||
opacity: 0.7;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
letter-spacing: 1px;
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-family: var(--font-display);
|
|
||||||
font-size: 5rem;
|
|
||||||
line-height: 0.9;
|
|
||||||
margin: 0;
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: -2px;
|
|
||||||
color: var(--c-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 .highlight {
|
|
||||||
color: var(--c-accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.date-range {
|
|
||||||
font-family: var(--font-mono);
|
|
||||||
font-size: 1.2rem;
|
|
||||||
margin-top: 20px;
|
|
||||||
padding-left: 20px;
|
|
||||||
border-left: 4px solid var(--c-accent);
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Grid System */
|
|
||||||
.grid-container {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(12, 1fr);
|
|
||||||
gap: 20px;
|
|
||||||
margin-bottom: 60px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Section Titles */
|
|
||||||
.section-label {
|
|
||||||
grid-column: span 12;
|
|
||||||
font-family: var(--font-display);
|
|
||||||
font-size: 2rem;
|
|
||||||
text-transform: uppercase;
|
|
||||||
border-bottom: 2px solid var(--c-text);
|
|
||||||
padding-bottom: 10px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: flex-end;
|
|
||||||
}
|
|
||||||
.section-label span {
|
|
||||||
background: var(--c-text);
|
|
||||||
color: var(--c-bg);
|
|
||||||
padding: 2px 10px;
|
|
||||||
font-size: 1rem;
|
|
||||||
font-family: var(--font-mono);
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Stats Big Number */
|
|
||||||
.stat-box {
|
|
||||||
grid-column: span 4;
|
|
||||||
border: 1px solid var(--c-text);
|
|
||||||
padding: 20px;
|
|
||||||
position: relative;
|
|
||||||
background: rgba(255, 255, 255, 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-box::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: 4px; left: 4px; right: 4px; bottom: 4px;
|
|
||||||
border: 1px solid var(--c-grid);
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-label {
|
|
||||||
font-family: var(--font-mono);
|
|
||||||
font-size: 0.9rem;
|
|
||||||
text-transform: uppercase;
|
|
||||||
color: var(--c-dec-1);
|
|
||||||
margin-bottom: 10px;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-value {
|
|
||||||
font-family: var(--font-display);
|
|
||||||
font-size: 4rem;
|
|
||||||
color: var(--c-accent);
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* AI Summary - Terminal Style */
|
|
||||||
.ai-terminal {
|
|
||||||
grid-column: span 8;
|
|
||||||
background: var(--c-text);
|
|
||||||
color: var(--c-bg);
|
|
||||||
padding: 20px;
|
|
||||||
font-family: var(--font-mono);
|
|
||||||
font-size: 0.9rem;
|
|
||||||
line-height: 1.6;
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.ai-terminal::before {
|
|
||||||
content: "AI_ANALYSIS_MODULE // v.2.0";
|
|
||||||
display: block;
|
|
||||||
border-bottom: 1px solid #444;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
color: var(--c-accent);
|
|
||||||
font-size: 0.7rem;
|
|
||||||
}
|
|
||||||
.cursor {
|
|
||||||
display: inline-block;
|
|
||||||
width: 8px;
|
|
||||||
height: 14px;
|
|
||||||
background: var(--c-accent);
|
|
||||||
animation: blink 1s infinite;
|
|
||||||
}
|
|
||||||
@keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }
|
|
||||||
|
|
||||||
/* Charts */
|
|
||||||
.chart-wrapper {
|
|
||||||
grid-column: span 12;
|
|
||||||
border: 1px solid var(--c-text);
|
|
||||||
padding: 20px;
|
|
||||||
background: #fff;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.chart-wrapper.half {
|
|
||||||
grid-column: span 6;
|
|
||||||
}
|
|
||||||
.chart-deco {
|
|
||||||
position: absolute;
|
|
||||||
top: -10px;
|
|
||||||
right: 20px;
|
|
||||||
background: var(--c-bg);
|
|
||||||
padding: 0 10px;
|
|
||||||
font-family: var(--font-mono);
|
|
||||||
font-size: 0.8rem;
|
|
||||||
border: 1px solid var(--c-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Leaderboard - Asymmetrical List */
|
|
||||||
.game-list {
|
|
||||||
grid-column: span 12;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.game-item {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 60px 80px 1fr 150px;
|
|
||||||
align-items: center;
|
|
||||||
gap: 20px;
|
|
||||||
border-bottom: 1px solid var(--c-grid);
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.game-cover {
|
|
||||||
width: 80px;
|
|
||||||
height: 106px; /* 3:4 aspect ratio */
|
|
||||||
background: #000;
|
|
||||||
border: 1px solid var(--c-text);
|
|
||||||
overflow: hidden;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.game-cover img {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
object-fit: cover;
|
|
||||||
filter: grayscale(100%) contrast(120%); /* Retro B&W look */
|
|
||||||
transition: filter 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.game-item:hover .game-cover img {
|
|
||||||
filter: grayscale(0%) contrast(100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.game-rank {
|
|
||||||
font-family: var(--font-display);
|
|
||||||
font-size: 2rem;
|
|
||||||
color: var(--c-text);
|
|
||||||
opacity: 0.3;
|
|
||||||
}
|
|
||||||
.game-item:nth-child(1) .game-rank { color: var(--c-dec-3); opacity: 1; }
|
|
||||||
.game-item:nth-child(2) .game-rank { color: var(--c-dec-1); opacity: 1; }
|
|
||||||
.game-item:nth-child(3) .game-rank { color: var(--c-dec-2); opacity: 1; }
|
|
||||||
|
|
||||||
.game-info h3 {
|
|
||||||
margin: 0;
|
|
||||||
font-family: var(--font-body);
|
|
||||||
font-size: 1.2rem;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.game-time {
|
|
||||||
font-family: var(--font-mono);
|
|
||||||
text-align: right;
|
|
||||||
color: var(--c-accent);
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Footer */
|
|
||||||
footer {
|
|
||||||
margin-top: 80px;
|
|
||||||
border-top: 4px solid var(--c-text);
|
|
||||||
padding-top: 20px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
font-family: var(--font-mono);
|
|
||||||
font-size: 0.8rem;
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Responsive */
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
.grid-container { display: flex; flex-direction: column; }
|
|
||||||
.chart-wrapper.half { grid-column: span 12; }
|
|
||||||
h1 { font-size: 3rem; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/* CRT Scanline Effect Overlay (Optional, subtle) */
|
|
||||||
.crt-overlay {
|
|
||||||
position: fixed;
|
|
||||||
top: 0; left: 0; width: 100%; height: 100%;
|
|
||||||
background: linear-gradient(rgba(18, 16, 16, 0) 50%, rgba(0, 0, 0, 0.05) 50%);
|
|
||||||
background-size: 100% 4px;
|
|
||||||
pointer-events: none;
|
|
||||||
z-index: 999;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<div class="crt-overlay"></div>
|
|
||||||
|
|
||||||
<div class="layout">
|
|
||||||
<!-- Decorative Bars -->
|
|
||||||
<div class="color-bar">
|
|
||||||
<div class="c-block cb-1"></div>
|
|
||||||
<div class="c-block cb-2"></div>
|
|
||||||
<div class="c-block cb-3"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<header>
|
|
||||||
<div class="header-meta">System Report // {{.ExportTime}}</div>
|
|
||||||
<h1>Luna<span class="highlight">Box</span><br>Instruction<br>Catalogue</h1>
|
|
||||||
<div class="date-range">
|
|
||||||
PERIOD: {{.StartDate}} >> {{.EndDate}}
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<div class="grid-container">
|
|
||||||
<!-- Stats -->
|
|
||||||
<div class="stat-box" style="grid-column: span 3;">
|
|
||||||
<span class="stat-label">Total Sessions</span>
|
|
||||||
<div class="stat-value">{{.TotalPlayCount}}</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="stat-box" style="grid-column: span 3;">
|
|
||||||
<span class="stat-label">Total Duration</span>
|
|
||||||
<div class="stat-value" style="font-size: 2.5rem; margin-top: 10px;">{{.TotalPlayTimeStr}}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- AI Summary -->
|
|
||||||
{{if .AISummary}}
|
|
||||||
<div class="ai-terminal" style="grid-column: span 6;">
|
|
||||||
{{.AISummary}}<span class="cursor"></span>
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
<!-- Charts -->
|
|
||||||
{{if .ChartLabels}}
|
|
||||||
<div class="section-label">
|
|
||||||
Analytics <span>DATA_VISUALIZATION</span>
|
|
||||||
</div>
|
|
||||||
<div class="grid-container">
|
|
||||||
<div class="chart-wrapper">
|
|
||||||
<div class="chart-deco">FIGURE_01: TIME_SERIES</div>
|
|
||||||
<canvas id="trendChart" height="300"></canvas>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
{{if .GameTrendData}}
|
|
||||||
<div class="grid-container">
|
|
||||||
<div class="chart-wrapper">
|
|
||||||
<div class="chart-deco">FIGURE_02: GAME_TRENDS</div>
|
|
||||||
<canvas id="gameTrendChart" height="300"></canvas>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
<!-- Leaderboard -->
|
|
||||||
{{if .Leaderboard}}
|
|
||||||
<div class="section-label">
|
|
||||||
Top Records <span>RANKING_MODULE</span>
|
|
||||||
</div>
|
|
||||||
<div class="grid-container">
|
|
||||||
<div class="game-list">
|
|
||||||
{{range $index, $game := .Leaderboard}}
|
|
||||||
<div class="game-item">
|
|
||||||
<div class="game-rank">#{{add $index 1}}</div>
|
|
||||||
<div class="game-cover">
|
|
||||||
{{if $game.CoverBase64}}
|
|
||||||
<img src="{{$game.CoverBase64}}" alt="{{$game.GameName}}">
|
|
||||||
{{else if $game.CoverURL}}
|
|
||||||
<img src="{{$game.CoverURL}}" alt="{{$game.GameName}}">
|
|
||||||
{{else}}
|
|
||||||
<div style="width:100%;height:100%;background:#333;display:flex;align-items:center;justify-content:center;color:#555;font-size:0.8rem;">NO_IMG</div>
|
|
||||||
{{end}}
|
|
||||||
</div>
|
|
||||||
<div class="game-info">
|
|
||||||
<h3>{{$game.GameName}}</h3>
|
|
||||||
</div>
|
|
||||||
<div class="game-time">{{$game.DurationStr}}</div>
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<div>Generated by {{.AppName}} v{{.AppVersion}}</div>
|
|
||||||
<div>END OF LINE_</div>
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Data Injection -->
|
|
||||||
<script id="chart-data-config" type="application/json">
|
|
||||||
{
|
|
||||||
"labels": {{ .ChartLabels | safeJS }},
|
|
||||||
"data": {{ .ChartData | safeJS }},
|
|
||||||
"gameTrend": {{ .GameTrendData | safeJS }}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// Chart Configuration
|
|
||||||
Chart.defaults.font.family = "'JetBrains Mono', monospace";
|
|
||||||
Chart.defaults.color = '#181818';
|
|
||||||
|
|
||||||
const commonOptions = {
|
|
||||||
responsive: true,
|
|
||||||
maintainAspectRatio: false,
|
|
||||||
plugins: {
|
|
||||||
legend: {
|
|
||||||
labels: {
|
|
||||||
usePointStyle: true,
|
|
||||||
boxWidth: 10
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
scales: {
|
|
||||||
x: {
|
|
||||||
grid: {
|
|
||||||
color: 'rgba(24, 24, 24, 0.1)',
|
|
||||||
tickLength: 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
y: {
|
|
||||||
grid: {
|
|
||||||
color: 'rgba(24, 24, 24, 0.1)',
|
|
||||||
borderDash: [4, 4]
|
|
||||||
},
|
|
||||||
beginAtZero: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Load Data
|
|
||||||
let config = {};
|
|
||||||
try {
|
|
||||||
config = JSON.parse(document.getElementById('chart-data-config').textContent);
|
|
||||||
} catch (e) { console.error(e); }
|
|
||||||
|
|
||||||
// Render Trend Chart
|
|
||||||
if (config.labels && config.data) {
|
|
||||||
const ctx = document.getElementById('trendChart');
|
|
||||||
if (ctx) {
|
|
||||||
new Chart(ctx, {
|
|
||||||
type: 'line',
|
|
||||||
data: {
|
|
||||||
labels: config.labels,
|
|
||||||
datasets: [{
|
|
||||||
label: 'PLAY_TIME (Hours)',
|
|
||||||
data: config.data,
|
|
||||||
borderColor: '#B2653B',
|
|
||||||
backgroundColor: 'rgba(178, 101, 59, 0.1)',
|
|
||||||
borderWidth: 2,
|
|
||||||
pointBackgroundColor: '#F5EDDC',
|
|
||||||
pointBorderColor: '#B2653B',
|
|
||||||
pointRadius: 4,
|
|
||||||
pointHoverRadius: 6,
|
|
||||||
fill: true,
|
|
||||||
tension: 0 // Sharp lines for retro feel
|
|
||||||
}]
|
|
||||||
},
|
|
||||||
options: commonOptions
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Render Game Distribution
|
|
||||||
if (config.gameTrend) {
|
|
||||||
const ctx2 = document.getElementById('gameTrendChart');
|
|
||||||
if (ctx2) {
|
|
||||||
// Palette for multiple items
|
|
||||||
const palette = ['#B2653B', '#5C7F71', '#802520', '#BA8530', '#181818'];
|
|
||||||
|
|
||||||
// Map data to datasets
|
|
||||||
const datasets = config.gameTrend.map((ds, index) => {
|
|
||||||
const color = palette[index % palette.length];
|
|
||||||
return {
|
|
||||||
label: ds.label, // Game Name
|
|
||||||
data: ds.data, // Array of hours
|
|
||||||
borderColor: color,
|
|
||||||
backgroundColor: color,
|
|
||||||
borderWidth: 2,
|
|
||||||
pointBackgroundColor: '#F5EDDC',
|
|
||||||
pointBorderColor: color,
|
|
||||||
pointRadius: 4,
|
|
||||||
tension: 0 // Sharp lines
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
new Chart(ctx2, {
|
|
||||||
type: 'line',
|
|
||||||
data: {
|
|
||||||
labels: config.labels, // Date labels
|
|
||||||
datasets: datasets
|
|
||||||
},
|
|
||||||
options: commonOptions
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
Reference in New Issue
Block a user