Source for file Axis.php
Documentation is available at Axis.php
* Description: Accesses all Axis characteristics
* @copyright Copyright (c) 1995-2008 by Steema Software SL. All Rights Reserved. <info@steema.com>
* @link http://www.steema.com
private $automatic = true;
private $automaticMaximum = true;
private $automaticMinimum = true;
private $desiredIncrement= 0;
private $logarithmicBase = 10;
private $maximumOffset= 0;
private $minimumOffset= 0;
private $minorTickCount = 3;
private $tickonlabelsonly = true;
private $startPosition= 0;
private $endPosition = 100;
private $relativePosition= 0;
private $otherSide= false;
private static $MAXPIXELPOS = 32767;
public static $MINAXISRANGE = 0.0000000001;
public static $AXISCLICKGAP = 3; // min pixels distance to trigger axis click
function __get( $property ) {
$method = "get{$property}";
function __set ( $property,$value ) {
$method = "set{$property}";
return $this->$method($value);
public function Axis($horiz= false, $isOtherSide= false, $chart= null) {
parent::__construct($chart);
$this->otherSide = $isOtherSide;
private function internalSetMaximum($value) {
private function internalSetMinimum($value) {
* Accesses the Label characteristics of Axis Labels.
* Returns the custom labels
* @return AxisLabelsItems
return $this->labels->getItems();
* Calculates Max and Min of axis scale based on associated Series.
* Description Max and Min of axis scale based on associated Series.
$this->automaticMinimum = $value;
$this->automaticMaximum = $value;
* Determines the Custom axis to be drawn horizontally.
* Sets a custom axis to be drawn horizontally.
* Positions the Axis labels to the Otherside of the axis.<br> For instance,
* moves labels on a vertical Axis to the right of the Axis. This is
* useful when adding a Custom Axis, to place the labelling to the Right
* for a right vertical Axis, or to the Top for a Top Axis.
* Sets the Axis labels to the Otherside of the axis.
if ($this->logarithmic) {
private function reCalcAdjustedMinMax($pos1, $pos2) {
* Called internally to recalculate the max and min $values using the
* Rect parameter positions.<br>
* The Rect parameter determines in pixels the margins to apply to
* ChartRect. The Axis recalculates the appropiate maximum and minimum
* $values using the Rect parameter positions.
$tmp = $this->reCalcAdjustedMinMax($rect->x, $rect->getRight());
$tmp = $this->reCalcAdjustedMinMax($rect->y, $rect->getBottom());
* Returns true if Axis is a Custom Axis
return $this->chart->isAxisCustom($this);
* Calculates Maximum and Minimum $values based on Max and Min $values of
* the dependent Series.<br>
* AdjustMaxMin is automatically called if Axis.Automatic is true.
* The Chart Zoom.Undo method calls AdjustMaxMin for Left, Right,Top
$this->minimumvalue = $tmp->min;
$this->maximumvalue = $tmp->max;
private function setAutoMinMax($variable, $var2, $value) {
// if both are automatic, then Automatic should be True too
$this->automatic = false;
* Controls if Axis will adjust the Maximum $value automatically based on
* the maximum $value of its associated Series.<br>
return $this->automaticMaximum;
* The Axis adjusts the Maximum $value automatically based on the maximum
* $value of its associated Series when true.<br>
$this->automaticMaximum = $this->setAutoMinMax($this->automaticMaximum, $this->automaticMinimum,
* Controls minimum $value automatically based on the minimum $value of
* its associated Series.<br>
return $this->automaticMinimum;
* The Axis adjusts the Minimum $value automatically based on the maximum
* $value of its associated Series when true.<br>
$this->automaticMinimum = $this->setAutoMinMax($this->automaticMinimum, $this->automaticMaximum,
* Determines the kind of pen used to draw the major Axis lines.<br>
* These are the lines which go from Axis Minimum to Axis Maximum screen
* Determines the kind of pen used to draw the Grid lines at every Axis
* Label position.<br> These are the lines which go from "cousin Axis"
* Minimum to "cousin Axis" Maximum screen positions for each Label
* Use the MinorGrid property to make the Grid from Minor Ticks visible.
if ($this->grid == null) {
* Obsolete. Please use Labels.<!-- -->OnAxis instead.
return $this->labels->bOnAxis;
* Obsolete. Please use Labels.<!-- -->OnAxis instead.
$this->labels->bOnAxis = $value;
* Returns if the Axis dependent $values are DateTime or not. <br>
* Each Chart Axis can consider $values to be normal numbers or DateTime
* $values. An axis is "DateTime" if at least one Active Series with
* datetime $values is associated to it.<br>
for ($t = 0; $t < $this->chart->getSeriesCount(); $t++ ) {
$s = $this->chart->getSeries($t);
if ($s->associatedToAxis($this)) {
return $this->getHorizontal() ? $s->getXValues()->getDateTime() :
$s->getYValues()->getDateTime();
* Determines the minimum step between axis labels.<br>
* Can use DateTimeStep for date-time axis. It must be a positive number
* or DateTime $value. TChart will use this $value as the inicial axis label
* step. If there is not enough space for all labels, TChart will calculate
* a bigger one. You can use the DateTimeStep constant array for DateTime
return $this->desiredIncrement;
* Sets the minimum step between axis labels.
/** @todo RAISING EXCEPTIONS HERE FORCES DECLARING "THROW" EVERYWHERE! */
// throw new TeeChartException(Language.getString("AxisIncrementNeg"));
//if (isDateTime()) System.Convert.ToDateTime($value).ToString();
* Swaps the Axis Minimum and Maximum scales.<br>
* When true, Axis Minimum and Maximum scales will be swapped. Axis labels
* and Series points will be displayed accordingly. This applies both to
* vertical and horizontal axis.<br>
* Swaps the Axis Minimum and Maximum scales when true.<br>
if ($this == $this->getChart()->getAxes()->getDepth())
* Scales the Axis Logarithmically when true.<br>
* Axis Minimum and Maximum $values should be greater than 0, and Axis
* cannot be of DateTime type.<br>
return $this->logarithmic;
* Scales the Axis Logarithmically when true.<br>
* @throws TeeChartException
if ($this->chart != null) { //CDI for custom axes at designtime this $value is
return (!$this->automatic) && (!$this->automaticMaximum);
* Amount of pixels that will be left as a margin at axis maximum
* It is useful when you don't want the series to display points very
* close to axis boundaries. <br>
* <pre><font face="Courier" size="4">
* myChart.getAxes().getBottom().setMaximumOffset(4);
* myChart.getAxes().getBottom().setMinimumOffset(4);
return $this->maximumOffset;
* Sets the amount of pixels that will be left as a margin at axis maximum
* The highest $value an Axis will use to scale their dependent Series
* It can be any number or DateTime $value. It must be greater than the
* Axis.Minimum $value.<br><br>
* Axis.Automatic property must be FALSE. If Axis.Automatic is true,
* the Axis will set Maximum and Minimum $values to Maximum and Minimum
* dependent Series $values.
return $this->maximumvalue;
* Sets the highest $value an Axis will use to scale their dependent Series
$this->internalSetMaximum($value);
return (!$this->automatic) && (!$this->automaticMinimum);
* Advanced use. Smallest Axis calculation increment.<br>
* Advanced use. Determines the smallest Axis calculation increment.<br>
* The lowest $value an Axis will use to scale their dependent Series
* It can be any number or DateTime $value. It must be lower than the
* Axis.Maximum $value. <br><br>
* Axis.Automatic property must be FALSE. If Axis.Automatic is true,
* the Axis will set Maximum and Minimum $values to Maximum and Minimum
* dependent Series $values.
return $this->minimumvalue;
* Sets the lowest $value an Axis will use to scale their dependent Series
$this->internalSetMinimum($value);
* The number of pixels that will be left as a margin at axis minimum
* It is useful when you don't want the series to display points very close
* to axis boundaries.<br>
return $this->minimumOffset;
* Determines the number of pixels that will be left as a margin at axis
* The number of Axis minor ticks between major ticks.<br>
* Axis minor ticks are the Axis sub-ticks between major ticks. It should
* be a positive number greater than zero and less than half the number
* of pixels between major ticks, otherwise Minor ticks will "overlap".<br>
return $this->minorTickCount;
* Determines the number of Axis minor ticks between major ticks.<br>
* Determines the Pen used to draw the Axis Minor ticks.<br>
* Minor ticks will only be displayed if MinorTicks.Visible is true.<br>
if ($this->minorTicks == null) {
$this->minorTicks->length = 2;
$this->minorTicks->defaultLength = 2;
return $this->minorTicks;
$this->minorTicks= $value;
* Obsolete. Please use Position instead.
* Determines the screen co-ordinate where axis is drawn.<br>
* It returns the position of the Axis in pixels relative to the Chart
* Panel. For horizontal axes the number is a Y position, for vertical
* axes an X position. <br>
* The Axis Ticks and Axis Grid to be drawn only coincide at Labels.<br>
* Otherwise, they will be drawn at all axis increment positions.
* When the Axis.Labels.Separation property is greater than 0 (default 10),
* Axis increases the increment property to afunction Axis Label overlap.<br>
return $this->tickonlabelsonly;
* Sets the Axis Ticks and Axis Grid to be drawn to only coincide at
* Determines the kind of Pen used to draw Axis marks along the Axis line.
* Ticks position is calculated based on Axis.Increment,
* Axis.Labels.Separation and Axis.Label.Style methods.<br>
* There are three kind of ticks available: Ticks, MinorTicks and
* TicksInner.<br> You can show or hide any of them of have all of them
* Visible. Ticks.Length defines the length of Axis Ticks in logical pixels.
if ($this->ticks == null) {
$this->ticks->defaultLength = 4;
* Determines the kind of Pen used to draw Axis marks along the Axis line.
* This does the same as Ticks, but lines are drawn inside Chart boundaries
* instead. TicksInner position is calculated based on Axis.Increment,
* Axis.Labels.Separation and Axis.Label.Style.<br> There are three kind of
* ticks available: Ticks, MinorTicks and TicksInner.<br> You can show or
* hide any of them of have all of them Visible. TickInnerLength defines
* the length of Axis TicksInner in logical pixels.
if ($this->ticksInner == null) {
return $this->ticksInner;
* An Axis sub-class used to define Title attributes.<br>
* Axis Titles are a string of text drawn near Axes. Use Text to specify
* Use Font and Angle to set the format desired.
* Obsolete. Please use Axis.<!-- -->Title.<!-- -->CustomSize
return $this->getTitle()->getCustomSize();
* Obsolete. Please use Axis.<!-- -->Title.<!-- -->CustomSize
$this->getTitle()->setCustomSize($value);
* Shows or hides the Axis lines, ticks, grids, labels and title.<br>
* You can change it both at design and runtime.<br>
* Shows the Axis lines, ticks, grids, labels and title when true.<br>
* Determines the Z axis position along chart Depth as a percentage of the
* It can even be set to negative $values to place the axis in front of the
* Chart, or $values greater than 100% to place the axis behind the Chart.
* In 3D or orthogonal display modes, ZPosition controls where to display
* the axis line. It useful if you want to move axis to front or to back
* Sets the Z axis position along chart Depth as a percentage of the
* Obsolete. Please use Axis.<!-- -->Grid.<!-- -->Centered property
* Obsolete. Please use Axis.<!-- -->Grid.<!-- -->Centered property
$this->getGrid()->setCentered($value);
* Determines the Axis position as percentage 0-100% of the Chart.<br>
* 0 being Top for a horizontal Axis and Left for a vertical Axis.
return $this->relativePosition;
* Determines the Axis position as percentage 0-100% of the Chart.<br>
* Defines axis Position units (pixels or percentage).<br>
* When PositionUnits is Percent, Position $value is a percentage of total
* When PositionUnits is Pixels, Position is considered in pixels. <br>
* Default $value: Percent
return $this->positionUnits;
* Determines the axis Position units (pixels or percentage).<br>
* Default $value: Percent
* @param $value PositionUnits
if ($this->positionUnits != $value) {
$this->positionUnits = $value;
* Axis Start position on its own Axis expressed as a percentage.<br>
* For a vertical Axis a StartPosition of 75 would place the top of
* the Axis 75% down the Chart.<br>
return $this->startPosition;
* Sets the Axis Start position on its own Axis expressed as a percentage.
* Axis End Position on its own Axis expressed as a percentage (0-100%).<br>
* For a Vertical Axis a $value of 75% would place the beginning of the
* scale at 75% down from Top.<br>
return $this->endPosition;
* Sets the Axis End Position on its own Axis expressed as a percentage.<br>
* The base for the Logarithmic scale when Axis Logarithmic = true.
return $this->logarithmicBase;
* Sets the base for the Logarithmic scale when Axis Logarithmic = true.
* Characteristics of the Grid coincidental to Minor Ticks.<br>
* The Minor Grid.Visible is false as default.
$tmpResult = $this->getTitle()->getCaption();
if ($tmpResult->length() == 0) {
if ($this== $this->getChart()->getAxes()->getDepth())
return Language::getString("DepthAxis");
if ($this == $this->getChart()->getAxes()->getDepthTop())
* Returns the minimum and maximum $values of the associated Series.
if ($this->automatic || $this->automaticMaximum) {
$tmp->max = $this->maximumvalue;
if ($this->automatic || $this->automaticMinimum) {
$tmp->min = $this->minimumvalue;
private function maxLabelsValueWidth() {
if (($this->isDateTime() && $this->labels->getExactDateTime()) ||
$this->labels->getRoundFirstLabel()) {
$tmpB = round($tmp * (($this->iMaximum / $tmp))); //MM error on 'small'(20x20) chart with int32
// GetAxisLabelEventHandler oldGetAxisLabel;
// if (chart.getParent()!=null) oldGetAxisLabel=chart.getParent().GetAxisLabel;
$tmpResult = ($this->chart->getGraphics3D()->textWidth(" ") +
$this->labels->labelValue($tmpA))->width,
$this->chart->multiLineTextWidth($this->labels->labelValue($tmpB))->width));
* Returns the maximum width in pixels of all Axis Labels.
if ($this->getLabels()->getItems()->count() == 0) {
return $this->maxLabelsValueWidth();
return $this->chart->maxMarkWidth();
return $this->chart->maxTextWidth();
$g= $this->chart->getGraphics3D();
for ($t = 0; $t < sizeof($items); $t++ ) {
$g->setFont($items->getItem($t)->getFont());
$this->chart->multiLineTextWidth($items->getItem($t)->getText())->width);
private function internalCalcSize($tmpFont, $tmpAngle, $tmpText, $tmpSize) {
$g = $this->chart->getGraphics3D();
return $g->fontTextHeight($tmpFont);
default: // optimized for speed
return $g->textWidth($tmpText,$tmpFont);
return $g->fontTextHeight($tmpFont);
default: // optimized for speed
return $g->textWidth($tmpText,$tmpFont);
$result= $this->internalCalcSize($this->labels->getFont(), $this->labels->getAngle(), "",
$this->labels->getCustomSize());
if ($this->labels->getAlternate())
private function internalCalcDepthPosValue($value) {
private function internalCalcLogPosValue($isx, $value) {
return $isx ? $this->iStartPos + $tmpResult :
* Returns the corresponding $value of a Screen position in pixels.
* @param $value Screen $value
* @return Position on screen in pixels
* Description Calculates the Horizontal coordinate in pixels of $value parameter
* You can use CalcXPos$value when requiring pixel positions from which
* to plot Drawing output.
return $this->internalCalcDepthPosValue($value);
if ($this->logarithmic) {
return $this->internalCalcLogPosValue(true, $value);
if ($tmp > self::$MAXPIXELPOS) {
$tmp = self::$MAXPIXELPOS;
if ($tmp < - self::$MAXPIXELPOS) {
$tmp = - self::$MAXPIXELPOS;
* Calculates the Vertical coordinate in pixels of $value parameter.
* @param $value $value Parameter
* @return $Vertical coordinate in pixels
return $this->internalCalcDepthPosValue($value);
if ($this->logarithmic) {
return $this->internalCalcLogPosValue(false, $value);
// compile with //#define CHECKOVER
// if you wish to afunction axis coordinates overflow when zooming,
// specially in Windows 95, 98 or Me.
if ($tmp > self::$MAXPIXELPOS) {
$tmp = self::$MAXPIXELPOS;
if ($tmp < - self::$MAXPIXELPOS) {
$tmp = - self::$MAXPIXELPOS;
//#else // faster version (no checking)...
// $tmp = (int) (($value - iMinimum) * iAxisSizeRange);
// return inverted ? IStartPos + tmp : IEndPos - tmp;
$this->chart->getAspect()->getWidth3D();
return MathUtils::round($result * $this->zPosition * 0.01); // 6.0
* Returns the amount in pixels that corresponds to a portion of the axis
* of size "$value" in axis scales.
* @return $Potrtion of axis in pixels
if ($this->logarithmic) {
private function internalCalcPos($a, $b) {
* Returns the corresponding $value of a Screen position.
* @param $value $Screen $value
* @return double Position on screen in pixels
if ($this->logarithmic) {
private function axisRect() {
if ($this->posAxis > $this->labels->position) {
$pos1 = $this->labels->position;
$pos2 = $this->posAxis + self::$AXISCLICKGAP;
$pos1 = $this->posAxis - self::$AXISCLICKGAP;
$pos2 = $this->labels->position;
return Rectangle::fromLTRB($tmpPos1, $pos1, $tmpPos2, $pos2);
* Returns if X and Y coordinates are close to the Axis position.
* @param xy Po$(X and Y coordinates)
* @return boolean - X and Y coordinates as integer
/* public function clicked($xy) {
return $this->clicked($xy->x, $xy->y);
* Returns if X and Y coordinates are close to the Axis position.
* @param x Pixel location
* @param y Pixel location
* @return boolean - true if X and Y coordinates are
return $this->chart->isAxisVisible($this) && $this->axisRect()->contains($x, $y);
* Returns the calculated Maximum Horizontal $value for the specified AAxis.
* AAxis can be Axis.Top or Axis.Bottom. Calculated means that the return
* $value will be the Maximum $value of the Maximum Series X $values.
* Only Series with the HorizontalAxis equal to AAxis will be considered.
* @see Axis#getMinX$value
* @see Axis#getMinY$value
* @see Axis#getMaxY$value
return $this->chart->getMaxXValue($this);
* Returns the calculated Maximum Vertical $value for the specified AAxis.
* AAxis can be Axis.Left or Axis.Right. Calculated means that the return
* $value will be the Maximum $value of the Maximum Series Y $values. Only
* Series with the VerticalAxis equal to AAxis will be considered.
* @see Axis#getMinX$value
* @see Axis#getMaxX$value
* @see Axis#getMinY$value
return $this->chart->getMaxYValue($this);
* Returns the calculated Minimum Horizontal $value for the specified AAxis.
* AAxis can be Axis.Top or Axis.Bottom. Calculated means that the return
* $value will the Minimum $value of the Minimum Series X $values. Only
* Series with the HorizontalAxis equal to AAxis will be considered.
* @see Axis#getMaxX$value
* @see Axis#getMinY$value
* @see Axis#getMaxY$value
return $this->chart->getMinXValue($this);
* Returns the calculted Minimum Vertical $value for the specified AAxis.
* AAxis can be Axis.Left or Axis.Right. Calculated means that the return
* $value will the Minimum $value of the Minimum Series Y $values. Only
* Series with the VerticalAxis equal to AAxis will be considered.
* @see Axis#getMinX$value
* @see Axis#getMaxX$value
* @see Axis#getMaxY$value
return $this->chart->getMinYValue($this);
* Returns either a Time or Date format depending if the astep parameter
* is lower than one day (time) or greater (date).
private function nextStep($oldStep) {
return 10 * $this->nextStep(0.1 * $oldStep);
} else if ($oldStep < 1) {
return 0.1 * $this->nextStep($oldStep * 10);
} else if ($oldStep < 2) {
} else if ($oldStep < 5) {
// returns AxisLabelStyle
private function internalCalcLabelStyle() {
for ($t = 0; $t < $this->chart->getSeriesCount(); $t++ ) {
$s = $this->chart->getSeries($t);
if ($s->getHasZValues() ||
($s->getMinZValue() != $s->getMaxZValue())) {
for ($t = 0; $t < $this->chart->getSeriesCount(); $t++ ) {
$tmpSeries = $this->chart->getSeries($t);
if (($tmpSeries->getActive()) &&
($tmpSeries->associatedToAxis($this))) {
if ((($this->horizontal) && ($tmpSeries->getYMandatory())) ||
((!$this->horizontal) && (!$tmpSeries->getYMandatory()))) {
if (($tmpSeries->getLabels() != null) &&
(strlen($tmpSeries->getLabels[0]) != 0)) {
private function internalCalcLabelsIncrement($maxNumLabels) {
if ($this->desiredIncrement <= 0) {
$tmpResult = abs($this->iRange) / ($maxNumLabels + 1);
if ($this->anySeriesHasLessThan($maxNumLabels)) {
$tmpResult = max(1, $tmpResult);
$tmpResult = $this->desiredIncrement;
$tempNumLabels = $maxNumLabels + 1;
if (is_Infinite($this->iRange)) {
if ($this->labels->getSeparation() >= 0) {
$tmp = $this->iRange / $tmpResult;
if (abs($tmp) < intval('1000000000000')) { // Int MAX_VALUE
if ($tempNumLabels > $maxNumLabels) {
$tmpResult = $this->nextStep($tmpResult);
$tmpResult = $this->nextStep($tmpResult);
$inf = is_Infinite($tmpResult);
} while (($tempNumLabels > $maxNumLabels) &&
($tmpResult <= $this->iRange) && (!$inf));
static private function nextDateTimeStep($aStep) {
if ($aStep >= ($tmpDateTimeStep->STEP[$t])) {
return $tmpDateTimeStep->STEP[$t + 1];
private function calcDateTimeIncrement($maxNumLabels) {
$tmpResult = max($this->desiredIncrement,
if (($tmpResult > 0) && ($maxNumLabels > 0)) {
if (($this->iRange / $tmpResult) > 1000000) {
$tmpResult = $this->iRange / 1000000;
$tempNumLabels = MathUtils::round($this->iRange / $tmpResult);
if ($tempNumLabels > $maxNumLabels) {
if ($tmpResult < $tmpDateTimeStep->STEP[
$tmpResult = self::nextDateTimeStep($tmpResult);
} while ($tempNumLabels > $maxNumLabels);
return max($tmpResult, $tmpDateTimeStep->STEP[DateTimeStep::$ONEMILLISECOND]);
private function anySeriesHasLessThan($num) {
for ($t = 0; $t < $this->chart->getSeriesCount(); $t++ ) {
$s = $this->chart->getSeries($t);
if ($s->associatedToAxis($this)) {
$result = $s->getCount() <= $num;
private function calcLabelsIncrement($maxNumLabels) {
$tmpResult = $this->calcDateTimeIncrement($maxNumLabels);
$tmpResult = $this->internalCalcLabelsIncrement($maxNumLabels);
$tmpResult = $tmpDateTimeStep->STEP[DateTimeStep::$ONEMILLISECOND];
* Returns the calculated Axis Label increment.
* @param maxLabelSize $The maximum allowable LabelSize in pixels.
* @return double Size of increment in Axis units.
if ($this->labels->getSeparation() > 0) {
$maxLabelSize = ($maxLabelSize +
$this->labels->getSeparation() *
return $this->calcLabelsIncrement($tmp);
* Returns the calculated Axis Label increment and serves as a useable
* measure when Labelling is set to manual or automatic increments.<br>
* Please note that the related Increment property only returns the
* increment $value when those increments are manually set via the same
* @return double calculated Axis Label increment.
$this->labels->labelWidth($this->iMaximum));
$tmp = max($this->labels->labelHeight($this->iMinimum),
$this->labels->labelHeight($this->iMaximum));
if ($this->labels->getAlternate())
$result= $result/ $this->logarithmicBase;
$tmpResult = $this->axispen->getWidth() + 1;
$tmpResult += $this->ticks->length;
$tmpResult = max($tmpResult, $this->minorTicks->length);
return $this->horizontal ? $r->y : $r->getRight();
return $this->horizontal ? $r->getBottom() : $r->x;
private function inflateAxisRect($value, $r) {
$r->width = $tmpR - $tmpL;
$r->height = $tmpB - $tmpT;
private function inflateAxisPos($value, $amount) {
// returns CalcLabelsResults
private function calcLabelsRect($tmpSize, $r) {
$result->rect = $this->inflateAxisRect($tmpSize, $r);
* Used internally by Chart when creating Axes
* @param r Chart Rectangle
* @param inflateChartRectangle boolean Wall allowance (standard Axes only)
public function calcRect($r, $inflateChartRectangle) {
if ($inflateChartRectangle) {
// new? todo CalcLabelsResults tmpRes;
$tmpRes = $this->calcLabelsRect($this->internalCalcSize(
if ($this->labels->getVisible()) {
$tmpRes = $this->calcLabelsRect($this->getSizeLabels()+ 10, $r); // Rev aded +10
$this->labels->position = $tmpRes->position;
$r = $this->inflateAxisRect($tmp, $r);
$this->labels->position = $this->applyPosition($this->labels->position, $r);
if ($this->relativePosition != 0) {
$tmpsize = $this->horizontal ? $r->height : $r->width;
$tmpsize = MathUtils::round(0.01 * $this->relativePosition *
* Used internally to return Axis Datetime step.
* @param step$value double Desired increment
if ((abs($tmpDateTimeStep->STEP[$t] - $stepValue)) <
private function drawExponentLabel($x, $y, $tmpZ, $tmpSt2) {
$g = $this->chart->getGraphics3D();
$i = $tmpSt2->toUpperCase()->indexOf('E');
$g->textOut($x, $y, $tmpZ, $tmpSt2);
$tmp = $tmpSt2->substring(0, 1);
$tmpSub = $tmpSt2->substring(1);
$tmp = $tmpSt2->substring(0, $i - 1);
$tmpSub = $tmpSt2->substring($i + 1);
$oldSize = $font->getSize();
$g->textOut($x, $y, $tmpZ, $tmp);
$tmpW = $g->textWidth($tmp) + 1;
$font->setSize($font->getSize() - ($oldSize * 0.25));
$g->textOut( ($x + $tmpW),
($y - ($tmpH * 0.5)) + 2, $tmpZ,
$font->setSize($oldSize);
$font->setSize($font->getSize() -
$g->textOut($x, $y - ($tmpH * 0.5) + 2, $tmpZ,
$tmpW = $g->textWidth($tmpSub) + 1;
$font->setSize($oldSize);
$g->textOut(($x - $tmpW), $y, $tmpZ, $tmp);
static private function numTextLines($st) {
// TODO $i = $st->indexOf(Language::getString("LineSeparator"));
$st = $st->substring($i + 1);
$i = $st->indexOf(Language::getString("LineSeparator"));
if ($st->length() != 0) {
* Draws Axis Label (String) at specified X,Y co-ordinate at Angle.
* @param angle $Angle at which Label is drawn
* @param st String asociated to Label
* @param labelItem TextShape
$this->drawAxisLabel($this->labels->getFont(), $x, $y, $angle, $st, $labelItem);
* Draws Axis Label (String) in font f at specified X,Y co-ordinate at
* @param angle $Angle at which Label is drawn
* @param st String asociated to Label
* @param format TextShape
public function drawAxisLabel($f, $x, $y, $angle, $st, $format) {
$old_name = TChart::$controlName;
TChart::$controlName .= 'AxisLabel';
/*StringAlignment[][] aligns =
new StringAlignment[][] { {StringAlignment.FAR,
StringAlignment.NEAR}, {StringAlignment.CENTER,
StringAlignment tmpAlign, tmpAlign2;
$g = $this->chart->getGraphics3D();
$oldStrAlign = $g->getTextAlign();
$tmpFontH = $g->getFontHeight();
$intOtherSide = $this->otherSide ? 1 : 0;
$notIntOtherSide = $this->otherSide ? 0 : 1;
$n = self::numTextLines($st);
$textWidth = $g->textWidth($st);
if (($angle > 90) && ($angle <= 180)) {
// $y += $delta; //1st line
$y += ($delta * ($n) / 2);
} else if (($angle > 0) && ($angle < 90)) {
$x -= ($delta * ($n) / 2);
if ($this->getLabels()->getAlign() == AxisLabelAlign::$DEF) {
} else if ($angle == 90) {
$x -= ($delta * ($n) / 2);
if ($this->getLabels()->getAlign() == AxisLabelAlign::$DEF) {
} else if (($angle > 180) && ($angle <= 270)) {
$x = $x + $delta + ($delta * ($n) / 2);
if ($this->getLabels()->getAlign() == AxisLabelAlign::$DEF) {
if (($angle > 90) && ($angle <= 180)) {
} else if (($angle > 0) && ($angle < 90)) {
$x -= ($delta * ($n) / 2);
if ($this->getLabels()->getAlign() == AxisLabelAlign::$DEF) {
//$y += $this->maxLabelsWidth();
} else if ($angle == 90) {
$x -= ($delta * ($n) / 2);
if ($this->getLabels()->getAlign() == AxisLabelAlign::$DEF) {
$y += $mlv + (0.10 * $mlv);
// $y -= $this->maxLabelsWidth();
} else if (($angle > 180) && ($angle <= 270)) {
$x += $delta + ($delta * ($n) / 2);
if ($this->getLabels()->getAlign() == AxisLabelAlign::$DEF) {
} else if ($this->otherSide) {
if ((($angle > 270) && ($angle <= 360)) || ($angle == 0)) {
$y -= ($delta * ($n)) / 2;
if ($this->getLabels()->getAlign() == AxisLabelAlign::$DEF) {
} else if (($angle > 90) && ($angle <= 180)) {
$y += 100+ $delta; //1st line
$y += ($delta * ($n)) / 2;
if ($this->getLabels()->getAlign() == AxisLabelAlign::$DEF) {
} else if (($angle > 0) && ($angle <= 90)) {
$y += ($delta * ($n)) / 2;
if ((($angle > 270) && ($angle <= 360)) || ($angle == 0)) {
$y -= ($delta * ($n)) / 2;
if ($this->getLabels()->getAlign() == AxisLabelAlign::$DEF) {
} else if (($angle > 90) && ($angle <= 180)) {
$y += ($delta * ($n)) / 2;
if ($this->getLabels()->getAlign() == AxisLabelAlign::$DEF) {
} else if (($angle > 0) && ($angle < 90)) {
$y += ($textWidth / 2) + 2;
if (!$format->getTransparent()) {
// TODO UPDATE THIS PART OF CODE FOR ALIGNMENT
$tmpSize = $g->textWidth("W") / 4; //4 instead 2 so the margin don't be so high
$format->setTop($y + $delta);
$tmp = $this->chart->multiLineTextWidth($st);
$tmpH = $tmpFontH * $tmpNum;
$format->setBottom($format->getTop() + $tmpH);
$format->setRight($format->getLeft() + $tmpW);
$tmpW = ($format->getRight() - $format->getLeft());
$format->setLeft($format->getLeft() - $tmpW);
$format->setRight($format->getLeft() + $tmpW);
$tmpW = ($format->getRight() - $format->getLeft()) / 2;
$format->setLeft($format->getLeft() - $tmpW);
$format->setRight($format->getRight() + $tmpW);
$format->setLeft($format->getLeft() - $tmpSize);
$format. setRight($format->getRight() + $tmpSize);
$format->setShapeBounds($g->calcRect3D($format->getShapeBounds(),
$format->drawRectRotated($g, $format->getShapeBounds(),
$g->getBrush()->setVisible(false);
$g->setTextAlign($tmpAlign);
$is3D = $this->chart->getAspect()->getView3D();
for ($tt = 1; $tt <= $n; $tt++ ) {
// TODO $i = $tmpSt->indexOf(Language.getString("LineSeparator"));
// TODO remove temporary below line
$tmpSt2 = ($i != - 1) ? substr($tmpSt,0, $i) : $tmpSt;
if ($this->labels->getExponent()) {
$tmpSt2 = $this->drawExponentLabel($x, $y, $tmpZ, $tmpSt2);
$g->textOut($x, $y, $tmpZ, $tmpSt2);
$g->textOut($x, $y, 0, $tmpSt2);
if (($angle >= 0) && ($angle <= 90)) {
} else if (($angle > 90) && ($angle <= 180)) {
} else if (($angle > 180) && ($angle <= 270)) {
} else if (($angle > 270) && ($angle < 360)) {
$g->rotateLabel($x, $y, $tmpZ, $tmpSt2, $angle);
$tmpSt = substr($tmpSt,0,$i + 1);
$g->setTextAlign($oldStrAlign);
TChart::$controlName= $old_name;
return StringAlignment::$NEAR;
return StringAlignment::$FAR;
private function getDepthAxisPos() {
return $this->chart->getChartRect()->getBottom()->calcZPos();
* TeeChart internal use. Outputs the title during the chart painting
$old_name = TChart::$controlName;
TChart::$controlName .= 'Axis_Title_';
$g = $this->chart->getGraphics3D();
$g->textOut($x, $y, $this->chart->getAspect()->getWidth3D() / 2,
$old = $this->labels->getExponent();
$this->labels->setExponent(false);
$this->labels->setExponent($old);
TChart::$controlName= $old_name;
private function _decMonths($howMany, $date) {
return $this->decMonths($howMany, $date->day, $date->month, $date->year);
private function decMonths($howMany, $day, $month, $year) {
$month = 12 - ($howMany - $month);
return new DateParts($year, $month, $day);
private function /*DateParts*/ _incMonths($howMany, /*DateParts*/ $date) {
return $this->incMonths($howMany, $date->year, $date->month, $date->day);
private function /*DateParts*/ incMonths($howMany, $day, $month, $year) {
$increment, $value, $anIncrement,
private function incDecMonths($howMany, /*DateParts*/ $date, $increment) {
$this->incMonths($howMany, $date);
$this->decMonths($howMany, $date);
* Is a set of constants used to specify a date time increment.
* @param isDateTime boolean
* @param increment boolean
* @param anIncrement double
* @param tmpWhichDatetime int
* @return double date time increment $value
$anIncrement, $tmpWhichDatetime) {
// TODO get the format from ... ??
$tmpArrayDateTime= date('Y-m-d',$value);
$d = new DateParts($tmpArrayDateTime['year'],
$tmpArrayDateTime['month'],
$tmpArrayDateTime['day']);
switch ($tmpWhichDatetime) {
} else if ($d->day > 1) {
$this->incDecMonths(1, $d, $increment);
$this->incDecMonths(1, $d, $increment);
$this->incDecMonths(2, $d, $increment);
$this->incDecMonths(3, $d, $increment);
$this->incDecMonths(4, $d, $increment);
$this->incDecMonths(6, $d, $increment);
$value += $increment ? $anIncrement : - $anIncrement;
* Returns the most logical Axis Label style.<br>
* It calculates the "best candidate" label style based on how many Active
* Series are in the Chart and if the Series has po$labels. The
* LabelStyle property must be set to talAuto for this function to work.<br>
* If LabelStyle is not talAuto, the LabelStyle property $value is returned.
return ($this->getLabels()->iStyle == AxisLabelStyle::$AUTO) ?
$this->internalCalcLabelStyle() : $this->labels->iStyle;
public function _draw($g, $calcPosAxis) {
$old = $this->chart->getGraphics3D();
$this->chart->setGraphics3D($g);
$this->draw($calcPosAxis);
$this->chart->setGraphics3D($old);
* Displays an Axis at the specified screen positions with the current
* Normally you do not need to call the Draw method directly.
* @param calcPosAxis boolean True if space allowance for Axis Labelling
public function draw($calcPosAxis) {
private function reCalcSizeCenter() {
private function doCalculation($aStartPos, $aSize) {
$this->doCalculation(0, $this->chart->getAspect()->getWidth3D());
$r = $this->chart->getChartRect();
$this->doCalculation($r->x, $this->chart->getChartRect()->width);
$this->doCalculation($r->y, $this->chart->getChartRect()->height);
$this->reCalcSizeCenter();
* Displays an Axis at the specified screen positions with the current
* Main drawing method. Custom draw methods can be overloads.
* @param gridVisible boolean
public function __draw($posLabels, $posTitle, $posAxis,
* Displays an Axis at the specified screen positions with the current
* Main drawing method. Custom draw methods can be overloads.
* @param gridVisible boolean
public function ___draw($posLabels, $posTitle, $posAxis,
$gridVisible, $aStartPos,
$this->reCalcSizeCenter();
$oldgridvisible = $this->getGrid()->getVisible();
$this->grid->setVisible($gridVisible);
$this->grid->setVisible($oldgridvisible);
* Scrolls or displaces the Axis Maximum and Minimum $values by the Offset
* If you want to scroll the Axis outside Series limits,
* CheckLimits must be false.
* @param checkLimits boolean
public function scroll($offset, $checkLimits) {
($this->maximumvalue < $this->chart->internalMinMax($this, false,
$this->automatic = false;
$this->automaticMaximum = false;
$this->maximumvalue += $offset;
$this->automaticMinimum = false;
$this->minimumvalue += $offset;
* Changes the current Axis Minimum and Maximum scales.<br>
* Axis.Automatic must be set to false.
* @param minDate DateTime Axis Minimum scale
* @param maxDate DateTime Axis Maximum scale
$this->setMinMax($minDate->toDouble(), $maxDate->toDouble());
* Changes the current Axis Minimum and Maximum scales.<br>
* Axis.Automatic must be set to false.
* @param min double Axis Minimum scale
* @param max double Axis Maximum scale
$this->automatic = false;
$this->automaticMinimum = false;
$this->automaticMaximum = false;
if ($min > $max) { // swap
$this->internalSetMinimum($min);
$this->internalSetMaximum($max);
if (($this->maximumvalue - $this->minimumvalue) < self::$MINAXISRANGE) {
$this->internalSetMaximum($this->minimumvalue + self::$MINAXISRANGE);
$this->labels->setChart($this->chart);
$this->labels->axis= $this;
private function setInternals() {
* Displays an Axis at the specified screen positions with the current
* Main drawing method. Custom draw methods can be overloads.
* @param gridVisible boolean
* @param aStartPosition int
* @param aEndPosition int
public function ____draw($posLabels, $posTitle, $posAxis,
$aStartPosition, $aEndPosition) {
$aStartPosition, $aEndPosition);
* Displays an Axis at the specified screen positions with the current
* Main drawing method. Custom draw methods can be overloads.
* @param gridVisible boolean
* @param aIncrement double
public function _____draw($posLabels, $posTitle,
$aIncrement, $aStartPos, $aEndPos) {
$oldMin = $this->minimumvalue;
$oldMax = $this->maximumvalue;
$oldIncrement = $this->desiredIncrement;
$oldAutomatic = $this->automatic;
$this->automatic = false;
$this->minimumvalue = $aMinimum;
$this->maximumvalue = $aMaximum;
$this->desiredIncrement = $aIncrement;
$this->draw($posLabels, $posTitle, $posAxis, $gridVisible, $aStartPos,
$this->minimumvalue = $oldMin;
$this->maximumvalue = $oldMax;
$this->desiredIncrement = $oldIncrement;
$this->automatic = $oldAutomatic;
public function DateParts($year= 0, $month= 0, $day= 0) {
// TODO return (new DateTime($this->year, $this->month, $this->day))->toDouble();
|