@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+164 -38
+4 -2
src/__phutil_library_map__.php
··· 2649 2649 'PhabricatorChangeParserTestCase' => 'applications/repository/worker/__tests__/PhabricatorChangeParserTestCase.php', 2650 2650 'PhabricatorChangesetCachePurger' => 'applications/cache/purger/PhabricatorChangesetCachePurger.php', 2651 2651 'PhabricatorChangesetResponse' => 'infrastructure/diff/PhabricatorChangesetResponse.php', 2652 - 'PhabricatorChartFunction' => 'applications/fact/function/PhabricatorChartFunction.php', 2652 + 'PhabricatorChartAxis' => 'applications/fact/chart/PhabricatorChartAxis.php', 2653 + 'PhabricatorChartFunction' => 'applications/fact/chart/PhabricatorChartFunction.php', 2653 2654 'PhabricatorChatLogApplication' => 'applications/chatlog/application/PhabricatorChatLogApplication.php', 2654 2655 'PhabricatorChatLogChannel' => 'applications/chatlog/storage/PhabricatorChatLogChannel.php', 2655 2656 'PhabricatorChatLogChannelListController' => 'applications/chatlog/controller/PhabricatorChatLogChannelListController.php', ··· 3204 3205 'PhabricatorFactApplication' => 'applications/fact/application/PhabricatorFactApplication.php', 3205 3206 'PhabricatorFactChart' => 'applications/fact/storage/PhabricatorFactChart.php', 3206 3207 'PhabricatorFactChartController' => 'applications/fact/controller/PhabricatorFactChartController.php', 3207 - 'PhabricatorFactChartFunction' => 'applications/fact/function/PhabricatorFactChartFunction.php', 3208 + 'PhabricatorFactChartFunction' => 'applications/fact/chart/PhabricatorFactChartFunction.php', 3208 3209 'PhabricatorFactController' => 'applications/fact/controller/PhabricatorFactController.php', 3209 3210 'PhabricatorFactCursor' => 'applications/fact/storage/PhabricatorFactCursor.php', 3210 3211 'PhabricatorFactDAO' => 'applications/fact/storage/PhabricatorFactDAO.php', ··· 8621 8622 'PhabricatorChangeParserTestCase' => 'PhabricatorWorkingCopyTestCase', 8622 8623 'PhabricatorChangesetCachePurger' => 'PhabricatorCachePurger', 8623 8624 'PhabricatorChangesetResponse' => 'AphrontProxyResponse', 8625 + 'PhabricatorChartAxis' => 'Phobject', 8624 8626 'PhabricatorChartFunction' => 'Phobject', 8625 8627 'PhabricatorChatLogApplication' => 'PhabricatorApplication', 8626 8628 'PhabricatorChatLogChannel' => array(
+27
src/applications/fact/chart/PhabricatorChartAxis.php
··· 1 + <?php 2 + 3 + final class PhabricatorChartAxis 4 + extends Phobject { 5 + 6 + private $minimumValue; 7 + private $maximumValue; 8 + 9 + public function setMinimumValue($minimum_value) { 10 + $this->minimumValue = $minimum_value; 11 + return $this; 12 + } 13 + 14 + public function getMinimumValue() { 15 + return $this->minimumValue; 16 + } 17 + 18 + public function setMaximumValue($maximum_value) { 19 + $this->maximumValue = $maximum_value; 20 + return $this; 21 + } 22 + 23 + public function getMaximumValue() { 24 + return $this->maximumValue; 25 + } 26 + 27 + }
+46
src/applications/fact/chart/PhabricatorChartFunction.php
··· 1 + <?php 2 + 3 + abstract class PhabricatorChartFunction 4 + extends Phobject { 5 + 6 + private $xAxis; 7 + private $yAxis; 8 + private $limit; 9 + 10 + final public function getFunctionKey() { 11 + return $this->getPhobjectClassConstant('FUNCTIONKEY', 32); 12 + } 13 + 14 + final public static function getAllFunctions() { 15 + return id(new PhutilClassMapQuery()) 16 + ->setAncestorClass(__CLASS__) 17 + ->setUniqueMethod('getFunctionKey') 18 + ->execute(); 19 + } 20 + 21 + final public function setArguments(array $arguments) { 22 + $this->newArguments($arguments); 23 + return $this; 24 + } 25 + 26 + abstract protected function newArguments(array $arguments); 27 + 28 + final public function setXAxis(PhabricatorChartAxis $x_axis) { 29 + $this->xAxis = $x_axis; 30 + return $this; 31 + } 32 + 33 + final public function getXAxis() { 34 + return $this->xAxis; 35 + } 36 + 37 + final public function setYAxis(PhabricatorChartAxis $y_axis) { 38 + $this->yAxis = $y_axis; 39 + return $this; 40 + } 41 + 42 + final public function getYAxis() { 43 + return $this->yAxis; 44 + } 45 + 46 + }
+56 -12
src/applications/fact/controller/PhabricatorFactChartController.php
··· 24 24 return $this->newChartResponse(); 25 25 } 26 26 27 + list($domain_min, $domain_max) = $this->getDomain($functions); 28 + 29 + $axis = id(new PhabricatorChartAxis()) 30 + ->setMinimumValue($domain_min) 31 + ->setMaximumValue($domain_max); 32 + 27 33 $datasets = array(); 28 34 foreach ($functions as $function) { 35 + $function->setXAxis($axis); 36 + 29 37 $function->loadData(); 30 38 31 39 $points = $function->getDatapoints(2000); ··· 44 52 'color' => '#ff00ff', 45 53 ); 46 54 } 55 + 47 56 48 57 $y_min = 0; 49 58 $y_max = 0; 50 - $x_min = null; 51 - $x_max = 0; 52 59 foreach ($datasets as $dataset) { 53 60 if (!$dataset['y']) { 54 61 continue; ··· 56 63 57 64 $y_min = min($y_min, min($dataset['y'])); 58 65 $y_max = max($y_max, max($dataset['y'])); 59 - 60 - if ($x_min === null) { 61 - $x_min = min($dataset['x']); 62 - } else { 63 - $x_min = min($x_min, min($dataset['x'])); 64 - } 65 - 66 - $x_max = max($x_max, max($dataset['x'])); 67 66 } 68 67 69 68 $chart_data = array( 70 69 'datasets' => $datasets, 71 - 'xMin' => $x_min, 72 - 'xMax' => $x_max, 70 + 'xMin' => $domain_min, 71 + 'xMax' => $domain_max, 73 72 'yMin' => $y_min, 74 73 'yMax' => $y_max, 75 74 ); ··· 116 115 ->appendChild($box); 117 116 118 117 } 118 + 119 + private function getDomain(array $functions) { 120 + $domain_min_list = null; 121 + $domain_max_list = null; 122 + foreach ($functions as $function) { 123 + if ($function->hasDomain()) { 124 + $domain = $function->getDomain(); 125 + 126 + list($domain_min, $domain_max) = $domain; 127 + 128 + if ($domain_min !== null) { 129 + $domain_min_list[] = $domain_min; 130 + } 131 + 132 + if ($domain_max !== null) { 133 + $domain_max_list[] = $domain_max; 134 + } 135 + } 136 + } 137 + 138 + $domain_min = null; 139 + $domain_max = null; 140 + 141 + if ($domain_min_list) { 142 + $domain_min = min($domain_min_list); 143 + } 144 + 145 + if ($domain_max_list) { 146 + $domain_max = max($domain_max_list); 147 + } 148 + 149 + // If we don't have any domain data from the actual functions, pick a 150 + // plausible domain automatically. 151 + 152 + if ($domain_max === null) { 153 + $domain_max = PhabricatorTime::getNow(); 154 + } 155 + 156 + if ($domain_min === null) { 157 + $domain_min = $domain_max - phutil_units('365 days in seconds'); 158 + } 159 + 160 + return array($domain_min, $domain_max); 161 + } 162 + 119 163 120 164 }
-24
src/applications/fact/function/PhabricatorChartFunction.php
··· 1 - <?php 2 - 3 - abstract class PhabricatorChartFunction 4 - extends Phobject { 5 - 6 - final public function getFunctionKey() { 7 - return $this->getPhobjectClassConstant('FUNCTIONKEY', 32); 8 - } 9 - 10 - final public static function getAllFunctions() { 11 - return id(new PhutilClassMapQuery()) 12 - ->setAncestorClass(__CLASS__) 13 - ->setUniqueMethod('getFunctionKey') 14 - ->execute(); 15 - } 16 - 17 - final public function setArguments(array $arguments) { 18 - $this->newArguments($arguments); 19 - return $this; 20 - } 21 - 22 - abstract protected function newArguments(array $arguments); 23 - 24 - }
+31
src/applications/fact/function/PhabricatorFactChartFunction.php src/applications/fact/chart/PhabricatorFactChartFunction.php
··· 83 83 return array(); 84 84 } 85 85 86 + $axis = $this->getXAxis(); 87 + $x_min = $axis->getMinimumValue(); 88 + $x_max = $axis->getMaximumValue(); 89 + 90 + if ($x_min !== null) { 91 + foreach ($points as $key => $point) { 92 + if ($point['x'] < $x_min) { 93 + unset($points[$key]); 94 + } 95 + } 96 + } 97 + 98 + if ($x_max !== null) { 99 + foreach ($points as $key => $point) { 100 + if ($point['x'] > $x_max) { 101 + unset($points[$key]); 102 + } 103 + } 104 + } 105 + 86 106 // If we have too many data points, throw away some of the data. 87 107 $count = count($points); 88 108 if ($count > $limit) { ··· 97 117 } 98 118 99 119 return $points; 120 + } 121 + 122 + public function hasDomain() { 123 + return true; 124 + } 125 + 126 + public function getDomain() { 127 + // TODO: We can examine the data to fit a better domain. 128 + 129 + $now = PhabricatorTime::getNow(); 130 + return array($now - phutil_units('90 days in seconds'), $now); 100 131 } 101 132 102 133 }