1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-10 08:52:39 +01:00

Select the domain (X-axis range) for charts before pulling data

Summary:
Depends on D20441. Ref T13279. Currently, we pull all the data, then decide what the X-axis should look like.

Since users will reasonably want to do stuff like "show me march-april 2018" in the future, we need to move toward flipping this around so that we can support cases where the domain is specified by the user.

For actual chart functions (like "constant(3)" or "cos(x)"), we must also know the domain before we pull data, since there are an infinite number of places where we can evaluate the function "constant(3)".

See note in T13279 about continunity.

Test Plan: {F6382356}

Reviewers: amckinley

Reviewed By: amckinley

Subscribers: yelirekim

Maniphest Tasks: T13279

Differential Revision: https://secure.phabricator.com/D20442
This commit is contained in:
epriestley 2019-04-17 06:05:34 -07:00
parent 954831f533
commit 23d8f000f7
5 changed files with 140 additions and 14 deletions

View file

@ -2649,7 +2649,8 @@ phutil_register_library_map(array(
'PhabricatorChangeParserTestCase' => 'applications/repository/worker/__tests__/PhabricatorChangeParserTestCase.php',
'PhabricatorChangesetCachePurger' => 'applications/cache/purger/PhabricatorChangesetCachePurger.php',
'PhabricatorChangesetResponse' => 'infrastructure/diff/PhabricatorChangesetResponse.php',
'PhabricatorChartFunction' => 'applications/fact/function/PhabricatorChartFunction.php',
'PhabricatorChartAxis' => 'applications/fact/chart/PhabricatorChartAxis.php',
'PhabricatorChartFunction' => 'applications/fact/chart/PhabricatorChartFunction.php',
'PhabricatorChatLogApplication' => 'applications/chatlog/application/PhabricatorChatLogApplication.php',
'PhabricatorChatLogChannel' => 'applications/chatlog/storage/PhabricatorChatLogChannel.php',
'PhabricatorChatLogChannelListController' => 'applications/chatlog/controller/PhabricatorChatLogChannelListController.php',
@ -3204,7 +3205,7 @@ phutil_register_library_map(array(
'PhabricatorFactApplication' => 'applications/fact/application/PhabricatorFactApplication.php',
'PhabricatorFactChart' => 'applications/fact/storage/PhabricatorFactChart.php',
'PhabricatorFactChartController' => 'applications/fact/controller/PhabricatorFactChartController.php',
'PhabricatorFactChartFunction' => 'applications/fact/function/PhabricatorFactChartFunction.php',
'PhabricatorFactChartFunction' => 'applications/fact/chart/PhabricatorFactChartFunction.php',
'PhabricatorFactController' => 'applications/fact/controller/PhabricatorFactController.php',
'PhabricatorFactCursor' => 'applications/fact/storage/PhabricatorFactCursor.php',
'PhabricatorFactDAO' => 'applications/fact/storage/PhabricatorFactDAO.php',
@ -8621,6 +8622,7 @@ phutil_register_library_map(array(
'PhabricatorChangeParserTestCase' => 'PhabricatorWorkingCopyTestCase',
'PhabricatorChangesetCachePurger' => 'PhabricatorCachePurger',
'PhabricatorChangesetResponse' => 'AphrontProxyResponse',
'PhabricatorChartAxis' => 'Phobject',
'PhabricatorChartFunction' => 'Phobject',
'PhabricatorChatLogApplication' => 'PhabricatorApplication',
'PhabricatorChatLogChannel' => array(

View file

@ -0,0 +1,27 @@
<?php
final class PhabricatorChartAxis
extends Phobject {
private $minimumValue;
private $maximumValue;
public function setMinimumValue($minimum_value) {
$this->minimumValue = $minimum_value;
return $this;
}
public function getMinimumValue() {
return $this->minimumValue;
}
public function setMaximumValue($maximum_value) {
$this->maximumValue = $maximum_value;
return $this;
}
public function getMaximumValue() {
return $this->maximumValue;
}
}

View file

@ -3,6 +3,10 @@
abstract class PhabricatorChartFunction
extends Phobject {
private $xAxis;
private $yAxis;
private $limit;
final public function getFunctionKey() {
return $this->getPhobjectClassConstant('FUNCTIONKEY', 32);
}
@ -21,4 +25,22 @@ abstract class PhabricatorChartFunction
abstract protected function newArguments(array $arguments);
final public function setXAxis(PhabricatorChartAxis $x_axis) {
$this->xAxis = $x_axis;
return $this;
}
final public function getXAxis() {
return $this->xAxis;
}
final public function setYAxis(PhabricatorChartAxis $y_axis) {
$this->yAxis = $y_axis;
return $this;
}
final public function getYAxis() {
return $this->yAxis;
}
}

View file

@ -83,6 +83,26 @@ final class PhabricatorFactChartFunction
return array();
}
$axis = $this->getXAxis();
$x_min = $axis->getMinimumValue();
$x_max = $axis->getMaximumValue();
if ($x_min !== null) {
foreach ($points as $key => $point) {
if ($point['x'] < $x_min) {
unset($points[$key]);
}
}
}
if ($x_max !== null) {
foreach ($points as $key => $point) {
if ($point['x'] > $x_max) {
unset($points[$key]);
}
}
}
// If we have too many data points, throw away some of the data.
$count = count($points);
if ($count > $limit) {
@ -99,4 +119,15 @@ final class PhabricatorFactChartFunction
return $points;
}
public function hasDomain() {
return true;
}
public function getDomain() {
// TODO: We can examine the data to fit a better domain.
$now = PhabricatorTime::getNow();
return array($now - phutil_units('90 days in seconds'), $now);
}
}

View file

@ -24,8 +24,16 @@ final class PhabricatorFactChartController extends PhabricatorFactController {
return $this->newChartResponse();
}
list($domain_min, $domain_max) = $this->getDomain($functions);
$axis = id(new PhabricatorChartAxis())
->setMinimumValue($domain_min)
->setMaximumValue($domain_max);
$datasets = array();
foreach ($functions as $function) {
$function->setXAxis($axis);
$function->loadData();
$points = $function->getDatapoints(2000);
@ -45,10 +53,9 @@ final class PhabricatorFactChartController extends PhabricatorFactController {
);
}
$y_min = 0;
$y_max = 0;
$x_min = null;
$x_max = 0;
foreach ($datasets as $dataset) {
if (!$dataset['y']) {
continue;
@ -56,20 +63,12 @@ final class PhabricatorFactChartController extends PhabricatorFactController {
$y_min = min($y_min, min($dataset['y']));
$y_max = max($y_max, max($dataset['y']));
if ($x_min === null) {
$x_min = min($dataset['x']);
} else {
$x_min = min($x_min, min($dataset['x']));
}
$x_max = max($x_max, max($dataset['x']));
}
$chart_data = array(
'datasets' => $datasets,
'xMin' => $x_min,
'xMax' => $x_max,
'xMin' => $domain_min,
'xMax' => $domain_max,
'yMin' => $y_min,
'yMax' => $y_max,
);
@ -117,4 +116,49 @@ final class PhabricatorFactChartController extends PhabricatorFactController {
}
private function getDomain(array $functions) {
$domain_min_list = null;
$domain_max_list = null;
foreach ($functions as $function) {
if ($function->hasDomain()) {
$domain = $function->getDomain();
list($domain_min, $domain_max) = $domain;
if ($domain_min !== null) {
$domain_min_list[] = $domain_min;
}
if ($domain_max !== null) {
$domain_max_list[] = $domain_max;
}
}
}
$domain_min = null;
$domain_max = null;
if ($domain_min_list) {
$domain_min = min($domain_min_list);
}
if ($domain_max_list) {
$domain_max = max($domain_max_list);
}
// If we don't have any domain data from the actual functions, pick a
// plausible domain automatically.
if ($domain_max === null) {
$domain_max = PhabricatorTime::getNow();
}
if ($domain_min === null) {
$domain_min = $domain_max - phutil_units('365 days in seconds');
}
return array($domain_min, $domain_max);
}
}