Source for file CanvasFlex.php
Documentation is available at CanvasFlex.php
parent::GraphicsGD($c, $c->getWidth(), $c->getHeight());
$this->iCanvasType = "Flex";
$this->embeddedImages = true;
private function ImageSource($graphic)
if ($this->EmbeddedImages)
return '@Embed("' . $this->ImageFileName($graphic) . '")';
return $this->ImageFileName($graphic);
private function GraphicsExtension($format)
private function CalcResult($tmp)
$tmpExt = $this->GraphicsExtension($tmp->RawFormat);
$result = "TeeChart_Flex_Temp_" . $this->iImageID . "." . $tmpExt;
$tmp->Save($this->ImagePath . "/" . $result);
private function ImageFileName($graphic)
/*MemoryStream ms = new MemoryStream();
Bitmap bmp = new Bitmap(graphic);
format.Save(ms, bmp, bmp.Width, bmp.Height);
return $this->CalcResult($bmp);
return $this->CalcResult($graphic);
private function FlexSize($R)
return $this->FlexSizeWH($R->Width, $R->Height);
private function FlexSizeWH($w, $h)
private function ParseSeriesID($ID)
if (strpos($ID,"Series") != false)
$elements = Split('_',$ID);
// TODO must work for all Series... now just work for 0 index
// $seriesIndex = str_replace("Series", "", $elements[1]) - 1;
for ($tt= 0; $tt < sizeof($elements); ++ $tt)
if (strstr($elements[$tt], 'SeriesPointer')!= false)
$valueIndex=(int) $elements[4];
// $srsPtrIndx = array_search('id=\"SeriesPointer', $elements); // strpos($elements, "SeriesPointer");
// $valueIndex = (int)($elements[2]);
// if ($srsPtrIndx > (sizeof($elements) - 3 )) // - 2 before
// $valueIndex += $elements[$srsPtrIndx + 1];
if ($this->Chart->Tools[$i]->Active && $this->chart->getTool($i) instanceof MarksTip)
$marksTip = $this->chart->getTool($i);
if ($marksTip->series == $this->chart->getSeries($seriesIndex) || $marksTip->series == null)
$series = $this->chart->getSeries($seriesIndex);
$tmpStyle = $series->getMarks()->getStyle();
$tmpOld = $this->chart->getAutoRepaint();
$this->chart->autoRepaint = false;
$series->getMarks()->style = $marksTip->getStyle();
$this->tipString = $series->getValueMarkText($valueIndex);
$series->getMarks()->style = $tmpStyle;
$this->chart->autoRepaint = $tmpOld;
private function AddAnimation($ID)
if ($this->ParseSeriesID($ID))
$result = ' toolTip="' . $this->tipString . '"';
for ($i = 0; $i < sizeof($this->chart->animations); $i++ )
$animation = $this->chart->animations[$i];
switch ($animation->trigger)
$ineffect = "mouseDownEffect";
$outeffect = "mouseUpEffect";
case AnimationTrigger::$MouseOver:
$ineffect = "rollOverEffect";
$outeffect = "rollOutEffect";
if ($animation instanceof Expand) {
switch ($animation->target)
$strTarget = 'SeriesMarks';
$strTarget = 'SeriesPointer';
if (strpos($ID,$strTarget) != false)
if (strpos($ID,'Chart_Series') != false)
$result .= ' ' . $ineffect . ' ="{teeexpand}" ' . $outeffect . ' ="{teeunexpand}"';
private function AddTag($ATag, $AText)
$this->AddToStream($this->iIdent . '<' . $ATag . $ID . ' ' . $AText . $this->AddAnimation($ID) . '/>');
private function CalcAlpha($penOnly)
return $this->Pen->Transparency;
if ($this->Brush->Visible)
return $this->Brush->Transparency;
else if ($this->Pen->Visible)
return $this->Pen->Transparency;
$tmpID = $this->CurrentID();
$this->isMarksTip = false;
if (strstr($tmpID, 'SeriesPointer_') != false)
if (strstr($tmpID, 'Chart_Series') != false)
$series_index = substr($tmpID,12,1);
for ($t = 0; $t < sizeof($this->chart->getTools()); $t++ ) {
$s = $this->chart->getTool($t);
//if ($s->getSeries() ==)
$this->isMarksTip = true;
/* if (strpos($tmpID,"MarksTip_") != false)
$this->isMarksTip = true;
$tmpID = str_replace("MarksTip_", "",$tmpID);
$this->isMarksTip = false;
while( (in_array( $result, $this->iItems )) != FALSE )
$result = $tmpID . "_" . $tmp;
return ' id="' . $result . '"';
private function CurrentID()
if (sizeof($this->iPath) == 0)
if ($this->Chart->Parent != null)
// If we wanto display the name of the component which references to the
// mxml file lines we have to add a Control property into the TChart class
// for example and set and assign each class name to it at the time it's
//$tmpStr .= get_class($this->getChart()->getParent()) . "_";
$tmpStr .= TChart::$controlName . "_";
$tmpStr->Append($this->iPath[0]);
for ($i = 1; $i < sizeof($this->iPath); $i++ )
$tmpStr .= "_" . $this->iPath[$i];
private function PenWidth()
if ($this->Pen->Width == 1)
return ' strokeWidth="' . $this->Pen->Width . '"';
private function BrushColor()
if ($this->Brush->Visible)
if ($this->Brush->Gradient->Visible)
return $this->FlexGradient($this->Brush->Gradient);
return " brushColor=" . $this->FlexColor($this->Brush->Color); ;
private function GradientDirection($direction)
private function FlexGradient($gradient)
return ' gradientType="' . $tmpType . '" ' .
'gradientDir="' . $this->GradientDirection($gradient->Direction) . '" ' .
"startColor=" . $this->FlexColor($gradient->StartColor) . " " .
"endColor=" . $this->FlexColor($gradient->EndColor) . " ";
private function PenColor()
if ($this->getPen()->getVisible())
return ' strokeColor=' . $this->FlexColor($this->getPen()->getColor());
return ' strokeColor=""';
private function ColorInternal($color)
$result = "0x" . self::rgbhex($color->getRed(), $color->getGreen(), $color->getBlue());
// Converts RGB color to Hex
static function rgbhex($red,$green,$blue) {
private function FlexColor($aColor)
return '"' . $this->ColorInternal($aColor) . '"';
private function FlexAlpha($transparency)
return ' alpha="' . $this->FloatToStr(1.0 - ($transparency / 100.0)) . '"';
private function FlexPoints($Points)
$tmpStr->Append('points="[');
$tmpStr->Append($this->$Points[0]);
for ($i = 1; $i < sizeof($Points); $i++ )
$tmpStr->Append("," . $this->$Points[$i]);
private function FontStyle($AFont)
return ' fontStyle="italic" ';
private function FontWeight($AFont)
return ' fontWeight="bold" ';
private function TextDecoration($AFont)
return ' textDecoration="underline" ';
private function FlexFont($AFont)
return $this->FontStyle($AFont) .
$this->FontWeight($AFont) .
' fontSize="' . (int) ($AFont->Size/* * 1.2*/) . '" ' .
$this->TextDecoration($AFont) .
' fontFamily="Verdana" ' .
' color=' . $this->FlexColor($AFont->Color) . " ";
// ' fontFamily="' . $AFont->Name . '" ' .
#region protected and internal members
protected internal override TVisualBlock BeginEntity(string Entity, TVisualBlock Visual)
TVisualBlock Result = Visual;
this.iIdent = this.iIdent + " ";
protected internal override UIElement BeginEntity(string Entity, UIElement Visual)
UIElement Result = Visual;
this.iIdent = this.iIdent + " ";
protected internal override object BeginEntity(string Entity, object Visual)
this.iIdent = this.iIdent + " ";
protected internal override function EndEntity()
this.iPath.RemoveAt(this.iPath.Count - 1);
this.iIdent = this.iIdent.Remove(0, 1);
private function AddAnimationTypes()
for ($i = 0; $i < sizeof($this->chart->getAnimations()); $i++ )
$animation = $this->chart->getAnimation($i);
if ($animation instanceof Expand)
$this->AddToStream(' <mx:Move duration="' . $expand->getSpeed() .
'" suspendBackgroundProcessing="true" xBy="-' .
($expand->getSizeBy() / 2) . '" yBy="-' . ($expand->getSizeBy() / 2) .
$this->AddToStream(' <mx:Resize duration="' . $expand->getSpeed() .
'" suspendBackgroundProcessing="true" widthBy="' .
$expand->getSizeBy() . '" heightBy="' .
$expand->getSizeBy() . '"/>');
$this->AddToStream(' <mx:Resize duration="' . $expand->getSpeed() .
'" suspendBackgroundProcessing="true" widthBy="-' .
$expand->getSizeBy() . '" heightBy="-' .
$expand->getSizeBy() . '"/>');
$this->AddToStream(' <mx:Move duration="' . $expand->getSpeed() .
'" suspendBackgroundProcessing="true" xBy="' .
($expand->getSizeBy() / 2) . '" yBy="' . ($expand->getSizeBy() / 2) .
/// Adds canvas instruction to stream.
/// <param name="text">Instructions to be added to stream.</param>
$linetext = $text . "\r\n";
fwrite($this->fStream,$linetext);
private function AddMarksTip()
for ($i = 0; $i < sizeof($this->chart->getTools()); $i++ )
$this->AddToStream(' import mx.managers.ToolTipManager;');
$this->AddToStream(' import com.steema.graphics.HtmlToolTip;');
$this->AddToStream(' ToolTipManager.toolTipClass = HtmlToolTip;');
public /*protected */ function InitWindow($a, $r, $MaxDepth)
$this->iAddedInitApp = false;
$this->AddToStream('<!-- Generated by TeeChart for .NET -->');
$this->AddToStream('<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"');
$this->AddToStream(' xmlns:tee="com.steema.graphics.*"');
//iApplication = swFromStream.
$this->AddAnimationTypes();
$this->AddToStream(' <mx:Canvas ' . $this->FlexSize($r) . ' horizontalScrollPolicy = "off" verticalScrollPolicy = "off">');
// TODO search original net file for pointtostr
return 'x="' . (int) $X . '" y="' . (int) $Y . '"';
//throw new Exception("The method or operation is not implemented.");
public function textOut($x, $y, $z, $text, $align=- 1)
$fontFileName = $font->getName();
$fontSize = $font->getFontSize();
$textWidth = $this->textWidth($text); // $lrx - $llx;
$textHeight = $this->textHeight($text); // $fontSize; // $lry - $ury;
/* if (in_array (StringAlignment::$VERTICAL_CENTER_ALIGN, $align)) {
/*if (in_array (StringAlignment::$VERTICAL_TOP_ALIGN, $align)) {
if (in_array (StringAlignment::$VERTICAL_BOTTOM_ALIGN, $align)) {
$x -= MathUtils::round($this->TextWidth($text));
//$x += MathUtils::round($this->TextWidth($text) / 2.0);
$y -= MathUtils::round($this->TextHeight($text) / 2.0);
$this->AddTag("mx:Label", 'text="' . $text . '" ' . $this->PointToStr($x, $y) .
$this->FlexFont($this->Font) . ' textAlign="left"');
return 'rx="' . '8' . '" ry="' . '8' . '"';
if ($this->getBrush()->getImage() != null)
// TODO $this->Draw($r, $b->Image, $b->ImageTransparent);
if ($this->getChart()->getPanel()->getBorderRound() > 0)
$this->AddTag("tee:RoundRect", $this->PointToStr($r->X, $r->Y) . " " . $this->FlexSize($r) . " " . $this->RXY($r) .
$this->FlexAlpha($this->CalcAlpha(false)) . $this->PenColor() . $this->BrushColor() . $this->PenWidth());
$this->AddTag("tee:Rectangle", $this->PointToStr($r->X, $r->Y) . " " .
$this->FlexSize($r) . $this->FlexAlpha($this->CalcAlpha(false)) . $this->PenColor() . $this->BrushColor() . $this->PenWidth());
return $this->embeddedImages;
$this->embeddedImages = $value;
$this->imagePath = $value;
public function Arc($x1, $y1, $x2, $y2, $startAngle, $sweepAngle)
'x0="' . $x1 . '" y0="' . $y1 . '" ' .
'x1="' . $x2 . '" y1="' . $y2 . '" ' .
'startAngle="' . $this->FloatToStr($startAngle) .
'" endAngle="' . $this->FloatToStr($startAngle . $sweepAngle) . '" ' .
$this->FlexAlpha($this->CalcAlpha(true)) .
public function _Arc($x1, $y1, $x2, $y2, $x3, $y3, $x4, $y4)
$this->CalcArcAngles($x1, $y1, $x2, $y2, $x3, $y3, $x4, $y4, /*out*/ $start, /*out*/ $sweep);
$this->Arc((int) $x1, (int) $y1, (int) $x2, (int) $y2, (float) $start, (float) $sweep);
//throw new Exception("The method or operation is not implemented.");
public function ellipse($x1, $y1, $x2, $y2, $z= 0, $angle= 0)
// todo here draw directly the ellipse with p1 and p2 $this->ellipsePoints($p1, $p2);
// todo remove Point[] p = new Point[NUMCIRCLEPOINTS]; // : Array[0..NumCirclePoints-1] of TPoint;
for ($t = 0; $t < 3; $t++ ) {
$xCenter = ($x2 + $x1) * 0.5;
$yCenter = ($y2 + $y1) * 0.5;
$xRadius = ($x2 - $x1) * 0.5;
$yRadius = ($y2 - $y1) * 0.5;
$tmpPiStep = 2 * M_PI / (self::$NUMCIRCLEPOINTS - 1);
// initial rotation (rotation matrix elements)
$tmpSinAngle = sin($angle);
$tmpCosAngle = cos($angle);
for ($t = 0; $t < self::$NUMCIRCLEPOINTS; $t++ ) {
$tmpSin = sin($t * $tmpPiStep);
$tmpCos = cos($t * $tmpPiStep);
$tmpX = $xRadius * $tmpSin;
$tmpY = $yRadius * $tmpCos;
( - $tmpX * $tmpSinAngle +
$old = $this->getPen()->getVisible();
$this->getPen()->setVisible(false);
for ($t = 1; $t < self::$NUMCIRCLEPOINTS; $t++ ) {
// has to be in loop because the Polygon
// transforms the positions from 3d to 2d in each pass
// close it up with polygon from last to first
$points[1] = $p[self::$NUMCIRCLEPOINTS - 1];
$this->getPen()->setVisible($old);
if ($this->getPen()->getVisible()) {
// updates x,y,width,height to be used in imagefilledellipse correctly
//$x1=$x1+(($x2-$x1) / 2);
//$y1=$y1+(($y2-$y1) / 2);
$tmpWidth= ((int) $x2-(int) $x1); //*2;
$tmpHeight= ((int) $y2-(int) $y1); //*2;
/*$x1=(int)$x1+(((int)$x2-(int)$x1));
$y1=(int)$y1+(((int)$y2-(int)$y1));
$tmpWidth=((int)$x2-(int)$x1);
$tmpHeight=((int)$y2-(int)$y1);
if ($this->brush->getVisible()) {
$this->AddTag("tee:Ellipse", $this->PointToStr((int) $x1, (int) $y1) . " " . $this->FlexSizeWH((int) $tmpWidth, (int) $tmpHeight) .
$this->FlexAlpha($this->CalcAlpha(false)) . $this->BrushColor() . $this->PenColor() . $this->PenWidth());
//throw new Exception("The method or operation is not implemented.");
public function Draw($x, $y, $image)
$this->AddTag('mx:Image', $this->PointToStr($x, $y) . ' source="' . $this->ImageSource($image) . '"');
public function _Draw($destRect, $srcRect, $image, $transparent)
$this->AddTag('mx:Image', $this->PointToStr($destRect->X, $destRect->Y) . ' ' .
' scaleX="' . $this->FloatToStr($destRect->Width / $image->Width) . '" ' .
' scaleY="' . $this->FloatToStr($destRect->Height / $image->Height) + '" ' .
' source="' . $this->ImageSource($image) . '"');
public override function Polygon(params PointDouble[] $p)
$this->AddTag("tee:Polygon", $this->FlexPoints($p) . " " .
$this->FlexAlpha($this->CalcAlpha(false)) . $this->BrushColor() . $this->PenColor() .
public function Polygon(/*params* Point[]*/ $p)
$this->AddTag("tee:Polygon", $this->FlexPoints($p) . " " .
$this->FlexAlpha($this->CalcAlpha(false)) . $this->BrushColor() . $this->PenColor() .
//throw new Exception("The method or operation is not implemented.");
//throw new Exception("The method or operation is not implemented.");
//throw new Exception("The method or operation is not implemented.");
//throw new Exception("The method or operation is not implemented.");
//throw new Exception("The method or operation is not implemented.");
public function GradientFill($left, $top, $right, $bottom, $startColor, $endColor, $direction)
//throw new Exception("The method or operation is not implemented.");
public function Pixel($x, $y, $z, $color)
//throw new Exception("The method or operation is not implemented.");
$this->AddTag("tee:Polyline", $this->FlexPoints($p) . ' ' .
$this->FlexAlpha($this->CalcAlpha(true)) . $this->PenColor() . $this->PenWidth());
$this->DoText($x, $y, $text, $rotDegree, $this->Font->Color);
//throw new Exception("The method or operation is not implemented.");
//throw new Exception("The method or operation is not implemented.");
private function Pos0($x= null, $y= null)
if (($x== null) && ($y== null)) {
$result= 'x0="' . round($x) . '" y0="' . round($y) . '"';
private function Pos1($x, $y)
private function DashLenGap()
switch ($this->Pen->Style)
return ' len="' . $len . '" gap="' . $gap . '"';
public function LineTo($x, $y)
$this->AddTag("tee:Line", $this->Pos0() . " " . $this->Pos1($x, $y) .
$this->FlexAlpha($this->CalcAlpha(true)) . $this->PenColor() .
$this->AddTag("tee:DashLine", $this->Pos0() . " " . $this->Pos1($x, $y) .
$this->FlexAlpha($this->CalcAlpha(true)) . $this->PenColor() . $this->PenWidth() .
* @param integer line start (X)
* @param integer line start (Y)
* @param integer line end (X)
* @param integer line end (Y)
* @param Color line color
* @param integer line width
function line($x1, $y1, $x2, $y2, $color= null, $width = - 1)
//$color = $this->PenColor();
// Assign the pen width for the image
//$width = $this->pen->getWidth();
$this->AddTag("tee:Line", $this->Pos0($x1,$y1) . " " . $this->Pos1($x2, $y2) .
$this->FlexAlpha($this->CalcAlpha(true)) . $this->PenColor() .
$this->AddTag("tee:DashLine", $this->Pos0($x1, $y1) . " " . $this->Pos1($x2, $y2) .
$this->FlexAlpha($this->CalcAlpha(true)) . $this->PenColor() . $this->PenWidth() .
* Draws a Line between point p0 and point p1 using specific pen.
* @param pen ChartPen id the pen used
* @param p0 Point is origin xy
* @param p1 Point is destination xy
public function ___line($pen, $p0, $p1) {
$this->AddTag("tee:Line", $this->Pos0($p0->getX(),$p0->getY()) . " " . $this->Pos1($p1->getX(), $p1->getY()) .
$this->FlexAlpha($this->CalcAlpha(true)) . $this->PenColor() .
$this->AddTag("tee:DashLine", $this->Pos0($p0->getX(),$p0->getY()) . " " . $this->Pos1($p1->getX(), $p1->getY()) .
$this->FlexAlpha($this->CalcAlpha(true)) . $this->PenColor() . $this->PenWidth() .
* Draws a Line from (X,Y,Z0) to (X,Y,Z1).
public function zLine($x, $y, $z0, $z1) {
$c1 = imagecolorallocate($this->img, $this->pen->getColor()->red,
$this->pen->getColor()->green,
$this->pen->getColor()->blue);
$this->AddTag("tee:Line", $this->Pos0($p1->getX(),$p1->getY()) . " " . $this->Pos1($p2->getX(), $p2->getY()) .
$this->FlexAlpha($this->CalcAlpha(true)) . $this->PenColor() .
$this->AddTag("tee:DashLine", $this->Pos0($p1->getX(),$p1->getY()) . " " . $this->Pos1($p2->getX(), $p2->getY()) .
$this->FlexAlpha($this->CalcAlpha(true)) . $this->PenColor() . $this->PenWidth() .
* Draws a Horizontal at z depth position.
$this->AddTag("tee:Line", $this->Pos0($p1->getX(),$p1->getY()) . " " . $this->Pos1($p2->getX(), $p2->getY()) .
$this->FlexAlpha($this->CalcAlpha(true)) . $this->PenColor() .
$this->AddTag("tee:DashLine", $this->Pos0($p1->getX(),$p1->getY()) . " " . $this->Pos1($p2->getX(), $p2->getY()) .
$this->FlexAlpha($this->CalcAlpha(true)) . $this->PenColor() . $this->PenWidth() .
* Draws a Vertical Line from (X,Top) to (X,Bottom) at z depth position.
$this->AddTag("tee:Line", $this->Pos0($p1->getX(),$p1->getY()) . " " . $this->Pos1($p2->getX(), $p2->getY()) .
$this->FlexAlpha($this->CalcAlpha(true)) . $this->PenColor() .
$this->AddTag("tee:DashLine", $this->Pos0($p1->getX(),$p1->getY()) . " " . $this->Pos1($p2->getX(), $p2->getY()) .
$this->FlexAlpha($this->CalcAlpha(true)) . $this->PenColor() . $this->PenWidth() .
//throw new Exception("The method or operation is not implemented.");
//throw new Exception("The method or operation is not implemented.");
public function AddLink($x, $y, $Text, $URL, $Hint)
$this->AddTag('mx:LinkButton', 'label="' . $Text . '" ' . $this->PointToStr($x, $y) .
' toolTip="' . $Hint . '" ' .
$this->FlexFont($this->Font) .
'click="navigateToURL(new URLRequest("' . $URL . "'), '" . $Hint . '")"');
|