1/* 2 * aegis - project change supervisor 3 * Copyright (C) 1998, 2002, 2003, 2005-2008 Peter Miller 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see 17 * <http://www.gnu.org/licenses/>. 18 */ 19 20auto pn, p; 21pn = project_name(); 22p = project[pn]; 23auto ps, cs; 24ps = p.state; 25auto ph, when, n, max, href; 26 27auto script_name; 28script_name = getenv("SCRIPT_NAME"); 29if (script_name == "") 30 script_name = "http://localhost/cgi-bin/aegis.cgi"; 31 32auto cmap; 33cmap = 34{ 35 chain = "255+0+0"; 36 internal_bug = "255+255+0"; 37 internal_enhancement = "0+255+0"; 38 internal_improvement = "0+255+255"; 39 external_bug = "192+192+0"; 40 external_enhancement = "0+192+0"; 41 external_improvement = "0+192+192"; 42}; 43 44columns({width = 1000; }); 45print("Content-Type: text/html"); 46print(""); 47print("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\"" 48 ## "\"http://www.w3.org/TR/REC-html40/loose.dtd\">"); 49print("<html><head>"); 50print("<meta name=\"ROBOTS\" content=\"NOINDEX, NOFOLLOW\">"); 51print("<meta name=\"GENERATOR\" content=\"" ## script_name ## "\">"); 52print("<meta http-equiv=\"Content-Type\" " 53 ## "content=\"text/html; charset=ISO-8859-1\">"); 54print("<style type=\"text/css\"> " 55 ## "tr.even-group { background-color: #CCCCCC; } " 56 ## "body { background-color: white; } " 57 ## "</style>"); 58/* 59 * Netscape 4.x has numerous CSS bugs, two of which need mentioning. 60 * 1. If a style sheet is not present Netscape says 404 Not found, when 61 * it should silently ignore it. 2. Style sheets who's media is not 62 * "screen" will be ignored. Fortunately we can use (2) to get around (1). 63 */ 64print("<link rel=\"stylesheet\" type=\"text/css\" href=\"/aedefault.css\" " 65 ## "media=\"all\">"); 66auto stack, depth, bn; 67depth=0; 68stack[depth] = project[pn].state.name; 69while ("" != ( bn = project[stack[depth]].state.parent_name )) { 70 stack[++depth] = bn; 71} 72while ( depth >= 0) { 73 print("<link rel=\"stylesheet\" type=\"text/css\" href=\"/" ## 74 stack[depth--] ## ".css\" " ## "media=\"all\">"); 75} 76print("<title>"); 77print("Project " ## quote_html(pn) ## ", Change Cause Histogram"); 78print("</title><head><body><h1 align=center>"); 79 80print("<a href=\"" ## script_name ## "\">Project</a>"); 81auto long_project_name; 82auto prj_name_parts; 83prj_name_parts = split(pn, '.'); 84href = script_name ## "?file@proj_menu+project@" 85 ## quote_url(prj_name_parts[0]); 86long_project_name = "<a href=\"" ## href ## "\" >" 87 ## quote_html(prj_name_parts[0]) ## "</a>"; 88auto j; 89for (j = 1; j < count(prj_name_parts); j++) 90{ 91 href ##= '.' ## prj_name_parts[j]; 92 long_project_name ##= ".<a href=\"" ## href ## "\" >" 93 ## quote_html(prj_name_parts[j]) ## "</a>"; 94}; 95long_project_name = "“" ## long_project_name ## "”,<br>"; 96/* HTTP limits lines to 510 characters */ 97for (j in wrap(long_project_name, 510)) 98 print(j); 99 100print("Change Cause Histogram"); 101print("</h1>"); 102print("<div class=\"information\">"); 103 104auto earliest_year, latest_year; 105earliest_year = 0; 106latest_year = 0; 107auto bucket, year; 108bucket = {}; 109for (ph in ps.branch.history) 110{ 111 cs = ps.branch.change[ph.change_number]; 112 when = cs.history[count(cs.history) - 1].when; 113 year = 0 + strftime("%Y", when); 114 if (typeof(bucket[year]) == "nul") 115 bucket[year] = {}; 116 bucket[year][cs.cause]++; 117 bucket[year].Total++; 118 if (earliest_year == 0 || earliest_year > year) 119 earliest_year = year; 120 if (latest_year < year) 121 latest_year = year; 122} 123 124max = 1; 125for (year in keys(bucket)) 126{ 127 n = 0 + bucket[year].Total; 128 if (n > max) 129 max = n; 130} 131max = 400. / max; 132 133auto clr; 134print("<table align=center>"); 135print("<tr><th>Year</th><th>Count</th></tr>"); 136for (year = earliest_year; year <= latest_year; ++year) 137{ 138 n = 0 + bucket[year].Total; 139 print("<tr><td valign=top align=right>"); 140 if (n > 0) 141 { 142 href = script_name ## "?file@proj_cch2"; 143 href ##= "+project@" ## quote_url(project_name()); 144 href ##= "+" ## year; 145 print("<a href=\"" ## href ## "\">"); 146 } 147 print(year); 148 if (n > 0) 149 print("</a>"); 150 print("</td><td valign=top align=right>"); 151 print(n); 152 print("</td><td valign=top>"); 153 auto cause; 154 for (cause in [chain, 155 internal_bug, internal_enhancement, internal_improvement, 156 external_bug, external_enhancement, external_improvement]) 157 { 158 n = 0 + bucket[year][cause]; 159 if (n > 0) 160 { 161 clr = cmap[cause]; 162 if (clr == "") 163 clr = "255+0+255"; 164 n = round(n * max); 165 if (n < 3) 166 n = 3; 167 href = script_name ## "?file@rect+" ## n ## "+12"; 168 href ##= "+color+" ## clr; 169 print("<img src=\"" ## href ## "\" width="##n##" height=12>"); 170 } 171 } 172 print("</td></tr>"); 173} 174print("</table>"); 175print("</div>"); 176print("<hr>"); 177 178print("<div class=\"legend\">"); 179print("<h2 align=center>Legend</h2>"); 180print("This table associates each color in the above graph with"); 181print("a change cause. A brief description of each cause is"); 182print("also given."); 183print("<table align=center>"); 184print("<tr><th>Color</th><th>Cause</th><th>Description</th></tr>"); 185 186clr = cmap[chain]; 187href = script_name ## "?file@rect+50+12+color+" ## clr; 188print("<tr><td valign=top>"); 189print("<img src=\""##href##"\" width=50 height=12>"); 190print("</td><td valign=top align=center>"); 191print("chain"); 192print("</td><td valign=top>"); 193print("This cause is used for bugs introduced by previous changes."); 194print("This is a special case of the <dfn>internal_bug</dfn> cause."); 195print("</td></tr>"); 196 197clr = cmap[internal_bug]; 198href = script_name ## "?file@rect+50+12+color+" ## clr; 199print("<tr><td valign=top>"); 200print("<img src=\""##href##"\" width=50 height=12>"); 201print("</td><td valign=top align=center>"); 202print("internal_bug"); 203print("</td><td valign=top>"); 204print("This cause is used for bugs found by the development team, or by"); 205print("the development organization."); 206print("</td></tr>"); 207 208clr = cmap[internal_enhancement]; 209href = script_name ## "?file@rect+50+12+color+" ## clr; 210print("<tr><td valign=top>"); 211print("<img src=\""##href##"\" width=50 height=12>"); 212print("</td><td valign=top align=center>"); 213print("internal_enhancement"); 214print("</td><td valign=top>"); 215print("This cause is used for new functionality requested by the"); 216print("development team, or by the development organization."); 217print("</td></tr>"); 218 219clr = cmap[internal_improvement]; 220href = script_name ## "?file@rect+50+12+color+" ## clr; 221print("<tr><td valign=top>"); 222print("<img src=\""##href##"\" width=50 height=12>"); 223print("</td><td valign=top align=center>"); 224print("internal_improvement"); 225print("</td><td valign=top>"); 226print("This cause is used for improvement to existing functionality"); 227print("(e.g. performance) requested by the development team, or by the"); 228print("development organization."); 229print("</td></tr>"); 230 231clr = cmap[external_bug]; 232href = script_name ## "?file@rect+50+12+color+" ## clr; 233print("<tr><td valign=top>"); 234print("<img src=\""##href##"\" width=50 height=12>"); 235print("</td><td valign=top align=center>"); 236print("external_bug"); 237print("</td><td valign=top>"); 238print("This cause is used for bugs found by the customer, or by a source"); 239print("outside the development organization."); 240print("</td></tr>"); 241 242clr = cmap[external_enhancement]; 243href = script_name ## "?file@rect+50+12+color+" ## clr; 244print("<tr><td valign=top>"); 245print("<img src=\""##href##"\" width=50 height=12>"); 246print("</td><td valign=top align=center>"); 247print("external_enhancement"); 248print("</td><td valign=top>"); 249print("This cause is used for new functionality requested by the customer,"); 250print("or by a source outside the development organization."); 251print("</td></tr>"); 252 253clr = cmap[external_improvement]; 254href = script_name ## "?file@rect+50+12+color+" ## clr; 255print("<tr><td valign=top>"); 256print("<img src=\""##href##"\" width=50 height=12>"); 257print("</td><td valign=top align=center>"); 258print("external_improvement"); 259print("</td><td valign=top>"); 260print("This cause is used for improvement to existing functionality"); 261print("(e.g. performance) requested by the customer, or a source outside"); 262print("the development development organization."); 263print("</td></tr>"); 264 265print("</table>"); 266print("</div>"); 267 268print("<hr>"); 269print("<p align=center class=\"navbar\">["); 270print("<a href=\"" ## script_name ## "\">Project List</a> |"); 271href = script_name ## "?file@proj_menu+project@" ## quote_url(pn); 272print("<a href=\"" ## href ## "\">Project Menu</a> |"); 273href = script_name ## "?file@changes+project@" ## quote_url(pn); 274print("<a href=\"" ## href ## "\">Change List</a>"); 275print("]</p>"); 276 277print("<hr>"); 278print("This page was generated " ## now() ## "."); 279print("</body></html>"); 280