Heuristic ranking analysis
[contractdashboard.git] / lib / pChart2.1.0 / class / pScatter.class.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
<?php
 /*
     pScatter - class to draw scatter charts
 
     Version     : 2.1.0
     Made by     : Jean-Damien POGOLOTTI
     Last Update : 26/01/11
 
     This file can be distributed under the license you can find at :
 
                       http://www.pchart.net/license
 
     You can find the whole class documentation on the pChart web site.
 */
 
 define("SCATTER_MISSING_X_SERIE"       , 190001);
 define("SCATTER_MISSING_Y_SERIE"       , 190002);
 
 /* pScatter class definition */
 class pScatter
  {
   var $pChartObject;
   var $pDataObject;
 
   /* Class creator */
   function pScatter($pChartObject,$pDataObject)
    {
     $this->pChartObject = $pChartObject;
     $this->pDataObject  = $pDataObject;
    }
 
   /* Prepare the scale */
   function drawScatterScale($Format="")
    {
     $Mode              = isset($Format["Mode"]) ? $Format["Mode"] : SCALE_MODE_FLOATING;
     $Floating          = isset($Format["Floating"]) ? $Format["Floating"] : FALSE;
     $XLabelsRotation   = isset($Format["XLabelsRotation"]) ? $Format["XLabelsRotation"] : 90;
     $MinDivHeight      = isset($Format["MinDivHeight"]) ? $Format["MinDivHeight"] : 20;
     $Factors           = isset($Format["Factors"]) ? $Format["Factors"] : array(1,2,5);
     $ManualScale       = isset($Format["ManualScale"]) ? $Format["ManualScale"] : array("0"=>array("Min"=>-100,"Max"=>100));
     $XMargin           = isset($Format["XMargin"]) ? $Format["XMargin"] : 0;
     $YMargin           = isset($Format["YMargin"]) ? $Format["YMargin"] : 0;
     $ScaleSpacing      = isset($Format["ScaleSpacing"]) ? $Format["ScaleSpacing"] : 15;
     $InnerTickWidth    = isset($Format["InnerTickWidth"]) ? $Format["InnerTickWidth"] : 2;
     $OuterTickWidth    = isset($Format["OuterTickWidth"]) ? $Format["OuterTickWidth"] : 2;
     $DrawXLines        = isset($Format["DrawXLines"]) ? $Format["DrawXLines"] : ALL;
     $DrawYLines        = isset($Format["DrawYLines"]) ? $Format["DrawYLines"] : ALL;
     $GridTicks         = isset($Format["GridTicks"]) ? $Format["GridTicks"] : 4;
     $GridR             = isset($Format["GridR"]) ? $Format["GridR"] : 255;
     $GridG             = isset($Format["GridG"]) ? $Format["GridG"] : 255;
     $GridB             = isset($Format["GridB"]) ? $Format["GridB"] : 255;
     $GridAlpha         = isset($Format["GridAlpha"]) ? $Format["GridAlpha"] : 40;
     $AxisRo            = isset($Format["AxisR"]) ? $Format["AxisR"] : 0;
     $AxisGo            = isset($Format["AxisG"]) ? $Format["AxisG"] : 0;
     $AxisBo            = isset($Format["AxisB"]) ? $Format["AxisB"] : 0;
     $AxisAlpha         = isset($Format["AxisAlpha"]) ? $Format["AxisAlpha"] : 100;
     $TickRo            = isset($Format["TickR"]) ? $Format["TickR"] : 0;
     $TickGo            = isset($Format["TickG"]) ? $Format["TickG"] : 0;
     $TickBo            = isset($Format["TickB"]) ? $Format["TickB"] : 0;
     $TickAlpha         = isset($Format["TickAlpha"]) ? $Format["TickAlpha"] : 100;
     $DrawSubTicks      = isset($Format["DrawSubTicks"]) ? $Format["DrawSubTicks"] : FALSE;
     $InnerSubTickWidth = isset($Format["InnerSubTickWidth"]) ? $Format["InnerSubTickWidth"] : 0;
     $OuterSubTickWidth = isset($Format["OuterSubTickWidth"]) ? $Format["OuterSubTickWidth"] : 2;
     $SubTickR          = isset($Format["SubTickR"]) ? $Format["SubTickR"] : 255;
     $SubTickG          = isset($Format["SubTickG"]) ? $Format["SubTickG"] : 0;
     $SubTickB          = isset($Format["SubTickB"]) ? $Format["SubTickB"] : 0;
     $SubTickAlpha      = isset($Format["SubTickAlpha"]) ? $Format["SubTickAlpha"] : 100;
     $XReleasePercent   = isset($Format["XReleasePercent"]) ? $Format["XReleasePercent"] : 1;
     $DrawArrows        = isset($Format["DrawArrows"]) ? $Format["DrawArrows"] : FALSE;
     $ArrowSize         = isset($Format["ArrowSize"]) ? $Format["ArrowSize"] : 8;
     $CycleBackground   = isset($Format["CycleBackground"]) ? $Format["CycleBackground"] : FALSE;
     $BackgroundR1      = isset($Format["BackgroundR1"]) ? $Format["BackgroundR1"] : 255;
     $BackgroundG1      = isset($Format["BackgroundG1"]) ? $Format["BackgroundG1"] : 255;
     $BackgroundB1      = isset($Format["BackgroundB1"]) ? $Format["BackgroundB1"] : 255;
     $BackgroundAlpha1  = isset($Format["BackgroundAlpha1"]) ? $Format["BackgroundAlpha1"] : 10;
     $BackgroundR2      = isset($Format["BackgroundR2"]) ? $Format["BackgroundR2"] : 230;
     $BackgroundG2      = isset($Format["BackgroundG2"]) ? $Format["BackgroundG2"] : 230;
     $BackgroundB2      = isset($Format["BackgroundB2"]) ? $Format["BackgroundB2"] : 230;
     $BackgroundAlpha2  = isset($Format["BackgroundAlpha2"]) ? $Format["BackgroundAlpha2"] : 10;
 
     /* Check if we have at least both one X and Y axis */
     $GotXAxis = FALSE; $GotYAxis = FALSE;
     foreach($this->pDataObject->Data["Axis"] as $AxisID => $AxisSettings)
      {
       if ( $AxisSettings["Identity"] == AXIS_X ) { $GotXAxis = TRUE; }
       if ( $AxisSettings["Identity"] == AXIS_Y ) { $GotYAxis = TRUE; }
      }
     if ( !$GotXAxis ) { return(SCATTER_MISSING_X_SERIE); }
     if ( !$GotYAxis ) { return(SCATTER_MISSING_Y_SERIE); }
 
     /* Skip a NOTICE event in case of an empty array */
     if ( $DrawYLines == NONE ) { $DrawYLines = array("zarma"=>"31"); }
 
     $Data = $this->pDataObject->getData();
 
     foreach($Data["Axis"] as $AxisID => $AxisSettings)
      {
       if ( $AxisSettings["Identity"] == AXIS_X)
        { $Width = $this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1 - $XMargin*2; }
       else
        { $Width = $this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1 - $YMargin*2; }
 
       $AxisMin = ABSOLUTE_MAX; $AxisMax = OUT_OF_SIGHT;
       if ( $Mode == SCALE_MODE_FLOATING )
        {
         foreach($Data["Series"] as $SerieID => $SerieParameter)
          {
           if ( $SerieParameter["Axis"] == $AxisID && $Data["Series"][$SerieID]["isDrawable"] )
            {
             $AxisMax = max($AxisMax,$Data["Series"][$SerieID]["Max"]);
             $AxisMin = min($AxisMin,$Data["Series"][$SerieID]["Min"]);
            }
          }
         $AutoMargin = (($AxisMax-$AxisMin)/100)*$XReleasePercent;
 
         $Data["Axis"][$AxisID]["Min"] = $AxisMin-$AutoMargin; $Data["Axis"][$AxisID]["Max"] = $AxisMax+$AutoMargin;
        }
       elseif ( $Mode == SCALE_MODE_MANUAL )
        {
         if ( isset($ManualScale[$AxisID]["Min"]) && isset($ManualScale[$AxisID]["Max"]) )
          {
           $Data["Axis"][$AxisID]["Min"] = $ManualScale[$AxisID]["Min"];
           $Data["Axis"][$AxisID]["Max"] = $ManualScale[$AxisID]["Max"];
          }
         else
          { echo "Manual scale boundaries not set."; exit(); }
        }
 
       /* Full manual scale */
       if ( isset($ManualScale[$AxisID]["Rows"]) && isset($ManualScale[$AxisID]["RowHeight"]) )
        $Scale = array("Rows"=>$ManualScale[$AxisID]["Rows"],"RowHeight"=>$ManualScale[$AxisID]["RowHeight"],"XMin"=>$ManualScale[$AxisID]["Min"],"XMax"=>$ManualScale[$AxisID]["Max"]);
       else
        {
         $MaxDivs = floor($Width/$MinDivHeight);
         $Scale   = $this->pChartObject->computeScale($Data["Axis"][$AxisID]["Min"],$Data["Axis"][$AxisID]["Max"],$MaxDivs,$Factors,$AxisID);
        }
 
       $Data["Axis"][$AxisID]["Margin"]    = $AxisSettings["Identity"] == AXIS_X ? $XMargin : $YMargin;
       $Data["Axis"][$AxisID]["ScaleMin"]  = $Scale["XMin"];
       $Data["Axis"][$AxisID]["ScaleMax"]  = $Scale["XMax"];
       $Data["Axis"][$AxisID]["Rows"]      = $Scale["Rows"];
       $Data["Axis"][$AxisID]["RowHeight"] = $Scale["RowHeight"];
 
       if ( isset($Scale["Format"]) ) { $Data["Axis"][$AxisID]["Format"] = $Scale["Format"]; }
 
       if ( !isset($Data["Axis"][$AxisID]["Display"]) ) { $Data["Axis"][$AxisID]["Display"] = NULL; }
       if ( !isset($Data["Axis"][$AxisID]["Format"]) )  { $Data["Axis"][$AxisID]["Format"] = NULL; }
       if ( !isset($Data["Axis"][$AxisID]["Unit"]) )    { $Data["Axis"][$AxisID]["Unit"] = NULL; }
      }
 
     /* Get the default font color */
     $FontColorRo = $this->pChartObject->FontColorR; $FontColorGo = $this->pChartObject->FontColorG; $FontColorBo = $this->pChartObject->FontColorB;
 
     /* Set the original boundaries */
     $AxisPos["L"] = $this->pChartObject->GraphAreaX1; $AxisPos["R"] = $this->pChartObject->GraphAreaX2; $AxisPos["T"] = $this->pChartObject->GraphAreaY1; $AxisPos["B"] = $this->pChartObject->GraphAreaY2;
 
     foreach($Data["Axis"] as $AxisID => $AxisSettings)
      {
       if ( isset($AxisSettings["Color"]) )
        {
         $AxisR = $AxisSettings["Color"]["R"]; $AxisG = $AxisSettings["Color"]["G"]; $AxisB = $AxisSettings["Color"]["B"];
         $TickR = $AxisSettings["Color"]["R"]; $TickG = $AxisSettings["Color"]["G"]; $TickB = $AxisSettings["Color"]["B"];
         $this->pChartObject->setFontProperties(array("R"=>$AxisSettings["Color"]["R"],"G"=>$AxisSettings["Color"]["G"],"B"=>$AxisSettings["Color"]["B"]));
        }
       else
        {
         $AxisR = $AxisRo; $AxisG = $AxisGo; $AxisB = $AxisBo;
         $TickR = $TickRo; $TickG = $TickGo; $TickB = $TickBo;
         $this->pChartObject->setFontProperties(array("R"=>$FontColorRo,"G"=>$FontColorGo,"B"=>$FontColorBo));
        }
 
       $LastValue = "w00t"; $ID = 1;
       if ( $AxisSettings["Identity"] == AXIS_X )
        {
         if ( $AxisSettings["Position"] == AXIS_POSITION_BOTTOM )
          {
           if ( $XLabelsRotation == 0 )                            { $LabelAlign = TEXT_ALIGN_TOPMIDDLE; $LabelOffset = 2; }
           if ( $XLabelsRotation > 0 && $XLabelsRotation < 190 )   { $LabelAlign = TEXT_ALIGN_MIDDLERIGHT; $LabelOffset = 5; }
           if ( $XLabelsRotation == 180 )                          { $LabelAlign = TEXT_ALIGN_BOTTOMMIDDLE; $LabelOffset = 5; }
           if ( $XLabelsRotation > 180 && $XLabelsRotation < 360 ) { $LabelAlign = TEXT_ALIGN_MIDDLELEFT; $LabelOffset = 2; }
 
           if ( $Floating )
            { $FloatingOffset = $YMargin; $this->pChartObject->drawLine($this->pChartObject->GraphAreaX1+$AxisSettings["Margin"],$AxisPos["B"],$this->pChartObject->GraphAreaX2-$AxisSettings["Margin"],$AxisPos["B"],array("R"=>$AxisR,"G"=>$AxisG,"B"=>$AxisB,"Alpha"=>$AxisAlpha)); }
           else
            { $FloatingOffset = 0; $this->pChartObject->drawLine($this->pChartObject->GraphAreaX1,$AxisPos["B"],$this->pChartObject->GraphAreaX2,$AxisPos["B"],array("R"=>$AxisR,"G"=>$AxisG,"B"=>$AxisB,"Alpha"=>$AxisAlpha)); }
 
           if ( $DrawArrows ) { $this->pChartObject->drawArrow($this->pChartObject->GraphAreaX2-$AxisSettings["Margin"],$AxisPos["B"],$this->pChartObject->GraphAreaX2+($ArrowSize*2),$AxisPos["B"],array("FillR"=>$AxisR,"FillG"=>$AxisG,"FillB"=>$AxisB,"Size"=>$ArrowSize)); }
 
           $Width = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1) - $AxisSettings["Margin"]*2;
           $Step   = $Width / $AxisSettings["Rows"]; $SubTicksSize = $Step /2; $MaxBottom = $AxisPos["B"];
           $LastX  = NULL;
           for($i=0;$i<=$AxisSettings["Rows"];$i++)
            {
             $XPos  = $this->pChartObject->GraphAreaX1 + $AxisSettings["Margin"] + $Step*$i;
             $YPos  = $AxisPos["B"];
             $Value = $this->pChartObject->scaleFormat($AxisSettings["ScaleMin"] + $AxisSettings["RowHeight"]*$i,$AxisSettings["Display"],$AxisSettings["Format"],$AxisSettings["Unit"]);
 
             if ( $i%2 == 1 ) { $BGColor = array("R"=>$BackgroundR1,"G"=>$BackgroundG1,"B"=>$BackgroundB1,"Alpha"=>$BackgroundAlpha1); } else { $BGColor = array("R"=>$BackgroundR2,"G"=>$BackgroundG2,"B"=>$BackgroundB2,"Alpha"=>$BackgroundAlpha2); }
             if ( $LastX != NULL && $CycleBackground  && ( $DrawXLines == ALL || in_array($AxisID,$DrawXLines) )) { $this->pChartObject->drawFilledRectangle($LastX,$this->pChartObject->GraphAreaY1+$FloatingOffset,$XPos,$this->pChartObject->GraphAreaY2-$FloatingOffset,$BGColor); }
 
             if ( $DrawXLines == ALL || in_array($AxisID,$DrawXLines) ) { $this->pChartObject->drawLine($XPos,$this->pChartObject->GraphAreaY1+$FloatingOffset,$XPos,$this->pChartObject->GraphAreaY2-$FloatingOffset,array("R"=>$GridR,"G"=>$GridG,"B"=>$GridB,"Alpha"=>$GridAlpha,"Ticks"=>$GridTicks)); }
             if ( $DrawSubTicks && $i != $AxisSettings["Rows"] )
              $this->pChartObject->drawLine($XPos+$SubTicksSize,$YPos-$InnerSubTickWidth,$XPos+$SubTicksSize,$YPos+$OuterSubTickWidth,array("R"=>$SubTickR,"G"=>$SubTickG,"B"=>$SubTickB,"Alpha"=>$SubTickAlpha));
 
             $this->pChartObject->drawLine($XPos,$YPos-$InnerTickWidth,$XPos,$YPos+$OuterTickWidth,array("R"=>$TickR,"G"=>$TickG,"B"=>$TickB,"Alpha"=>$TickAlpha));
             $Bounds    = $this->pChartObject->drawText($XPos,$YPos+$OuterTickWidth+$LabelOffset,$Value,array("Angle"=>$XLabelsRotation,"Align"=>$LabelAlign));
             $TxtBottom = $YPos+2+$OuterTickWidth+2+($Bounds[0]["Y"]-$Bounds[2]["Y"]);
             $MaxBottom = max($MaxBottom,$TxtBottom);
 
             $LastX = $XPos;
            }
 
           if ( isset($AxisSettings["Name"]) )
            {
             $YPos   = $MaxBottom+2;
             $XPos   = $this->pChartObject->GraphAreaX1+($this->pChartObject->GraphAreaX2-$this->pChartObject->GraphAreaX1)/2;
             $Bounds = $this->pChartObject->drawText($XPos,$YPos,$AxisSettings["Name"],array("Align"=>TEXT_ALIGN_TOPMIDDLE));
             $MaxBottom = $Bounds[0]["Y"];
 
             $this->pDataObject->Data["GraphArea"]["Y2"] = $MaxBottom + $this->pChartObject->FontSize;
            }
 
           $AxisPos["B"] = $MaxBottom + $ScaleSpacing;
          }
         elseif ( $AxisSettings["Position"] == AXIS_POSITION_TOP )
          {
           if ( $XLabelsRotation == 0 )                                 { $LabelAlign = TEXT_ALIGN_BOTTOMMIDDLE; $LabelOffset = 2; }
           if ( $XLabelsRotation > 0 && $XLabelsRotation < 190 )        { $LabelAlign = TEXT_ALIGN_MIDDLELEFT; $LabelOffset = 2; }
           if ( $XLabelsRotation == 180 )                               { $LabelAlign = TEXT_ALIGN_TOPMIDDLE; $LabelOffset = 5; }
           if ( $XLabelsRotation > 180 && $SLabelxRotation < 360 )      { $LabelAlign = TEXT_ALIGN_MIDDLERIGHT; $LabelOffset = 5; }
 
           if ( $Floating )
            { $FloatingOffset = $YMargin; $this->pChartObject->drawLine($this->pChartObject->GraphAreaX1+$AxisSettings["Margin"],$AxisPos["T"],$this->pChartObject->GraphAreaX2-$AxisSettings["Margin"],$AxisPos["T"],array("R"=>$AxisR,"G"=>$AxisG,"B"=>$AxisB,"Alpha"=>$AxisAlpha)); }
           else
            { $FloatingOffset = 0; $this->pChartObject->drawLine($this->pChartObject->GraphAreaX1,$AxisPos["T"],$this->pChartObject->GraphAreaX2,$AxisPos["T"],array("R"=>$AxisR,"G"=>$AxisG,"B"=>$AxisB,"Alpha"=>$AxisAlpha)); }
 
           if ( $DrawArrows ) { $this->pChartObject->drawArrow($this->pChartObject->GraphAreaX2-$AxisSettings["Margin"],$AxisPos["T"],$this->pChartObject->GraphAreaX2+($ArrowSize*2),$AxisPos["T"],array("FillR"=>$AxisR,"FillG"=>$AxisG,"FillB"=>$AxisB,"Size"=>$ArrowSize)); }
 
           $Width = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1) - $AxisSettings["Margin"]*2;
           $Step   = $Width / $AxisSettings["Rows"]; $SubTicksSize = $Step /2; $MinTop = $AxisPos["T"];
           $LastX  = NULL;
           for($i=0;$i<=$AxisSettings["Rows"];$i++)
            {
             $XPos  = $this->pChartObject->GraphAreaX1 + $AxisSettings["Margin"] + $Step*$i;
             $YPos  = $AxisPos["T"];
             $Value = $this->pChartObject->scaleFormat($AxisSettings["ScaleMin"] + $AxisSettings["RowHeight"]*$i,$AxisSettings["Display"],$AxisSettings["Format"],$AxisSettings["Unit"]);
 
             if ( $i%2 == 1 ) { $BGColor = array("R"=>$BackgroundR1,"G"=>$BackgroundG1,"B"=>$BackgroundB1,"Alpha"=>$BackgroundAlpha1); } else { $BGColor = array("R"=>$BackgroundR2,"G"=>$BackgroundG2,"B"=>$BackgroundB2,"Alpha"=>$BackgroundAlpha2); }
             if ( $LastX != NULL && $CycleBackground  && ( $DrawXLines == ALL || in_array($AxisID,$DrawXLines) )) { $this->pChartObject->drawFilledRectangle($LastX,$this->pChartObject->GraphAreaY1+$FloatingOffset,$XPos,$this->pChartObject->GraphAreaY2-$FloatingOffset,$BGColor); }
 
             if ( $DrawXLines == ALL || in_array($AxisID,$DrawXLines) ) { $this->pChartObject->drawLine($XPos,$this->pChartObject->GraphAreaY1+$FloatingOffset,$XPos,$this->pChartObject->GraphAreaY2-$FloatingOffset,array("R"=>$GridR,"G"=>$GridG,"B"=>$GridB,"Alpha"=>$GridAlpha,"Ticks"=>$GridTicks)); }
 
             if ( $DrawSubTicks && $i != $AxisSettings["Rows"] )
              $this->pChartObject->drawLine($XPos+$SubTicksSize,$YPos-$OuterSubTickWidth,$XPos+$SubTicksSize,$YPos+$InnerSubTickWidth,array("R"=>$SubTickR,"G"=>$SubTickG,"B"=>$SubTickB,"Alpha"=>$SubTickAlpha));
 
             $this->pChartObject->drawLine($XPos,$YPos-$OuterTickWidth,$XPos,$YPos+$InnerTickWidth,array("R"=>$TickR,"G"=>$TickG,"B"=>$TickB,"Alpha"=>$TickAlpha));
             $Bounds = $this->pChartObject->drawText($XPos,$YPos-$OuterTickWidth-$LabelOffset,$Value,array("Angle"=>$XLabelsRotation,"Align"=>$LabelAlign));
             $TxtBox = $YPos-$OuterTickWidth-4-($Bounds[0]["Y"]-$Bounds[2]["Y"]);
             $MinTop = min($MinTop,$TxtBox);
 
             $LastX = $XPos;
            }
 
           if ( isset($AxisSettings["Name"]) )
            {
             $YPos   = $MinTop-2;
             $XPos   = $this->pChartObject->GraphAreaX1+($this->pChartObject->GraphAreaX2-$this->pChartObject->GraphAreaX1)/2;
             $Bounds = $this->pChartObject->drawText($XPos,$YPos,$AxisSettings["Name"],array("Align"=>TEXT_ALIGN_BOTTOMMIDDLE));
             $MinTop = $Bounds[2]["Y"];
 
             $this->pDataObject->Data["GraphArea"]["Y1"] = $MinTop;
            }
 
           $AxisPos["T"] = $MinTop - $ScaleSpacing;
          }
        }
       elseif ( $AxisSettings["Identity"] == AXIS_Y )
        {
         if ( $AxisSettings["Position"] == AXIS_POSITION_LEFT )
          {
 
           if ( $Floating )
            { $FloatingOffset = $XMargin; $this->pChartObject->drawLine($AxisPos["L"],$this->pChartObject->GraphAreaY1+$AxisSettings["Margin"],$AxisPos["L"],$this->pChartObject->GraphAreaY2-$AxisSettings["Margin"],array("R"=>$AxisR,"G"=>$AxisG,"B"=>$AxisB,"Alpha"=>$AxisAlpha)); }
           else
            { $FloatingOffset = 0; $this->pChartObject->drawLine($AxisPos["L"],$this->pChartObject->GraphAreaY1,$AxisPos["L"],$this->pChartObject->GraphAreaY2,array("R"=>$AxisR,"G"=>$AxisG,"B"=>$AxisB,"Alpha"=>$AxisAlpha)); }
 
           if ( $DrawArrows ) { $this->pChartObject->drawArrow($AxisPos["L"],$this->pChartObject->GraphAreaY1+$AxisSettings["Margin"],$AxisPos["L"],$this->pChartObject->GraphAreaY1-($ArrowSize*2),array("FillR"=>$AxisR,"FillG"=>$AxisG,"FillB"=>$AxisB,"Size"=>$ArrowSize)); }
 
           $Height = ($this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1) - $AxisSettings["Margin"]*2;
           $Step   = $Height / $AxisSettings["Rows"]; $SubTicksSize = $Step /2; $MinLeft = $AxisPos["L"];
           $LastY  = NULL;
           for($i=0;$i<=$AxisSettings["Rows"];$i++)
            {
             $YPos  = $this->pChartObject->GraphAreaY2 - $AxisSettings["Margin"] - $Step*$i;
             $XPos  = $AxisPos["L"];
             $Value = $this->pChartObject->scaleFormat($AxisSettings["ScaleMin"] + $AxisSettings["RowHeight"]*$i,$AxisSettings["Display"],$AxisSettings["Format"],$AxisSettings["Unit"]);
 
             if ( $i%2 == 1 ) { $BGColor = array("R"=>$BackgroundR1,"G"=>$BackgroundG1,"B"=>$BackgroundB1,"Alpha"=>$BackgroundAlpha1); } else { $BGColor = array("R"=>$BackgroundR2,"G"=>$BackgroundG2,"B"=>$BackgroundB2,"Alpha"=>$BackgroundAlpha2); }
             if ( $LastY != NULL && $CycleBackground && ( $DrawYLines == ALL || in_array($AxisID,$DrawYLines) )) { $this->pChartObject->drawFilledRectangle($this->pChartObject->GraphAreaX1+$FloatingOffset,$LastY,$this->pChartObject->GraphAreaX2-$FloatingOffset,$YPos,$BGColor); }
 
             if ( ($YPos != $this->pChartObject->GraphAreaY1 && $YPos != $this->pChartObject->GraphAreaY2) && ($DrawYLines == ALL || in_array($AxisID,$DrawYLines) )) { $this->pChartObject->drawLine($this->pChartObject->GraphAreaX1+$FloatingOffset,$YPos,$this->pChartObject->GraphAreaX2-$FloatingOffset,$YPos,array("R"=>$GridR,"G"=>$GridG,"B"=>$GridB,"Alpha"=>$GridAlpha,"Ticks"=>$GridTicks)); }
 
             if ( $DrawSubTicks && $i != $AxisSettings["Rows"] )
              $this->pChartObject->drawLine($XPos-$OuterSubTickWidth,$YPos-$SubTicksSize,$XPos+$InnerSubTickWidth,$YPos-$SubTicksSize,array("R"=>$SubTickR,"G"=>$SubTickG,"B"=>$SubTickB,"Alpha"=>$SubTickAlpha));
 
             $this->pChartObject->drawLine($XPos-$OuterTickWidth,$YPos,$XPos+$InnerTickWidth,$YPos,array("R"=>$TickR,"G"=>$TickG,"B"=>$TickB,"Alpha"=>$TickAlpha));
             $Bounds  = $this->pChartObject->drawText($XPos-$OuterTickWidth-2,$YPos,$Value,array("Align"=>TEXT_ALIGN_MIDDLERIGHT));
             $TxtLeft = $XPos-$OuterTickWidth-2-($Bounds[1]["X"]-$Bounds[0]["X"]);
             $MinLeft = min($MinLeft,$TxtLeft);
 
             $LastY = $YPos;
            }
 
           if ( isset($AxisSettings["Name"]) )
            {
             $XPos    = $MinLeft-2;
             $YPos    = $this->pChartObject->GraphAreaY1+($this->pChartObject->GraphAreaY2-$this->pChartObject->GraphAreaY1)/2;
             $Bounds  = $this->pChartObject->drawText($XPos,$YPos,$AxisSettings["Name"],array("Align"=>TEXT_ALIGN_BOTTOMMIDDLE,"Angle"=>90));
             $MinLeft = $Bounds[2]["X"];
 
             $this->pDataObject->Data["GraphArea"]["X1"] = $MinLeft;
            }
 
           $AxisPos["L"] = $MinLeft - $ScaleSpacing;
          }
         elseif ( $AxisSettings["Position"] == AXIS_POSITION_RIGHT )
          {
 
           if ( $Floating )
            { $FloatingOffset = $XMargin; $this->pChartObject->drawLine($AxisPos["R"],$this->pChartObject->GraphAreaY1+$AxisSettings["Margin"],$AxisPos["R"],$this->pChartObject->GraphAreaY2-$AxisSettings["Margin"],array("R"=>$AxisR,"G"=>$AxisG,"B"=>$AxisB,"Alpha"=>$AxisAlpha)); }
           else
            { $FloatingOffset = 0; $this->pChartObject->drawLine($AxisPos["R"],$this->pChartObject->GraphAreaY1,$AxisPos["R"],$this->pChartObject->GraphAreaY2,array("R"=>$AxisR,"G"=>$AxisG,"B"=>$AxisB,"Alpha"=>$AxisAlpha)); }
 
           if ( $DrawArrows ) { $this->pChartObject->drawArrow($AxisPos["R"],$this->pChartObject->GraphAreaY1+$AxisSettings["Margin"],$AxisPos["R"],$this->pChartObject->GraphAreaY1-($ArrowSize*2),array("FillR"=>$AxisR,"FillG"=>$AxisG,"FillB"=>$AxisB,"Size"=>$ArrowSize)); }
 
           $Height = ($this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1) - $AxisSettings["Margin"]*2;
           $Step   = $Height / $AxisSettings["Rows"]; $SubTicksSize = $Step /2; $MaxLeft = $AxisPos["R"];
           $LastY  = NULL;
           for($i=0;$i<=$AxisSettings["Rows"];$i++)
            {
             $YPos  = $this->pChartObject->GraphAreaY2 - $AxisSettings["Margin"] - $Step*$i;
             $XPos  = $AxisPos["R"];
             $Value = $this->pChartObject->scaleFormat($AxisSettings["ScaleMin"] + $AxisSettings["RowHeight"]*$i,$AxisSettings["Display"],$AxisSettings["Format"],$AxisSettings["Unit"]);
 
             if ( $i%2 == 1 ) { $BGColor = array("R"=>$BackgroundR1,"G"=>$BackgroundG1,"B"=>$BackgroundB1,"Alpha"=>$BackgroundAlpha1); } else { $BGColor = array("R"=>$BackgroundR2,"G"=>$BackgroundG2,"B"=>$BackgroundB2,"Alpha"=>$BackgroundAlpha2); }
             if ( $LastY != NULL && $CycleBackground  && ( $DrawYLines == ALL || in_array($AxisID,$DrawYLines) )) { $this->pChartObject->drawFilledRectangle($this->pChartObject->GraphAreaX1+$FloatingOffset,$LastY,$this->pChartObject->GraphAreaX2-$FloatingOffset,$YPos,$BGColor); }
 
             if ( ($YPos != $this->pChartObject->GraphAreaY1 && $YPos != $this->pChartObject->GraphAreaY2) && ($DrawYLines == ALL || in_array($AxisID,$DrawYLines)) ) { $this->pChartObject->drawLine($this->pChartObject->GraphAreaX1+$FloatingOffset,$YPos,$this->pChartObject->GraphAreaX2-$FloatingOffset,$YPos,array("R"=>$GridR,"G"=>$GridG,"B"=>$GridB,"Alpha"=>$GridAlpha,"Ticks"=>$GridTicks)); }
 
             if ( $DrawSubTicks && $i != $AxisSettings["Rows"] )
              $this->pChartObject->drawLine($XPos-$InnerSubTickWidth,$YPos-$SubTicksSize,$XPos+$OuterSubTickWidth,$YPos-$SubTicksSize,array("R"=>$SubTickR,"G"=>$SubTickG,"B"=>$SubTickB,"Alpha"=>$SubTickAlpha));
 
             $this->pChartObject->drawLine($XPos-$InnerTickWidth,$YPos,$XPos+$OuterTickWidth,$YPos,array("R"=>$TickR,"G"=>$TickG,"B"=>$TickB,"Alpha"=>$TickAlpha));
             $Bounds  = $this->pChartObject->drawText($XPos+$OuterTickWidth+2,$YPos,$Value,array("Align"=>TEXT_ALIGN_MIDDLELEFT));
             $TxtLeft = $XPos+$OuterTickWidth+2+($Bounds[1]["X"]-$Bounds[0]["X"]);
             $MaxLeft = max($MaxLeft,$TxtLeft);
 
             $LastY = $YPos;
            }
 
           if ( isset($AxisSettings["Name"]) )
            {
             $XPos    = $MaxLeft+6;
             $YPos    = $this->pChartObject->GraphAreaY1+($this->pChartObject->GraphAreaY2-$this->pChartObject->GraphAreaY1)/2;
             $Bounds  = $this->pChartObject->drawText($XPos,$YPos,$AxisSettings["Name"],array("Align"=>TEXT_ALIGN_BOTTOMMIDDLE,"Angle"=>270));
             $MaxLeft = $Bounds[2]["X"];
 
             $this->pDataObject->Data["GraphArea"]["X2"] = $MaxLeft + $this->pChartObject->FontSize;
            }
 
           $AxisPos["R"] = $MaxLeft + $ScaleSpacing;
          }
        }
      }
 
     $this->pDataObject->saveAxisConfig($Data["Axis"]);
    }
 
   /* Draw a scatter plot chart */
   function drawScatterPlotChart($Format=NULL)
    {
     $PlotSize          = isset($Format["PlotSize"]) ? $Format["PlotSize"] : 3;
     $PlotBorder        = isset($Format["PlotBorder"]) ? $Format["PlotBorder"] : FALSE;
     $BorderR           = isset($Format["BorderR"]) ? $Format["BorderR"] : 250;
     $BorderG           = isset($Format["BorderG"]) ? $Format["BorderG"] : 250;
     $BorderB           = isset($Format["BorderB"]) ? $Format["BorderB"] : 250;
     $BorderAlpha       = isset($Format["BorderAlpha"]) ? $Format["BorderAlpha"] : 30;
     $BorderSize        = isset($Format["BorderSize"]) ? $Format["BorderSize"] : 1;
     $Surrounding       = isset($Format["Surrounding"]) ? $Format["Surrounding"] : NULL;
 
     $Data    = $this->pDataObject->getData();
     $Palette = $this->pDataObject->getPalette();
 
     $BorderColor = array("R"=>$BorderR,"G"=>$BorderG,"B"=>$BorderB,"Alpha"=>$BorderAlpha);
 
     foreach($Data["ScatterSeries"] as $Key => $Series)
      {
       $SerieX = $Series["X"]; $SerieValuesX = $Data["Series"][$SerieX]["Data"]; $SerieXAxis = $Data["Series"][$SerieX]["Axis"];
       $SerieY = $Series["Y"]; $SerieValuesY = $Data["Series"][$SerieY]["Data"]; $SerieYAxis = $Data["Series"][$SerieY]["Axis"];
 
       if ( isset($Series["Picture"]) && $Series["Picture"] != "" )
        { $Picture = $Series["Picture"]; list($PicWidth,$PicHeight,$PicType) = $this->pChartObject->getPicInfo($Picture); }
       else
        { $Picture = NULL; }
 
       $PosArrayX = $this->getPosArray($SerieValuesX,$SerieXAxis);
       if ( !is_array($PosArrayX) ) { $Value = $PosArrayX; $PosArrayX = ""; $PosArrayX[0] = $Value; }
       $PosArrayY = $this->getPosArray($SerieValuesY,$SerieYAxis);
       if ( !is_array($PosArrayY) ) { $Value = $PosArrayY; $PosArrayY = ""; $PosArrayY[0] = $Value; }
 
       $Color = array("R"=>$Series["Color"]["R"],"G"=>$Series["Color"]["G"],"B"=>$Series["Color"]["B"],"Alpha"=>$Series["Color"]["Alpha"]);
 
       foreach($PosArrayX as $Key => $Value)
        {
         $X = $Value; $Y = $PosArrayY[$Key];
 
         if ( $X != VOID && $Y != VOID )
          {
           if ( $Picture == NULL )
            {
             if ( $PlotBorder ) { $this->pChartObject->drawFilledCircle($X,$Y,$PlotSize+$BorderSize,$BorderColor); }
             $this->pChartObject->drawFilledCircle($X,$Y,$PlotSize,$Color);
            }
           else
            { $this->pChartObject->drawFromPicture($PicType,$Picture,$X-$PicWidth/2,$Y-$PicHeight/2); }
          }
        }
      }
    }
 
   /* Draw a scatter line chart */
   function drawScatterLineChart($Format=NULL)
    {
     $Data    = $this->pDataObject->getData();
     $Palette = $this->pDataObject->getPalette();
 
     /* Parse all the series to draw */
     foreach($Data["ScatterSeries"] as $Key => $Series)
      {
       $SerieX = $Series["X"]; $SerieValuesX = $Data["Series"][$SerieX]["Data"]; $SerieXAxis = $Data["Series"][$SerieX]["Axis"];
       $SerieY = $Series["Y"]; $SerieValuesY = $Data["Series"][$SerieY]["Data"]; $SerieYAxis = $Data["Series"][$SerieY]["Axis"];
       $Ticks  = $Series["Ticks"];
       $Weight = $Series["Weight"];
 
       $PosArrayX = $this->getPosArray($SerieValuesX,$SerieXAxis);
       if ( !is_array($PosArrayX) ) { $Value = $PosArrayX; $PosArrayX = ""; $PosArrayX[0] = $Value; }
       $PosArrayY = $this->getPosArray($SerieValuesY,$SerieYAxis);
       if ( !is_array($PosArrayY) ) { $Value = $PosArrayY; $PosArrayY = ""; $PosArrayY[0] = $Value; }
 
       $Color = array("R"=>$Series["Color"]["R"],"G"=>$Series["Color"]["G"],"B"=>$Series["Color"]["B"],"Alpha"=>$Series["Color"]["Alpha"]);
       if ( $Ticks != 0 )  { $Color["Ticks"]  = $Ticks; }
       if ( $Weight != 0 ) { $Color["Weight"] = $Weight; }
 
       $LastX = VOID; $LastY = VOID;
       foreach($PosArrayX as $Key => $Value)
        {
         $X = $Value; $Y = $PosArrayY[$Key];
 
         if ( $X != VOID && $Y != VOID && $LastX != VOID && $LastY != VOID)
          $this->pChartObject->drawLine($LastX,$LastY,$X,$Y,$Color);
 
         $LastX = $X; $LastY = $Y;
        }
      }
    }
 
   /* Draw a scatter spline chart */
   function drawScatterSplineChart($Format=NULL)
    {
     $Data    = $this->pDataObject->getData();
     $Palette = $this->pDataObject->getPalette();
 
     foreach($Data["ScatterSeries"] as $Key => $Series)
      {
       $SerieX = $Series["X"]; $SerieValuesX = $Data["Series"][$SerieX]["Data"]; $SerieXAxis = $Data["Series"][$SerieX]["Axis"];
       $SerieY = $Series["Y"]; $SerieValuesY = $Data["Series"][$SerieY]["Data"]; $SerieYAxis = $Data["Series"][$SerieY]["Axis"];
       $Ticks  = $Series["Ticks"];
       $Weight = $Series["Weight"];
 
       $PosArrayX = $this->getPosArray($SerieValuesX,$SerieXAxis);
       if ( !is_array($PosArrayX) ) { $Value = $PosArrayX; $PosArrayX = ""; $PosArrayX[0] = $Value; }
       $PosArrayY = $this->getPosArray($SerieValuesY,$SerieYAxis);
       if ( !is_array($PosArrayY) ) { $Value = $PosArrayY; $PosArrayY = ""; $PosArrayY[0] = $Value; }
 
       $SplineSettings = array("R"=>$Series["Color"]["R"],"G"=>$Series["Color"]["G"],"B"=>$Series["Color"]["B"],"Alpha"=>$Series["Color"]["Alpha"]);
       if ( $Ticks != 0 )  { $SplineSettings["Ticks"]  = $Ticks; }
       if ( $Weight != 0 ) { $SplineSettings["Weight"] = $Weight; }
 
       $LastX = VOID; $LastY = VOID; $WayPoints = ""; $Forces = "";
       foreach($PosArrayX as $Key => $Value)
        {
         $X = $Value; $Y = $PosArrayY[$Key];
 
         $Force = $this->pChartObject->getLength($LastX,$LastY,$X,$Y)/5;
 
         if ( $X != VOID && $Y != VOID )
          { $WayPoints[] = array($X,$Y); $Forces[] = $Force; }
 
         if ( $Y == VOID && $LastY != NULL )
          { $SplineSettings["Forces"] = $Forces; $this->pChartObject->drawSpline($WayPoints,$SplineSettings); $WayPoints = ""; $Forces = "";}
 
         $LastX = $X; $LastY = $Y;
        }
       $SplineSettings["Forces"] = $Forces; 
       $this->pChartObject->drawSpline($WayPoints,$SplineSettings);
      }
    }
 
   /* Return the scaled plot position */
   function getPosArray($Values,$AxisID)
    {
     $Data = $this->pDataObject->getData();
 
     if ( !is_array($Values) ) { $Values = array($Values); }
 
     if ( $Data["Axis"][$AxisID]["Identity"] == AXIS_X )
      {
       $Height      = ($this->pChartObject->GraphAreaX2 - $this->pChartObject->GraphAreaX1) - $Data["Axis"][$AxisID]["Margin"]*2;
       $ScaleHeight = $Data["Axis"][$AxisID]["ScaleMax"] - $Data["Axis"][$AxisID]["ScaleMin"];
       $Step        = $Height / $ScaleHeight;
 
       $Result = "";
       foreach($Values as $Key => $Value)
        {
         if ( $Value == VOID ) 
          $Result[] = VOID;
         else
          $Result[] = $this->pChartObject->GraphAreaX1 + $Data["Axis"][$AxisID]["Margin"] + ($Step * ($Value-$Data["Axis"][$AxisID]["ScaleMin"]));
        }
 
       if ( count($Result) == 1 ) { return($Result[0]); } else { return($Result); }
      }
     else
      {
       $Height      = ($this->pChartObject->GraphAreaY2 - $this->pChartObject->GraphAreaY1) - $Data["Axis"][$AxisID]["Margin"]*2;
       $ScaleHeight = $Data["Axis"][$AxisID]["ScaleMax"] - $Data["Axis"][$AxisID]["ScaleMin"];
       $Step        = $Height / $ScaleHeight;
 
       $Result = "";
       foreach($Values as $Key => $Value)
        {
         if ( $Value == VOID ) 
          $Result[] = VOID;
         else
          $Result[] = $this->pChartObject->GraphAreaY2 - $Data["Axis"][$AxisID]["Margin"] - ($Step * ($Value-$Data["Axis"][$AxisID]["ScaleMin"]));
        }
 
       if ( count($Result) == 1 ) { return($Result[0]); } else { return($Result); }
      }
    }
 
   /* Draw the legend of the active series */
   function drawScatterLegend($X,$Y,$Format="")
    {
     $Family            = isset($Format["Family"]) ? $Format["Family"] : LEGEND_FAMILY_BOX;
     $FontName          = isset($Format["FontName"]) ? $Format["FontName"] : $this->pChartObject->FontName;
     $FontSize          = isset($Format["FontSize"]) ? $Format["FontSize"] : $this->pChartObject->FontSize;
     $FontR             = isset($Format["FontR"]) ? $Format["FontR"] : $this->pChartObject->FontColorR;
     $FontG             = isset($Format["FontG"]) ? $Format["FontG"] : $this->pChartObject->FontColorG;
     $FontB             = isset($Format["FontB"]) ? $Format["FontB"] : $this->pChartObject->FontColorB;
     $BoxWidth          = isset($Format["BoxWidth"]) ? $Format["BoxWidth"] : 5;
     $BoxHeight         = isset($Format["BoxHeight"]) ? $Format["BoxHeight"] : 5;
     $IconAreaWidth     = isset($Format["IconAreaWidth"]) ? $Format["IconAreaWidth"] : $BoxWidth;
     $IconAreaHeight    = isset($Format["IconAreaHeight"]) ? $Format["IconAreaHeight"] : $BoxHeight;
     $XSpacing          = isset($Format["XSpacing"]) ? $Format["XSpacing"] : 5;
     $Margin            = isset($Format["Margin"]) ? $Format["Margin"] : 5;
     $R                 = isset($Format["R"]) ? $Format["R"] : 200;
     $G                 = isset($Format["G"]) ? $Format["G"] : 200;
     $B                 = isset($Format["B"]) ? $Format["B"] : 200;
     $Alpha             = isset($Format["Alpha"]) ? $Format["Alpha"] : 100;
     $BorderR           = isset($Format["BorderR"]) ? $Format["BorderR"] : 255;
     $BorderG           = isset($Format["BorderG"]) ? $Format["BorderG"] : 255;
     $BorderB           = isset($Format["BorderB"]) ? $Format["BorderB"] : 255;
     $Surrounding       = isset($Format["Surrounding"]) ? $Format["Surrounding"] : NULL;
     $Style             = isset($Format["Style"]) ? $Format["Style"] : LEGEND_ROUND;
     $Mode              = isset($Format["Mode"]) ? $Format["Mode"] : LEGEND_VERTICAL;
 
     if ( $Surrounding != NULL ) { $BorderR = $R + $Surrounding; $BorderG = $G + $Surrounding; $BorderB = $B + $Surrounding; }
 
     $Data = $this->pDataObject->getData();
 
     foreach($Data["ScatterSeries"] as $Key => $Series)
      {
       if ( $Series["isDrawable"] == TRUE && isset($Series["Picture"]))
        {
         list($PicWidth,$PicHeight) = $this->pChartObject->getPicInfo($Series["Picture"]);
         if ( $IconAreaWidth < $PicWidth ) { $IconAreaWidth = $PicWidth; }
         if ( $IconAreaHeight < $PicHeight ) { $IconAreaHeight = $PicHeight; }
        }
      }
 
     $YStep = max($this->pChartObject->FontSize,$IconAreaHeight) + 5;
     $XStep = $IconAreaWidth + 5;
     $XStep = $XSpacing;
 
     $Boundaries = ""; $Boundaries["L"] = $X; $Boundaries["T"] = $Y; $Boundaries["R"] = 0; $Boundaries["B"] = 0; $vY = $Y; $vX = $X;
     foreach($Data["ScatterSeries"] as $Key => $Series)
      {
       if ( $Series["isDrawable"] == TRUE )
        {
         if ( $Mode == LEGEND_VERTICAL )
          {
           $BoxArray = $this->pChartObject->getTextBox($vX+$IconAreaWidth+4,$vY+$IconAreaHeight/2,$FontName,$FontSize,0,$Series["Description"]);
 
           if ( $Boundaries["T"] > $BoxArray[2]["Y"]+$IconAreaHeight/2 ) { $Boundaries["T"] = $BoxArray[2]["Y"]+$IconAreaHeight/2; }
           if ( $Boundaries["R"] < $BoxArray[1]["X"]+2 ) { $Boundaries["R"] = $BoxArray[1]["X"]+2; }
           if ( $Boundaries["B"] < $BoxArray[1]["Y"]+2+$IconAreaHeight/2 ) { $Boundaries["B"] = $BoxArray[1]["Y"]+2+$IconAreaHeight/2; }
 
           $Lines = preg_split("/\n/",$Series["Description"]);
           $vY = $vY + max($this->pChartObject->FontSize*count($Lines),$IconAreaHeight) + 5;
          }
         elseif ( $Mode == LEGEND_HORIZONTAL )
          {
           $Lines = preg_split("/\n/",$Series["Description"]);
           $Width = "";
           foreach($Lines as $Key => $Value)
            {
             $BoxArray = $this->pChartObject->getTextBox($vX+$IconAreaWidth+6,$Y+$IconAreaHeight/2+(($this->pChartObject->FontSize+3)*$Key),$FontName,$FontSize,0,$Value);
 
             if ( $Boundaries["T"] > $BoxArray[2]["Y"]+$IconAreaHeight/2 ) { $Boundaries["T"] = $BoxArray[2]["Y"]+$IconAreaHeight/2; }
             if ( $Boundaries["R"] < $BoxArray[1]["X"]+2 ) { $Boundaries["R"] = $BoxArray[1]["X"]+2; }
             if ( $Boundaries["B"] < $BoxArray[1]["Y"]+2+$IconAreaHeight/2 ) { $Boundaries["B"] = $BoxArray[1]["Y"]+2+$IconAreaHeight/2; }
 
             $Width[] = $BoxArray[1]["X"];
            }
 
           $vX=max($Width)+$XStep;
          }
        }
      }
     $vY=$vY-$YStep; $vX=$vX-$XStep;
 
     $TopOffset  = $Y - $Boundaries["T"];
     if ( $Boundaries["B"]-($vY+$IconAreaHeight) < $TopOffset ) { $Boundaries["B"] = $vY+$IconAreaHeight+$TopOffset; }
 
     if ( $Style == LEGEND_ROUND )
      $this->pChartObject->drawRoundedFilledRectangle($Boundaries["L"]-$Margin,$Boundaries["T"]-$Margin,$Boundaries["R"]+$Margin,$Boundaries["B"]+$Margin,$Margin,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"BorderR"=>$BorderR,"BorderG"=>$BorderG,"BorderB"=>$BorderB));
     elseif ( $Style == LEGEND_BOX )
      $this->pChartObject->drawFilledRectangle($Boundaries["L"]-$Margin,$Boundaries["T"]-$Margin,$Boundaries["R"]+$Margin,$Boundaries["B"]+$Margin,array("R"=>$R,"G"=>$G,"B"=>$B,"Alpha"=>$Alpha,"BorderR"=>$BorderR,"BorderG"=>$BorderG,"BorderB"=>$BorderB));
 
     $RestoreShadow = $this->pChartObject->Shadow; $this->Shadow = FALSE;
     foreach($Data["ScatterSeries"] as $Key => $Series)
      {
       if ( $Series["isDrawable"] == TRUE )
        {
         $R = $Series["Color"]["R"]; $G = $Series["Color"]["G"]; $B = $Series["Color"]["B"];
         $Ticks = $Series["Ticks"]; $Weight = $Series["Weight"];
 
         if ( isset($Series["Picture"]) )
          {
           $Picture = $Series["Picture"];
           list($PicWidth,$PicHeight) = $this->pChartObject->getPicInfo($Picture);
           $PicX = $X+$IconAreaWidth/2; $PicY = $Y+$IconAreaHeight/2; 
 
           $this->pChartObject->drawFromPNG($PicX-$PicWidth/2,$PicY-$PicHeight/2,$Picture);
          }
         else
          {
           if ( $Family == LEGEND_FAMILY_BOX )
            {
             if ( $BoxWidth != $IconAreaWidth ) { $XOffset = floor(($IconAreaWidth-$BoxWidth)/2); } else { $XOffset = 0; }
             if ( $BoxHeight != $IconAreaHeight ) { $YOffset = floor(($IconAreaHeight-$BoxHeight)/2); } else { $YOffset = 0; }
 
             $this->pChartObject->drawFilledRectangle($X+1+$XOffset,$Y+1+$YOffset,$X+$BoxWidth+$XOffset+1,$Y+$BoxHeight+1+$YOffset,array("R"=>0,"G"=>0,"B"=>0,"Alpha"=>20));
             $this->pChartObject->drawFilledRectangle($X+$XOffset,$Y+$YOffset,$X+$BoxWidth+$XOffset,$Y+$BoxHeight+$YOffset,array("R"=>$R,"G"=>$G,"B"=>$B,"Surrounding"=>20));
            }
           elseif ( $Family == LEGEND_FAMILY_CIRCLE )
            {
             $this->pChartObject->drawFilledCircle($X+1+$IconAreaWidth/2,$Y+1+$IconAreaHeight/2,min($IconAreaHeight/2,$IconAreaWidth/2),array("R"=>0,"G"=>0,"B"=>0,"Alpha"=>20));
             $this->pChartObject->drawFilledCircle($X+$IconAreaWidth/2,$Y+$IconAreaHeight/2,min($IconAreaHeight/2,$IconAreaWidth/2),array("R"=>$R,"G"=>$G,"B"=>$B,"Surrounding"=>20));
            }
           elseif ( $Family == LEGEND_FAMILY_LINE )
            {
             $this->pChartObject->drawLine($X+1,$Y+1+$IconAreaHeight/2,$X+1+$IconAreaWidth,$Y+1+$IconAreaHeight/2,array("R"=>0,"G"=>0,"B"=>0,"Alpha"=>20,"Ticks"=>$Ticks,"Weight"=>$Weight));
             $this->pChartObject->drawLine($X,$Y+$IconAreaHeight/2,$X+$IconAreaWidth,$Y+$IconAreaHeight/2,array("R"=>$R,"G"=>$G,"B"=>$B,"Ticks"=>$Ticks,"Weight"=>$Weight));
            }
          }
 
         if ( $Mode == LEGEND_VERTICAL )
          {
           $Lines = preg_split("/\n/",$Series["Description"]);
           foreach($Lines as $Key => $Value)
            $this->pChartObject->drawText($X+$IconAreaWidth+4,$Y+$IconAreaHeight/2+(($this->pChartObject->FontSize+3)*$Key),$Value,array("R"=>$FontR,"G"=>$FontG,"B"=>$FontB,"Align"=>TEXT_ALIGN_MIDDLELEFT));
 
           $Y=$Y+max($this->pChartObject->FontSize*count($Lines),$IconAreaHeight) + 5;
          }
         elseif ( $Mode == LEGEND_HORIZONTAL )
          {
           $Lines = preg_split("/\n/",$Series["Description"]);
           $Width = "";
           foreach($Lines as $Key => $Value)
            {
             $BoxArray = $this->pChartObject->drawText($X+$IconAreaWidth+4,$Y+$IconAreaHeight/2+(($this->pChartObject->FontSize+3)*$Key),$Value,array("R"=>$FontR,"G"=>$FontG,"B"=>$FontB,"Align"=>TEXT_ALIGN_MIDDLELEFT));
             $Width[] = $BoxArray[1]["X"];
            }
           $X=max($Width)+2+$XStep;
          }
        }
      }
 
     $this->Shadow = $RestoreShadow;
    }
 
   /* Get the legend box size */
   function getScatterLegendSize($Format="")
    {
     $FontName  = isset($Format["FontName"]) ? $Format["FontName"] : $this->pChartObject->FontName;
     $FontSize  = isset($Format["FontSize"]) ? $Format["FontSize"] : $this->pChartObject->FontSize;
     $BoxSize   = isset($Format["BoxSize"]) ? $Format["BoxSize"] : 5;
     $Margin    = isset($Format["Margin"]) ? $Format["Margin"] : 5;
     $Style     = isset($Format["Style"]) ? $Format["Style"] : LEGEND_ROUND;
     $Mode      = isset($Format["Mode"]) ? $Format["Mode"] : LEGEND_VERTICAL;
 
     $YStep = max($this->pChartObject->FontSize,$BoxSize) + 5;
     $XStep = $BoxSize + 5;
 
     $X=100; $Y=100;
 
     $Data = $this->pDataObject->getData();
 
     foreach($Data["ScatterSeries"] as $Key => $Series)
      {
       if ( $Series["isDrawable"] == TRUE && isset($Series["Picture"]))
        {
         list($PicWidth,$PicHeight) = $this->pChartObject->getPicInfo($Series["Picture"]);
         if ( $IconAreaWidth < $PicWidth ) { $IconAreaWidth = $PicWidth; }
         if ( $IconAreaHeight < $PicHeight ) { $IconAreaHeight = $PicHeight; }
        }
      }
 
     $YStep = max($this->pChartObject->FontSize,$IconAreaHeight) + 5;
     $XStep = $IconAreaWidth + 5;
     $XStep = $XSpacing;
 
     $Boundaries = ""; $Boundaries["L"] = $X; $Boundaries["T"] = $Y; $Boundaries["R"] = 0; $Boundaries["B"] = 0; $vY = $Y; $vX = $X;
     foreach($Data["ScatterSeries"] as $Key => $Series)
      {
       if ( $Series["isDrawable"] == TRUE )
        {
         if ( $Mode == LEGEND_VERTICAL )
          {
           $BoxArray = $this->pChartObject->getTextBox($vX+$IconAreaWidth+4,$vY+$IconAreaHeight/2,$FontName,$FontSize,0,$Series["Description"]);
 
           if ( $Boundaries["T"] > $BoxArray[2]["Y"]+$IconAreaHeight/2 ) { $Boundaries["T"] = $BoxArray[2]["Y"]+$IconAreaHeight/2; }
           if ( $Boundaries["R"] < $BoxArray[1]["X"]+2 ) { $Boundaries["R"] = $BoxArray[1]["X"]+2; }
           if ( $Boundaries["B"] < $BoxArray[1]["Y"]+2+$IconAreaHeight/2 ) { $Boundaries["B"] = $BoxArray[1]["Y"]+2+$IconAreaHeight/2; }
 
           $Lines = preg_split("/\n/",$Series["Description"]);
           $vY = $vY + max($this->pChartObject->FontSize*count($Lines),$IconAreaHeight) + 5;
          }
         elseif ( $Mode == LEGEND_HORIZONTAL )
          {
           $Lines = preg_split("/\n/",$Series["Description"]);
           $Width = "";
           foreach($Lines as $Key => $Value)
            {
             $BoxArray = $this->pChartObject->getTextBox($vX+$IconAreaWidth+6,$Y+$IconAreaHeight/2+(($this->pChartObject->FontSize+3)*$Key),$FontName,$FontSize,0,$Value);
 
             if ( $Boundaries["T"] > $BoxArray[2]["Y"]+$IconAreaHeight/2 ) { $Boundaries["T"] = $BoxArray[2]["Y"]+$IconAreaHeight/2; }
             if ( $Boundaries["R"] < $BoxArray[1]["X"]+2 ) { $Boundaries["R"] = $BoxArray[1]["X"]+2; }
             if ( $Boundaries["B"] < $BoxArray[1]["Y"]+2+$IconAreaHeight/2 ) { $Boundaries["B"] = $BoxArray[1]["Y"]+2+$IconAreaHeight/2; }
 
             $Width[] = $BoxArray[1]["X"];
            }
 
           $vX=max($Width)+$XStep;
          }
        }
      }
     $vY=$vY-$YStep; $vX=$vX-$XStep;
 
     $TopOffset  = $Y - $Boundaries["T"];
     if ( $Boundaries["B"]-($vY+$BoxSize) < $TopOffset ) { $Boundaries["B"] = $vY+$BoxSize+$TopOffset; }
 
     $Width  = ($Boundaries["R"]+$Margin) - ($Boundaries["L"]-$Margin);
     $Height = ($Boundaries["B"]+$Margin) - ($Boundaries["T"]-$Margin);
 
     return(array("Width"=>$Width,"Height"=>$Height));
    }
 
   /* Draw the line of best fit */
   function drawScatterBestFit($Format="")
    {
     $Ticks     = isset($Format["Ticks"]) ? $Format["Ticks"] : 0;
 
     $Data    = $this->pDataObject->getData();
 
     foreach($Data["ScatterSeries"] as $Key => $Series)
      {
       $SerieX = $Series["X"]; $SerieValuesX = $Data["Series"][$SerieX]["Data"]; $SerieXAxis = $Data["Series"][$SerieX]["Axis"];
       $SerieY = $Series["Y"]; $SerieValuesY = $Data["Series"][$SerieY]["Data"]; $SerieYAxis = $Data["Series"][$SerieY]["Axis"];
 
       $Color = array("R"=>$Series["Color"]["R"],"G"=>$Series["Color"]["G"],"B"=>$Series["Color"]["B"],"Alpha"=>$Series["Color"]["Alpha"]);
       $Color["Ticks"] = $Ticks;
 
       $PosArrayX = $Data["Series"][$Series["X"]]["Data"];
       $PosArrayY = $Data["Series"][$Series["Y"]]["Data"];
 
       $Sxy = 0; $Sx = 0; $Sy = 0; $Sxx = 0;
       foreach($PosArrayX as $Key => $Value)
        {
         $X = $Value; $Y = $PosArrayY[$Key];
 
         $Sxy = $Sxy + $X*$Y;
         $Sx  = $Sx + $X;
         $Sy  = $Sy + $Y;
         $Sxx = $Sxx + $X*$X;
        }
 
       $n = count($PosArrayX);
       $M = (($n*$Sxy)-($Sx*$Sy)) / (($n*$Sxx)-($Sx*$Sx));
       $B = (($Sy)-($M*$Sx))/($n);
 
       $X1 = $this->getPosArray($Data["Axis"][$SerieXAxis]["ScaleMin"],$SerieXAxis);
       $Y1 = $this->getPosArray($M * $Data["Axis"][$SerieXAxis]["ScaleMin"] + $B,$SerieYAxis);
       $X2 = $this->getPosArray($Data["Axis"][$SerieXAxis]["ScaleMax"],$SerieXAxis);
       $Y2 = $this->getPosArray($M * $Data["Axis"][$SerieXAxis]["ScaleMax"] + $B,$SerieYAxis);
 
       if ( $Y1 < $this->pChartObject->GraphAreaY1 ) { $X1 = $X1 + ($this->pChartObject->GraphAreaY1-$Y1); $Y1 = $this->pChartObject->GraphAreaY1; }
       if ( $Y1 > $this->pChartObject->GraphAreaY2 ) { $X1 = $X1 + ($Y1-$this->pChartObject->GraphAreaY2); $Y1 = $this->pChartObject->GraphAreaY2; }
       if ( $Y2 < $this->pChartObject->GraphAreaY1 ) { $X2 = $X2 - ($this->pChartObject->GraphAreaY1-$Y2); $Y2 = $this->pChartObject->GraphAreaY1; }
       if ( $Y2 > $this->pChartObject->GraphAreaY2 ) { $X2 = $X2 - ($Y2-$this->pChartObject->GraphAreaY2); $Y2 = $this->pChartObject->GraphAreaY2; }
 
       $this->pChartObject->drawLine($X1,$Y1,$X2,$Y2,$Color);
      }
    }
  }
?>