1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-02-02 01:48:23 +01:00

Add a "sin()" function to charts

Summary:
Depends on D20443. Ref T13279. This is probably not terribly useful on its own, but is mostly a function which takes another function as an argument, and a step toward more useful functions like arithmetic and drawing a picture of an owl.

The only structural change here is that functions now read data parameters (domain, sample limit) using a more tailored "ChartDataQuery" instead of reading the actual axis. Mostly, I want a more cohesive representation of query state that can be easily passed to sub-functions, as here.

Test Plan: {F6382432}

Reviewers: amckinley

Reviewed By: amckinley

Subscribers: yelirekim

Maniphest Tasks: T13279

Differential Revision: https://secure.phabricator.com/D20444
This commit is contained in:
epriestley 2019-04-17 07:17:28 -07:00
parent c4e4448ee6
commit d8dba26a08
7 changed files with 116 additions and 25 deletions

View file

@ -2650,6 +2650,7 @@ phutil_register_library_map(array(
'PhabricatorChangesetCachePurger' => 'applications/cache/purger/PhabricatorChangesetCachePurger.php',
'PhabricatorChangesetResponse' => 'infrastructure/diff/PhabricatorChangesetResponse.php',
'PhabricatorChartAxis' => 'applications/fact/chart/PhabricatorChartAxis.php',
'PhabricatorChartDataQuery' => 'applications/fact/chart/PhabricatorChartDataQuery.php',
'PhabricatorChartFunction' => 'applications/fact/chart/PhabricatorChartFunction.php',
'PhabricatorChatLogApplication' => 'applications/chatlog/application/PhabricatorChatLogApplication.php',
'PhabricatorChatLogChannel' => 'applications/chatlog/storage/PhabricatorChatLogChannel.php',
@ -4564,6 +4565,7 @@ phutil_register_library_map(array(
'PhabricatorShortSite' => 'aphront/site/PhabricatorShortSite.php',
'PhabricatorShowFiletreeSetting' => 'applications/settings/setting/PhabricatorShowFiletreeSetting.php',
'PhabricatorSimpleEditType' => 'applications/transactions/edittype/PhabricatorSimpleEditType.php',
'PhabricatorSinChartFunction' => 'applications/fact/chart/PhabricatorSinChartFunction.php',
'PhabricatorSite' => 'aphront/site/PhabricatorSite.php',
'PhabricatorSlackAuthProvider' => 'applications/auth/provider/PhabricatorSlackAuthProvider.php',
'PhabricatorSlowvoteApplication' => 'applications/slowvote/application/PhabricatorSlowvoteApplication.php',
@ -8625,6 +8627,7 @@ phutil_register_library_map(array(
'PhabricatorChangesetCachePurger' => 'PhabricatorCachePurger',
'PhabricatorChangesetResponse' => 'AphrontProxyResponse',
'PhabricatorChartAxis' => 'Phobject',
'PhabricatorChartDataQuery' => 'Phobject',
'PhabricatorChartFunction' => 'Phobject',
'PhabricatorChatLogApplication' => 'PhabricatorApplication',
'PhabricatorChatLogChannel' => array(
@ -10860,6 +10863,7 @@ phutil_register_library_map(array(
'PhabricatorShortSite' => 'PhabricatorSite',
'PhabricatorShowFiletreeSetting' => 'PhabricatorSelectSetting',
'PhabricatorSimpleEditType' => 'PhabricatorEditType',
'PhabricatorSinChartFunction' => 'PhabricatorChartFunction',
'PhabricatorSite' => 'AphrontSite',
'PhabricatorSlackAuthProvider' => 'PhabricatorOAuth2AuthProvider',
'PhabricatorSlowvoteApplication' => 'PhabricatorApplication',

View file

@ -0,0 +1,37 @@
<?php
final class PhabricatorChartDataQuery
extends Phobject {
private $limit;
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;
}
public function setLimit($limit) {
$this->limit = $limit;
return $this;
}
public function getLimit() {
return $this->limit;
}
}

View file

@ -27,10 +27,9 @@ final class PhabricatorConstantChartFunction
$this->value = $arguments[0];
}
public function getDatapoints($limit) {
$axis = $this->getXAxis();
$x_min = $axis->getMinimumValue();
$x_max = $axis->getMaximumValue();
public function getDatapoints(PhabricatorChartDataQuery $query) {
$x_min = $query->getMinimumValue();
$x_max = $query->getMaximumValue();
$points = array();
$steps = $this->newLinearSteps($x_min, $x_max, 2);

View file

@ -77,15 +77,15 @@ final class PhabricatorFactChartFunction
$this->datapoints = $points;
}
public function getDatapoints($limit) {
public function getDatapoints(PhabricatorChartDataQuery $query) {
$points = $this->datapoints;
if (!$points) {
return array();
}
$axis = $this->getXAxis();
$x_min = $axis->getMinimumValue();
$x_max = $axis->getMaximumValue();
$x_min = $query->getMinimumValue();
$x_max = $query->getMaximumValue();
$limit = $query->getLimit();
if ($x_min !== null) {
foreach ($points as $key => $point) {
@ -104,14 +104,16 @@ final class PhabricatorFactChartFunction
}
// If we have too many data points, throw away some of the data.
$count = count($points);
if ($count > $limit) {
$ii = 0;
$every = ceil($count / $limit);
foreach ($points as $key => $point) {
$ii++;
if (($ii % $every) && ($ii != $count)) {
unset($points[$key]);
if ($limit !== null) {
$count = count($points);
if ($count > $limit) {
$ii = 0;
$every = ceil($count / $limit);
foreach ($points as $key => $point) {
$ii++;
if (($ii % $every) && ($ii != $count)) {
unset($points[$key]);
}
}
}
}

View file

@ -0,0 +1,44 @@
<?php
final class PhabricatorSinChartFunction
extends PhabricatorChartFunction {
const FUNCTIONKEY = 'sin';
private $argument;
protected function newArguments(array $arguments) {
if (count($arguments) !== 1) {
throw new Exception(
pht(
'Chart function "sin(..)" expects one argument, got %s.',
count($arguments)));
}
$argument = $arguments[0];
if (!($argument instanceof PhabricatorChartFunction)) {
throw new Exception(
pht(
'Argument to chart function should be a function, got %s.',
phutil_describe_type($argument)));
}
$this->argument = $argument;
}
public function getDatapoints(PhabricatorChartDataQuery $query) {
$points = $this->argument->getDatapoints($query);
foreach ($points as $key => $point) {
$points[$key]['y'] = sin(deg2rad($points[$key]['y']));
}
return $points;
}
public function hasDomain() {
return false;
}
}

View file

@ -14,10 +14,10 @@ final class PhabricatorXChartFunction
}
}
public function getDatapoints($limit) {
$axis = $this->getXAxis();
$x_min = $axis->getMinimumValue();
$x_max = $axis->getMaximumValue();
public function getDatapoints(PhabricatorChartDataQuery $query) {
$x_min = $query->getMinimumValue();
$x_max = $query->getMaximumValue();
$limit = $query->getLimit();
$points = array();
$steps = $this->newLinearSteps($x_min, $x_max, $limit);

View file

@ -20,25 +20,30 @@ final class PhabricatorFactChartController extends PhabricatorFactController {
$functions[] = id(new PhabricatorFactChartFunction())
->setArguments(array('tasks.open-count.create'));
$functions[] = id(new PhabricatorConstantChartFunction())
->setArguments(array(256));
$functions[] = id(new PhabricatorXChartFunction())
$x_function = id(new PhabricatorXChartFunction())
->setArguments(array());
$functions[] = id(new PhabricatorSinChartFunction())
->setArguments(array($x_function));
list($domain_min, $domain_max) = $this->getDomain($functions);
$axis = id(new PhabricatorChartAxis())
->setMinimumValue($domain_min)
->setMaximumValue($domain_max);
$data_query = id(new PhabricatorChartDataQuery())
->setMinimumValue($domain_min)
->setMaximumValue($domain_max)
->setLimit(2000);
$datasets = array();
foreach ($functions as $function) {
$function->setXAxis($axis);
$function->loadData();
$points = $function->getDatapoints(2000);
$points = $function->getDatapoints($data_query);
$x = array();
$y = array();