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 echo $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($Report, $name='days_adjust', $selected=false) {
71 $names[]=_('Tuesday');
72 $names[]=_('Wednesday');
73 $names[]=_('Thursday');
75 $names[]=_('Saturday');
76 return html_build_select_box_from_arrays ($days,$names,$name,$selected,false);
78 // return html_build_select_box_from_arrays (array_reverse(array_values($Report->adjust_days)),array_reverse(array_keys($Report->adjust_days)),$name,$selected,false);
81 function report_months_box($Report, $name='month', $selected=false) {
82 $arr =& $Report->getMonthStartArr();
85 for ($i=0; $i<count($arr); $i++) {
86 $arr2[$i]=date(_('Y-m'),$arr[$i]);
89 return html_build_select_box_from_arrays ($arr,$arr2,$name,$selected,false);
92 function report_useract_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_user_act_daily 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_user_act_daily WHERE user_id=users.user_id)) ORDER BY lastname',
102 return html_build_select_box($res, $name, $selected, false);
105 function report_usertime_box($name='dev_id', $selected='1', $start_with='') {
107 $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',
109 strtolower("$start_with%"),
110 strtolower("$start_with%"))) ;
112 $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',
115 return html_build_select_box($res, $name, $selected, false);
118 function report_group_box($name='g_id', $selected='1') {
120 $res = db_query_params ('SELECT group_id,group_name FROM groups WHERE status=$1 ORDER BY group_name',
122 return html_build_select_box($res, $name, $selected, false);
125 function report_area_box($name='area', $selected='1', $Group=false) {
129 $use_tracker = $Group->usesTracker();
130 $use_forum = $Group->usesForum();
131 $use_docman = $Group->usesDocman();
132 $use_pm = $Group->usesPM();
133 $use_frs = $Group->usesFRS();
135 $use_tracker = forge_get_config('use_tracker');
136 $use_forum = forge_get_config('use_forum');
137 $use_docman = forge_get_config('use_docman');
138 $use_pm = forge_get_config('use_pm');
139 $use_frs = forge_get_config('use_frs');
143 $arr2[]=_('Tracker');
159 $arr2[]=_('Downloads');
162 $arr2[]=_('Page Views');
164 if (is_object($Group) && $Group->getID()) {
165 $hookParams['group'] = $Group->getID();
166 $hookParams['group_id'] = $Group->getID();
167 $hookParams['show'] = array('none'); // No display => No compute this time.
168 $hookParams['ids'] = &$arr;
169 $hookParams['texts'] = &$arr2;
170 plugin_hook ("activity", $hookParams) ;
173 return html_build_select_box_from_arrays ($arr,$arr2,$name,$selected,false);
176 function report_tracker_box($name='datatype', $selected='1') {
177 if (forge_get_config('use_tracker')) {
181 $arr[]=_('Feature Requests');
182 $arr[]=_('Other Trackers');
189 if (forge_get_config('use_forum')) {
190 $arr[]=_('Forum Messages');
193 if (forge_get_config('use_pm')) {
197 if (forge_get_config('use_frs')) {
198 $arr[]=_('Downloads');
201 return html_build_select_box_from_arrays ($arr2,$arr,$name,$selected,false);
204 function report_time_category_box($name='category',$selected=false) {
205 global $report_time_category_res;
206 if (!$report_time_category_res) {
207 $report_time_category_res = db_query_params ('SELECT * FROM rep_time_category',
210 return html_build_select_box($report_time_category_res,$name,$selected,false);
214 // Takes an array of labels and an array values and removes vals < 2% and sets up an "other"
216 function report_pie_arr($labels, $vals, $format=1) {
217 global $pie_labels,$pie_vals;
220 //first get sum of all values
221 for ($i=0; $i<count($vals); $i++) {
225 //now prune out vals where < 2%
227 for ($i=0; $i<count($vals); $i++) {
228 if (($vals[$i]/$total) < .02) {
231 $pie_labels[]=utf8_decode(util_unconvert_htmlspecialchars($labels[$i]))." (". number_format($vals[$i],$format) .") ";
232 $pie_vals[]=$vals[$i];
236 $pie_labels[]=_('Other')." (". number_format($rem,$format) .") ";
242 function report_package_box($group_id, $name='dev_id', $selected='') {
244 $res = db_query_params ('SELECT package_id, name FROM frs_package WHERE frs_package.group_id = $1',
246 return html_build_select_box($res, $name, $selected, false);
249 function trackeract_graph($group_id, $area, $SPAN, $start, $end, $atid) {
254 if (!strlen($area)) {
255 echo '<p class="information">'._('No selected area.').'</p>';
258 $report = new ReportTrackerAct($SPAN, $group_id, $atid, $start, $end);
259 if ($report->isError()) {
260 echo '<p class="error">'.$report->getErrorMessage().'</p>';
263 $rdates = $report->getRawDates();
267 $ydata[] =& $report->getAverageTimeData();
268 $label[] = _('Avg Time Open (in days)');
269 $ydata[] =& $report->getOpenCountData();
270 $label[] = _('Total Opened');
271 $ydata[] =& $report->getStillOpenCountData();
272 $label[] = _('Total Still Open');
273 $chartid = 'projecttrackergraph_'.$group_id;
275 echo '<script type="text/javascript">//<![CDATA['."\n";
276 echo 'var values = new Array();';
277 echo 'var ticks = new Array();';
278 echo 'var labels = new Array();';
279 echo 'var series = new Array();';
280 echo 'var plot'.$chartid.';';
281 for ($z = 0; $z < count($ydata); $z++) {
282 echo 'values['.$z.'] = new Array();';
283 echo 'labels.push({label:\''.$label[$z].'\'});';
287 case REPORT_TYPE_MONTHLY : {
291 case REPORT_TYPE_WEEKLY : {
296 for ($j = 0; $j < count($rdates); $j++) {
297 for ($z = 0; $z < count($ydata); $z++) {
298 if (isset($ydata[$z][$j])) {
299 if ($ydata[$z][$j] === false || $ydata[$z][$j] === NULL) {
302 if ($ydata[$z][$j] > $yMax) {
303 $yMax = $ydata[$z][$j];
305 echo 'values['.$z.'].push('.$ydata[$z][$j].');';
307 echo 'values['.$z.'].push(0);';
310 $tickArr[] = date($formatDate, $rdates[$j]);
311 echo 'ticks.push(\''.$tickArr[$j].'\');';
313 for ($z = 0; $z < count($ydata); $z++) {
314 echo 'series.push(values['.$z.']);';
316 echo 'jQuery(document).ready(function(){
317 plot'.$chartid.' = jQuery.jqplot (\'chart'.$chartid.'\', series, {
318 title : \''.utf8_decode(_('Tracker Activity')).' ( '.strftime('%x',$start).' - '.strftime('%x',$end).') \',
332 renderer:jQuery.jqplot.BarRenderer,
338 show:true, location: \'ne\',
345 renderer: jQuery.jqplot.CategoryAxisRenderer,
364 echo 'jQuery(window).resize(function() {
365 plot'.$chartid.'.replot();
367 echo '//]]></script>';
368 echo '<div id="chart'.$chartid.'"></div>';
372 function trackerpie_graph($group_id, $area, $SPAN, $start, $end, $atid) {
377 if (!strlen($area)) {
378 echo '<p class="information">'._('No selected area.').'</p>';
381 $report = new ReportTrackerAct($SPAN, $group_id, $atid, $start, $end);
382 if ($report->isError()) {
383 echo '<p class="error">'.$report->getErrorMessage().'</p>';
388 $dbres = $report->getPerAssignee($atid, $start, $end);
389 $areaname = _('Per assignee');
393 $chartid = 'projecttrackerpie_'.$group_id;
394 echo '<script type="text/javascript">//<![CDATA['."\n";
395 echo 'var plot'.$chartid.';';
396 echo 'var data = new Array();';
397 while ($row = db_fetch_array($dbres)) {
398 echo 'data.push([\''.htmlentities($row[0]).'\',\''.$row[1].'\']);';
400 echo 'jQuery(document).ready(function(){
401 plot'.$chartid.' = jQuery.jqplot (\'chart'.$chartid.'\', [data],
403 title : \''.utf8_decode($areaname." (".strftime('%x',$start) ." - ". strftime('%x',$end) .")").'\',
405 // Make this a pie chart.
406 renderer: jQuery.jqplot.PieRenderer,
408 // Put data labels on the pie slices.
409 // By default, labels show the percentage of the slice.
410 showDataLabels: true,
411 dataLabels: \'percent\',
415 show:true, location: \'e\',
420 echo 'jQuery(window).resize(function() {
421 plot'.$chartid.'.replot( { resetAxes: true } );
423 echo '//]]></script>';
424 echo '<div id="chart'.$chartid.'"></div>';
428 function report_graph($type, $SPAN, $start, $end) {
429 $now = time() - 60*24*24;
435 $report = new ReportUserCum($SPAN, $start, $end);
436 $label[0] = _('Cumulative Users');
440 $report = new ReportUserAdded($SPAN, $start, $end);
441 $label[0] = _('Users Added');
445 $report = new ReportGroupAdded($SPAN, $start, $end);
446 $label[0] = _('Projects Added');
450 $report = new ReportGroupCum($SPAN, $start, $end);
451 $label[0] = _('Cumulative Projects');
456 if ($report->isError()) {
457 echo '<p class="error">'.$report->getErrorMessage().'</p>';
460 $rdates = $report->getRawDates();
462 echo '<p class="error">'._('No data to display.').'</p>';
465 $ydata[0] = $report->getData();
467 if ($SPAN == REPORT_TYPE_DAILY) {
469 $formatDate = 'Y/m/d';
471 while ($looptime < $end) {
472 $timeStampArr[$i] = $looptime;
473 $timeStampArrFormat[$i] = date($formatDate, $looptime);
474 $looptime += REPORT_DAY_SPAN;
477 } elseif ($SPAN == REPORT_TYPE_WEEKLY) {
478 $timeStampArr = $report->getWeekStartArr();
479 $timeStampArrFormat = $report->getWeekStartArrFormat();
481 } elseif ($SPAN == REPORT_TYPE_MONTHLY) {
482 $timeStampArr = $report->getMonthStartArr();
483 $timeStampArrFormat = $report->getMonthStartArrFormat();
487 $chartid = '_useradded';
489 echo '<script type="text/javascript">//<![CDATA['."\n";
490 echo 'var plot'.$chartid.';';
491 echo 'var '.$chartid.'values = new Array();';
492 echo 'var '.$chartid.'labels = new Array();';
493 echo 'var '.$chartid.'series = new Array();';
494 for ($z = 0; $z < count($ydata); $z++) {
495 echo $chartid.'values['.$z.'] = new Array();';
496 echo $chartid.'labels.push({label:\''.$label[$z].'\'});';
498 case REPORT_TYPE_DAILY :
499 case REPORT_TYPE_MONTHLY : {
500 for ($j = 0; $j < count($timeStampArr); $j++) {
501 if (in_array($timeStampArr[$j], $rdates)) {
502 $thekey = array_search($timeStampArr[$j], $rdates);
503 if (isset($ydata[$z][$thekey])) {
504 if ($ydata[$z][$thekey] === false) {
505 $ydata[$z][$thekey] = 0;
507 if ($ydata[$z][$thekey] > $yMax) {
508 $yMax = $ydata[$z][$thekey];
510 echo 'var '.$chartid.'datevalues = '.$ydata[$z][$thekey].';';
512 echo 'var '.$chartid.'datevalues = 0;';
515 echo 'var '.$chartid.'datevalues = 0;';
517 echo 'var '.$chartid.'date = \''.$timeStampArrFormat[$j].'\';';
518 echo $chartid.'values['.$z.'].push(['.$chartid.'date, '.$chartid.'datevalues]);';
522 case REPORT_TYPE_WEEKLY : {
523 for ($j = 0; $j < count($rdates); $j++) {
524 $wrdates[$j] = date($formatDate, $rdates[$j]);
526 for ($j = 0; $j < count($timeStampArr); $j++) {
527 if (in_array($timeStampArrFormat[$j], $wrdates)) {
528 $thekey = array_search($timeStampArr[$j], $wrdates);
529 if (isset($ydata[$z][$thekey])) {
530 if ($ydata[$z][$thekey] === false) {
531 $ydata[$z][$thekey] = 0;
533 if ($ydata[$z][$thekey] > $yMax) {
534 $yMax = $ydata[$z][$thekey];
536 echo 'var '.$chartid.'datevalues = '.$ydata[$z][$thekey].';';
538 echo 'var '.$chartid.'datevalues = 0;';
541 echo 'var '.$chartid.'datevalues = 0;';
543 echo 'var '.$chartid.'date = \''.$timeStampArrFormat[$j].'\';';
544 echo $chartid.'values['.$z.'].push(['.$chartid.'date, '.$chartid.'datevalues]);';
550 for ($z = 0; $z < count($ydata); $z++) {
551 echo $chartid.'series.push('.$chartid.'values['.$z.']);';
553 echo 'jQuery(document).ready(function(){
554 plot'.$chartid.' = jQuery.jqplot (\'chart'.$chartid.'\', '.$chartid.'series, {
556 tickRenderer: jQuery.jqplot.CanvasAxisTickRenderer,
563 show:true, location: \'ne\',
570 renderer: jQuery.jqplot.CategoryAxisRenderer,
571 label: \''.$label[0].'\',
590 echo 'jQuery(window).resize(function() {
591 plot'.$chartid.'.replot( { resetAxes: true } );
593 echo '//]]></script>';
594 echo '<div id="chart'.$chartid.'"></div>';
598 function report_actgraph($type, $SPAN, $start, $end, $id, $area) {
599 $now = time() - 60*24*24;
605 $report = new ReportUserAct($SPAN, $id, $start, $end);
606 $u =& user_get_object($id);
607 if (!$u || $u->isError()) {
608 exit_error(_("Could Not Get User"));
613 $report = new ReportProjectAct($SPAN, $id, $start, $end);
614 $g = group_get_object($id);
615 if (!$g || !is_object($g)) {
617 } elseif ($g->isError()) {
618 exit_error($g->getErrorMessage(), '');
623 $report = new ReportSiteAct($SPAN, $start, $end);
628 if ($report->isError()) {
629 echo '<p class="error">'.$report->getErrorMessage().'</p>';
632 $rdates = $report->getRawDates();
634 echo '<p class="error">'._('No data to display.').'</p>';
640 if ($SPAN == REPORT_TYPE_DAILY) {
643 while ($looptime < $end) {
644 $timeStampArr[$i] = $looptime;
645 $looptime += REPORT_DAY_SPAN;
648 $formatDate = 'Y/m/d';
649 } elseif ($SPAN == REPORT_TYPE_WEEKLY) {
650 $timeStampArr = $report->getWeekStartArr();
652 } elseif ($SPAN == REPORT_TYPE_MONTHLY) {
653 $timeStampArr = $report->getMonthStartArr();
657 $initialSizeOfTimeStampArr = count($timeStampArr);
658 for ($j = 0; $j < $initialSizeOfTimeStampArr; $j++) {
659 if ($timeStampArr[$j] < $start || $timeStampArr[$j] >= $end) {
660 unset($timeStampArr[$j]);
664 $timeStampArr = array_values($timeStampArr);
665 for ($j = 0; $j < count($timeStampArr); $j++) {
666 $tickArr[] = date($formatDate, $timeStampArr[$j]);
671 $ydata[] =& $report->getDocs();
672 $areaname = _('Docs');
673 $label[] = _('Documents');
677 $ydata[] =& $report->getDownloads();
678 $areaname = _('Downloads');
679 $label[] = _('Downloads');
683 $ydata[] =& $report->getForum();
684 $areaname = _('Forums');
685 $label[] = _('Forums');
689 $ydata[] =& $report->getPageViews();
690 $areaname = _('Page views');
691 $label[] = _('Page views');
695 $ydata[] =& $report->getTaskOpened();
696 $ydata[] =& $report->getTaskClosed();
697 $areaname = _('Tasks');
698 $label[] = _('Task open');
699 $label[] = _('Task close');
703 $ydata[] =& $report->getTrackerOpened();
704 $ydata[] =& $report->getTrackerClosed();
705 $areaname = _('Trackers');
706 $label[] = _('Tracker items opened');
707 $label[] = _('Tracker items closed');
716 $hookParams['group'] = $id;
717 $hookParams['results'] = &$results;
718 $hookParams['show'] = &$show;
719 $hookParams['begin'] = $start;
720 $hookParams['end'] = $end;
721 $hookParams['ids'] = &$ids;
722 $hookParams['texts'] = &$texts;
723 plugin_hook("activity", $hookParams);
725 $areaname = $texts[0];
726 $label[] = $texts[0];
728 foreach ($results as $arr) {
729 $dd = date($formatDate, $arr['activity_date']);
731 case REPORT_TYPE_MONTHLY : {
732 $d = mktime(0, 0, 0, substr($dd, 5, 2) , 1, substr($dd, 0, 4));
735 case REPORT_TYPE_WEEKLY: {
736 $d = strtotime(substr($dd, 0, 4).'-W'.substr($dd, 5, 2));
739 case REPORT_TYPE_DAILY: {
740 $d = mktime(0, 0, 0, substr($dd, 5, 2) , substr($dd, 8, 2), substr($dd, 0, 4));
747 // Now, stores the values in the ydata array for the graph.
750 foreach ($rdates as $d) {
751 $ydata[0][$i++] = isset($sum[$d]) ? $sum[$d] : 0;
757 $chartid = 'report_actgraph_'.$id;
759 echo '<script type="text/javascript">//<![CDATA['."\n";
760 echo 'var plot'.$chartid.';';
761 echo 'var values = new Array();';
762 echo 'var ticks = new Array();';
763 echo 'var labels = new Array();';
764 echo 'var series = new Array();';
765 for ($z = 0; $z < count($ydata); $z++) {
766 echo 'values['.$z.'] = new Array();';
767 echo 'labels.push({label:\''.$label[$z].'\'});';
770 case REPORT_TYPE_DAILY :
771 case REPORT_TYPE_MONTHLY : {
772 for ($j = 0; $j < count($timeStampArr); $j++) {
773 for ($z = 0; $z < count($ydata); $z++) {
774 if (in_array($timeStampArr[$j], $rdates)) {
775 $thekey = array_search($timeStampArr[$j], $rdates);
776 if (isset($ydata[$z][$thekey])) {
777 if ($ydata[$z][$thekey] === false) {
778 $ydata[$z][$thekey] = 0;
780 if ($ydata[$z][$thekey] > $yMax) {
781 $yMax = $ydata[$z][$thekey];
783 echo 'values['.$z.'].push('.$ydata[$z][$thekey].');';
785 echo 'values['.$z.'].push(0);';
788 echo 'values['.$z.'].push(0);';
791 echo 'ticks.push(\''.$tickArr[$j].'\');';
795 case REPORT_TYPE_WEEKLY : {
796 for ($j = 0; $j < count($rdates); $j++) {
797 $wrdates[$j] = date($formatDate, $rdates[$j]);
799 for ($j = 0; $j < count($tickArr); $j++) {
800 for ($z = 0; $z < count($ydata); $z++) {
801 if (in_array($tickArr[$j], $wrdates)) {
802 $thekey = array_search($tickArr[$j], $wrdates);
803 if (isset($ydata[$z][$thekey])) {
804 if ($ydata[$z][$thekey] === false) {
805 $ydata[$z][$thekey] = 0;
807 if ($ydata[$z][$thekey] > $yMax) {
808 $yMax = $ydata[$z][$thekey];
810 echo 'values['.$z.'].push('.$ydata[$z][$thekey].');';
812 echo 'values['.$z.'].push(0);';
815 echo 'values['.$z.'].push(0);';
818 echo 'ticks.push(\''.$tickArr[$j].'\');';
823 for ($z = 0; $z < count($ydata); $z++) {
824 echo 'series.push(values['.$z.']);';
826 echo 'jQuery(document).ready(function(){
827 plot'.$chartid.' = jQuery.jqplot (\'chart'.$chartid.'\', series, {
828 title : \''.utf8_decode($areaname).' ( '.strftime('%x', $start).' - '.strftime('%x', $end).') \',
830 tickRenderer: jQuery.jqplot.CanvasAxisTickRenderer,
843 renderer:jQuery.jqplot.BarRenderer,
849 show:true, location: \'ne\',
856 renderer: jQuery.jqplot.CategoryAxisRenderer,
877 echo 'jQuery(window).resize(function() {
878 plot'.$chartid.'.replot();
880 echo '//]]></script>';
881 echo '<div id="chart'.$chartid.'"></div>';
885 function report_toolspiegraph($datatype = 0, $start, $end) {
886 $now = time() - 60*24*24;
891 $res = db_query_params ('SELECT g.group_name,count(*) AS count
892 FROM groups g, artifact_group_list agl, artifact a
893 WHERE g.group_id=agl.group_id
894 AND agl.group_artifact_id=a.group_artifact_id
895 AND a.open_date BETWEEN $1 AND $2
898 ORDER BY count DESC',
902 } elseif ($datatype == 5) {
903 $res = db_query_params ('SELECT g.group_name,count(*) AS count
904 FROM groups g, forum_group_list fgl, forum f
905 WHERE g.group_id=fgl.group_id
906 AND fgl.group_forum_id=f.group_forum_id
907 AND f.post_date BETWEEN $1 AND $2
909 ORDER BY count DESC',
912 } elseif ($datatype == 6) {
913 $res = db_query_params ('SELECT g.group_name,count(*) AS count
914 FROM groups g, project_group_list pgl, project_task pt
915 WHERE g.group_id=pgl.group_id
916 AND pgl.group_project_id=pt.group_project_id
917 AND pt.start_date BETWEEN $1 AND $2
919 ORDER BY count DESC',
923 $res = db_query_params ('SELECT g.group_name,count(*) AS count
924 FROM groups g, frs_package fp, frs_release fr, frs_file ff, frs_dlstats_file fdf
925 WHERE g.group_id=fp.group_id
926 AND fp.package_id=fr.package_id
927 AND fr.release_id=ff.release_id
928 AND ff.file_id=fdf.file_id
929 AND (((fdf.month > $1) OR (fdf.month = $1 AND fdf.day >= $2))
930 AND ((fdf.month < $3) OR (fdf.month = $3 AND fdf.day < $4)))
932 ORDER BY count DESC',
933 array (date('Ym',$start),
940 exit_error(db_error(), '');
944 $arr[2] = 'Support Requests';
946 $arr[4] = 'Feature Requests';
947 $arr[0] = 'Other Trackers';
948 $arr[5] = 'Forum Messages';
950 $arr[7] = 'Downloads';
952 $chartid = 'toolspie';
953 if (db_numrows($res)) {
954 echo '<script type="text/javascript">//<![CDATA['."\n";
955 echo 'var data'.$chartid.' = new Array();';
956 while ($row = db_fetch_array($res)) {
957 echo 'data'.$chartid.'.push([\''.htmlentities($row[0]).'\','.$row[1].']);';
959 echo 'var plot'.$chartid.';';
960 echo 'jQuery(document).ready(function(){
961 plot'.$chartid.' = jQuery.jqplot (\'chart'.$chartid.'\', [data'.$chartid.'],
963 title : \''.$arr[$datatype].' ('.strftime('%x', $start) .' - '. strftime('%x', $end) .')\',
965 renderer: jQuery.jqplot.PieRenderer,
967 showDataLabels: true,
968 dataLabels: \'percent\',
973 show:true, location: \'e\',
978 echo 'jQuery(window).resize(function() {
979 plot'.$chartid.'.replot( { resetAxes: true } );
981 echo '//]]></script>';
982 echo '<div id="chart'.$chartid.'"></div>';
984 echo '<p class="information" >'._('No data to display.').'</p>';
988 function report_timegraph($type = 'site', $area = 'tasks', $start, $end, $id = 0) {
989 global $pie_labels, $pie_vals;
991 $now = time() - 60*24*24;
997 $report = new ReportSiteTime($area, $start, $end);
1001 $report = new ReportProjectTime($id, $area, $start, $end);
1005 $report = new ReportUserTime($id, $area, $start, $end);
1010 $arr['tasks']='By Task';
1011 $arr['category']='By Category';
1012 $arr['subproject']='By Subproject';
1013 $arr['user']='By User';
1015 report_pie_arr($report->labels, $report->getData());
1017 $chartid = 'timegraph';
1018 if (count($pie_vals)) {
1019 echo '<script type="text/javascript">//<![CDATA['."\n";
1020 echo 'var data'.$chartid.' = new Array();';
1021 for ($i = 0; $i < count($pie_vals); $i++) {
1022 echo 'data'.$chartid.'.push([\''.htmlentities($pie_labels[0]).'\',\''.$pie_vals[1].'\']);';
1024 echo 'var plot'.$chartid.';';
1025 echo 'jQuery(document).ready(function(){
1026 plot'.$chartid.' = jQuery.jqplot (\'chart'.$chartid.'\', [data'.$chartid.'],
1028 title : \''.$arr[$area].' ('.strftime('%x', $start) .' - '. strftime('%x', $end) .')\',
1030 renderer: jQuery.jqplot.PieRenderer,
1032 showDataLabels: true,
1033 dataLabels: \'percent\',
1037 show:true, location: \'e\',
1042 echo 'jQuery(window).resize(function() {
1043 plot'.$chartid.'.replot( { resetAxes: true } );
1045 echo '//]]></script>';
1046 echo '<div id="chart'.$chartid.'"></div>';
1048 echo '<p class="information" >'._('No data to display.').'</p>';
1052 function report_sitetimebargraph($start, $end) {
1053 $now = time() - 60*24*24;
1058 $res = db_query_params('SELECT week,sum(hours)
1059 FROM rep_time_tracking
1061 BETWEEN $1 AND $2 GROUP BY week',
1062 array($start, $end));
1064 $report = new Report();
1065 if ($report->isError()) {
1066 exit_error($report->getErrorMessage());
1068 $report->setDates($res,0);
1069 $report->setData($res,1);
1070 $chartid = 'sitetimebargraph';
1071 $areaname = _('Hours Recorded');
1073 $dates[0] = $report->getDates();
1074 $ydata[0] = $report->getData();
1075 $label[0] = _(' Hours');
1076 if (count($ydata[0])) {
1077 echo '<script type="text/javascript">//<![CDATA['."\n";
1078 echo 'var plot'.$chartid.';';
1079 echo 'var values = new Array();';
1080 echo 'var ticks = new Array();';
1081 echo 'var labels = new Array();';
1082 echo 'var series = new Array();';
1083 for ($z = 0; $z < count($ydata); $z++) {
1084 echo 'values['.$z.'] = new Array();';
1085 echo 'labels.push({label:\''.$label[$z].'\'});';
1086 for ($j = 0; $j < count($ydata[$z]); $j++) {
1087 echo 'values['.$z.'].push('.$ydata[$z][$j].')';
1088 echo 'ticks.push('.$dates[$z][$j].')';
1091 for ($z = 0; $z < count($ydata); $z++) {
1092 echo 'series.push(values['.$z.']);';
1094 echo 'jQuery(document).ready(function(){
1095 plot'.$chartid.' = jQuery.jqplot (\'chart'.$chartid.'\', series, {
1096 title : \''.utf8_decode($areaname).' ( '.strftime('%x', $start).' - '.strftime('%x', $end).') \',
1098 tickRenderer: jQuery.jqplot.CanvasAxisTickRenderer,
1102 showGridline: false,
1111 renderer:jQuery.jqplot.BarRenderer,
1117 show:true, location: \'ne\',
1124 renderer: jQuery.jqplot.CategoryAxisRenderer,
1133 formatString: \'%d\'
1145 echo 'jQuery(window).resize(function() {
1146 plot'.$chartid.'.replot();
1148 echo '//]]></script>';
1149 echo '<div id="chart'.$chartid.'"></div>';
1151 echo '<p class="information">'._('No data to display').'</p>';
1156 function report_pm_hbar($id, $values, $ticks, $labels, $stackSeries = false) {
1158 echo '<script type="text/javascript">//<![CDATA['."\n";
1159 echo 'var plot'.$id.';';
1160 echo 'var values'.$id.' = new Array();';
1161 echo 'var ticks'.$id.' = new Array();';
1162 echo 'var labels'.$id.' = new Array();';
1163 echo 'var series'.$id.' = new Array();';
1164 for ($z = 0; $z < count($values); $z++) {
1165 echo 'values'.$id.'['.$z.'] = new Array();';
1166 echo 'labels'.$id.'.push({label:\''.$labels[$z].'\'});';
1168 for ($j = 0; $j < count($ticks); $j++) {
1169 for ($z = 0; $z < count($values); $z++) {
1170 if ($stackSeries !== false && $stackSeries[$j] > $yMax) {
1171 $yMax = $stackSeries[$j];
1172 } elseif ($values[$z][$j] > $yMax) {
1173 $yMax = $values[$z][$j];
1175 echo 'values'.$id.'['.$z.'].push('.$values[$z][$j].');';
1177 echo 'ticks'.$id.'.push(\''.$ticks[$j].'\');';
1179 for ($z = 0; $z < count($values); $z++) {
1180 echo 'series'.$id.'.push(values'.$id.'['.$z.']);';
1182 $height = 40 + 50 * count($ticks);
1184 echo 'jQuery(document).ready(function(){
1185 plot'.$id.' = jQuery.jqplot (\'chart'.$id.'\', series'.$id.', {
1186 height: '.$height.',';
1188 echo ' stackSeries: true,';
1190 echo ' axesDefaults: {
1191 tickRenderer: jQuery.jqplot.CanvasAxisTickRenderer,
1195 showGridline: false,
1204 renderer:jQuery.jqplot.BarRenderer,
1210 barDirection: \'horizontal\',
1215 show:true, location: \'ne\'
1227 formatString: \'%d\'
1231 renderer: jQuery.jqplot.CategoryAxisRenderer,
1237 echo 'jQuery(window).resize(function() {
1238 plot'.$id.'.replot();
1240 echo '//]]></script>';
1241 echo '<div id="chart'.$id.'"></div>';
1246 // c-file-style: "bsd"