function pDraw::drawStackedBarChart

5.x pDraw.class.php pDraw::drawStackedBarChart($Format = NULL)

File

inc/pchart/pchart/class/pDraw.class.php, line 4775

Class

pDraw

Code

function drawStackedBarChart($Format = NULL) 
 {
  $DisplayValues = isset($Format ["DisplayValues"]) ? $Format ["DisplayValues"] : FALSE;
  $DisplayOrientation = isset($Format ["DisplayOrientation"]) ? $Format ["DisplayOrientation"] : ORIENTATION_AUTO;
  $DisplayRound = isset($Format ["DisplayRound"]) ? $Format ["DisplayRound"] : 0;
  $DisplayColor = isset($Format ["DisplayColor"]) ? $Format ["DisplayColor"] : DISPLAY_MANUAL;
  $DisplayFont = isset($Format ["DisplayFont"]) ? $Format ["DisplayFont"] : $this->FontName;
  $DisplaySize = isset($Format ["DisplaySize"]) ? $Format ["DisplaySize"] : $this->FontSize;
  $DisplayR = isset($Format ["DisplayR"]) ? $Format ["DisplayR"] : 0;
  $DisplayG = isset($Format ["DisplayG"]) ? $Format ["DisplayG"] : 0;
  $DisplayB = isset($Format ["DisplayB"]) ? $Format ["DisplayB"] : 0;
  $Interleave = isset($Format ["Interleave"]) ? $Format ["Interleave"] : .5;
  $Rounded = isset($Format ["Rounded"]) ? $Format ["Rounded"] : FALSE;
  $RoundRadius = isset($Format ["RoundRadius"]) ? $Format ["RoundRadius"] : 4;
  $Surrounding = isset($Format ["Surrounding"]) ? $Format ["Surrounding"] : NULL;
  $BorderR = isset($Format ["BorderR"]) ? $Format ["BorderR"] : -1;
  $BorderG = isset($Format ["BorderG"]) ? $Format ["BorderG"] : -1;
  $BorderB = isset($Format ["BorderB"]) ? $Format ["BorderB"] : -1;
  $Gradient = isset($Format ["Gradient"]) ? $Format ["Gradient"] : FALSE;
  $GradientMode = isset($Format ["GradientMode"]) ? $Format ["GradientMode"] : GRADIENT_SIMPLE;
  $GradientAlpha = isset($Format ["GradientAlpha"]) ? $Format ["GradientAlpha"] : 20;
  $GradientStartR = isset($Format ["GradientStartR"]) ? $Format ["GradientStartR"] : 255;
  $GradientStartG = isset($Format ["GradientStartG"]) ? $Format ["GradientStartG"] : 255;
  $GradientStartB = isset($Format ["GradientStartB"]) ? $Format ["GradientStartB"] : 255;
  $GradientEndR = isset($Format ["GradientEndR"]) ? $Format ["GradientEndR"] : 0;
  $GradientEndG = isset($Format ["GradientEndG"]) ? $Format ["GradientEndG"] : 0;
  $GradientEndB = isset($Format ["GradientEndB"]) ? $Format ["GradientEndB"] : 0;
  $InnerSurrounding = isset($Format ["InnerSurrounding"]) ? $Format ["InnerSurrounding"] : NULL;
  $InnerBorderR = isset($Format ["InnerBorderR"]) ? $Format ["InnerBorderR"] : -1;
  $InnerBorderG = isset($Format ["InnerBorderG"]) ? $Format ["InnerBorderG"] : -1;
  $InnerBorderB = isset($Format ["InnerBorderB"]) ? $Format ["InnerBorderB"] : -1;
  $RecordImageMap = isset($Format ["RecordImageMap"]) ? $Format ["RecordImageMap"] : FALSE;
  $FontFactor = isset($Format ["FontFactor"]) ? $Format ["FontFactor"] : 8;

  $this->LastChartLayout = CHART_LAST_LAYOUT_STACKED;

  $Data = $this->DataSet->getData();
  list($XMargin, $XDivs) = $this->scaleGetXSettings();

  $RestoreShadow = $this->Shadow;

  $LastX = "";
  $LastY = "";
  foreach ($Data ["Series"] as $SerieName => $Serie) 
   {
    if ($Serie ["isDrawable"] == TRUE && $SerieName != $Data ["Abscissa"]) 
     {
      $R = $Serie ["Color"]["R"];
      $G = $Serie ["Color"]["G"];
      $B = $Serie ["Color"]["B"];
      $Alpha = $Serie ["Color"]["Alpha"];
      $Ticks = $Serie ["Ticks"];
      if ($DisplayColor == DISPLAY_AUTO) {
        $DisplayR = 255;
        $DisplayG = 255;
        $DisplayB = 255;
      }
      if ($Surrounding != NULL) {
        $BorderR = $R + $Surrounding;
        $BorderG = $G + $Surrounding;
        $BorderB = $B + $Surrounding;
      }
      if ($InnerSurrounding != NULL) {
        $InnerBorderR = $R + $InnerSurrounding;
        $InnerBorderG = $G + $InnerSurrounding;
        $InnerBorderB = $B + $InnerSurrounding;
      }
      if ($InnerBorderR == -1) {
        $InnerColor = NULL;
      }
      else {
        $InnerColor = array("R" => $InnerBorderR, "G" => $InnerBorderG, "B" => $InnerBorderB);
      }

      $AxisID = $Serie ["Axis"];
      $Mode = $Data ["Axis"][$AxisID]["Display"];
      $Format = $Data ["Axis"][$AxisID]["Format"];
      $Unit = $Data ["Axis"][$AxisID]["Unit"];

      if (isset($Serie ["Description"])) {
        $SerieDescription = $Serie ["Description"];
      }
      else {
        $SerieDescription = $SerieName;
      }

      $PosArray = $this->scaleComputeY($Serie ["Data"], array("AxisID" => $Serie ["Axis"]), TRUE);
      $YZero = $this->scaleComputeY(0, array("AxisID" => $Serie ["Axis"]));

      $this->DataSet->Data ["Series"][$SerieName]["XOffset"] = 0;

      $Color = array("TransCorner" => TRUE, "R" => $R, "G" => $G, "B" => $B, "Alpha" => $Alpha, "BorderR" => $BorderR, "BorderG" => $BorderG, "BorderB" => $BorderB);

      if ($Data ["Orientation"] == SCALE_POS_LEFTRIGHT) 
       {
        if ($YZero > $this->GraphAreaY2 -1) {
          $YZero = $this->GraphAreaY2 -1;
        }
        if ($YZero > $this->GraphAreaY2 -1) {
          $YZero = $this->GraphAreaY2 -1;
        }

        if ($XDivs == 0) {
          $XStep = ($this->GraphAreaX2 -$this->GraphAreaX1) / 4;
        }
        else {
          $XStep = ($this->GraphAreaX2 -$this->GraphAreaX1 -$XMargin * 2) / $XDivs;
        }
        $X = $this->GraphAreaX1 + $XMargin;

        $XSize = ($XStep / (1 + $Interleave));
        $XOffset = -($XSize / 2);

        if (!is_array($PosArray)) {
          $Value = $PosArray;
          $PosArray = "";
          $PosArray [0] = $Value;
        }
        foreach ($PosArray as $Key => $Height) 
         {
          if ($Height != VOID && $Serie ["Data"][$Key] != 0) 
           {
            if ($Serie ["Data"][$Key] > 0) {
              $Pos = "+";
            }
            else {
              $Pos = "-";
            }

            if (!isset($LastY [$Key])) {
              $LastY [$Key] = "";
            }
            if (!isset($LastY [$Key][$Pos])) {
              $LastY [$Key][$Pos] = $YZero;
            }

            $Y1 = $LastY [$Key][$Pos];
            $Y2 = $Y1 - $Height;

            if (($Rounded || $BorderR != -1) && ($Pos == "+" && $Y1 != $YZero)) {
              $YSpaceUp = 1;
            }
            else {
              $YSpaceUp = 0;
            }
            if (($Rounded || $BorderR != -1) && ($Pos == "-" && $Y1 != $YZero)) {
              $YSpaceDown = 1;
            }
            else {
              $YSpaceDown = 0;
            }

            if ($RecordImageMap) {
              $this->addToImageMap("RECT", floor($X + $XOffset) . "," . floor($Y1 -$YSpaceUp + $YSpaceDown) . "," . floor($X + $XOffset + $XSize) . "," . floor($Y2), $this->toHTMLColor($R, $G, $B), $SerieDescription, $this->scaleFormat($Serie ["Data"][$Key], $Mode, $Format, $Unit));
            }

            if ($Rounded) {
              $this->drawRoundedFilledRectangle($X + $XOffset, $Y1 -$YSpaceUp + $YSpaceDown, $X + $XOffset + $XSize, $Y2, $RoundRadius, $Color);
            }
            else 
             {
              $this->drawFilledRectangle($X + $XOffset, $Y1 -$YSpaceUp + $YSpaceDown, $X + $XOffset + $XSize, $Y2, $Color);

              if ($InnerColor != NULL) {
                $RestoreShadow = $this->Shadow;
                $this->Shadow = FALSE;
                $this->drawRectangle(min($X + $XOffset + 1, $X + $XOffset + $XSize), min($Y1 -$YSpaceUp + $YSpaceDown, $Y2) + 1, max($X + $XOffset + 1, $X + $XOffset + $XSize) -1, max($Y1 -$YSpaceUp + $YSpaceDown, $Y2) -1, $InnerColor);
                $this->Shadow = $RestoreShadow;
              }

              if ($Gradient) 
               {
                $this->Shadow = FALSE;

                if ($GradientMode == GRADIENT_SIMPLE) 
                 {
                  $GradientColor = array("StartR" => $GradientStartR, "StartG" => $GradientStartG, "StartB" => $GradientStartB, "EndR" => $GradientEndR, "EndG" => $GradientEndG, "EndB" => $GradientEndB, "Alpha" => $GradientAlpha);
                  $this->drawGradientArea($X + $XOffset, $Y1 -1 -$YSpaceUp + $YSpaceDown, $X + $XOffset + $XSize, $Y2 + 1, DIRECTION_VERTICAL, $GradientColor);
                }
                elseif ($GradientMode == GRADIENT_EFFECT_CAN) 
                 {
                  $GradientColor1 = array("StartR" => $GradientEndR, "StartG" => $GradientEndG, "StartB" => $GradientEndB, "EndR" => $GradientStartR, "EndG" => $GradientStartG, "EndB" => $GradientStartB, "Alpha" => $GradientAlpha);
                  $GradientColor2 = array("StartR" => $GradientStartR, "StartG" => $GradientStartG, "StartB" => $GradientStartB, "EndR" => $GradientEndR, "EndG" => $GradientEndG, "EndB" => $GradientEndB, "Alpha" => $GradientAlpha);
                  $XSpan = floor($XSize / 3);

                  $this->drawGradientArea($X + $XOffset -.5, $Y1 -.5 -$YSpaceUp + $YSpaceDown, $X + $XOffset + $XSpan, $Y2 + .5, DIRECTION_HORIZONTAL, $GradientColor1);
                  $this->drawGradientArea($X + $XSpan + $XOffset -.5, $Y1 -.5 -$YSpaceUp + $YSpaceDown, $X + $XOffset + $XSize, $Y2 + .5, DIRECTION_HORIZONTAL, $GradientColor2);
                }
                $this->Shadow = $RestoreShadow;
              }
            }

            if ($DisplayValues) 
             {
              $BarHeight = abs($Y2 -$Y1) -2;
              $BarWidth = $XSize + ($XOffset / 2) -$FontFactor;

              $Caption = $this->scaleFormat(round($Serie ["Data"][$Key], $DisplayRound), $Mode, $Format, $Unit);
              $TxtPos = $this->getTextBox(0, 0, $DisplayFont, $DisplaySize, 0, $Caption);
              $TxtHeight = abs($TxtPos [2]["Y"] - $TxtPos [0]["Y"]);
              $TxtWidth = abs($TxtPos [1]["X"] - $TxtPos [0]["X"]);

              $XCenter = (($X + $XOffset + $XSize) - ($X + $XOffset)) / 2 + $X + $XOffset;
              $YCenter = (($Y2) - ($Y1 -$YSpaceUp + $YSpaceDown)) / 2 + $Y1 -$YSpaceUp + $YSpaceDown;

              $Done = FALSE;
              if ($DisplayOrientation == ORIENTATION_HORIZONTAL || $DisplayOrientation == ORIENTATION_AUTO) 
               {
                if ($TxtHeight < $BarHeight && $TxtWidth < $BarWidth) 
                 {
                  $this->drawText($XCenter, $YCenter, $this->scaleFormat($Serie ["Data"][$Key], $Mode, $Format, $Unit), array("R" => $DisplayR, "G" => $DisplayG, "B" => $DisplayB, "Align" => TEXT_ALIGN_MIDDLEMIDDLE, "FontSize" => $DisplaySize, "FontName" => $DisplayFont));
                  $Done = TRUE;
                }
              }

              if ($DisplayOrientation == ORIENTATION_VERTICAL || ($DisplayOrientation == ORIENTATION_AUTO && !$Done)) 
               {
                if ($TxtHeight < $BarWidth && $TxtWidth < $BarHeight) {
                  $this->drawText($XCenter, $YCenter, $this->scaleFormat($Serie ["Data"][$Key], $Mode, $Format, $Unit), array("R" => $DisplayR, "G" => $DisplayG, "B" => $DisplayB, "Angle" => 90, "Align" => TEXT_ALIGN_MIDDLEMIDDLE, "FontSize" => $DisplaySize, "FontName" => $DisplayFont));
                }
              }
            }

            $LastY [$Key][$Pos] = $Y2;
          }

          $X = $X + $XStep;
        }
      }
      else 
       {
        if ($YZero < $this->GraphAreaX1 + 1) {
          $YZero = $this->GraphAreaX1 + 1;
        }
        if ($YZero > $this->GraphAreaX2 -1) {
          $YZero = $this->GraphAreaX2 -1;
        }

        if ($XDivs == 0) {
          $YStep = ($this->GraphAreaY2 -$this->GraphAreaY1) / 4;
        }
        else {
          $YStep = ($this->GraphAreaY2 -$this->GraphAreaY1 -$XMargin * 2) / $XDivs;
        }
        $Y = $this->GraphAreaY1 + $XMargin;

        $YSize = $YStep / (1 + $Interleave);
        $YOffset = -($YSize / 2);

        if (!is_array($PosArray)) {
          $Value = $PosArray;
          $PosArray = "";
          $PosArray [0] = $Value;
        }
        foreach ($PosArray as $Key => $Width) 
         {
          if ($Width != VOID && $Serie ["Data"][$Key] != 0) 
           {
            if ($Serie ["Data"][$Key] > 0) {
              $Pos = "+";
            }
            else {
              $Pos = "-";
            }

            if (!isset($LastX [$Key])) {
              $LastX [$Key] = "";
            }
            if (!isset($LastX [$Key][$Pos])) {
              $LastX [$Key][$Pos] = $YZero;
            }

            $X1 = $LastX [$Key][$Pos];
            $X2 = $X1 + $Width;

            if (($Rounded || $BorderR != -1) && ($Pos == "+" && $X1 != $YZero)) {
              $XSpaceLeft = 2;
            }
            else {
              $XSpaceLeft = 0;
            }
            if (($Rounded || $BorderR != -1) && ($Pos == "-" && $X1 != $YZero)) {
              $XSpaceRight = 2;
            }
            else {
              $XSpaceRight = 0;
            }

            if ($RecordImageMap) {
              $this->addToImageMap("RECT", floor($X1 + $XSpaceLeft) . "," . floor($Y + $YOffset) . "," . floor($X2 -$XSpaceRight) . "," . floor($Y + $YOffset + $YSize), $this->toHTMLColor($R, $G, $B), $SerieDescription, $this->scaleFormat($Serie ["Data"][$Key], $Mode, $Format, $Unit));
            }

            if ($Rounded) {
              $this->drawRoundedFilledRectangle($X1 + $XSpaceLeft, $Y + $YOffset, $X2 -$XSpaceRight, $Y + $YOffset + $YSize, $RoundRadius, $Color);
            }
            else 
             {
              $this->drawFilledRectangle($X1 + $XSpaceLeft, $Y + $YOffset, $X2 -$XSpaceRight, $Y + $YOffset + $YSize, $Color);

              if ($InnerColor != NULL) {
                $RestoreShadow = $this->Shadow;
                $this->Shadow = FALSE;
                $this->drawRectangle(min($X1 + $XSpaceLeft, $X2 -$XSpaceRight) + 1, min($Y + $YOffset, $Y + $YOffset + $YSize) + 1, max($X1 + $XSpaceLeft, $X2 -$XSpaceRight) -1, max($Y + $YOffset, $Y + $YOffset + $YSize) -1, $InnerColor);
                $this->Shadow = $RestoreShadow;
              }

              if ($Gradient) 
               {
                $this->Shadow = FALSE;

                if ($GradientMode == GRADIENT_SIMPLE) 
                 {
                  $GradientColor = array("StartR" => $GradientStartR, "StartG" => $GradientStartG, "StartB" => $GradientStartB, "EndR" => $GradientEndR, "EndG" => $GradientEndG, "EndB" => $GradientEndB, "Alpha" => $GradientAlpha);
                  $this->drawGradientArea($X1 + $XSpaceLeft, $Y + $YOffset, $X2 -$XSpaceRight, $Y + $YOffset + $YSize, DIRECTION_HORIZONTAL, $GradientColor);
                }
                elseif ($GradientMode == GRADIENT_EFFECT_CAN) 
                 {
                  $GradientColor1 = array("StartR" => $GradientEndR, "StartG" => $GradientEndG, "StartB" => $GradientEndB, "EndR" => $GradientStartR, "EndG" => $GradientStartG, "EndB" => $GradientStartB, "Alpha" => $GradientAlpha);
                  $GradientColor2 = array("StartR" => $GradientStartR, "StartG" => $GradientStartG, "StartB" => $GradientStartB, "EndR" => $GradientEndR, "EndG" => $GradientEndG, "EndB" => $GradientEndB, "Alpha" => $GradientAlpha);
                  $YSpan = floor($YSize / 3);

                  $this->drawGradientArea($X1 + $XSpaceLeft, $Y + $YOffset, $X2 -$XSpaceRight, $Y + $YOffset + $YSpan, DIRECTION_VERTICAL, $GradientColor1);
                  $this->drawGradientArea($X1 + $XSpaceLeft, $Y + $YOffset + $YSpan, $X2 -$XSpaceRight, $Y + $YOffset + $YSize, DIRECTION_VERTICAL, $GradientColor2);
                }
                $this->Shadow = $RestoreShadow;
              }
            }

            if ($DisplayValues) 
             {
              $BarWidth = abs($X2 -$X1) -$FontFactor;
              $BarHeight = $YSize + ($YOffset / 2) -$FontFactor / 2;
              $Caption = $this->scaleFormat(round($Serie ["Data"][$Key], $DisplayRound), $Mode, $Format, $Unit);
              $TxtPos = $this->getTextBox(0, 0, $DisplayFont, $DisplaySize, 0, $Caption);
              $TxtHeight = abs($TxtPos [2]["Y"] - $TxtPos [0]["Y"]);
              $TxtWidth = abs($TxtPos [1]["X"] - $TxtPos [0]["X"]);

              $XCenter = ($X2 - $X1) / 2 + $X1;
              $YCenter = (($Y + $YOffset + $YSize) - ($Y + $YOffset)) / 2 + $Y + $YOffset;

              $Done = FALSE;
              if ($DisplayOrientation == ORIENTATION_HORIZONTAL || $DisplayOrientation == ORIENTATION_AUTO) 
               {
                if ($TxtHeight < $BarHeight && $TxtWidth < $BarWidth) 
                 {
                  $this->drawText($XCenter, $YCenter, $this->scaleFormat($Serie ["Data"][$Key], $Mode, $Format, $Unit), array("R" => $DisplayR, "G" => $DisplayG, "B" => $DisplayB, "Align" => TEXT_ALIGN_MIDDLEMIDDLE, "FontSize" => $DisplaySize, "FontName" => $DisplayFont));
                  $Done = TRUE;
                }
              }

              if ($DisplayOrientation == ORIENTATION_VERTICAL || ($DisplayOrientation == ORIENTATION_AUTO && !$Done)) 
               {
                if ($TxtHeight < $BarWidth && $TxtWidth < $BarHeight) {
                  $this->drawText($XCenter, $YCenter, $this->scaleFormat($Serie ["Data"][$Key], $Mode, $Format, $Unit), array("R" => $DisplayR, "G" => $DisplayG, "B" => $DisplayB, "Angle" => 90, "Align" => TEXT_ALIGN_MIDDLEMIDDLE, "FontSize" => $DisplaySize, "FontName" => $DisplayFont));
                }
              }
            }

            $LastX [$Key][$Pos] = $X2;
          }

          $Y = $Y + $YStep;
        }
      }
    }
  }
}