From 7379e495fc9cbb08a879002508a9e35c2c22120f Mon Sep 17 00:00:00 2001 From: liumengyi Date: Wed, 15 May 2024 15:46:10 +0800 Subject: [PATCH] * Finish task #118238, add cfd of kanban for execution statistic block. --- module/block/lang/de.php | 3 +- module/block/lang/en.php | 3 +- module/block/lang/fr.php | 3 +- module/block/lang/zh-cn.php | 3 +- .../block/ui/executionstatisticblock.html.php | 267 ++++++++++++------ module/block/zen.php | 29 +- 6 files changed, 212 insertions(+), 96 deletions(-) diff --git a/module/block/lang/de.php b/module/block/lang/de.php index 7917d155ec..cb8e094835 100644 --- a/module/block/lang/de.php +++ b/module/block/lang/de.php @@ -634,7 +634,8 @@ $lang->block->executionstatistic->progress = 'Progress'; $lang->block->executionstatistic->totalEstimate = 'Estimate'; $lang->block->executionstatistic->totalConsumed = 'Consumed'; $lang->block->executionstatistic->totalLeft = 'Left'; -$lang->block->executionstatistic->burn = 'Execution Burn'; +$lang->block->executionstatistic->burn = $lang->execution->common . ' Burn'; +$lang->block->executionstatistic->cfd = $lang->execution->common . ' Task CFD'; $lang->block->executionstatistic->story = 'Story'; $lang->block->executionstatistic->doneStory = 'Done'; $lang->block->executionstatistic->totalStory = 'Total'; diff --git a/module/block/lang/en.php b/module/block/lang/en.php index 8bfc3f4e6c..e73f8404d8 100644 --- a/module/block/lang/en.php +++ b/module/block/lang/en.php @@ -634,7 +634,8 @@ $lang->block->executionstatistic->progress = 'Progress'; $lang->block->executionstatistic->totalEstimate = 'Estimate'; $lang->block->executionstatistic->totalConsumed = 'Consumed'; $lang->block->executionstatistic->totalLeft = 'Left'; -$lang->block->executionstatistic->burn = 'Execution Burn'; +$lang->block->executionstatistic->burn = $lang->execution->common . ' Burn'; +$lang->block->executionstatistic->cfd = $lang->execution->common . ' Task CFD'; $lang->block->executionstatistic->story = 'Story'; $lang->block->executionstatistic->doneStory = 'Done'; $lang->block->executionstatistic->totalStory = 'Total'; diff --git a/module/block/lang/fr.php b/module/block/lang/fr.php index 930a7bb669..3c36262f2c 100644 --- a/module/block/lang/fr.php +++ b/module/block/lang/fr.php @@ -634,7 +634,8 @@ $lang->block->executionstatistic->progress = 'Progress'; $lang->block->executionstatistic->totalEstimate = 'Estimate'; $lang->block->executionstatistic->totalConsumed = 'Consumed'; $lang->block->executionstatistic->totalLeft = 'Left'; -$lang->block->executionstatistic->burn = 'Execution Burn'; +$lang->block->executionstatistic->burn = $lang->execution->common . ' Burn'; +$lang->block->executionstatistic->cfd = $lang->execution->common . ' Task CFD'; $lang->block->executionstatistic->story = 'Story'; $lang->block->executionstatistic->doneStory = 'Done'; $lang->block->executionstatistic->totalStory = 'Total'; diff --git a/module/block/lang/zh-cn.php b/module/block/lang/zh-cn.php index 57427d2405..43267d6a6e 100644 --- a/module/block/lang/zh-cn.php +++ b/module/block/lang/zh-cn.php @@ -634,7 +634,8 @@ $lang->block->executionstatistic->progress = '执行进度'; $lang->block->executionstatistic->totalEstimate = '预计工时'; $lang->block->executionstatistic->totalConsumed = '消耗工时'; $lang->block->executionstatistic->totalLeft = '剩余工时'; -$lang->block->executionstatistic->burn = '执行燃尽图'; +$lang->block->executionstatistic->burn = $lang->execution->common . '燃尽图'; +$lang->block->executionstatistic->cfd = $lang->execution->common . '任务累计流图'; $lang->block->executionstatistic->story = '需求'; $lang->block->executionstatistic->doneStory = '已完成'; $lang->block->executionstatistic->totalStory = '需求总数'; diff --git a/module/block/ui/executionstatisticblock.html.php b/module/block/ui/executionstatisticblock.html.php index ecbd52fc35..a22a83a8f2 100644 --- a/module/block/ui/executionstatisticblock.html.php +++ b/module/block/ui/executionstatisticblock.html.php @@ -42,41 +42,192 @@ foreach($projects as $projectID => $projectName) $projectItems[] = array('value' => $projectID, 'text' => $projectName, 'data-url' => $url, 'data-on' => 'click', 'data-do' => "loadBlock('$block->id', options.url)"); } -/* 燃尽图。Burn chart. */ -$burn = div -( - div(setClass('font-bold mb-2'), $lang->block->executionstatistic->burn), - echarts - ( - set::color(array('#2B80FF', '#D2D6E5')), - set::width('100%'), - set::height(140), - set::grid(array('left' => '2px', 'top' => '30px', 'right' => '10px', 'bottom' => '0', 'containLabel' => true)), - set::legend(array('show' => true, 'right' => '0')), - set::xAxis(array('type' => 'category', 'data' => $chartData['labels'], 'boundaryGap' => false, 'splitLine' => array('show' => false), 'axisTick' => array('alignWithLabel' => true, 'interval' => '0'), 'axisLabel' => array('rotate' => 45))), - set::yAxis(array('type' => 'value', 'name' => 'h', 'minInterval' => $chartData['baseLine'][0], 'splitLine' => array('show' => false), 'axisLine' => array('show' => true, 'color' => '#DDD'))), - set::series +if($execution->type == 'kanban') +{ + $index = 0; + $chartColors = array('#33B4DB', '#7ECF69', '#FFC73A', '#FF5A61', '#50C8D0', '#AF5AFF', '#4EA3FF', '#FF8C5A', '#6C73FF'); + $chartSeries = array(); + if(!empty($chartData['line'])) + { + foreach($chartData['line'] as $label => $set) + { + $chartSeries[] = array( + 'name' => $label, + 'type' => 'line', + 'stack' => 'Total', + 'data' => array_values($set), + 'color' => $chartColors[$index], + 'areaStyle' => array('color' => $chartColors[$index], 'opacity' => 0.2), + 'itemStyle' => array('normal' => array('lineStyle' => array('width' => 1))), + 'emphasis' => array('focus' => 'series') + ); + + $index ++; + } + } + /* 任务计流图图。CFD chart. */ + $chart = div ( - array + div(setClass('font-bold mb-2'), $lang->block->executionstatistic->cfd), + echarts ( - array + set::series($chartSeries), + set::width('100%'), + set::height(200), + set::tooltip(array( + 'trigger' => 'axis', + 'axisPointer' => array('type' => 'cross', 'label' => array('backgroundColor' => '#6a7985')), + 'textStyle' => array('fontWeight' => 100), + 'formatter' => "RAWJSRAWJS" + )), + set::legend(array( + 'data' => array_keys(array_reverse($chartData['line'])) + )), + set::grid(array( + 'top' => '80px', + 'left' => '2px', + 'right' => '2px', + 'bottom' => '2px', + 'containLabel' => true + )), + set::xAxis(array(array( + 'type' => 'category', + 'boundaryGap' => false, + 'data' => $chartData['labels'], + 'name' => $lang->execution->burnXUnit, + 'axisLine' => array('show' => true, 'lineStyle' =>array('color' => '#999', 'width' =>1)) + ))), + set::yAxis(array(array( + 'type' => 'value', + 'name' => $lang->execution->count, + 'minInterval' => 1, + 'nameTextStyle' => array('fontWeight' => 'normal'), + 'axisPointer' => array('label' => array('show' => true, 'precision' => 0)), + 'axisLine' => array('show' => true, 'lineStyle' => array('color' => '#999', 'width' => 1)) + ))) + ) + ); + $taskStoryInfo = null; +} +else +{ + /* 燃尽图。Burn chart. */ + $chart = div + ( + div(setClass('font-bold mb-2'), $lang->block->executionstatistic->burn), + echarts + ( + set::color(array('#2B80FF', '#D2D6E5')), + set::width('100%'), + set::height(140), + set::grid(array('left' => '2px', 'top' => '30px', 'right' => '10px', 'bottom' => '0', 'containLabel' => true)), + set::legend(array('show' => true, 'right' => '0')), + set::xAxis(array('type' => 'category', 'data' => $chartData['labels'], 'boundaryGap' => false, 'splitLine' => array('show' => false), 'axisTick' => array('alignWithLabel' => true, 'interval' => '0'), 'axisLabel' => array('rotate' => 45))), + set::yAxis(array('type' => 'value', 'name' => 'h', 'minInterval' => $chartData['baseLine'][0], 'splitLine' => array('show' => false), 'axisLine' => array('show' => true, 'color' => '#DDD'))), + set::series ( - 'type' => 'line', - 'name' => $lang->execution->charts->burn->graph->actuality, - 'data' => $chartData['burnLine'], - 'emphasis' => array('label' => array('show' => true)) - ), - array - ( - 'type' => 'line', - 'name' => $lang->execution->charts->burn->graph->reference, - 'data' => $chartData['baseLine'], - 'emphasis' => array('label' => array('show' => true)) + array + ( + array + ( + 'type' => 'line', + 'name' => $lang->execution->charts->burn->graph->actuality, + 'data' => $chartData['burnLine'], + 'emphasis' => array('label' => array('show' => true)), + 'symbolSize' => 8, + 'symbol' => 'circle' + ), + array + ( + 'type' => 'line', + 'name' => $lang->execution->charts->burn->graph->reference, + 'data' => $chartData['baseLine'], + 'emphasis' => array('label' => array('show' => true)), + 'symbolSize' => 8, + 'symbol' => 'circle' + ), + array + ( + 'data' => empty($chartData['delayLine']) ? array() : $chartData['delayLine'], + 'type' => 'line', + 'name' => $lang->execution->charts->burn->graph->delay, + 'symbolSize' => 8, + 'symbol' => 'circle', + 'itemStyle' => array + ( + 'normal' => array + ( + 'color' => '#F00', + 'lineStyle' => array + ( + 'color' => '#F00' + ) + ), + 'emphasis' => array + ( + 'color' => '#fff', + 'borderColor' => '#F00', + 'borderWidth' => 2 + ) + ), + ) + ) ) ) - ) - ) -); + ); + + /* 任务故事信息。Task story info. */ + $taskStoryInfo = col + ( + setClass('gap-2'), + row + ( + div(setClass('w-12 flex-none'), strong($lang->block->executionstatistic->task)), + row + ( + setClass('flex-auto'), + cell + ( + setClass('w-1/3'), + span(setClass('text-sm text-gray'), $lang->block->executionstatistic->totalTask), + strong(setClass('num ml-2'), $execution->totalTask) + ), + cell + ( + setClass('w-1/3'), + span(setClass('text-sm text-gray'), $lang->block->executionstatistic->undoneTask), + strong(setClass('num ml-2'), $execution->undoneTask) + ), + cell + ( + setClass('w-1/3'), + span(setClass('text-sm text-gray'), $lang->block->executionstatistic->yesterdayDoneTask), + strong(setClass('num ml-2'), $execution->yesterdayDoneTask) + ) + ) + ), + row + ( + div(setClass('w-12 flex-none'), strong($lang->block->executionstatistic->story)), + row + ( + setClass('flex-auto'), + cell + ( + setClass('w-1/3'), + span(setClass('text-sm text-gray'), $lang->block->executionstatistic->totalStory), + strong(setClass('num ml-2'), $execution->totalStory) + ), + cell + ( + setClass('w-1/3'), + span(setClass('text-sm text-gray'), $lang->block->executionstatistic->doneStory), + strong(setClass('num ml-2'), $execution->doneStory) + ) + ) + ) + ); +} /* 进度环。Progress circle. */ $progressCircle = div @@ -164,58 +315,6 @@ $hoursInfo = row ) ); -/* 任务故事信息。Task story info. */ -$taskStoryInfo = col -( - setClass('gap-2'), - row - ( - div(setClass('w-12 flex-none'), strong($lang->block->executionstatistic->task)), - row - ( - setClass('flex-auto'), - cell - ( - setClass('w-1/3'), - span(setClass('text-sm text-gray'), $lang->block->executionstatistic->totalTask), - strong(setClass('num ml-2'), $execution->totalTask) - ), - cell - ( - setClass('w-1/3'), - span(setClass('text-sm text-gray'), $lang->block->executionstatistic->undoneTask), - strong(setClass('num ml-2'), $execution->undoneTask) - ), - cell - ( - setClass('w-1/3'), - span(setClass('text-sm text-gray'), $lang->block->executionstatistic->yesterdayDoneTask), - strong(setClass('num ml-2'), $execution->yesterdayDoneTask) - ) - ) - ), - row - ( - div(setClass('w-12 flex-none'), strong($lang->block->executionstatistic->story)), - row - ( - setClass('flex-auto'), - cell - ( - setClass('w-1/3'), - span(setClass('text-sm text-gray'), $lang->block->executionstatistic->totalStory), - strong(setClass('num ml-2'), $execution->totalStory) - ), - cell - ( - setClass('w-1/3'), - span(setClass('text-sm text-gray'), $lang->block->executionstatistic->doneStory), - strong(setClass('num ml-2'), $execution->doneStory) - ) - ) - ) -); - $blockView = null; if($longBlock) { @@ -231,7 +330,7 @@ if($longBlock) col ( setClass('gap-0 flex-auto'), - $burn, + $chart, $taskStoryInfo ) ); @@ -252,7 +351,7 @@ else cell ( setClass('flex-auto min-w-0'), - $burn + $chart ) ), $hoursInfo, diff --git a/module/block/zen.php b/module/block/zen.php index 164340a863..97b4044750 100644 --- a/module/block/zen.php +++ b/module/block/zen.php @@ -1159,16 +1159,29 @@ class blockZen extends block $execution->totalHours = $execution->totalLeft + $execution->totalConsumed; $execution->progress = $execution->totalHours ? round($execution->totalConsumed / $execution->totalHours * 100) : 0; // 计算执行的进度, 公式为 [任务消耗工时数 / (任务消耗工时数+任务剩余工时数)]。 - /* Process the burns. */ - $execution->burns = array(); - $burnData = isset($burns[$execution->id]) ? $burns[$execution->id] : array(); - foreach($burnData as $data) $execution->burns[] = $data->value; + if($execution->type == 'kanban') + { + /* Process the cfd. */ + $this->app->loadClass('date'); + list($begin, $end) = $this->execution->getBeginEnd4CFD($execution); + $dateList = date::getDateList($begin, $end, 'Y-m-d', 'noweekend'); + $chartData = $this->execution->buildCFDData($executionID, $dateList, 'task'); + if(isset($chartData['line'])) $chartData['line'] = array_reverse($chartData['line']); + $this->view->chartData = $chartData; + } + else + { + /* Process the burns. */ + $execution->burns = array(); + $burnData = isset($burns[$execution->id]) ? $burns[$execution->id] : array(); + $deadline = $execution->status == 'closed' ? substr($execution->closedDate, 0, 10) : $execution->suspendedDate; + $deadline = strpos('closed,suspended', $execution->status) === false ? helper::today() : $deadline; + list($dateList, $interval) = $this->execution->getDateList($execution->begin, $deadline, 'noweekend', 0, 'Y-m-d', $execution->end); - $deadline = $execution->status == 'closed' ? substr($execution->closedDate, 0, 10) : $execution->suspendedDate; - $deadline = strpos('closed,suspended', $execution->status) === false ? helper::today() : $deadline; - list($dateList, $interval) = $this->execution->getDateList($execution->begin, $deadline, 'noweekend', 0, 'Y-m-d', $execution->end); + foreach($burnData as $data) $execution->burns[] = $data->value; + $this->view->chartData = $this->execution->buildBurnData($executionID, $dateList, 'left', $execution->end); + } - $this->view->chartData = $this->execution->buildBurnData($executionID, $dateList, 'left', $execution->end); $this->view->executions = $executions; $this->view->projects = $this->project->getPairsByIdList(array_keys($projectIdList)); $this->view->currentProjectID = $projectID;