3 * FusionForge reporting system
5 * Copyright 2003-2004, Tim Perdue/GForge, LLC
6 * Copyright 2009, Roland Mas
7 * Copyright (C) 2010 Alain Peyrat - Alcatel-Lucent
8 * Copyright 2013, Franck Villaume - TrivialDev
10 * This file is part of FusionForge. FusionForge is free software;
11 * you can redistribute it and/or modify it under the terms of the
12 * GNU General Public License as published by the Free Software
13 * Foundation; either version 2 of the Licence, or (at your option)
16 * FusionForge is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License along
22 * with FusionForge; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 function report_header($title) {
27 $t = sprintf(_('%s Reporting'), forge_get_config ('forge_name')) . _(': ') . $title;
28 site_header(array('title'=>$t));
31 function report_footer() {
33 $HTML->footer(array());
36 function report_span_box($name='SPAN', $selected='1', $suppress_daily=false) {
37 if ($suppress_daily) {
39 $titles=array(_('Weekly'),
43 $titles=array(_('Daily'),
47 return html_build_select_box_from_arrays ($vals,$titles,$name,$selected,false);
50 function report_weeks_box($Report, $name='week', $selected=false) {
51 $arr =& $Report->getWeekStartArr();
54 for ($i=0; $i<count($arr); $i++) {
55 $arr2[$i]=date(_('Y-m-d'), $arr[$i]) .' '._('to').' '. date(_('Y-m-d'), ($arr[$i]+6*24*60*60));
58 return html_build_select_box_from_arrays ($arr,$arr2,$name,$selected,false);
61 function report_day_adjust_box() {
62 $days = array('0', '1', '2', '3', '4', '5', '6');
63 $names = array(_('Sunday'), _('Monday'), _('Tuesday'),
64 _('Wednesday'), _('Thursday'), _('Friday'), _('Saturday'));
65 return html_build_select_box_from_arrays($days, $names, 'days_adjust', false, false);
68 function report_months_box($Report, $name='month', $selected=false) {
69 $arr =& $Report->getMonthStartArr();
72 for ($i=0; $i<count($arr); $i++) {
73 $arr2[$i]=date(_('Y-m'),$arr[$i]);
76 return html_build_select_box_from_arrays ($arr,$arr2,$name,$selected,false);
79 function report_useract_box($name='dev_id', $selected='1', $start_with='') {
81 $res = db_query_params ('SELECT user_id,realname FROM users WHERE status=$1 AND (exists (SELECT user_id FROM rep_user_act_daily WHERE user_id=users.user_id)) AND (lower(lastname) LIKE $2 OR lower(user_name) LIKE $3) ORDER BY lastname',
83 strtolower("$start_with%"),
84 strtolower("$start_with%"))) ;
86 $res = db_query_params ('SELECT user_id,realname FROM users WHERE status=$1 AND (exists (SELECT user_id FROM rep_user_act_daily WHERE user_id=users.user_id)) ORDER BY lastname',
89 return html_build_select_box($res, $name, $selected, false);
92 function report_usertime_box($name='dev_id', $selected='1', $start_with='') {
94 $res = db_query_params ('SELECT user_id,realname FROM users WHERE status=$1 AND (exists (SELECT user_id FROM rep_time_tracking WHERE user_id=users.user_id)) AND (lower(lastname) LIKE $2 OR lower(user_name) LIKE $3) ORDER BY lastname',
96 strtolower("$start_with%"),
97 strtolower("$start_with%"))) ;
99 $res = db_query_params ('SELECT user_id,realname FROM users WHERE status=$1 AND (exists (SELECT user_id FROM rep_time_tracking WHERE user_id=users.user_id)) ORDER BY lastname',
102 return html_build_select_box($res, $name, $selected, false);
105 function report_group_box($name='g_id', $selected='1') {
107 $res = db_query_params ('SELECT group_id,group_name FROM groups WHERE status=$1 ORDER BY group_name',
109 return html_build_select_box($res, $name, $selected, false);
112 function report_area_box($name='area', $selected='1', $Group=false) {
116 $use_tracker = $Group->usesTracker();
117 $use_forum = $Group->usesForum();
118 $use_docman = $Group->usesDocman();
119 $use_pm = $Group->usesPM();
120 $use_frs = $Group->usesFRS();
121 $use_pageviews = true;
123 $use_tracker = forge_get_config('use_tracker');
124 $use_forum = forge_get_config('use_forum');
125 $use_docman = forge_get_config('use_docman');
126 $use_pm = forge_get_config('use_pm');
127 $use_frs = false; // Not implemented in ReportUserAct: forge_get_config('use_frs');
128 $use_pageviews = false;
132 $arr2[]=_('Tracker');
148 $arr2[]=_('Downloads');
150 if ($use_pageviews) {
152 $arr2[]=_('Page Views');
155 if (is_object($Group) && $Group->getID()) {
156 $hookParams['group'] = $Group->getID();
157 $hookParams['group_id'] = $Group->getID();
158 $hookParams['show'] = array('none'); // No display => No compute this time.
159 $hookParams['ids'] = &$arr;
160 $hookParams['texts'] = &$arr2;
161 plugin_hook ("activity", $hookParams) ;
164 return html_build_select_box_from_arrays ($arr,$arr2,$name,$selected,false);
167 function report_tracker_box($name='datatype', $selected='1') {
170 if (forge_get_config('use_tracker')) {
174 $arr[]=_('Feature Requests');
175 $arr[]=_('Other Trackers');
182 if (forge_get_config('use_forum')) {
183 $arr[]=_('Forum Messages');
186 if (forge_get_config('use_pm')) {
190 if (forge_get_config('use_frs')) {
191 $arr[]=_('Downloads');
194 return html_build_select_box_from_arrays ($arr2,$arr,$name,$selected,false);
197 function report_time_category_box($name='category',$selected=false) {
198 global $report_time_category_res;
199 if (!$report_time_category_res) {
200 $report_time_category_res = db_query_params ('SELECT * FROM rep_time_category', array());
202 return html_build_select_box($report_time_category_res,$name,$selected,false);
206 // Takes an array of labels and an array values and removes vals < 2% and sets up an "other"
208 function report_pie_arr($labels, $vals, $format=1) {
209 global $pie_labels,$pie_vals;
212 //first get sum of all values
213 for ($i=0; $i<count($vals); $i++) {
217 //now prune out vals where < 2%
219 for ($i=0; $i<count($vals); $i++) {
220 if (($vals[$i]/$total) < .02) {
223 $pie_labels[]=util_unconvert_htmlspecialchars($labels[$i])." (". number_format($vals[$i],$format) .") ";
224 $pie_vals[]=$vals[$i];
228 $pie_labels[]=_('Other')." (". number_format($rem,$format) .") ";
234 function report_package_box($group_id, $name='dev_id', $selected='') {
236 $res = db_query_params ('SELECT package_id, name FROM frs_package WHERE frs_package.group_id = $1',
238 return html_build_select_box($res, $name, $selected, false);
241 function trackeract_graph($group_id, $area, $SPAN, $start, $end, $atid) {
246 if (!strlen($area)) {
247 echo '<p class="information">'._('No selected area.').'</p>';
250 $report = new ReportTrackerAct($SPAN, $group_id, $atid, $start, $end);
251 if ($report->isError()) {
252 echo '<p class="error">'.$report->getErrorMessage().'</p>';
255 $rdates = $report->getRawDates();
259 $ydata[] =& $report->getAverageTimeData();
260 $label[] = _('Avg Time Open (in days)');
261 $ydata[] =& $report->getOpenCountData();
262 $label[] = _('Total Opened');
263 $ydata[] =& $report->getStillOpenCountData();
264 $label[] = _('Total Still Open');
265 $chartid = 'projecttrackergraph_'.$group_id;
267 echo '<script type="text/javascript">//<![CDATA['."\n";
268 echo 'var values = new Array();';
269 echo 'var ticks = new Array();';
270 echo 'var labels = new Array();';
271 echo 'var series = new Array();';
272 echo 'var plot'.$chartid.';';
273 for ($z = 0; $z < count($ydata); $z++) {
274 echo 'values['.$z.'] = new Array();';
275 echo 'labels.push({label:\''.$label[$z].'\'});';
279 case REPORT_TYPE_MONTHLY : {
283 case REPORT_TYPE_WEEKLY : {
288 for ($j = 0; $j < count($rdates); $j++) {
289 for ($z = 0; $z < count($ydata); $z++) {
290 if (isset($ydata[$z][$j])) {
291 if ($ydata[$z][$j] === false || $ydata[$z][$j] === NULL) {
294 if ($ydata[$z][$j] > $yMax) {
295 $yMax = $ydata[$z][$j];
297 echo 'values['.$z.'].push('.$ydata[$z][$j].');';
299 echo 'values['.$z.'].push(0);';
302 $tickArr[] = date($formatDate, $rdates[$j]);
303 echo 'ticks.push(\''.$tickArr[$j].'\');';
305 for ($z = 0; $z < count($ydata); $z++) {
306 echo 'series.push(values['.$z.']);';
308 echo 'jQuery(document).ready(function(){
309 plot'.$chartid.' = jQuery.jqplot (\'chart'.$chartid.'\', series, {
310 title : \''._('Tracker Activity').' ('.strftime('%x',$start).' - '.strftime('%x',$end).') \',
324 renderer:jQuery.jqplot.BarRenderer,
330 show:true, location: \'ne\',
337 renderer: jQuery.jqplot.CategoryAxisRenderer,
356 echo 'jQuery(window).resize(function() {
357 plot'.$chartid.'.replot();
359 echo '//]]></script>';
360 echo '<div id="chart'.$chartid.'"></div>';
364 function trackerpie_graph($group_id, $area, $SPAN, $start, $end, $atid) {
369 if (!strlen($area)) {
370 echo '<p class="information">'._('No selected area.').'</p>';
373 $report = new ReportTrackerAct($SPAN, $group_id, $atid, $start, $end);
374 if ($report->isError()) {
375 echo '<p class="error">'.$report->getErrorMessage().'</p>';
380 $dbres = $report->getPerAssignee($atid, $start, $end);
381 $areaname = _('Per assignee');
385 $chartid = 'projecttrackerpie_'.$group_id;
386 echo '<script type="text/javascript">//<![CDATA['."\n";
387 echo 'var plot'.$chartid.';';
388 echo 'var data = new Array();';
389 while ($row = db_fetch_array($dbres)) {
390 echo 'data.push([\''.htmlentities($row[0]).'\',\''.$row[1].'\']);';
392 echo 'jQuery(document).ready(function(){
393 plot'.$chartid.' = jQuery.jqplot (\'chart'.$chartid.'\', [data],
395 title : \''.$areaname." (".strftime('%x',$start) ." - ". strftime('%x',$end) .")".'\',
397 // Make this a pie chart.
398 renderer: jQuery.jqplot.PieRenderer,
400 // Put data labels on the pie slices.
401 // By default, labels show the percentage of the slice.
402 showDataLabels: true,
403 dataLabels: \'percent\',
407 show:true, location: \'e\',
412 echo 'jQuery(window).resize(function() {
413 plot'.$chartid.'.replot( { resetAxes: true } );
415 echo '//]]></script>';
416 echo '<div id="chart'.$chartid.'"></div>';
420 function report_graph($type, $SPAN, $start, $end) {
421 $now = time() - 60*60*24; // 1 day
427 $report = new ReportUserCum($SPAN, $start, $end);
428 $label[0] = _('Cumulative Users');
432 $report = new ReportUserAdded($SPAN, $start, $end);
433 $label[0] = _('Users Added');
437 $report = new ReportGroupAdded($SPAN, $start, $end);
438 $label[0] = _('Projects Added');
442 $report = new ReportGroupCum($SPAN, $start, $end);
443 $label[0] = _('Cumulative Projects');
448 if ($report->isError()) {
449 echo '<p class="error">'.$report->getErrorMessage().'</p>';
452 $rdates = $report->getRawDates();
454 echo '<p class="information">'._('No data to display.').'</p>';
457 $ydata[0] = $report->getData();
459 if ($SPAN == REPORT_TYPE_DAILY) {
461 $formatDate = 'Y-m-d';
463 while ($looptime < $end) {
464 $timeStampArr[$i] = $looptime;
465 $timeStampArrFormat[$i] = date($formatDate, $looptime);
466 $looptime += REPORT_DAY_SPAN;
469 } elseif ($SPAN == REPORT_TYPE_WEEKLY) {
470 $timeStampArr = $report->getWeekStartArr();
471 $timeStampArrFormat = $report->getWeekStartArrFormat();
473 } elseif ($SPAN == REPORT_TYPE_MONTHLY) {
474 $timeStampArr = $report->getMonthStartArr();
475 $timeStampArrFormat = $report->getMonthStartArrFormat();
479 $chartid = '_useradded';
481 echo '<script type="text/javascript">//<![CDATA['."\n";
482 echo 'var plot'.$chartid.';';
483 echo 'var '.$chartid.'values = new Array();';
484 echo 'var '.$chartid.'labels = new Array();';
485 echo 'var '.$chartid.'series = new Array();';
486 for ($z = 0; $z < count($ydata); $z++) {
487 echo $chartid.'values['.$z.'] = new Array();';
488 echo $chartid.'labels.push({label:\''.$label[$z].'\'});';
490 case REPORT_TYPE_DAILY:
491 case REPORT_TYPE_MONTHLY: {
492 for ($j = 0; $j < count($timeStampArr); $j++) {
493 if (in_array($timeStampArr[$j], $rdates)) {
494 $thekey = array_search($timeStampArr[$j], $rdates);
495 if (isset($ydata[$z][$thekey])) {
496 if ($ydata[$z][$thekey] === false) {
497 $ydata[$z][$thekey] = 0;
499 if ($ydata[$z][$thekey] > $yMax) {
500 $yMax = $ydata[$z][$thekey];
502 echo 'var '.$chartid.'datevalues = '.$ydata[$z][$thekey].';';
504 echo 'var '.$chartid.'datevalues = 0;';
507 echo 'var '.$chartid.'datevalues = 0;';
509 echo 'var '.$chartid.'date = \''.$timeStampArrFormat[$j].'\';';
510 echo $chartid.'values['.$z.'].push(['.$chartid.'date, '.$chartid.'datevalues]);';
514 case REPORT_TYPE_WEEKLY: {
515 for ($j = 0; $j < count($rdates); $j++) {
516 $wrdates[$j] = date($formatDate, $rdates[$j]);
518 for ($j = 0; $j < count($timeStampArr); $j++) {
519 if (in_array($timeStampArrFormat[$j], $wrdates)) {
520 $thekey = array_search($timeStampArr[$j], $wrdates);
521 if (isset($ydata[$z][$thekey])) {
522 if ($ydata[$z][$thekey] === false) {
523 $ydata[$z][$thekey] = 0;
525 if ($ydata[$z][$thekey] > $yMax) {
526 $yMax = $ydata[$z][$thekey];
528 echo 'var '.$chartid.'datevalues = '.$ydata[$z][$thekey].';';
530 echo 'var '.$chartid.'datevalues = 0;';
533 echo 'var '.$chartid.'datevalues = 0;';
535 echo 'var '.$chartid.'date = \''.$timeStampArrFormat[$j].'\';';
536 echo $chartid.'values['.$z.'].push(['.$chartid.'date, '.$chartid.'datevalues]);';
542 for ($z = 0; $z < count($ydata); $z++) {
543 echo $chartid.'series.push('.$chartid.'values['.$z.']);';
545 echo 'jQuery(document).ready(function(){
546 plot'.$chartid.' = jQuery.jqplot (\'chart'.$chartid.'\', '.$chartid.'series, {
548 tickRenderer: jQuery.jqplot.CanvasAxisTickRenderer,
555 show:true, location: \'ne\',
562 renderer: jQuery.jqplot.CategoryAxisRenderer,
563 label: \''.$label[0].'\',
582 echo 'jQuery(window).resize(function() {
583 plot'.$chartid.'.replot( { resetAxes: true } );
585 echo '//]]></script>';
586 echo '<div id="chart'.$chartid.'"></div>';
590 function report_actgraph($type, $SPAN, $start, $end, $id, $area) {
591 $now = time() - 60*60*24; // 1 day
597 $report = new ReportUserAct($SPAN, $id, $start, $end);
598 $u = user_get_object($id);
599 if (!$u || $u->isError()) {
600 exit_error(_("Could Not Get User"));
605 $report = new ReportProjectAct($SPAN, $id, $start, $end);
606 $g = group_get_object($id);
607 if (!$g || !is_object($g)) {
609 } elseif ($g->isError()) {
610 exit_error($g->getErrorMessage(), '');
615 $report = new ReportSiteAct($SPAN, $start, $end);
620 if ($report->isError()) {
621 echo '<p class="error">'.$report->getErrorMessage().'</p>';
624 $rdates = $report->getRawDates();
626 echo '<p class="information">'._('No data to display.').'</p>';
630 $SPAN = REPORT_TYPE_DAILY;
633 if ($SPAN == REPORT_TYPE_DAILY) {
636 while ($looptime < $end) {
637 $timeStampArr[$i] = $looptime;
638 $looptime += REPORT_DAY_SPAN;
641 $formatDate = 'Y/m/d';
642 } elseif ($SPAN == REPORT_TYPE_WEEKLY) {
643 $timeStampArr = $report->getWeekStartArr();
645 } elseif ($SPAN == REPORT_TYPE_MONTHLY) {
646 $timeStampArr = $report->getMonthStartArr();
650 $initialSizeOfTimeStampArr = count($timeStampArr);
651 for ($j = 0; $j < $initialSizeOfTimeStampArr; $j++) {
652 if ($timeStampArr[$j] < $start || $timeStampArr[$j] >= $end) {
653 unset($timeStampArr[$j]);
657 $timeStampArr = array_values($timeStampArr);
658 for ($j = 0; $j < count($timeStampArr); $j++) {
659 $tickArr[] = date($formatDate, $timeStampArr[$j]);
664 $ydata[] =& $report->getDocs();
665 $areaname = _('Docs');
666 $label[] = _('Documents');
670 $ydata[] =& $report->getDownloads();
671 $areaname = _('Downloads');
672 $label[] = _('Downloads');
676 $ydata[] =& $report->getForum();
677 $areaname = _('Forums');
678 $label[] = _('Forums');
682 $ydata[] =& $report->getPageViews();
683 $areaname = _('Page Views');
684 $label[] = _('Page Views');
688 $ydata[] =& $report->getTaskOpened();
689 $ydata[] =& $report->getTaskClosed();
690 $areaname = _('Tasks');
691 $label[] = _('Task open');
692 $label[] = _('Task close');
696 $ydata[] =& $report->getTrackerOpened();
697 $ydata[] =& $report->getTrackerClosed();
698 $areaname = _('Trackers');
699 $label[] = _('Tracker items opened');
700 $label[] = _('Tracker items closed');
709 $hookParams['group'] = $id;
710 $hookParams['results'] = &$results;
711 $hookParams['show'] = &$show;
712 $hookParams['begin'] = $start;
713 $hookParams['end'] = $end;
714 $hookParams['ids'] = &$ids;
715 $hookParams['texts'] = &$texts;
716 plugin_hook("activity", $hookParams);
718 $areaname = $texts[0];
719 $label[] = $texts[0];
721 foreach ($results as $arr) {
722 $dd = date($formatDate, $arr['activity_date']);
724 case REPORT_TYPE_MONTHLY : {
725 $d = mktime(0, 0, 0, substr($dd, 5, 2) , 1, substr($dd, 0, 4));
728 case REPORT_TYPE_WEEKLY: {
729 $d = strtotime(substr($dd, 0, 4).'-W'.substr($dd, 5, 2));
732 case REPORT_TYPE_DAILY: {
733 $d = mktime(0, 0, 0, substr($dd, 5, 2) , substr($dd, 8, 2), substr($dd, 0, 4));
740 // Now, stores the values in the ydata array for the graph.
743 foreach ($rdates as $d) {
744 $ydata[0][$i++] = isset($sum[$d]) ? $sum[$d] : 0;
750 $chartid = 'report_actgraph_'.$id;
752 echo '<script type="text/javascript">//<![CDATA['."\n";
753 echo 'var plot'.$chartid.';';
754 echo 'var values = new Array();';
755 echo 'var ticks = new Array();';
756 echo 'var labels = new Array();';
757 echo 'var series = new Array();';
758 for ($z = 0; $z < count($ydata); $z++) {
759 echo 'values['.$z.'] = new Array();';
760 echo 'labels.push({label:\''.$label[$z].'\'});';
763 case REPORT_TYPE_DAILY:
764 case REPORT_TYPE_MONTHLY: {
765 for ($j = 0; $j < count($timeStampArr); $j++) {
766 for ($z = 0; $z < count($ydata); $z++) {
767 if (in_array($timeStampArr[$j], $rdates)) {
768 $thekey = array_search($timeStampArr[$j], $rdates);
769 if (isset($ydata[$z][$thekey])) {
770 if ($ydata[$z][$thekey] === false) {
771 $ydata[$z][$thekey] = 0;
773 if ($ydata[$z][$thekey] > $yMax) {
774 $yMax = $ydata[$z][$thekey];
776 echo 'values['.$z.'].push('.$ydata[$z][$thekey].');';
778 echo 'values['.$z.'].push(0);';
781 echo 'values['.$z.'].push(0);';
784 echo 'ticks.push(\''.$tickArr[$j].'\');';
788 case REPORT_TYPE_WEEKLY : {
789 for ($j = 0; $j < count($rdates); $j++) {
790 $wrdates[$j] = date($formatDate, $rdates[$j]);
792 for ($j = 0; $j < count($tickArr); $j++) {
793 for ($z = 0; $z < count($ydata); $z++) {
794 if (in_array($tickArr[$j], $wrdates)) {
795 $thekey = array_search($tickArr[$j], $wrdates);
796 if (isset($ydata[$z][$thekey])) {
797 if ($ydata[$z][$thekey] === false) {
798 $ydata[$z][$thekey] = 0;
800 if ($ydata[$z][$thekey] > $yMax) {
801 $yMax = $ydata[$z][$thekey];
803 echo 'values['.$z.'].push('.$ydata[$z][$thekey].');';
805 echo 'values['.$z.'].push(0);';
808 echo 'values['.$z.'].push(0);';
811 echo 'ticks.push(\''.$tickArr[$j].'\');';
816 for ($z = 0; $z < count($ydata); $z++) {
817 echo 'series.push(values['.$z.']);';
819 echo 'jQuery(document).ready(function(){
820 plot'.$chartid.' = jQuery.jqplot (\'chart'.$chartid.'\', series, {
821 title : \''.$areaname.' ('.strftime('%x', $start).' - '.strftime('%x', $end).') \',
823 tickRenderer: jQuery.jqplot.CanvasAxisTickRenderer,
836 renderer:jQuery.jqplot.BarRenderer,
842 show:true, location: \'ne\',
849 renderer: jQuery.jqplot.CategoryAxisRenderer,
870 echo 'jQuery(window).resize(function() {
871 plot'.$chartid.'.replot();
873 echo '//]]></script>';
874 echo '<div id="chart'.$chartid.'"></div>';
878 function report_toolspiegraph($datatype = 0, $start, $end) {
879 $now = time() - 60*60*24; // 1 day
884 $res = db_query_params ('SELECT g.group_name,count(*) AS count
885 FROM groups g, artifact_group_list agl, artifact a
886 WHERE g.group_id=agl.group_id
887 AND agl.group_artifact_id=a.group_artifact_id
888 AND a.open_date BETWEEN $1 AND $2
891 ORDER BY count DESC',
895 } elseif ($datatype == 5) {
896 $res = db_query_params ('SELECT g.group_name,count(*) AS count
897 FROM groups g, forum_group_list fgl, forum f
898 WHERE g.group_id=fgl.group_id
899 AND fgl.group_forum_id=f.group_forum_id
900 AND f.post_date BETWEEN $1 AND $2
902 ORDER BY count DESC',
905 } elseif ($datatype == 6) {
906 $res = db_query_params ('SELECT g.group_name,count(*) AS count
907 FROM groups g, project_group_list pgl, project_task pt
908 WHERE g.group_id=pgl.group_id
909 AND pgl.group_project_id=pt.group_project_id
910 AND pt.start_date BETWEEN $1 AND $2
912 ORDER BY count DESC',
916 $res = db_query_params ('SELECT g.group_name,count(*) AS count
917 FROM groups g, frs_package fp, frs_release fr, frs_file ff, frs_dlstats_file fdf
918 WHERE g.group_id=fp.group_id
919 AND fp.package_id=fr.package_id
920 AND fr.release_id=ff.release_id
921 AND ff.file_id=fdf.file_id
922 AND (((fdf.month > $1) OR (fdf.month = $1 AND fdf.day >= $2))
923 AND ((fdf.month < $3) OR (fdf.month = $3 AND fdf.day < $4)))
925 ORDER BY count DESC',
926 array (date('Ym',$start),
933 exit_error(db_error(), '');
937 $arr[2] = _('Support Requests');
938 $arr[3] = _('Patches');
939 $arr[4] = _('Feature Requests');
940 $arr[0] = _('Other Trackers');
941 $arr[5] = _('Forum Messages');
942 $arr[6] = _('Tasks');
943 $arr[7] = _('Downloads');
945 $chartid = 'toolspie';
946 if (db_numrows($res)) {
947 echo '<script type="text/javascript">//<![CDATA['."\n";
948 echo 'var data'.$chartid.' = new Array();';
949 while ($row = db_fetch_array($res)) {
950 echo 'data'.$chartid.'.push([\''.htmlentities($row[0]).'\','.$row[1].']);';
952 echo 'var plot'.$chartid.';';
953 echo 'jQuery(document).ready(function(){
954 plot'.$chartid.' = jQuery.jqplot (\'chart'.$chartid.'\', [data'.$chartid.'],
956 title : \''.$arr[$datatype].' ('.strftime('%x', $start) .' - '. strftime('%x', $end) .')\',
958 renderer: jQuery.jqplot.PieRenderer,
960 showDataLabels: true,
961 dataLabels: \'percent\',
966 show:true, location: \'e\',
967 rendererOptions: {numberRows: 11, numberColumns: 2}
972 echo 'jQuery(window).resize(function() {
973 plot'.$chartid.'.replot( { resetAxes: true } );
975 echo '//]]></script>';
976 echo '<div id="chart'.$chartid.'"></div>';
978 echo '<p class="information" >'._('No data to display.').'</p>';
982 function report_timegraph($type = 'site', $area = 'tasks', $start, $end, $id = 0) {
983 global $pie_labels, $pie_vals;
985 $now = time() - 60*60*24; // 1 day
991 $report = new ReportSiteTime($area, $start, $end);
995 $report = new ReportProjectTime($id, $area, $start, $end);
999 $report = new ReportUserTime($id, $area, $start, $end);
1004 $arr['tasks'] = _('By Task');
1005 $arr['category'] = _('By Category');
1006 $arr['subproject'] = _('By Subproject');
1007 $arr['user'] = _('By User');
1009 report_pie_arr($report->labels, $report->getData());
1011 $chartid = 'timegraph';
1012 if (count($pie_vals)) {
1013 echo '<script type="text/javascript">//<![CDATA['."\n";
1014 echo 'var data'.$chartid.' = new Array();';
1015 for ($i = 0; $i < count($pie_vals); $i++) {
1016 echo 'data'.$chartid.'.push([\''.htmlentities($pie_labels[$i]).'\','.$pie_vals[$i].']);';
1018 echo 'var plot'.$chartid.';';
1019 echo 'jQuery(document).ready(function(){
1020 plot'.$chartid.' = jQuery.jqplot (\'chart'.$chartid.'\', [data'.$chartid.'],
1022 title : \''.$arr[$area].' ('.strftime('%x', $start) .' - '. strftime('%x', $end) .')\',
1024 renderer: jQuery.jqplot.PieRenderer,
1026 showDataLabels: true,
1027 dataLabels: \'percent\',
1031 show:true, location: \'e\',
1036 echo 'jQuery(window).resize(function() {
1037 plot'.$chartid.'.replot( { resetAxes: true } );
1039 echo '//]]></script>';
1040 echo '<div id="chart'.$chartid.'"></div>';
1042 echo '<p class="information" >'._('No data to display.').'</p>';
1046 function report_sitetimebargraph($start, $end) {
1047 $now = time() - 60*60*24; // 1 day
1052 $res = db_query_params('SELECT week,sum(hours)
1053 FROM rep_time_tracking
1055 BETWEEN $1 AND $2 GROUP BY week',
1056 array($start, $end));
1058 $report = new Report();
1059 if ($report->isError()) {
1060 exit_error($report->getErrorMessage());
1062 $report->setDates($res,0);
1063 $report->setData($res,1);
1064 $chartid = 'sitetimebargraph';
1065 $areaname = _('Hours Recorded');
1067 $dates[0] = $report->getDates();
1068 $ydata[0] = $report->getData();
1069 $label[0] = _(' Hours');
1070 if (count($ydata[0])) {
1071 echo '<script type="text/javascript">//<![CDATA['."\n";
1072 echo 'var plot'.$chartid.';';
1073 echo 'var values = new Array();';
1074 echo 'var ticks = new Array();';
1075 echo 'var labels = new Array();';
1076 echo 'var series = new Array();';
1077 for ($z = 0; $z < count($ydata); $z++) {
1078 echo 'values['.$z.'] = new Array();';
1079 echo 'labels.push({label:\''.$label[$z].'\'});';
1080 for ($j = 0; $j < count($ydata[$z]); $j++) {
1081 echo 'values['.$z.'].push('.$ydata[$z][$j].')';
1082 echo 'ticks.push('.$dates[$z][$j].')';
1085 for ($z = 0; $z < count($ydata); $z++) {
1086 echo 'series.push(values['.$z.']);';
1088 echo 'jQuery(document).ready(function(){
1089 plot'.$chartid.' = jQuery.jqplot (\'chart'.$chartid.'\', series, {
1090 title : \''.$areaname.' ('.strftime('%x', $start).' - '.strftime('%x', $end).') \',
1092 tickRenderer: jQuery.jqplot.CanvasAxisTickRenderer,
1096 showGridline: false,
1105 renderer:jQuery.jqplot.BarRenderer,
1111 show:true, location: \'ne\',
1118 renderer: jQuery.jqplot.CategoryAxisRenderer,
1127 formatString: \'%d\'
1139 echo 'jQuery(window).resize(function() {
1140 plot'.$chartid.'.replot();
1142 echo '//]]></script>';
1143 echo '<div id="chart'.$chartid.'"></div>';
1145 echo '<p class="information">'._('No data to display.').'</p>';
1150 function report_pm_hbar($id, $values, $ticks, $labels, $stackSeries = false) {
1152 echo '<script type="text/javascript">//<![CDATA['."\n";
1153 echo 'var plot'.$id.';';
1154 echo 'var values'.$id.' = new Array();';
1155 echo 'var ticks'.$id.' = new Array();';
1156 echo 'var labels'.$id.' = new Array();';
1157 echo 'var series'.$id.' = new Array();';
1158 for ($z = 0; $z < count($values); $z++) {
1159 echo 'values'.$id.'['.$z.'] = new Array();';
1160 echo 'labels'.$id.'.push({label:\''.$labels[$z].'\'});';
1162 for ($j = 0; $j < count($ticks); $j++) {
1163 for ($z = 0; $z < count($values); $z++) {
1164 if ($stackSeries !== false && $stackSeries[$j] > $yMax) {
1165 $yMax = $stackSeries[$j];
1166 } elseif ($values[$z][$j] > $yMax) {
1167 $yMax = $values[$z][$j];
1169 echo 'values'.$id.'['.$z.'].push('.$values[$z][$j].');';
1171 echo 'ticks'.$id.'.push(\''.$ticks[$j].'\');';
1173 for ($z = 0; $z < count($values); $z++) {
1174 echo 'series'.$id.'.push(values'.$id.'['.$z.']);';
1176 $height = 40 + 50 * count($ticks);
1178 echo 'jQuery(document).ready(function(){
1179 plot'.$id.' = jQuery.jqplot (\'chart'.$id.'\', series'.$id.', {
1180 height: '.$height.',';
1182 echo ' stackSeries: true,';
1184 echo ' axesDefaults: {
1185 tickRenderer: jQuery.jqplot.CanvasAxisTickRenderer,
1189 showGridline: false,
1198 renderer:jQuery.jqplot.BarRenderer,
1204 barDirection: \'horizontal\',
1209 show:true, location: \'ne\'
1221 formatString: \'%d\'
1225 renderer: jQuery.jqplot.CategoryAxisRenderer,
1231 echo 'jQuery(window).resize(function() {
1232 plot'.$id.'.replot();
1234 echo '//]]></script>';
1235 echo '<div id="chart'.$id.'"></div>';
1240 // c-file-style: "bsd"