diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -2649,7 +2649,8 @@ '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 @@ '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 @@ 'PhabricatorChangeParserTestCase' => 'PhabricatorWorkingCopyTestCase', 'PhabricatorChangesetCachePurger' => 'PhabricatorCachePurger', 'PhabricatorChangesetResponse' => 'AphrontProxyResponse', + 'PhabricatorChartAxis' => 'Phobject', 'PhabricatorChartFunction' => 'Phobject', 'PhabricatorChatLogApplication' => 'PhabricatorApplication', 'PhabricatorChatLogChannel' => array( diff --git a/src/applications/fact/chart/PhabricatorChartAxis.php b/src/applications/fact/chart/PhabricatorChartAxis.php new file mode 100644 --- /dev/null +++ b/src/applications/fact/chart/PhabricatorChartAxis.php @@ -0,0 +1,27 @@ +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; + } + +} diff --git a/src/applications/fact/function/PhabricatorChartFunction.php b/src/applications/fact/chart/PhabricatorChartFunction.php rename from src/applications/fact/function/PhabricatorChartFunction.php rename to src/applications/fact/chart/PhabricatorChartFunction.php --- a/src/applications/fact/function/PhabricatorChartFunction.php +++ b/src/applications/fact/chart/PhabricatorChartFunction.php @@ -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 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; + } + } diff --git a/src/applications/fact/function/PhabricatorFactChartFunction.php b/src/applications/fact/chart/PhabricatorFactChartFunction.php rename from src/applications/fact/function/PhabricatorFactChartFunction.php rename to src/applications/fact/chart/PhabricatorFactChartFunction.php --- a/src/applications/fact/function/PhabricatorFactChartFunction.php +++ b/src/applications/fact/chart/PhabricatorFactChartFunction.php @@ -83,6 +83,26 @@ 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 @@ 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); + } + } diff --git a/src/applications/fact/controller/PhabricatorFactChartController.php b/src/applications/fact/controller/PhabricatorFactChartController.php --- a/src/applications/fact/controller/PhabricatorFactChartController.php +++ b/src/applications/fact/controller/PhabricatorFactChartController.php @@ -24,8 +24,16 @@ 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 @@ ); } + $y_min = 0; $y_max = 0; - $x_min = null; - $x_max = 0; foreach ($datasets as $dataset) { if (!$dataset['y']) { continue; @@ -56,20 +63,12 @@ $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 @@ } + 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); + } + + }