| [ Index ] |
PHP Cross Reference of MantisBT |
[Summary view] [Print] [Text view]
1 <?php 2 # MantisBT - A PHP based bugtracking system 3 4 # MantisBT is free software: you can redistribute it and/or modify 5 # it under the terms of the GNU General Public License as published by 6 # the Free Software Foundation, either version 2 of the License, or 7 # (at your option) any later version. 8 # 9 # MantisBT is distributed in the hope that it will be useful, 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 # GNU General Public License for more details. 13 # 14 # You should have received a copy of the GNU General Public License 15 # along with MantisBT. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * @package CoreAPI 19 * @subpackage GraphAPI 20 * @copyright Copyright (C) 2000 - 2002 Kenzaburo Ito - kenito@300baud.org 21 * @copyright Copyright (C) 2002 - 2011 MantisBT Team - mantisbt-dev@lists.sourceforge.net 22 * @link http://www.mantisbt.org 23 */ 24 25 26 if( OFF == plugin_config_get( 'eczlibrary' ) ) { 27 $t_font_path = get_font_path(); 28 if( $t_font_path !== '' && !defined('TTF_DIR') ) { 29 define( 'TTF_DIR', $t_font_path ); 30 } 31 $t_jpgraph_path = plugin_config_get( 'jpgraph_path', '' ); 32 if( $t_jpgraph_path !== '' ) { 33 set_include_path(get_include_path() . PATH_SEPARATOR . $t_jpgraph_path ); 34 $ip = get_include_path(); 35 require_once( 'jpgraph.php' ); 36 require_once( 'jpgraph_line.php' ); 37 require_once( 'jpgraph_bar.php' ); 38 require_once( 'jpgraph_pie.php' ); 39 require_once( 'jpgraph_pie3d.php' ); 40 require_once( 'jpgraph_canvas.php' ); 41 } else { 42 require_lib( 'jpgraph/jpgraph.php' ); 43 require_lib( 'jpgraph/jpgraph_line.php' ); 44 require_lib( 'jpgraph/jpgraph_bar.php' ); 45 require_lib( 'jpgraph/jpgraph_pie.php' ); 46 require_lib( 'jpgraph/jpgraph_pie3d.php' ); 47 require_lib( 'jpgraph/jpgraph_canvas.php' ); 48 } 49 } else { 50 require_lib( 'ezc/Base/src/base.php' ); 51 } 52 53 function graph_get_font() { 54 $t_font = plugin_config_get( 'font', 'arial' ); 55 56 if ( plugin_config_get( 'eczlibrary' ) == ON ) { 57 $t_font_map = array( 58 'arial' => 'arial.ttf', 59 'verdana' => 'verdana.ttf', 60 'trebuchet' => 'trebuc.ttf', 61 'verasans' => 'Vera.ttf', 62 'times' => 'times.ttf', 63 'georgia' => 'georgia.ttf', 64 'veraserif' => 'VeraSe.ttf', 65 'courier' => 'cour.ttf', 66 'veramono' => 'VeraMono.ttf', 67 ); 68 69 if( isset( $t_font_map[$t_font] ) ) { 70 $t_font = $t_font_map[$t_font]; 71 } else { 72 $t_font = 'arial.ttf'; 73 } 74 $t_font_path = get_font_path(); 75 if( empty($t_font_path) ) { 76 error_text('Unable to read/find font', 'Unable to read/find font'); 77 } 78 $t_font_file = $t_font_path . $t_font; 79 if( file_exists($t_font_file) === false || is_readable($t_font_file) === false ) { 80 error_text('Unable to read/find font', 'Unable to read/find font'); 81 } 82 return $t_font_file; 83 } else { 84 $t_font_map = array( 85 'arial' => FF_ARIAL, 86 'verdana' => FF_VERDANA, 87 'trebuchet' => FF_TREBUCHE, 88 'verasans' => FF_VERA, 89 'times' => FF_TIMES, 90 'georgia' => FF_GEORGIA, 91 'veraserif' => FF_VERASERIF, 92 'courier' => FF_COURIER, 93 'veramono' => FF_VERAMONO, 94 ); 95 96 if( isset( $t_font_map[$t_font] ) ) { 97 return $t_font_map[$t_font]; 98 } else { 99 return FF_FONT1; 100 } 101 } 102 } 103 104 # ## Graph API ### 105 # -------------------- 106 # graphing routines 107 # -------------------- 108 function graph_bar( $p_metrics, $p_title = '', $p_graph_width = 350, $p_graph_height = 400 ) { 109 $t_graph_font = graph_get_font(); 110 111 error_check( is_array( $p_metrics ) ? array_sum( $p_metrics ) : 0, $p_title ); 112 113 if ( plugin_config_get( 'eczlibrary' ) == ON ) { 114 $graph = new ezcGraphBarChart(); 115 $graph->title = $p_title; 116 $graph->background->color = '#FFFFFF'; 117 $graph->options->font = $t_graph_font ; 118 $graph->options->font->maxFontSize = 12; 119 $graph->legend = false; 120 121 $graph->data[0] = new ezcGraphArrayDataSet( $p_metrics ); 122 $graph->data[0]->color = '#FFFF00'; 123 124 $graph->xAxis->axisLabelRenderer = new ezcGraphAxisRotatedLabelRenderer(); 125 $graph->xAxis->axisLabelRenderer->angle = 45; 126 127 $graph->driver = new ezcGraphGdDriver(); 128 //$graph->driver->options->supersampling = 1; 129 $graph->driver->options->jpegQuality = 100; 130 $graph->driver->options->imageFormat = IMG_JPEG; 131 132 $graph->renderer->options->syncAxisFonts = false; 133 134 $graph->renderToOutput( $p_graph_width, $p_graph_height); 135 } else { 136 $graph = new Graph( $p_graph_width, $p_graph_height ); 137 $graph->img->SetMargin( 40, 40, 40, 170 ); 138 if( ON == plugin_config_get( 'jpgraph_antialias' ) ) { 139 $graph->img->SetAntiAliasing(); 140 } 141 $graph->SetScale( 'textlin' ); 142 $graph->SetMarginColor( 'white' ); 143 $graph->SetFrame( false ); 144 $graph->title->Set( $p_title ); 145 $graph->title->SetFont( $t_graph_font, FS_BOLD ); 146 $graph->xaxis->SetTickLabels( array_keys( $p_metrics ) ); 147 if( FF_FONT2 <= $t_graph_font ) { 148 $graph->xaxis->SetLabelAngle( 60 ); 149 } else { 150 $graph->xaxis->SetLabelAngle( 90 ); 151 # can't rotate non truetype fonts 152 } 153 $graph->xaxis->SetFont( $t_graph_font ); 154 155 $graph->legend->SetFont( $t_graph_font ); 156 157 $graph->yaxis->scale->ticks->SetDirection( -1 ); 158 $graph->yaxis->SetFont( $t_graph_font ); 159 160 $p1 = new BarPlot( array_values( $p_metrics ) ); 161 $p1->SetFillColor( 'yellow' ); 162 $p1->SetWidth( 0.8 ); 163 $graph->Add( $p1 ); 164 if( helper_show_query_count() ) { 165 $graph->subtitle->Set( db_count_queries() . ' queries (' . db_time_queries() . 'sec)' ); 166 $graph->subtitle->SetFont( $t_graph_font, FS_NORMAL, 8 ); 167 } 168 169 $graph->Stroke(); 170 } 171 } 172 173 # Function which displays the charts using the absolute values according to the status (opened/closed/resolved) 174 function graph_group( $p_metrics, $p_title = '', $p_graph_width = 350, $p_graph_height = 400, $p_baseline = 100 ) { 175 176 # $p_metrics is an array of three arrays 177 # $p_metrics['open'] = array( 'enum' => value, ...) 178 # $p_metrics['resolved'] 179 # $p_metrics['closed'] 180 181 $t_graph_font = graph_get_font(); 182 183 # count up array portions that are set 184 $t_count = 0; 185 foreach( array( 'open', 'resolved', 'closed' ) as $t_label ) { 186 if( isset( $p_metrics[$t_label] ) && is_array( $p_metrics[$t_label] ) ) { 187 $t_count += array_sum( $p_metrics[$t_label] ); 188 } 189 } 190 191 error_check( $t_count, $p_title ); 192 193 # calculate totals 194 $total = graph_total_metrics( $p_metrics ); 195 196 if ( plugin_config_get( 'eczlibrary' ) == ON ) { 197 $graph = new ezcGraphBarChart(); 198 $graph->title = $p_title; 199 $graph->background->color = '#FFFFFF'; 200 $graph->options->font = $t_graph_font ; 201 $graph->options->font->maxFontSize = 12; 202 $graph->legend = false; 203 204 foreach( array( 'open', 'resolved', 'closed' ) as $t_label ) { 205 $graph->data[$t_label] = new ezcGraphArrayDataSet( $p_metrics[$t_label] ); 206 } 207 $graph->data['total'] = new ezcGraphArrayDataSet( $total ); 208 //$graph->data['total']->displayType = ezcGraph::LINE; 209 //$graph->data['total']->barMargin = -20; 210 $graph->options->fillLines = 210; 211 $graph->xAxis->axisLabelRenderer = new ezcGraphAxisRotatedLabelRenderer(); 212 $graph->xAxis->axisLabelRenderer->angle = 45; 213 214 $graph->driver = new ezcGraphGdDriver(); 215 //$graph->driver->options->supersampling = 1; 216 $graph->driver->options->jpegQuality = 100; 217 $graph->driver->options->imageFormat = IMG_JPEG; 218 219 $graph->renderer->options->syncAxisFonts = false; 220 221 $graph->renderToOutput( $p_graph_width, $p_graph_height); 222 } else { 223 # defines margin according to height 224 $graph = new Graph( $p_graph_width, $p_graph_height ); 225 $graph->img->SetMargin( 45, 35, 35, $p_baseline ); 226 if( ON == plugin_config_get( 'jpgraph_antialias' ) ) { 227 $graph->img->SetAntiAliasing(); 228 } 229 $graph->SetScale( 'textlin' ); 230 $graph->SetMarginColor( 'white' ); 231 $graph->SetFrame( false ); 232 $graph->title->SetFont( $t_graph_font, FS_BOLD ); 233 $graph->title->Set( $p_title ); 234 $graph->xaxis->SetTickLabels( array_keys( $p_metrics['open'] ) ); 235 if( FF_FONT2 <= $t_graph_font ) { 236 $graph->xaxis->SetLabelAngle( 60 ); 237 } else { 238 $graph->xaxis->SetLabelAngle( 90 ); 239 # can't rotate non truetype fonts 240 } 241 $graph->xaxis->SetFont( $t_graph_font ); 242 $graph->legend->Pos( 0.05, 0.08 ); 243 $graph->legend->SetFont( $t_graph_font ); 244 245 $graph->yaxis->scale->ticks->SetDirection( -1 ); 246 $graph->yaxis->SetFont( $t_graph_font ); 247 $graph->yscale->SetGrace( 10 ); 248 249 # adds on the same graph 250 $tot = new BarPlot( array_values( $total ) ); 251 $tot->SetFillColor( 'lightblue' ); 252 $tot->SetWidth( 0.7 ); 253 $tot->SetLegend( plugin_lang_get( 'legend_total' ) ); 254 $graph->Add( $tot ); 255 256 $p1 = new BarPlot( array_values( $p_metrics['open'] ) ); 257 $p1->SetFillColor( 'yellow' ); 258 $p1->SetWidth( 1 ); 259 $p1->SetLegend( plugin_lang_get( 'legend_opened' ) ); 260 261 $p2 = new BarPlot( array_values( $p_metrics['closed'] ) ); 262 $p2->SetFillColor( 'blue' ); 263 $p2->SetWidth( 1 ); 264 $p2->SetLegend( plugin_lang_get( 'legend_closed' ) ); 265 266 $p3 = new BarPlot( array_values( $p_metrics['resolved'] ) ); 267 $p3->SetFillColor( 'red' ); 268 $p3->SetWidth( 1 ); 269 $p3->SetLegend( plugin_lang_get( 'legend_resolved' ) ); 270 271 $gbplot = new GroupBarPlot( array( $p1, $p3, $p2 ) ); 272 $graph->Add( $gbplot ); 273 274 if( helper_show_query_count() ) { 275 $graph->subtitle->Set( db_count_queries() . ' queries (' . db_time_queries() . 'sec)' ); 276 $graph->subtitle->SetFont( $t_graph_font, FS_NORMAL, 8 ); 277 } 278 $graph->Stroke(); 279 } 280 } 281 282 # -------------------- 283 # Function that displays pie charts 284 function graph_pie( $p_metrics, $p_title = '', $p_graph_width = 500, $p_graph_height = 350, $p_center = 0.4, $p_poshorizontal = 0.10, $p_posvertical = 0.09 ) { 285 $t_graph_font = graph_get_font(); 286 287 error_check( is_array( $p_metrics ) ? array_sum( $p_metrics ) : 0, $p_title ); 288 289 if ( plugin_config_get( 'eczlibrary' ) == ON ) { 290 $graph = new ezcGraphPieChart(); 291 $graph->title = $p_title; 292 $graph->background->color = '#FFFFFF'; 293 $graph->options->font = $t_graph_font ; 294 $graph->options->font->maxFontSize = 12; 295 $graph->legend = false; 296 297 $graph->data[0] = new ezcGraphArrayDataSet( $p_metrics ); 298 $graph->data[0]->color = '#FFFF00'; 299 300 $graph->renderer = new ezcGraphRenderer3d(); 301 $graph->renderer->options->dataBorder = false; 302 $graph->renderer->options->pieChartShadowSize = 10; 303 $graph->renderer->options->pieChartGleam = .5; 304 $graph->renderer->options->pieChartHeight = 16; 305 $graph->renderer->options->legendSymbolGleam = .5; 306 307 $graph->driver = new ezcGraphGdDriver(); 308 //$graph->driver->options->supersampling = 1; 309 $graph->driver->options->jpegQuality = 100; 310 $graph->driver->options->imageFormat = IMG_JPEG; 311 312 $graph->renderer->options->syncAxisFonts = false; 313 314 $graph->renderToOutput( $p_graph_width, $p_graph_height); 315 } else { 316 $graph = new PieGraph( $p_graph_width, $p_graph_height ); 317 $graph->img->SetMargin( 40, 40, 40, 100 ); 318 $graph->title->Set( $p_title ); 319 $graph->title->SetFont( $t_graph_font, FS_BOLD ); 320 321 $graph->SetMarginColor( 'white' ); 322 $graph->SetFrame( false ); 323 324 $graph->legend->Pos( $p_poshorizontal, $p_posvertical ); 325 $graph->legend->SetFont( $t_graph_font ); 326 327 $p1 = new PiePlot3d( array_values( $p_metrics ) ); 328 329 // should be reversed? 330 $p1->SetTheme( 'earth' ); 331 332 # $p1->SetTheme("sand"); 333 $p1->SetCenter( $p_center ); 334 $p1->SetAngle( 60 ); 335 $p1->SetLegends( array_keys( $p_metrics ) ); 336 337 # Label format 338 $p1->value->SetFormat( '%2.0f' ); 339 $p1->value->Show(); 340 $p1->value->SetFont( $t_graph_font ); 341 342 $graph->Add( $p1 ); 343 if( helper_show_query_count() ) { 344 $graph->subtitle->Set( db_count_queries() . ' queries (' . db_time_queries() . 'sec)' ); 345 $graph->subtitle->SetFont( $t_graph_font, FS_NORMAL, 8 ); 346 } 347 $graph->Stroke(); 348 } 349 } 350 351 # -------------------- 352 function graph_cumulative_bydate( $p_metrics, $p_graph_width = 300, $p_graph_height = 380 ) { 353 354 $t_graph_font = graph_get_font(); 355 error_check( is_array( $p_metrics ) ? count( $p_metrics ) : 0, plugin_lang_get( 'cumulative' ) . ' ' . lang_get( 'by_date' ) ); 356 357 if ( plugin_config_get( 'eczlibrary' ) == ON ) { 358 $graph = new ezcGraphLineChart(); 359 360 $graph->background->color = '#FFFFFF'; 361 362 $graph->xAxis = new ezcGraphChartElementNumericAxis(); 363 364 $graph->data[0] = new ezcGraphArrayDataSet( $p_metrics[0] ); 365 $graph->data[0]->label = plugin_lang_get( 'legend_reported' ); 366 $graph->data[0]->color = '#FF0000'; 367 368 $graph->data[1] = new ezcGraphArrayDataSet( $p_metrics[1] ); 369 $graph->data[1]->label = plugin_lang_get( 'legend_resolved' ); 370 $graph->data[1]->color = '#0000FF'; 371 372 $graph->data[2] = new ezcGraphArrayDataSet( $p_metrics[2] ); 373 $graph->data[2]->label = plugin_lang_get( 'legend_still_open' ); 374 $graph->data[2]->color = '#000000'; 375 376 $graph->additionalAxis[2] = $nAxis = new ezcGraphChartElementNumericAxis(); 377 $nAxis->chartPosition = 1; 378 $nAxis->background = '#005500'; 379 $nAxis->border = '#005500'; 380 $nAxis->position = ezcGraph::BOTTOM; 381 $graph->data[2]->yAxis = $nAxis; 382 383 $graph->xAxis->labelCallback = 'graph_date_format'; 384 $graph->xAxis->axisLabelRenderer = new ezcGraphAxisRotatedLabelRenderer(); 385 $graph->xAxis->axisLabelRenderer->angle = -45; 386 387 $graph->legend->position = ezcGraph::BOTTOM; 388 $graph->legend->background = '#FFFFFF80'; 389 390 $graph->driver = new ezcGraphGdDriver(); 391 //$graph->driver->options->supersampling = 1; 392 $graph->driver->options->jpegQuality = 100; 393 $graph->driver->options->imageFormat = IMG_JPEG; 394 395 $graph->title = plugin_lang_get( 'cumulative' ) . ' ' . lang_get( 'by_date' ); 396 $graph->options->font = $t_graph_font ; 397 398 $graph->renderToOutput( $p_graph_width, $p_graph_height); 399 } else { 400 foreach( $p_metrics[0] as $i => $vals ) { 401 if( $i > 0 ) { 402 $plot_date[] = $i; 403 $reported_plot[] = $p_metrics[0][$i]; 404 $resolved_plot[] = $p_metrics[1][$i]; 405 $still_open_plot[] = $p_metrics[2][$i]; 406 } 407 } 408 409 $graph = new Graph( $p_graph_width, $p_graph_height ); 410 $graph->img->SetMargin( 40, 40, 40, 170 ); 411 if( ON == plugin_config_get( 'jpgraph_antialias' ) ) { 412 $graph->img->SetAntiAliasing(); 413 } 414 $graph->SetScale( 'linlin'); 415 $graph->yaxis->SetColor("red"); 416 $graph->SetY2Scale("lin"); 417 $graph->SetMarginColor( 'white' ); 418 $graph->SetFrame( false ); 419 $graph->title->Set( plugin_lang_get( 'cumulative' ) . ' ' . lang_get( 'by_date' ) ); 420 $graph->title->SetFont( $t_graph_font, FS_BOLD ); 421 422 $graph->legend->Pos( 0.05, 0.9, 'right', 'bottom' ); 423 $graph->legend->SetShadow( false ); 424 $graph->legend->SetFillColor( 'white' ); 425 $graph->legend->SetLayout( LEGEND_HOR ); 426 $graph->legend->SetFont( $t_graph_font ); 427 428 $graph->yaxis->scale->ticks->SetDirection( -1 ); 429 $graph->yaxis->SetFont( $t_graph_font ); 430 $graph->y2axis->SetFont( $t_graph_font ); 431 432 if( FF_FONT2 <= $t_graph_font ) { 433 $graph->xaxis->SetLabelAngle( 60 ); 434 } else { 435 $graph->xaxis->SetLabelAngle( 90 ); 436 # can't rotate non truetype fonts 437 } 438 $graph->xaxis->SetLabelFormatCallback( 'graph_date_format' ); 439 $graph->xaxis->SetFont( $t_graph_font ); 440 441 $p1 = new LinePlot( $reported_plot, $plot_date ); 442 $p1->SetColor( 'blue' ); 443 $p1->SetCenter(); 444 $p1->SetLegend( plugin_lang_get( 'legend_reported' ) ); 445 $graph->AddY2( $p1 ); 446 447 $p3 = new LinePlot( $still_open_plot, $plot_date ); 448 $p3->SetColor( 'red' ); 449 $p3->SetCenter(); 450 $p3->SetLegend( plugin_lang_get( 'legend_still_open' ) ); 451 $graph->Add( $p3 ); 452 453 $p2 = new LinePlot( $resolved_plot, $plot_date ); 454 $p2->SetColor( 'black' ); 455 $p2->SetCenter(); 456 $p2->SetLegend( plugin_lang_get( 'legend_resolved' ) ); 457 $graph->AddY2( $p2 ); 458 459 if( helper_show_query_count() ) { 460 $graph->subtitle->Set( db_count_queries() . ' queries (' . db_time_queries() . 'sec)' ); 461 $graph->subtitle->SetFont( $t_graph_font, FS_NORMAL, 8 ); 462 } 463 $graph->Stroke(); 464 } 465 } 466 467 # -------------------- 468 function graph_bydate( $p_metrics, $p_labels, $p_title, $p_graph_width = 300, $p_graph_height = 380 ) { 469 $t_graph_font = graph_get_font(); 470 error_check( is_array( $p_metrics ) ? count( $p_metrics ) : 0, lang_get( 'by_date' ) ); 471 472 if ( plugin_config_get( 'eczlibrary' ) == ON ) { 473 $t_metrics = array(); 474 $t_dates = array_shift($p_metrics); //[0]; 475 $t_cnt = count($p_metrics); 476 477 foreach( $t_dates as $i => $val ) { 478 //$t_metrics[$val] 479 for($j = 0; $j < $t_cnt; $j++ ) { 480 $t_metrics[$j][$val] = $p_metrics[$j][$i]; 481 } 482 } 483 484 $graph = new ezcGraphLineChart(); 485 $graph->background->color = '#FFFFFF'; 486 487 $graph->xAxis = new ezcGraphChartElementNumericAxis(); 488 for($k = 0; $k < $t_cnt; $k++ ) { 489 $graph->data[$k] = new ezcGraphArrayDataSet( $t_metrics[$k] ); 490 $graph->data[$k]->label = $p_labels[$k+1]; 491 } 492 493 $graph->xAxis->labelCallback = 'graph_date_format'; 494 $graph->xAxis->axisLabelRenderer = new ezcGraphAxisRotatedLabelRenderer(); 495 $graph->xAxis->axisLabelRenderer->angle = -45; 496 497 $graph->legend->position = ezcGraph::BOTTOM; 498 $graph->legend->background = '#FFFFFF80'; 499 500 $graph->driver = new ezcGraphGdDriver(); 501 //$graph->driver->options->supersampling = 1; 502 $graph->driver->options->jpegQuality = 100; 503 $graph->driver->options->imageFormat = IMG_JPEG; 504 505 $graph->title = $p_title . ' ' . lang_get( 'by_date' ); 506 $graph->options->font = $t_graph_font ; 507 508 $graph->renderToOutput( $p_graph_width, $p_graph_height); 509 } else { 510 $graph = new Graph( $p_graph_width, $p_graph_height ); 511 $graph->img->SetMargin( 40, 140, 40, 100 ); 512 if( ON == plugin_config_get( 'jpgraph_antialias' ) ) { 513 $graph->img->SetAntiAliasing(); 514 } 515 $graph->SetScale( 'linlin' ); 516 $graph->SetMarginColor( 'white' ); 517 $graph->SetFrame( false ); 518 $graph->title->Set( $p_title . ' ' . lang_get( 'by_date' ) ); 519 $graph->title->SetFont( $t_graph_font, FS_BOLD ); 520 521 $graph->legend->Pos( 0.01, 0.05, 'right', 'top' ); 522 $graph->legend->SetShadow( false ); 523 $graph->legend->SetFillColor( 'white' ); 524 $graph->legend->SetLayout( LEGEND_VERT ); 525 $graph->legend->SetFont( $t_graph_font ); 526 527 $graph->yaxis->scale->ticks->SetDirection( -1 ); 528 $graph->yaxis->SetFont( $t_graph_font ); 529 $graph->yaxis->scale->SetAutoMin( 0 ); 530 531 if( FF_FONT2 <= $t_graph_font ) { 532 $graph->xaxis->SetLabelAngle( 60 ); 533 } else { 534 $graph->xaxis->SetLabelAngle( 90 ); 535 # can't rotate non truetype fonts 536 } 537 $graph->xaxis->SetLabelFormatCallback( 'graph_date_format' ); 538 $graph->xaxis->SetFont( $t_graph_font ); 539 540 /* $t_line_colours = plugin_config_get( 'jpgraph_colors' ); 541 $t_count_colours = count( $t_line_colours );*/ 542 $t_lines = count( $p_metrics ) - 1; 543 $t_line = array(); 544 for( $i = 1;$i <= $t_lines;$i++ ) { 545 $t_line[$i] = new LinePlot( $p_metrics[$i], $p_metrics[0] ); 546 //$t_line[$i]->SetColor( $t_line_colours[$i % $t_count_colours] ); 547 $t_line[$i]->SetCenter(); 548 $t_line[$i]->SetLegend( $p_labels[$i] ); 549 $graph->Add( $t_line[$i] ); 550 } 551 552 if( helper_show_query_count() ) { 553 $graph->subtitle->Set( db_count_queries() . ' queries (' . db_time_queries() . 'sec)' ); 554 $graph->subtitle->SetFont( $t_graph_font, FS_NORMAL, 8 ); 555 } 556 $graph->Stroke(); 557 } 558 } 559 560 # -------------------- 561 # utilities 562 # -------------------- 563 function graph_total_metrics( $p_metrics ) { 564 foreach( $p_metrics['open'] as $t_enum => $t_value ) { 565 $total[$t_enum] = $t_value + $p_metrics['resolved'][$t_enum] + $p_metrics['closed'][$t_enum]; 566 } 567 return $total; 568 } 569 570 # -------------------- 571 # Data Extractions 572 # -------------------- 573 # -------------------- 574 # summarize metrics by a single field in the bug table 575 function create_bug_enum_summary( $p_enum_string, $p_enum ) { 576 $t_project_id = helper_get_current_project(); 577 $t_bug_table = db_get_table( 'bug' ); 578 $t_user_id = auth_get_current_user_id(); 579 $specific_where = " AND " . helper_project_specific_where( $t_project_id, $t_user_id ); 580 581 $t_metrics = array(); 582 $t_assoc_array = MantisEnum::getAssocArrayIndexedByValues( $p_enum_string ); 583 584 foreach ( $t_assoc_array as $t_value => $t_label ) { 585 $query = "SELECT COUNT(*) 586 FROM $t_bug_table 587 WHERE $p_enum='$t_value' $specific_where"; 588 $result = db_query( $query ); 589 $t_metrics[$t_label] = db_result( $result, 0 ); 590 } 591 592 return $t_metrics; 593 } 594 595 # Function which gives the absolute values according to the status (opened/closed/resolved) 596 function enum_bug_group( $p_enum_string, $p_enum ) { 597 $t_bug_table = db_get_table( 'bug' ); 598 599 $t_project_id = helper_get_current_project(); 600 $t_bug_table = db_get_table( 'bug' ); 601 $t_user_id = auth_get_current_user_id(); 602 $t_res_val = config_get( 'bug_resolved_status_threshold' ); 603 $t_clo_val = config_get( 'bug_closed_status_threshold' ); 604 $specific_where = " AND " . helper_project_specific_where( $t_project_id, $t_user_id ); 605 606 $t_array_indexed_by_enum_values = MantisEnum::getAssocArrayIndexedByValues( $p_enum_string ); 607 $enum_count = count( $t_array_indexed_by_enum_values ); 608 foreach ( $t_array_indexed_by_enum_values as $t_value => $t_label ) { 609 # Calculates the number of bugs opened and puts the results in a table 610 $query = "SELECT COUNT(*) 611 FROM $t_bug_table 612 WHERE $p_enum='$t_value' AND 613 status<'$t_res_val' $specific_where"; 614 $result2 = db_query( $query ); 615 $t_metrics['open'][$t_label] = db_result( $result2, 0, 0 ); 616 617 # Calculates the number of bugs closed and puts the results in a table 618 $query = "SELECT COUNT(*) 619 FROM $t_bug_table 620 WHERE $p_enum='$t_value' AND 621 status='$t_clo_val' $specific_where"; 622 $result2 = db_query( $query ); 623 $t_metrics['closed'][$t_label] = db_result( $result2, 0, 0 ); 624 625 # Calculates the number of bugs resolved and puts the results in a table 626 $query = "SELECT COUNT(*) 627 FROM $t_bug_table 628 WHERE $p_enum='$t_value' AND 629 status>='$t_res_val' AND 630 status<'$t_clo_val' $specific_where"; 631 $result2 = db_query( $query ); 632 $t_metrics['resolved'][$t_label] = db_result( $result2, 0, 0 ); 633 } 634 635 # ## end for 636 637 return $t_metrics; 638 } 639 640 # -------------------- 641 function create_developer_summary() { 642 $t_project_id = helper_get_current_project(); 643 $t_user_table = db_get_table( 'user' ); 644 $t_bug_table = db_get_table( 'bug' ); 645 $t_user_id = auth_get_current_user_id(); 646 $specific_where = " AND " . helper_project_specific_where( $t_project_id, $t_user_id ); 647 648 $t_res_val = config_get( 'bug_resolved_status_threshold' ); 649 $t_clo_val = config_get( 'bug_closed_status_threshold' ); 650 651 $query = "SELECT handler_id, status 652 FROM $t_bug_table 653 WHERE handler_id > 0 $specific_where"; 654 $result = db_query_bound( $query ); 655 $t_total_handled = db_num_rows( $result ); 656 657 $t_handler_arr = array(); 658 $t_handlers = array(); 659 for( $i = 0;$i < $t_total_handled;$i++ ) { 660 $row = db_fetch_array( $result ); 661 if( !isset( $t_handler_arr[$row['handler_id']] ) ) { 662 $t_handler_arr[$row['handler_id']]['res'] = 0; 663 $t_handler_arr[$row['handler_id']]['open'] = 0; 664 $t_handler_arr[$row['handler_id']]['close'] = 0; 665 $t_handlers[] = $row['handler_id']; 666 } 667 if( $row['status'] >= $t_res_val ) { 668 if( $row['status'] >= $t_clo_val ) { 669 $t_handler_arr[$row['handler_id']]['close']++; 670 } else { 671 $t_handler_arr[$row['handler_id']]['res']++; 672 } 673 } else { 674 $t_handler_arr[$row['handler_id']]['open']++; 675 } 676 } 677 678 if( count( $t_handler_arr ) == 0 ) { 679 return array( 'open' => array() ); 680 } 681 682 user_cache_array_rows( $t_handlers ); 683 684 foreach( $t_handler_arr as $t_handler => $t_data ) { 685 $t_username = user_get_name( $t_handler ); 686 687 $t_metrics['open'][$t_username] = $t_data['open']; 688 $t_metrics['resolved'][$t_username] = $t_data['res']; 689 $t_metrics['closed'][$t_username] = $t_data['close']; 690 } 691 ksort($t_metrics); 692 693 # end for 694 return $t_metrics; 695 } 696 697 # -------------------- 698 function create_reporter_summary() { 699 global $reporter_name, $reporter_count; 700 701 $t_project_id = helper_get_current_project(); 702 $t_user_table = db_get_table( 'user' ); 703 $t_bug_table = db_get_table( 'bug' ); 704 $t_user_id = auth_get_current_user_id(); 705 $specific_where = helper_project_specific_where( $t_project_id, $t_user_id ); 706 707 $query = "SELECT reporter_id 708 FROM $t_bug_table 709 WHERE $specific_where"; 710 $result = db_query_bound( $query ); 711 $t_total_reported = db_num_rows( $result ); 712 713 $t_reporter_arr = array(); 714 $t_reporters = array(); 715 for( $i = 0;$i < $t_total_reported;$i++ ) { 716 $row = db_fetch_array( $result ); 717 718 if( isset( $t_reporter_arr[$row['reporter_id']] ) ) { 719 $t_reporter_arr[$row['reporter_id']]++; 720 } else { 721 $t_reporter_arr[$row['reporter_id']] = 1; 722 $t_reporters[] = $row['reporter_id']; 723 } 724 } 725 726 if( count( $t_reporter_arr ) == 0 ) { 727 return array(); 728 } 729 730 user_cache_array_rows( $t_reporters ); 731 732 foreach( $t_reporter_arr as $t_reporter => $t_count ) { 733 $t_metrics[ user_get_name( $t_reporter ) ] = $t_count; 734 } 735 ksort($t_metrics); 736 737 # end for 738 return $t_metrics; 739 } 740 741 # -------------------- 742 function create_category_summary() { 743 global $category_name, $category_bug_count; 744 745 $t_project_id = helper_get_current_project(); 746 $t_cat_table = db_get_table( 'category' ); 747 $t_bug_table = db_get_table( 'bug' ); 748 $t_user_id = auth_get_current_user_id(); 749 $specific_where = helper_project_specific_where( $t_project_id, $t_user_id ); 750 751 $query = "SELECT id, name 752 FROM $t_cat_table 753 WHERE $specific_where 754 ORDER BY name"; 755 $result = db_query_bound( $query ); 756 $category_count = db_num_rows( $result ); 757 758 $t_metrics = array(); 759 for( $i = 0;$i < $category_count;$i++ ) { 760 $row = db_fetch_array( $result ); 761 $t_cat_name = $row['name']; 762 $t_cat_id = $row['id']; 763 $query = "SELECT COUNT(*) 764 FROM $t_bug_table 765 WHERE category_id=" . db_param() . " AND $specific_where"; 766 $result2 = db_query_bound( $query, Array( $t_cat_id ) ); 767 if ( isset($t_metrics[$t_cat_name]) ) { 768 $t_metrics[$t_cat_name] = $t_metrics[$t_cat_name] + db_result( $result2, 0, 0 ); 769 } else { 770 $t_metrics[$t_cat_name] = db_result( $result2, 0, 0 ); 771 } 772 } 773 774 # end for 775 return $t_metrics; 776 } 777 778 # -------------------- 779 function create_cumulative_bydate() { 780 781 $t_clo_val = config_get( 'bug_closed_status_threshold' ); 782 $t_res_val = config_get( 'bug_resolved_status_threshold' ); 783 $t_bug_table = db_get_table( 'bug' ); 784 $t_history_table = db_get_table( 'bug_history' ); 785 786 $t_project_id = helper_get_current_project(); 787 $t_user_id = auth_get_current_user_id(); 788 $specific_where = helper_project_specific_where( $t_project_id, $t_user_id ); 789 790 # Get all the submitted dates 791 $query = "SELECT date_submitted 792 FROM $t_bug_table 793 WHERE $specific_where 794 ORDER BY date_submitted"; 795 $result = db_query_bound( $query ); 796 $bug_count = db_num_rows( $result ); 797 798 for( $i = 0;$i < $bug_count;$i++ ) { 799 $row = db_fetch_array( $result ); 800 801 # rationalise the timestamp to a day to reduce the amount of data 802 $t_date = $row['date_submitted']; 803 $t_date = (int)( $t_date / SECONDS_PER_DAY ); 804 805 if( isset( $metrics[$t_date] ) ) { 806 $metrics[$t_date][0]++; 807 } else { 808 $metrics[$t_date] = array( 1, 0, 0, ); 809 } 810 } 811 812 # ## Get all the dates where a transition from not resolved to resolved may have happened 813 # also, get the last updated date for the bug as this may be all the information we have 814 $query = "SELECT $t_bug_table.id, last_updated, date_modified, new_value, old_value 815 FROM $t_bug_table LEFT JOIN $t_history_table 816 ON $t_bug_table.id = $t_history_table.bug_id 817 WHERE $specific_where 818 AND $t_bug_table.status >= '$t_res_val' 819 AND ( ( $t_history_table.new_value >= '$t_res_val' 820 AND $t_history_table.field_name = 'status' ) 821 OR $t_history_table.id is NULL ) 822 ORDER BY $t_bug_table.id, date_modified ASC"; 823 $result = db_query( $query ); 824 $bug_count = db_num_rows( $result ); 825 826 $t_last_id = 0; 827 $t_last_date = 0; 828 829 for( $i = 0;$i < $bug_count;$i++ ) { 830 $row = db_fetch_array( $result ); 831 $t_id = $row['id']; 832 833 # if h_last_updated is NULL, there were no appropriate history records 834 # (i.e. pre 0.18 data), use last_updated from bug table instead 835 if( NULL == $row['date_modified'] ) { 836 $t_date = $row['last_updated']; 837 } else { 838 if( $t_res_val > $row['old_value'] ) { 839 $t_date = $row['date_modified']; 840 } 841 } 842 if( $t_id <> $t_last_id ) { 843 if( 0 <> $t_last_id ) { 844 845 # rationalise the timestamp to a day to reduce the amount of data 846 $t_date_index = (int)( $t_last_date / SECONDS_PER_DAY ); 847 848 if( isset( $metrics[$t_date_index] ) ) { 849 $metrics[$t_date_index][1]++; 850 } else { 851 $metrics[$t_date_index] = array( 852 0, 853 1, 854 0, 855 ); 856 } 857 } 858 $t_last_id = $t_id; 859 } 860 $t_last_date = $t_date; 861 } 862 863 ksort( $metrics ); 864 865 $metrics_count = count( $metrics ); 866 $t_last_opened = 0; 867 $t_last_resolved = 0; 868 foreach( $metrics as $i => $vals ) { 869 $t_date = $i * SECONDS_PER_DAY; 870 $t_metrics[0][$t_date] = $t_last_opened = $metrics[$i][0] + $t_last_opened; 871 $t_metrics[1][$t_date] = $t_last_resolved = $metrics[$i][1] + $t_last_resolved; 872 $t_metrics[2][$t_date] = $t_metrics[0][$t_date] - $t_metrics[1][$t_date]; 873 } 874 return $t_metrics; 875 } 876 877 function graph_date_format( $p_date ) { 878 return date( config_get( 'short_date_format' ), $p_date ); 879 } 880 881 # ---------------------------------------------------- 882 # Check that there is enough data to create graph 883 # ---------------------------------------------------- 884 function error_check( $bug_count, $title ) { 885 if( 0 == $bug_count ) { 886 $t_graph_font = graph_get_font(); 887 888 error_text( $title, plugin_lang_get( 'not_enough_data' ) ); 889 } 890 } 891 892 function error_text( $title, $text ) { 893 if( OFF == plugin_config_get( 'eczlibrary' ) ) { 894 $graph = new CanvasGraph( 300, 380 ); 895 896 $txt = new Text( $text, 150, 100 ); 897 $txt->Align( "center", "center", "center" ); 898 $txt->SetFont( $t_graph_font, FS_BOLD ); 899 $graph->title->Set( $title ); 900 $graph->title->SetFont( $t_graph_font, FS_BOLD ); 901 $graph->AddText( $txt ); 902 $graph->Stroke(); 903 } else { 904 $im = imagecreate(300, 300); 905 /* @todo check: error graphs dont support utf8 */ 906 $bg = imagecolorallocate($im, 255, 255, 255); 907 $textcolor = imagecolorallocate($im, 0, 0, 0); 908 imagestring($im, 5, 0, 0, $text, $textcolor); 909 header('Content-type: image/png'); 910 imagepng($im); 911 imagedestroy($im); 912 } 913 die; 914 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Thu Jul 28 15:48:31 2011 | Cross-referenced by PHPXref 0.7 |