'Evolution', self::GRAPH_TYPE_VERTICAL_BAR => 'VerticalBar', self::GRAPH_TYPE_HORIZONTAL_BAR => 'HorizontalBar', self::GRAPH_TYPE_BASIC_PIE => 'Pie', self::GRAPH_TYPE_3D_PIE => 'Pie3D', ); const ABSCISSA_SERIE_NAME = 'ABSCISSA'; private $aliasedGraph; /** * @var pImage */ protected $pImage; /** * @var pData */ protected $pData; protected $ordinateLabels; protected $showLegend; protected $abscissaSeries; protected $abscissaLogos; protected $ordinateSeries; protected $ordinateLogos; protected $colors; protected $font; protected $fontSize; protected $textColor; protected $backgroundColor; protected $gridColor; protected $legendFontSize; protected $width; protected $height; protected $forceSkippedLabels = false; abstract protected function getDefaultColors(); abstract public function renderGraph(); /** * Return the StaticGraph according to the static graph type $graphType * * @throws Exception If the static graph type is unknown * @param string $graphType * @return \Piwik\Plugins\ImageGraph\StaticGraph */ public static function factory($graphType) { if (isset(self::$availableStaticGraphTypes[$graphType])) { $className = self::$availableStaticGraphTypes[$graphType]; $className = __NAMESPACE__ . "\\StaticGraph\\" . $className; Loader::loadClass($className); return new $className; } else { throw new Exception( Piwik::translate( 'General_ExceptionInvalidStaticGraphType', array($graphType, implode(', ', self::getAvailableStaticGraphTypes())) ) ); } } public static function getAvailableStaticGraphTypes() { return array_keys(self::$availableStaticGraphTypes); } /** * Save rendering to disk * * @param string $filename without path * @return string path of file */ public function sendToDisk($filename) { $filePath = self::getOutputPath($filename); $this->pImage->Render($filePath); return $filePath; } /** * @return resource rendered static graph */ public function getRenderedImage() { return $this->pImage->Picture; } /** * Output rendering to browser */ public function sendToBrowser() { $this->pImage->stroke(); } public function setWidth($width) { $this->width = $width; } public function setHeight($height) { $this->height = $height; } public function setFontSize($fontSize) { if (!is_numeric($fontSize)) { $fontSize = API::DEFAULT_FONT_SIZE; } $this->fontSize = $fontSize; } public function setLegendFontSize($legendFontSize) { $this->legendFontSize = $legendFontSize; } public function setFont($font) { $this->font = $font; } public function setTextColor($textColor) { $this->textColor = self::hex2rgb($textColor); } public function setBackgroundColor($backgroundColor) { $this->backgroundColor = self::hex2rgb($backgroundColor); } public function setGridColor($gridColor) { $this->gridColor = self::hex2rgb($gridColor); } public function setOrdinateSeries($ordinateSeries) { $this->ordinateSeries = $ordinateSeries; } public function setOrdinateLogos($ordinateLogos) { $this->ordinateLogos = $ordinateLogos; } public function setAbscissaLogos($abscissaLogos) { $this->abscissaLogos = $abscissaLogos; } public function setAbscissaSeries($abscissaSeries) { $this->abscissaSeries = $abscissaSeries; } public function setShowLegend($showLegend) { $this->showLegend = $showLegend; } public function setForceSkippedLabels($forceSkippedLabels) { $this->forceSkippedLabels = $forceSkippedLabels; } public function setOrdinateLabels($ordinateLabels) { $this->ordinateLabels = $ordinateLabels; } public function setAliasedGraph($aliasedGraph) { $this->aliasedGraph = $aliasedGraph; } public function setColors($colors) { $i = 0; foreach ($this->getDefaultColors() as $colorKey => $defaultColor) { if (isset($colors[$i]) && $this->hex2rgb($colors[$i])) { $hexColor = $colors[$i]; } else { $hexColor = $defaultColor; } $this->colors[$colorKey] = $this->hex2rgb($hexColor); $i++; } } /** * Return $filename with temp directory and delete file * * @static * @param $filename * @return string path of file in temp directory */ protected static function getOutputPath($filename) { $outputFilename = PIWIK_USER_PATH . '/tmp/assets/' . $filename; $outputFilename = SettingsPiwik::rewriteTmpPathWithHostname($outputFilename); @chmod($outputFilename, 0600); @unlink($outputFilename); return $outputFilename; } protected function initpData() { $this->pData = new pData(); foreach ($this->ordinateSeries as $column => $data) { $this->pData->addPoints($data, $column); $this->pData->setSerieDescription($column, $this->ordinateLabels[$column]); if (isset($this->ordinateLogos[$column])) { $ordinateLogo = $this->ordinateLogos[$column]; $this->pData->setSeriePicture($column, $ordinateLogo); } } $this->pData->addPoints($this->abscissaSeries, self::ABSCISSA_SERIE_NAME); $this->pData->setAbscissa(self::ABSCISSA_SERIE_NAME); } protected function initpImage() { $this->pImage = new pImage($this->width, $this->height, $this->pData); $this->pImage->Antialias = $this->aliasedGraph; $this->pImage->setFontProperties( array_merge( array( 'FontName' => $this->font, 'FontSize' => $this->fontSize, ), $this->textColor ) ); } protected function getTextWidthHeight($text, $fontSize = false) { if (!$fontSize) { $fontSize = $this->fontSize; } if (!$this->pImage) { $this->initpImage(); } // could not find a way to get pixel perfect width & height info using imageftbbox $textInfo = $this->pImage->drawText( 0, 0, $text, array( 'Alpha' => 0, 'FontSize' => $fontSize, 'FontName' => $this->font ) ); return array($textInfo[1]['X'] + 1, $textInfo[0]['Y'] - $textInfo[2]['Y']); } protected function getMaximumTextWidthHeight($values) { if (array_values($values) === $values) { $values = array('' => $values); } $maxWidth = 0; $maxHeight = 0; foreach ($values as $column => $data) { foreach ($data as $value) { list($valueWidth, $valueHeight) = $this->getTextWidthHeight($value); if ($valueWidth > $maxWidth) { $maxWidth = $valueWidth; } if ($valueHeight > $maxHeight) { $maxHeight = $valueHeight; } } } return array($maxWidth, $maxHeight); } protected function drawBackground() { $this->pImage->drawFilledRectangle( 0, 0, $this->width, $this->height, array_merge(array('Alpha' => 100), $this->backgroundColor) ); } private static function hex2rgb($hexColor) { if (preg_match('/([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/', $hexColor, $matches)) { return array( 'R' => hexdec($matches[1]), 'G' => hexdec($matches[2]), 'B' => hexdec($matches[3]) ); } else { return false; } } }