Fossil SCM

In the by-month and by-year reports, for the row that shows the current year or month, included a dashed box that shows the event count projected to the end of the current month or year.

drh 2023-05-26 00:18 trunk
Commit 42ce541d1208d4c72e6e460e1e1539418e0e69b19c4c35f132c8c3e43c3e07a8
--- skins/ardoise/css.txt
+++ skins/ardoise/css.txt
@@ -1387,11 +1387,16 @@
13871387
}
13881388
.intLink[title=Hyperlink]:hover {
13891389
background: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMiIgaGVpZ2h0PSIyMiIgdmlld0JveD0iMCAwIDUuODIxIDUuODIxIj48cmVjdCByeT0iLjI2NSIgcng9Ii4yNjUiIHk9Ii0uMDAxIiBoZWlnaHQ9IjUuODIxIiB3aWR0aD0iNS44MjEiIGZpbGw9IiM1NTUiLz48cGF0aCBkPSJNMS43NTIgMy45NjhoLjc5M20tLjc5My0yLjExN2guNzkzbS0uNzkzIDIuMTE3Yy0uMzQzIDAtLjY1OS0uMTE5LS44My0uNDE1LS4xNzEtLjI5Ny0uMTcxLS45OSAwLTEuMjg3LjE3MS0uMjk2LjQ4Ny0uNDE1LjgzLS40MTVtMi4yMTcgMi4xMTdoLS43OTRtLjc5NC0yLjExN2gtLjc5NG0uNzk0IDIuMTE3Yy4zNDIgMCAuNjU4LS4xMTkuODMtLjQxNS4xNy0uMjk3LjE3LS45OSAwLTEuMjg3LS4xNzItLjI5Ni0uNDg4LS40MTUtLjgzLS40MTVNMi4xMTcgMi45MWgxLjU4NyIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjZGRkIiBzdHJva2Utd2lkdGg9Ii41MjkiLz48L3N2Zz4=)
13901390
}
13911391
.statistics-report-graph-line {
1392
- background-color: #ff8000
1392
+ border: 2px solid #ff8000;
1393
+ background-color: #ff8000;
1394
+}
1395
+.statistics-report-graph-extra {
1396
+ border: 2px dashed #446979;
1397
+ border-left-style: none;
13931398
}
13941399
mark,
13951400
p.noMoreShun,
13961401
p.shunned,
13971402
span.modpending {
13981403
--- skins/ardoise/css.txt
+++ skins/ardoise/css.txt
@@ -1387,11 +1387,16 @@
1387 }
1388 .intLink[title=Hyperlink]:hover {
1389 background: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMiIgaGVpZ2h0PSIyMiIgdmlld0JveD0iMCAwIDUuODIxIDUuODIxIj48cmVjdCByeT0iLjI2NSIgcng9Ii4yNjUiIHk9Ii0uMDAxIiBoZWlnaHQ9IjUuODIxIiB3aWR0aD0iNS44MjEiIGZpbGw9IiM1NTUiLz48cGF0aCBkPSJNMS43NTIgMy45NjhoLjc5M20tLjc5My0yLjExN2guNzkzbS0uNzkzIDIuMTE3Yy0uMzQzIDAtLjY1OS0uMTE5LS44My0uNDE1LS4xNzEtLjI5Ny0uMTcxLS45OSAwLTEuMjg3LjE3MS0uMjk2LjQ4Ny0uNDE1LjgzLS40MTVtMi4yMTcgMi4xMTdoLS43OTRtLjc5NC0yLjExN2gtLjc5NG0uNzk0IDIuMTE3Yy4zNDIgMCAuNjU4LS4xMTkuODMtLjQxNS4xNy0uMjk3LjE3LS45OSAwLTEuMjg3LS4xNzItLjI5Ni0uNDg4LS40MTUtLjgzLS40MTVNMi4xMTcgMi45MWgxLjU4NyIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjZGRkIiBzdHJva2Utd2lkdGg9Ii41MjkiLz48L3N2Zz4=)
1390 }
1391 .statistics-report-graph-line {
1392 background-color: #ff8000
 
 
 
 
 
1393 }
1394 mark,
1395 p.noMoreShun,
1396 p.shunned,
1397 span.modpending {
1398
--- skins/ardoise/css.txt
+++ skins/ardoise/css.txt
@@ -1387,11 +1387,16 @@
1387 }
1388 .intLink[title=Hyperlink]:hover {
1389 background: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMiIgaGVpZ2h0PSIyMiIgdmlld0JveD0iMCAwIDUuODIxIDUuODIxIj48cmVjdCByeT0iLjI2NSIgcng9Ii4yNjUiIHk9Ii0uMDAxIiBoZWlnaHQ9IjUuODIxIiB3aWR0aD0iNS44MjEiIGZpbGw9IiM1NTUiLz48cGF0aCBkPSJNMS43NTIgMy45NjhoLjc5M20tLjc5My0yLjExN2guNzkzbS0uNzkzIDIuMTE3Yy0uMzQzIDAtLjY1OS0uMTE5LS44My0uNDE1LS4xNzEtLjI5Ny0uMTcxLS45OSAwLTEuMjg3LjE3MS0uMjk2LjQ4Ny0uNDE1LjgzLS40MTVtMi4yMTcgMi4xMTdoLS43OTRtLjc5NC0yLjExN2gtLjc5NG0uNzk0IDIuMTE3Yy4zNDIgMCAuNjU4LS4xMTkuODMtLjQxNS4xNy0uMjk3LjE3LS45OSAwLTEuMjg3LS4xNzItLjI5Ni0uNDg4LS40MTUtLjgzLS40MTVNMi4xMTcgMi45MWgxLjU4NyIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjZGRkIiBzdHJva2Utd2lkdGg9Ii41MjkiLz48L3N2Zz4=)
1390 }
1391 .statistics-report-graph-line {
1392 border: 2px solid #ff8000;
1393 background-color: #ff8000;
1394 }
1395 .statistics-report-graph-extra {
1396 border: 2px dashed #446979;
1397 border-left-style: none;
1398 }
1399 mark,
1400 p.noMoreShun,
1401 p.shunned,
1402 span.modpending {
1403
--- skins/eagle/css.txt
+++ skins/eagle/css.txt
@@ -416,11 +416,16 @@
416416
table.numbered-lines td.line-numbers span.selected-line {
417417
background-color: #7EA2D9;
418418
}
419419
420420
.statistics-report-graph-line {
421
+ border: 2px solid #7EA2D9;
421422
background-color: #7EA2D9;
423
+}
424
+.statistics-report-graph-extra {
425
+ border: 2px solid #7EA2D9;
426
+ border-left-style: none;
422427
}
423428
424429
.timelineModernCell[id], .timelineColumnarCell[id], .timelineDetailCell[id] {
425430
background-color: #455978;
426431
}
427432
--- skins/eagle/css.txt
+++ skins/eagle/css.txt
@@ -416,11 +416,16 @@
416 table.numbered-lines td.line-numbers span.selected-line {
417 background-color: #7EA2D9;
418 }
419
420 .statistics-report-graph-line {
 
421 background-color: #7EA2D9;
 
 
 
 
422 }
423
424 .timelineModernCell[id], .timelineColumnarCell[id], .timelineDetailCell[id] {
425 background-color: #455978;
426 }
427
--- skins/eagle/css.txt
+++ skins/eagle/css.txt
@@ -416,11 +416,16 @@
416 table.numbered-lines td.line-numbers span.selected-line {
417 background-color: #7EA2D9;
418 }
419
420 .statistics-report-graph-line {
421 border: 2px solid #7EA2D9;
422 background-color: #7EA2D9;
423 }
424 .statistics-report-graph-extra {
425 border: 2px solid #7EA2D9;
426 border-left-style: none;
427 }
428
429 .timelineModernCell[id], .timelineColumnarCell[id], .timelineDetailCell[id] {
430 background-color: #455978;
431 }
432
--- skins/xekri/css.txt
+++ skins/xekri/css.txt
@@ -513,11 +513,16 @@
513513
/**************************************
514514
* Statistics Reports
515515
*/
516516
517517
.statistics-report-graph-line {
518
+ border: 2px solid #22e;
518519
background-color: #22e;
520
+}
521
+.statistics-report-graph-extra {
522
+ border: 2px dashed #22e;
523
+ border-left-style: none;
519524
}
520525
521526
.statistics-report-table-events th {
522527
padding: 0 1rem;
523528
}
524529
--- skins/xekri/css.txt
+++ skins/xekri/css.txt
@@ -513,11 +513,16 @@
513 /**************************************
514 * Statistics Reports
515 */
516
517 .statistics-report-graph-line {
 
518 background-color: #22e;
 
 
 
 
519 }
520
521 .statistics-report-table-events th {
522 padding: 0 1rem;
523 }
524
--- skins/xekri/css.txt
+++ skins/xekri/css.txt
@@ -513,11 +513,16 @@
513 /**************************************
514 * Statistics Reports
515 */
516
517 .statistics-report-graph-line {
518 border: 2px solid #22e;
519 background-color: #22e;
520 }
521 .statistics-report-graph-extra {
522 border: 2px dashed #22e;
523 border-left-style: none;
524 }
525
526 .statistics-report-table-events th {
527 padding: 0 1rem;
528 }
529
--- src/default.css
+++ src/default.css
@@ -732,11 +732,16 @@
732732
pre.textPlain {
733733
white-space: pre-wrap;
734734
word-wrap: break-word;
735735
}
736736
.statistics-report-graph-line {
737
+ border: 2px solid #446979;
737738
background-color: #446979;
739
+}
740
+.statistics-report-graph-extra {
741
+ border: 2px dashed #446979;
742
+ border-left-style: none;
738743
}
739744
.statistics-report-table-events th {
740745
padding: 0 1em 0 1em;
741746
}
742747
.statistics-report-table-events td {
743748
--- src/default.css
+++ src/default.css
@@ -732,11 +732,16 @@
732 pre.textPlain {
733 white-space: pre-wrap;
734 word-wrap: break-word;
735 }
736 .statistics-report-graph-line {
 
737 background-color: #446979;
 
 
 
 
738 }
739 .statistics-report-table-events th {
740 padding: 0 1em 0 1em;
741 }
742 .statistics-report-table-events td {
743
--- src/default.css
+++ src/default.css
@@ -732,11 +732,16 @@
732 pre.textPlain {
733 white-space: pre-wrap;
734 word-wrap: break-word;
735 }
736 .statistics-report-graph-line {
737 border: 2px solid #446979;
738 background-color: #446979;
739 }
740 .statistics-report-graph-extra {
741 border: 2px dashed #446979;
742 border-left-style: none;
743 }
744 .statistics-report-table-events th {
745 padding: 0 1em 0 1em;
746 }
747 .statistics-report-table-events td {
748
+41 -5
--- src/statrep.c
+++ src/statrep.c
@@ -169,32 +169,48 @@
169169
the per-year event totals */
170170
int nMaxEvents = 1; /* for calculating length of graph
171171
bars. */
172172
int iterations = 0; /* number of weeks/months we iterate
173173
over */
174
+
175
+ char *zCurrentTF; /* The timeframe in which 'now' lives */
176
+ double rNowFraction; /* Fraction of 'now' timeframe that has
177
+ passed */
178
+ int nTFChar; /* Prefix of date() for timeframe */
179
+
180
+ nTFChar = includeMonth ? 7 : 4;
174181
stats_report_init_view();
175182
db_prepare(&query,
176183
"SELECT substr(date(mtime),1,%d) AS timeframe,"
177184
" count(*) AS eventCount"
178185
" FROM v_reports"
179186
" WHERE ifnull(coalesce(euser,user,'')=%Q,1)"
180187
" GROUP BY timeframe"
181188
" ORDER BY timeframe DESC",
182
- includeMonth ? 7 : 4, zUserName);
189
+ nTFChar, zUserName);
183190
@ <h1>Timeline Events (%s(stats_report_label_for_type()))
184191
@ by year%s(includeMonth ? "/month" : "")
185192
if( zUserName ){
186193
@ for user %h(zUserName)
187194
}
188195
@ </h1>
189196
@ <table border='0' cellpadding='2' cellspacing='0' \
197
+ zCurrentTF = db_text(0, "SELECT substr(date(),1,%d)", nTFChar);
190198
if( !includeMonth ){
191199
@ class='statistics-report-table-events sortable' \
192200
@ data-column-types='tnx' data-init-sort='0'>
193201
style_table_sorter();
202
+ rNowFraction = db_double(0.5,
203
+ "SELECT (unixepoch() - unixepoch('now','start of year'))*1.0/"
204
+ " (unixepoch('now','start of year','+1 year') - "
205
+ " unixepoch('now','start of year'));");
194206
}else{
195207
@ class='statistics-report-table-events'>
208
+ rNowFraction = db_double(0.5,
209
+ "SELECT (unixepoch() - unixepoch('now','start of month'))*1.0/"
210
+ " (unixepoch('now','start of month','+1 month') - "
211
+ " unixepoch('now','start of month'));");
196212
}
197213
@ <thead>
198214
@ <th>%s(zTimeLabel)</th>
199215
@ <th>Events</th>
200216
@ <th width='90%%'><!-- relative commits graph --></th>
@@ -203,11 +219,16 @@
203219
Run the query twice. The first time we calculate the maximum
204220
number of events for a given row. Maybe someone with better SQL
205221
Fu can re-implement this with a single query.
206222
*/
207223
while( SQLITE_ROW == db_step(&query) ){
208
- const int nCount = db_column_int(&query, 1);
224
+ int nCount = db_column_int(&query, 1);
225
+ if( strcmp(db_column_text(&query,0),zCurrentTF)==0
226
+ && rNowFraction>0.05
227
+ ){
228
+ nCount = (int)(((double)nCount)/rNowFraction);
229
+ }
209230
if(nCount>nMaxEvents){
210231
nMaxEvents = nCount;
211232
}
212233
++iterations;
213234
}
@@ -266,15 +287,30 @@
266287
}
267288
cgi_printf("'>%s</a>", zTimeframe);
268289
}
269290
@ </td><td>%d(nCount)</td>
270291
@ <td>
271
- @ <div class='statistics-report-graph-line'
272
- @ style='width:%d(nSize)%%;'>&nbsp;</div>
292
+ if( strcmp(zTimeframe, zCurrentTF)==0
293
+ && rNowFraction>0.05
294
+ && nCount>0
295
+ && nMaxEvents>0
296
+ ){
297
+ /* If the timespan covered by this row contains "now", then project
298
+ ** the number of changes until the completion of the timespan and
299
+ ** show a dashed box of that projection. */
300
+ int nExtra = (int)(((double)nCount)/rNowFraction) - nCount;
301
+ int nXSize = (100 * nExtra)/nMaxEvents;
302
+ @ <span class='statistics-report-graph-line' \
303
+ @ style='display:inline-block;min-width:%d(nSize)%%;'>&nbsp;</span>\
304
+ @ <span class='statistics-report-graph-extra' \
305
+ @ style='display:inline-block;min-width:%d(nXSize)%%;'>&nbsp;</span>\
306
+ }else{
307
+ @ <div class='statistics-report-graph-line' \
308
+ @ style='width:%d(nSize)%%;'>&nbsp;</div> \
309
+ }
273310
@ </td>
274311
@ </tr>
275
-
276312
/*
277313
Potential improvement: calculate the min/max event counts and
278314
use percent-based graph bars.
279315
*/
280316
}
281317
--- src/statrep.c
+++ src/statrep.c
@@ -169,32 +169,48 @@
169 the per-year event totals */
170 int nMaxEvents = 1; /* for calculating length of graph
171 bars. */
172 int iterations = 0; /* number of weeks/months we iterate
173 over */
 
 
 
 
 
 
 
174 stats_report_init_view();
175 db_prepare(&query,
176 "SELECT substr(date(mtime),1,%d) AS timeframe,"
177 " count(*) AS eventCount"
178 " FROM v_reports"
179 " WHERE ifnull(coalesce(euser,user,'')=%Q,1)"
180 " GROUP BY timeframe"
181 " ORDER BY timeframe DESC",
182 includeMonth ? 7 : 4, zUserName);
183 @ <h1>Timeline Events (%s(stats_report_label_for_type()))
184 @ by year%s(includeMonth ? "/month" : "")
185 if( zUserName ){
186 @ for user %h(zUserName)
187 }
188 @ </h1>
189 @ <table border='0' cellpadding='2' cellspacing='0' \
 
190 if( !includeMonth ){
191 @ class='statistics-report-table-events sortable' \
192 @ data-column-types='tnx' data-init-sort='0'>
193 style_table_sorter();
 
 
 
 
194 }else{
195 @ class='statistics-report-table-events'>
 
 
 
 
196 }
197 @ <thead>
198 @ <th>%s(zTimeLabel)</th>
199 @ <th>Events</th>
200 @ <th width='90%%'><!-- relative commits graph --></th>
@@ -203,11 +219,16 @@
203 Run the query twice. The first time we calculate the maximum
204 number of events for a given row. Maybe someone with better SQL
205 Fu can re-implement this with a single query.
206 */
207 while( SQLITE_ROW == db_step(&query) ){
208 const int nCount = db_column_int(&query, 1);
 
 
 
 
 
209 if(nCount>nMaxEvents){
210 nMaxEvents = nCount;
211 }
212 ++iterations;
213 }
@@ -266,15 +287,30 @@
266 }
267 cgi_printf("'>%s</a>", zTimeframe);
268 }
269 @ </td><td>%d(nCount)</td>
270 @ <td>
271 @ <div class='statistics-report-graph-line'
272 @ style='width:%d(nSize)%%;'>&nbsp;</div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
273 @ </td>
274 @ </tr>
275
276 /*
277 Potential improvement: calculate the min/max event counts and
278 use percent-based graph bars.
279 */
280 }
281
--- src/statrep.c
+++ src/statrep.c
@@ -169,32 +169,48 @@
169 the per-year event totals */
170 int nMaxEvents = 1; /* for calculating length of graph
171 bars. */
172 int iterations = 0; /* number of weeks/months we iterate
173 over */
174
175 char *zCurrentTF; /* The timeframe in which 'now' lives */
176 double rNowFraction; /* Fraction of 'now' timeframe that has
177 passed */
178 int nTFChar; /* Prefix of date() for timeframe */
179
180 nTFChar = includeMonth ? 7 : 4;
181 stats_report_init_view();
182 db_prepare(&query,
183 "SELECT substr(date(mtime),1,%d) AS timeframe,"
184 " count(*) AS eventCount"
185 " FROM v_reports"
186 " WHERE ifnull(coalesce(euser,user,'')=%Q,1)"
187 " GROUP BY timeframe"
188 " ORDER BY timeframe DESC",
189 nTFChar, zUserName);
190 @ <h1>Timeline Events (%s(stats_report_label_for_type()))
191 @ by year%s(includeMonth ? "/month" : "")
192 if( zUserName ){
193 @ for user %h(zUserName)
194 }
195 @ </h1>
196 @ <table border='0' cellpadding='2' cellspacing='0' \
197 zCurrentTF = db_text(0, "SELECT substr(date(),1,%d)", nTFChar);
198 if( !includeMonth ){
199 @ class='statistics-report-table-events sortable' \
200 @ data-column-types='tnx' data-init-sort='0'>
201 style_table_sorter();
202 rNowFraction = db_double(0.5,
203 "SELECT (unixepoch() - unixepoch('now','start of year'))*1.0/"
204 " (unixepoch('now','start of year','+1 year') - "
205 " unixepoch('now','start of year'));");
206 }else{
207 @ class='statistics-report-table-events'>
208 rNowFraction = db_double(0.5,
209 "SELECT (unixepoch() - unixepoch('now','start of month'))*1.0/"
210 " (unixepoch('now','start of month','+1 month') - "
211 " unixepoch('now','start of month'));");
212 }
213 @ <thead>
214 @ <th>%s(zTimeLabel)</th>
215 @ <th>Events</th>
216 @ <th width='90%%'><!-- relative commits graph --></th>
@@ -203,11 +219,16 @@
219 Run the query twice. The first time we calculate the maximum
220 number of events for a given row. Maybe someone with better SQL
221 Fu can re-implement this with a single query.
222 */
223 while( SQLITE_ROW == db_step(&query) ){
224 int nCount = db_column_int(&query, 1);
225 if( strcmp(db_column_text(&query,0),zCurrentTF)==0
226 && rNowFraction>0.05
227 ){
228 nCount = (int)(((double)nCount)/rNowFraction);
229 }
230 if(nCount>nMaxEvents){
231 nMaxEvents = nCount;
232 }
233 ++iterations;
234 }
@@ -266,15 +287,30 @@
287 }
288 cgi_printf("'>%s</a>", zTimeframe);
289 }
290 @ </td><td>%d(nCount)</td>
291 @ <td>
292 if( strcmp(zTimeframe, zCurrentTF)==0
293 && rNowFraction>0.05
294 && nCount>0
295 && nMaxEvents>0
296 ){
297 /* If the timespan covered by this row contains "now", then project
298 ** the number of changes until the completion of the timespan and
299 ** show a dashed box of that projection. */
300 int nExtra = (int)(((double)nCount)/rNowFraction) - nCount;
301 int nXSize = (100 * nExtra)/nMaxEvents;
302 @ <span class='statistics-report-graph-line' \
303 @ style='display:inline-block;min-width:%d(nSize)%%;'>&nbsp;</span>\
304 @ <span class='statistics-report-graph-extra' \
305 @ style='display:inline-block;min-width:%d(nXSize)%%;'>&nbsp;</span>\
306 }else{
307 @ <div class='statistics-report-graph-line' \
308 @ style='width:%d(nSize)%%;'>&nbsp;</div> \
309 }
310 @ </td>
311 @ </tr>
 
312 /*
313 Potential improvement: calculate the min/max event counts and
314 use percent-based graph bars.
315 */
316 }
317

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button