1 | <?php |
---|
2 | /*======================================================================= |
---|
3 | // File: JPGRAPH_STOCK.PHP |
---|
4 | // Description: Stock plot extension for JpGraph |
---|
5 | // Created: 2003-01-27 |
---|
6 | // Ver: $Id: jpgraph_stock.php 1364 2009-06-24 07:07:44Z ljp $ |
---|
7 | // |
---|
8 | // Copyright (c) Asial Corporation. All rights reserved. |
---|
9 | //======================================================================== |
---|
10 | */ |
---|
11 | |
---|
12 | //=================================================== |
---|
13 | // CLASS StockPlot |
---|
14 | //=================================================== |
---|
15 | class StockPlot extends Plot { |
---|
16 | protected $iTupleSize = 4; |
---|
17 | private $iWidth=9; |
---|
18 | private $iEndLines=1; |
---|
19 | private $iStockColor1='white',$iStockColor2='darkred',$iStockColor3='darkred'; |
---|
20 | //--------------- |
---|
21 | // CONSTRUCTOR |
---|
22 | function __construct($datay,$datax=false) { |
---|
23 | if( count($datay) % $this->iTupleSize ) { |
---|
24 | JpGraphError::RaiseL(21001,$this->iTupleSize); |
---|
25 | //('Data values for Stock charts must contain an even multiple of '.$this->iTupleSize.' data points.'); |
---|
26 | } |
---|
27 | parent::__construct($datay,$datax); |
---|
28 | $this->numpoints /= $this->iTupleSize; |
---|
29 | } |
---|
30 | //--------------- |
---|
31 | // PUBLIC METHODS |
---|
32 | |
---|
33 | function SetColor($aColor,$aColor1='white',$aColor2='darkred',$aColor3='darkred') { |
---|
34 | $this->color = $aColor; |
---|
35 | $this->iStockColor1 = $aColor1; |
---|
36 | $this->iStockColor2 = $aColor2; |
---|
37 | $this->iStockColor3 = $aColor3; |
---|
38 | } |
---|
39 | |
---|
40 | function SetWidth($aWidth) { |
---|
41 | // Make sure it's odd |
---|
42 | $this->iWidth = 2*floor($aWidth/2)+1; |
---|
43 | } |
---|
44 | |
---|
45 | function HideEndLines($aHide=true) { |
---|
46 | $this->iEndLines = !$aHide; |
---|
47 | } |
---|
48 | |
---|
49 | // Gets called before any axis are stroked |
---|
50 | function PreStrokeAdjust($graph) { |
---|
51 | if( $this->center ) { |
---|
52 | $a=0.5; $b=0.5; |
---|
53 | $this->numpoints++; |
---|
54 | } else { |
---|
55 | $a=0; $b=0; |
---|
56 | } |
---|
57 | $graph->xaxis->scale->ticks->SetXLabelOffset($a); |
---|
58 | $graph->SetTextScaleOff($b); |
---|
59 | } |
---|
60 | |
---|
61 | // Method description |
---|
62 | function Stroke($img,$xscale,$yscale) { |
---|
63 | $n=$this->numpoints; |
---|
64 | if( $this->center ) $n--; |
---|
65 | if( isset($this->coords[1]) ) { |
---|
66 | if( count($this->coords[1])!=$n ) { |
---|
67 | JpGraphError::RaiseL(2003,count($this->coords[1]),$n); |
---|
68 | // ("Number of X and Y points are not equal. Number of X-points:".count($this->coords[1])." Number of Y-points:$numpoints"); |
---|
69 | } |
---|
70 | else { |
---|
71 | $exist_x = true; |
---|
72 | } |
---|
73 | } |
---|
74 | else { |
---|
75 | $exist_x = false; |
---|
76 | } |
---|
77 | |
---|
78 | if( $exist_x ) { |
---|
79 | $xs=$this->coords[1][0]; |
---|
80 | } |
---|
81 | else { |
---|
82 | $xs=0; |
---|
83 | } |
---|
84 | |
---|
85 | $ts = $this->iTupleSize; |
---|
86 | $this->csimareas = ''; |
---|
87 | for( $i=0; $i<$n; ++$i) { |
---|
88 | |
---|
89 | //If value is NULL, then don't draw a bar at all |
---|
90 | if ($this->coords[0][$i*$ts] === null) continue; |
---|
91 | |
---|
92 | if( $exist_x ) { |
---|
93 | $x=$this->coords[1][$i]; |
---|
94 | if ($x === null) continue; |
---|
95 | } |
---|
96 | else { |
---|
97 | $x=$i; |
---|
98 | } |
---|
99 | $xt = $xscale->Translate($x); |
---|
100 | |
---|
101 | $neg = $this->coords[0][$i*$ts] > $this->coords[0][$i*$ts+1] ; |
---|
102 | $yopen = $yscale->Translate($this->coords[0][$i*$ts]); |
---|
103 | $yclose = $yscale->Translate($this->coords[0][$i*$ts+1]); |
---|
104 | $ymin = $yscale->Translate($this->coords[0][$i*$ts+2]); |
---|
105 | $ymax = $yscale->Translate($this->coords[0][$i*$ts+3]); |
---|
106 | |
---|
107 | $dx = floor($this->iWidth/2); |
---|
108 | $xl = $xt - $dx; |
---|
109 | $xr = $xt + $dx; |
---|
110 | |
---|
111 | if( $neg ) { |
---|
112 | $img->SetColor($this->iStockColor3); |
---|
113 | } |
---|
114 | else { |
---|
115 | $img->SetColor($this->iStockColor1); |
---|
116 | } |
---|
117 | $img->FilledRectangle($xl,$yopen,$xr,$yclose); |
---|
118 | $img->SetLineWeight($this->weight); |
---|
119 | if( $neg ) { |
---|
120 | $img->SetColor($this->iStockColor2); |
---|
121 | } |
---|
122 | else { |
---|
123 | $img->SetColor($this->color); |
---|
124 | } |
---|
125 | |
---|
126 | $img->Rectangle($xl,$yopen,$xr,$yclose); |
---|
127 | |
---|
128 | if( $yopen < $yclose ) { |
---|
129 | $ytop = $yopen ; |
---|
130 | $ybottom = $yclose ; |
---|
131 | } |
---|
132 | else { |
---|
133 | $ytop = $yclose ; |
---|
134 | $ybottom = $yopen ; |
---|
135 | } |
---|
136 | $img->SetColor($this->color); |
---|
137 | $img->Line($xt,$ytop,$xt,$ymax); |
---|
138 | $img->Line($xt,$ybottom,$xt,$ymin); |
---|
139 | |
---|
140 | if( $this->iEndLines ) { |
---|
141 | $img->Line($xl,$ymax,$xr,$ymax); |
---|
142 | $img->Line($xl,$ymin,$xr,$ymin); |
---|
143 | } |
---|
144 | |
---|
145 | // A chance for subclasses to add things to the bar |
---|
146 | // for data point i |
---|
147 | $this->ModBox($img,$xscale,$yscale,$i,$xl,$xr,$neg); |
---|
148 | |
---|
149 | // Setup image maps |
---|
150 | if( !empty($this->csimtargets[$i]) ) { |
---|
151 | $this->csimareas.= '<area shape="rect" coords="'. |
---|
152 | round($xl).','.round($ytop).','. |
---|
153 | round($xr).','.round($ybottom).'" '; |
---|
154 | $this->csimareas .= ' href="'.$this->csimtargets[$i].'"'; |
---|
155 | if( !empty($this->csimalts[$i]) ) { |
---|
156 | $sval=$this->csimalts[$i]; |
---|
157 | $this->csimareas .= " title=\"$sval\" alt=\"$sval\" "; |
---|
158 | } |
---|
159 | $this->csimareas.= " />\n"; |
---|
160 | } |
---|
161 | } |
---|
162 | return true; |
---|
163 | } |
---|
164 | |
---|
165 | // A hook for subclasses to modify the plot |
---|
166 | function ModBox($img,$xscale,$yscale,$i,$xl,$xr,$neg) {} |
---|
167 | |
---|
168 | } // Class |
---|
169 | |
---|
170 | //=================================================== |
---|
171 | // CLASS BoxPlot |
---|
172 | //=================================================== |
---|
173 | class BoxPlot extends StockPlot { |
---|
174 | private $iPColor='black',$iNColor='white'; |
---|
175 | |
---|
176 | function __construct($datay,$datax=false) { |
---|
177 | $this->iTupleSize=5; |
---|
178 | parent::__construct($datay,$datax); |
---|
179 | } |
---|
180 | |
---|
181 | function SetMedianColor($aPos,$aNeg) { |
---|
182 | $this->iPColor = $aPos; |
---|
183 | $this->iNColor = $aNeg; |
---|
184 | } |
---|
185 | |
---|
186 | function ModBox($img,$xscale,$yscale,$i,$xl,$xr,$neg) { |
---|
187 | if( $neg ) |
---|
188 | $img->SetColor($this->iNColor); |
---|
189 | else |
---|
190 | $img->SetColor($this->iPColor); |
---|
191 | |
---|
192 | $y = $yscale->Translate($this->coords[0][$i*5+4]); |
---|
193 | $img->Line($xl,$y,$xr,$y); |
---|
194 | } |
---|
195 | } |
---|
196 | |
---|
197 | /* EOF */ |
---|
198 | ?> |
---|