Fossil SCM
Added new /reports page: byweekday. Most tags and commits happen on Thursdays. Most tickets on Wednesdays.
Commit
2cf6304bc375a0c0c0dc7375c8200a4e2de93166
Parent
b7ff537dca97208…
2 files changed
+73
+1
+73
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -2371,10 +2371,79 @@ | ||
| 2371 | 2371 | @ </tbody></table> |
| 2372 | 2372 | db_finalize(&query); |
| 2373 | 2373 | output_table_sorting_javascript("statsTable","tnx"); |
| 2374 | 2374 | } |
| 2375 | 2375 | |
| 2376 | +/* | |
| 2377 | +** Implements the "byweekday" view for /reports. | |
| 2378 | +*/ | |
| 2379 | +static void stats_report_day_of_week(){ | |
| 2380 | + Stmt query = empty_Stmt; | |
| 2381 | + int nRowNumber = 0; /* current TR number */ | |
| 2382 | + int nEventTotal = 0; /* Total event count */ | |
| 2383 | + int rowClass = 0; /* counter for alternating | |
| 2384 | + row colors */ | |
| 2385 | + Blob sql = empty_blob; /* SQL */ | |
| 2386 | + int nMaxEvents = 1; /* max number of events for | |
| 2387 | + all rows. */ | |
| 2388 | + static char const * daysOfWeek[] = { | |
| 2389 | + "Monday", "Tuesday", "Wednesday", "Thursday", | |
| 2390 | + "Friday", "Saturday", "Sunday" | |
| 2391 | + }; | |
| 2392 | + | |
| 2393 | + stats_report_init_view(); | |
| 2394 | + stats_report_event_types_menu("byweekday", NULL); | |
| 2395 | + blob_append(&sql, | |
| 2396 | + "SELECT cast(mtime %% 7 AS INTEGER) dow, " | |
| 2397 | + "COUNT(*) AS eventCount " | |
| 2398 | + "FROM v_reports " | |
| 2399 | + "GROUP BY dow ORDER BY dow", | |
| 2400 | + -1); | |
| 2401 | + db_prepare(&query, blob_str(&sql)); | |
| 2402 | + blob_reset(&sql); | |
| 2403 | + @ <h1>Timeline Events | |
| 2404 | + @ (%s(stats_report_label_for_type())) by Day of the Week</h1> | |
| 2405 | + @ <table class='statistics-report-table-events' border='0' | |
| 2406 | + @ cellpadding='2' cellspacing='0' id='statsTable'> | |
| 2407 | + @ <thead><tr> | |
| 2408 | + @ <th>DoW</th> | |
| 2409 | + @ <th>Day</th> | |
| 2410 | + @ <th>Events</th> | |
| 2411 | + @ <th width='90%%'><!-- relative commits graph --></th> | |
| 2412 | + @ </tr></thead><tbody> | |
| 2413 | + while( SQLITE_ROW == db_step(&query) ){ | |
| 2414 | + const int nCount = db_column_int(&query, 1); | |
| 2415 | + if(nCount>nMaxEvents){ | |
| 2416 | + nMaxEvents = nCount; | |
| 2417 | + } | |
| 2418 | + } | |
| 2419 | + db_reset(&query); | |
| 2420 | + while( SQLITE_ROW == db_step(&query) ){ | |
| 2421 | + int const dayNum =db_column_int(&query, 0); | |
| 2422 | + const int nCount = db_column_int(&query, 1); | |
| 2423 | + int nSize = nCount | |
| 2424 | + ? (int)(100 * nCount / nMaxEvents) | |
| 2425 | + : 0; | |
| 2426 | + if(!nCount) continue /* arguable! Possible? */; | |
| 2427 | + else if(!nSize) nSize = 1; | |
| 2428 | + rowClass = ++nRowNumber % 2; | |
| 2429 | + nEventTotal += nCount; | |
| 2430 | + @<tr class='row%d(rowClass)'> | |
| 2431 | + @ <td>%d(dayNum)</td> | |
| 2432 | + @ <td>%s(daysOfWeek[dayNum])</td> | |
| 2433 | + @ <td>%d(nCount)</td> | |
| 2434 | + @ <td> | |
| 2435 | + @ <div class='statistics-report-graph-line' | |
| 2436 | + @ style='width:%d(nSize)%%;'> </div> | |
| 2437 | + @ </td> | |
| 2438 | + @</tr> | |
| 2439 | + } | |
| 2440 | + @ </tbody></table> | |
| 2441 | + db_finalize(&query); | |
| 2442 | + output_table_sorting_javascript("statsTable","ntnx"); | |
| 2443 | +} | |
| 2444 | + | |
| 2376 | 2445 | |
| 2377 | 2446 | /* |
| 2378 | 2447 | ** Helper for stats_report_by_month_year(), which generates a list of |
| 2379 | 2448 | ** week numbers. zTimeframe should be either a timeframe in the form YYYY |
| 2380 | 2449 | ** or YYYY-MM. |
| @@ -2541,10 +2610,11 @@ | ||
| 2541 | 2610 | timeline_submenu(&url, "(Remove User Flag)", "view", zView, "user"); |
| 2542 | 2611 | } |
| 2543 | 2612 | timeline_submenu(&url, "By Year", "view", "byyear", 0); |
| 2544 | 2613 | timeline_submenu(&url, "By Month", "view", "bymonth", 0); |
| 2545 | 2614 | timeline_submenu(&url, "By Week", "view", "byweek", 0); |
| 2615 | + timeline_submenu(&url, "By Weekday", "view", "byweekday", 0); | |
| 2546 | 2616 | timeline_submenu(&url, "By User", "view", "byuser", "user"); |
| 2547 | 2617 | url_reset(&url); |
| 2548 | 2618 | style_header("Activity Reports"); |
| 2549 | 2619 | if(0==fossil_strcmp(zView,"byyear")){ |
| 2550 | 2620 | stats_report_by_month_year(0, 0, zUserName); |
| @@ -2552,17 +2622,20 @@ | ||
| 2552 | 2622 | stats_report_by_month_year(1, 0, zUserName); |
| 2553 | 2623 | }else if(0==fossil_strcmp(zView,"byweek")){ |
| 2554 | 2624 | stats_report_year_weeks(zUserName); |
| 2555 | 2625 | }else if(0==fossil_strcmp(zView,"byuser")){ |
| 2556 | 2626 | stats_report_by_user(); |
| 2627 | + }else if(0==fossil_strcmp(zView,"byweekday")){ | |
| 2628 | + stats_report_day_of_week(); | |
| 2557 | 2629 | }else{ |
| 2558 | 2630 | @ <h1>Select a report to show:</h1> |
| 2559 | 2631 | @ <ul> |
| 2560 | 2632 | @ <li><a href='?view=byyear'>Events by year</a></li> |
| 2561 | 2633 | @ <li><a href='?view=bymonth'>Events by month</a></li> |
| 2562 | 2634 | @ <li><a href='?view=byweek'>Events by calendar week</a></li> |
| 2635 | + @ <li><a href='?view=byweekday'>Events by day of the week</a></li> | |
| 2563 | 2636 | @ <li><a href='?view=byuser'>Events by user</a></li> |
| 2564 | 2637 | @ </ul> |
| 2565 | 2638 | } |
| 2566 | 2639 | |
| 2567 | 2640 | style_footer(); |
| 2568 | 2641 | } |
| 2569 | 2642 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -2371,10 +2371,79 @@ | |
| 2371 | @ </tbody></table> |
| 2372 | db_finalize(&query); |
| 2373 | output_table_sorting_javascript("statsTable","tnx"); |
| 2374 | } |
| 2375 | |
| 2376 | |
| 2377 | /* |
| 2378 | ** Helper for stats_report_by_month_year(), which generates a list of |
| 2379 | ** week numbers. zTimeframe should be either a timeframe in the form YYYY |
| 2380 | ** or YYYY-MM. |
| @@ -2541,10 +2610,11 @@ | |
| 2541 | timeline_submenu(&url, "(Remove User Flag)", "view", zView, "user"); |
| 2542 | } |
| 2543 | timeline_submenu(&url, "By Year", "view", "byyear", 0); |
| 2544 | timeline_submenu(&url, "By Month", "view", "bymonth", 0); |
| 2545 | timeline_submenu(&url, "By Week", "view", "byweek", 0); |
| 2546 | timeline_submenu(&url, "By User", "view", "byuser", "user"); |
| 2547 | url_reset(&url); |
| 2548 | style_header("Activity Reports"); |
| 2549 | if(0==fossil_strcmp(zView,"byyear")){ |
| 2550 | stats_report_by_month_year(0, 0, zUserName); |
| @@ -2552,17 +2622,20 @@ | |
| 2552 | stats_report_by_month_year(1, 0, zUserName); |
| 2553 | }else if(0==fossil_strcmp(zView,"byweek")){ |
| 2554 | stats_report_year_weeks(zUserName); |
| 2555 | }else if(0==fossil_strcmp(zView,"byuser")){ |
| 2556 | stats_report_by_user(); |
| 2557 | }else{ |
| 2558 | @ <h1>Select a report to show:</h1> |
| 2559 | @ <ul> |
| 2560 | @ <li><a href='?view=byyear'>Events by year</a></li> |
| 2561 | @ <li><a href='?view=bymonth'>Events by month</a></li> |
| 2562 | @ <li><a href='?view=byweek'>Events by calendar week</a></li> |
| 2563 | @ <li><a href='?view=byuser'>Events by user</a></li> |
| 2564 | @ </ul> |
| 2565 | } |
| 2566 | |
| 2567 | style_footer(); |
| 2568 | } |
| 2569 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -2371,10 +2371,79 @@ | |
| 2371 | @ </tbody></table> |
| 2372 | db_finalize(&query); |
| 2373 | output_table_sorting_javascript("statsTable","tnx"); |
| 2374 | } |
| 2375 | |
| 2376 | /* |
| 2377 | ** Implements the "byweekday" view for /reports. |
| 2378 | */ |
| 2379 | static void stats_report_day_of_week(){ |
| 2380 | Stmt query = empty_Stmt; |
| 2381 | int nRowNumber = 0; /* current TR number */ |
| 2382 | int nEventTotal = 0; /* Total event count */ |
| 2383 | int rowClass = 0; /* counter for alternating |
| 2384 | row colors */ |
| 2385 | Blob sql = empty_blob; /* SQL */ |
| 2386 | int nMaxEvents = 1; /* max number of events for |
| 2387 | all rows. */ |
| 2388 | static char const * daysOfWeek[] = { |
| 2389 | "Monday", "Tuesday", "Wednesday", "Thursday", |
| 2390 | "Friday", "Saturday", "Sunday" |
| 2391 | }; |
| 2392 | |
| 2393 | stats_report_init_view(); |
| 2394 | stats_report_event_types_menu("byweekday", NULL); |
| 2395 | blob_append(&sql, |
| 2396 | "SELECT cast(mtime %% 7 AS INTEGER) dow, " |
| 2397 | "COUNT(*) AS eventCount " |
| 2398 | "FROM v_reports " |
| 2399 | "GROUP BY dow ORDER BY dow", |
| 2400 | -1); |
| 2401 | db_prepare(&query, blob_str(&sql)); |
| 2402 | blob_reset(&sql); |
| 2403 | @ <h1>Timeline Events |
| 2404 | @ (%s(stats_report_label_for_type())) by Day of the Week</h1> |
| 2405 | @ <table class='statistics-report-table-events' border='0' |
| 2406 | @ cellpadding='2' cellspacing='0' id='statsTable'> |
| 2407 | @ <thead><tr> |
| 2408 | @ <th>DoW</th> |
| 2409 | @ <th>Day</th> |
| 2410 | @ <th>Events</th> |
| 2411 | @ <th width='90%%'><!-- relative commits graph --></th> |
| 2412 | @ </tr></thead><tbody> |
| 2413 | while( SQLITE_ROW == db_step(&query) ){ |
| 2414 | const int nCount = db_column_int(&query, 1); |
| 2415 | if(nCount>nMaxEvents){ |
| 2416 | nMaxEvents = nCount; |
| 2417 | } |
| 2418 | } |
| 2419 | db_reset(&query); |
| 2420 | while( SQLITE_ROW == db_step(&query) ){ |
| 2421 | int const dayNum =db_column_int(&query, 0); |
| 2422 | const int nCount = db_column_int(&query, 1); |
| 2423 | int nSize = nCount |
| 2424 | ? (int)(100 * nCount / nMaxEvents) |
| 2425 | : 0; |
| 2426 | if(!nCount) continue /* arguable! Possible? */; |
| 2427 | else if(!nSize) nSize = 1; |
| 2428 | rowClass = ++nRowNumber % 2; |
| 2429 | nEventTotal += nCount; |
| 2430 | @<tr class='row%d(rowClass)'> |
| 2431 | @ <td>%d(dayNum)</td> |
| 2432 | @ <td>%s(daysOfWeek[dayNum])</td> |
| 2433 | @ <td>%d(nCount)</td> |
| 2434 | @ <td> |
| 2435 | @ <div class='statistics-report-graph-line' |
| 2436 | @ style='width:%d(nSize)%%;'> </div> |
| 2437 | @ </td> |
| 2438 | @</tr> |
| 2439 | } |
| 2440 | @ </tbody></table> |
| 2441 | db_finalize(&query); |
| 2442 | output_table_sorting_javascript("statsTable","ntnx"); |
| 2443 | } |
| 2444 | |
| 2445 | |
| 2446 | /* |
| 2447 | ** Helper for stats_report_by_month_year(), which generates a list of |
| 2448 | ** week numbers. zTimeframe should be either a timeframe in the form YYYY |
| 2449 | ** or YYYY-MM. |
| @@ -2541,10 +2610,11 @@ | |
| 2610 | timeline_submenu(&url, "(Remove User Flag)", "view", zView, "user"); |
| 2611 | } |
| 2612 | timeline_submenu(&url, "By Year", "view", "byyear", 0); |
| 2613 | timeline_submenu(&url, "By Month", "view", "bymonth", 0); |
| 2614 | timeline_submenu(&url, "By Week", "view", "byweek", 0); |
| 2615 | timeline_submenu(&url, "By Weekday", "view", "byweekday", 0); |
| 2616 | timeline_submenu(&url, "By User", "view", "byuser", "user"); |
| 2617 | url_reset(&url); |
| 2618 | style_header("Activity Reports"); |
| 2619 | if(0==fossil_strcmp(zView,"byyear")){ |
| 2620 | stats_report_by_month_year(0, 0, zUserName); |
| @@ -2552,17 +2622,20 @@ | |
| 2622 | stats_report_by_month_year(1, 0, zUserName); |
| 2623 | }else if(0==fossil_strcmp(zView,"byweek")){ |
| 2624 | stats_report_year_weeks(zUserName); |
| 2625 | }else if(0==fossil_strcmp(zView,"byuser")){ |
| 2626 | stats_report_by_user(); |
| 2627 | }else if(0==fossil_strcmp(zView,"byweekday")){ |
| 2628 | stats_report_day_of_week(); |
| 2629 | }else{ |
| 2630 | @ <h1>Select a report to show:</h1> |
| 2631 | @ <ul> |
| 2632 | @ <li><a href='?view=byyear'>Events by year</a></li> |
| 2633 | @ <li><a href='?view=bymonth'>Events by month</a></li> |
| 2634 | @ <li><a href='?view=byweek'>Events by calendar week</a></li> |
| 2635 | @ <li><a href='?view=byweekday'>Events by day of the week</a></li> |
| 2636 | @ <li><a href='?view=byuser'>Events by user</a></li> |
| 2637 | @ </ul> |
| 2638 | } |
| 2639 | |
| 2640 | style_footer(); |
| 2641 | } |
| 2642 |
+1
| --- www/changes.wiki | ||
| +++ www/changes.wiki | ||
| @@ -18,10 +18,11 @@ | ||
| 18 | 18 | [/help?cmd=diff|fossil (g)diff], [/help?cmd=stash|fossil stash diff]. |
| 19 | 19 | * Add --strip-trailing-cr option to [/help?cmd=diff|fossil (g)diff] and |
| 20 | 20 | [/help?cmd=stash|fossil stash diff]. |
| 21 | 21 | * Add button "Ignore Whitespace" to /annotate, /blame, /ci, /fdiff |
| 22 | 22 | and /vdiff UI pages. |
| 23 | + * Enhanced [/reports?view=byweekday|/reports] with a "byweekday" view. | |
| 23 | 24 | |
| 24 | 25 | <h2>Changes For Version 1.28 (2014-01-27)</h2> |
| 25 | 26 | * Enhance [/help?cmd=/reports | /reports] to support event type filtering. |
| 26 | 27 | * When cloning a repository, the user name passed via the URL (if any) |
| 27 | 28 | is now used as the default local admin user's name. |
| 28 | 29 |
| --- www/changes.wiki | |
| +++ www/changes.wiki | |
| @@ -18,10 +18,11 @@ | |
| 18 | [/help?cmd=diff|fossil (g)diff], [/help?cmd=stash|fossil stash diff]. |
| 19 | * Add --strip-trailing-cr option to [/help?cmd=diff|fossil (g)diff] and |
| 20 | [/help?cmd=stash|fossil stash diff]. |
| 21 | * Add button "Ignore Whitespace" to /annotate, /blame, /ci, /fdiff |
| 22 | and /vdiff UI pages. |
| 23 | |
| 24 | <h2>Changes For Version 1.28 (2014-01-27)</h2> |
| 25 | * Enhance [/help?cmd=/reports | /reports] to support event type filtering. |
| 26 | * When cloning a repository, the user name passed via the URL (if any) |
| 27 | is now used as the default local admin user's name. |
| 28 |
| --- www/changes.wiki | |
| +++ www/changes.wiki | |
| @@ -18,10 +18,11 @@ | |
| 18 | [/help?cmd=diff|fossil (g)diff], [/help?cmd=stash|fossil stash diff]. |
| 19 | * Add --strip-trailing-cr option to [/help?cmd=diff|fossil (g)diff] and |
| 20 | [/help?cmd=stash|fossil stash diff]. |
| 21 | * Add button "Ignore Whitespace" to /annotate, /blame, /ci, /fdiff |
| 22 | and /vdiff UI pages. |
| 23 | * Enhanced [/reports?view=byweekday|/reports] with a "byweekday" view. |
| 24 | |
| 25 | <h2>Changes For Version 1.28 (2014-01-27)</h2> |
| 26 | * Enhance [/help?cmd=/reports | /reports] to support event type filtering. |
| 27 | * When cloning a repository, the user name passed via the URL (if any) |
| 28 | is now used as the default local admin user's name. |
| 29 |