mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-29 18:22:41 +01:00
Give "Burndown" charts a more straightforward definition and move all the event stuff into "Activity" charts
Summary: Depends on D20818. Ref T13279. The behavior of the "burndown" chart has wandered fairly far afield; make it look more like a burndown. Move the other thing into an "Activity" chart. Test Plan: {F6865207} Maniphest Tasks: T13279 Differential Revision: https://secure.phabricator.com/D20819
This commit is contained in:
parent
c06dd4818b
commit
16de9151c7
4 changed files with 203 additions and 113 deletions
|
@ -4224,6 +4224,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorProfileMenuItemView' => 'applications/search/engine/PhabricatorProfileMenuItemView.php',
|
'PhabricatorProfileMenuItemView' => 'applications/search/engine/PhabricatorProfileMenuItemView.php',
|
||||||
'PhabricatorProfileMenuItemViewList' => 'applications/search/engine/PhabricatorProfileMenuItemViewList.php',
|
'PhabricatorProfileMenuItemViewList' => 'applications/search/engine/PhabricatorProfileMenuItemViewList.php',
|
||||||
'PhabricatorProject' => 'applications/project/storage/PhabricatorProject.php',
|
'PhabricatorProject' => 'applications/project/storage/PhabricatorProject.php',
|
||||||
|
'PhabricatorProjectActivityChartEngine' => 'applications/project/chart/PhabricatorProjectActivityChartEngine.php',
|
||||||
'PhabricatorProjectAddHeraldAction' => 'applications/project/herald/PhabricatorProjectAddHeraldAction.php',
|
'PhabricatorProjectAddHeraldAction' => 'applications/project/herald/PhabricatorProjectAddHeraldAction.php',
|
||||||
'PhabricatorProjectApplication' => 'applications/project/application/PhabricatorProjectApplication.php',
|
'PhabricatorProjectApplication' => 'applications/project/application/PhabricatorProjectApplication.php',
|
||||||
'PhabricatorProjectArchiveController' => 'applications/project/controller/PhabricatorProjectArchiveController.php',
|
'PhabricatorProjectArchiveController' => 'applications/project/controller/PhabricatorProjectArchiveController.php',
|
||||||
|
@ -10733,6 +10734,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorSpacesInterface',
|
'PhabricatorSpacesInterface',
|
||||||
'PhabricatorEditEngineSubtypeInterface',
|
'PhabricatorEditEngineSubtypeInterface',
|
||||||
),
|
),
|
||||||
|
'PhabricatorProjectActivityChartEngine' => 'PhabricatorChartEngine',
|
||||||
'PhabricatorProjectAddHeraldAction' => 'PhabricatorProjectHeraldAction',
|
'PhabricatorProjectAddHeraldAction' => 'PhabricatorProjectHeraldAction',
|
||||||
'PhabricatorProjectApplication' => 'PhabricatorApplication',
|
'PhabricatorProjectApplication' => 'PhabricatorApplication',
|
||||||
'PhabricatorProjectArchiveController' => 'PhabricatorProjectController',
|
'PhabricatorProjectArchiveController' => 'PhabricatorProjectController',
|
||||||
|
|
|
@ -0,0 +1,135 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorProjectActivityChartEngine
|
||||||
|
extends PhabricatorChartEngine {
|
||||||
|
|
||||||
|
const CHARTENGINEKEY = 'project.activity';
|
||||||
|
|
||||||
|
public function setProjects(array $projects) {
|
||||||
|
assert_instances_of($projects, 'PhabricatorProject');
|
||||||
|
$project_phids = mpull($projects, 'getPHID');
|
||||||
|
return $this->setEngineParameter('projectPHIDs', $project_phids);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function newChart(PhabricatorFactChart $chart, array $map) {
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
|
$map = $map + array(
|
||||||
|
'projectPHIDs' => array(),
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($map['projectPHIDs']) {
|
||||||
|
$projects = id(new PhabricatorProjectQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withPHIDs($map['projectPHIDs'])
|
||||||
|
->execute();
|
||||||
|
$project_phids = mpull($projects, 'getPHID');
|
||||||
|
} else {
|
||||||
|
$project_phids = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$project_phid = head($project_phids);
|
||||||
|
|
||||||
|
$functions = array();
|
||||||
|
$stacks = array();
|
||||||
|
|
||||||
|
$function = $this->newFunction(
|
||||||
|
array(
|
||||||
|
'accumulate',
|
||||||
|
array(
|
||||||
|
'compose',
|
||||||
|
array('fact', 'tasks.open-count.assign.project', $project_phid),
|
||||||
|
array('min', 0),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
$function->getFunctionLabel()
|
||||||
|
->setKey('moved-in')
|
||||||
|
->setName(pht('Tasks Moved Into Project'))
|
||||||
|
->setColor('rgba(128, 128, 200, 1)')
|
||||||
|
->setFillColor('rgba(128, 128, 200, 0.15)');
|
||||||
|
|
||||||
|
$functions[] = $function;
|
||||||
|
|
||||||
|
$function = $this->newFunction(
|
||||||
|
array(
|
||||||
|
'accumulate',
|
||||||
|
array(
|
||||||
|
'compose',
|
||||||
|
array('fact', 'tasks.open-count.status.project', $project_phid),
|
||||||
|
array('min', 0),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
$function->getFunctionLabel()
|
||||||
|
->setKey('reopened')
|
||||||
|
->setName(pht('Tasks Reopened'))
|
||||||
|
->setColor('rgba(128, 128, 200, 1)')
|
||||||
|
->setFillColor('rgba(128, 128, 200, 0.15)');
|
||||||
|
|
||||||
|
$functions[] = $function;
|
||||||
|
|
||||||
|
$function = $this->newFunction(
|
||||||
|
array(
|
||||||
|
'accumulate',
|
||||||
|
array('fact', 'tasks.open-count.create.project', $project_phid),
|
||||||
|
));
|
||||||
|
|
||||||
|
$function->getFunctionLabel()
|
||||||
|
->setKey('created')
|
||||||
|
->setName(pht('Tasks Created'))
|
||||||
|
->setColor('rgba(0, 0, 200, 1)')
|
||||||
|
->setFillColor('rgba(0, 0, 200, 0.15)');
|
||||||
|
|
||||||
|
$functions[] = $function;
|
||||||
|
|
||||||
|
$function = $this->newFunction(
|
||||||
|
array(
|
||||||
|
'accumulate',
|
||||||
|
array(
|
||||||
|
'compose',
|
||||||
|
array('fact', 'tasks.open-count.status.project', $project_phid),
|
||||||
|
array('max', 0),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
$function->getFunctionLabel()
|
||||||
|
->setKey('closed')
|
||||||
|
->setName(pht('Tasks Closed'))
|
||||||
|
->setColor('rgba(0, 200, 0, 1)')
|
||||||
|
->setFillColor('rgba(0, 200, 0, 0.15)');
|
||||||
|
|
||||||
|
$functions[] = $function;
|
||||||
|
|
||||||
|
$function = $this->newFunction(
|
||||||
|
array(
|
||||||
|
'accumulate',
|
||||||
|
array(
|
||||||
|
'compose',
|
||||||
|
array('fact', 'tasks.open-count.assign.project', $project_phid),
|
||||||
|
array('max', 0),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
|
||||||
|
$function->getFunctionLabel()
|
||||||
|
->setKey('moved-out')
|
||||||
|
->setName(pht('Tasks Moved Out of Project'))
|
||||||
|
->setColor('rgba(128, 200, 128, 1)')
|
||||||
|
->setFillColor('rgba(128, 200, 128, 0.15)');
|
||||||
|
|
||||||
|
$functions[] = $function;
|
||||||
|
|
||||||
|
$stacks[] = array('created', 'reopened', 'moved-in');
|
||||||
|
$stacks[] = array('closed', 'moved-out');
|
||||||
|
|
||||||
|
$datasets = array();
|
||||||
|
|
||||||
|
$dataset = id(new PhabricatorChartStackedAreaDataset())
|
||||||
|
->setFunctions($functions)
|
||||||
|
->setStacks($stacks);
|
||||||
|
|
||||||
|
$datasets[] = $dataset;
|
||||||
|
$chart->attachDatasets($datasets);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -29,140 +29,79 @@ final class PhabricatorProjectBurndownChartEngine
|
||||||
}
|
}
|
||||||
|
|
||||||
$functions = array();
|
$functions = array();
|
||||||
$stacks = array();
|
|
||||||
|
|
||||||
if ($project_phids) {
|
if ($project_phids) {
|
||||||
foreach ($project_phids as $project_phid) {
|
$open_function = $this->newFunction(
|
||||||
$function = $this->newFunction(
|
|
||||||
array(
|
array(
|
||||||
'accumulate',
|
'accumulate',
|
||||||
array(
|
array(
|
||||||
'compose',
|
'sum',
|
||||||
array('fact', 'tasks.open-count.assign.project', $project_phid),
|
$this->newFactSum(
|
||||||
array('min', 0),
|
'tasks.open-count.create.project', $project_phids),
|
||||||
|
$this->newFactSum(
|
||||||
|
'tasks.open-count.status.project', $project_phids),
|
||||||
|
$this->newFactSum(
|
||||||
|
'tasks.open-count.assign.project', $project_phids),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
||||||
$function->getFunctionLabel()
|
$closed_function = $this->newFunction(
|
||||||
->setKey('moved-in')
|
|
||||||
->setName(pht('Tasks Moved Into Project'))
|
|
||||||
->setColor('rgba(128, 128, 200, 1)')
|
|
||||||
->setFillColor('rgba(128, 128, 200, 0.15)');
|
|
||||||
|
|
||||||
$functions[] = $function;
|
|
||||||
|
|
||||||
$function = $this->newFunction(
|
|
||||||
array(
|
array(
|
||||||
'accumulate',
|
'accumulate',
|
||||||
array(
|
$this->newFactSum('tasks.open-count.status.project', $project_phids),
|
||||||
'compose',
|
|
||||||
array('fact', 'tasks.open-count.status.project', $project_phid),
|
|
||||||
array('min', 0),
|
|
||||||
),
|
|
||||||
));
|
));
|
||||||
|
|
||||||
$function->getFunctionLabel()
|
|
||||||
->setKey('reopened')
|
|
||||||
->setName(pht('Tasks Reopened'))
|
|
||||||
->setColor('rgba(128, 128, 200, 1)')
|
|
||||||
->setFillColor('rgba(128, 128, 200, 0.15)');
|
|
||||||
|
|
||||||
$functions[] = $function;
|
|
||||||
|
|
||||||
$function = $this->newFunction(
|
|
||||||
array(
|
|
||||||
'accumulate',
|
|
||||||
array('fact', 'tasks.open-count.create.project', $project_phid),
|
|
||||||
));
|
|
||||||
|
|
||||||
$function->getFunctionLabel()
|
|
||||||
->setKey('created')
|
|
||||||
->setName(pht('Tasks Created'))
|
|
||||||
->setColor('rgba(0, 0, 200, 1)')
|
|
||||||
->setFillColor('rgba(0, 0, 200, 0.15)');
|
|
||||||
|
|
||||||
$functions[] = $function;
|
|
||||||
|
|
||||||
$function = $this->newFunction(
|
|
||||||
array(
|
|
||||||
'accumulate',
|
|
||||||
array(
|
|
||||||
'compose',
|
|
||||||
array('fact', 'tasks.open-count.status.project', $project_phid),
|
|
||||||
array('max', 0),
|
|
||||||
),
|
|
||||||
));
|
|
||||||
|
|
||||||
$function->getFunctionLabel()
|
|
||||||
->setKey('closed')
|
|
||||||
->setName(pht('Tasks Closed'))
|
|
||||||
->setColor('rgba(0, 200, 0, 1)')
|
|
||||||
->setFillColor('rgba(0, 200, 0, 0.15)');
|
|
||||||
|
|
||||||
$functions[] = $function;
|
|
||||||
|
|
||||||
$function = $this->newFunction(
|
|
||||||
array(
|
|
||||||
'accumulate',
|
|
||||||
array(
|
|
||||||
'compose',
|
|
||||||
array('fact', 'tasks.open-count.assign.project', $project_phid),
|
|
||||||
array('max', 0),
|
|
||||||
),
|
|
||||||
));
|
|
||||||
|
|
||||||
$function->getFunctionLabel()
|
|
||||||
->setKey('moved-out')
|
|
||||||
->setName(pht('Tasks Moved Out of Project'))
|
|
||||||
->setColor('rgba(128, 200, 128, 1)')
|
|
||||||
->setFillColor('rgba(128, 200, 128, 0.15)');
|
|
||||||
|
|
||||||
$functions[] = $function;
|
|
||||||
|
|
||||||
$stacks[] = array('created', 'reopened', 'moved-in');
|
|
||||||
$stacks[] = array('closed', 'moved-out');
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
$function = $this->newFunction(
|
$open_function = $this->newFunction(
|
||||||
array(
|
array(
|
||||||
'accumulate',
|
'accumulate',
|
||||||
array('fact', 'tasks.open-count.create'),
|
array('fact', 'tasks.open-count.create'),
|
||||||
));
|
));
|
||||||
|
|
||||||
$function->getFunctionLabel()
|
$closed_function = $this->newFunction(
|
||||||
|
array(
|
||||||
|
'accumulate',
|
||||||
|
array('fact', 'tasks.open-count.status'),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
$open_function->getFunctionLabel()
|
||||||
->setKey('open')
|
->setKey('open')
|
||||||
->setName(pht('Open Tasks'))
|
->setName(pht('Open Tasks'))
|
||||||
->setColor('rgba(0, 0, 200, 1)')
|
->setColor('rgba(0, 0, 200, 1)')
|
||||||
->setFillColor('rgba(0, 0, 200, 0.15)');
|
->setFillColor('rgba(0, 0, 200, 0.15)');
|
||||||
|
|
||||||
$functions[] = $function;
|
$closed_function->getFunctionLabel()
|
||||||
|
|
||||||
$function = $this->newFunction(
|
|
||||||
array(
|
|
||||||
'accumulate',
|
|
||||||
array('fact', 'tasks.open-count.status'),
|
|
||||||
));
|
|
||||||
|
|
||||||
$function->getFunctionLabel()
|
|
||||||
->setKey('closed')
|
->setKey('closed')
|
||||||
->setName(pht('Closed Tasks'))
|
->setName(pht('Closed Tasks'))
|
||||||
->setColor('rgba(0, 200, 0, 1)')
|
->setColor('rgba(0, 200, 0, 1)')
|
||||||
->setFillColor('rgba(0, 200, 0, 0.15)');
|
->setFillColor('rgba(0, 200, 0, 0.15)');
|
||||||
|
|
||||||
$functions[] = $function;
|
|
||||||
}
|
|
||||||
|
|
||||||
$datasets = array();
|
$datasets = array();
|
||||||
|
|
||||||
$dataset = id(new PhabricatorChartStackedAreaDataset())
|
$dataset = id(new PhabricatorChartStackedAreaDataset())
|
||||||
->setFunctions($functions);
|
->setFunctions(
|
||||||
|
array(
|
||||||
if ($stacks) {
|
$open_function,
|
||||||
$dataset->setStacks($stacks);
|
$closed_function,
|
||||||
}
|
))
|
||||||
|
->setStacks(
|
||||||
|
array(
|
||||||
|
array('open'),
|
||||||
|
array('closed'),
|
||||||
|
));
|
||||||
|
|
||||||
$datasets[] = $dataset;
|
$datasets[] = $dataset;
|
||||||
$chart->attachDatasets($datasets);
|
$chart->attachDatasets($datasets);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function newFactSum($fact_key, array $phids) {
|
||||||
|
$result = array();
|
||||||
|
$result[] = 'sum';
|
||||||
|
|
||||||
|
foreach ($phids as $phid) {
|
||||||
|
$result[] = array('fact', $fact_key, $phid);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,10 +44,24 @@ final class PhabricatorProjectReportsController
|
||||||
->setParentPanelPHIDs(array())
|
->setParentPanelPHIDs(array())
|
||||||
->renderPanel();
|
->renderPanel();
|
||||||
|
|
||||||
|
$activity_panel = id(new PhabricatorProjectActivityChartEngine())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->setProjects(array($project))
|
||||||
|
->buildChartPanel();
|
||||||
|
|
||||||
|
$activity_panel->setName(pht('%s: Activity', $project->getName()));
|
||||||
|
|
||||||
|
$activity_view = id(new PhabricatorDashboardPanelRenderingEngine())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->setPanel($activity_panel)
|
||||||
|
->setParentPanelPHIDs(array())
|
||||||
|
->renderPanel();
|
||||||
|
|
||||||
$view = id(new PHUITwoColumnView())
|
$view = id(new PHUITwoColumnView())
|
||||||
->setFooter(
|
->setFooter(
|
||||||
array(
|
array(
|
||||||
$chart_view,
|
$chart_view,
|
||||||
|
$activity_view,
|
||||||
));
|
));
|
||||||
|
|
||||||
return $this->newPage()
|
return $this->newPage()
|
||||||
|
|
Loading…
Reference in a new issue