<?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; |
|