Fossil SCM

Added sub-submenu to /reports for selecting type of event to filter on.

stephan 2013-10-11 19:58 trunk
Commit 3e915d420ac777f0423fc585ae4c54183b52b465
1 file changed +88 -22
+88 -22
--- src/timeline.c
+++ src/timeline.c
@@ -1851,10 +1851,24 @@
18511851
}
18521852
db_finalize(&q);
18531853
style_footer();
18541854
}
18551855
1856
+
1857
+/*
1858
+** Used by stats_report_xxxxx() to remember which type of events
1859
+** to show. Populated by stats_report_init_view() and holds the
1860
+** return value of that function.
1861
+*/
1862
+static int statsReportType = 0;
1863
+
1864
+/*
1865
+** Set by stats_report_init_view() to one of the y=XXXX values
1866
+** accepted by /timeline?y=XXXX.
1867
+*/
1868
+static char const * statsReportTimelineYFlag = NULL;
1869
+
18561870
/*
18571871
** Creates a TEMP VIEW named v_reports which is a wrapper around the
18581872
** EVENT table filtered on event.type. It looks for the request
18591873
** parameter 'type' (reminder: we "should" use 'y' for consistency
18601874
** with /timeline, but /reports uses 'y' for the year) and expects it
@@ -1873,10 +1887,11 @@
18731887
*/
18741888
static int stats_report_init_view(){
18751889
char const * zType = PD("type","*"); /* analog to /timeline?y=... */
18761890
char const * zRealType = NULL; /* normalized form of zType */
18771891
int rc = 0; /* result code */
1892
+ assert( !statsReportType && "Must not be called more than once." );
18781893
switch( (zType && *zType) ? *zType : 0 ){
18791894
case 'c':
18801895
case 'C':
18811896
zRealType = "ci";
18821897
rc = *zRealType;
@@ -1905,29 +1920,33 @@
19051920
rc = '*';
19061921
break;
19071922
}
19081923
assert(0 != rc);
19091924
if(zRealType){
1925
+ statsReportTimelineYFlag = zRealType;
19101926
db_multi_exec("CREATE TEMP VIEW v_reports AS "
19111927
"SELECT * FROM event WHERE type GLOB %Q",
19121928
zRealType);
19131929
}else{
1930
+ statsReportTimelineYFlag = "a";
19141931
db_multi_exec("CREATE TEMP VIEW v_reports AS "
19151932
"SELECT * FROM event");
19161933
}
1917
- return rc;
1934
+ return statsReportType = rc;
19181935
}
19191936
19201937
/*
1921
-** Expects to be passed the return value of stats_report_init_view(),
1922
-** and returns a string suitable (for a given value of suitable) for
1923
-** use in a label. The returned bytes are static.
1938
+** Returns a string suitable (for a given value of suitable) for
1939
+** use in a label with the header of the /reports pages, dependent
1940
+** on the 'type' flag. See stats_report_init_view().
1941
+** The returned bytes are static.
19241942
*/
1925
-static char const * stats_report_label_for_type( int reportType ){
1926
- switch( reportType ){
1943
+static char const * stats_report_label_for_type(){
1944
+ assert( statsReportType && "Must call stats_report_init_view() first." );
1945
+ switch( statsReportType ){
19271946
case 'c':
1928
- return "commits";
1947
+ return "checkins";
19291948
case 'w':
19301949
return "wiki changes";
19311950
case 't':
19321951
return "ticket changes";
19331952
case 'g':
@@ -1934,10 +1953,50 @@
19341953
return "tag changes";
19351954
default:
19361955
return "all types";
19371956
}
19381957
}
1958
+
1959
+/*
1960
+** A helper for the /reports family of pages which prints out a menu
1961
+** of links for the various type=XXX flags. zCurrentViewName must be
1962
+** the name/value of the 'view' parameter which is in effect at
1963
+** the time this is called. e.g. if called from the 'byuser' view
1964
+** then zCurrentViewName must be "byuser".
1965
+*/
1966
+static void stats_report_event_types_menu(char const * zCurrentViewName){
1967
+ char * zTop = mprintf("%s/reports?view=%s", g.zTop, zCurrentViewName);
1968
+ cgi_printf("<div>");
1969
+ cgi_printf("<span>Event types:</span> ");
1970
+ if('*' == statsReportType){
1971
+ cgi_printf(" <strong>all</strong>", zTop);
1972
+ }else{
1973
+ cgi_printf(" <a href='%s'>all</a>", zTop);
1974
+ }
1975
+ if('c' == statsReportType){
1976
+ cgi_printf(" <strong>checkins</strong>", zTop);
1977
+ }else{
1978
+ cgi_printf(" <a href='%s&type=ci'>checkins</a>", zTop);
1979
+ }
1980
+ if( 't' == statsReportType ){
1981
+ cgi_printf(" <strong>tickets</strong>", zTop);
1982
+ }else{
1983
+ cgi_printf(" <a href='%s&type=t'>tickets</a>", zTop);
1984
+ }
1985
+ if( 'g' == statsReportType ){
1986
+ cgi_printf(" <strong>tags</strong>", zTop);
1987
+ }else{
1988
+ cgi_printf(" <a href='%s&type=g'>tags</a>", zTop);
1989
+ }
1990
+ if( 'w' == statsReportType ){
1991
+ cgi_printf(" <strong>wiki</strong>", zTop);
1992
+ }else{
1993
+ cgi_printf(" <a href='%s&type=w'>wiki</a>", zTop);
1994
+ }
1995
+ fossil_free(zTop);
1996
+ cgi_printf("</div>");
1997
+}
19391998
19401999
19412000
/*
19422001
** Helper for stats_report_by_month_year(), which generates a list of
19432002
** week numbers. zTimeframe should be either a timeframe in the form YYYY
@@ -1958,13 +2017,13 @@
19582017
zTimeframe);
19592018
while( SQLITE_ROW == db_step(&stWeek) ){
19602019
const char * zWeek = db_column_text(&stWeek,0);
19612020
const int nCount = db_column_int(&stWeek,1);
19622021
cgi_printf("<a href='%s/timeline?"
1963
- "yw=%t-%t&n=%d'>%s</a>",
2022
+ "yw=%t-%t&n=%d&y=%s'>%s</a>",
19642023
g.zTop, yearPart, zWeek,
1965
- nCount, zWeek);
2024
+ nCount, statsReportTimelineYFlag, zWeek);
19662025
}
19672026
db_finalize(&stWeek);
19682027
}
19692028
19702029
/*
@@ -1993,13 +2052,14 @@
19932052
Blob header = empty_blob; /* Page header text */
19942053
int nMaxEvents = 1; /* for calculating length of graph
19952054
bars. */
19962055
int iterations = 0; /* number of weeks/months we iterate
19972056
over */
1998
- int reportType = stats_report_init_view();
2057
+ stats_report_init_view();
2058
+ stats_report_event_types_menu( includeMonth ? "bymonth" : "byyear" );
19992059
blob_appendf(&header, "Timeline Events (%s) by year%s",
2000
- stats_report_label_for_type(reportType),
2060
+ stats_report_label_for_type(),
20012061
(includeMonth ? "/month" : ""));
20022062
blob_appendf(&sql,
20032063
"SELECT substr(date(mtime),1,%d) AS timeframe, "
20042064
"count(*) AS eventCount "
20052065
"FROM v_reports ",
@@ -2068,21 +2128,23 @@
20682128
nEventsPerYear += nCount;
20692129
@<tr class='row%d(rowClass)'>
20702130
@ <td>
20712131
if(includeMonth){
20722132
cgi_printf("<a href='%s/timeline?"
2073
- "ym=%t&n=%d",
2074
- g.zTop, zTimeframe, nCount );
2133
+ "ym=%t&n=%d&y=%s",
2134
+ g.zTop, zTimeframe, nCount,
2135
+ statsReportTimelineYFlag );
20752136
/* Reminder: n=nCount is not actually correct for bymonth unless
20762137
that was the only user who caused events.
20772138
*/
20782139
if( zUserName && *zUserName ){
20792140
cgi_printf("&u=%t", zUserName);
20802141
}
20812142
cgi_printf("' target='_new'>%s</a>",zTimeframe);
20822143
}else {
2083
- cgi_printf("<a href='?view=byweek&y=%s", zTimeframe);
2144
+ cgi_printf("<a href='?view=byweek&y=%s&type=%c",
2145
+ zTimeframe, (char)statsReportType);
20842146
if(zUserName && *zUserName){
20852147
cgi_printf("&u=%t", zUserName);
20862148
}
20872149
cgi_printf("'>%s</a>", zTimeframe);
20882150
}
@@ -2140,21 +2202,22 @@
21402202
int rowClass = 0; /* counter for alternating
21412203
row colors */
21422204
Blob sql = empty_blob; /* SQL */
21432205
int nMaxEvents = 1; /* max number of events for
21442206
all rows. */
2145
- int reportType = stats_report_init_view();
2207
+ stats_report_init_view();
2208
+ stats_report_event_types_menu("byuser");
21462209
blob_append(&sql,
21472210
"SELECT user, "
21482211
"COUNT(*) AS eventCount "
21492212
"FROM v_reports "
21502213
"GROUP BY user ORDER BY eventCount DESC",
21512214
-1);
21522215
db_prepare(&query, blob_str(&sql));
21532216
blob_reset(&sql);
21542217
@ <h1>Timeline Events
2155
- @ (%s(stats_report_label_for_type(reportType))) by User</h1>
2218
+ @ (%s(stats_report_label_for_type())) by User</h1>
21562219
@ <table class='statistics-report-table-events' border='0'
21572220
@ cellpadding='2' cellspacing='0' id='statsTable'>
21582221
@ <thead><tr>
21592222
@ <th>User</th>
21602223
@ <th>Events</th>
@@ -2176,11 +2239,11 @@
21762239
if(!nCount) continue /* arguable! Possible? */;
21772240
rowClass = ++nRowNumber % 2;
21782241
nEventTotal += nCount;
21792242
@<tr class='row%d(rowClass)'>
21802243
@ <td>
2181
- @ <a href="?view=bymonth&user=%h(zUser)">%h(zUser)</a>
2244
+ @ <a href="?view=bymonth&user=%h(zUser)&type=%c((char)statsReportType)">%h(zUser)</a>
21822245
@ </td><td>%d(nCount)</td>
21832246
@ <td>
21842247
@ <div class='statistics-report-graph-line'
21852248
@ style='height:16px;width:%d(nSize)%%;'>
21862249
@ </div></td>
@@ -2209,11 +2272,12 @@
22092272
char * zDefaultYear = NULL;
22102273
Blob sql = empty_blob;
22112274
int nMaxEvents = 1; /* max number of events for
22122275
all rows. */
22132276
int iterations = 0; /* # of active time periods. */
2214
- int reportType = stats_report_init_view();
2277
+ stats_report_init_view();
2278
+ stats_report_event_types_menu("byweek");
22152279
cgi_printf("Select year: ");
22162280
blob_append(&sql,
22172281
"SELECT DISTINCT substr(date(mtime),1,4) AS y "
22182282
"FROM v_reports WHERE 1 ", -1);
22192283
if(zUserName&&*zUserName){
@@ -2225,11 +2289,12 @@
22252289
while( SQLITE_ROW == db_step(&qYears) ){
22262290
const char * zT = db_column_text(&qYears, 0);
22272291
if( i++ ){
22282292
cgi_printf(" ");
22292293
}
2230
- cgi_printf("<a href='?view=byweek&y=%s", zT);
2294
+ cgi_printf("<a href='?view=byweek&y=%s&type=%c", zT,
2295
+ (char)statsReportType);
22312296
if(zUserName && *zUserName){
22322297
cgi_printf("&user=%t",zUserName);
22332298
}
22342299
cgi_printf("'>%s</a>",zT);
22352300
}
@@ -2244,11 +2309,11 @@
22442309
Stmt stWeek = empty_Stmt;
22452310
int rowCount = 0;
22462311
int total = 0;
22472312
Blob header = empty_blob;
22482313
blob_appendf(&header, "Timeline events (%s) for the calendar weeks "
2249
- "of %h", stats_report_label_for_type(reportType),
2314
+ "of %h", stats_report_label_for_type(),
22502315
zYear);
22512316
blob_appendf(&sql,
22522317
"SELECT DISTINCT strftime('%%%%W',mtime) AS wk, "
22532318
"count(*) AS n "
22542319
"FROM v_reports "
@@ -2287,12 +2352,13 @@
22872352
const int nSize = nCount
22882353
? (int)(100 * nCount / nMaxEvents)
22892354
: 0;
22902355
total += nCount;
22912356
cgi_printf("<tr class='row%d'>", ++rowCount % 2 );
2292
- cgi_printf("<td><a href='%s/timeline?yw=%t-%s&n=%d",
2293
- g.zTop, zYear, zWeek, nCount);
2357
+ cgi_printf("<td><a href='%s/timeline?yw=%t-%s&n=%d&y=%s",
2358
+ g.zTop, zYear, zWeek, nCount,
2359
+ statsReportTimelineYFlag);
22942360
if(zUserName && *zUserName){
22952361
cgi_printf("&u=%t",zUserName);
22962362
}
22972363
cgi_printf("'>%s</a></td>",zWeek);
22982364
22992365
--- src/timeline.c
+++ src/timeline.c
@@ -1851,10 +1851,24 @@
1851 }
1852 db_finalize(&q);
1853 style_footer();
1854 }
1855
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1856 /*
1857 ** Creates a TEMP VIEW named v_reports which is a wrapper around the
1858 ** EVENT table filtered on event.type. It looks for the request
1859 ** parameter 'type' (reminder: we "should" use 'y' for consistency
1860 ** with /timeline, but /reports uses 'y' for the year) and expects it
@@ -1873,10 +1887,11 @@
1873 */
1874 static int stats_report_init_view(){
1875 char const * zType = PD("type","*"); /* analog to /timeline?y=... */
1876 char const * zRealType = NULL; /* normalized form of zType */
1877 int rc = 0; /* result code */
 
1878 switch( (zType && *zType) ? *zType : 0 ){
1879 case 'c':
1880 case 'C':
1881 zRealType = "ci";
1882 rc = *zRealType;
@@ -1905,29 +1920,33 @@
1905 rc = '*';
1906 break;
1907 }
1908 assert(0 != rc);
1909 if(zRealType){
 
1910 db_multi_exec("CREATE TEMP VIEW v_reports AS "
1911 "SELECT * FROM event WHERE type GLOB %Q",
1912 zRealType);
1913 }else{
 
1914 db_multi_exec("CREATE TEMP VIEW v_reports AS "
1915 "SELECT * FROM event");
1916 }
1917 return rc;
1918 }
1919
1920 /*
1921 ** Expects to be passed the return value of stats_report_init_view(),
1922 ** and returns a string suitable (for a given value of suitable) for
1923 ** use in a label. The returned bytes are static.
 
1924 */
1925 static char const * stats_report_label_for_type( int reportType ){
1926 switch( reportType ){
 
1927 case 'c':
1928 return "commits";
1929 case 'w':
1930 return "wiki changes";
1931 case 't':
1932 return "ticket changes";
1933 case 'g':
@@ -1934,10 +1953,50 @@
1934 return "tag changes";
1935 default:
1936 return "all types";
1937 }
1938 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1939
1940
1941 /*
1942 ** Helper for stats_report_by_month_year(), which generates a list of
1943 ** week numbers. zTimeframe should be either a timeframe in the form YYYY
@@ -1958,13 +2017,13 @@
1958 zTimeframe);
1959 while( SQLITE_ROW == db_step(&stWeek) ){
1960 const char * zWeek = db_column_text(&stWeek,0);
1961 const int nCount = db_column_int(&stWeek,1);
1962 cgi_printf("<a href='%s/timeline?"
1963 "yw=%t-%t&n=%d'>%s</a>",
1964 g.zTop, yearPart, zWeek,
1965 nCount, zWeek);
1966 }
1967 db_finalize(&stWeek);
1968 }
1969
1970 /*
@@ -1993,13 +2052,14 @@
1993 Blob header = empty_blob; /* Page header text */
1994 int nMaxEvents = 1; /* for calculating length of graph
1995 bars. */
1996 int iterations = 0; /* number of weeks/months we iterate
1997 over */
1998 int reportType = stats_report_init_view();
 
1999 blob_appendf(&header, "Timeline Events (%s) by year%s",
2000 stats_report_label_for_type(reportType),
2001 (includeMonth ? "/month" : ""));
2002 blob_appendf(&sql,
2003 "SELECT substr(date(mtime),1,%d) AS timeframe, "
2004 "count(*) AS eventCount "
2005 "FROM v_reports ",
@@ -2068,21 +2128,23 @@
2068 nEventsPerYear += nCount;
2069 @<tr class='row%d(rowClass)'>
2070 @ <td>
2071 if(includeMonth){
2072 cgi_printf("<a href='%s/timeline?"
2073 "ym=%t&n=%d",
2074 g.zTop, zTimeframe, nCount );
 
2075 /* Reminder: n=nCount is not actually correct for bymonth unless
2076 that was the only user who caused events.
2077 */
2078 if( zUserName && *zUserName ){
2079 cgi_printf("&u=%t", zUserName);
2080 }
2081 cgi_printf("' target='_new'>%s</a>",zTimeframe);
2082 }else {
2083 cgi_printf("<a href='?view=byweek&y=%s", zTimeframe);
 
2084 if(zUserName && *zUserName){
2085 cgi_printf("&u=%t", zUserName);
2086 }
2087 cgi_printf("'>%s</a>", zTimeframe);
2088 }
@@ -2140,21 +2202,22 @@
2140 int rowClass = 0; /* counter for alternating
2141 row colors */
2142 Blob sql = empty_blob; /* SQL */
2143 int nMaxEvents = 1; /* max number of events for
2144 all rows. */
2145 int reportType = stats_report_init_view();
 
2146 blob_append(&sql,
2147 "SELECT user, "
2148 "COUNT(*) AS eventCount "
2149 "FROM v_reports "
2150 "GROUP BY user ORDER BY eventCount DESC",
2151 -1);
2152 db_prepare(&query, blob_str(&sql));
2153 blob_reset(&sql);
2154 @ <h1>Timeline Events
2155 @ (%s(stats_report_label_for_type(reportType))) by User</h1>
2156 @ <table class='statistics-report-table-events' border='0'
2157 @ cellpadding='2' cellspacing='0' id='statsTable'>
2158 @ <thead><tr>
2159 @ <th>User</th>
2160 @ <th>Events</th>
@@ -2176,11 +2239,11 @@
2176 if(!nCount) continue /* arguable! Possible? */;
2177 rowClass = ++nRowNumber % 2;
2178 nEventTotal += nCount;
2179 @<tr class='row%d(rowClass)'>
2180 @ <td>
2181 @ <a href="?view=bymonth&user=%h(zUser)">%h(zUser)</a>
2182 @ </td><td>%d(nCount)</td>
2183 @ <td>
2184 @ <div class='statistics-report-graph-line'
2185 @ style='height:16px;width:%d(nSize)%%;'>
2186 @ </div></td>
@@ -2209,11 +2272,12 @@
2209 char * zDefaultYear = NULL;
2210 Blob sql = empty_blob;
2211 int nMaxEvents = 1; /* max number of events for
2212 all rows. */
2213 int iterations = 0; /* # of active time periods. */
2214 int reportType = stats_report_init_view();
 
2215 cgi_printf("Select year: ");
2216 blob_append(&sql,
2217 "SELECT DISTINCT substr(date(mtime),1,4) AS y "
2218 "FROM v_reports WHERE 1 ", -1);
2219 if(zUserName&&*zUserName){
@@ -2225,11 +2289,12 @@
2225 while( SQLITE_ROW == db_step(&qYears) ){
2226 const char * zT = db_column_text(&qYears, 0);
2227 if( i++ ){
2228 cgi_printf(" ");
2229 }
2230 cgi_printf("<a href='?view=byweek&y=%s", zT);
 
2231 if(zUserName && *zUserName){
2232 cgi_printf("&user=%t",zUserName);
2233 }
2234 cgi_printf("'>%s</a>",zT);
2235 }
@@ -2244,11 +2309,11 @@
2244 Stmt stWeek = empty_Stmt;
2245 int rowCount = 0;
2246 int total = 0;
2247 Blob header = empty_blob;
2248 blob_appendf(&header, "Timeline events (%s) for the calendar weeks "
2249 "of %h", stats_report_label_for_type(reportType),
2250 zYear);
2251 blob_appendf(&sql,
2252 "SELECT DISTINCT strftime('%%%%W',mtime) AS wk, "
2253 "count(*) AS n "
2254 "FROM v_reports "
@@ -2287,12 +2352,13 @@
2287 const int nSize = nCount
2288 ? (int)(100 * nCount / nMaxEvents)
2289 : 0;
2290 total += nCount;
2291 cgi_printf("<tr class='row%d'>", ++rowCount % 2 );
2292 cgi_printf("<td><a href='%s/timeline?yw=%t-%s&n=%d",
2293 g.zTop, zYear, zWeek, nCount);
 
2294 if(zUserName && *zUserName){
2295 cgi_printf("&u=%t",zUserName);
2296 }
2297 cgi_printf("'>%s</a></td>",zWeek);
2298
2299
--- src/timeline.c
+++ src/timeline.c
@@ -1851,10 +1851,24 @@
1851 }
1852 db_finalize(&q);
1853 style_footer();
1854 }
1855
1856
1857 /*
1858 ** Used by stats_report_xxxxx() to remember which type of events
1859 ** to show. Populated by stats_report_init_view() and holds the
1860 ** return value of that function.
1861 */
1862 static int statsReportType = 0;
1863
1864 /*
1865 ** Set by stats_report_init_view() to one of the y=XXXX values
1866 ** accepted by /timeline?y=XXXX.
1867 */
1868 static char const * statsReportTimelineYFlag = NULL;
1869
1870 /*
1871 ** Creates a TEMP VIEW named v_reports which is a wrapper around the
1872 ** EVENT table filtered on event.type. It looks for the request
1873 ** parameter 'type' (reminder: we "should" use 'y' for consistency
1874 ** with /timeline, but /reports uses 'y' for the year) and expects it
@@ -1873,10 +1887,11 @@
1887 */
1888 static int stats_report_init_view(){
1889 char const * zType = PD("type","*"); /* analog to /timeline?y=... */
1890 char const * zRealType = NULL; /* normalized form of zType */
1891 int rc = 0; /* result code */
1892 assert( !statsReportType && "Must not be called more than once." );
1893 switch( (zType && *zType) ? *zType : 0 ){
1894 case 'c':
1895 case 'C':
1896 zRealType = "ci";
1897 rc = *zRealType;
@@ -1905,29 +1920,33 @@
1920 rc = '*';
1921 break;
1922 }
1923 assert(0 != rc);
1924 if(zRealType){
1925 statsReportTimelineYFlag = zRealType;
1926 db_multi_exec("CREATE TEMP VIEW v_reports AS "
1927 "SELECT * FROM event WHERE type GLOB %Q",
1928 zRealType);
1929 }else{
1930 statsReportTimelineYFlag = "a";
1931 db_multi_exec("CREATE TEMP VIEW v_reports AS "
1932 "SELECT * FROM event");
1933 }
1934 return statsReportType = rc;
1935 }
1936
1937 /*
1938 ** Returns a string suitable (for a given value of suitable) for
1939 ** use in a label with the header of the /reports pages, dependent
1940 ** on the 'type' flag. See stats_report_init_view().
1941 ** The returned bytes are static.
1942 */
1943 static char const * stats_report_label_for_type(){
1944 assert( statsReportType && "Must call stats_report_init_view() first." );
1945 switch( statsReportType ){
1946 case 'c':
1947 return "checkins";
1948 case 'w':
1949 return "wiki changes";
1950 case 't':
1951 return "ticket changes";
1952 case 'g':
@@ -1934,10 +1953,50 @@
1953 return "tag changes";
1954 default:
1955 return "all types";
1956 }
1957 }
1958
1959 /*
1960 ** A helper for the /reports family of pages which prints out a menu
1961 ** of links for the various type=XXX flags. zCurrentViewName must be
1962 ** the name/value of the 'view' parameter which is in effect at
1963 ** the time this is called. e.g. if called from the 'byuser' view
1964 ** then zCurrentViewName must be "byuser".
1965 */
1966 static void stats_report_event_types_menu(char const * zCurrentViewName){
1967 char * zTop = mprintf("%s/reports?view=%s", g.zTop, zCurrentViewName);
1968 cgi_printf("<div>");
1969 cgi_printf("<span>Event types:</span> ");
1970 if('*' == statsReportType){
1971 cgi_printf(" <strong>all</strong>", zTop);
1972 }else{
1973 cgi_printf(" <a href='%s'>all</a>", zTop);
1974 }
1975 if('c' == statsReportType){
1976 cgi_printf(" <strong>checkins</strong>", zTop);
1977 }else{
1978 cgi_printf(" <a href='%s&type=ci'>checkins</a>", zTop);
1979 }
1980 if( 't' == statsReportType ){
1981 cgi_printf(" <strong>tickets</strong>", zTop);
1982 }else{
1983 cgi_printf(" <a href='%s&type=t'>tickets</a>", zTop);
1984 }
1985 if( 'g' == statsReportType ){
1986 cgi_printf(" <strong>tags</strong>", zTop);
1987 }else{
1988 cgi_printf(" <a href='%s&type=g'>tags</a>", zTop);
1989 }
1990 if( 'w' == statsReportType ){
1991 cgi_printf(" <strong>wiki</strong>", zTop);
1992 }else{
1993 cgi_printf(" <a href='%s&type=w'>wiki</a>", zTop);
1994 }
1995 fossil_free(zTop);
1996 cgi_printf("</div>");
1997 }
1998
1999
2000 /*
2001 ** Helper for stats_report_by_month_year(), which generates a list of
2002 ** week numbers. zTimeframe should be either a timeframe in the form YYYY
@@ -1958,13 +2017,13 @@
2017 zTimeframe);
2018 while( SQLITE_ROW == db_step(&stWeek) ){
2019 const char * zWeek = db_column_text(&stWeek,0);
2020 const int nCount = db_column_int(&stWeek,1);
2021 cgi_printf("<a href='%s/timeline?"
2022 "yw=%t-%t&n=%d&y=%s'>%s</a>",
2023 g.zTop, yearPart, zWeek,
2024 nCount, statsReportTimelineYFlag, zWeek);
2025 }
2026 db_finalize(&stWeek);
2027 }
2028
2029 /*
@@ -1993,13 +2052,14 @@
2052 Blob header = empty_blob; /* Page header text */
2053 int nMaxEvents = 1; /* for calculating length of graph
2054 bars. */
2055 int iterations = 0; /* number of weeks/months we iterate
2056 over */
2057 stats_report_init_view();
2058 stats_report_event_types_menu( includeMonth ? "bymonth" : "byyear" );
2059 blob_appendf(&header, "Timeline Events (%s) by year%s",
2060 stats_report_label_for_type(),
2061 (includeMonth ? "/month" : ""));
2062 blob_appendf(&sql,
2063 "SELECT substr(date(mtime),1,%d) AS timeframe, "
2064 "count(*) AS eventCount "
2065 "FROM v_reports ",
@@ -2068,21 +2128,23 @@
2128 nEventsPerYear += nCount;
2129 @<tr class='row%d(rowClass)'>
2130 @ <td>
2131 if(includeMonth){
2132 cgi_printf("<a href='%s/timeline?"
2133 "ym=%t&n=%d&y=%s",
2134 g.zTop, zTimeframe, nCount,
2135 statsReportTimelineYFlag );
2136 /* Reminder: n=nCount is not actually correct for bymonth unless
2137 that was the only user who caused events.
2138 */
2139 if( zUserName && *zUserName ){
2140 cgi_printf("&u=%t", zUserName);
2141 }
2142 cgi_printf("' target='_new'>%s</a>",zTimeframe);
2143 }else {
2144 cgi_printf("<a href='?view=byweek&y=%s&type=%c",
2145 zTimeframe, (char)statsReportType);
2146 if(zUserName && *zUserName){
2147 cgi_printf("&u=%t", zUserName);
2148 }
2149 cgi_printf("'>%s</a>", zTimeframe);
2150 }
@@ -2140,21 +2202,22 @@
2202 int rowClass = 0; /* counter for alternating
2203 row colors */
2204 Blob sql = empty_blob; /* SQL */
2205 int nMaxEvents = 1; /* max number of events for
2206 all rows. */
2207 stats_report_init_view();
2208 stats_report_event_types_menu("byuser");
2209 blob_append(&sql,
2210 "SELECT user, "
2211 "COUNT(*) AS eventCount "
2212 "FROM v_reports "
2213 "GROUP BY user ORDER BY eventCount DESC",
2214 -1);
2215 db_prepare(&query, blob_str(&sql));
2216 blob_reset(&sql);
2217 @ <h1>Timeline Events
2218 @ (%s(stats_report_label_for_type())) by User</h1>
2219 @ <table class='statistics-report-table-events' border='0'
2220 @ cellpadding='2' cellspacing='0' id='statsTable'>
2221 @ <thead><tr>
2222 @ <th>User</th>
2223 @ <th>Events</th>
@@ -2176,11 +2239,11 @@
2239 if(!nCount) continue /* arguable! Possible? */;
2240 rowClass = ++nRowNumber % 2;
2241 nEventTotal += nCount;
2242 @<tr class='row%d(rowClass)'>
2243 @ <td>
2244 @ <a href="?view=bymonth&user=%h(zUser)&type=%c((char)statsReportType)">%h(zUser)</a>
2245 @ </td><td>%d(nCount)</td>
2246 @ <td>
2247 @ <div class='statistics-report-graph-line'
2248 @ style='height:16px;width:%d(nSize)%%;'>
2249 @ </div></td>
@@ -2209,11 +2272,12 @@
2272 char * zDefaultYear = NULL;
2273 Blob sql = empty_blob;
2274 int nMaxEvents = 1; /* max number of events for
2275 all rows. */
2276 int iterations = 0; /* # of active time periods. */
2277 stats_report_init_view();
2278 stats_report_event_types_menu("byweek");
2279 cgi_printf("Select year: ");
2280 blob_append(&sql,
2281 "SELECT DISTINCT substr(date(mtime),1,4) AS y "
2282 "FROM v_reports WHERE 1 ", -1);
2283 if(zUserName&&*zUserName){
@@ -2225,11 +2289,12 @@
2289 while( SQLITE_ROW == db_step(&qYears) ){
2290 const char * zT = db_column_text(&qYears, 0);
2291 if( i++ ){
2292 cgi_printf(" ");
2293 }
2294 cgi_printf("<a href='?view=byweek&y=%s&type=%c", zT,
2295 (char)statsReportType);
2296 if(zUserName && *zUserName){
2297 cgi_printf("&user=%t",zUserName);
2298 }
2299 cgi_printf("'>%s</a>",zT);
2300 }
@@ -2244,11 +2309,11 @@
2309 Stmt stWeek = empty_Stmt;
2310 int rowCount = 0;
2311 int total = 0;
2312 Blob header = empty_blob;
2313 blob_appendf(&header, "Timeline events (%s) for the calendar weeks "
2314 "of %h", stats_report_label_for_type(),
2315 zYear);
2316 blob_appendf(&sql,
2317 "SELECT DISTINCT strftime('%%%%W',mtime) AS wk, "
2318 "count(*) AS n "
2319 "FROM v_reports "
@@ -2287,12 +2352,13 @@
2352 const int nSize = nCount
2353 ? (int)(100 * nCount / nMaxEvents)
2354 : 0;
2355 total += nCount;
2356 cgi_printf("<tr class='row%d'>", ++rowCount % 2 );
2357 cgi_printf("<td><a href='%s/timeline?yw=%t-%s&n=%d&y=%s",
2358 g.zTop, zYear, zWeek, nCount,
2359 statsReportTimelineYFlag);
2360 if(zUserName && *zUserName){
2361 cgi_printf("&u=%t",zUserName);
2362 }
2363 cgi_printf("'>%s</a></td>",zWeek);
2364
2365

Keyboard Shortcuts

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