1<?php 2 3namespace Kanboard\Controller; 4 5use Kanboard\Filter\TaskProjectFilter; 6use Kanboard\Model\TaskModel; 7 8/** 9 * Project Analytic Controller 10 * 11 * @package Kanboard\Controller 12 * @author Frederic Guillot 13 */ 14class AnalyticController extends BaseController 15{ 16 /** 17 * Show average Lead and Cycle time 18 * 19 * @access public 20 */ 21 public function leadAndCycleTime() 22 { 23 $project = $this->getProject(); 24 list($from, $to) = $this->getDates(); 25 26 $this->response->html($this->helper->layout->analytic('analytic/lead_cycle_time', array( 27 'values' => array( 28 'from' => $from, 29 'to' => $to, 30 ), 31 'project' => $project, 32 'average' => $this->averageLeadCycleTimeAnalytic->build($project['id']), 33 'metrics' => $this->projectDailyStatsModel->getRawMetrics($project['id'], $from, $to), 34 'title' => t('Lead and cycle time'), 35 ))); 36 } 37 38 /** 39 * Show comparison between actual and estimated hours chart 40 * 41 * @access public 42 */ 43 public function timeComparison() 44 { 45 $project = $this->getProject(); 46 47 $paginator = $this->paginator 48 ->setUrl('AnalyticController', 'timeComparison', array('project_id' => $project['id'])) 49 ->setMax(30) 50 ->setOrder(TaskModel::TABLE.'.id') 51 ->setQuery($this->taskQuery 52 ->withFilter(new TaskProjectFilter($project['id'])) 53 ->getQuery() 54 ) 55 ->calculate(); 56 57 $this->response->html($this->helper->layout->analytic('analytic/time_comparison', array( 58 'project' => $project, 59 'paginator' => $paginator, 60 'metrics' => $this->estimatedTimeComparisonAnalytic->build($project['id']), 61 'title' => t('Estimated vs actual time'), 62 ))); 63 } 64 65 /** 66 * Show average time spent by column 67 * 68 * @access public 69 */ 70 public function averageTimeByColumn() 71 { 72 $project = $this->getProject(); 73 74 $this->response->html($this->helper->layout->analytic('analytic/avg_time_columns', array( 75 'project' => $project, 76 'metrics' => $this->averageTimeSpentColumnAnalytic->build($project['id']), 77 'title' => t('Average time into each column'), 78 ))); 79 } 80 81 /** 82 * Show tasks distribution graph 83 * 84 * @access public 85 */ 86 public function taskDistribution() 87 { 88 $project = $this->getProject(); 89 90 $this->response->html($this->helper->layout->analytic('analytic/task_distribution', array( 91 'project' => $project, 92 'metrics' => $this->taskDistributionAnalytic->build($project['id']), 93 'title' => t('Task distribution'), 94 ))); 95 } 96 97 /** 98 * Show users repartition 99 * 100 * @access public 101 */ 102 public function userDistribution() 103 { 104 $project = $this->getProject(); 105 106 $this->response->html($this->helper->layout->analytic('analytic/user_distribution', array( 107 'project' => $project, 108 'metrics' => $this->userDistributionAnalytic->build($project['id']), 109 'title' => t('User repartition'), 110 ))); 111 } 112 113 /** 114 * Show cumulative flow diagram 115 * 116 * @access public 117 */ 118 public function cfd() 119 { 120 $this->commonAggregateMetrics('analytic/cfd', 'total', t('Cumulative flow diagram')); 121 } 122 123 /** 124 * Show burndown chart 125 * 126 * @access public 127 */ 128 public function burndown() 129 { 130 $this->commonAggregateMetrics('analytic/burndown', 'score', t('Burndown chart')); 131 } 132 133 /** 134 * Estimated vs actual time per column 135 * 136 * @access public 137 */ 138 public function estimatedVsActualByColumn() 139 { 140 $project = $this->getProject(); 141 142 $this->response->html($this->helper->layout->analytic('analytic/estimated_actual_column', array( 143 'project' => $project, 144 'metrics' => $this->estimatedActualColumnAnalytic->build($project['id']), 145 'title' => t('Estimated vs actual time per column'), 146 ))); 147 } 148 149 /** 150 * Common method for CFD and Burdown chart 151 * 152 * @access private 153 * @param string $template 154 * @param string $column 155 * @param string $title 156 */ 157 private function commonAggregateMetrics($template, $column, $title) 158 { 159 $project = $this->getProject(); 160 list($from, $to) = $this->getDates(); 161 162 $displayGraph = $this->projectDailyColumnStatsModel->countDays($project['id'], $from, $to) >= 2; 163 $metrics = $displayGraph ? $this->projectDailyColumnStatsModel->getAggregatedMetrics($project['id'], $from, $to, $column) : array(); 164 165 $this->response->html($this->helper->layout->analytic($template, array( 166 'values' => array( 167 'from' => $from, 168 'to' => $to, 169 ), 170 'display_graph' => $displayGraph, 171 'metrics' => $metrics, 172 'project' => $project, 173 'title' => $title, 174 ))); 175 } 176 177 private function getDates() 178 { 179 $values = $this->request->getValues(); 180 181 $from = $this->request->getStringParam('from', date('Y-m-d', strtotime('-1week'))); 182 $to = $this->request->getStringParam('to', date('Y-m-d')); 183 184 if (! empty($values)) { 185 $from = $this->dateParser->getIsoDate($values['from']); 186 $to = $this->dateParser->getIsoDate($values['to']); 187 } 188 189 return array($from, $to); 190 } 191} 192