@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
at upstream/main 74 lines 2.0 kB view raw
1<?php 2 3final class PhabricatorAccumulateChartFunction 4 extends PhabricatorHigherOrderChartFunction { 5 6 const FUNCTIONKEY = 'accumulate'; 7 8 protected function newArguments() { 9 return array( 10 $this->newArgument() 11 ->setName('x') 12 ->setType('function'), 13 ); 14 } 15 16 public function evaluateFunction(array $xv) { 17 // First, we're going to accumulate the underlying function. Then 18 // we'll map the inputs through the accumulation. 19 20 $datasource = $this->getArgument('x'); 21 22 // Use an unconstrained query to pull all the data from the underlying 23 // source. We need to accumulate data since the beginning of time to 24 // figure out the right Y-intercept -- otherwise, we'll always start at 25 // "0" wherever our domain begins. 26 $empty_query = new PhabricatorChartDataQuery(); 27 28 $datasource_xv = $datasource->newInputValues($empty_query); 29 if (!$datasource_xv) { 30 // When the datasource has no datapoints, we can't evaluate the function 31 // anywhere. 32 return array_fill(0, count($xv), null); 33 } 34 35 $yv = $datasource->evaluateFunction($datasource_xv); 36 37 $map = array_combine($datasource_xv, $yv); 38 39 $accumulator = 0; 40 foreach ($map as $x => $y) { 41 $accumulator += $y; 42 $map[$x] = $accumulator; 43 } 44 45 // The value of "accumulate(x)" is the largest datapoint in the map which 46 // is no larger than "x". 47 48 $map_x = array_keys($map); 49 $idx = -1; 50 $max = count($map_x) - 1; 51 52 $yv = array(); 53 54 $value = 0; 55 foreach ($xv as $x) { 56 // While the next "x" we need to evaluate the function at lies to the 57 // right of the next datapoint, move the current datapoint forward until 58 // we're at the rightmost datapoint which is not larger than "x". 59 while ($idx < $max) { 60 if ($map_x[$idx + 1] > $x) { 61 break; 62 } 63 64 $idx++; 65 $value = $map[$map_x[$idx]]; 66 } 67 68 $yv[] = $value; 69 } 70 71 return $yv; 72 } 73 74}