Path: blob/master/src/applications/fact/chart/PhabricatorAccumulateChartFunction.php
12256 views
<?php12final class PhabricatorAccumulateChartFunction3extends PhabricatorHigherOrderChartFunction {45const FUNCTIONKEY = 'accumulate';67protected function newArguments() {8return array(9$this->newArgument()10->setName('x')11->setType('function'),12);13}1415public function evaluateFunction(array $xv) {16// First, we're going to accumulate the underlying function. Then17// we'll map the inputs through the accumulation.1819$datasource = $this->getArgument('x');2021// Use an unconstrained query to pull all the data from the underlying22// source. We need to accumulate data since the beginning of time to23// figure out the right Y-intercept -- otherwise, we'll always start at24// "0" wherever our domain begins.25$empty_query = new PhabricatorChartDataQuery();2627$datasource_xv = $datasource->newInputValues($empty_query);28if (!$datasource_xv) {29// When the datasource has no datapoints, we can't evaluate the function30// anywhere.31return array_fill(0, count($xv), null);32}3334$yv = $datasource->evaluateFunction($datasource_xv);3536$map = array_combine($datasource_xv, $yv);3738$accumulator = 0;39foreach ($map as $x => $y) {40$accumulator += $y;41$map[$x] = $accumulator;42}4344// The value of "accumulate(x)" is the largest datapoint in the map which45// is no larger than "x".4647$map_x = array_keys($map);48$idx = -1;49$max = count($map_x) - 1;5051$yv = array();5253$value = 0;54foreach ($xv as $x) {55// While the next "x" we need to evaluate the function at lies to the56// right of the next datapoint, move the current datapoint forward until57// we're at the rightmost datapoint which is not larger than "x".58while ($idx < $max) {59if ($map_x[$idx + 1] > $x) {60break;61}6263$idx++;64$value = $map[$map_x[$idx]];65}6667$yv[] = $value;68}6970return $yv;71}7273}747576