mirror of
https://github.com/Nezumi-2711/astrbot_plugin_qq_group_daily_analysis.git
synced 2026-09-23 04:09:59 +00:00
feat: Add Retro Futurism report templates and components
This commit is contained in:
committed by
Helian Nuits
parent
4ca8180933
commit
59b82a29c9
@@ -0,0 +1,15 @@
|
||||
{% if chart_data %}
|
||||
{% for item in chart_data %}
|
||||
<div class="activity-row">
|
||||
<div class="activity-hour">{{ "%02d"|format(item.hour) }}:00</div>
|
||||
<div class="activity-meter">
|
||||
<div class="activity-bar" style="--pct: {{ "%.2f"|format(item.percentage) }}%;"></div>
|
||||
</div>
|
||||
<div class="activity-count">{{ item.count }}</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="activity-row">
|
||||
<div class="topic-meta" style="grid-column: span 3;">NO_DATA_AVAILABLE</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -0,0 +1,735 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Retro Futurism Daily Export</title>
|
||||
<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=Oswald:wght@400;600&family=JetBrains+Mono:wght@400;600&family=Noto+Sans+SC:wght@400;500&display=swap"
|
||||
rel="stylesheet">
|
||||
<style>
|
||||
@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;
|
||||
|
||||
--c-dec-1: #5C7F71;
|
||||
--c-dec-2: #802520;
|
||||
--c-dec-3: #BA8530;
|
||||
|
||||
--c-grid: rgba(24, 24, 24, 0.08);
|
||||
|
||||
/* Fonts */
|
||||
--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;
|
||||
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: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.c-block {
|
||||
width: 40px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
.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: 60px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.header-meta {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.75rem;
|
||||
color: var(--c-text);
|
||||
opacity: 0.65;
|
||||
margin-bottom: 12px;
|
||||
letter-spacing: 0.15rem;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-family: var(--font-display);
|
||||
font-size: 4.5rem;
|
||||
line-height: 0.9;
|
||||
margin: 0 0 20px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: -0.1rem;
|
||||
color: var(--c-text);
|
||||
}
|
||||
|
||||
h1 .highlight {
|
||||
color: var(--c-accent);
|
||||
}
|
||||
|
||||
.header-brief {
|
||||
max-width: 500px;
|
||||
color: rgba(24, 24, 24, 0.7);
|
||||
line-height: 1.6;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.header-meta-row {
|
||||
display: flex;
|
||||
gap: 30px;
|
||||
}
|
||||
|
||||
.meta-block {
|
||||
padding-left: 16px;
|
||||
border-left: 3px solid var(--c-accent);
|
||||
}
|
||||
|
||||
.meta-label {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.7rem;
|
||||
letter-spacing: 0.15rem;
|
||||
text-transform: uppercase;
|
||||
color: rgba(24, 24, 24, 0.5);
|
||||
}
|
||||
|
||||
.meta-value {
|
||||
display: block;
|
||||
margin-top: 4px;
|
||||
color: var(--c-text);
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
/* CRT Console */
|
||||
.crt-console {
|
||||
background: var(--c-text);
|
||||
color: var(--c-bg);
|
||||
padding: 20px 24px;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.85rem;
|
||||
line-height: 1.6;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
grid-column: span 12;
|
||||
}
|
||||
|
||||
.crt-console::before {
|
||||
content: "CRT_CHANNEL // PEAK_ACTIVITY";
|
||||
display: block;
|
||||
border-bottom: 1px solid #444;
|
||||
padding-bottom: 8px;
|
||||
margin-bottom: 12px;
|
||||
color: var(--c-accent);
|
||||
font-size: 0.65rem;
|
||||
letter-spacing: 0.2rem;
|
||||
}
|
||||
|
||||
.crt-label {
|
||||
font-size: 0.7rem;
|
||||
letter-spacing: 0.2rem;
|
||||
text-transform: uppercase;
|
||||
color: rgba(245, 237, 220, 0.7);
|
||||
}
|
||||
|
||||
.crt-value {
|
||||
font-family: var(--font-display);
|
||||
font-size: 2.5rem;
|
||||
color: var(--c-accent);
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
.crt-sub {
|
||||
font-size: 0.8rem;
|
||||
color: rgba(245, 237, 220, 0.8);
|
||||
}
|
||||
|
||||
/* Grid System */
|
||||
.grid-container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(12, 1fr);
|
||||
gap: 20px;
|
||||
margin-bottom: 60px;
|
||||
}
|
||||
|
||||
/* Section Labels */
|
||||
.section-label {
|
||||
grid-column: span 12;
|
||||
font-family: var(--font-display);
|
||||
font-size: 1.8rem;
|
||||
text-transform: uppercase;
|
||||
border-bottom: 2px solid var(--c-text);
|
||||
padding-bottom: 8px;
|
||||
margin-bottom: 20px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
letter-spacing: 0.1rem;
|
||||
}
|
||||
|
||||
.section-label span {
|
||||
background: var(--c-text);
|
||||
color: var(--c-bg);
|
||||
padding: 2px 10px;
|
||||
font-size: 0.75rem;
|
||||
font-family: var(--font-mono);
|
||||
vertical-align: middle;
|
||||
letter-spacing: 0.15rem;
|
||||
}
|
||||
|
||||
/* Stat Box */
|
||||
.stat-box {
|
||||
grid-column: span 3;
|
||||
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.75rem;
|
||||
text-transform: uppercase;
|
||||
color: var(--c-dec-1);
|
||||
margin-bottom: 10px;
|
||||
display: block;
|
||||
letter-spacing: 0.15rem;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-family: var(--font-display);
|
||||
font-size: 3rem;
|
||||
color: var(--c-accent);
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.stat-note {
|
||||
font-size: 0.8rem;
|
||||
color: rgba(24, 24, 24, 0.6);
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
/* Content Box (for topics, titles, quotes) */
|
||||
.content-box {
|
||||
grid-column: span 12;
|
||||
border: 1px solid var(--c-text);
|
||||
padding: 24px;
|
||||
background: #fff;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.content-box::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 6px;
|
||||
left: 6px;
|
||||
right: 6px;
|
||||
bottom: 6px;
|
||||
border: 1px solid var(--c-grid);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Activity Chart */
|
||||
.activity-wrapper {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.activity-row {
|
||||
display: grid;
|
||||
grid-template-columns: 60px 1fr 50px;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 6px 0;
|
||||
border-bottom: 1px solid var(--c-grid);
|
||||
}
|
||||
|
||||
.activity-row:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.activity-hour {
|
||||
letter-spacing: 0.1rem;
|
||||
color: rgba(24, 24, 24, 0.6);
|
||||
}
|
||||
|
||||
.activity-meter {
|
||||
background: rgba(24, 24, 24, 0.08);
|
||||
height: 8px;
|
||||
border-radius: 2px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.activity-bar {
|
||||
height: 100%;
|
||||
width: var(--pct, 10%);
|
||||
background: var(--c-accent);
|
||||
}
|
||||
|
||||
.activity-count {
|
||||
text-align: right;
|
||||
color: rgba(24, 24, 24, 0.6);
|
||||
}
|
||||
|
||||
/* Topic List */
|
||||
.topic-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.topic-item {
|
||||
display: grid;
|
||||
grid-template-columns: 50px 1fr;
|
||||
gap: 20px;
|
||||
padding-bottom: 16px;
|
||||
border-bottom: 1px solid var(--c-grid);
|
||||
}
|
||||
|
||||
.topic-item:last-child {
|
||||
border-bottom: none;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.topic-index {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 1rem;
|
||||
letter-spacing: 0.2rem;
|
||||
color: rgba(24, 24, 24, 0.3);
|
||||
}
|
||||
|
||||
.topic-title {
|
||||
margin: 0 0 6px;
|
||||
font-size: 1.1rem;
|
||||
letter-spacing: 0.05rem;
|
||||
color: var(--c-text);
|
||||
}
|
||||
|
||||
.topic-meta {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.7rem;
|
||||
letter-spacing: 0.15rem;
|
||||
color: rgba(24, 24, 24, 0.5);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.topic-detail {
|
||||
color: rgba(24, 24, 24, 0.7);
|
||||
line-height: 1.6;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
/* User Title Grid */
|
||||
.title-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.title-item {
|
||||
border: 1px solid var(--c-text);
|
||||
padding: 18px;
|
||||
position: relative;
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
.title-item::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
left: 4px;
|
||||
width: 24px;
|
||||
height: 4px;
|
||||
background: var(--c-dec-1);
|
||||
}
|
||||
|
||||
.title-item::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
left: 32px;
|
||||
width: 24px;
|
||||
height: 4px;
|
||||
background: var(--c-dec-2);
|
||||
}
|
||||
|
||||
.title-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.title-avatar {
|
||||
width: 52px;
|
||||
height: 52px;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--c-text);
|
||||
background: rgba(24, 24, 24, 0.08);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.title-avatar img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
filter: grayscale(50%) contrast(110%);
|
||||
}
|
||||
|
||||
.title-avatar-fallback {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.7rem;
|
||||
letter-spacing: 0.15rem;
|
||||
color: rgba(24, 24, 24, 0.5);
|
||||
}
|
||||
|
||||
.title-name {
|
||||
font-weight: 600;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.title-mbti {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.65rem;
|
||||
letter-spacing: 0.15rem;
|
||||
background: rgba(24, 24, 24, 0.08);
|
||||
padding: 2px 8px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.title-role {
|
||||
font-family: var(--font-mono);
|
||||
letter-spacing: 0.2rem;
|
||||
text-transform: uppercase;
|
||||
color: var(--c-accent);
|
||||
margin: 8px 0;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.title-reason {
|
||||
margin: 0;
|
||||
font-size: 0.85rem;
|
||||
color: rgba(24, 24, 24, 0.7);
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* Quote List */
|
||||
.quote-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.quote-item {
|
||||
border: 1px dashed var(--c-text);
|
||||
padding: 20px;
|
||||
position: relative;
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.quote-item::before {
|
||||
content: '"';
|
||||
font-family: var(--font-display);
|
||||
font-size: 2rem;
|
||||
color: var(--c-accent);
|
||||
opacity: 0.5;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.quote-content {
|
||||
font-size: 1rem;
|
||||
color: var(--c-text);
|
||||
margin: 8px 0;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.quote-author {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.75rem;
|
||||
letter-spacing: 0.15rem;
|
||||
color: rgba(24, 24, 24, 0.6);
|
||||
}
|
||||
|
||||
.quote-note {
|
||||
font-size: 0.8rem;
|
||||
color: rgba(24, 24, 24, 0.7);
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
/* Token Strip */
|
||||
.token-strip {
|
||||
grid-column: span 12;
|
||||
border-top: 2px solid var(--c-text);
|
||||
padding-top: 16px;
|
||||
display: flex;
|
||||
gap: 40px;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.75rem;
|
||||
letter-spacing: 0.1rem;
|
||||
}
|
||||
|
||||
.token-label {
|
||||
color: rgba(24, 24, 24, 0.5);
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
footer {
|
||||
margin-top: 60px;
|
||||
border-top: 3px solid var(--c-text);
|
||||
padding-top: 16px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.7rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.15rem;
|
||||
color: rgba(24, 24, 24, 0.6);
|
||||
}
|
||||
|
||||
/* CRT Overlay */
|
||||
.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.03) 50%);
|
||||
background-size: 100% 4px;
|
||||
pointer-events: none;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 768px) {
|
||||
.layout {
|
||||
padding: 40px 24px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 3rem;
|
||||
}
|
||||
|
||||
.stat-box {
|
||||
grid-column: span 6;
|
||||
}
|
||||
|
||||
.title-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.header-meta-row {
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
}
|
||||
}
|
||||
</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 // {{current_date}}</div>
|
||||
<h1>Daily<br><span class="highlight">Analysis</span><br>Export</h1>
|
||||
<p class="header-brief">
|
||||
QQ群日常活动分析报告,基于消息统计与AI分析生成
|
||||
</p>
|
||||
<div class="header-meta-row">
|
||||
<div class="meta-block">
|
||||
<div class="meta-label">Generated At</div>
|
||||
<span class="meta-value">{{current_datetime}}</span>
|
||||
</div>
|
||||
<div class="meta-block">
|
||||
<div class="meta-label">Peak Window</div>
|
||||
<span class="meta-value">{{most_active_period}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- Stats Grid -->
|
||||
<div class="grid-container">
|
||||
<div class="stat-box">
|
||||
<span class="stat-label">Messages</span>
|
||||
<div class="stat-value">{{message_count}}</div>
|
||||
<div class="stat-note">累计消息数量</div>
|
||||
</div>
|
||||
|
||||
<div class="stat-box">
|
||||
<span class="stat-label">Participants</span>
|
||||
<div class="stat-value">{{participant_count}}</div>
|
||||
<div class="stat-note">参与者计数</div>
|
||||
</div>
|
||||
|
||||
<div class="stat-box">
|
||||
<span class="stat-label">Characters</span>
|
||||
<div class="stat-value">{{total_characters}}</div>
|
||||
<div class="stat-note">文本总字数</div>
|
||||
</div>
|
||||
|
||||
<div class="stat-box">
|
||||
<span class="stat-label">Emoji</span>
|
||||
<div class="stat-value">{{emoji_count}}</div>
|
||||
<div class="stat-note">表情符号统计</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- CRT Console -->
|
||||
<div class="grid-container">
|
||||
<div class="crt-console">
|
||||
<div class="crt-label">Peak Activity Window</div>
|
||||
<div class="crt-value">{{most_active_period}}</div>
|
||||
<div class="crt-sub">活跃序列 SCAN // 消息流强度 {{message_count}}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Hourly Activity -->
|
||||
<div class="section-label">
|
||||
Hourly Broadcast <span>ACTIVITY_SPECTRUM</span>
|
||||
</div>
|
||||
<div class="grid-container">
|
||||
<div class="content-box">
|
||||
<div class="activity-wrapper">
|
||||
{{hourly_chart_html}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Topics -->
|
||||
<div class="section-label">
|
||||
Thread Matrix <span>TOPICS_MODULE</span>
|
||||
</div>
|
||||
<div class="grid-container">
|
||||
<div class="content-box">
|
||||
<div class="topic-list">
|
||||
{{topics_html}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Titles -->
|
||||
<div class="section-label">
|
||||
Operator Registry <span>TITLES_MODULE</span>
|
||||
</div>
|
||||
<div class="grid-container">
|
||||
<div class="content-box">
|
||||
<div class="title-grid">
|
||||
{{titles_html}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Quotes -->
|
||||
<div class="section-label">
|
||||
Golden Lines <span>QUOTES_MODULE</span>
|
||||
</div>
|
||||
<div class="grid-container">
|
||||
<div class="content-box">
|
||||
<div class="quote-list">
|
||||
{{quotes_html}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Token Strip -->
|
||||
<div class="grid-container">
|
||||
<div class="token-strip">
|
||||
<div><span class="token-label">Total Tokens //</span> {{total_tokens}}</div>
|
||||
<div><span class="token-label">Prompt //</span> {{prompt_tokens}}</div>
|
||||
<div><span class="token-label">Completion //</span> {{completion_tokens}}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<div>CRT_EXPORT_CHANNEL // QQ群日常分析</div>
|
||||
<div>END_OF_LINE_</div>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,727 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Retro Futurism Daily Export</title>
|
||||
<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=Oswald:wght@400;600&family=JetBrains+Mono:wght@400;600&family=Noto+Sans+SC:wght@400;500&display=swap"
|
||||
rel="stylesheet">
|
||||
<style>
|
||||
@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 {
|
||||
--c-main: #B2653B;
|
||||
--c-bg: #F5EDDC;
|
||||
--c-dark: #181818;
|
||||
--c-grid: rgba(186, 133, 48, 0.2);
|
||||
--c-accent-1: #5C7F71;
|
||||
--c-accent-2: #802520;
|
||||
--c-accent-3: #BA8530;
|
||||
--font-display: "Oswald", "Oswald-Fallback", Impact, "Arial Black", sans-serif;
|
||||
--font-body: "Noto Sans SC", "NotoSans-Fallback", "Microsoft YaHei", "PingFang SC", sans-serif;
|
||||
--font-mono: "JetBrains Mono", "JetBrains-Fallback", Consolas, Monaco, "Courier New", monospace;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
background: linear-gradient(180deg, #f8f2e5, #efe1ca 65%, #fbf5ea);
|
||||
font-family: var(--font-body);
|
||||
color: var(--c-dark);
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
body::before {
|
||||
content: "";
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background-image:
|
||||
linear-gradient(var(--c-grid) 1px, transparent 1px),
|
||||
linear-gradient(90deg, var(--c-grid) 1px, transparent 1px);
|
||||
background-size: 72px 72px;
|
||||
opacity: 0.4;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
body::after {
|
||||
content: "";
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background:
|
||||
radial-gradient(circle at 12% 10%, rgba(92, 127, 113, 0.25), transparent 45%),
|
||||
radial-gradient(circle at 80% 15%, rgba(128, 37, 32, 0.2), transparent 40%),
|
||||
linear-gradient(90deg, rgba(178, 101, 59, 0.08), transparent 55%);
|
||||
opacity: 0.7;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.scanlines {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
background-image: linear-gradient(rgba(24, 24, 24, 0.08) 50%, transparent 50%);
|
||||
background-size: 100% 5px;
|
||||
mix-blend-mode: multiply;
|
||||
opacity: 0.35;
|
||||
}
|
||||
|
||||
.report-shell {
|
||||
position: relative;
|
||||
width: min(1100px, calc(100% - 48px));
|
||||
margin: 48px auto 80px;
|
||||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.95), rgba(246, 232, 210, 0.98));
|
||||
border-left: 16px solid var(--c-main);
|
||||
border-right: 2px solid rgba(24, 24, 24, 0.08);
|
||||
box-shadow: 0 40px 80px rgba(0, 0, 0, 0.25);
|
||||
overflow: hidden;
|
||||
padding-bottom: 60px;
|
||||
}
|
||||
|
||||
.report-shell::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -50px;
|
||||
width: 180px;
|
||||
height: 100%;
|
||||
background: linear-gradient(180deg, rgba(24, 24, 24, 0), rgba(178, 101, 59, 0.1), rgba(24, 24, 24, 0));
|
||||
}
|
||||
|
||||
.color-strip {
|
||||
position: absolute;
|
||||
top: 32px;
|
||||
left: -40px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.color-strip span {
|
||||
width: 120px;
|
||||
height: 6px;
|
||||
}
|
||||
|
||||
.strip-1 {
|
||||
background: var(--c-accent-1);
|
||||
}
|
||||
|
||||
.strip-2 {
|
||||
background: var(--c-accent-2);
|
||||
}
|
||||
|
||||
.strip-3 {
|
||||
background: var(--c-accent-3);
|
||||
}
|
||||
|
||||
header.hero {
|
||||
display: grid;
|
||||
grid-template-columns: 2.2fr 1fr;
|
||||
gap: 40px;
|
||||
padding: 80px 64px 40px 64px;
|
||||
}
|
||||
|
||||
.hero-label {
|
||||
font-family: var(--font-mono);
|
||||
letter-spacing: 0.3rem;
|
||||
font-size: 0.78rem;
|
||||
text-transform: uppercase;
|
||||
color: rgba(24, 24, 24, 0.65);
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.hero-title {
|
||||
font-family: var(--font-display);
|
||||
font-size: clamp(3rem, 6vw, 4.8rem);
|
||||
text-transform: uppercase;
|
||||
line-height: 0.9;
|
||||
margin: 0 0 18px;
|
||||
letter-spacing: 0.1rem;
|
||||
}
|
||||
|
||||
.hero-title .accent {
|
||||
color: var(--c-main);
|
||||
}
|
||||
|
||||
.hero-brief {
|
||||
max-width: 460px;
|
||||
color: rgba(24, 24, 24, 0.7);
|
||||
line-height: 1.6;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.hero-meta {
|
||||
display: flex;
|
||||
gap: 24px;
|
||||
margin-top: 28px;
|
||||
font-family: var(--font-mono);
|
||||
}
|
||||
|
||||
.hero-meta .meta-block {
|
||||
border-left: 4px solid var(--c-main);
|
||||
padding-left: 14px;
|
||||
}
|
||||
|
||||
.meta-label {
|
||||
font-size: 0.72rem;
|
||||
letter-spacing: 0.2rem;
|
||||
text-transform: uppercase;
|
||||
color: rgba(24, 24, 24, 0.5);
|
||||
}
|
||||
|
||||
.meta-value {
|
||||
display: block;
|
||||
margin-top: 4px;
|
||||
color: var(--c-dark);
|
||||
}
|
||||
|
||||
.crt-console {
|
||||
background: #181818;
|
||||
color: var(--c-bg);
|
||||
padding: 24px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid rgba(245, 237, 220, 0.25);
|
||||
box-shadow: inset 0 0 25px rgba(0, 0, 0, 0.5);
|
||||
min-height: 280px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.crt-console::before {
|
||||
content: "CRT CHANNEL";
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 16px;
|
||||
font-family: var(--font-mono);
|
||||
letter-spacing: 0.22rem;
|
||||
font-size: 0.68rem;
|
||||
color: rgba(245, 237, 220, 0.6);
|
||||
}
|
||||
|
||||
.crt-label {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.78rem;
|
||||
letter-spacing: 0.28rem;
|
||||
text-transform: uppercase;
|
||||
color: rgba(245, 237, 220, 0.7);
|
||||
}
|
||||
|
||||
.crt-value {
|
||||
font-family: var(--font-display);
|
||||
font-size: 3rem;
|
||||
color: var(--c-main);
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
.crt-sub {
|
||||
font-size: 0.9rem;
|
||||
color: rgba(245, 237, 220, 0.8);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.section-shell {
|
||||
padding: 0 64px;
|
||||
}
|
||||
|
||||
.stat-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||
gap: 18px;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
border: 1px solid rgba(24, 24, 24, 0.12);
|
||||
padding: 20px;
|
||||
box-shadow: inset 0 0 0 1px rgba(24, 24, 24, 0.05);
|
||||
min-height: 140px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.stat-card::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 18px;
|
||||
border: 1px dashed rgba(24, 24, 24, 0.08);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.78rem;
|
||||
letter-spacing: 0.2rem;
|
||||
text-transform: uppercase;
|
||||
color: rgba(24, 24, 24, 0.55);
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-family: var(--font-display);
|
||||
font-size: 2.8rem;
|
||||
line-height: 1;
|
||||
color: var(--c-main);
|
||||
margin: 16px 0 8px;
|
||||
}
|
||||
|
||||
.stat-note {
|
||||
font-size: 0.9rem;
|
||||
color: rgba(24, 24, 24, 0.7);
|
||||
}
|
||||
|
||||
.module {
|
||||
margin: 36px 0;
|
||||
padding: 32px 32px 40px;
|
||||
border-left: 5px solid rgba(178, 101, 59, 0.6);
|
||||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.95), rgba(245, 237, 220, 0.85));
|
||||
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.08);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.module::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 16px;
|
||||
border: 1px solid rgba(24, 24, 24, 0.06);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.module-heading {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.module-kicker {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.75rem;
|
||||
letter-spacing: 0.3rem;
|
||||
text-transform: uppercase;
|
||||
color: rgba(24, 24, 24, 0.55);
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.module-title {
|
||||
margin: 0;
|
||||
font-family: var(--font-display);
|
||||
font-size: 2.2rem;
|
||||
letter-spacing: 0.1rem;
|
||||
}
|
||||
|
||||
.module-tag {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.75rem;
|
||||
letter-spacing: 0.3rem;
|
||||
background: var(--c-dark);
|
||||
color: var(--c-bg);
|
||||
padding: 6px 14px;
|
||||
border-radius: 30px;
|
||||
}
|
||||
|
||||
.activity-panel {
|
||||
background: #fff5eb;
|
||||
padding: 20px;
|
||||
border: 1px solid rgba(24, 24, 24, 0.08);
|
||||
}
|
||||
|
||||
.activity-board {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.activity-row {
|
||||
display: grid;
|
||||
grid-template-columns: 80px 1fr 70px;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
font-family: var(--font-mono);
|
||||
color: rgba(24, 24, 24, 0.6);
|
||||
}
|
||||
|
||||
.activity-hour {
|
||||
letter-spacing: 0.1rem;
|
||||
}
|
||||
|
||||
.activity-meter {
|
||||
background: rgba(24, 24, 24, 0.08);
|
||||
height: 10px;
|
||||
border-radius: 20px;
|
||||
overflow: hidden;
|
||||
border: 1px solid rgba(24, 24, 24, 0.1);
|
||||
}
|
||||
|
||||
.activity-bar {
|
||||
height: 100%;
|
||||
width: var(--pct, 10%);
|
||||
background: linear-gradient(90deg, rgba(178, 101, 59, 0.8), rgba(178, 101, 59, 0.3));
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.activity-count {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.topic-stack {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 18px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.topic-card {
|
||||
display: grid;
|
||||
grid-template-columns: 90px 1fr;
|
||||
gap: 20px;
|
||||
padding-bottom: 18px;
|
||||
border-bottom: 1px solid rgba(24, 24, 24, 0.08);
|
||||
}
|
||||
|
||||
.topic-index {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 1.2rem;
|
||||
letter-spacing: 0.35rem;
|
||||
color: rgba(24, 24, 24, 0.35);
|
||||
}
|
||||
|
||||
.topic-title {
|
||||
margin: 0;
|
||||
font-size: 1.2rem;
|
||||
letter-spacing: 0.04rem;
|
||||
color: var(--c-dark);
|
||||
}
|
||||
|
||||
.topic-meta {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.8rem;
|
||||
letter-spacing: 0.16rem;
|
||||
color: rgba(24, 24, 24, 0.5);
|
||||
margin: 6px 0;
|
||||
}
|
||||
|
||||
.topic-detail {
|
||||
color: rgba(24, 24, 24, 0.75);
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.title-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
|
||||
gap: 18px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.title-card {
|
||||
display: grid;
|
||||
grid-template-columns: 72px 1fr;
|
||||
column-gap: 18px;
|
||||
padding: 18px;
|
||||
border: 1px solid rgba(24, 24, 24, 0.08);
|
||||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.95), rgba(245, 237, 220, 0.6));
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.title-card::before,
|
||||
.title-card::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
height: 4px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.title-card::before {
|
||||
left: 12px;
|
||||
width: 32px;
|
||||
background: var(--c-accent-1);
|
||||
}
|
||||
|
||||
.title-card::after {
|
||||
left: 48px;
|
||||
width: 32px;
|
||||
background: var(--c-accent-2);
|
||||
}
|
||||
|
||||
.title-avatar {
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
border: 1px solid rgba(24, 24, 24, 0.12);
|
||||
background: rgba(24, 24, 24, 0.08);
|
||||
grid-row: 1 / span 3;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.title-avatar img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
filter: grayscale(35%) contrast(110%);
|
||||
}
|
||||
|
||||
.title-avatar-fallback {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.78rem;
|
||||
letter-spacing: 0.25rem;
|
||||
color: rgba(24, 24, 24, 0.5);
|
||||
}
|
||||
|
||||
.title-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
grid-column: 2;
|
||||
}
|
||||
|
||||
.title-name {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.title-mbti {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.75rem;
|
||||
letter-spacing: 0.18rem;
|
||||
background: rgba(24, 24, 24, 0.08);
|
||||
padding: 2px 10px;
|
||||
}
|
||||
|
||||
.title-role {
|
||||
grid-column: 2;
|
||||
font-family: var(--font-mono);
|
||||
letter-spacing: 0.3rem;
|
||||
text-transform: uppercase;
|
||||
color: var(--c-main);
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
.title-reason {
|
||||
grid-column: 2;
|
||||
margin: 0;
|
||||
font-size: 0.92rem;
|
||||
color: rgba(24, 24, 24, 0.75);
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.quote-stack {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 18px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.quote-card {
|
||||
padding: 24px;
|
||||
border: 1px dashed rgba(24, 24, 24, 0.15);
|
||||
background: #fff8ee;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.quote-card::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: -6px;
|
||||
right: 40px;
|
||||
width: 90px;
|
||||
height: 6px;
|
||||
background: var(--c-dark);
|
||||
}
|
||||
|
||||
.quote-glyph {
|
||||
font-size: 2.5rem;
|
||||
color: rgba(178, 101, 59, 0.4);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.quote-content {
|
||||
font-size: 1.05rem;
|
||||
color: var(--c-dark);
|
||||
margin: 12px 0;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.quote-author {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.85rem;
|
||||
letter-spacing: 0.2rem;
|
||||
color: rgba(24, 24, 24, 0.6);
|
||||
}
|
||||
|
||||
.quote-note {
|
||||
font-size: 0.9rem;
|
||||
color: rgba(24, 24, 24, 0.7);
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.token-strip {
|
||||
padding: 0 64px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.token-panel {
|
||||
border-top: 1px solid rgba(24, 24, 24, 0.15);
|
||||
padding: 16px 0 8px;
|
||||
display: flex;
|
||||
gap: 30px;
|
||||
font-family: var(--font-mono);
|
||||
letter-spacing: 0.15rem;
|
||||
}
|
||||
|
||||
footer {
|
||||
padding: 0 64px;
|
||||
margin-top: 28px;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.78rem;
|
||||
letter-spacing: 0.25rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
color: rgba(24, 24, 24, 0.65);
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
header.hero {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.report-shell {
|
||||
width: calc(100% - 24px);
|
||||
margin: 24px auto 60px;
|
||||
}
|
||||
|
||||
.section-shell,
|
||||
.token-strip {
|
||||
padding: 0 32px;
|
||||
}
|
||||
|
||||
.module {
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.stat-grid {
|
||||
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="scanlines"></div>
|
||||
<main class="report-shell">
|
||||
<div class="color-strip">
|
||||
<span class="strip-1"></span>
|
||||
<span class="strip-2"></span>
|
||||
<span class="strip-3"></span>
|
||||
</div>
|
||||
<header class="hero">
|
||||
<div>
|
||||
<div class="hero-label">Instruction Catalogue // Retro Futurism Export</div>
|
||||
<h1 class="hero-title">Left <span class="accent">Aligned</span><br>Daily Report</h1>
|
||||
<p class="hero-brief">
|
||||
利用网格与留白塑造复古终端的秩序感,配合 #B2653B 主色的橙铜质感,
|
||||
打造一份兼容当代阅读体验的指令式日报。
|
||||
</p>
|
||||
<div class="hero-meta">
|
||||
<div class="meta-block">
|
||||
<div class="meta-label">Report Date</div>
|
||||
<span class="meta-value">{{current_date}}</span>
|
||||
</div>
|
||||
<div class="meta-block">
|
||||
<div class="meta-label">Generated At</div>
|
||||
<span class="meta-value">{{current_datetime}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="crt-console">
|
||||
<div class="crt-label">Peak Window</div>
|
||||
<div class="crt-value">{{most_active_period}}</div>
|
||||
<div class="crt-sub">活跃序列 SCAN</div>
|
||||
<div class="crt-sub">消息流强度 {{message_count}}</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<section class="section-shell">
|
||||
<div class="stat-grid">
|
||||
<article class="stat-card">
|
||||
<div class="stat-label">Messages</div>
|
||||
<div class="stat-value">{{message_count}}</div>
|
||||
<div class="stat-note">累计消息数量</div>
|
||||
</article>
|
||||
<article class="stat-card">
|
||||
<div class="stat-label">Participants</div>
|
||||
<div class="stat-value">{{participant_count}}</div>
|
||||
<div class="stat-note">参与者计数</div>
|
||||
</article>
|
||||
<article class="stat-card">
|
||||
<div class="stat-label">Characters</div>
|
||||
<div class="stat-value">{{total_characters}}</div>
|
||||
<div class="stat-note">文本总字数</div>
|
||||
</article>
|
||||
<article class="stat-card">
|
||||
<div class="stat-label">Emoji Count</div>
|
||||
<div class="stat-value">{{emoji_count}}</div>
|
||||
<div class="stat-note">表情符号统计</div>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section-shell module module-activity">
|
||||
<div class="module-heading">
|
||||
<div>
|
||||
<div class="module-kicker">Activity Spectrum</div>
|
||||
<h2 class="module-title">Hourly Broadcast</h2>
|
||||
</div>
|
||||
<div class="module-tag">GRID-01</div>
|
||||
</div>
|
||||
<div class="activity-panel">
|
||||
{{hourly_chart_html}}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="section-shell">
|
||||
{{topics_html}}
|
||||
{{titles_html}}
|
||||
{{quotes_html}}
|
||||
</div>
|
||||
|
||||
<section class="token-strip">
|
||||
<div class="module-kicker">Token Monitor</div>
|
||||
<div class="token-panel">
|
||||
<div>Total Tokens // {{total_tokens}}</div>
|
||||
<div>Prompt Tokens // {{prompt_tokens}}</div>
|
||||
<div>Completion Tokens // {{completion_tokens}}</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<span>CRT EXPORT CHANNEL</span>
|
||||
<span>END OF LINE</span>
|
||||
</footer>
|
||||
</main>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,10 @@
|
||||
{% if quotes %}
|
||||
{% for quote in quotes %}
|
||||
<article class="quote-item">
|
||||
<div class="quote-glyph">"</div>
|
||||
<p class="quote-content">{{ quote.content }}</p>
|
||||
<div class="quote-author">— {{ quote.sender }}</div>
|
||||
<p class="quote-note">{{ quote.reason }}</p>
|
||||
</article>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
@@ -0,0 +1,12 @@
|
||||
{% if topics %}
|
||||
{% for topic in topics %}
|
||||
<article class="topic-item">
|
||||
<div class="topic-index">{{ "%02d"|format(topic.index) }}</div>
|
||||
<div>
|
||||
<h3 class="topic-title">{{ topic.topic.topic }}</h3>
|
||||
<p class="topic-meta">PARTICIPANTS: {{ topic.contributors }}</p>
|
||||
<p class="topic-detail">{{ topic.topic.detail }}</p>
|
||||
</div>
|
||||
</article>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
@@ -0,0 +1,21 @@
|
||||
{% if titles %}
|
||||
{% for title in titles %}
|
||||
<article class="title-item">
|
||||
<div class="title-header">
|
||||
<div class="title-avatar">
|
||||
{% if title.avatar_data %}
|
||||
<img src="{{ title.avatar_data }}" alt="{{ title.name }}">
|
||||
{% else %}
|
||||
<div class="title-avatar-fallback">CRT</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div>
|
||||
<span class="title-name">{{ title.name }}</span>
|
||||
<span class="title-mbti">{{ title.mbti }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="title-role">{{ title.title }}</div>
|
||||
<p class="title-reason">{{ title.reason }}</p>
|
||||
</article>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
@@ -0,0 +1,562 @@
|
||||
<!--
|
||||
@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