You are here

function pChart::drawFilledCubicCurve in Visitors 7.0

Same name and namespace in other branches
  1. 8 pchart/pChart.inc \pChart::drawFilledCubicCurve()

File

pchart/pChart.inc, line 1015

Class

pChart

Code

function drawFilledCubicCurve(&$Data, &$DataDescription, $Accuracy = 0.1, $Alpha = 100, $AroundZero = FALSE) {

  /* Validate the Data and DataDescription array */
  $this
    ->validateDataDescription("drawFilledCubicCurve", $DataDescription);
  $this
    ->validateData("drawFilledCubicCurve", $Data);
  $LayerWidth = $this->GArea_X2 - $this->GArea_X1;
  $LayerHeight = $this->GArea_Y2 - $this->GArea_Y1;
  $YZero = $LayerHeight - (0 - $this->VMin) * $this->DivisionRatio;
  if ($YZero > $LayerHeight) {
    $YZero = $LayerHeight;
  }
  $GraphID = 0;
  foreach ($DataDescription["Values"] as $Key2 => $ColName) {
    $XIn = "";
    $Yin = "";
    $Yt = "";
    $U = "";
    $XIn[0] = 0;
    $YIn[0] = 0;
    $ID = 0;
    foreach ($DataDescription["Description"] as $keyI => $ValueI) {
      if ($keyI == $ColName) {
        $ColorID = $ID;
      }
      $ID++;
    }
    $Index = 1;
    $XLast = -1;
    $Missing = "";
    foreach ($Data as $Key => $Values) {
      $Value = $Data[$Key][$ColName];
      $XIn[$Index] = $Index;
      $YIn[$Index] = $Value;
      if (!is_numeric($Value)) {
        $Missing[$Index] = TRUE;
      }
      $Index++;
    }
    $Index--;
    $Yt[0] = 0;
    $Yt[1] = 0;
    $U[1] = 0;
    for ($i = 2; $i <= $Index - 1; $i++) {
      $Sig = ($XIn[$i] - $XIn[$i - 1]) / ($XIn[$i + 1] - $XIn[$i - 1]);
      $p = $Sig * $Yt[$i - 1] + 2;
      $Yt[$i] = ($Sig - 1) / $p;
      $U[$i] = ($YIn[$i + 1] - $YIn[$i]) / ($XIn[$i + 1] - $XIn[$i]) - ($YIn[$i] - $YIn[$i - 1]) / ($XIn[$i] - $XIn[$i - 1]);
      $U[$i] = (6 * $U[$i] / ($XIn[$i + 1] - $XIn[$i - 1]) - $Sig * $U[$i - 1]) / $p;
    }
    $qn = 0;
    $un = 0;
    $Yt[$Index] = ($un - $qn * $U[$Index - 1]) / ($qn * $Yt[$Index - 1] + 1);
    for ($k = $Index - 1; $k >= 1; $k--) {
      $Yt[$k] = $Yt[$k] * $Yt[$k + 1] + $U[$k];
    }
    $Points = "";
    $Points[] = $this->GAreaXOffset;
    $Points[] = $LayerHeight;
    $this->Layers[0] = imagecreatetruecolor($LayerWidth, $LayerHeight);
    $C_White = imagecolorallocate($this->Layers[0], 255, 255, 255);
    imagefilledrectangle($this->Layers[0], 0, 0, $LayerWidth, $LayerHeight, $C_White);
    imagecolortransparent($this->Layers[0], $C_White);
    $YLast = NULL;
    $XPos = $this->GAreaXOffset;
    $PointsCount = 2;
    for ($X = 1; $X <= $Index; $X = $X + $Accuracy) {
      $klo = 1;
      $khi = $Index;
      $k = $khi - $klo;
      while ($k > 1) {
        $k = $khi - $klo;
        if ($XIn[$k] >= $X) {
          $khi = $k;
        }
        else {
          $klo = $k;
        }
      }
      $klo = $khi - 1;
      $h = $XIn[$khi] - $XIn[$klo];
      $a = ($XIn[$khi] - $X) / $h;
      $b = ($X - $XIn[$klo]) / $h;
      $Value = $a * $YIn[$klo] + $b * $YIn[$khi] + (($a * $a * $a - $a) * $Yt[$klo] + ($b * $b * $b - $b) * $Yt[$khi]) * ($h * $h) / 6;
      $YPos = $LayerHeight - ($Value - $this->VMin) * $this->DivisionRatio;
      if ($YLast != NULL && $AroundZero && !isset($Missing[floor($X)]) && !isset($Missing[floor($X + 1)])) {
        $aPoints = "";
        $aPoints[] = $XLast;
        $aPoints[] = $YLast;
        $aPoints[] = $XPos;
        $aPoints[] = $YPos;
        $aPoints[] = $XPos;
        $aPoints[] = $YZero;
        $aPoints[] = $XLast;
        $aPoints[] = $YZero;
        $C_Graph = imagecolorallocate($this->Layers[0], $this->Palette[$ColorID]["R"], $this->Palette[$ColorID]["G"], $this->Palette[$ColorID]["B"]);
        imagefilledpolygon($this->Layers[0], $aPoints, 4, $C_Graph);
      }
      if (!isset($Missing[floor($X)]) || $YLast == NULL) {
        $PointsCount++;
        $Points[] = $XPos;
        $Points[] = $YPos;
      }
      else {
        $PointsCount++;
        $Points[] = $XLast;
        $Points[] = $LayerHeight;
      }
      $YLast = $YPos;
      $XLast = $XPos;
      $XPos = $XPos + $this->DivisionWidth * $Accuracy;
    }

    // Add potentialy missing values
    $XPos = $XPos - $this->DivisionWidth * $Accuracy;
    if ($XPos < $LayerWidth - $this->GAreaXOffset) {
      $YPos = $LayerHeight - ($YIn[$Index] - $this->VMin) * $this->DivisionRatio;
      if ($YLast != NULL && $AroundZero) {
        $aPoints = "";
        $aPoints[] = $XLast;
        $aPoints[] = $YLast;
        $aPoints[] = $LayerWidth - $this->GAreaXOffset;
        $aPoints[] = $YPos;
        $aPoints[] = $LayerWidth - $this->GAreaXOffset;
        $aPoints[] = $YZero;
        $aPoints[] = $XLast;
        $aPoints[] = $YZero;
        $C_Graph = imagecolorallocate($this->Layers[0], $this->Palette[$ColorID]["R"], $this->Palette[$ColorID]["G"], $this->Palette[$ColorID]["B"]);
        imagefilledpolygon($this->Layers[0], $aPoints, 4, $C_Graph);
      }
      if ($YIn[$klo] != "" && $YIn[$khi] != "" || $YLast == NULL) {
        $PointsCount++;
        $Points[] = $LayerWidth - $this->GAreaXOffset;
        $Points[] = $YPos;
      }
    }
    $Points[] = $LayerWidth - $this->GAreaXOffset;
    $Points[] = $LayerHeight;
    if (!$AroundZero) {
      $C_Graph = imagecolorallocate($this->Layers[0], $this->Palette[$ColorID]["R"], $this->Palette[$ColorID]["G"], $this->Palette[$ColorID]["B"]);
      imagefilledpolygon($this->Layers[0], $Points, $PointsCount, $C_Graph);
    }
    imagecopymerge($this->Picture, $this->Layers[0], $this->GArea_X1, $this->GArea_Y1, 0, 0, $LayerWidth, $LayerHeight, $Alpha);
    imagedestroy($this->Layers[0]);
    $this
      ->drawCubicCurve($Data, $DataDescription, $Accuracy, $ColName);
    $GraphID++;
  }
}