add amendments metric
[contractdashboard.git] / lib / jpgraph / jpgraph_polar.php
blob:a/lib/jpgraph/jpgraph_polar.php -> blob:b/lib/jpgraph/jpgraph_polar.php
<?php <?php
/*======================================================================= /*=======================================================================
// File: JPGRAPH_POLAR.PHP // File: JPGRAPH_POLAR.PHP
// Description: Polar plot extension for JpGraph // Description: Polar plot extension for JpGraph
// Created: 2003-02-02 // Created: 2003-02-02
// Ver: $Id: jpgraph_polar.php 1796 2009-09-07 09:37:19Z ljp $ // Ver: $Id: jpgraph_polar.php 1796 2009-09-07 09:37:19Z ljp $
// //
// Copyright (c) Aditus Consulting. All rights reserved. // Copyright (c) Aditus Consulting. All rights reserved.
//======================================================================== //========================================================================
*/ */
   
require_once ('jpgraph_plotmark.inc.php'); require_once ('jpgraph_plotmark.inc.php');
require_once "jpgraph_log.php"; require_once "jpgraph_log.php";
   
   
define('POLAR_360',1); define('POLAR_360',1);
define('POLAR_180',2); define('POLAR_180',2);
   
// //
// Note. Don't attempt to make sense of this code. // Note. Don't attempt to make sense of this code.
// In order not to have to be able to inherit the scaling code // In order not to have to be able to inherit the scaling code
// from the main graph package we have had to make some "tricks" since // from the main graph package we have had to make some "tricks" since
// the original scaling and axis was not designed to do what is // the original scaling and axis was not designed to do what is
// required here. // required here.
// There were two option. 1: Re-implement everything and get a clean design // There were two option. 1: Re-implement everything and get a clean design
// and 2: do some "small" trickery and be able to inherit most of // and 2: do some "small" trickery and be able to inherit most of
// the functionlity from the main graph package. // the functionlity from the main graph package.
// We choose 2: here in order to save some time. // We choose 2: here in order to save some time.
// //
   
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// class PolarPlot // class PolarPlot
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
class PolarPlot { class PolarPlot {
public $line_style='solid',$mark; public $line_style='solid',$mark;
public $legendcsimtarget=''; public $legendcsimtarget='';
public $legendcsimalt=''; public $legendcsimalt='';
public $legend=""; public $legend="";
public $csimtargets=array(); // Array of targets for CSIM public $csimtargets=array(); // Array of targets for CSIM
public $csimareas=""; // Resultant CSIM area tags public $csimareas=""; // Resultant CSIM area tags
public $csimalts=null; // ALT:s for corresponding target public $csimalts=null; // ALT:s for corresponding target
public $scale=null; public $scale=null;
private $numpoints=0; private $numpoints=0;
private $iColor='navy',$iFillColor=''; private $iColor='navy',$iFillColor='';
private $iLineWeight=1; private $iLineWeight=1;
private $coord=null; private $coord=null;
   
function __construct($aData) { function __construct($aData) {
$n = count($aData); $n = count($aData);
if( $n & 1 ) { if( $n & 1 ) {
JpGraphError::RaiseL(17001); JpGraphError::RaiseL(17001);
//('Polar plots must have an even number of data point. Each data point is a tuple (angle,radius).'); //('Polar plots must have an even number of data point. Each data point is a tuple (angle,radius).');
} }
$this->numpoints = $n/2; $this->numpoints = $n/2;
$this->coord = $aData; $this->coord = $aData;
$this->mark = new PlotMark(); $this->mark = new PlotMark();
} }
   
function SetWeight($aWeight) { function SetWeight($aWeight) {
$this->iLineWeight = $aWeight; $this->iLineWeight = $aWeight;
} }
   
function SetColor($aColor){ function SetColor($aColor){
$this->iColor = $aColor; $this->iColor = $aColor;
} }
   
function SetFillColor($aColor){ function SetFillColor($aColor){
$this->iFillColor = $aColor; $this->iFillColor = $aColor;
} }
   
function Max() { function Max() {
$m = $this->coord[1]; $m = $this->coord[1];
$i=1; $i=1;
while( $i < $this->numpoints ) { while( $i < $this->numpoints ) {
$m = max($m,$this->coord[2*$i+1]); $m = max($m,$this->coord[2*$i+1]);
++$i; ++$i;
} }
return $m; return $m;
} }
// Set href targets for CSIM // Set href targets for CSIM
function SetCSIMTargets($aTargets,$aAlts=null) { function SetCSIMTargets($aTargets,$aAlts=null) {
$this->csimtargets=$aTargets; $this->csimtargets=$aTargets;
$this->csimalts=$aAlts; $this->csimalts=$aAlts;
} }
   
// Get all created areas // Get all created areas
function GetCSIMareas() { function GetCSIMareas() {
return $this->csimareas; return $this->csimareas;
} }
   
function SetLegend($aLegend,$aCSIM="",$aCSIMAlt="") { function SetLegend($aLegend,$aCSIM="",$aCSIMAlt="") {
$this->legend = $aLegend; $this->legend = $aLegend;
$this->legendcsimtarget = $aCSIM; $this->legendcsimtarget = $aCSIM;
$this->legendcsimalt = $aCSIMAlt; $this->legendcsimalt = $aCSIMAlt;
} }
   
// Private methods // Private methods
   
function Legend($aGraph) { function Legend($aGraph) {
$color = $this->iColor ; $color = $this->iColor ;
if( $this->legend != "" ) { if( $this->legend != "" ) {
if( $this->iFillColor!='' ) { if( $this->iFillColor!='' ) {
$color = $this->iFillColor; $color = $this->iFillColor;
$aGraph->legend->Add($this->legend,$color,$this->mark,0, $aGraph->legend->Add($this->legend,$color,$this->mark,0,
$this->legendcsimtarget,$this->legendcsimalt); $this->legendcsimtarget,$this->legendcsimalt);
} }
else { else {
$aGraph->legend->Add($this->legend,$color,$this->mark,$this->line_style, $aGraph->legend->Add($this->legend,$color,$this->mark,$this->line_style,
$this->legendcsimtarget,$this->legendcsimalt); $this->legendcsimtarget,$this->legendcsimalt);
} }
} }
} }
   
function Stroke($img,$scale) { function Stroke($img,$scale) {
   
$i=0; $i=0;
$p=array(); $p=array();
$this->csimareas=''; $this->csimareas='';
while($i < $this->numpoints) { while($i < $this->numpoints) {
list($x1,$y1) = $scale->PTranslate($this->coord[2*$i],$this->coord[2*$i+1]); list($x1,$y1) = $scale->PTranslate($this->coord[2*$i],$this->coord[2*$i+1]);
$p[2*$i] = $x1; $p[2*$i] = $x1;
$p[2*$i+1] = $y1; $p[2*$i+1] = $y1;
   
if( isset($this->csimtargets[$i]) ) { if( isset($this->csimtargets[$i]) ) {
$this->mark->SetCSIMTarget($this->csimtargets[$i]); $this->mark->SetCSIMTarget($this->csimtargets[$i]);
$this->mark->SetCSIMAlt($this->csimalts[$i]); $this->mark->SetCSIMAlt($this->csimalts[$i]);
$this->mark->SetCSIMAltVal($this->coord[2*$i], $this->coord[2*$i+1]); $this->mark->SetCSIMAltVal($this->coord[2*$i], $this->coord[2*$i+1]);
$this->mark->Stroke($img,$x1,$y1); $this->mark->Stroke($img,$x1,$y1);
$this->csimareas .= $this->mark->GetCSIMAreas(); $this->csimareas .= $this->mark->GetCSIMAreas();
} }
else { else {
$this->mark->Stroke($img,$x1,$y1); $this->mark->Stroke($img,$x1,$y1);
} }
   
++$i; ++$i;
} }
   
if( $this->iFillColor != '' ) { if( $this->iFillColor != '' ) {
$img->SetColor($this->iFillColor); $img->SetColor($this->iFillColor);
$img->FilledPolygon($p); $img->FilledPolygon($p);
} }
$img->SetLineWeight($this->iLineWeight); $img->SetLineWeight($this->iLineWeight);
$img->SetColor($this->iColor); $img->SetColor($this->iColor);
$img->Polygon($p,$this->iFillColor!=''); $img->Polygon($p,$this->iFillColor!='');
} }
} }
   
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// class PolarAxis // class PolarAxis
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
class PolarAxis extends Axis { class PolarAxis extends Axis {
private $angle_step=15,$angle_color='lightgray',$angle_label_color='black'; private $angle_step=15,$angle_color='lightgray',$angle_label_color='black';
private $angle_fontfam=FF_FONT1,$angle_fontstyle=FS_NORMAL,$angle_fontsize=10; private $angle_fontfam=FF_FONT1,$angle_fontstyle=FS_NORMAL,$angle_fontsize=10;
private $angle_fontcolor = 'navy'; private $angle_fontcolor = 'navy';
private $gridminor_color='lightgray',$gridmajor_color='lightgray'; private $gridminor_color='lightgray',$gridmajor_color='lightgray';
private $show_minor_grid = false, $show_major_grid = true ; private $show_minor_grid = false, $show_major_grid = true ;
private $show_angle_mark=true, $show_angle_grid=true, $show_angle_label=true; private $show_angle_mark=true, $show_angle_grid=true, $show_angle_label=true;
private $angle_tick_len=3, $angle_tick_len2=3, $angle_tick_color='black'; private $angle_tick_len=3, $angle_tick_len2=3, $angle_tick_color='black';
private $show_angle_tick=true; private $show_angle_tick=true;
private $radius_tick_color='black'; private $radius_tick_color='black';
   
function __construct($img,$aScale) { function __construct($img,$aScale) {
parent::__construct($img,$aScale); parent::__construct($img,$aScale);
} }
   
function ShowAngleDegreeMark($aFlg=true) { function ShowAngleDegreeMark($aFlg=true) {
$this->show_angle_mark = $aFlg; $this->show_angle_mark = $aFlg;
} }
   
function SetAngleStep($aStep) { function SetAngleStep($aStep) {
$this->angle_step=$aStep; $this->angle_step=$aStep;
} }
   
function HideTicks($aFlg=true,$aAngleFlg=true) { function HideTicks($aFlg=true,$aAngleFlg=true) {
parent::HideTicks($aFlg,$aFlg); parent::HideTicks($aFlg,$aFlg);
$this->show_angle_tick = !$aAngleFlg; $this->show_angle_tick = !$aAngleFlg;
} }
   
function ShowAngleLabel($aFlg=true) { function ShowAngleLabel($aFlg=true) {
$this->show_angle_label = $aFlg; $this->show_angle_label = $aFlg;
} }
   
function ShowGrid($aMajor=true,$aMinor=false,$aAngle=true) { function ShowGrid($aMajor=true,$aMinor=false,$aAngle=true) {
$this->show_minor_grid = $aMinor; $this->show_minor_grid = $aMinor;
$this->show_major_grid = $aMajor; $this->show_major_grid = $aMajor;
$this->show_angle_grid = $aAngle ; $this->show_angle_grid = $aAngle ;
} }
   
function SetAngleFont($aFontFam,$aFontStyle=FS_NORMAL,$aFontSize=10) { function SetAngleFont($aFontFam,$aFontStyle=FS_NORMAL,$aFontSize=10) {
$this->angle_fontfam = $aFontFam; $this->angle_fontfam = $aFontFam;
$this->angle_fontstyle = $aFontStyle; $this->angle_fontstyle = $aFontStyle;
$this->angle_fontsize = $aFontSize; $this->angle_fontsize = $aFontSize;
} }
   
function SetColor($aColor,$aRadColor='',$aAngleColor='') { function SetColor($aColor,$aRadColor='',$aAngleColor='') {
if( $aAngleColor == '' ) if( $aAngleColor == '' )
$aAngleColor=$aColor; $aAngleColor=$aColor;
parent::SetColor($aColor,$aRadColor); parent::SetColor($aColor,$aRadColor);
$this->angle_fontcolor = $aAngleColor; $this->angle_fontcolor = $aAngleColor;
} }
   
function SetGridColor($aMajorColor,$aMinorColor='',$aAngleColor='') { function SetGridColor($aMajorColor,$aMinorColor='',$aAngleColor='') {
if( $aMinorColor == '' ) if( $aMinorColor == '' )
$aMinorColor = $aMajorColor; $aMinorColor = $aMajorColor;
if( $aAngleColor == '' ) if( $aAngleColor == '' )
$aAngleColor = $aMajorColor; $aAngleColor = $aMajorColor;
   
$this->gridminor_color = $aMinorColor; $this->gridminor_color = $aMinorColor;
$this->gridmajor_color = $aMajorColor; $this->gridmajor_color = $aMajorColor;
$this->angle_color = $aAngleColor; $this->angle_color = $aAngleColor;
} }
   
function SetTickColors($aRadColor,$aAngleColor='') { function SetTickColors($aRadColor,$aAngleColor='') {
$this->radius_tick_color = $aRadColor; $this->radius_tick_color = $aRadColor;
$this->angle_tick_color = $aAngleColor; $this->angle_tick_color = $aAngleColor;
} }
   
// Private methods // Private methods
function StrokeGrid($pos) { function StrokeGrid($pos) {
$x = round($this->img->left_margin + $this->img->plotwidth/2); $x = round($this->img->left_margin + $this->img->plotwidth/2);
$this->scale->ticks->Stroke($this->img,$this->scale,$pos); $this->scale->ticks->Stroke($this->img,$this->scale,$pos);
   
// Stroke the minor arcs // Stroke the minor arcs
$pmin = array(); $pmin = array();
$p = $this->scale->ticks->ticks_pos; $p = $this->scale->ticks->ticks_pos;
$n = count($p); $n = count($p);
$i = 0; $i = 0;
$this->img->SetColor($this->gridminor_color); $this->img->SetColor($this->gridminor_color);
while( $i < $n ) { while( $i < $n ) {
$r = $p[$i]-$x+1; $r = $p[$i]-$x+1;
$pmin[]=$r; $pmin[]=$r;
if( $this->show_minor_grid ) { if( $this->show_minor_grid ) {
$this->img->Circle($x,$pos,$r); $this->img->Circle($x,$pos,$r);
} }
$i++; $i++;
} }
   
$limit = max($this->img->plotwidth,$this->img->plotheight)*1.4 ; $limit = max($this->img->plotwidth,$this->img->plotheight)*1.4 ;
while( $r < $limit ) { while( $r < $limit ) {
$off = $r; $off = $r;
$i=1; $i=1;
$r = $off + round($p[$i]-$x+1); $r = $off + round($p[$i]-$x+1);
while( $r < $limit && $i < $n ) { while( $r < $limit && $i < $n ) {
$r = $off+$p[$i]-$x; $r = $off+$p[$i]-$x;
$pmin[]=$r; $pmin[]=$r;
if( $this->show_minor_grid ) { if( $this->show_minor_grid ) {
$this->img->Circle($x,$pos,$r); $this->img->Circle($x,$pos,$r);
} }
$i++; $i++;
} }
} }
   
// Stroke the major arcs // Stroke the major arcs
if( $this->show_major_grid ) { if( $this->show_major_grid ) {
// First determine how many minor step on // First determine how many minor step on
// every major step. We have recorded the minor radius // every major step. We have recorded the minor radius
// in pmin and use these values. This is done in order // in pmin and use these values. This is done in order
// to avoid rounding errors if we were to recalculate the // to avoid rounding errors if we were to recalculate the
// different major radius. // different major radius.
$pmaj = $this->scale->ticks->maj_ticks_pos; $pmaj = $this->scale->ticks->maj_ticks_pos;
$p = $this->scale->ticks->ticks_pos; $p = $this->scale->ticks->ticks_pos;
if( $this->scale->name == 'lin' ) { if( $this->scale->name == 'lin' ) {
$step=round(($pmaj[1] - $pmaj[0])/($p[1] - $p[0])); $step=round(($pmaj[1] - $pmaj[0])/($p[1] - $p[0]));
} }
else { else {
$step=9; $step=9;
} }
$n = round(count($pmin)/$step); $n = round(count($pmin)/$step);
$i = 0; $i = 0;
$this->img->SetColor($this->gridmajor_color); $this->img->SetColor($this->gridmajor_color);
$limit = max($this->img->plotwidth,$this->img->plotheight)*1.4 ; $limit = max($this->img->plotwidth,$this->img->plotheight)*1.4 ;
$off = $r; $off = $r;
$i=0; $i=0;
$r = $pmin[$i*$step]; $r = $pmin[$i*$step];
while( $r < $limit && $i < $n ) { while( $r < $limit && $i < $n ) {
$r = $pmin[$i*$step]; $r = $pmin[$i*$step];
$this->img->Circle($x,$pos,$r); $this->img->Circle($x,$pos,$r);
$i++; $i++;
} }
} }
   
// Draw angles // Draw angles
if( $this->show_angle_grid ) { if( $this->show_angle_grid ) {
$this->img->SetColor($this->angle_color); $this->img->SetColor($this->angle_color);
$d = max($this->img->plotheight,$this->img->plotwidth)*1.4 ; $d = max($this->img->plotheight,$this->img->plotwidth)*1.4 ;
$a = 0; $a = 0;
$p = $this->scale->ticks->ticks_pos; $p = $this->scale->ticks->ticks_pos;
$start_radius = $p[1]-$x; $start_radius = $p[1]-$x;
while( $a < 360 ) { while( $a < 360 ) {
if( $a == 90 || $a == 270 ) { if( $a == 90 || $a == 270 ) {
// Make sure there are no rounding problem with // Make sure there are no rounding problem with
// exactly vertical lines // exactly vertical lines
$this->img->Line($x+$start_radius*cos($a/180*M_PI)+1, $this->img->Line($x+$start_radius*cos($a/180*M_PI)+1,
$pos-$start_radius*sin($a/180*M_PI), $pos-$start_radius*sin($a/180*M_PI),
$x+$start_radius*cos($a/180*M_PI)+1, $x+$start_radius*cos($a/180*M_PI)+1,
$pos-$d*sin($a/180*M_PI)); $pos-$d*sin($a/180*M_PI));
   
} }
else { else {
$this->img->Line($x+$start_radius*cos($a/180*M_PI)+1, $this->img->Line($x+$start_radius*cos($a/180*M_PI)+1,
$pos-$start_radius*sin($a/180*M_PI), $pos-$start_radius*sin($a/180*M_PI),
$x+$d*cos($a/180*M_PI), $x+$d*cos($a/180*M_PI),
$pos-$d*sin($a/180*M_PI)); $pos-$d*sin($a/180*M_PI));
} }
$a += $this->angle_step; $a += $this->angle_step;
} }
} }
} }
   
function StrokeAngleLabels($pos,$type) { function StrokeAngleLabels($pos,$type) {
   
if( !$this->show_angle_label ) if( !$this->show_angle_label )
return; return;
   
$x0 = round($this->img->left_margin+$this->img->plotwidth/2)+1; $x0 = round($this->img->left_margin+$this->img->plotwidth/2)+1;
   
$d = max($this->img->plotwidth,$this->img->plotheight)*1.42; $d = max($this->img->plotwidth,$this->img->plotheight)*1.42;
$a = $this->angle_step; $a = $this->angle_step;
$t = new Text(); $t = new Text();
$t->SetColor($this->angle_fontcolor); $t->SetColor($this->angle_fontcolor);
$t->SetFont($this->angle_fontfam,$this->angle_fontstyle,$this->angle_fontsize); $t->SetFont($this->angle_fontfam,$this->angle_fontstyle,$this->angle_fontsize);
$xright = $this->img->width - $this->img->right_margin; $xright = $this->img->width - $this->img->right_margin;
$ytop = $this->img->top_margin; $ytop = $this->img->top_margin;
$xleft = $this->img->left_margin; $xleft = $this->img->left_margin;
$ybottom = $this->img->height - $this->img->bottom_margin; $ybottom = $this->img->height - $this->img->bottom_margin;
$ha = 'left'; $ha = 'left';
$va = 'center'; $va = 'center';
$w = $this->img->plotwidth/2; $w = $this->img->plotwidth/2;
$h = $this->img->plotheight/2; $h = $this->img->plotheight/2;
$xt = $x0; $yt = $pos; $xt = $x0; $yt = $pos;
$margin=5; $margin=5;
   
$tl = $this->angle_tick_len ; // Outer len $tl = $this->angle_tick_len ; // Outer len
$tl2 = $this->angle_tick_len2 ; // Interior len $tl2 = $this->angle_tick_len2 ; // Interior len
   
$this->img->SetColor($this->angle_tick_color); $this->img->SetColor($this->angle_tick_color);
$rot90 = $this->img->a == 90 ; $rot90 = $this->img->a == 90 ;
   
if( $type == POLAR_360 ) { if( $type == POLAR_360 ) {
   
// Corner angles of the four corners // Corner angles of the four corners
$ca1 = atan($h/$w)/M_PI*180; $ca1 = atan($h/$w)/M_PI*180;
$ca2 = 180-$ca1; $ca2 = 180-$ca1;
$ca3 = $ca1+180; $ca3 = $ca1+180;
$ca4 = 360-$ca1; $ca4 = 360-$ca1;
$end = 360; $end = 360;
   
while( $a < $end ) { while( $a < $end ) {
$ca = cos($a/180*M_PI); $ca = cos($a/180*M_PI);
$sa = sin($a/180*M_PI); $sa = sin($a/180*M_PI);
$x = $d*$ca; $x = $d*$ca;
$y = $d*$sa; $y = $d*$sa;
$xt=1000;$yt=1000; $xt=1000;$yt=1000;