wukong-gitlog-cli 1.0.6 → 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [1.0.7](https://github.com/tomatobybike/wukong-gitlog-cli/compare/v1.0.6...v1.0.7) (2025-11-29)
6
+
7
+
8
+ ### Features
9
+
10
+ * 🎸 charts 2 echarts ([6d6d780](https://github.com/tomatobybike/wukong-gitlog-cli/commit/6d6d780c053cd094a3a59ee58249d55bec504655))
11
+
5
12
  ### [1.0.6](https://github.com/tomatobybike/wukong-gitlog-cli/compare/v1.0.5...v1.0.6) (2025-11-29)
6
13
 
7
14
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wukong-gitlog-cli",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "description": "Advanced Git commit log exporter with Excel/JSON/TXT output, grouping, stats and CLI.",
5
5
  "keywords": [
6
6
  "git",
package/web/app.js CHANGED
@@ -1,4 +1,3 @@
1
- /* global Chart */
2
1
  /* eslint-disable import/no-absolute-path */
3
2
  const formatDate = (d) => new Date(d).toLocaleString();
4
3
 
@@ -19,38 +18,103 @@ async function loadData() {
19
18
  }
20
19
  }
21
20
 
22
- function renderCommitsTable(commits) {
21
+ let commitsAll = [];
22
+ let filtered = [];
23
+ let page = 1;
24
+ let pageSize = 10;
25
+
26
+ function renderCommitsTablePage() {
23
27
  const tbody = document.querySelector('#commitsTable tbody');
24
28
  tbody.innerHTML = '';
25
- commits.forEach((c) => {
29
+ const start = (page - 1) * pageSize;
30
+ const end = start + pageSize;
31
+ filtered.slice(start, end).forEach((c) => {
26
32
  const tr = document.createElement('tr');
27
33
  tr.innerHTML = `<td>${c.hash.slice(0, 8)}</td><td>${c.author}</td><td>${formatDate(c.date)}</td><td>${c.message}</td>`;
28
34
  tbody.appendChild(tr);
29
35
  });
30
36
  }
31
37
 
38
+ function updatePager() {
39
+ const totalPages = Math.max(1, Math.ceil(filtered.length / pageSize));
40
+ if (page > totalPages) page = totalPages;
41
+ const pageInfo = document.getElementById('pageInfo');
42
+ pageInfo.textContent = `${page} / ${totalPages}`;
43
+ document.getElementById('prevPage').disabled = page <= 1;
44
+ document.getElementById('nextPage').disabled = page >= totalPages;
45
+ }
46
+
47
+ function applySearch() {
48
+ const q = document.getElementById('searchInput').value.trim().toLowerCase();
49
+ if (!q) {
50
+ filtered = commitsAll.slice();
51
+ } else {
52
+ filtered = commitsAll.filter((c) => {
53
+ const h = c.hash.toLowerCase();
54
+ const a = String(c.author || '').toLowerCase();
55
+ const m = String(c.message || '').toLowerCase();
56
+ const d = formatDate(c.date).toLowerCase();
57
+ return h.includes(q) || a.includes(q) || m.includes(q) || d.includes(q);
58
+ });
59
+ }
60
+ page = 1;
61
+ updatePager();
62
+ renderCommitsTablePage();
63
+ }
64
+
65
+ function initTableControls() {
66
+ document.getElementById('searchInput').addEventListener('input', applySearch);
67
+ document.getElementById('pageSize').addEventListener('change', (e) => {
68
+ pageSize = parseInt(e.target.value, 10) || 10;
69
+ page = 1;
70
+ updatePager();
71
+ renderCommitsTablePage();
72
+ });
73
+ document.getElementById('prevPage').addEventListener('click', () => {
74
+ if (page > 1) {
75
+ page -= 1;
76
+ updatePager();
77
+ renderCommitsTablePage();
78
+ }
79
+ });
80
+ document.getElementById('nextPage').addEventListener('click', () => {
81
+ const totalPages = Math.max(1, Math.ceil(filtered.length / pageSize));
82
+ if (page < totalPages) {
83
+ page += 1;
84
+ updatePager();
85
+ renderCommitsTablePage();
86
+ }
87
+ });
88
+ }
89
+
32
90
  function drawHourlyOvertime(stats) {
33
- const ctx = document.getElementById('hourlyOvertimeChart').getContext('2d');
91
+ const el = document.getElementById('hourlyOvertimeChart');
92
+ const chart = echarts.init(el);
34
93
  const data = stats.hourlyOvertimeCommits || [];
35
94
  const labels = Array.from({ length: 24 }, (_, i) => String(i).padStart(2, '0'));
36
- const chartHourly = new Chart(ctx, {
37
- type: 'bar',
38
- data: { labels, datasets: [{ label: 'Overtime commits', data }] },
39
- options: { responsive: true }
95
+ chart.setOption({
96
+ tooltip: {},
97
+ xAxis: { type: 'category', data: labels },
98
+ yAxis: { type: 'value' },
99
+ series: [{ type: 'bar', name: 'Overtime commits', data }]
40
100
  });
41
- return chartHourly;
101
+ return chart;
42
102
  }
43
103
 
44
104
  function drawOutsideVsInside(stats) {
45
- const ctx = document.getElementById('outsideVsInsideChart').getContext('2d');
105
+ const el = document.getElementById('outsideVsInsideChart');
106
+ const chart = echarts.init(el);
46
107
  const outside = stats.outsideWorkCount || 0;
47
108
  const total = stats.total || 0;
48
109
  const inside = Math.max(0, total - outside);
49
- const chartPie = new Chart(ctx, {
50
- type: 'pie',
51
- data: { labels: ['Inside work', 'Outside work'], datasets: [{ data: [inside, outside], backgroundColor: ['#36a2eb', '#ff6384'] }] },
110
+ chart.setOption({
111
+ tooltip: {},
112
+ series: [{ type: 'pie', radius: '55%', data: [
113
+ { value: inside, name: '工作时间内' },
114
+ { value: outside, name: '下班时间' }
115
+ ] }]
52
116
  });
53
- return chartPie;
117
+ return chart;
54
118
  }
55
119
 
56
120
  function drawDailyTrend(commits) {
@@ -61,42 +125,45 @@ function drawDailyTrend(commits) {
61
125
  });
62
126
  const labels = Array.from(map.keys()).sort();
63
127
  const data = labels.map(l => map.get(l));
64
- const ctx = document.getElementById('dailyTrendChart').getContext('2d');
65
- const chartDaily = new Chart(ctx, {
66
- type: 'line',
67
- data: { labels, datasets: [{ label: 'Commits per day', data, fill: true, tension: 0.3 }] },
128
+ const el = document.getElementById('dailyTrendChart');
129
+ const chart = echarts.init(el);
130
+ chart.setOption({
131
+ tooltip: {},
132
+ xAxis: { type: 'category', data: labels },
133
+ yAxis: { type: 'value' },
134
+ series: [{ type: 'line', name: '每日提交', data, areaStyle: {} }]
68
135
  });
69
- return chartDaily;
136
+ return chart;
70
137
  }
71
138
 
72
139
  function drawWeeklyTrend(weekly) {
73
140
  const labels = weekly.map(w => w.period);
74
141
  const dataRate = weekly.map(w => +(w.outsideWorkRate * 100).toFixed(1));
75
142
  const dataCount = weekly.map(w => w.outsideWorkCount);
76
- const ctx = document.getElementById('weeklyTrendChart').getContext('2d');
77
- const chartWeekly = new Chart(ctx, {
78
- type: 'line',
79
- data: {
80
- labels,
81
- datasets: [
82
- { label: '加班占比(%)', data: dataRate, borderColor: '#ff6384', yAxisID: 'y1' },
83
- { label: '加班次数', data: dataCount, borderColor: '#36a2eb', yAxisID: 'y2' },
84
- ]
85
- },
86
- options: {
87
- responsive: true,
88
- scales: {
89
- y1: { type: 'linear', position: 'left', min: 0, max: 100 },
90
- y2: { type: 'linear', position: 'right' }
91
- }
92
- }
143
+ const el = document.getElementById('weeklyTrendChart');
144
+ const chart = echarts.init(el);
145
+ chart.setOption({
146
+ tooltip: {},
147
+ xAxis: { type: 'category', data: labels },
148
+ yAxis: [
149
+ { type: 'value', min: 0, max: 100 },
150
+ { type: 'value' }
151
+ ],
152
+ series: [
153
+ { type: 'line', name: '加班占比(%)', data: dataRate, yAxisIndex: 0 },
154
+ { type: 'line', name: '加班次数', data: dataCount, yAxisIndex: 1 }
155
+ ]
93
156
  });
94
- return chartWeekly;
157
+ return chart;
95
158
  }
96
159
 
97
160
  (async function main() {
98
161
  const { commits, stats, weekly } = await loadData();
99
- renderCommitsTable(commits);
162
+ commitsAll = commits;
163
+ filtered = commitsAll.slice();
164
+ initTableControls();
165
+ updatePager();
166
+ renderCommitsTablePage();
100
167
  drawHourlyOvertime(stats);
101
168
  drawOutsideVsInside(stats);
102
169
  drawDailyTrend(commits);
package/web/index.html CHANGED
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width,initial-scale=1" />
6
6
  <title>wukong-gitlog-cli — Overtime Dashboard</title>
7
7
  <link rel="stylesheet" href="/style.css" />
8
- <script src="./static/chart.js"></script>
8
+ <script src="./static/echarts.min.js"></script>
9
9
  </head>
10
10
  <body>
11
11
  <header>
@@ -15,28 +15,43 @@
15
15
  <section id="chartsHalf">
16
16
  <div class="chart-card">
17
17
  <h2>下班时间 vs 工作时间提交占比</h2>
18
- <canvas id="outsideVsInsideChart"></canvas>
18
+ <div id="outsideVsInsideChart" class="echart"></div>
19
19
  </div>
20
20
  <div class="chart-card"></div>
21
21
  </section>
22
22
  <section id="charts">
23
23
  <div class="chart-card">
24
24
  <h2>每小时加班分布 (小时 -> 提交数)</h2>
25
- <canvas id="hourlyOvertimeChart"></canvas>
25
+ <div id="hourlyOvertimeChart" class="echart"></div>
26
26
  </div>
27
27
 
28
28
  <div class="chart-card">
29
29
  <h2>按日提交趋势</h2>
30
- <canvas id="dailyTrendChart"></canvas>
30
+ <div id="dailyTrendChart" class="echart"></div>
31
31
  </div>
32
32
  <div class="chart-card">
33
33
  <h2>每周趋势(加班占比)</h2>
34
- <canvas id="weeklyTrendChart"></canvas>
34
+ <div id="weeklyTrendChart" class="echart"></div>
35
35
  </div>
36
36
  </section>
37
37
 
38
38
  <section class="table-card">
39
39
  <h2>提交清单</h2>
40
+ <div id="tableControls">
41
+ <input id="searchInput" type="search" placeholder="搜索作者/信息/Hash" />
42
+ <label for="pageSize">每页显示</label>
43
+ <select id="pageSize">
44
+ <option value="10">10</option>
45
+ <option value="20">20</option>
46
+ <option value="50">50</option>
47
+ <option value="100">100</option>
48
+ </select>
49
+ <div class="pager">
50
+ <button id="prevPage">上一页</button>
51
+ <span id="pageInfo"></span>
52
+ <button id="nextPage">下一页</button>
53
+ </div>
54
+ </div>
40
55
  <table id="commitsTable">
41
56
  <thead>
42
57
  <tr>