mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-24 06:20:56 +01:00
Add chart functions "x()" and "constant(3)"
Summary: Depends on D20442. Ref T13279. Add basic support for drawing chart functions that are not based on Facts first-party ETL datasets. Some general goals: - This might be useful to draw a line like "goal" or "profitability". - This might be useful to pull data from an external source. - For composable functions like "add" or "subtract", which are useful in manipulating ETL datasets, these value functions will make testing easier. Test Plan: Added a `constant(256)` function: {F6382408} Reviewers: amckinley Reviewed By: amckinley Subscribers: yelirekim Maniphest Tasks: T13279 Differential Revision: https://secure.phabricator.com/D20443
This commit is contained in:
parent
cd2215fd4a
commit
c4e4448ee6
5 changed files with 155 additions and 3 deletions
|
@ -2802,6 +2802,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorConpherenceWidgetVisibleSetting' => 'applications/settings/setting/PhabricatorConpherenceWidgetVisibleSetting.php',
|
'PhabricatorConpherenceWidgetVisibleSetting' => 'applications/settings/setting/PhabricatorConpherenceWidgetVisibleSetting.php',
|
||||||
'PhabricatorConsoleApplication' => 'applications/console/application/PhabricatorConsoleApplication.php',
|
'PhabricatorConsoleApplication' => 'applications/console/application/PhabricatorConsoleApplication.php',
|
||||||
'PhabricatorConsoleContentSource' => 'infrastructure/contentsource/PhabricatorConsoleContentSource.php',
|
'PhabricatorConsoleContentSource' => 'infrastructure/contentsource/PhabricatorConsoleContentSource.php',
|
||||||
|
'PhabricatorConstantChartFunction' => 'applications/fact/chart/PhabricatorConstantChartFunction.php',
|
||||||
'PhabricatorContactNumbersSettingsPanel' => 'applications/settings/panel/PhabricatorContactNumbersSettingsPanel.php',
|
'PhabricatorContactNumbersSettingsPanel' => 'applications/settings/panel/PhabricatorContactNumbersSettingsPanel.php',
|
||||||
'PhabricatorContentSource' => 'infrastructure/contentsource/PhabricatorContentSource.php',
|
'PhabricatorContentSource' => 'infrastructure/contentsource/PhabricatorContentSource.php',
|
||||||
'PhabricatorContentSourceModule' => 'infrastructure/contentsource/PhabricatorContentSourceModule.php',
|
'PhabricatorContentSourceModule' => 'infrastructure/contentsource/PhabricatorContentSourceModule.php',
|
||||||
|
@ -4935,6 +4936,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorWorkingCopyDiscoveryTestCase' => 'applications/repository/engine/__tests__/PhabricatorWorkingCopyDiscoveryTestCase.php',
|
'PhabricatorWorkingCopyDiscoveryTestCase' => 'applications/repository/engine/__tests__/PhabricatorWorkingCopyDiscoveryTestCase.php',
|
||||||
'PhabricatorWorkingCopyPullTestCase' => 'applications/repository/engine/__tests__/PhabricatorWorkingCopyPullTestCase.php',
|
'PhabricatorWorkingCopyPullTestCase' => 'applications/repository/engine/__tests__/PhabricatorWorkingCopyPullTestCase.php',
|
||||||
'PhabricatorWorkingCopyTestCase' => 'applications/repository/engine/__tests__/PhabricatorWorkingCopyTestCase.php',
|
'PhabricatorWorkingCopyTestCase' => 'applications/repository/engine/__tests__/PhabricatorWorkingCopyTestCase.php',
|
||||||
|
'PhabricatorXChartFunction' => 'applications/fact/chart/PhabricatorXChartFunction.php',
|
||||||
'PhabricatorXHPASTDAO' => 'applications/phpast/storage/PhabricatorXHPASTDAO.php',
|
'PhabricatorXHPASTDAO' => 'applications/phpast/storage/PhabricatorXHPASTDAO.php',
|
||||||
'PhabricatorXHPASTParseTree' => 'applications/phpast/storage/PhabricatorXHPASTParseTree.php',
|
'PhabricatorXHPASTParseTree' => 'applications/phpast/storage/PhabricatorXHPASTParseTree.php',
|
||||||
'PhabricatorXHPASTViewController' => 'applications/phpast/controller/PhabricatorXHPASTViewController.php',
|
'PhabricatorXHPASTViewController' => 'applications/phpast/controller/PhabricatorXHPASTViewController.php',
|
||||||
|
@ -8790,6 +8792,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorConpherenceWidgetVisibleSetting' => 'PhabricatorInternalSetting',
|
'PhabricatorConpherenceWidgetVisibleSetting' => 'PhabricatorInternalSetting',
|
||||||
'PhabricatorConsoleApplication' => 'PhabricatorApplication',
|
'PhabricatorConsoleApplication' => 'PhabricatorApplication',
|
||||||
'PhabricatorConsoleContentSource' => 'PhabricatorContentSource',
|
'PhabricatorConsoleContentSource' => 'PhabricatorContentSource',
|
||||||
|
'PhabricatorConstantChartFunction' => 'PhabricatorChartFunction',
|
||||||
'PhabricatorContactNumbersSettingsPanel' => 'PhabricatorSettingsPanel',
|
'PhabricatorContactNumbersSettingsPanel' => 'PhabricatorSettingsPanel',
|
||||||
'PhabricatorContentSource' => 'Phobject',
|
'PhabricatorContentSource' => 'Phobject',
|
||||||
'PhabricatorContentSourceModule' => 'PhabricatorConfigModule',
|
'PhabricatorContentSourceModule' => 'PhabricatorConfigModule',
|
||||||
|
@ -11288,6 +11291,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorWorkingCopyDiscoveryTestCase' => 'PhabricatorWorkingCopyTestCase',
|
'PhabricatorWorkingCopyDiscoveryTestCase' => 'PhabricatorWorkingCopyTestCase',
|
||||||
'PhabricatorWorkingCopyPullTestCase' => 'PhabricatorWorkingCopyTestCase',
|
'PhabricatorWorkingCopyPullTestCase' => 'PhabricatorWorkingCopyTestCase',
|
||||||
'PhabricatorWorkingCopyTestCase' => 'PhabricatorTestCase',
|
'PhabricatorWorkingCopyTestCase' => 'PhabricatorTestCase',
|
||||||
|
'PhabricatorXChartFunction' => 'PhabricatorChartFunction',
|
||||||
'PhabricatorXHPASTDAO' => 'PhabricatorLiskDAO',
|
'PhabricatorXHPASTDAO' => 'PhabricatorLiskDAO',
|
||||||
'PhabricatorXHPASTParseTree' => 'PhabricatorXHPASTDAO',
|
'PhabricatorXHPASTParseTree' => 'PhabricatorXHPASTDAO',
|
||||||
'PhabricatorXHPASTViewController' => 'PhabricatorController',
|
'PhabricatorXHPASTViewController' => 'PhabricatorController',
|
||||||
|
|
|
@ -25,6 +25,10 @@ abstract class PhabricatorChartFunction
|
||||||
|
|
||||||
abstract protected function newArguments(array $arguments);
|
abstract protected function newArguments(array $arguments);
|
||||||
|
|
||||||
|
public function loadData() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
final public function setXAxis(PhabricatorChartAxis $x_axis) {
|
final public function setXAxis(PhabricatorChartAxis $x_axis) {
|
||||||
$this->xAxis = $x_axis;
|
$this->xAxis = $x_axis;
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -43,4 +47,53 @@ abstract class PhabricatorChartFunction
|
||||||
return $this->yAxis;
|
return $this->yAxis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function newLinearSteps($src, $dst, $count) {
|
||||||
|
$count = (int)$count;
|
||||||
|
$src = (int)$src;
|
||||||
|
$dst = (int)$dst;
|
||||||
|
|
||||||
|
if ($count === 0) {
|
||||||
|
throw new Exception(
|
||||||
|
pht('Can not generate zero linear steps between two values!'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($src === $dst) {
|
||||||
|
return array($src);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($count === 1) {
|
||||||
|
return array($src);
|
||||||
|
}
|
||||||
|
|
||||||
|
$is_reversed = ($src > $dst);
|
||||||
|
if ($is_reversed) {
|
||||||
|
$min = (double)$dst;
|
||||||
|
$max = (double)$src;
|
||||||
|
} else {
|
||||||
|
$min = (double)$src;
|
||||||
|
$max = (double)$dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
$step = (double)($max - $min) / (double)($count - 1);
|
||||||
|
|
||||||
|
$steps = array();
|
||||||
|
for ($cursor = $min; $cursor <= $max; $cursor += $step) {
|
||||||
|
$x = (int)round($cursor);
|
||||||
|
|
||||||
|
if (isset($steps[$x])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$steps[$x] = $x;
|
||||||
|
}
|
||||||
|
|
||||||
|
$steps = array_values($steps);
|
||||||
|
|
||||||
|
if ($is_reversed) {
|
||||||
|
$steps = array_reverse($steps);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $steps;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorConstantChartFunction
|
||||||
|
extends PhabricatorChartFunction {
|
||||||
|
|
||||||
|
const FUNCTIONKEY = 'constant';
|
||||||
|
|
||||||
|
private $value;
|
||||||
|
|
||||||
|
protected function newArguments(array $arguments) {
|
||||||
|
if (count($arguments) !== 1) {
|
||||||
|
throw new Exception(
|
||||||
|
pht(
|
||||||
|
'Chart function "constant(...)" expects one argument, got %s. '.
|
||||||
|
'Pass a constant.',
|
||||||
|
count($arguments)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_int($arguments[0])) {
|
||||||
|
throw new Exception(
|
||||||
|
pht(
|
||||||
|
'First argument for "fact(...)" is invalid: expected int, '.
|
||||||
|
'got %s.',
|
||||||
|
phutil_describe_type($arguments[0])));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->value = $arguments[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDatapoints($limit) {
|
||||||
|
$axis = $this->getXAxis();
|
||||||
|
$x_min = $axis->getMinimumValue();
|
||||||
|
$x_max = $axis->getMaximumValue();
|
||||||
|
|
||||||
|
$points = array();
|
||||||
|
$steps = $this->newLinearSteps($x_min, $x_max, 2);
|
||||||
|
foreach ($steps as $step) {
|
||||||
|
$points[] = array(
|
||||||
|
'x' => $step,
|
||||||
|
'y' => $this->value,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $points;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasDomain() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
38
src/applications/fact/chart/PhabricatorXChartFunction.php
Normal file
38
src/applications/fact/chart/PhabricatorXChartFunction.php
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorXChartFunction
|
||||||
|
extends PhabricatorChartFunction {
|
||||||
|
|
||||||
|
const FUNCTIONKEY = 'x';
|
||||||
|
|
||||||
|
protected function newArguments(array $arguments) {
|
||||||
|
if (count($arguments) !== 0) {
|
||||||
|
throw new Exception(
|
||||||
|
pht(
|
||||||
|
'Chart function "x()" expects zero arguments, got %s.',
|
||||||
|
count($arguments)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDatapoints($limit) {
|
||||||
|
$axis = $this->getXAxis();
|
||||||
|
$x_min = $axis->getMinimumValue();
|
||||||
|
$x_max = $axis->getMaximumValue();
|
||||||
|
|
||||||
|
$points = array();
|
||||||
|
$steps = $this->newLinearSteps($x_min, $x_max, $limit);
|
||||||
|
foreach ($steps as $step) {
|
||||||
|
$points[] = array(
|
||||||
|
'x' => $step,
|
||||||
|
'y' => $step,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $points;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasDomain() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -20,9 +20,11 @@ final class PhabricatorFactChartController extends PhabricatorFactController {
|
||||||
$functions[] = id(new PhabricatorFactChartFunction())
|
$functions[] = id(new PhabricatorFactChartFunction())
|
||||||
->setArguments(array('tasks.open-count.create'));
|
->setArguments(array('tasks.open-count.create'));
|
||||||
|
|
||||||
if ($is_chart_mode) {
|
$functions[] = id(new PhabricatorConstantChartFunction())
|
||||||
return $this->newChartResponse();
|
->setArguments(array(256));
|
||||||
}
|
|
||||||
|
$functions[] = id(new PhabricatorXChartFunction())
|
||||||
|
->setArguments(array());
|
||||||
|
|
||||||
list($domain_min, $domain_max) = $this->getDomain($functions);
|
list($domain_min, $domain_max) = $this->getDomain($functions);
|
||||||
|
|
||||||
|
@ -73,6 +75,10 @@ final class PhabricatorFactChartController extends PhabricatorFactController {
|
||||||
'yMax' => $y_max,
|
'yMax' => $y_max,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if ($is_chart_mode) {
|
||||||
|
return $this->newChartResponse();
|
||||||
|
}
|
||||||
|
|
||||||
return id(new AphrontAjaxResponse())->setContent($chart_data);
|
return id(new AphrontAjaxResponse())->setContent($chart_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue