/** * This function draw a filled cubic curve */ function drawFilledCubicCurve(pData $data, $Accuracy = 0.1, $Alpha = 100, $AroundZero = FALSE) { /* Validate the Data and DataDescription array */ $this->validateDataDescription("drawFilledCubicCurve", $data->getDataDescription()); $this->validateData("drawFilledCubicCurve", $data->getData()); $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 ($data->getDataDescription()->values as $ColName) { $XIn = array(); $YIn = array(); $Yt = array(); $U = array(); $ColorID = $data->getDataDescription()->getColumnIndex($ColName); $numElements = 1; $XLast = -1; $Missing = array(); $data->getXYMap($ColName, $XIn, $YIn, $Missing, $numElements); $Yt[0] = 0; $Yt[1] = 0; $U[1] = 0; $this->calculateCubicCurve($Yt, $XIn, $YIn, $U, $numElements); $Yt[$numElements] = 0; for ($k = $numElements - 1; $k >= 1; $k--) { $Yt[$k] = $Yt[$k] * $Yt[$k + 1] + $U[$k]; } $Points = ""; $Points[] = $this->GAreaXOffset + $this->GArea_X1; $Points[] = $LayerHeight + $this->GArea_Y1; $YLast = NULL; $XPos = $this->GAreaXOffset; $PointsCount = 2; for ($X = 1; $X <= $numElements; $X = $X + $Accuracy) { $klo = 1; $khi = $numElements; $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 + $this->GArea_X1; $aPoints[] = min($YLast + $this->GArea_Y1, $this->GArea_Y2); $aPoints[] = $XPos + $this->GArea_X1; $aPoints[] = min($YPos + $this->GArea_Y1, $this->GArea_Y2); $aPoints[] = $XPos + $this->GArea_X1; $aPoints[] = $YZero + $this->GArea_Y1; $aPoints[] = $XLast + $this->GArea_X1; $aPoints[] = $YZero + $this->GArea_Y1; $this->canvas->drawFilledPolygon($aPoints, 4, $this->palette->getColor($ColorID), $alpha); } if (!isset($Missing[floor($X)]) || $YLast == NULL) { $PointsCount++; $Points[] = $XPos + $this->GArea_X1; $Points[] = min($YPos + $this->GArea_Y1, $this->GArea_Y2); } else { $PointsCount++; $Points[] = $XLast + $this->GArea_X1; $Points[] = min($LayerHeight + $this->GArea_Y1, $this->GArea_Y2); } $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[$numElements] - $this->VMin) * $this->DivisionRatio; if ($YLast != NULL && $AroundZero) { $aPoints = ""; $aPoints[] = $XLast + $this->GArea_X1; $aPoints[] = max($YLast + $this->GArea_Y1, $this->GArea_Y1); $aPoints[] = $LayerWidth - $this->GAreaXOffset + $this->GArea_X1; $aPoints[] = max($YPos + $this->GArea_Y1, $this->GArea_Y1); $aPoints[] = $LayerWidth - $this->GAreaXOffset + $this->GArea_X1; $aPoints[] = max($YZero + $this->GArea_Y1, $this->GArea_Y1); $aPoints[] = $XLast + $this->GArea_X1; $aPoints[] = max($YZero + $this->GArea_Y1, $this->GArea_Y1); $this->canvas->drawFilledPolygon($aPoints, 4, $this->palette->getColor($ColorID), $alpha); } if ($YIn[$klo] != "" && $YIn[$khi] != "" || $YLast == NULL) { $PointsCount++; $Points[] = $LayerWidth - $this->GAreaXOffset + $this->GArea_X1; $Points[] = $YPos + $this->GArea_Y1; } } $Points[] = $LayerWidth - $this->GAreaXOffset + $this->GArea_X1; $Points[] = $LayerHeight + $this->GArea_Y1; if (!$AroundZero) { $this->canvas->drawFilledPolygon($Points, $PointsCount, $this->palette->getColor($ColorID), $Alpha); } $this->drawCubicCurve($data, $Accuracy, $ColName); $GraphID++; } }
/** * Check that if our data set contains non-numeric data, it will * add they keys to the $missing array */ public function testGetXYMapMissing() { $data = new pData(); $data->addPoints(array(2, 3, 4, 'apple', 5, 'banana'), 'series1'); $data->addPoints(array(3, 4, 5, 6, 7), 'series2'); $xIn = array(); $yIn = array(); $missing = array(); $data->getXYMap('series1', $xIn, $yIn, $missing, $index); $this->assertEquals(6, $index); $this->assertEquals(array(4 => true, 6 => true), $missing); }