order to get the limits for the loops // that creates the position for the labels. This code is generic and can be // used for any ranges of the data. // $n = count($aData); $startmonth = date('n',$aData[0]); $startday = date('j',$aData[0]); $startyear = date('Y',$aData[0]); $endmonth = date('n',$aData[$n-1]); $endyear = date('Y',$aData[$n-1]); $endday = date('j',$aData[$n-1]); // // Now create the positions for all the ticks. In this example we // put a tick at the start of every month and also on the very // first and last X-position. // $tickPositions = array(); $minTickPositions = array(); $i=0;$j=0; // put a label at the very left data pos if( $aEndPoints ) { $tickPositions[$i++] = $aData[0]; } $m = $startmonth; $y = $startyear; // Skip the first month label if it is before the startdate if( $startday == 1 ) { $tickPositions[$i++] = mktime(0,0,0,$m,1,$y); } if( $startday < 15 ) { $minTickPositions[$j++] = mktime(0,0,0,$m,15,$y); } ++$m; // Loop through all the years included in the scale for($y=$startyear; $y <= $endyear; ++$y ) { // Loop through all the months. There are three cases to consider: // 1. We are in the first year and must start with the startmonth // 2. We are in the end year and we must stop at last month of the scale // 3. A year in between where we run through all the 12 months $stopmonth = $y == $endyear ? $endmonth : 12; while( $m <= $stopmonth ) { switch( $aType ) { case 1: // Set minor tick at the middle of the month if( $m <= $stopmonth ) { if( !($y==$endyear && $m==$stopmonth && $endday < 15) ) $minTickPositions[$j++] = mktime(0,0,0,$m,15,$y); } // Major at month // Get timestamp of first hour of first day in each month $tickPositions[$i++] = mktime(0,0,0,$m,1,$y); break; } ++$m; } $m=1; } // For the case where all dates are within the same month // we want to make sure we have at least two ticks on the scale // since the scale want work properly otherwise if($startmonth == $endmonth && $startyear == $endyear && $aType==1 ) { $tickPositions[$i++] = mktime(0 ,0 ,0, $startmonth + 1, 1, $startyear); } // put a label at the very right data pos if( $aEndPoints ) { $tickPositions[$i] = $aData[$n-1]; } return array($tickPositions,$minTickPositions); } } //============================================================================= // Class ReadFileData //============================================================================= Class ReadFileData { //---------------------------------------------------------------------------- // Desciption: // Read numeric data from a file. // Each value should be separated by either a new line or by a specified // separator character (default is ','). // Before returning the data each value is converted to a proper float // value. The routine is robust in the sense that non numeric data in the // file will be discarded. // // Returns: // The number of data values read on success, FALSE on failure //---------------------------------------------------------------------------- function FromCSV($aFile,&$aData,$aSepChar=',',$aMaxLineLength=1024) { $rh = fopen($aFile,'r'); if( $rh === false ) return false; $tmp = array(); $lineofdata = fgetcsv($rh, 1000, ','); while ( $lineofdata !== FALSE) { $tmp = array_merge($tmp,$lineofdata); $lineofdata = fgetcsv($rh, $aMaxLineLength, $aSepChar); } fclose($rh); // Now make sure that all data is numeric. By default // all data is read as strings $n = count($tmp); $aData = array(); $cnt=0; for($i=0; $i < $n; ++$i) { if( $tmp[$i] !== "" ) { $aData[$cnt++] = floatval($tmp[$i]); } } return $cnt; } } ?>iZeroSum=0; foreach( $aData as $idx => $legdata ) { $legsum = array_sum($legdata); $maxnum = max($maxnum,count($legdata)-1); $max = max($legsum-$legdata[0],$max); $totlegsum += $legsum; $this->iZeroSum += $legdata[0] ; } if( round($totlegsum) > 100 ) { JpGraphError::RaiseL(22001,$legsum); //("Total percentage for all windrose legs in a windrose plot can not exceed 100% !\n(Current max is: ".$legsum.')'); } $this->iMax = $max ; $this->iMaxNum = $maxnum; $this->iNumCirc = $this->GetNumCirc(); $this->iMaxVal = $this->iNumCirc * $this->iDelta ; } // Return number of grid circles function GetNumCirc() { // Never return less than 1 circles $num = ceil($this->iMax / $this->iDelta); return max(1,$num) ; } function SetMaxValue($aMax) { $this->iMax = $aMax; $this->iNumCirc = $this->GetNumCirc(); $this->iMaxVal = $this->iNumCirc * $this->iDelta ; } // Set step size for circular grid function Set($aMax,$aDelta=null) { if( $aDelta==null ) { $this->SetMaxValue($aMax); return; } $this->iDelta = $aDelta; $this->iNumCirc = ceil($aMax/$aDelta); //$this->GetNumCirc(); $this->iMaxVal = $this->iNumCirc * $this->iDelta ; $this->iMax=$aMax; // Remember that user has specified interval so don't // do autoscaling $this->iManualScale = true; } function AutoScale($aRadius,$aMinDist=30) { if( $this->iManualScale ) return; // Make sure distance (in pixels) between two circles // is never less than $aMinDist pixels $tst = ceil($aRadius / $this->iNumCirc) ; while( $tst <= $aMinDist && $this->iDelta < 100 ) { $this->iDelta += 5; $tst = ceil($aRadius / $this->GetNumCirc()) ; } if( $this->iDelta >= 100 ) { JpGraphError::RaiseL(22002);//('Graph is too small to have a scale. Please make the graph larger.'); } // If the distance is to large try w