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,2015-2016, 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() {
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 = false;
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_id'] = $Group->getID();
157 $hookParams['show'] = array('none'); // No display => No compute this time.
158 $hookParams['ids'] = &$arr;
159 $hookParams['texts'] = &$arr2;
160 plugin_hook ("activity", $hookParams) ;
163 return html_build_select_box_from_arrays ($arr,$arr2,$name,$selected,false);
166 function report_tracker_box($name='datatype', $selected='1') {
169 if (forge_get_config('use_tracker')) {
173 $arr[]=_('Feature Requests');
174 $arr[]=_('Other Trackers');
181 if (forge_get_config('use_forum')) {
182 $arr[]=_('Forum Messages');
185 if (forge_get_config('use_pm')) {
189 if (forge_get_config('use_frs')) {
190 $arr[]=_('Downloads');
193 return html_build_select_box_from_arrays ($arr2,$arr,$name,$selected,false);
196 function report_time_category_box($name='category',$selected=false) {
197 global $report_time_category_res;
198 if (!$report_time_category_res) {
199 $report_time_category_res = db_query_params ('SELECT * FROM rep_time_category', array());
201 return html_build_select_box($report_time_category_res,$name,$selected,false);
205 // Takes an array of labels and an array values and removes vals < 2% and sets up an "other"
207 function report_pie_arr($labels, $vals, $format=1) {
208 global $pie_labels,$pie_vals;
211 //first get sum of all values
212 for ($i=0; $i<count($vals); $i++) {
216 //now prune out vals where < 2%
218 for ($i=0; $i<count($vals); $i++) {
219 if (($vals[$i]/$total) < .02) {
222 $pie_labels[]=util_unconvert_htmlspecialchars($labels[$i])." (". number_format($vals[$i],$format) .") ";
223 $pie_vals[]=$vals[$i];
227 $pie_labels[]=_('Other')." (". number_format($rem,$format) .") ";
232 function report_package_box($group_id, $name='dev_id', $selected='') {
234 $res = db_query_params ('SELECT package_id, name FROM frs_package WHERE frs_package.group_id = $1',
236 return html_build_select_box($res, $name, $selected, false);
239 function trackeract_graph($group_id, $area, $SPAN, $start, $end, $atid) {
245 if (!strlen($area)) {
246 echo $HTML->information(_('No selected area.'));
249 $report = new ReportTrackerAct($SPAN, $group_id, $atid, $start, $end);
250 if ($report->isError()) {
251 echo $HTML->error_msg($report->getErrorMessage());
254 $rdates = $report->getRawDates();
258 $ydata[] =& $report->getAverageTimeData();
259 $label[] = _('Avg Time Open (in days)');
260 $ydata[] =& $report->getOpenCountData();
261 $label[] = _('Total Opened');
262 $ydata[] =& $report->getStillOpenCountData();
263 $label[] = _('Total Still Open');
264 $chartid = 'projecttrackergraph_'.$group_id;
266 echo '<script type="text/javascript">//<![CDATA['."\n";
267 echo 'var values = new Array();';
268 echo 'var ticks = new Array();';
269 echo 'var labels = new Array();';
270 echo 'var series = new Array();';
271 echo 'var plot'.$chartid.';';
272 for ($z = 0; $z < count($ydata); $z++) {
273 echo 'values['.$z.'] = new Array();';
274 echo 'labels.push({label:\''.$label[$z].'\'});';
278 case REPORT_TYPE_MONTHLY : {
282 case REPORT_TYPE_WEEKLY : {
287 for ($j = 0; $j < count($rdates); $j++) {
288 for ($z = 0; $z < count($ydata); $z++) {
289 if (isset($ydata[$z][$j])) {
290 if ($ydata[$z][$j] === false || $ydata[$z][$j] === NULL) {
293 if ($ydata[$z][$j] > $yMax) {
294 $yMax = $ydata[$z][$j];
296 echo 'values['.$z.'].push('.$ydata[$z][$j].');';
298 echo 'values['.$z.'].push(0);';
301 $tickArr[] = date($formatDate, $rdates[$j]);
302 echo 'ticks.push(\''.$tickArr[$j].'\');';
304 for ($z = 0; $z < count($ydata); $z++) {
305 echo 'series.push(values['.$z.']);';
307 echo 'jQuery(document).ready(function(){
308 plot'.$chartid.' = jQuery.jqplot (\'chart'.$chartid.'\', series, {
322 renderer:jQuery.jqplot.BarRenderer,
328 show:true, location: \'ne\',
335 renderer: jQuery.jqplot.CategoryAxisRenderer,
354 echo 'jQuery(window).resize(function() {
355 plot'.$chartid.'.replot();
357 echo '//]]></script>';
358 echo $HTML->html_chartid('chart'.$chartid, _('Tracker Activity').' ('.date(_('Y-m-d'), $start).' - '.date(_('Y-m-d'), $end).')');
362 function trackerpie_graph($group_id, $area, $SPAN, $start, $end, $atid) {
368 if (!strlen($area)) {
369 echo $HTML->information(_('No selected area.'));
372 $report = new ReportTrackerAct($SPAN, $group_id, $atid, $start, $end);
373 if ($report->isError()) {
374 echo $HTML->error_msg($report->getErrorMessage());
379 $dbres = $report->getPerAssignee($atid, $start, $end);
380 $areaname = _('Per assignee');
384 if (db_numrows($dbres)) {
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],
396 // Make this a pie chart.
397 renderer: jQuery.jqplot.PieRenderer,
399 // Put data labels on the pie slices.
400 // By default, labels show the percentage of the slice.
401 showDataLabels: true,
405 show:true, location: \'e\',
410 echo 'jQuery(window).resize(function() {
411 plot'.$chartid.'.replot( { resetAxes: true } );
413 echo '//]]></script>';
414 echo $HTML->html_chartid('chart'.$chartid, $areaname.' ('.date(_('Y-m-d'), $start).' - '.date(_('Y-m-d'), $end).')');
416 echo $HTML->information(_('No data to display'));
421 function report_graph($type, $SPAN, $start, $end) {
423 $now = time() - 60*60*24; // 1 day
429 $report = new ReportUserCum($SPAN, $start, $end);
430 $label[0] = _('Cumulative Users');
434 $report = new ReportUserAdded($SPAN, $start, $end);
435 $label[0] = _('Users Added');
439 $report = new ReportGroupAdded($SPAN, $start, $end);
440 $label[0] = _('Projects Added');
444 $report = new ReportGroupCum($SPAN, $start, $end);
445 $label[0] = _('Cumulative Projects');
450 if ($report->isError()) {
451 echo $HTML->error_msg($report->getErrorMessage());
454 $rdates = $report->getRawDates();
456 echo $HTML->information(_('No data to display.'));
459 $ydata[0] = $report->getData();
461 if ($SPAN == REPORT_TYPE_DAILY) {
463 $formatDate = 'Y-m-d';
465 while ($looptime < $end) {
466 $timeStampArr[$i] = $looptime;
467 $timeStampArrFormat[$i] = date($formatDate, $looptime);
468 $looptime += REPORT_DAY_SPAN;
471 } elseif ($SPAN == REPORT_TYPE_WEEKLY) {
472 $timeStampArr = $report->getWeekStartArr();
473 $timeStampArrFormat = $report->getWeekStartArrFormat();
475 } elseif ($SPAN == REPORT_TYPE_MONTHLY) {
476 $timeStampArr = $report->getMonthStartArr();
477 $timeStampArrFormat = $report->getMonthStartArrFormat();
481 $chartid = '_useradded';
483 echo '<script type="text/javascript">//<![CDATA['."\n";
484 echo 'var plot'.$chartid.';';
485 echo 'var '.$chartid.'values = new Array();';
486 echo 'var '.$chartid.'labels = new Array();';
487 echo 'var '.$chartid.'series = new Array();';
488 for ($z = 0; $z < count($ydata); $z++) {
489 echo $chartid.'values['.$z.'] = new Array();';
490 echo $chartid.'labels.push({label:\''.$label[$z].'\'});';
492 case REPORT_TYPE_DAILY:
493 case REPORT_TYPE_MONTHLY: {
494 for ($j = 0; $j < count($timeStampArr); $j++) {
495 if (in_array($timeStampArr[$j], $rdates)) {
496 $thekey = array_search($timeStampArr[$j], $rdates);
497 if (isset($ydata[$z][$thekey])) {
498 if ($ydata[$z][$thekey] === false) {
499 $ydata[$z][$thekey] = 0;
501 if ($ydata[$z][$thekey] > $yMax) {
502 $yMax = $ydata[$z][$thekey];
504 echo 'var '.$chartid.'datevalues = '.$ydata[$z][$thekey].';';
506 echo 'var '.$chartid.'datevalues = 0;';
509 echo 'var '.$chartid.'datevalues = 0;';
511 echo 'var '.$chartid.'date = \''.$timeStampArrFormat[$j].'\';';
512 echo $chartid.'values['.$z.'].push(['.$chartid.'date, '.$chartid.'datevalues]);';
516 case REPORT_TYPE_WEEKLY: {
517 for ($j = 0; $j < count($rdates); $j++) {
518 $wrdates[$j] = date($formatDate, $rdates[$j]);
520 for ($j = 0; $j < count($timeStampArr); $j++) {
521 if (in_array($timeStampArrFormat[$j], $wrdates)) {
522 $thekey = array_search($timeStampArr[$j], $rdates);
523 if (isset($ydata[$z][$thekey])) {
524 if ($ydata[$z][$thekey] === false) {
525 $ydata[$z][$thekey] = 0;
527 if ($ydata[$z][$thekey] > $yMax) {
528 $yMax = $ydata[$z][$thekey];
530 echo 'var '.$chartid.'datevalues = '.$ydata[$z][$thekey].';';
532 echo 'var '.$chartid.'datevalues = 0;';
535 echo 'var '.$chartid.'datevalues = 0;';
537 echo 'var '.$chartid.'date = \''.$timeStampArrFormat[$j].'\';';
538 echo $chartid.'values['.$z.'].push(['.$chartid.'date, '.$chartid.'datevalues]);';
544 for ($z = 0; $z < count($ydata); $z++) {
545 echo $chartid.'series.push('.$chartid.'values['.$z.']);';
547 echo 'jQuery(document).ready(function(){
548 plot'.$chartid.' = jQuery.jqplot (\'chart'.$chartid.'\', '.$chartid.'series, {
550 tickRenderer: jQuery.jqplot.CanvasAxisTickRenderer,
557 show:true, location: \'ne\',
564 renderer: jQuery.jqplot.CategoryAxisRenderer,
583 echo 'jQuery(window).resize(function() {
584 plot'.$chartid.'.replot( { resetAxes: true } );
586 echo '//]]></script>';
587 echo $HTML->html_chartid('chart'.$chartid, $label[0].' ('.date(_('Y-m-d'), $start).' - '.date(_('Y-m-d'), $end).')');
591 function report_actgraph($type, $SPAN, $start, $end, $id, $area) {
593 $now = time() - 60*60*24; // 1 day
599 $report = new ReportUserAct($SPAN, $id, $start, $end);
600 $u = user_get_object($id);
601 if (!$u || $u->isError()) {
602 exit_error(_("Could Not Get User"));
607 $report = new ReportProjectAct($SPAN, $id, $start, $end);
608 $g = group_get_object($id);
609 if (!$g || !is_object($g)) {
611 } elseif ($g->isError()) {
612 exit_error($g->getErrorMessage(), '');
617 $report = new ReportSiteAct($SPAN, $start, $end);
622 if ($report->isError()) {
623 echo $HTML->error_msg($report->getErrorMessage());
626 $rdates = $report->getRawDates();
628 echo $HTML->information(_('No data to display.'));
632 $SPAN = REPORT_TYPE_DAILY;
635 if ($SPAN == REPORT_TYPE_DAILY) {
638 while ($looptime < $end) {
639 $timeStampArr[$i] = $looptime;
640 $looptime += REPORT_DAY_SPAN;
643 $formatDate = 'Y/m/d';
644 } elseif ($SPAN == REPORT_TYPE_WEEKLY) {
645 $timeStampArr = $report->getWeekStartArr();
647 } elseif ($SPAN == REPORT_TYPE_MONTHLY) {
648 $timeStampArr = $report->getMonthStartArr();
652 $initialSizeOfTimeStampArr = count($timeStampArr);
653 for ($j = 0; $j < $initialSizeOfTimeStampArr; $j++) {
654 if ($timeStampArr[$j] < $start || $timeStampArr[$j] >= $end) {
655 unset($timeStampArr[$j]);
659 $timeStampArr = array_values($timeStampArr);
660 for ($j = 0; $j < count($timeStampArr); $j++) {
661 $tickArr[] = date($formatDate, $timeStampArr[$j]);
666 $ydata[] =& $report->getDocs();
667 $areaname = _('Docs');
668 $label[] = _('Documents');
672 $ydata[] =& $report->getDownloads();
673 $areaname = _('Downloads');
674 $label[] = _('Downloads');
678 $ydata[] =& $report->getForum();
679 $areaname = _('Forums');
680 $label[] = _('Forums');
684 $ydata[] =& $report->getPageViews();
685 $areaname = _('Page Views');
686 $label[] = _('Page Views');
690 $ydata[] =& $report->getTaskOpened();
691 $ydata[] =& $report->getTaskClosed();
692 $areaname = _('Tasks');
693 $label[] = _('Task open');
694 $label[] = _('Task close');
698 $ydata[] =& $report->getTrackerOpened();
699 $ydata[] =& $report->getTrackerClosed();
700 $areaname = _('Trackers');
701 $label[] = _('Tracker items opened');
702 $label[] = _('Tracker items closed');
711 $hookParams['group_id'] = $id;
712 $hookParams['results'] = &$results;
713 $hookParams['show'] = &$show;
714 $hookParams['begin'] = $start;
715 $hookParams['end'] = $end;
716 $hookParams['ids'] = &$ids;
717 $hookParams['texts'] = &$texts;
718 $hookParams['exclusive_area'] = $area;
719 plugin_hook("activity", $hookParams);
721 $areaname = $texts[0];
722 $label[] = $texts[0];
724 foreach ($results as $arr) {
725 $dd = date($formatDate, $arr['activity_date']);
727 case REPORT_TYPE_MONTHLY: {
728 $d = mktime(0, 0, 0, substr($dd, 5, 2) , 1, substr($dd, 0, 4));
731 case REPORT_TYPE_WEEKLY: {
732 $d = strtotime(substr($dd, 0, 4).'-W'.substr($dd, 5, 2));
733 $d -= 86400; # weeks are based on Sunday in getWeekStartArr()
736 case REPORT_TYPE_DAILY: {
737 $d = mktime(0, 0, 0, substr($dd, 5, 2) , substr($dd, 8, 2), substr($dd, 0, 4));
744 // Now, stores the values in the ydata array for the graph.
747 foreach ($rdates as $d) {
748 $ydata[0][$i++] = isset($sum[$d]) ? $sum[$d] : 0;
754 $chartid = 'report_actgraph_'.$id;
756 echo '<script type="text/javascript">//<![CDATA['."\n";
757 echo 'var plot'.$chartid.';';
758 echo 'var values = new Array();';
759 echo 'var ticks = new Array();';
760 echo 'var labels = new Array();';
761 echo 'var series = new Array();';
762 for ($z = 0; $z < count($ydata); $z++) {
763 echo 'values['.$z.'] = new Array();';
764 echo 'labels.push({label:\''.$label[$z].'\'});';
767 case REPORT_TYPE_DAILY:
768 case REPORT_TYPE_MONTHLY: {
769 for ($j = 0; $j < count($timeStampArr); $j++) {
770 for ($z = 0; $z < count($ydata); $z++) {
771 if (in_array($timeStampArr[$j], $rdates)) {
772 $thekey = array_search($timeStampArr[$j], $rdates);
773 if (isset($ydata[$z][$thekey])) {
774 if ($ydata[$z][$thekey] === false) {
775 $ydata[$z][$thekey] = 0;
777 if ($ydata[$z][$thekey] > $yMax) {
778 $yMax = $ydata[$z][$thekey];
780 echo 'values['.$z.'].push('.$ydata[$z][$thekey].');';
782 echo 'values['.$z.'].push(0);';
785 echo 'values['.$z.'].push(0);';
788 echo 'ticks.push(\''.$tickArr[$j].'\');';
792 case REPORT_TYPE_WEEKLY: {
793 for ($j = 0; $j < count($rdates); $j++) {
794 $wrdates[$j] = date($formatDate, $rdates[$j]);
796 for ($j = 0; $j < count($tickArr); $j++) {
797 for ($z = 0; $z < count($ydata); $z++) {
798 if (in_array($tickArr[$j], $wrdates)) {
799 $thekey = array_search($tickArr[$j], $wrdates);
800 if (isset($ydata[$z][$thekey])) {
801 if ($ydata[$z][$thekey] === false) {
802 $ydata[$z][$thekey] = 0;
804 if ($ydata[$z][$thekey] > $yMax) {
805 $yMax = $ydata[$z][$thekey];
807 echo 'values['.$z.'].push('.$ydata[$z][$thekey].');';
809 echo 'values['.$z.'].push(0);';
812 echo 'values['.$z.'].push(0);';
815 echo 'ticks.push(\''.$tickArr[$j].'\');';
820 for ($z = 0; $z < count($ydata); $z++) {
821 echo 'series.push(values['.$z.']);';
823 echo 'jQuery(document).ready(function(){
824 plot'.$chartid.' = jQuery.jqplot (\'chart'.$chartid.'\', series, {
826 tickRenderer: jQuery.jqplot.CanvasAxisTickRenderer,
839 renderer:jQuery.jqplot.BarRenderer,
845 show:true, location: \'ne\',
852 renderer: jQuery.jqplot.CategoryAxisRenderer,
873 echo 'jQuery(window).resize(function() {
874 plot'.$chartid.'.replot();
876 echo '//]]></script>';
877 echo $HTML->html_chartid('chart'.$chartid, $areaname.' ('.date(_('Y-m-d'), $start).' - '.date(_('Y-m-d'), $end).')');
881 function report_toolspiegraph($datatype, $start, $end) {
883 $now = time() - 60*60*24; // 1 day
888 $res = db_query_params ('SELECT g.group_name,count(*) AS count
889 FROM groups g, artifact_group_list agl, artifact a
890 WHERE g.group_id=agl.group_id
891 AND agl.group_artifact_id=a.group_artifact_id
892 AND a.open_date BETWEEN $1 AND $2
895 ORDER BY count DESC',
899 } elseif ($datatype == 5) {
900 $res = db_query_params ('SELECT g.group_name,count(*) AS count
901 FROM groups g, forum_group_list fgl, forum f
902 WHERE g.group_id=fgl.group_id
903 AND fgl.group_forum_id=f.group_forum_id
904 AND f.post_date BETWEEN $1 AND $2
906 ORDER BY count DESC',
909 } elseif ($datatype == 6) {
910 $res = db_query_params ('SELECT g.group_name,count(*) AS count
911 FROM groups g, project_group_list pgl, project_task pt
912 WHERE g.group_id=pgl.group_id
913 AND pgl.group_project_id=pt.group_project_id
914 AND pt.start_date BETWEEN $1 AND $2
916 ORDER BY count DESC',
920 $res = db_query_params ('SELECT g.group_name,count(*) AS count
921 FROM groups g, frs_package fp, frs_release fr, frs_file ff, frs_dlstats_file fdf
922 WHERE g.group_id=fp.group_id
923 AND fp.package_id=fr.package_id
924 AND fr.release_id=ff.release_id
925 AND ff.file_id=fdf.file_id
926 AND (((fdf.month > $1) OR (fdf.month = $1 AND fdf.day >= $2))
927 AND ((fdf.month < $3) OR (fdf.month = $3 AND fdf.day < $4)))
929 ORDER BY count DESC',
930 array (date('Ym',$start),
937 exit_error(db_error(), '');
941 $arr[2] = _('Support Requests');
942 $arr[3] = _('Patches');
943 $arr[4] = _('Feature Requests');
944 $arr[0] = _('Other Trackers');
945 $arr[5] = _('Forum Messages');
946 $arr[6] = _('Tasks');
947 $arr[7] = _('Downloads');
949 $chartid = 'toolspie';
950 if (db_numrows($res)) {
951 echo '<script type="text/javascript">//<![CDATA['."\n";
952 echo 'var data'.$chartid.' = new Array();';
953 while ($row = db_fetch_array($res)) {
954 echo 'data'.$chartid.'.push([\''.htmlentities($row[0]).'\','.$row[1].']);';
956 echo 'var plot'.$chartid.';';
957 echo 'jQuery(document).ready(function(){
958 plot'.$chartid.' = jQuery.jqplot (\'chart'.$chartid.'\', [data'.$chartid.'],
961 renderer: jQuery.jqplot.PieRenderer,
963 showDataLabels: true,
964 dataLabels: \'percent\',
969 show:true, location: \'e\',
970 rendererOptions: {numberRows: 11, numberColumns: 2}
975 echo 'jQuery(window).resize(function() {
976 plot'.$chartid.'.replot( { resetAxes: true } );
978 echo '//]]></script>';
979 echo $HTML->html_chartid('chart'.$chartid, $arr[$datatype].' ('.date(_('Y-m-d'), $start).' - '.date(_('Y-m-d'), $end).')');
981 echo $HTML->information(_('No data to display.'));
985 function report_timegraph($type, $area, $start, $end, $id = 0) {
986 global $pie_labels, $pie_vals;
989 $now = time() - 60*60*24; // 1 day
995 $report = new ReportSiteTime($area, $start, $end);
999 $report = new ReportProjectTime($id, $area, $start, $end);
1003 $report = new ReportUserTime($id, $area, $start, $end);
1008 $arr['tasks'] = _('By Task');
1009 $arr['category'] = _('By Category');
1010 $arr['subproject'] = _('By Subproject');
1011 $arr['user'] = _('By User');
1013 report_pie_arr($report->labels, $report->getData());
1015 $chartid = 'timegraph';
1016 if (count($pie_vals)) {
1017 echo '<script type="text/javascript">//<![CDATA['."\n";
1018 echo 'var data'.$chartid.' = new Array();';
1019 for ($i = 0; $i < count($pie_vals); $i++) {
1020 echo 'data'.$chartid.'.push([\''.htmlentities($pie_labels[$i]).'\','.$pie_vals[$i].']);';
1022 echo 'var plot'.$chartid.';';
1023 echo 'jQuery(document).ready(function(){
1024 plot'.$chartid.' = jQuery.jqplot (\'chart'.$chartid.'\', [data'.$chartid.'],
1027 renderer: jQuery.jqplot.PieRenderer,
1029 showDataLabels: true,
1030 dataLabels: \'percent\',
1034 show:true, location: \'e\',
1039 echo 'jQuery(window).resize(function() {
1040 plot'.$chartid.'.replot( { resetAxes: true } );
1042 echo '//]]></script>';
1043 echo $HTML->html_chartid('chart'.$chartid, $arr[$area].' ('.date(_('Y-m-d'), $start).' - '.date(_('Y-m-d'), $end).')');
1045 echo $HTML->information(_('No data to display.'));
1049 function report_sitetimebargraph($start, $end) {
1051 $now = time() - 60*60*24; // 1 day
1056 $res = db_query_params('SELECT week,sum(hours)
1057 FROM rep_time_tracking
1059 BETWEEN $1 AND $2 GROUP BY week',
1060 array($start, $end));
1062 $report = new Report();
1063 if ($report->isError()) {
1064 exit_error($report->getErrorMessage());
1066 $report->setDates($res,0);
1067 $report->setData($res,1);
1068 $chartid = 'sitetimebargraph';
1069 $areaname = _('Hours Recorded');
1071 $dates[0] = $report->getDates();
1072 $ydata[0] = $report->getData();
1073 $label[0] = _(' Hours');
1074 if (count($ydata[0])) {
1075 echo '<script type="text/javascript">//<![CDATA['."\n";
1076 echo 'var plot'.$chartid.';';
1077 echo 'var values = new Array();';
1078 echo 'var ticks = new Array();';
1079 echo 'var labels = new Array();';
1080 echo 'var series = new Array();';
1081 for ($z = 0; $z < count($ydata); $z++) {
1082 echo 'values['.$z.'] = new Array();';
1083 echo 'labels.push({label:\''.$label[$z].'\'});';
1084 for ($j = 0; $j < count($ydata[$z]); $j++) {
1085 echo 'values['.$z.'].push('.$ydata[$z][$j].')';
1086 echo 'ticks.push('.$dates[$z][$j].')';
1089 for ($z = 0; $z < count($ydata); $z++) {
1090 echo 'series.push(values['.$z.']);';
1092 echo 'jQuery(document).ready(function(){
1093 plot'.$chartid.' = jQuery.jqplot (\'chart'.$chartid.'\', series, {
1095 tickRenderer: jQuery.jqplot.CanvasAxisTickRenderer,
1099 showGridline: false,
1108 renderer:jQuery.jqplot.BarRenderer,
1114 show:true, location: \'ne\',
1121 renderer: jQuery.jqplot.CategoryAxisRenderer,
1130 formatString: \'%d\'
1142 echo 'jQuery(window).resize(function() {
1143 plot'.$chartid.'.replot();
1145 echo '//]]></script>';
1146 echo $HTML->html_chartid('chart'.$chartid, $areaname.' ('.date(_('Y-m-d'), $start).' - '.date(_('Y-m-d'), $end).')');
1148 echo $HTML->information(_('No data to display.'));
1153 function report_pm_hbar($id, $values, $ticks, $labels, $stackSeries = false) {
1156 echo '<script type="text/javascript">//<![CDATA['."\n";
1157 echo 'var plot'.$id.';';
1158 echo 'var values'.$id.' = new Array();';
1159 echo 'var ticks'.$id.' = new Array();';
1160 echo 'var labels'.$id.' = new Array();';
1161 echo 'var series'.$id.' = new Array();';
1162 for ($z = 0; $z < count($values); $z++) {
1163 echo 'values'.$id.'['.$z.'] = new Array();';
1164 echo 'labels'.$id.'.push({label:\''.$labels[$z].'\'});';
1166 for ($j = 0; $j < count($ticks); $j++) {
1167 for ($z = 0; $z < count($values); $z++) {
1168 if ($stackSeries !== false && $stackSeries[$j] > $yMax) {
1169 $yMax = $stackSeries[$j];
1170 } elseif ($values[$z][$j] > $yMax) {
1171 $yMax = $values[$z][$j];
1173 echo 'values'.$id.'['.$z.'].push('.$values[$z][$j].');';
1175 echo 'ticks'.$id.'.push(\''.$ticks[$j].'\');';
1177 for ($z = 0; $z < count($values); $z++) {
1178 echo 'series'.$id.'.push(values'.$id.'['.$z.']);';
1180 $height = 40 + 50 * count($ticks);
1182 echo 'jQuery(document).ready(function(){
1183 plot'.$id.' = jQuery.jqplot (\'chart'.$id.'\', series'.$id.', {
1184 height: '.$height.',';
1186 echo ' stackSeries: true,';
1188 echo ' axesDefaults: {
1189 tickRenderer: jQuery.jqplot.CanvasAxisTickRenderer,
1193 showGridline: false,
1202 renderer:jQuery.jqplot.BarRenderer,
1208 barDirection: \'horizontal\',
1213 show:true, location: \'ne\'
1225 formatString: \'%d\'
1229 renderer: jQuery.jqplot.CategoryAxisRenderer,
1235 echo 'jQuery(window).resize(function() {
1236 plot'.$id.'.replot();
1238 echo '//]]></script>';
1239 echo $HTML->html_chartid('chart'.$id);
1244 // c-file-style: "bsd"