@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<?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}