pax_global_header00006660000000000000000000000064142126445750014524gustar00rootroot0000000000000052 comment=7b1a978ec8c4d5f9eb9aa7b1af2efbc0130c6484 Sparkline-2.2.0/000077500000000000000000000000001421264457500134555ustar00rootroot00000000000000Sparkline-2.2.0/Dockerfile000066400000000000000000000013651421264457500154540ustar00rootroot00000000000000FROM php:7.0-cli-alpine ENV PHPIZE_DEPS \ autoconf \ dpkg \ dpkg-dev \ file \ g++ \ gcc \ libc-dev \ make \ pkgconf \ re2c USER root RUN apk update \ && apk --update add --virtual \ build-dependencies \ freetype-dev \ libjpeg-turbo-dev \ libpng-dev \ $PHPIZE_DEPS \ && apk add \ freetype \ libjpeg-turbo \ libpng \ && pecl install xdebug-2.5.0 \ && docker-php-ext-enable xdebug \ && docker-php-ext-configure gd \ --with-freetype \ --with-jpeg \ && docker-php-ext-install \ gd \ && curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer USER www-data Sparkline-2.2.0/LICENSE000066400000000000000000000020751421264457500144660ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2015 David Patiashvili Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Sparkline-2.2.0/README.md000066400000000000000000000120521421264457500147340ustar00rootroot00000000000000# Sparkline PHP Class (using GD) to generate sparklines [![Build Status](https://app.travis-ci.com/davaxi/Sparkline.svg?branch=master)](https://app.travis-ci.com/davaxi/Sparkline) [![Latest Stable Version](https://poser.pugx.org/davaxi/sparkline/v/stable)](https://packagist.org/packages/davaxi/sparkline) [![Total Downloads](https://poser.pugx.org/davaxi/sparkline/downloads)](https://packagist.org/packages/davaxi/sparkline) [![Latest Unstable Version](https://poser.pugx.org/davaxi/sparkline/v/unstable)](https://packagist.org/packages/davaxi/sparkline) [![License](https://poser.pugx.org/davaxi/sparkline/license)](https://packagist.org/packages/davaxi/sparkline) [![Maintainability](https://api.codeclimate.com/v1/badges/9a5da533685204c53989/maintainability)](https://codeclimate.com/github/davaxi/Sparkline/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/9a5da533685204c53989/test_coverage)](https://codeclimate.com/github/davaxi/Sparkline/test_coverage) [![Issue Count](https://codeclimate.com/github/davaxi/Sparkline/badges/issue_count.svg)](https://codeclimate.com/github/davaxi/Sparkline) ## Installation This page contains information about installing the Library for PHP. ### Requirements - PHP version 7.0.0 or greater - The GD PHP extension - The MBString PHP extension #### Using Composer You can install the library by adding it as a dependency to your composer.json. ```shell $ composer require davaxi/sparkline ``` or ```json "require": { "davaxi/sparkline": "^2.2" } ``` #### For PHP >= 5.4.0 Show https://github.com/davaxi/Sparkline/tree/1.2.3 ## Usage Example: ![Sparkline](https://raw.githubusercontent.com/davaxi/Sparkline/master/tests/data/testGenerate2-mockup.png) ```php setData(array(2,4,5,6,10,7,8,5,7,7,11,8,6,9,11,9,13,14,12,16)); $sparkline->display(); ?> ``` ## Documentation ```php $sparkline = new Davaxi\Sparkline(); // Change format (Default value 80x20) $sparkline->setFormat('100x40'); // or $sparkline->setWidth(100); $sparkline->setHeight(40); // Apply padding $sparkline->setPadding('10'); // > top: 10 | right: 10 | bottom: 10 | left: 10 $sparkline->setPadding('10 20'); // > top: 10 | right: 20 | bottom: 10 | left: 20 $sparkline->setPadding('10 20 30'); // > top: 10 | right: 20 | bottom: 30 | left: 20 $sparkline->setPadding('10 20 30 40'); // > top: 10 | right: 20 | bottom: 30 | left: 40 // Change background color (Default value #FFFFFF) $sparkline->setBackgroundColorHex('#0f354b'); // or $sparkline->setBackgroundColorRGB(15, 53, 75); // or $sparkline->deactivateBackgroundColor(); // Change line color (Default value #1388db) $sparkline->setLineColorHex('#1c628b'); // or $sparkline->setLineColorRGB(28, 98, 139); // Change line thickness (Default value 1.75 px) $sparkline->setLineThickness(2.2); // Change fill color (Default value #e6f2fa) $sparkline->setFillColorHex('#8b1c2b'); // or $sparkline->setFillColorRGB(139, 28, 43); // or for specific series $sparkline->deactivateFillColor(); // or for all series $sparkline->deactivateAllFillColor(); $sparkline->setData(array(.....)); // Set data set $sparkline->getData(); // Get seted data $sparkline->generate(); // If ou want regenerate picture // Change base of height value (default max($data)) $sparkline->setBase(20); // Change origin of chart value (yAxis) (default: 0) $sparkline->setOriginValue(40); // Add dot on first/last/minimal/maximal value // Data set before used method $sparkline->addPoint('minimum', 3, '#efefef'); $sparkline->addPoint('maximum', 3, '#efefef'); $sparkline->addPoint('first', 3, '#efefef'); $sparkline->addPoint('last', 3, '#efefef'); // Or by index $sparkline->addPoint(1, 3, '#efefef'); // If display $sparkline->setEtag('your hash'); // If you want add ETag header $sparkline->setFilename('yourPictureName'); // For filenamen header $sparkline->setExpire('+1 day'); // If you want add expire header // or $sparkline->setExpire(strtotime('+1 day')); $sparkline->display(); // Display with correctly headers // If save $sparkline->save('/your/path/to/save/picture'); $sparkline->destroy(); // Destroy picture after generated / displayed / saved ``` ### Multiple sparkline series ```php addSeries([0,1,2,3]); $sparkline->addSeries([2,3,5,6]); // Or $sparkline->setData( [0,1,2,3], [2,3,5,6] ); // For add point on series $sparkline->addPoint('first', 3, '#efefef', 0); // Add point on series 0 $sparkline->addPoint('last', 3, '#efefef', 1); // add point on series 1 // For fill colors, specify on last argument series index's $sparkline->setFillColorHex('#8b1c2b', 0); $sparkline->setFillColorHex('#8bdddf', 1); // or $sparkline->setFillColorRGB(139, 28, 43, 0); $sparkline->setFillColorRGB(139, 28, 55, 1); // For line colors, specify on last argument series index's $sparkline->setLineColorHex('#1c628b', 0); $sparkline->setLineColorHex('#1c62df', 1); // or $sparkline->setLineColorRGB(28, 98, 139, 0); $sparkline->setLineColorRGB(28, 98, 55, 1); ``` Sparkline-2.2.0/autoload.php000066400000000000000000000000631421264457500157750ustar00rootroot00000000000000=7.0", "ext-gd": "*", "ext-mbstring": "*" }, "require-dev": { "ext-xdebug": "*", "phpunit/php-code-coverage": "^9", "phpunit/phpunit": "9.3.5", "codeclimate/php-test-reporter": "^0.4.1" }, "autoload": { "psr-4": { "Davaxi\\": "src/" } } } Sparkline-2.2.0/composer.json000066400000000000000000000020121421264457500161720ustar00rootroot00000000000000{ "name": "davaxi/sparkline", "description": "PHP Class (using GD) to generate sparklines", "version": "2.2.0", "type": "library", "keywords": [ "sparkline", "php", "picture" ], "license": "MIT", "authors": [ { "name": "David Patiashvili", "email": "stratagem.david@gmail.com", "homepage": "https://www.patiashvili.fr/", "role": "Developer" } ], "support": { "issues": "https://github.com/davaxi/Sparkline/issues", "source": "https://github.com/davaxi/Sparkline/releases" }, "minimum-stability": "stable", "require": { "php": ">=7.0", "ext-gd": "*", "ext-mbstring": "*" }, "require-dev": { "ext-xdebug": "*", "codeclimate/php-test-reporter": "dev-master", "phpunit/php-code-coverage": "^3.3.0", "phpunit/phpunit": "^5.3" }, "autoload": { "psr-4": { "Davaxi\\": "src/" } } } Sparkline-2.2.0/docker-compose.yml000066400000000000000000000007451421264457500171200ustar00rootroot00000000000000version: "3" services: composer: build: dockerfile: Dockerfile context: . working_dir: /app entrypoint: - composer volumes: - .:/app php: build: dockerfile: Dockerfile context: . working_dir: /app entrypoint: - php volumes: - .:/app phpunit: build: dockerfile: Dockerfile context: . working_dir: /app entrypoint: - /app/vendor/bin/phpunit volumes: - .:/appSparkline-2.2.0/src/000077500000000000000000000000001421264457500142445ustar00rootroot00000000000000Sparkline-2.2.0/src/Sparkline.php000066400000000000000000000130601421264457500167050ustar00rootroot00000000000000eTag = null; return; } $this->eTag = md5($eTag); } /** * @param string $filename * Without extension */ public function setFilename(string $filename) { $this->filename = $filename; } /** * @param string|int $expire * time format or string format */ public function setExpire($expire) { if (null === $expire) { $this->expire = null; return; } if (is_numeric($expire)) { $this->expire = $expire; return; } $this->expire = strtotime($expire); } public function generate() { list($width, $height) = $this->getNormalizedSize(); $count = $this->getCount(); $picture = new Picture($width, $height); $picture->applyBackground($this->backgroundColor); $lineThickness = (int)round($this->lineThickness * $this->ratioComputing); $picture->applyThickness($lineThickness); $stepCount = $this->getMaxNumberOfDataPointsAcrossSerieses(); foreach ($this->data as $seriesIndex => $series) { $seriesNormalized = $this->getNormalizedData($seriesIndex); list($polygon, $line) = $this->getChartElements($seriesNormalized, $stepCount); $picture->applyPolygon($polygon, $this->getFillColor($seriesIndex), $count); $picture->applyLine($line, $this->getLineColor($seriesIndex)); foreach ($this->points as $point) { if ($point['series'] != $seriesIndex) { continue; } $isFirst = $point['index'] === 0; $lineIndex = $isFirst ? 0 : $point['index'] - 1; $picture->applyDot( $line[$lineIndex][$isFirst ? 0 : 2], $line[$lineIndex][$isFirst ? 1 : 3], $point['radius'] * $this->ratioComputing, $point['color'] ); } } $this->file = $picture->generate($this->width, $this->height); } /** * @param array $server */ public function setServer(array $server) { $this->server = $server; } /** * @param string $key * * @return mixed|null */ public function getServerValue(string $key) { if (isset($this->server[$key])) { return $this->server[$key]; } return null; } /** * @return bool */ protected function checkNoModified(): bool { $httpIfNoneMatch = $this->getServerValue('HTTP_IF_NONE_MATCH'); if ($this->eTag && $httpIfNoneMatch) { if ($httpIfNoneMatch === $this->eTag) { $serverProtocol = $this->getServerValue('SERVER_PROTOCOL'); header($serverProtocol . ' 304 Not Modified', true, 304); return true; } } return false; } public function display() { if (!$this->file) { $this->generate(); } if ($this->checkNoModified()) { return; } header('Content-Type: image/png'); header('Content-Disposition: inline; filename="' . $this->filename . '.png"'); header('Accept-Ranges: none'); if ($this->eTag) { header('ETag: ' . $this->eTag); } if (null !== $this->expire) { header('Expires: ' . gmdate('D, d M Y H:i:s T', $this->expire)); } imagepng($this->file); } /** * @param string $savePath */ public function save(string $savePath) { if (!$this->file) { $this->generate(); } imagepng($this->file, $savePath); } /** * @return string */ public function toBase64(): string { if (!$this->file) { $this->generate(); } ob_start(); imagepng($this->file); $buffer = ob_get_contents(); if (ob_get_length()) { ob_end_clean(); } return base64_encode($buffer); } public function destroy() { if ($this->file) { imagedestroy($this->file); } $this->file = null; } } Sparkline-2.2.0/src/Sparkline/000077500000000000000000000000001421264457500161745ustar00rootroot00000000000000Sparkline-2.2.0/src/Sparkline/DataTrait.php000066400000000000000000000076451421264457500205760ustar00rootroot00000000000000base = $base; } /** * @param float $originValue * Set origin value of chart */ public function setOriginValue(float $originValue) { $this->originValue = $originValue; } /** * @param ...$allSeries */ public function setData(...$allSeries) { $allSeries = func_get_args(); $this->data = []; foreach ($allSeries as $data) { $this->addSeries($data); } } /** * @param array $data */ public function addSeries(array $data) { $data = array_values($data); $count = count($data); if (!$count) { $this->data[] = [0, 0]; return; } if ($count < static::MIN_DATA_LENGTH) { $this->data[] = array_fill(0, 2, $data[0]); return; } $this->data[] = $data; } /** * @return int */ public function getSeriesCount(): int { return count($this->data); } /** * @param int $seriesIndex * @return array */ public function getNormalizedData(int $seriesIndex = 0): array { $data = $this->data[$seriesIndex]; foreach ($data as $i => $value) { $data[$i] = max(0, $value - $this->originValue); } return $data; } /** * @param int $seriesIndex * @return array */ public function getData(int $seriesIndex = 0): array { return $this->data[$seriesIndex]; } /** * @param int $seriesIndex * @return int */ public function getCount(int $seriesIndex = 0): int { return count($this->data[$seriesIndex]); } /** * @param int $seriesIndex * @return array */ protected function getMaxValueWithIndex(int $seriesIndex = 0): array { $max = max($this->data[$seriesIndex]); $maxKeys = array_keys($this->data[$seriesIndex], $max); $maxIndex = end($maxKeys); if ($this->base) { $max = $this->base; } return [$maxIndex, $max]; } /** * @param int $seriesIndex * @return float */ protected function getMaxValue(int $seriesIndex = 0): float { if ($this->base) { return $this->base; } return max($this->data[$seriesIndex]); } /** * TODO: this could be cached somehow * @return float */ protected function getMaxValueAcrossSeries(): float { if ($this->base) { return $this->base; } $maxes = array_map('max', $this->data); return max($maxes); } protected function getMaxNumberOfDataPointsAcrossSerieses() { $counts = array_map('count', $this->data); return max($counts); } /** * @param int $seriesIndex * @return array */ protected function getMinValueWithIndex(int $seriesIndex = 0): array { $min = min($this->data[$seriesIndex]); $minKey = array_keys($this->data[$seriesIndex], $min); $minIndex = end($minKey); return [$minIndex, $min]; } /** * @param int $seriesIndex * @return array */ protected function getExtremeValues(int $seriesIndex = 0): array { list($minIndex, $min) = $this->getMinValueWithIndex($seriesIndex); list($maxIndex, $max) = $this->getMaxValueWithIndex($seriesIndex); return [$minIndex, $min, $maxIndex, $max]; } } Sparkline-2.2.0/src/Sparkline/FormatTrait.php000066400000000000000000000131041421264457500211400ustar00rootroot00000000000000 0, 'right' => 0, 'bottom' => 0, 'left' => 0, ]; /** * @param string $format (Width x Height) */ public function setFormat(string $format) { $values = explode('x', $format); if (count($values) !== static::FORMAT_DIMENSION) { throw new InvalidArgumentException('Invalid format params. Expected string Width x Height'); } $this->setWidth($values[0]); $this->setHeight($values[1]); } /** * @param int $width */ public function setWidth(int $width) { $this->width = $width; } /** * @param int $height */ public function setHeight(int $height) { $this->height = $height; } /** * Set padding : format top right bottom left * ex: 0 10 0 10. * * @param string $padding */ public function setPadding(string $padding) { list($top, $right, $bottom, $left) = $this->paddingStringToArray($padding); $this->padding['top'] = $top; $this->padding['right'] = $right; $this->padding['bottom'] = $bottom; $this->padding['left'] = $left; } /** * @return int */ protected function getNormalizedHeight() : int { return $this->height * $this->ratioComputing; } /** * @return int */ protected function getInnerHeight(): int { return $this->height - $this->padding['top'] - $this->padding['bottom']; } /** * @return array */ protected function getNormalizedPadding(): array { return array_map( function ($value) { return round($value * $this->ratioComputing); }, $this->padding ); } /** * @return int */ protected function getInnerNormalizedHeight(): int { return $this->getInnerHeight() * $this->ratioComputing; } /** * @return int */ protected function getNormalizedWidth(): int { return $this->width * $this->ratioComputing; } /** * @return int */ protected function getInnerWidth(): int { return $this->width - ($this->padding['left'] + $this->padding['right']); } /** * @return int */ protected function getInnerNormalizedWidth(): int { return $this->getInnerWidth() * $this->ratioComputing; } /** * @return array */ protected function getNormalizedSize(): array { return [ $this->getNormalizedWidth(), $this->getNormalizedHeight(), ]; } /** * @return array */ protected function getInnerNormalizedSize(): array { return [ $this->getInnerNormalizedWidth(), $this->getInnerNormalizedHeight(), ]; } /** * @param int $count * * @return float */ protected function getStepWidth(int $count): float { $innerWidth = $this->getInnerNormalizedWidth(); return $innerWidth / ($count - 1); } /** * @param array $data * @param int $height * * @return array */ protected function getDataForChartElements(array $data, int $height): array { $max = $this->getMaxValueAcrossSeries(); $minHeight = 1 * $this->ratioComputing; $maxHeight = $height - $minHeight; foreach ($data as $i => $value) { $value = (int)$value; if ($value <= 0) { $value = 0; } if ($value > 0) { $value = round(($value / $max) * $height); } $data[$i] = max($minHeight, min($value, $maxHeight)); } return $data; } /** * @param array $data * @param int $count count of steps in sparkline image (does not have to == count($data)) * @return array */ protected function getChartElements(array $data, int $count): array { $step = $this->getStepWidth($count); $height = $this->getInnerNormalizedHeight(); $normalizedPadding = $this->getNormalizedPadding(); $data = $this->getDataForChartElements($data, $height); $pictureX1 = $pictureX2 = (int)ceil($normalizedPadding['left']); $pictureY1 = (int)ceil($normalizedPadding['top'] + $height - $data[0]); $polygon = []; $line = []; // Initialize $polygon[] = $normalizedPadding['left']; $polygon[] = $normalizedPadding['top'] + $height; // First element $polygon[] = $pictureX1; $polygon[] = $pictureY1; for ($i = 1; $i < count($data); ++$i) { $pictureX2 = (int)ceil($pictureX1 + $step); $pictureY2 = (int)ceil($normalizedPadding['top'] + $height - $data[$i]); $line[] = [$pictureX1, $pictureY1, $pictureX2, $pictureY2]; $polygon[] = $pictureX2; $polygon[] = $pictureY2; $pictureX1 = $pictureX2; $pictureY1 = $pictureY2; } // Last $polygon[] = $pictureX2; $polygon[] = $normalizedPadding['top'] + $height; return [$polygon, $line]; } } Sparkline-2.2.0/src/Sparkline/Picture.php000066400000000000000000000102311421264457500203150ustar00rootroot00000000000000width = $width; $this->height = $height; $this->resource = imagecreatetruecolor($width, $height); } /** * @param array $setColor * * @return int */ protected function getBackground(array $setColor = []): int { if ($setColor) { return imagecolorallocate( $this->resource, $setColor[0], $setColor[1], $setColor[2] ); } return imagecolorallocatealpha( $this->resource, 0, 0, 0, 127 ); } /** * @param array $lineColor * * @return int */ public function getLineColor(array $lineColor): int { return imagecolorallocate( $this->resource, $lineColor[0], $lineColor[1], $lineColor[2] ); } /** * @param array $backgroundColor */ public function applyBackground(array $backgroundColor) { imagesavealpha($this->resource, true); imagefill( $this->resource, 0, 0, $this->getBackground($backgroundColor) ); } /** * @param int $lineThickness */ public function applyThickness(int $lineThickness) { imagesetthickness($this->resource, $lineThickness); } /** * @param array $polygon * @param array $fillColor * @param int $count */ public function applyPolygon(array $polygon, array $fillColor, int $count) { if (!$fillColor) { return; } $fillColor = imagecolorallocate($this->resource, $fillColor[0], $fillColor[1], $fillColor[2]); if (version_compare(PHP_VERSION, '8.1.0') === -1) { imagefilledpolygon($this->resource, $polygon, $count + 2, $fillColor); } else { imagefilledpolygon($this->resource, $polygon, $fillColor); } } /** * @param array $line * @param array $lineColor */ public function applyLine(array $line, array $lineColor) { $lineColor = $this->getLineColor($lineColor); foreach ($line as $coordinates) { list($pictureX1, $pictureY1, $pictureX2, $pictureY2) = $coordinates; imageline($this->resource, $pictureX1, $pictureY1, $pictureX2, $pictureY2, $lineColor); } } /** * @param int $positionX * @param int $positionY * @param float $radius * @param array $color */ public function applyDot(int $positionX, int $positionY, float $radius, array $color) { if (!$color || !$radius) { return; } $minimumColor = imagecolorallocate( $this->resource, $color[0], $color[1], $color[2] ); $dotDiameter = (int)round($radius * static::DOT_RADIUS_TO_WIDTH); imagefilledellipse( $this->resource, $positionX, $positionY, $dotDiameter, $dotDiameter, $minimumColor ); } /** * @param int $width * @param int $height * * @return resource */ public function generate(int $width, int $height) { $sparkline = imagecreatetruecolor($width, $height); imagealphablending($sparkline, false); imagecopyresampled( $sparkline, $this->resource, 0, 0, 0, 0, $width, $height, $this->width, $this->height ); imagesavealpha($sparkline, true); imagedestroy($this->resource); return $sparkline; } } Sparkline-2.2.0/src/Sparkline/PointTrait.php000066400000000000000000000036601421264457500210070ustar00rootroot00000000000000getPointIndexMapping($seriesIndex); if (array_key_exists($index, $mapping)) { $index = $mapping[$index]; if ($index < 0) { return; } } if (!is_numeric($index)) { throw new InvalidArgumentException('Invalid index : ' . $index); } $this->checkPointIndex($index, $seriesIndex); $this->points[] = [ 'series' => $seriesIndex, 'index' => $index, 'radius' => $dotRadius, 'color' => $this->colorHexToRGB($colorHex), ]; } /** * @param int $seriesIndex * @return array */ protected function getPointIndexMapping(int $seriesIndex = 0): array { $count = $this->getCount($seriesIndex); list($minIndex, $min, $maxIndex, $max) = $this->getExtremeValues($seriesIndex); $mapping = []; $mapping['first'] = $count > 1 ? 0 : -1; $mapping['last'] = $count > 1 ? $count - 1 : -1; $mapping['minimum'] = $min !== $max ? $minIndex : -1; $mapping['maximum'] = $min !== $max ? $maxIndex : -1; return $mapping; } /** * @param int $index * @param int $seriesIndex */ protected function checkPointIndex(int $index, int $seriesIndex) { $count = $this->getCount($seriesIndex); if ($index < 0 || $index >= $count) { throw new InvalidArgumentException('Index out of range [0-' . ($count - 1) . '] : ' . $index); } } } Sparkline-2.2.0/src/Sparkline/StyleTrait.php000066400000000000000000000125631421264457500210200ustar00rootroot00000000000000backgroundColor = []; } /** * @param string $color (hexadecimal) */ public function setBackgroundColorHex(string $color) { list($red, $green, $blue) = $this->colorHexToRGB($color); $this->setBackgroundColorRGB($red, $green, $blue); } /** * @param int $red * @param int $green * @param int $blue */ public function setBackgroundColorRGB(int $red, int $green, int $blue) { $this->backgroundColor = [$red, $green, $blue]; } /** * @param string $color (hexadecimal) * @param int $seriesIndex */ public function setLineColorHex(string $color, int $seriesIndex = 0) { list($red, $green, $blue) = $this->colorHexToRGB($color); $this->setLineColorRGB($red, $green, $blue, $seriesIndex); } /** * @param int $red * @param int $green * @param int $blue * @param int $seriesIndex */ public function setLineColorRGB(int $red, int $green, int $blue, int $seriesIndex = 0) { $this->lineColor[$seriesIndex] = [$red, $green, $blue]; } /** * @param float $thickness (in px) */ public function setLineThickness(float $thickness) { $this->lineThickness = $thickness; } /** * @param int $seriesIndex * @return array */ public function getLineColor(int $seriesIndex = 0): array { return $this->lineColor[$seriesIndex] ?? $this->lineColor[0]; } /** * Set fill color to transparent. * @param int $seriesIndex */ public function deactivateFillColor(int $seriesIndex = 0) { unset($this->fillColor[$seriesIndex]); } /** * Set all fill color to transparent. * @return void */ public function deactivateAllFillColor() { $this->fillColor = []; } /** * @param string $color (hexadecimal) * @param int $seriesIndex */ public function setFillColorHex(string $color, int $seriesIndex = 0) { list($red, $green, $blue) = $this->colorHexToRGB($color); $this->setFillColorRGB($red, $green, $blue, $seriesIndex); } /** * @param int $red * @param int $green * @param int $blue * @param int $seriesIndex */ public function setFillColorRGB(int $red, int $green, int $blue, int $seriesIndex = 0) { $this->fillColor[$seriesIndex] = [$red, $green, $blue]; } /** * @param int $seriesIndex * @return array */ public function getFillColor(int $seriesIndex = 0): array { if (!isset($this->fillColor[$seriesIndex])) { return []; } return $this->fillColor[$seriesIndex]; } /** * @param string $color (hexadecimal) * @exceptions \InvalidArgumentException * * @return array (r,g,b) */ protected function colorHexToRGB(string $color): array { if (!$this->checkColorHex($color)) { throw new InvalidArgumentException('Invalid hexadecimal value ' . $color); } $color = mb_strtolower($color); $color = ltrim($color, '#'); if (mb_strlen($color) === static::HEXADECIMAL_ALIAS_LENGTH) { $color = $color[0] . $color[0] . $color[1] . $color[1] . $color[2] . $color[2]; } $color = hexdec($color); return [ 0xFF & ($color >> 0x10), // Red 0xFF & ($color >> 0x8), // Green 0xFF & $color, // Blue ]; } /** * Formats: * all * vertical horizontal * top horizontal bottom * top right bottom left. * * @param string $padding * * @return array */ protected function paddingStringToArray(string $padding): array { $parts = explode(' ', $padding); switch (count($parts)) { case static::CSS_PADDING_ONE: $value = (float)$parts[0]; return [$value, $value, $value, $value]; case static::CSS_PADDING_TWO: $verticalValue = (float)$parts[0]; $horizontalValue = (float)$parts[1]; return [$verticalValue, $horizontalValue, $verticalValue, $horizontalValue]; case static::CSS_PADDING_THREE: $parts[3] = $parts[1]; return $parts; case static::CSS_PADDING: return $parts; default: throw new InvalidArgumentException('Invalid padding format'); } } /** * @param $color * * @return int */ protected static function checkColorHex($color): int { return preg_match('/^#?+[0-9a-f]{3}(?:[0-9a-f]{3})?$/i', $color); } } Sparkline-2.2.0/src/autoload.php000066400000000000000000000007261421264457500165720ustar00rootroot00000000000000