|
|
<!DOCTYPE html>
|
|
|
<html lang="zh-CN">
|
|
|
<head>
|
|
|
<meta charset="UTF-8">
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
<title>OpenRank Dashboard - 开源贡献分析平台</title>
|
|
|
<link rel="stylesheet" href="styles.css">
|
|
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
|
|
<!-- Inline tiny favicon to avoid browser requesting /favicon.ico and causing 404 in dev console -->
|
|
|
<link rel="icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR4nGNgYAAAAAMAASsJTYQAAAAASUVORK5CYII=">
|
|
|
</head>
|
|
|
<body>
|
|
|
<div class="container">
|
|
|
<!-- 头部导航 -->
|
|
|
<header class="header">
|
|
|
<div class="logo">
|
|
|
<i class="fas fa-chart-network"></i>
|
|
|
<span>OpenRank Analytics</span>
|
|
|
</div>
|
|
|
<div class="mode-switch" id="mode-switch">
|
|
|
<button class="mode-btn active" data-mode="global">全局模式</button>
|
|
|
<button class="mode-btn" data-mode="project">项目模式</button>
|
|
|
</div>
|
|
|
<nav class="nav">
|
|
|
<button class="nav-btn active" data-tab="overview">总览</button>
|
|
|
<button class="nav-btn" data-tab="repositories">仓库分析</button>
|
|
|
<button class="nav-btn" data-tab="developers">开发者分析</button>
|
|
|
<button class="nav-btn" data-tab="network">网络图谱</button>
|
|
|
<button class="nav-btn" data-tab="settings">配置</button>
|
|
|
</nav>
|
|
|
<div class="header-actions">
|
|
|
<button class="btn-primary" id="calculate-btn">
|
|
|
<i class="fas fa-calculator"></i>
|
|
|
计算 OpenRank
|
|
|
</button>
|
|
|
</div>
|
|
|
</header>
|
|
|
|
|
|
<!-- 主要内容区域 -->
|
|
|
<main class="main-content" id="global-root">
|
|
|
<!-- 总览面板 -->
|
|
|
<div class="tab-content active" id="overview">
|
|
|
<div class="stats-grid">
|
|
|
<!-- 关键指标卡片 -->
|
|
|
<div class="stat-card">
|
|
|
<div class="stat-icon">
|
|
|
<i class="fas fa-users"></i>
|
|
|
</div>
|
|
|
<div class="stat-info">
|
|
|
<h3>活跃开发者</h3>
|
|
|
<span class="stat-value" id="active-developers">0</span>
|
|
|
<span class="stat-change positive">+12%</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="stat-card">
|
|
|
<div class="stat-icon">
|
|
|
<i class="fas fa-code-branch"></i>
|
|
|
</div>
|
|
|
<div class="stat-info">
|
|
|
<h3>活跃仓库</h3>
|
|
|
<span class="stat-value" id="active-repos">0</span>
|
|
|
<span class="stat-change positive">+8%</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="stat-card">
|
|
|
<div class="stat-icon">
|
|
|
<i class="fas fa-star"></i>
|
|
|
</div>
|
|
|
<div class="stat-info">
|
|
|
<h3>总 OpenRank</h3>
|
|
|
<span class="stat-value" id="total-openrank">0</span>
|
|
|
<span class="stat-change positive">+15%</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="stat-card">
|
|
|
<div class="stat-icon">
|
|
|
<i class="fas fa-trending-up"></i>
|
|
|
</div>
|
|
|
<div class="stat-info">
|
|
|
<h3>平均贡献度</h3>
|
|
|
<span class="stat-value" id="avg-contribution">0</span>
|
|
|
<span class="stat-change positive">+5%</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 图表区域 -->
|
|
|
<div class="charts-grid">
|
|
|
<div class="chart-card">
|
|
|
<h3>OpenRank 分布</h3>
|
|
|
<div class="chart-container" id="distribution-chart">
|
|
|
<canvas id="distribution-canvas"></canvas>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="chart-card">
|
|
|
<h3>活动类型分析</h3>
|
|
|
<div class="chart-container" id="activity-chart">
|
|
|
<canvas id="activity-canvas"></canvas>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="chart-card full-width">
|
|
|
<h3>Top 10 开发者排名</h3>
|
|
|
<div class="ranking-table" id="developer-ranking">
|
|
|
<div class="table-header">
|
|
|
<span>排名</span>
|
|
|
<span>开发者</span>
|
|
|
<span>OpenRank</span>
|
|
|
<span>变化</span>
|
|
|
</div>
|
|
|
<div class="table-body" id="ranking-body">
|
|
|
<!-- 排名数据将通过JS动态生成 -->
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 仓库分析面板 -->
|
|
|
<div class="tab-content" id="repositories">
|
|
|
<div class="panel-header">
|
|
|
<h2>仓库分析</h2>
|
|
|
<div class="filter-controls">
|
|
|
<select id="repo-filter">
|
|
|
<option value="all">所有仓库</option>
|
|
|
<option value="top10">Top 10</option>
|
|
|
<option value="rising">上升最快</option>
|
|
|
</select>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="repo-grid" id="repo-grid">
|
|
|
<!-- 仓库卡片将通过JS动态生成 -->
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 开发者分析面板 -->
|
|
|
<div class="tab-content" id="developers">
|
|
|
<div class="panel-header">
|
|
|
<h2>开发者分析</h2>
|
|
|
<div class="search-box">
|
|
|
<input type="text" placeholder="搜索开发者..." id="developer-search">
|
|
|
<i class="fas fa-search"></i>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="developer-stats">
|
|
|
<!-- 开发者分析内容 -->
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 网络图谱面板 -->
|
|
|
<div class="tab-content" id="network">
|
|
|
<div class="panel-header">
|
|
|
<h2>协作网络图谱</h2>
|
|
|
<div class="graph-controls">
|
|
|
<button class="btn-secondary" id="zoom-in">
|
|
|
<i class="fas fa-plus"></i>
|
|
|
</button>
|
|
|
<button class="btn-secondary" id="zoom-out">
|
|
|
<i class="fas fa-minus"></i>
|
|
|
</button>
|
|
|
<button class="btn-secondary" id="reset-view">
|
|
|
<i class="fas fa-sync"></i>
|
|
|
</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="graph-container" id="network-graph">
|
|
|
<canvas id="graph-canvas"></canvas>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 配置面板 -->
|
|
|
<div class="tab-content" id="settings">
|
|
|
<div class="panel-header">
|
|
|
<h2>算法配置</h2>
|
|
|
</div>
|
|
|
<div class="settings-grid">
|
|
|
<div class="setting-card">
|
|
|
<h3>全局参数</h3>
|
|
|
<div class="setting-item">
|
|
|
<label>衰减因子</label>
|
|
|
<input type="number" id="attenuation-factor" value="0.85" step="0.01" min="0" max="1">
|
|
|
</div>
|
|
|
<div class="setting-item">
|
|
|
<label>开发者继承比例</label>
|
|
|
<input type="number" id="developer-retention" value="0.5" step="0.01" min="0" max="1">
|
|
|
</div>
|
|
|
<div class="setting-item">
|
|
|
<label>仓库继承比例</label>
|
|
|
<input type="number" id="repo-retention" value="0.3" step="0.01" min="0" max="1">
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="setting-card">
|
|
|
<h3>活动权重</h3>
|
|
|
<div class="setting-item">
|
|
|
<label>Issue 评论</label>
|
|
|
<input type="number" id="issue-comment-weight" value="0.5252" step="0.0001">
|
|
|
</div>
|
|
|
<div class="setting-item">
|
|
|
<label>创建 Issue</label>
|
|
|
<input type="number" id="open-issue-weight" value="2.2235" step="0.0001">
|
|
|
</div>
|
|
|
<div class="setting-item">
|
|
|
<label>创建 PR</label>
|
|
|
<input type="number" id="open-pull-weight" value="4.0679" step="0.0001">
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</main>
|
|
|
|
|
|
<!-- 项目模式根容器(初始隐藏,通过模式切换显示) -->
|
|
|
<div id="project-mode-root" class="project-mode hidden">
|
|
|
<div class="project-layout">
|
|
|
<aside class="project-sidebar">
|
|
|
<div class="project-sidebar-header">
|
|
|
<h3>项目列表</h3>
|
|
|
<input type="text" id="project-search" placeholder="搜索项目..." />
|
|
|
</div>
|
|
|
<ul id="project-list" class="project-list"></ul>
|
|
|
</aside>
|
|
|
<section class="project-content" id="project-content">
|
|
|
<div class="project-placeholder">
|
|
|
<h3>选择一个项目查看项目级 OpenRank</h3>
|
|
|
<p>左侧选择仓库,右侧展示项目级贡献者、活动分布和时间序列。</p>
|
|
|
</div>
|
|
|
</section>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 状态栏 -->
|
|
|
<footer class="footer">
|
|
|
<div class="status-info">
|
|
|
<span class="status-dot"></span>
|
|
|
<span>系统就绪</span>
|
|
|
</div>
|
|
|
<div class="footer-info">
|
|
|
<span>OpenRank v1.0.0</span>
|
|
|
<span>最后更新: <span id="last-update">-</span></span>
|
|
|
</div>
|
|
|
</footer>
|
|
|
</div>
|
|
|
|
|
|
<!-- 加载动画 -->
|
|
|
<div class="loading-overlay" id="loading-overlay">
|
|
|
<div class="loading-spinner">
|
|
|
<i class="fas fa-atom fa-spin"></i>
|
|
|
<p>计算中...</p>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<!-- 计算 OpenRank 输入对话框 -->
|
|
|
<div class="modal" id="calc-modal">
|
|
|
<div class="modal-content" style="max-width:480px;position:relative;">
|
|
|
<button class="modal-close" data-close-calc>×</button>
|
|
|
<h3 style="margin-top:0;font-size:1.15rem;">计算 OpenRank</h3>
|
|
|
<p style="font-size:.8rem;opacity:.7;margin:.25rem 0 1rem;">请输入仓库 owner 与 repo,并指定起止日期(任意跨度)。如不填则默认最近 30 天。可使用快捷按钮快速填充最近 30/90/180/365 天。</p>
|
|
|
<form id="calc-form" style="display:flex;flex-direction:column;gap:.9rem;">
|
|
|
<div style="display:flex;flex-direction:column;gap:.4rem;">
|
|
|
<label style="font-size:.7rem;letter-spacing:.5px;opacity:.75;">Owner (组织 / 用户)</label>
|
|
|
<input id="calc-owner" type="text" placeholder="例如: demo-org" autocomplete="off" required style="background:rgba(255,255,255,0.1);border:1px solid rgba(255,255,255,0.2);color:#fff;padding:.55rem .7rem;border-radius:8px;outline:none;" />
|
|
|
</div>
|
|
|
<div style="display:flex;flex-direction:column;gap:.4rem;">
|
|
|
<label style="font-size:.7rem;letter-spacing:.5px;opacity:.75;">Repo (仓库名)</label>
|
|
|
<input id="calc-repo" type="text" placeholder="例如: awesome-project" autocomplete="off" required style="background:rgba(255,255,255,0.1);border:1px solid rgba(255,255,255,0.2);color:#fff;padding:.55rem .7rem;border-radius:8px;outline:none;" />
|
|
|
</div>
|
|
|
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:.75rem;align-items:end;">
|
|
|
<div style="display:flex;flex-direction:column;gap:.4rem;">
|
|
|
<label style="font-size:.7rem;letter-spacing:.5px;opacity:.75;">开始日期 (start)</label>
|
|
|
<input id="calc-start" type="date" style="background:rgba(255,255,255,0.1);border:1px solid rgba(255,255,255,0.2);color:#fff;padding:.55rem .6rem;border-radius:8px;outline:none;font-size:.75rem;" />
|
|
|
</div>
|
|
|
<div style="display:flex;flex-direction:column;gap:.4rem;">
|
|
|
<label style="font-size:.7rem;letter-spacing:.5px;opacity:.75;">结束日期 (end)</label>
|
|
|
<input id="calc-end" type="date" style="background:rgba(255,255,255,0.1);border:1px solid rgba(255,255,255,0.2);color:#fff;padding:.55rem .6rem;border-radius:8px;outline:none;font-size:.75rem;" />
|
|
|
</div>
|
|
|
<div style="display:flex;flex-direction:column;gap:.4rem;">
|
|
|
<label style="font-size:.7rem;letter-spacing:.5px;opacity:.75;">快捷范围</label>
|
|
|
<div style="display:flex;flex-wrap:wrap;gap:.35rem;">
|
|
|
<button type="button" class="quick-range-btn" data-range="30">30天</button>
|
|
|
<button type="button" class="quick-range-btn" data-range="90">90天</button>
|
|
|
<button type="button" class="quick-range-btn" data-range="180">180天</button>
|
|
|
<button type="button" class="quick-range-btn" data-range="365">365天</button>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div style="display:flex;gap:.6rem;justify-content:flex-end;margin-top:.5rem;">
|
|
|
<button type="button" class="btn-secondary" data-close-calc style="min-width:90px;">取消</button>
|
|
|
<button type="submit" class="btn-primary" style="min-width:140px;">开始计算</button>
|
|
|
</div>
|
|
|
</form>
|
|
|
<div id="calc-hint" style="margin-top:.75rem;font-size:.65rem;line-height:1.2;opacity:.55;">
|
|
|
说明:首次计算会写入合成仓库记录,项目模式刷新后即可选择;正式项目级重算需在项目面板触发。
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
|
<script src="app.js"></script>
|
|
|
</body>
|
|
|
</html>
|