Issues (459)

src/plot/AccLinePlot.php (4 issues)

1
<?php
2
3
/**
4
 * JPGraph v4.0.3
5
 */
6
7
namespace Amenadiel\JpGraph\Plot;
8
9
use Amenadiel\JpGraph\Util;
10
11
/**
12
 * @class AccLinePlot
13
 * // Description:
14
 */
15
class AccLinePlot extends Plot
16
{
17
    protected $plots;
18
    protected $nbrplots    = 0;
19
    private $iStartEndZero = true;
20
21
    /**
22
     * CONSTRUCTOR.
23
     *
24
     * @param mixed $plots
25
     */
26 1
    public function __construct($plots)
27
    {
28 1
        $this->plots     = $plots;
29 1
        $this->nbrplots  = safe_count($plots);
30 1
        $this->numpoints = $plots[0]->numpoints;
31
32
        // Verify that all plots have the same number of data points
33 1
        for ($i = 1; $i < $this->nbrplots; ++$i) {
34 1
            if ($plots[$i]->numpoints != $this->numpoints) {
35
                Util\JpGraphError::RaiseL(10003); //('Each plot in an accumulated lineplot must have the same number of data points',0)
36
            }
37
        }
38
39 1
        for ($i = 0; $i < $this->nbrplots; ++$i) {
40 1
            $this->LineInterpolate($this->plots[$i]->coords[0]);
41
        }
42 1
    }
43
44
    /**
45
     * PUBLIC METHODS.
46
     *
47
     * @param mixed $graph
48
     */
49 1
    public function Legend($graph)
50
    {
51 1
        foreach ($this->plots as $p) {
52 1
            $p->DoLegend($graph);
53
        }
54 1
    }
55
56 1
    public function Max()
57
    {
58 1
        list($xmax) = $this->plots[0]->Max();
59 1
        $nmax       = 0;
60 1
        $n          = safe_count($this->plots);
61 1
        for ($i = 0; $i < $n; ++$i) {
62 1
            $nc      = safe_count($this->plots[$i]->coords[0]);
63 1
            $nmax    = max($nmax, $nc);
64 1
            list($x) = $this->plots[$i]->Max();
65 1
            $xmax    = max($xmax, $x);
66
        }
67 1
        for ($i = 0; $i < $nmax; ++$i) {
68
            // Get y-value for line $i by adding the
69
            // individual bars from all the plots added.
70
            // It would be wrong to just add the
71
            // individual plots max y-value since that
72
            // would in most cases give to large y-value.
73 1
            $y = $this->plots[0]->coords[0][$i];
74 1
            for ($j = 1; $j < $this->nbrplots; ++$j) {
75 1
                $y += $this->plots[$j]->coords[0][$i];
76
            }
77 1
            $ymax[$i] = $y;
78
        }
79 1
        $ymax = max($ymax);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $ymax does not seem to be defined for all execution paths leading up to this point.
Loading history...
80
81 1
        return [$xmax, $ymax];
82
    }
83
84 1
    public function Min()
85
    {
86 1
        $nmax                 = 0;
87 1
        list($xmin, $ysetmin) = $this->plots[0]->Min();
88 1
        $n                    = safe_count($this->plots);
89 1
        for ($i = 0; $i < $n; ++$i) {
90 1
            $nc          = safe_count($this->plots[$i]->coords[0]);
91 1
            $nmax        = max($nmax, $nc);
92 1
            list($x, $y) = $this->plots[$i]->Min();
93 1
            $xmin        = min($xmin, $x);
94 1
            $ysetmin     = min($y, $ysetmin);
95
        }
96 1
        for ($i = 0; $i < $nmax; ++$i) {
97
            // Get y-value for line $i by adding the
98
            // individual bars from all the plots added.
99
            // It would be wrong to just add the
100
            // individual plots min y-value since that
101
            // would in most cases give to small y-value.
102 1
            $y = $this->plots[0]->coords[0][$i];
103 1
            for ($j = 1; $j < $this->nbrplots; ++$j) {
104 1
                $y += $this->plots[$j]->coords[0][$i];
105
            }
106 1
            $ymin[$i] = $y;
107
        }
108 1
        $ymin = min($ysetmin, min($ymin));
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $ymin does not seem to be defined for all execution paths leading up to this point.
Loading history...
109
110 1
        return [$xmin, $ymin];
111
    }
112
113
    // Gets called before any axis are stroked
114 1
    public function PreStrokeAdjust($graph)
115
    {
116
        // If another plot type have already adjusted the
117
        // offset we don't touch it.
118
        // (We check for empty in case the scale is  a log scale
119
        // and hence doesn't contain any xlabel_offset)
120
121 1
        if (empty($graph->xaxis->scale->ticks->xlabel_offset) ||
122 1
            $graph->xaxis->scale->ticks->xlabel_offset == 0) {
123 1
            if ($this->center) {
124
                ++$this->numpoints;
125
                $a = 0.5;
126
                $b = 0.5;
127
            } else {
128 1
                $a = 0;
129 1
                $b = 0;
130
            }
131 1
            $graph->xaxis->scale->ticks->SetXLabelOffset($a);
132 1
            $graph->SetTextScaleOff($b);
133 1
            $graph->xaxis->scale->ticks->SupressMinorTickMarks();
134
        }
135 1
    }
136
137
    public function SetInterpolateMode($aIntMode)
138
    {
139
        $this->iStartEndZero = $aIntMode;
140
    }
141
142
    // Replace all '-' with an interpolated value. We use straightforward
143
    // linear interpolation. If the data starts with one or several '-' they
144
    // will be replaced by the the first valid data point
145 1
    public function LineInterpolate(&$aData)
146
    {
147 1
        $n = safe_count($aData);
148 1
        $i = 0;
149
150
        // If first point is undefined we will set it to the same as the first
151
        // valid data
152 1
        if ($aData[$i] === '-') {
153
            // Find the first valid data
154
            while ($i < $n && $aData[$i] === '-') {
155
                ++$i;
156
            }
157
            if ($i < $n) {
158
                for ($j = 0; $j < $i; ++$j) {
159
                    if ($this->iStartEndZero) {
160
                        $aData[$i] = 0;
161
                    } else {
162
                        $aData[$j] = $aData[$i];
163
                    }
164
                }
165
            } else {
166
                // All '-' => Error
167
                return false;
168
            }
169
        }
170
171 1
        while ($i < $n) {
172 1
            while ($i < $n && $aData[$i] !== '-') {
173 1
                ++$i;
174
            }
175 1
            if ($i < $n) {
176
                $pstart = $i - 1;
177
178
                // Now see how long this segment of '-' are
179
                while ($i < $n && $aData[$i] === '-') {
180
                    ++$i;
181
                }
182
                if ($i < $n) {
183
                    $pend = $i;
184
                    $size = $pend - $pstart;
185
                    $k    = ($aData[$pend] - $aData[$pstart]) / $size;
186
                    // Replace the segment of '-' with a linear interpolated value.
187
                    for ($j = 1; $j < $size; ++$j) {
188
                        $aData[$pstart + $j] = $aData[$pstart] + $j * $k;
189
                    }
190
                } else {
191
                    // There are no valid end point. The '-' goes all the way to the end
192
                    // In that case we just set all the remaining values the the same as the
193
                    // last valid data point.
194
                    for ($j = $pstart + 1; $j < $n; ++$j) {
195
                        if ($this->iStartEndZero) {
196
                            $aData[$j] = 0;
197
                        } else {
198
                            $aData[$j] = $aData[$pstart];
199
                        }
200
                    }
201
                }
202
            }
203
        }
204
205 1
        return true;
206
    }
207
208
    // To avoid duplicate of line drawing code here we just
209
    // change the y-values for each plot and then restore it
210
    // after we have made the stroke. We must do this copy since
211
    // it wouldn't be possible to create an acc line plot
212
    // with the same graphs, i.e AccLinePlot(array($pl,$pl,$pl));
213
    // since this method would have a side effect.
214 1
    public function Stroke($img, $xscale, $yscale)
215
    {
216 1
        $img->SetLineWeight($this->weight);
217 1
        $this->numpoints = safe_count($this->plots[0]->coords[0]);
218
        // Allocate array
219 1
        $coords[$this->nbrplots][$this->numpoints] = 0;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$coords was never initialized. Although not strictly required by PHP, it is generally a good practice to add $coords = array(); before regardless.
Loading history...
220 1
        for ($i = 0; $i < $this->numpoints; ++$i) {
221 1
            $coords[0][$i] = $this->plots[0]->coords[0][$i];
222 1
            $accy          = $coords[0][$i];
223 1
            for ($j = 1; $j < $this->nbrplots; ++$j) {
224 1
                $coords[$j][$i] = $this->plots[$j]->coords[0][$i] + $accy;
225 1
                $accy           = $coords[$j][$i];
226
            }
227
        }
228 1
        for ($j = $this->nbrplots - 1; $j >= 0; --$j) {
229 1
            $p = $this->plots[$j];
230 1
            for ($i = 0; $i < $this->numpoints; ++$i) {
231 1
                $tmp[$i]          = $p->coords[0][$i];
232 1
                $p->coords[0][$i] = $coords[$j][$i];
233
            }
234 1
            $p->Stroke($img, $xscale, $yscale);
235 1
            for ($i = 0; $i < $this->numpoints; ++$i) {
236 1
                $p->coords[0][$i] = $tmp[$i];
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $tmp does not seem to be defined for all execution paths leading up to this point.
Loading history...
237
            }
238 1
            $p->coords[0][] = $tmp;
239
        }
240 1
    }
241
} // @class
242