diff --git a/module/execution/control.php b/module/execution/control.php index 1cc1c84b54..e81ff05f8b 100644 --- a/module/execution/control.php +++ b/module/execution/control.php @@ -1324,12 +1324,16 @@ class execution extends control list($begin, $end) = $this->execution->getBeginEnd4CFD($execution); $dateList = date::getDateList($begin, $end, 'Y-m-d', ''); + list($cycleTimeAvg, $throughput) = $this->execution->getCFDStatistics($executionID, $dateList, $type); + $this->view->title = $this->lang->execution->CFD; $this->view->type = $type; $this->view->execution = $execution; $this->view->executionName = $execution->name; $this->view->executionID = $executionID; $this->view->chartData = $this->execution->buildCFDData($executionID, $dateList, $type); + $this->view->cycleTimeAvg = $cycleTimeAvg; + $this->view->throughput = $throughput; $this->display(); } diff --git a/module/execution/css/cfd.css b/module/execution/css/cfd.css index b4c6fccabf..a4b56cf4df 100644 --- a/module/execution/css/cfd.css +++ b/module/execution/css/cfd.css @@ -1,4 +1,5 @@ .main-content > h2 {font-size: 16px;} + .pull-left .input-control {margin-right: 10px;} @media screen and (max-width: 1920px) @@ -12,3 +13,9 @@ { #cfdChart {width:1150px !important; height:400px !important}; } + +#mainContent {min-width: 1400px;} +#burnStatistics {position: absolute; left: 1200px; width: 180px; height: 200px; top: 20%; margin-top: -30px; line-height: 30px; color: #838A9D; font-size: 12px; border: 1px solid #dcdcdc; background-color: #F8F8F8; padding: 15px 20px; color: #3c4353; border-radius: 8px;} +#burnStatistics .bg-primary {margin-right: 5px;} +#burnStatistics .icon-help {color: black;} +#burnStatistics h3 {margin-top: 10px; text-indent: 10px; margin-bottom: 30px;} \ No newline at end of file diff --git a/module/execution/css/cfd.zh-cn.css b/module/execution/css/cfd.zh-cn.css new file mode 100644 index 0000000000..10fd34d04a --- /dev/null +++ b/module/execution/css/cfd.zh-cn.css @@ -0,0 +1 @@ +#burnStatistics {width : 160px;} diff --git a/module/execution/js/cfd.js b/module/execution/js/cfd.js index 0c037e391b..58c7daec4d 100644 --- a/module/execution/js/cfd.js +++ b/module/execution/js/cfd.js @@ -1,5 +1,7 @@ $(function() { + $('[data-toggle=tooltip]').tooltip(); + if(chartData) { var i = 0; diff --git a/module/execution/lang/de.php b/module/execution/lang/de.php index 41d14ce627..7ebbf823ef 100644 --- a/module/execution/lang/de.php +++ b/module/execution/lang/de.php @@ -412,6 +412,7 @@ $lang->execution->ge = "『%s』should be >= actual beg $lang->execution->storyDragError = "The {$lang->SRCommon} is still a draft or has been changed, please drag it after the review"; $lang->execution->countTip = ' (%s member)'; $lang->execution->pleaseInput = "Enter"; +$lang->execution->week = 'week'; /* Statistics. */ $lang->execution->charts = new stdclass(); @@ -429,6 +430,12 @@ $lang->execution->charts->burn->graph->reference = 'Referenz'; $lang->execution->charts->burn->graph->actuality = 'Aktualität'; $lang->execution->charts->burn->graph->delay = 'Delay'; +$lang->execution->charts->cfd = new stdclass(); +$lang->execution->charts->cfd->cycleTime = 'Average cycle time'; +$lang->execution->charts->cfd->cycleTimeTip = 'Average cycle time of each card from development start to completion'; +$lang->execution->charts->cfd->throughput = 'Throughput Rate'; +$lang->execution->charts->cfd->throughputTip = 'Throughput Rate = WIP / Average cycle time'; + $lang->execution->placeholder = new stdclass(); $lang->execution->placeholder->code = 'Abkurzung des Projektnamens'; $lang->execution->placeholder->totalLeft = 'Schätzungen zu Beginn des Projekts.'; diff --git a/module/execution/lang/en.php b/module/execution/lang/en.php index 9595d15d66..3d8b3f8888 100644 --- a/module/execution/lang/en.php +++ b/module/execution/lang/en.php @@ -412,6 +412,7 @@ $lang->execution->ge = "『%s』should be >= actual beg $lang->execution->storyDragError = "The {$lang->SRCommon} is still a draft or has been changed, please drag it after the review"; $lang->execution->countTip = ' (%s member)'; $lang->execution->pleaseInput = "Enter"; +$lang->execution->week = 'week'; /* Statistics. */ $lang->execution->charts = new stdclass(); @@ -429,6 +430,12 @@ $lang->execution->charts->burn->graph->reference = 'Ideal'; $lang->execution->charts->burn->graph->actuality = 'Actual'; $lang->execution->charts->burn->graph->delay = 'Delay'; +$lang->execution->charts->cfd = new stdclass(); +$lang->execution->charts->cfd->cycleTime = 'Average cycle time'; +$lang->execution->charts->cfd->cycleTimeTip = 'Average cycle time of each card from development start to completion'; +$lang->execution->charts->cfd->throughput = 'Throughput Rate'; +$lang->execution->charts->cfd->throughputTip = 'Throughput Rate = WIP / Average cycle time'; + $lang->execution->placeholder = new stdclass(); $lang->execution->placeholder->code = "Abbreviation of {$lang->executionCommon} name"; $lang->execution->placeholder->totalLeft = "Hours estimated on the first day of the {$lang->executionCommon}."; diff --git a/module/execution/lang/fr.php b/module/execution/lang/fr.php index 984b261d54..ca0ae9c74a 100644 --- a/module/execution/lang/fr.php +++ b/module/execution/lang/fr.php @@ -415,6 +415,7 @@ $lang->execution->ge = "『%s』should be >= actual beg $lang->execution->storyDragError = "The {$lang->SRCommon} is still a draft or has been changed, please drag it after the review"; $lang->execution->countTip = ' (%s member)'; $lang->execution->pleaseInput = "Enter"; +$lang->execution->week = 'week'; /* Statistics. */ $lang->execution->charts = new stdclass(); @@ -432,6 +433,12 @@ $lang->execution->charts->burn->graph->reference = 'Idéal'; $lang->execution->charts->burn->graph->actuality = 'Actuel'; $lang->execution->charts->burn->graph->delay = 'Delay'; +$lang->execution->charts->cfd = new stdclass(); +$lang->execution->charts->cfd->cycleTime = 'Average cycle time'; +$lang->execution->charts->cfd->cycleTimeTip = 'Average cycle time of each card from development start to completion'; +$lang->execution->charts->cfd->throughput = 'Throughput Rate'; +$lang->execution->charts->cfd->throughputTip = 'Throughput Rate = WIP / Average cycle time'; + $lang->execution->placeholder = new stdclass(); $lang->execution->placeholder->code = "Abréviation du nom du {$lang->executionCommon}"; $lang->execution->placeholder->totalLeft = "Heures estimées le premier jour du {$lang->executionCommon}."; diff --git a/module/execution/lang/zh-cn.php b/module/execution/lang/zh-cn.php index 4438833e1e..1586eb9f0b 100644 --- a/module/execution/lang/zh-cn.php +++ b/module/execution/lang/zh-cn.php @@ -412,6 +412,7 @@ $lang->execution->ge = "『%s』应当不小于实际 $lang->execution->storyDragError = "该{$lang->SRCommon}还是草稿或已变更状态,请评审通过后再拖动"; $lang->execution->countTip = '(%s人)'; $lang->execution->pleaseInput = "请输入"; +$lang->execution->week = '周'; /* 统计。*/ $lang->execution->charts = new stdclass(); @@ -429,6 +430,12 @@ $lang->execution->charts->burn->graph->reference = '参考'; $lang->execution->charts->burn->graph->actuality = '实际'; $lang->execution->charts->burn->graph->delay = '延期'; +$lang->execution->charts->cfd = new stdclass(); +$lang->execution->charts->cfd->cycleTime = '平均周期时间'; +$lang->execution->charts->cfd->cycleTimeTip = '平均每个卡片从开发启动到完成的周期时间'; +$lang->execution->charts->cfd->throughput = '吞吐率'; +$lang->execution->charts->cfd->throughputTip = '吞吐率 = 在制品 / 平均周期时间'; + $lang->execution->placeholder = new stdclass(); $lang->execution->placeholder->code = '团队内部的简称'; $lang->execution->placeholder->totalLeft = "{$lang->executionCommon}开始时的总预计工时"; diff --git a/module/execution/model.php b/module/execution/model.php index 5a82330dfb..cd935467a3 100644 --- a/module/execution/model.php +++ b/module/execution/model.php @@ -3094,8 +3094,8 @@ class executionModel extends model /** * Get begin and end for CFD. - * - * @param object $execution + * + * @param object $execution * @access public * @return void */ @@ -3236,7 +3236,7 @@ class executionModel extends model /** * Build CFD data. - * + * * @param int $executionID * @param string $type * @param array $dateList @@ -3294,6 +3294,44 @@ class executionModel extends model return $data; } + /** + * Get CFD statistics. + * + * @param int $executionID + * @param array $dateList + * @param string $type + * @access public + * @return void + */ + public function getCFDStatistics($executionID, $dateList, $type) + { + $kanbanData = $this->loadModel('kanban')->getRDKanban($executionID, $type); + $kanbanData = array_shift($kanbanData); + + $cycleTime = array(); + foreach($kanbanData->groups as $group) + { + foreach($group->lanes as $lane) + { + if(!isset($lane->items['closed'])) continue; + + foreach($lane->items['closed'] as $item) + { + $diffTime = $type == 'story' ? strtotime($item['lastEditedDate']) - strtotime($item['openedDate']) : strtotime($item['closedDate']) - strtotime($item['openedDate']); + $day = floor($diffTime / (3600 * 24)); + if($day > 0) $cycleTime[$item['id']] = $day; + } + } + } + + $itemCount = count($cycleTime); + if(!$itemCount) return array('', ''); + $cycleTimeAvg = round(array_sum($cycleTime) / $itemCount); + $throughput = round(($itemCount * 7) / $cycleTimeAvg, 1) . "{$this->lang->execution->kanbanCardsUnit}/" . $this->lang->execution->week; + + return array($cycleTimeAvg, $throughput); + } + /** * Get taskes by search. * diff --git a/module/execution/view/cfd.html.php b/module/execution/view/cfd.html.php index 2dc0232be5..57c8e38580 100644 --- a/module/execution/view/cfd.html.php +++ b/module/execution/view/cfd.html.php @@ -35,6 +35,12 @@