source: trunk/xgraph/jpgraph/jpgraph_table.php @ 42

Last change on this file since 42 was 42, checked in by marrucho, 10 years ago
File size: 48.3 KB
Line 
1<?php
2/*=======================================================================
3 // File:        JPGRAPH_TABLE.PHP
4 // Description: Classes to create basic tables of data
5 // Created:     2006-01-25
6 // Ver:         $Id: jpgraph_table.php 1514 2009-07-07 11:15:58Z ljp $
7 //
8 // Copyright (c) Asial Corporation. All rights reserved.
9 //========================================================================
10 */
11
12// Style of grid lines in table
13DEFINE('TGRID_SINGLE',1);
14DEFINE('TGRID_DOUBLE',2);
15DEFINE('TGRID_DOUBLE2',3);
16
17// Type of constrain for image constrain
18DEFINE('TIMG_WIDTH',1);
19DEFINE('TIMG_HEIGHT',2);
20
21//---------------------------------------------------------------------
22// CLASS GTextTableCell
23// Description:
24// Internal class that represents each cell in the table
25//---------------------------------------------------------------------
26class GTextTableCell {
27    public $iColSpan=1,$iRowSpan=1;
28    public $iMarginLeft=5,$iMarginRight=5,$iMarginTop=5,$iMarginBottom=5;
29    public $iVal=NULL;
30    private $iBGColor='', $iFontColor='black';
31    private $iFF=FF_FONT1,$iFS=FS_NORMAL,$iFSize=10;
32    private $iRow=0, $iCol=0;
33    private $iVertAlign = 'bottom', $iHorAlign = 'left';
34    private $iMerged=FALSE,$iPRow=NULL,$iPCol=NULL;
35    private $iTable=NULL;
36    private $iGridColor=array('darkgray','darkgray','darkgray','darkgray');
37    private $iGridWeight=array(1,1,0,0); // left,top,bottom,right;
38    private $iGridStyle=array(TGRID_SINGLE,TGRID_SINGLE,TGRID_SINGLE,TGRID_SINGLE); // left,top,bottom,right;
39    private $iNumberFormat=null;
40    private $iIcon=null, $iIconConstrain=array();
41    private $iCSIMtarget = '',$iCSIMwintarget = '', $iCSIMalt = '', $iCSIMArea = '';
42
43    function __construct($aVal='',$aRow=0,$aCol=0) {
44        $this->iVal = new Text($aVal);
45        $this->iRow = $aRow;
46        $this->iCol = $aCol;
47        $this->iPRow = $aRow; // Initialiy each cell is its own parent
48        $this->iPCol = $aCol;
49        $this->iIconConstrain = array(-1,-1);
50    }
51
52    function Init($aTable) {
53        $this->iTable = $aTable;
54    }
55
56    function SetCSIMTarget($aTarget,$aAlt='',$aWinTarget='') {
57        $this->iCSIMtarget = $aTarget;
58        $this->iCSIMwintarget = $aWinTarget;
59        $this->iCSIMalt = $aAlt;
60    }
61
62    function GetCSIMArea() {
63        if( $this->iCSIMtarget !== '' )
64        return $this->iCSIMArea;
65        else
66        return '';
67    }
68
69    function SetImageConstrain($aType,$aVal) {
70        if( !in_array($aType,array(TIMG_WIDTH, TIMG_HEIGHT)) ) {
71            JpGraphError::RaiseL(27015);
72        }
73        $this->iIconConstrain = array($aType,$aVal);
74    }
75
76    function SetCountryFlag($aFlag,$aScale=1.0,$aMix=100,$aStdSize=3) {
77        $this->iIcon = new IconPlot();
78        $this->iIcon->SetCountryFlag($aFlag,0,0,$aScale,$aMix,$aStdSize);
79    }
80
81    function SetImage($aFile,$aScale=1.0,$aMix=100) {
82        $this->iIcon = new IconPlot($aFile,0,0,$aScale,$aMix);
83    }
84
85    function SetImageFromString($aStr,$aScale=1.0,$aMix=100) {
86        $this->iIcon = new IconPlot("",0,0,$aScale,$aMix);
87        $this->iIcon->CreateFromString($aStr);
88    }
89
90    function SetRowColSpan($aRowSpan,$aColSpan) {
91        $this->iRowSpan = $aRowSpan;
92        $this->iColSpan = $aColSpan;
93        $this->iMerged = true;
94    }
95
96    function SetMerged($aPRow,$aPCol,$aFlg=true) {
97        $this->iMerged = $aFlg;
98        $this->iPRow=$aPRow;
99        $this->iPCol=$aPCol;
100    }
101
102    function IsMerged() {
103        return $this->iMerged;
104    }
105
106    function SetNumberFormat($aF) {
107        $this->iNumberFormat = $aF;
108    }
109
110    function Set($aTxt) {
111        $this->iVal->Set($aTxt);
112    }
113
114    function SetFont($aFF,$aFS,$aFSize) {
115        $this->iFF = $aFF;
116        $this->iFS = $aFS;
117        $this->iFSize = $aFSize;
118        $this->iVal->SetFont($aFF,$aFS,$aFSize);
119    }
120
121    function SetFillColor($aColor) {
122        $this->iBGColor=$aColor;
123    }
124
125    function SetFontColor($aColor) {
126        $this->iFontColor=$aColor;
127    }
128
129    function SetGridColor($aLeft,$aTop=null,$aBottom=null,$aRight=null) {
130        if( $aLeft !== null ) $this->iGridColor[0] = $aLeft;
131        if( $aTop !== null ) $this->iGridColor[1] = $aTop;
132        if( $aBottom !== null ) $this->iGridColor[2] = $aBottom;
133        if( $aRight !== null )$this->iGridColor[3] = $aRight;
134    }
135
136    function SetGridStyle($aLeft,$aTop=null,$aBottom=null,$aRight=null) {
137        if( $aLeft !== null ) $this->iGridStyle[0] = $aLeft;
138        if( $aTop !== null ) $this->iGridStyle[1] = $aTop;
139        if( $aBottom !== null ) $this->iGridStyle[2] = $aBottom;
140        if( $aRight !== null )$this->iGridStyle[3] = $aRight;
141    }
142
143    function SetGridWeight($aLeft=null,$aTop=null,$aBottom=null,$aRight=null) {
144        if( $aLeft !== null ) $this->iGridWeight[0] = $aLeft;
145        if( $aTop !== null ) $this->iGridWeight[1] = $aTop;
146        if( $aBottom !== null ) $this->iGridWeight[2] = $aBottom;
147        if( $aRight !== null ) $this->iGridWeight[3] = $aRight;
148    }
149
150    function SetMargin($aLeft,$aRight,$aTop,$aBottom) {
151        $this->iMarginLeft=$aLeft;
152        $this->iMarginRight=$aRight;
153        $this->iMarginTop=$aTop;
154        $this->iMarginBottom=$aBottom;
155    }
156
157    function GetWidth($aImg) {
158        if( $this->iIcon !== null ) {
159            if( $this->iIconConstrain[0] == TIMG_WIDTH ) {
160                $this->iIcon->SetScale(1);
161                $tmp = $this->iIcon->GetWidthHeight();
162                $this->iIcon->SetScale($this->iIconConstrain[1]/$tmp[0]);
163            }
164            elseif( $this->iIconConstrain[0] == TIMG_HEIGHT ) {
165                $this->iIcon->SetScale(1);
166                $tmp = $this->iIcon->GetWidthHeight();
167                $this->iIcon->SetScale($this->iIconConstrain[1]/$tmp[1]);
168            }
169            $tmp = $this->iIcon->GetWidthHeight();
170            $iwidth = $tmp[0];
171        }
172        else {
173            $iwidth=0;
174        }
175        if( $this->iTable->iCells[$this->iPRow][$this->iPCol]->iVal->dir == 0 ) {
176            $pwidth = $this->iTable->iCells[$this->iPRow][$this->iPCol]->iVal->GetWidth($aImg);
177        }
178        elseif( $this->iTable->iCells[$this->iPRow][$this->iPCol]->iVal->dir == 90 ) {
179            $pwidth = $this->iTable->iCells[$this->iPRow][$this->iPCol]->iVal->GetFontHeight($aImg)+2;
180        }
181        else {
182            $pwidth = $this->iTable->iCells[$this->iPRow][$this->iPCol]->iVal->GetWidth($aImg)+2;
183        }
184
185        $pcolspan = $this->iTable->iCells[$this->iPRow][$this->iPCol]->iColSpan;
186        return round(max($iwidth,$pwidth)/$pcolspan) + $this->iMarginLeft + $this->iMarginRight;
187    }
188
189    function GetHeight($aImg) {
190        if( $this->iIcon !== null ) {
191            if( $this->iIconConstrain[0] == TIMG_WIDTH ) {
192                $this->iIcon->SetScale(1);
193                $tmp = $this->iIcon->GetWidthHeight();
194                $this->iIcon->SetScale($this->iIconConstrain[1]/$tmp[0]);
195            }
196            elseif( $this->iIconConstrain[0] == TIMG_HEIGHT ) {
197                $this->iIcon->SetScale(1);
198                $tmp = $this->iIcon->GetWidthHeight();
199                $this->iIcon->SetScale($this->iIconConstrain[1]/$tmp[1]);
200            }
201            $tmp = $this->iIcon->GetWidthHeight();
202            $iheight =  $tmp[1];
203        }
204        else {
205            $iheight = 0;
206        }
207        if( $this->iTable->iCells[$this->iPRow][$this->iPCol]->iVal->dir == 0 ) {
208            $pheight = $this->iTable->iCells[$this->iPRow][$this->iPCol]->iVal->GetHeight($aImg);
209        }
210        else {
211            $pheight = $this->iTable->iCells[$this->iPRow][$this->iPCol]->iVal->GetHeight($aImg)+1;
212        }
213        $prowspan = $this->iTable->iCells[$this->iPRow][$this->iPCol]->iRowSpan;
214        return round(max($iheight,$pheight)/$prowspan) + $this->iMarginTop + $this->iMarginBottom;
215    }
216
217    function SetAlign($aHorAlign='left',$aVertAlign='bottom') {
218        $aHorAlign = strtolower($aHorAlign);
219        $aVertAlign = strtolower($aVertAlign);
220        $chk = array('left','right','center','bottom','top','middle');
221        if( !in_array($aHorAlign,$chk) || !in_array($aVertAlign,$chk) ) {
222            JpGraphError::RaiseL(27011,$aHorAlign,$aVertAlign);
223        }
224        $this->iVertAlign = $aVertAlign;
225        $this->iHorAlign = $aHorAlign;
226    }
227
228    function AdjustMarginsForGrid() {
229        if( $this->iCol > 0 ) {
230            switch( $this->iGridStyle[0] ) {
231                case TGRID_SINGLE:  $wf=1;  break;
232                case TGRID_DOUBLE:  $wf=3;  break;
233                case TGRID_DOUBLE2: $wf=4;  break;
234            }
235            $this->iMarginLeft += $this->iGridWeight[0]*$wf;
236        }
237        if( $this->iRow > 0 ) {
238            switch( $this->iGridStyle[1] ) {
239                case TGRID_SINGLE:  $wf=1;  break;
240                case TGRID_DOUBLE:  $wf=3;  break;
241                case TGRID_DOUBLE2: $wf=4;  break;
242            }
243            $this->iMarginTop += $this->iGridWeight[1]*$wf;
244        }
245        if( $this->iRow+$this->iRowSpan-1 < $this->iTable->iSize[0]-1 ) {
246            switch( $this->iGridStyle[2] ) {
247                case TGRID_SINGLE: $wf=1; break;
248                case TGRID_DOUBLE: $wf=3; break;
249                case TGRID_DOUBLE2: $wf=4; break;
250            }
251            $this->iMarginBottom += $this->iGridWeight[2]*$wf;
252        }
253        if( $this->iCol+$this->iColSpan-1 < $this->iTable->iSize[1]-1 ) {
254            switch( $this->iGridStyle[3] ) {
255                case TGRID_SINGLE: $wf=1; break;
256                case TGRID_DOUBLE: $wf=3; break;
257                case TGRID_DOUBLE2: $wf=4; break;
258            }
259            $this->iMarginRight += $this->iGridWeight[3]*$wf;
260        }
261    }
262
263    function StrokeVGrid($aImg,$aX,$aY,$aWidth,$aHeight,$aDir=1) {
264        // Left or right grid line
265        // For the right we increase the X-pos and for the right we decrease it. This is
266        // determined by the direction argument.
267        $idx = $aDir==1 ? 0 : 3;
268
269        // We don't stroke the grid lines that are on the edge of the table since this is
270        // the place of the border.
271        if( ( ($this->iCol > 0 && $idx==0) || ($this->iCol+$this->iColSpan-1 < $this->iTable->iSize[1]-1 && $idx==3) )
272        && $this->iGridWeight[$idx] > 0 ) {
273            $x = $aDir==1 ? $aX : $aX + $aWidth-1;
274            $y = $aY+$aHeight-1;
275            $aImg->SetColor($this->iGridColor[$idx]);
276            switch( $this->iGridStyle[$idx] ) {
277                case TGRID_SINGLE:
278                    for( $i=0; $i < $this->iGridWeight[$idx]; ++$i )
279                    $aImg->Line($x+$i*$aDir,$aY, $x+$i*$aDir,$y);
280                    break;
281
282                case TGRID_DOUBLE:
283                    for( $i=0; $i < $this->iGridWeight[$idx]; ++$i )
284                    $aImg->Line($x+$i*$aDir,$aY, $x+$i*$aDir,$y);
285                    $x += $this->iGridWeight[$idx]*2;
286                    for( $i=0; $i < $this->iGridWeight[$idx]; ++$i )
287                    $aImg->Line($x+$i*$aDir,$aY, $x+$i*$aDir,$y);
288                    break;
289
290                case TGRID_DOUBLE2:
291                    for( $i=0; $i < $this->iGridWeight[$idx]*2; ++$i )
292                    $aImg->Line($x+$i*$aDir,$aY,$x+$i*$aDir,$y);
293                    $x += $this->iGridWeight[$idx]*3;
294                    for( $i=0; $i < $this->iGridWeight[$idx]; ++$i )
295                    $aImg->Line($x+$i*$aDir,$aY, $x+$i*$aDir,$y);
296                    break;
297            }
298        }
299    }
300
301    function StrokeHGrid($aImg,$aX,$aY,$aWidth,$aHeight,$aDir=1) {
302        // Top or bottom grid line
303        // For the left we increase the X-pos and for the right we decrease it. This is
304        // determined by the direction argument.
305        $idx = $aDir==1 ? 1 : 2;
306
307        // We don't stroke the grid lines that are on the edge of the table since this is
308        // the place of the border.
309        if( ( ($this->iRow > 0 && $idx==1) || ($this->iRow+$this->iRowSpan-1 < $this->iTable->iSize[0]-1 && $idx==2) )
310        && $this->iGridWeight[$idx] > 0) {
311            $y = $aDir==1 ? $aY : $aY+$aHeight-1;
312            $x = $aX+$aWidth-1;
313            $aImg->SetColor($this->iGridColor[$idx]);
314            switch( $this->iGridStyle[$idx] ) {
315                case TGRID_SINGLE:
316                    for( $i=0; $i < $this->iGridWeight[$idx]; ++$i )
317                    $aImg->Line($aX,$y+$i, $x,$y+$i);
318                    break;
319
320                case TGRID_DOUBLE:
321                    for( $i=0; $i < $this->iGridWeight[$idx]; ++$i )
322                    $aImg->Line($aX,$y+$i, $x,$y+$i);
323                    $y += $this->iGridWeight[$idx]*2;
324                    for( $i=0; $i < $this->iGridWeight[$idx]; ++$i )
325                    $aImg->Line($aX,$y+$i, $x,$y+$i);
326                    break;
327
328                case TGRID_DOUBLE2:
329                    for( $i=0; $i < $this->iGridWeight[$idx]*2; ++$i )
330                    $aImg->Line($aX,$y+$i, $x,$y+$i);
331                    $y += $this->iGridWeight[$idx]*3;
332                    for( $i=0; $i < $this->iGridWeight[$idx]; ++$i )
333                    $aImg->Line($aX,$y+$i, $x,$y+$i);
334                    break;
335            }
336        }
337    }
338
339    function Stroke($aImg,$aX,$aY,$aWidth,$aHeight) {
340        // If this is a merged cell we only stroke if it is the parent cell.
341        // The parent cell holds the merged cell block
342        if( $this->iMerged && ($this->iRow != $this->iPRow || $this->iCol != $this->iPCol) ) {
343            return;
344        }
345
346        if( $this->iBGColor != '' ) {
347            $aImg->SetColor($this->iBGColor);
348            $aImg->FilledRectangle($aX,$aY,$aX+$aWidth-1,$aY+$aHeight-1);
349        }
350
351        $coords = $aX.','.$aY.','.($aX+$aWidth-1).','.$aY.','.($aX+$aWidth-1).','.($aY+$aHeight-1).','.$aX.','.($aY+$aHeight-1);
352        if( ! empty($this->iCSIMtarget) ) {
353            $this->iCSIMArea = '<area shape="poly" coords="'.$coords.'" href="'.$this->iCSIMtarget.'"';
354            if( ! empty($this->iCSIMwintarget) ) {
355                $this->iCSIMArea .= " target=\"".$this->iCSIMwintarget."\"";
356            }
357            if( ! empty($this->iCSIMalt) ) {
358                $this->iCSIMArea .= ' alt="'.$this->iCSIMalt.'" title="'.$this->iCSIMalt."\" ";
359            }
360            $this->iCSIMArea .= " />\n";
361        }
362
363        $this->StrokeVGrid($aImg,$aX,$aY,$aWidth,$aHeight);
364        $this->StrokeVGrid($aImg,$aX,$aY,$aWidth,$aHeight,-1);
365        $this->StrokeHGrid($aImg,$aX,$aY,$aWidth,$aHeight);
366        $this->StrokeHGrid($aImg,$aX,$aY,$aWidth,$aHeight,-1);
367
368        if( $this->iIcon !== null ) {
369            switch( $this->iHorAlign ) {
370                case 'left':
371                    $x = $aX+$this->iMarginLeft;
372                    $hanchor='left';
373                    break;
374                case 'center':
375                case 'middle':
376                    $x = $aX+$this->iMarginLeft+round(($aWidth-$this->iMarginLeft-$this->iMarginRight)/2);
377                    $hanchor='center';
378                    break;
379                case 'right':
380                    $x = $aX+$aWidth-$this->iMarginRight-1;
381                    $hanchor='right';
382                    break;
383                default:
384                    JpGraphError::RaiseL(27012,$this->iHorAlign);
385            }
386
387            switch( $this->iVertAlign ) {
388                case 'top':
389                    $y = $aY+$this->iMarginTop;
390                    $vanchor='top';
391                    break;
392                case 'center':
393                case 'middle':
394                    $y = $aY+$this->iMarginTop+round(($aHeight-$this->iMarginTop-$this->iMarginBottom)/2);
395                    $vanchor='center';
396                    break;
397                case 'bottom':
398                    $y = $aY+$aHeight-1-$this->iMarginBottom;
399                    $vanchor='bottom';
400                    break;
401                default:
402                    JpGraphError::RaiseL(27012,$this->iVertAlign);
403            }
404            $this->iIcon->SetAnchor($hanchor,$vanchor);
405            $this->iIcon->_Stroke($aImg,$x,$y);
406        }
407        $this->iVal->SetColor($this->iFontColor);
408        $this->iVal->SetFont($this->iFF,$this->iFS,$this->iFSize);
409        switch( $this->iHorAlign ) {
410            case 'left':
411                $x = $aX+$this->iMarginLeft;
412                break;
413            case 'center':
414            case 'middle':
415                $x = $aX+$this->iMarginLeft+round(($aWidth-$this->iMarginLeft-$this->iMarginRight)/2);
416                break;
417            case 'right':
418                $x = $aX+$aWidth-$this->iMarginRight-1;
419                break;
420            default:
421                JpGraphError::RaiseL(27012,$this->iHorAlign);
422        }
423        // A workaround for the shortcomings in the TTF font handling in GD
424        // The anchor position for rotated text (=90) is to "short" so we add
425        // an offset based on the actual font size
426        if( $this->iVal->dir != 0 && $this->iVal->font_family >= 10 ) {
427            $aY += 4 + round($this->iVal->font_size*0.8);
428        }
429        switch( $this->iVertAlign ) {
430            case 'top':
431                $y = $aY+$this->iMarginTop;
432                break;
433            case 'center':
434            case 'middle':
435                $y = $aY+$this->iMarginTop+round(($aHeight-$this->iMarginTop-$this->iMarginBottom)/2);
436                //$y -= round($this->iVal->GetFontHeight($aImg)/2);
437                $y -= round($this->iVal->GetHeight($aImg)/2);
438                break;
439            case 'bottom':
440                //$y = $aY+$aHeight-1-$this->iMarginBottom-$this->iVal->GetFontHeight($aImg);
441                $y = $aY+$aHeight-$this->iMarginBottom-$this->iVal->GetHeight($aImg);
442                break;
443            default:
444                JpGraphError::RaiseL(27012,$this->iVertAlign);
445        }
446        $this->iVal->SetAlign($this->iHorAlign,'top');
447        if( $this->iNumberFormat !== null && is_numeric($this->iVal->t) ) {
448            $this->iVal->t = sprintf($this->iNumberFormat,$this->iVal->t);
449        }
450        $this->iVal->Stroke($aImg,$x,$y);
451    }
452}
453
454//---------------------------------------------------------------------
455// CLASS GTextTable
456// Description:
457// Graphic text table
458//---------------------------------------------------------------------
459class GTextTable {
460    public $iCells = array(), $iSize=array(0,0); // Need to be public since they are used by the cell
461    private $iWidth=0, $iHeight=0;
462    private $iColWidth=NULL,$iRowHeight=NULL;
463    private $iImg=NULL;
464    private $iXPos=0, $iYPos=0;
465    private $iScaleXPos=null,$iScaleYPos=null;
466    private $iBGColor='';
467    private $iBorderColor='black',$iBorderWeight=1;
468    private $iInit=false;
469    private $iYAnchor='top',$iXAnchor='left';
470    /*-----------------------------------------------------------------
471     * First and second phase constructors
472     *-----------------------------------------------------------------
473     */
474    function __construct() {
475        // Empty
476    }
477
478    function Init($aRows=0,$aCols=0,$aFillText='') {
479        $this->iSize[0] = $aRows;
480        $this->iSize[1] = $aCols;
481        for($i=0; $i < $this->iSize[0]; ++$i) {
482            for($j=0; $j < $this->iSize[1]; ++$j) {
483                $this->iCells[$i][$j] = new GTextTableCell($aFillText,$i,$j);
484                $this->iCells[$i][$j]->Init($this);
485            }
486        }
487        $this->iInit=true;
488    }
489
490    /*-----------------------------------------------------------------
491     * Outer border of table
492     *-----------------------------------------------------------------
493     */
494    function SetBorder($aWeight=1,$aColor='black') {
495        $this->iBorderColor=$aColor;
496        $this->iBorderWeight = $aWeight;
497    }
498
499
500    /*-----------------------------------------------------------------
501     * Position in graph of table
502     *-----------------------------------------------------------------
503     */
504    function SetPos($aX,$aY) {
505        $this->iXPos = $aX;
506        $this->iYPos = $aY;
507    }
508
509    function SetScalePos($aX,$aY) {
510        $this->iScaleXPos = $aX;
511        $this->iScaleYPos = $aY;
512    }
513
514    function SetAnchorPos($aXAnchor,$aYAnchor='top') {
515        $this->iXAnchor = $aXAnchor;
516        $this->iYAnchor = $aYAnchor;
517    }
518
519    /*-----------------------------------------------------------------
520     * Setup country flag in a cell
521     *-----------------------------------------------------------------
522     */
523    function SetCellCountryFlag($aRow,$aCol,$aFlag,$aScale=1.0,$aMix=100,$aStdSize=3) {
524        $this->_chkR($aRow);
525        $this->_chkC($aCol);
526        $this->iCells[$aRow][$aCol]->SetCountryFlag($aFlag,$aScale,$aMix,$aStdSize);
527
528    }
529
530    /*-----------------------------------------------------------------
531     * Setup image in a cell
532     *-----------------------------------------------------------------
533     */
534    function SetCellImage($aRow,$aCol,$aFile,$aScale=1.0,$aMix=100) {
535        $this->_chkR($aRow);
536        $this->_chkC($aCol);
537        $this->iCells[$aRow][$aCol]->SetImage($aFile,$aScale,$aMix);
538    }
539
540    function SetRowImage($aRow,$aFile,$aScale=1.0,$aMix=100) {
541        $this->_chkR($aRow);
542        for($j=0; $j < $this->iSize[1]; ++$j) {
543            $this->iCells[$aRow][$j]->SetImage($aFile,$aScale,$aMix);
544        }
545    }
546
547    function SetColImage($aCol,$aFile,$aScale=1.0,$aMix=100) {
548        $this->_chkC($aCol);
549        for($j=0; $j < $this->iSize[0]; ++$j) {
550            $this->iCells[$j][$aCol]->SetImage($aFile,$aScale,$aMix);
551        }
552    }
553
554    function SetImage($aFileR1,$aScaleC1=null,$aMixR2=null,$aC2=null,$aFile=null,$aScale=1.0,$aMix=100) {
555        if( $aScaleC1 !== null && $aMixR2!==null && $aC2!==null && $aFile!==null ) {
556            $this->_chkR($aArgR1);  $this->_chkC($aC1);
557            $this->_chkR($aR2);  $this->_chkC($aC2);
558        }
559        else {
560            if( $aScaleC1 !== null ) $aScale = $aScaleC1;
561            if( $aMixR2 !== null ) $aMix = $aMixR2;
562            $aFile = $aFileR1;
563            $aMixR2 = $this->iSize[0]-1; $aFileR1 = 0;
564            $aC2 = $this->iSize[1]-1; $aScaleC1 = 0;
565        }
566        for($i=$aArgR1; $i <= $aR2; ++$i) {
567            for($j=$aC1; $j <= $aC2; ++$j) {
568                $this->iCells[$i][$j]->SetImage($aFile,$aScale,$aMix);
569            }
570        }
571    }
572
573    function SetCellImageConstrain($aRow,$aCol,$aType,$aVal) {
574        $this->_chkR($aRow);
575        $this->_chkC($aCol);
576        $this->iCells[$aRow][$aCol]->SetImageConstrain($aType,$aVal);
577    }
578
579    /*-----------------------------------------------------------------
580     * Generate a HTML version of the table
581     *-----------------------------------------------------------------
582     */
583    function toString() {
584        $t = '<table border=1 cellspacing=0 cellpadding=0>';
585        for($i=0; $i < $this->iSize[0]; ++$i) {
586            $t .= '<tr>';
587            for($j=0; $j < $this->iSize[1]; ++$j) {
588                $t .= '<td>';
589                if( $this->iCells[$i][$j]->iMerged )
590                $t .= 'M ';
591                $t .= 'val='.$this->iCells[$i][$j]->iVal->t;
592                $t .= ' (cs='.$this->iCells[$i][$j]->iColSpan.
593        ', rs='.$this->iCells[$i][$j]->iRowSpan.')';
594                $t .= '</td>';
595            }
596            $t .= '</tr>';
597        }
598        $t .= '</table>';
599        return $t;
600    }
601
602    /*-----------------------------------------------------------------
603     * Specify data for table
604     *-----------------------------------------------------------------
605     */
606    function Set($aArg1,$aArg2=NULL,$aArg3=NULL) {
607        if( $aArg2===NULL && $aArg3===NULL ) {
608            if( is_array($aArg1) ) {
609                if( is_array($aArg1[0]) ) {
610                    $m = count($aArg1);
611                    // Find the longest row
612                    $n=0;
613                    for($i=0; $i < $m; ++$i)
614                    $n = max(count($aArg1[$i]),$n);
615                    for($i=0; $i < $m; ++$i) {
616                        for($j=0; $j < $n; ++$j) {
617                            if( isset($aArg1[$i][$j]) ){
618                                $this->_setcell($i,$j,(string)$aArg1[$i][$j]);
619                            }
620                            else {
621                                $this->_setcell($i,$j);
622                            }
623                        }
624                    }
625                    $this->iSize[0] = $m;
626                    $this->iSize[1] = $n;
627                    $this->iInit=true;
628                }
629                else {
630                    JpGraphError::RaiseL(27001);
631                    //('Illegal argument to GTextTable::Set(). Array must be 2 dimensional');
632                }
633            }
634            else {
635                JpGraphError::RaiseL(27002);
636                //('Illegal argument to GTextTable::Set()');
637            }
638        }
639        else {
640            // Must be in the form (row,col,val)
641            $this->_chkR($aArg1);
642            $this->_chkC($aArg2);
643            $this->_setcell($aArg1,$aArg2,(string)$aArg3);
644        }
645    }
646
647    /*---------------------------------------------------------------------
648     * Cell margin setting
649     *---------------------------------------------------------------------
650     */
651    function SetPadding($aArgR1,$aC1=null,$aR2=null,$aC2=null,$aPad=null) {
652        if( $aC1 !== null && $aR2!==null && $aC2!==null && $aPad!==null ) {
653            $this->_chkR($aArgR1);  $this->_chkC($aC1);
654            $this->_chkR($aR2);  $this->_chkC($aC2);
655        }
656        else {
657            $aPad = $aArgR1;
658            $aR2 = $this->iSize[0]-1; $aArgR1 = 0;
659            $aC2 = $this->iSize[1]-1; $aC1 = 0;
660        }
661        for($i=$aArgR1; $i <= $aR2; ++$i) {
662            for($j=$aC1; $j <= $aC2; ++$j) {
663                $this->iCells[$i][$j]->SetMargin($aPad,$aPad,$aPad,$aPad);
664            }
665        }
666    }
667
668    function SetRowPadding($aRow,$aPad) {
669        $this->_chkR($aRow);
670        for($j=0; $j < $this->iSize[1]; ++$j) {
671            $this->iCells[$aRow][$j]->SetMargin($aPad,$aPad,$aPad,$aPad);
672        }
673    }
674
675    function SetColPadding($aCol,$aPad) {
676        $this->_chkC($aCol);
677        for($j=0; $j < $this->iSize[0]; ++$j) {
678            $this->iCells[$j][$aCol]->SetMargin($aPad,$aPad,$aPad,$aPad);
679        }
680    }
681
682    function SetCellPadding($aRow,$aCol,$aPad) {
683        $this->_chkR($aRow);
684        $this->_chkC($aCol);
685        $this->iCells[$aRow][$aCol]->SetMargin($aPad,$aPad,$aPad,$aPad);
686    }
687
688
689    /*---------------------------------------------------------------------
690     * Cell text orientation setting
691     *---------------------------------------------------------------------
692     */
693    function SetTextOrientation($aArgR1,$aC1=null,$aR2=null,$aC2=null,$aO=null) {
694        if( $aC1 !== null && $aR2!==null && $aC2!==null && $aPad!==null ) {
695            $this->_chkR($aArgR1);  $this->_chkC($aC1);
696            $this->_chkR($aR2);  $this->_chkC($aC2);
697        }
698        else {
699            $aO = $aArgR1;
700            $aR2 = $this->iSize[0]-1; $aArgR1 = 0;
701            $aC2 = $this->iSize[1]-1; $aC1 = 0;
702        }
703        for($i=$aArgR1; $i <= $aR2; ++$i) {
704            for($j=$aC1; $j <= $aC2; ++$j) {
705                $this->iCells[$i][$j]->iVal->SetOrientation($aO);
706            }
707        }
708    }
709
710    function SetRowTextOrientation($aRow,$aO) {
711        $this->_chkR($aRow);
712        for($j=0; $j < $this->iSize[1]; ++$j) {
713            $this->iCells[$aRow][$j]->iVal->SetOrientation($aO);
714        }
715    }
716
717    function SetColTextOrientation($aCol,$aO) {
718        $this->_chkC($aCol);
719        for($j=0; $j < $this->iSize[0]; ++$j) {
720            $this->iCells[$j][$aCol]->iVal->SetOrientation($aO);
721        }
722    }
723
724    function SetCellTextOrientation($aRow,$aCol,$aO) {
725        $this->_chkR($aRow);
726        $this->_chkC($aCol);
727        $this->iCells[$aRow][$aCol]->iVal->SetOrientation($aO);
728    }
729
730
731
732
733    /*---------------------------------------------------------------------
734     * Font color setting
735     *---------------------------------------------------------------------
736     */
737
738    function SetColor($aArgR1,$aC1=null,$aR2=null,$aC2=null,$aArg=null) {
739        if( $aC1 !== null && $aR2!==null && $aC2!==null && $aArg!==null ) {
740            $this->_chkR($aArgR1);  $this->_chkC($aC1);
741            $this->_chkR($aR2);  $this->_chkC($aC2);
742        }
743        else {
744            $aArg = $aArgR1;
745            $aR2 = $this->iSize[0]-1; $aArgR1 = 0;
746            $aC2 = $this->iSize[1]-1; $aC1 = 0;
747        }
748        for($i=$aArgR1; $i <= $aR2; ++$i) {
749            for($j=$aC1; $j <= $aC2; ++$j) {
750                $this->iCells[$i][$j]->SetFontColor($aArg);
751            }
752        }
753    }
754
755    function SetRowColor($aRow,$aColor) {
756        $this->_chkR($aRow);
757        for($j=0; $j < $this->iSize[1]; ++$j) {
758            $this->iCells[$aRow][$j]->SetFontColor($aColor);
759        }
760    }
761
762    function SetColColor($aCol,$aColor) {
763        $this->_chkC($aCol);
764        for($i=0; $i < $this->iSize[0]; ++$i) {
765            $this->iCells[$i][$aCol]->SetFontColor($aColor);
766        }
767    }
768
769    function SetCellColor($aRow,$aCol,$aColor) {
770        $this->_chkR($aRow);
771        $this->_chkC($aCol);
772        $this->iCells[$aRow][$aCol]->SetFontColor($aColor);
773    }
774
775    /*---------------------------------------------------------------------
776     * Fill color settings
777     *---------------------------------------------------------------------
778     */
779
780    function SetFillColor($aArgR1,$aC1=null,$aR2=null,$aC2=null,$aArg=null) {
781        if( $aC1 !== null && $aR2!==null && $aC2!==null && $aArg!==null ) {
782            $this->_chkR($aArgR1);  $this->_chkC($aC1);
783            $this->_chkR($aR2);  $this->_chkC($aC2);
784            for($i=$aArgR1; $i <= $aR2; ++$i) {
785                for($j=$aC1; $j <= $aC2; ++$j) {
786                    $this->iCells[$i][$j]->SetFillColor($aArg);
787                }
788            }
789        }
790        else {
791            $this->iBGColor = $aArgR1;
792        }
793    }
794
795    function SetRowFillColor($aRow,$aColor) {
796        $this->_chkR($aRow);
797        for($j=0; $j < $this->iSize[1]; ++$j) {
798            $this->iCells[$aRow][$j]->SetFillColor($aColor);
799        }
800    }
801
802    function SetColFillColor($aCol,$aColor) {
803        $this->_chkC($aCol);
804        for($i=0; $i < $this->iSize[0]; ++$i) {
805            $this->iCells[$i][$aCol]->SetFillColor($aColor);
806        }
807    }
808
809    function SetCellFillColor($aRow,$aCol,$aColor) {
810        $this->_chkR($aRow);
811        $this->_chkC($aCol);
812        $this->iCells[$aRow][$aCol]->SetFillColor($aColor);
813    }
814
815    /*---------------------------------------------------------------------
816     * Font family setting
817     *---------------------------------------------------------------------
818     */
819    function SetFont() {
820        $numargs = func_num_args();
821        if( $numargs == 2 || $numargs == 3 ) {
822            $aFF = func_get_arg(0);
823            $aFS = func_get_arg(1);
824            if( $numargs == 3 )
825            $aFSize=func_get_arg(2);
826            else
827            $aFSize=10;
828            $aR2 = $this->iSize[0]-1; $aR1 = 0;
829            $aC2 = $this->iSize[1]-1; $aC1 = 0;
830
831        }
832        elseif($numargs == 6 || $numargs == 7 ) {
833            $aR1 = func_get_arg(0); $aC1 = func_get_arg(1);
834            $aR2 = func_get_arg(2); $aC2 = func_get_arg(3);
835            $aFF = func_get_arg(4); $aFS = func_get_arg(5);
836            if( $numargs == 7 )
837            $aFSize=func_get_arg(6);
838            else
839            $aFSize=10;
840        }
841        else {
842            JpGraphError::RaiseL(27003);
843            //('Wrong number of arguments to GTextTable::SetColor()');
844        }
845        $this->_chkR($aR1);  $this->_chkC($aC1);
846        $this->_chkR($aR2);  $this->_chkC($aC2);
847        for($i=$aR1; $i <= $aR2; ++$i) {
848            for($j=$aC1; $j <= $aC2; ++$j) {
849                $this->iCells[$i][$j]->SetFont($aFF,$aFS,$aFSize);
850            }
851        }
852    }
853
854    function SetRowFont($aRow,$aFF,$aFS,$aFSize=10) {
855        $this->_chkR($aRow);
856        for($j=0; $j < $this->iSize[1]; ++$j) {
857            $this->iCells[$aRow][$j]->SetFont($aFF,$aFS,$aFSize);
858        }
859    }
860
861    function SetColFont($aCol,$aFF,$aFS,$aFSize=10) {
862        $this->_chkC($aCol);
863        for($i=0; $i < $this->iSize[0]; ++$i) {
864            $this->iCells[$i][$aCol]->SetFont($aFF,$aFS,$aFSize);
865        }
866    }
867
868    function SetCellFont($aRow,$aCol,$aFF,$aFS,$aFSize=10) {
869        $this->_chkR($aRow);
870        $this->_chkC($aCol);
871        $this->iCells[$aRow][$aCol]->SetFont($aFF,$aFS,$aFSize);
872    }
873
874    /*---------------------------------------------------------------------
875     * Cell align settings
876     *---------------------------------------------------------------------
877     */
878
879    function SetAlign($aR1HAlign=null,$aC1VAlign=null,$aR2=null,$aC2=null,$aHArg=null,$aVArg='center') {
880        if( $aC1VAlign !== null && $aR2!==null && $aC2!==null && $aHArg!==null ) {
881            $this->_chkR($aR1HAlign);  $this->_chkC($aC1VAlign);
882            $this->_chkR($aR2);  $this->_chkC($aC2);
883        }
884        else {
885            if( $aR1HAlign === null ) {
886                JpGraphError::RaiseL(27010);
887            }
888            if( $aC1VAlign === null ) {
889                $aC1VAlign = 'center';
890            }
891            $aHArg = $aR1HAlign;
892            $aVArg = $aC1VAlign === null ? 'center' : $aC1VAlign ;
893            $aR2 = $this->iSize[0]-1; $aR1HAlign = 0;
894            $aC2 = $this->iSize[1]-1; $aC1VAlign = 0;
895        }
896        for($i=$aR1HAlign; $i <= $aR2; ++$i) {
897            for($j=$aC1VAlign; $j <= $aC2; ++$j) {
898                $this->iCells[$i][$j]->SetAlign($aHArg,$aVArg);
899            }
900        }
901    }
902
903    function SetCellAlign($aRow,$aCol,$aHorAlign,$aVertAlign='bottom') {
904        $this->_chkR($aRow);
905        $this->_chkC($aCol);
906        $this->iCells[$aRow][$aCol]->SetAlign($aHorAlign,$aVertAlign);
907    }
908
909    function SetRowAlign($aRow,$aHorAlign,$aVertAlign='bottom') {
910        $this->_chkR($aRow);
911        for($j=0; $j < $this->iSize[1]; ++$j) {
912            $this->iCells[$aRow][$j]->SetAlign($aHorAlign,$aVertAlign);
913        }
914    }
915
916    function SetColAlign($aCol,$aHorAlign,$aVertAlign='bottom') {
917        $this->_chkC($aCol);
918        for($i=0; $i < $this->iSize[0]; ++$i) {
919            $this->iCells[$i][$aCol]->SetAlign($aHorAlign,$aVertAlign);
920        }
921    }
922
923    /*---------------------------------------------------------------------
924     * Cell number format
925     *---------------------------------------------------------------------
926     */
927
928    function SetNumberFormat($aArgR1,$aC1=null,$aR2=null,$aC2=null,$aArg=null) {
929        if( $aC1 !== null && $aR2!==null && $aC2!==null && $aArg!==null ) {
930            $this->_chkR($aArgR1);  $this->_chkC($aC1);
931            $this->_chkR($aR2);  $this->_chkC($aC2);
932        }
933        else {
934            $aArg = $aArgR1;
935            $aR2 = $this->iSize[0]-1; $aArgR1 = 0;
936            $aC2 = $this->iSize[1]-1; $aC1 = 0;
937        }
938        if( !is_string($aArg) ) {
939            JpGraphError::RaiseL(27013); // argument must be a string
940        }
941        for($i=$aArgR1; $i <= $aR2; ++$i) {
942            for($j=$aC1; $j <= $aC2; ++$j) {
943                $this->iCells[$i][$j]->SetNumberFormat($aArg);
944            }
945        }
946    }
947
948    function SetRowNumberFormat($aRow,$aF) {
949        $this->_chkR($aRow);
950        if( !is_string($aF) ) {
951            JpGraphError::RaiseL(27013); // argument must be a string
952        }
953        for($j=0; $j < $this->iSize[1]; ++$j) {
954            $this->iCells[$aRow][$j]->SetNumberFormat($aF);
955        }
956    }
957
958    function SetColNumberFormat($aCol,$aF) {
959        $this->_chkC($aCol);
960        if( !is_string($aF) ) {
961            JpGraphError::RaiseL(27013); // argument must be a string
962        }
963        for($i=0; $i < $this->iSize[0]; ++$i) {
964            $this->iCells[$i][$aCol]->SetNumberFormat($aF);
965        }
966    }
967
968    function SetCellNumberFormat($aRow,$aCol,$aF) {
969        $this->_chkR($aRow); $this->_chkC($aCol);
970        if( !is_string($aF) ) {
971            JpGraphError::RaiseL(27013); // argument must be a string
972        }
973        $this->iCells[$aRow][$aCol]->SetNumberFormat($aF);
974    }
975
976    /*---------------------------------------------------------------------
977     * Set row and column min size
978     *---------------------------------------------------------------------
979     */
980
981    function SetMinColWidth($aColWidth,$aWidth=null) {
982        // If there is only one argument this means that all
983        // columns get set to the same width
984        if( $aWidth===null ) {
985            for($i=0; $i < $this->iSize[1]; ++$i) {
986                $this->iColWidth[$i]  = $aColWidth;
987            }
988        }
989        else {
990            $this->_chkC($aColWidth);
991            $this->iColWidth[$aColWidth]  = $aWidth;
992        }
993    }
994
995    function SetMinRowHeight($aRowHeight,$aHeight=null) {
996        // If there is only one argument this means that all
997        // rows get set to the same height
998        if( $aHeight===null ) {
999            for($i=0; $i < $this->iSize[0]; ++$i) {
1000                $this->iRowHeight[$i]  = $aRowHeight;
1001            }
1002        }
1003        else {
1004            $this->_chkR($aRowHeight);
1005            $this->iRowHeight[$aRowHeight]  = $aHeight;
1006        }
1007    }
1008
1009    /*---------------------------------------------------------------------
1010     * Grid line settings
1011     *---------------------------------------------------------------------
1012     */
1013
1014    function SetGrid($aWeight=1,$aColor='black',$aStyle=TGRID_SINGLE) {
1015        $rc = $this->iSize[0];
1016        $cc = $this->iSize[1];
1017        for($i=0; $i < $rc; ++$i) {
1018            for($j=0; $j < $cc; ++$j) {
1019                $this->iCells[$i][$j]->SetGridColor($aColor,$aColor);
1020                $this->iCells[$i][$j]->SetGridWeight($aWeight,$aWeight);
1021                $this->iCells[$i][$j]->SetGridStyle($aStyle);
1022            }
1023        }
1024    }
1025
1026    function SetColGrid($aCol,$aWeight=1,$aColor='black',$aStyle=TGRID_SINGLE) {
1027        $this->_chkC($aCol);
1028        for($i=0; $i < $this->iSize[0]; ++$i) {
1029            $this->iCells[$i][$aCol]->SetGridWeight($aWeight);
1030            $this->iCells[$i][$aCol]->SetGridColor($aColor);
1031            $this->iCells[$i][$aCol]->SetGridStyle($aStyle);
1032        }
1033    }
1034
1035    function SetRowGrid($aRow,$aWeight=1,$aColor='black',$aStyle=TGRID_SINGLE) {
1036        $this->_chkR($aRow);
1037        for($j=0; $j < $this->iSize[1]; ++$j) {
1038            $this->iCells[$aRow][$j]->SetGridWeight(NULL,$aWeight);
1039            $this->iCells[$aRow][$j]->SetGridColor(NULL,$aColor);
1040            $this->iCells[$aRow][$j]->SetGridStyle(NULL,$aStyle);
1041        }
1042    }
1043
1044    /*---------------------------------------------------------------------
1045     * Merge cells
1046     *---------------------------------------------------------------------
1047     */
1048
1049    function MergeRow($aRow,$aHAlign='center',$aVAlign='center') {
1050        $this->_chkR($aRow);
1051        $this->MergeCells($aRow,0,$aRow,$this->iSize[1]-1,$aHAlign,$aVAlign);
1052    }
1053
1054    function MergeCol($aCol,$aHAlign='center',$aVAlign='center') {
1055        $this->_chkC($aCol);
1056        $this->MergeCells(0,$aCol,$this->iSize[0]-1,$aCol,$aHAlign,$aVAlign);
1057    }
1058
1059    function MergeCells($aR1,$aC1,$aR2,$aC2,$aHAlign='center',$aVAlign='center') {
1060        if( $aR1 > $aR2 || $aC1 > $aC2 ) {
1061            JpGraphError::RaiseL(27004);
1062            //('GTextTable::MergeCells(). Specified cell range to be merged is not valid.');
1063        }
1064        $this->_chkR($aR1); $this->_chkC($aC1);
1065        $this->_chkR($aR2); $this->_chkC($aC2);
1066        $rspan = $aR2-$aR1+1;
1067        $cspan = $aC2-$aC1+1;
1068        // Setup the parent cell for this merged group
1069        if( $this->iCells[$aR1][$aC1]->IsMerged() ) {
1070            JpGraphError::RaiseL(27005,$aR1,$aC1,$aR2,$aC2);
1071            //("Cannot merge already merged cells in the range ($aR1,$aC1), ($aR2,$aC2)");
1072        }
1073        $this->iCells[$aR1][$aC1]->SetRowColSpan($rspan,$cspan);
1074        $this->iCells[$aR1][$aC1]->SetAlign($aHAlign,$aVAlign);
1075        for($i=$aR1; $i <= $aR2; ++$i) {
1076            for($j=$aC1; $j <= $aC2; ++$j) {
1077                if( ! ($i == $aR1 && $j == $aC1) ) {
1078                    if( $this->iCells[$i][$j]->IsMerged() ) {
1079                        JpGraphError::RaiseL(27005,$aR1,$aC1,$aR2,$aC2);
1080                        //("Cannot merge already merged cells in the range ($aR1,$aC1), ($aR2,$aC2)");
1081                    }
1082                    $this->iCells[$i][$j]->SetMerged($aR1,$aC1,true);
1083                }
1084            }
1085        }
1086    }
1087
1088
1089    /*---------------------------------------------------------------------
1090     * CSIM methods
1091     *---------------------------------------------------------------------
1092     */
1093
1094    function SetCSIMTarget($aTarget,$aAlt=null,$aAutoTarget=false) {
1095        $m = $this->iSize[0];
1096        $n = $this->iSize[1];
1097        $csim = '';
1098        for($i=0; $i < $m; ++$i) {
1099            for($j=0; $j < $n; ++$j) {
1100                if( $aAutoTarget )
1101                $t = $aTarget."?row=$i&col=$j";
1102                else
1103                $t = $aTarget;
1104                $this->iCells[$i][$j]->SetCSIMTarget($t,$aAlt);
1105            }
1106        }
1107    }
1108
1109    function SetCellCSIMTarget($aRow,$aCol,$aTarget,$aAlt=null) {
1110        $this->_chkR($aRow);
1111        $this->_chkC($aCol);
1112        $this->iCells[$aRow][$aCol]->SetCSIMTarget($aTarget,$aAlt);
1113    }
1114
1115    /*---------------------------------------------------------------------
1116     * Private methods
1117     *---------------------------------------------------------------------
1118     */
1119
1120    function GetCSIMAreas() {
1121        $m = $this->iSize[0];
1122        $n = $this->iSize[1];
1123        $csim = '';
1124        for($i=0; $i < $m; ++$i) {
1125            for($j=0; $j < $n; ++$j) {
1126                $csim .= $this->iCells[$i][$j]->GetCSIMArea();
1127            }
1128        }
1129        return $csim;
1130    }
1131
1132    function _chkC($aCol) {
1133        if( ! $this->iInit ) {
1134            JpGraphError::Raise(27014); // Table not initialized
1135        }
1136        if( $aCol < 0 || $aCol >= $this->iSize[1] )
1137        JpGraphError::RaiseL(27006,$aCol);
1138        //("GTextTable:\nColumn argument ($aCol) is outside specified table size.");
1139    }
1140
1141    function _chkR($aRow) {
1142        if( ! $this->iInit ) {
1143            JpGraphError::Raise(27014); // Table not initialized
1144        }
1145        if( $aRow < 0 || $aRow >= $this->iSize[0] )
1146        JpGraphError::RaiseL(27007,$aRow);
1147        //("GTextTable:\nRow argument ($aRow) is outside specified table size.");
1148    }
1149
1150    function _getScalePos() {
1151        if( $this->iScaleXPos === null || $this->iScaleYPos === null ) {
1152            return false;
1153        }
1154        return array($this->iScaleXPos, $this->iScaleYPos);
1155    }
1156
1157    function _autoSizeTable($aImg) {
1158        // Get maximum column width and row height
1159        $m = $this->iSize[0];
1160        $n = $this->iSize[1];
1161        $w=1;$h=1;
1162
1163        // Get maximum row height per row
1164        for($i=0; $i < $m; ++$i) {
1165            $h=0;
1166            for($j=0; $j < $n; ++$j) {
1167                $h = max($h,$this->iCells[$i][$j]->GetHeight($aImg));
1168            }
1169            if( isset($this->iRowHeight[$i]) ) {
1170                $this->iRowHeight[$i]  = max($h,$this->iRowHeight[$i]);
1171            }
1172            else
1173            $this->iRowHeight[$i]  = $h;
1174        }
1175
1176        // Get maximum col width per columns
1177        for($j=0; $j < $n; ++$j) {
1178            $w=0;
1179            for($i=0; $i < $m; ++$i) {
1180                $w = max($w,$this->iCells[$i][$j]->GetWidth($aImg));
1181            }
1182            if( isset($this->iColWidth[$j]) ) {
1183                $this->iColWidth[$j]  = max($w,$this->iColWidth[$j]);
1184            }
1185            else
1186            $this->iColWidth[$j]  = $w;
1187        }
1188    }
1189
1190    function _setcell($aRow,$aCol,$aVal='') {
1191        if( isset($this->iCells[$aRow][$aCol]) ) {
1192            $this->iCells[$aRow][$aCol]->Set($aVal);
1193        }
1194        else {
1195            $this->iCells[$aRow][$aCol] = new GTextTableCell((string)$aVal,$aRow,$aCol);
1196            $this->iCells[$aRow][$aCol]->Init($this);
1197        }
1198    }
1199
1200    function StrokeWithScale($aImg,$aXScale,$aYScale) {
1201        if( is_numeric($this->iScaleXPos) && is_numeric($this->iScaleYPos) ) {
1202            $x = round($aXScale->Translate($this->iScaleXPos));
1203            $y = round($aYScale->Translate($this->iScaleYPos));
1204            $this->Stroke($aImg,$x,$y);
1205        }
1206        else {
1207            $this->Stroke($aImg);
1208        }
1209    }
1210
1211    function Stroke($aImg,$aX=NULL,$aY=NULL) {
1212        if( $aX !== NULL && $aY !== NULL ) {
1213            $this->iXPos = $aX;
1214            $this->iYPos = $aY;
1215        }
1216
1217        $rc = $this->iSize[0]; // row count
1218        $cc = $this->iSize[1]; // column count
1219
1220        if( $rc == 0 || $cc == 0 ) {
1221            JpGraphError::RaiseL(27009);
1222        }
1223
1224        // Adjust margins of each cell based on the weight of the grid. Each table grid line
1225        // is actually occupying the left side and top part of each cell.
1226        for($j=0; $j < $cc; ++$j) {
1227            $this->iCells[0][$j]->iMarginTop += $this->iBorderWeight;
1228        }
1229        for($i=0; $i < $rc; ++$i) {
1230            $this->iCells[$i][0]->iMarginLeft += $this->iBorderWeight;
1231        }
1232        for($i=0; $i < $rc; ++$i) {
1233            for($j=0; $j < $cc; ++$j) {
1234                $this->iCells[$i][$j]->AdjustMarginsForGrid();
1235            }
1236        }
1237
1238        // adjust row and column size depending on cell content
1239        $this->_autoSizeTable($aImg);
1240
1241        if( $this->iSize[1] != count($this->iColWidth) || $this->iSize[0] != count($this->iRowHeight) ) {
1242            JpGraphError::RaiseL(27008);
1243            //('Column and row size arrays must match the dimesnions of the table');
1244        }
1245
1246        // Find out overall table size
1247        $width=0;
1248        for($i=0; $i < $cc; ++$i) {
1249            $width += $this->iColWidth[$i];
1250        }
1251        $height=0;
1252        for($i=0; $i < $rc; ++$i) {
1253            $height += $this->iRowHeight[$i];
1254        }
1255
1256        // Adjust the X,Y position to alway be at the top left corner
1257        // The anchor position, i.e. how the client want to interpret the specified
1258        // x and y coordinate must be taken into account
1259        switch( strtolower($this->iXAnchor) ) {
1260            case 'left' :
1261                break;
1262            case 'center':
1263                $this->iXPos -= round($width/2);
1264                break;
1265            case 'right':
1266                $this->iXPos -= $width;
1267                break;
1268        }
1269        switch( strtolower($this->iYAnchor) ) {
1270            case 'top' :
1271                break;
1272            case 'center':
1273            case 'middle':
1274                $this->iYPos -= round($height/2);
1275                break;
1276            case 'bottom':
1277                $this->iYPos -= $height;
1278                break;
1279        }
1280
1281        // Set the overall background color of the table if set
1282        if( $this->iBGColor !== '' ) {
1283            $aImg->SetColor($this->iBGColor);
1284            $aImg->FilledRectangle($this->iXPos,$this->iYPos,$this->iXPos+$width,$this->iYPos+$height);
1285        }
1286
1287        // Stroke all cells
1288        $rpos=$this->iYPos;
1289        for($i=0; $i < $rc; ++$i) {
1290            $cpos=$this->iXPos;
1291            for($j=0; $j < $cc; ++$j) {
1292                // Calculate width and height of this cell if it is spanning
1293                // more than one column or row
1294                $cwidth=0;
1295                for( $k=0; $k < $this->iCells[$i][$j]->iColSpan; ++$k ) {
1296                    $cwidth += $this->iColWidth[$j+$k];
1297                }
1298                $cheight=0;
1299                for( $k=0; $k < $this->iCells[$i][$j]->iRowSpan; ++$k ) {
1300                    $cheight += $this->iRowHeight[$i+$k];
1301                }
1302
1303                $this->iCells[$i][$j]->Stroke($aImg,$cpos,$rpos,$cwidth,$cheight);
1304                $cpos += $this->iColWidth[$j];
1305            }
1306            $rpos += $this->iRowHeight[$i];
1307        }
1308
1309        // Stroke outer border
1310        $aImg->SetColor($this->iBorderColor);
1311        if( $this->iBorderWeight == 1 )
1312        $aImg->Rectangle($this->iXPos,$this->iYPos,$this->iXPos+$width,$this->iYPos+$height);
1313        else {
1314            for( $i=0; $i < $this->iBorderWeight; ++$i )
1315            $aImg->Rectangle($this->iXPos+$i,$this->iYPos+$i,
1316            $this->iXPos+$width-1+$this->iBorderWeight-$i,
1317            $this->iYPos+$height-1+$this->iBorderWeight-$i);
1318        }
1319    }
1320}
1321
1322/*
1323 EOF
1324 */
1325?>
Note: See TracBrowser for help on using the repository browser.