diff --git a/composer.json b/composer.json
index e4268c8..8ebceae 100644
--- a/composer.json
+++ b/composer.json
@@ -38,10 +38,10 @@
"symplify/easy-coding-standard": "^6.0"
},
"scripts": {
- "check-cs": "ecs check src",
- "fix-cs": "ecs check src --fix",
+ "check-cs": "ecs check src examples",
+ "fix-cs": "ecs check src examples --fix",
"lint": "parallel-lint --colors --exclude vendor .",
- "phpstan": "phpstan analyze src --level max -c phpstan.neon --error-format=fileoutput",
+ "phpstan": "phpstan analyze src examples --level max -c phpstan.neon --error-format=fileoutput",
"test": [
"@lint",
"@check-cs",
diff --git a/ecs.yml b/ecs.yml
index 6122870..eb02797 100644
--- a/ecs.yml
+++ b/ecs.yml
@@ -16,4 +16,6 @@ parameters:
SlevomatCodingStandard\Sniffs\Namespaces\ReferenceUsedNamesOnlySniff: ~
Symplify\CodingStandard\Sniffs\DependencyInjection\NoClassInstantiationSniff: ~
Symplify\CodingStandard\Sniffs\CleanCode\ForbiddenStaticFunctionSniff: ~
- SlevomatCodingStandard\Sniffs\TypeHints\TypeHintDeclarationSniff.MissingTraversableReturnTypeHintSpecification: ~ #DELETE
+ PhpCsFixer\Fixer\Import\OrderedImportsFixer: ~
+ Symplify\CodingStandard\Fixer\Commenting\BlockPropertyCommentFixer: ~
+ Symplify\CodingStandard\Sniffs\ControlStructure\SprintfOverContactSniff: ~
diff --git a/examples/badInput.php b/examples/badInput.php
index 18999dc..dd0a133 100644
--- a/examples/badInput.php
+++ b/examples/badInput.php
@@ -1,8 +1,9 @@
8,
8 => 2,
3 => 2,
- 4 => 2
+ 4 => 2,
];
$lineGraph->addMarkers($lineA, [AsciiColorizer::GREEN, AsciiColorizer::BOLD], [AsciiColorizer::RED]);
-echo $lineGraph->chart();
+$lineGraph->chart()->print();
diff --git a/examples/example.php b/examples/example.php
index f752962..b5b4c3f 100644
--- a/examples/example.php
+++ b/examples/example.php
@@ -1,9 +1,10 @@
setFormat( //control how y axis labels will be printed out
function ($x, Settings $settings) {
$padding = $settings->getPadding();
- $paddingLength = \strlen($padding);
+ $paddingLength = strlen($padding);
return substr($padding . round($x, 2), -$paddingLength);
}
@@ -57,7 +58,6 @@ function ($x, Settings $settings) {
Linechart::CROSS //Point can be made more visible with crosslines. Default is Linegraph::POINT
);
-
$graph = $lineGraph->chart(); //Graph is an object with all data drawn. It can be simply echoed or we can leverage its methods for output control
$graph->clearScreen(); //clears already outputed graphs
diff --git a/examples/floats.php b/examples/floats.php
index 5159d48..6dfd036 100644
--- a/examples/floats.php
+++ b/examples/floats.php
@@ -1,9 +1,10 @@
chart()->clearScreen()->print()->wait();
$lineGraph->clearAllMarkers();
}
-} catch (Exception $e) {
+} catch (\Throwable $e) {
echo $e->getMessage();
}
diff --git a/examples/html.php b/examples/html.php
index 0c5fd14..1e696b3 100644
--- a/examples/html.php
+++ b/examples/html.php
@@ -1,9 +1,10 @@
addMarkers($lineA, ['color: green'], ['color: red']);
$lineGraph->setSettings($settings);
-
-echo $lineGraph->chart();
+$lineGraph->chart()->print();
diff --git a/examples/image.php b/examples/image.php
index dc4e469..7db9813 100644
--- a/examples/image.php
+++ b/examples/image.php
@@ -1,10 +1,11 @@
outputChart();
+$text = (string) $graph;
// Calculate the required width to hold this text
$enclosingBox = imagettfbbox($fontSize, 0, $font, $text);
-$width = ($enclosingBox[2] - $enclosingBox[0]) - 10;
+$width = $enclosingBox[2] - $enclosingBox[0] - 10;
$height = $fontSize * $graph->getSettings()->getHeight() * 2;
diff --git a/examples/largeKeys.php b/examples/largeKeys.php
index bfb9242..70dbcf1 100644
--- a/examples/largeKeys.php
+++ b/examples/largeKeys.php
@@ -1,8 +1,9 @@
addMarkers($lineA, [AsciiColorizer::GREEN, AsciiColorizer::BOLD]);
-echo $lineGraph->chart();
+$lineGraph->chart()->print();
diff --git a/examples/line.php b/examples/line.php
index 2d38d8c..503efd6 100644
--- a/examples/line.php
+++ b/examples/line.php
@@ -2,13 +2,12 @@
declare(strict_types=1);
-use noximo\PHPColoredAsciiLinechart\Linechart;
use noximo\PHPColoredAsciiLinechart\Settings;
+use noximo\PHPColoredAsciiLinechart\Linechart;
require_once dirname(__DIR__) . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php';
$settings = new Settings();
$settings->setFPS(40);
-$settings->setHeight(null);
$lineGraph = new Linechart();
$lineGraph->setSettings($settings);
@@ -16,6 +15,6 @@
try {
$linechart = new Linechart();
$linechart->addMarkers([1, 1, 1, 1, 1, 1])->chart()->print();
-} catch (Exception $e) {
+} catch (\Throwable $e) {
echo $e->getMessage();
}
diff --git a/examples/randomValues.php b/examples/randomValues.php
index 2d025a6..d4e4aa9 100644
--- a/examples/randomValues.php
+++ b/examples/randomValues.php
@@ -1,9 +1,10 @@
setSettings($settings);
try {
+ $lineA = [];
+ $lineB = [];
+ $lineC = [];
+ $lineD = [];
for ($i = 0; $i < 120; $i++) {
- $lineA[$i] = ($lineA[$i - 1] ?? 1) + random_int(-2, 2);
- $lineB[$i] = ($lineB[$i - 1] ?? 1) + random_int(-2, 2);
- $lineC[$i] = ($lineC[$i - 1] ?? 1) + random_int(-2, 2);
- $lineD[$i] = ($lineD[$i - 1] ?? 1) + random_int(-2, 2);
+ $lineA[$i] = $lineA[$i - 1] ?? 1 + random_int(-2, 2);
+ $lineB[$i] = $lineB[$i - 1] ?? 1 + random_int(-2, 2);
+ $lineC[$i] = $lineC[$i - 1] ?? 1 + random_int(-2, 2);
+ $lineD[$i] = $lineD[$i - 1] ?? 1 + random_int(-2, 2);
}
for ($y = 0; $y < 1500; $y++) {
array_shift($lineA);
@@ -39,6 +44,6 @@
$lineGraph->chart()->clearScreen()->print()->wait();
$lineGraph->clearAllMarkers();
}
-} catch (Exception $e) {
- echo $e->getMessage();
+} catch (Throwable $throwable) {
+ echo $throwable->getMessage();
}
diff --git a/examples/realData.php b/examples/realData.php
index 3197d83..722688f 100644
--- a/examples/realData.php
+++ b/examples/realData.php
@@ -1,24 +1,24 @@
setFPS(40);
-$settings->setHeight(null);
$lineGraph = new Linechart();
$lineGraph->setSettings($settings);
try {
- $line = [0.0208, 0.020858, 0.021, 0.021, 0.0211, 0.0211, 0.0211, 0.0211, 0.0211, 0.021056, 0.0211, 0.0211, 0.0211, 0.0211, 0.0211, 0.0211, 0.0211, 0.0211, 0.021124, 0.0214, 0.0215, 0.021436, 0.02149, 0.021488, 0.02149, 0.02145, 0.02145, 0.021406, 0.02145, 0.02145, 0.02145, 0.0214, 0.02145, 0.021487, 0.02149, 0.021482, 0.02148, 0.02148, 0.0215, 0.0215, 0.0215, 0.0215, 0.021499, 0.021473, 0.021454, 0.021497, 0.021489, 0.021454, 0.021705, 0.02151, 0.021513,];
+ $line = [0.0208, 0.020858, 0.021, 0.021, 0.0211, 0.0211, 0.0211, 0.0211, 0.0211, 0.021056, 0.0211, 0.0211, 0.0211, 0.0211, 0.0211, 0.0211, 0.0211, 0.0211, 0.021124, 0.0214, 0.0215, 0.021436, 0.02149, 0.021488, 0.02149, 0.02145, 0.02145, 0.021406, 0.02145, 0.02145, 0.02145, 0.0214, 0.02145, 0.021487, 0.02149, 0.021482, 0.02148, 0.02148, 0.0215, 0.0215, 0.0215, 0.0215, 0.021499, 0.021473, 0.021454, 0.021497, 0.021489, 0.021454, 0.021705, 0.02151, 0.021513];
$lineGraph->addMarkers($line, [AsciiColorizer::GREEN], [AsciiColorizer::RED]);
$lineGraph->chart()->clearScreen()->print()->wait();
$lineGraph->clearAllMarkers();
-} catch (Exception $e) {
+} catch (\Throwable $e) {
echo $e->getMessage();
}
diff --git a/examples/sinus.php b/examples/sinus.php
index 60b167f..8a096d2 100644
--- a/examples/sinus.php
+++ b/examples/sinus.php
@@ -1,9 +1,10 @@
setFPS(40);
-$settings->setHeight(null);
$lineGraph = new Linechart();
$lineGraph->setSettings($settings);
@@ -23,7 +23,6 @@
$lineGraph->chart()->clearScreen()->print()->wait();
$lineGraph->clearAllMarkers();
-
-} catch (Exception $e) {
+} catch (\Throwable $e) {
echo $e->getMessage();
}
diff --git a/log/phpstan.html b/log/phpstan.html
new file mode 100644
index 0000000..21ca6ae
--- /dev/null
+++ b/log/phpstan.html
@@ -0,0 +1,217 @@
+
+
+
+ PHPStan analysis result
+
+PHPStan analysis result
+2019-08-20 22:11:06
+
+
+
+
+
+
+ Files with errors: 2 |
+
+
+
+
+ C:\wamp64\www\PHPColoredAsciiLinechart\examples\image.php (9×) |
+
+
+
+
+ 49
+ |
+
+ Parameter #1 $im of function imagedestroy expects resource, resource|false given.
+ - '#Parameter \#1 \$im of function imagedestroy expects resource, resource\|false given#'
+ |
+
+
+
+ 48
+ |
+
+ Parameter #1 $im of function imagepng expects resource, resource|false given.
+ - '#Parameter \#1 \$im of function imagepng expects resource, resource\|false given#'
+ |
+
+
+
+ 45
+ |
+
+ Parameter #1 $im of function imagettftext expects resource, resource|false given.
+ - '#Parameter \#1 \$im of function imagettftext expects resource, resource\|false given#'
+ |
+
+
+
+ 43
+ |
+
+ Parameter #1 $im of function imagefilledrectangle expects resource, resource|false given.
+ - '#Parameter \#1 \$im of function imagefilledrectangle expects resource, resource\|false given#'
+ |
+
+
+
+ 43
+ |
+
+ Parameter #4 $x2 of function imagefilledrectangle expects int, float|int given.
+ - '#Parameter \#4 \$x2 of function imagefilledrectangle expects int, float\|int given#'
+ |
+
+
+
+ 41
+ |
+
+ Parameter #1 $im of function imagecolorallocate expects resource, resource|false given.
+ - '#Parameter \#1 \$im of function imagecolorallocate expects resource, resource\|false given#'
+ |
+
+
+
+ 40
+ |
+
+ Parameter #1 $im of function imagecolorallocate expects resource, resource|false given.
+ - '#Parameter \#1 \$im of function imagecolorallocate expects resource, resource\|false given#'
+ |
+
+
+
+ 39
+ |
+
+ Parameter #1 $x_size of function imagecreatetruecolor expects int, float|int given.
+ - '#Parameter \#1 \$x_size of function imagecreatetruecolor expects int, float\|int given#'
+ |
+
+
+
+ 36
+ |
+
+ Only numeric types are allowed in *, int|null given on the right side.
+ - '#Only numeric types are allowed in \*, int\|null given on the right side#'
+ |
+
+
+
+ C:\wamp64\www\PHPColoredAsciiLinechart\examples\randomValues.php (4×) |
+
+
+
+
+ 35
+ |
+
+ Only numeric types are allowed in +, int|false given on the left side.
+ - '#Only numeric types are allowed in \+, int\|false given on the left side#'
+ |
+
+
+
+ 33
+ |
+
+ Only numeric types are allowed in +, int|false given on the left side.
+ - '#Only numeric types are allowed in \+, int\|false given on the left side#'
+ |
+
+
+
+ 31
+ |
+
+ Only numeric types are allowed in +, int|false given on the left side.
+ - '#Only numeric types are allowed in \+, int\|false given on the left side#'
+ |
+
+
+
+ 29
+ |
+
+ Only numeric types are allowed in +, int|false given on the left side.
+ - '#Only numeric types are allowed in \+, int\|false given on the left side#'
+ |
+
+
+
+
+
+
diff --git a/phpstan.neon b/phpstan.neon
index a740de3..b55ddea 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -4,19 +4,10 @@ parameters:
excludes_analyse:
- %rootDir%/vendor
ignoreErrors:
- - '#Access to an undefined property ccxt\\Exchange::\$secret.#'
- - '#Access to an undefined property ccxt\\Exchange::\$apiKey.#'
- - '#Access to an undefined property ccxt\\Exchange::\$has.#'
- - '#Constant ROOT_DIR not found.#'
- - '#Constant BITTREX_API_KEY not found.#'
- - '#Constant BITTREX_API_SECRET not found.#'
includes:
- - vendor/phpstan/phpstan-nette/extension.neon
- - vendor/phpstan/phpstan-nette/rules.neon
- vendor/phpstan/phpstan-deprecation-rules/rules.neon
- vendor/phpstan/phpstan-strict-rules/rules.neon
- - vendor/grifart/phpstan-oneline/config.neon
services:
errorFormatter.fileoutput:
- class: noximo\FileOutput(./log/phpstan.html, @errorFormatter.compact)
+ class: noximo\FileOutput(./log/phpstan.html, @errorFormatter.raw)
diff --git a/src/Chart.php b/src/Chart.php
index a6634c8..f72944a 100644
--- a/src/Chart.php
+++ b/src/Chart.php
@@ -4,6 +4,10 @@
namespace noximo\PHPColoredAsciiLinechart;
+use function chr;
+use function strlen;
+use function is_resource;
+
/**
* Class Graph
* @package noximo\PHPColoredConsoleLinegraph
@@ -59,74 +63,74 @@ public function __toString()
{
return $this->prepareChart() . $this->prepareText();
}
-
+
public function getSettings(): Settings
{
return $this->settings;
}
-
+
public function setSettings(Settings $settings): self
{
$this->settings = $settings;
return $this;
}
-
+
public function getResults(): array
{
return $this->results;
}
-
+
public function getMin(): float
{
return $this->min;
}
-
+
public function setMin(float $min): self
{
$this->min = $min;
return $this;
}
-
+
public function getMax(): float
{
return $this->max;
}
-
+
public function setMax(float $max): self
{
$this->max = $max;
return $this;
}
-
+
public function setWidth(int $width): self
{
$this->width = $width;
return $this;
}
-
+
public function addResult(array $result): void
{
$this->results[] = $result;
}
-
+
public function printAndwait(): self
{
$this->print()->wait();
return $this;
}
-
+
public function wait(): self
{
usleep((int) round(1000000 / $this->settings->getFps()));
return $this;
}
-
+
public function print(): self
{
$this->output($this->prepareChart());
@@ -134,7 +138,7 @@ public function print(): self
return $this;
}
-
+
public function toArray(): array
{
$return = [];
@@ -146,11 +150,13 @@ public function toArray(): array
return $return;
}
-
- public function clearScreen(?bool $useAlternativeMethod = null): self
+
+ public function clearScreen(bool $useAlternativeMethod = false): self
{
if ($useAlternativeMethod) {
- $output = \chr(27) . \chr(91) . 'H' . \chr(27) . \chr(91) . 'J';
+ $chr27 = chr(27);
+ $chr91 = chr(91);
+ $output = sprintf('%s%sH%s%sJ', $chr27, $chr91, $chr27, $chr91);
} else {
$output = "\033[0;0f";
}
@@ -159,7 +165,7 @@ public function clearScreen(?bool $useAlternativeMethod = null): self
return $this;
}
-
+
public function setAlltimeMaxHeight(int $allTimeMaxHeight): self
{
$this->allTimeMaxHeight = $allTimeMaxHeight;
@@ -175,7 +181,7 @@ public function printText(): self
return $this;
}
-
+
private function prepareChart(): string
{
$return = '';
@@ -206,41 +212,54 @@ private function prepareText(): string
return $return;
}
-
+
private function output(string $output): void
{
$fopen = fopen('php://stdout', 'wb');
- if (\is_resource($fopen)) {
+ if (is_resource($fopen)) {
fwrite($fopen, $output);
}
}
-
+
private function merge(): array
{
- $x = 0;
$merged = [];
foreach ($this->results as $result) {
foreach ($result as $x => $row) {
- foreach ($row as $y => $cell) {
- if ($this->shouldBeMerged($merged, (string) $x, (string) $y, (string) $cell)) {
- $merged[$x][$y] = (string) $cell;
- }
- }
+ $merged = $this->mergeRow($merged, $row, $x);
}
}
+ return $this->adjustAllTimeMaxHeight($merged, $x ?? 0);
+ }
+
+ private function mergeRow(array $merged, array $row, int $x): array
+ {
+ foreach ($row as $y => $cell) {
+ $cell = (string) $cell;
+ if ($this->shouldBeMerged($merged, $x, $y, $cell)) {
+ $merged[$x][$y] = $cell;
+ }
+ }
+
+ return $merged;
+ }
+
+ private function adjustAllTimeMaxHeight(array $merged, int $x): array
+ {
if ($x < $this->allTimeMaxHeight) {
- $width = $this->width + \strlen($this->settings->getPadding());
+ $width = $this->width + strlen($this->settings->getPadding());
+ $filledArray = array_fill(0, $width, ' ');
for ($i = 0, $iMax = $this->allTimeMaxHeight - $x; $i < $iMax; $i++) {
- $merged[] = array_fill(0, $width, ' ');
+ $merged[] = $filledArray;
}
}
return $merged;
}
-
- private function shouldBeMerged(array $merged, string $x, string $y, string $cell): bool
+
+ private function shouldBeMerged(array $merged, int $x, int $y, string $cell): bool
{
- return !isset($merged[$x][$y]) || ($cell !== ' ' && strpos($merged[$x][$y], 'm') === false);
+ return !isset($merged[$x][$y]) || ($cell !== ' ');
}
}
diff --git a/src/Colorizers/AsciiColorizer.php b/src/Colorizers/AsciiColorizer.php
index 42c5ebf..4771012 100644
--- a/src/Colorizers/AsciiColorizer.php
+++ b/src/Colorizers/AsciiColorizer.php
@@ -5,100 +5,145 @@
namespace noximo\PHPColoredAsciiLinechart\Colorizers;
use ReflectionClass;
+use ReflectionException;
+use function chr;
+use function in_array;
/**
* Class Colorize
* @package noximo\PHPColoredConsoleLinegraph
*/
-final class AsciiColorizer implements IColorizer
+final class AsciiColorizer implements ColorizerInterface
{
+ /** @var int */
public const BOLD = 1;
+ /** @var int */
public const DARK = 2;
+ /** @var int */
public const ITALIC = 3;
+ /** @var int */
public const UNDERLINE = 4;
+ /** @var int */
public const BLINK = 5;
+ /** @var int */
public const REVERSE = 7;
+ /** @var int */
public const CONCEALED = 8;
+ /** @var int */
public const BLACK = 30;
+ /** @var int */
public const RED = 31;
+ /** @var int */
public const GREEN = 32;
+ /** @var int */
public const YELLOW = 33;
+ /** @var int */
public const BLUE = 34;
+ /** @var int */
public const MAGENTA = 35;
+ /** @var int */
public const CYAN = 36;
+ /** @var int */
public const LIGHT_GRAY = 37;
+ /** @var int */
public const DARK_GRAY = 90;
+ /** @var int */
public const LIGHT_RED = 91;
+ /** @var int */
public const LIGHT_GREEN = 92;
+ /** @var int */
public const LIGHT_YELLOW = 93;
+ /** @var int */
public const LIGHT_BLUE = 94;
+ /** @var int */
public const LIGHT_MAGENTA = 95;
+ /** @var int */
public const LIGHT_CYAN = 96;
+ /** @var int */
public const WHITE = 97;
+ /** @var int */
public const BACKGROUND_DEFAULT = 49;
+ /** @var int */
public const BACKGROUND_BLACK = 40;
+ /** @var int */
public const BACKGROUND_RED = 41;
+ /** @var int */
public const BACKGROUND_GREEN = 42;
+ /** @var int */
public const BACKGROUND_YELLOW = 43;
+ /** @var int */
public const BACKGROUND_BLUE = 44;
+ /** @var int */
public const BACKGROUND_MAGENTA = 45;
+ /** @var int */
public const BACKGROUND_CYAN = 46;
+ /** @var int */
public const BACKGROUND_LIGHT_GRAY = 47;
+ /** @var int */
public const BACKGROUND_DARK_GRAY = 100;
+ /** @var int */
public const BACKGROUND_LIGHT_RED = 101;
+ /** @var int */
public const BACKGROUND_LIGHT_GREEN = 102;
+ /** @var int */
public const BACKGROUND_LIGHT_YELLOW = 103;
+ /** @var int */
public const BACKGROUND_LIGHT_BLUE = 104;
+ /** @var int */
public const BACKGROUND_LIGHT_MAGENTA = 105;
+ /** @var int */
public const BACKGROUND_LIGHT_CYAN = 106;
+ /** @var int */
public const BACKGROUND_WHITE = 107;
+ /** @var array */
private static $constants = [];
/**
* @param array|null $colors
*
+ * @return string
* @throws ColorException
- * @throws \ReflectionException
+ * @throws ReflectionException
*/
public function colorize(string $text, ?array $colors = null): string
{
@@ -107,32 +152,34 @@ public function colorize(string $text, ?array $colors = null): string
}
foreach ($colors as $color) {
- if (!$this->colorExists($color)) {
+ if (!$this->colorExists((int) $color)) {
throw new ColorException('Unknown color ' . $color . ', use constans of class Color');
}
}
- return \chr(27) . '[0m' . \chr(27) . '[' . implode(';', $colors) . 'm' . $text . \chr(27) . '[0m';
+ $chr27 = chr(27);
+
+ return sprintf('%s[0m%s[%sm%s%s[0m', $chr27, $chr27, implode(';', $colors), $text, $chr27);
}
/**
- * @throws \ReflectionException
+ * @throws ReflectionException
*/
public function colorExists(int $color): bool
{
- if (empty(self::$constants)) {
+ if (count(self::$constants) === 0) {
$oClass = new ReflectionClass(self::class);
self::$constants = $oClass->getConstants();
}
- return \in_array($color, self::$constants, true);
+ return in_array($color, self::$constants, true);
}
-
+
public function getEOL(): string
{
return PHP_EOL;
}
-
+
public function processFinalText(string $text): string
{
return $text;
diff --git a/src/Colorizers/IColorizer.php b/src/Colorizers/ColorizerInterface.php
similarity index 73%
rename from src/Colorizers/IColorizer.php
rename to src/Colorizers/ColorizerInterface.php
index 643f08d..95d934f 100644
--- a/src/Colorizers/IColorizer.php
+++ b/src/Colorizers/ColorizerInterface.php
@@ -4,18 +4,14 @@
namespace noximo\PHPColoredAsciiLinechart\Colorizers;
-/**
- * Interface IColor
- * @package noximo\PHPColoredConsoleLinegraph\Colorizers
- */
-interface IColorizer
+interface ColorizerInterface
{
/**
* @param array|null $colors
*/
public function colorize(string $text, ?array $colors = null): string;
-
+
public function getEOL(): string;
-
+
public function processFinalText(string $text): string;
}
diff --git a/src/Colorizers/HTMLColorizer.php b/src/Colorizers/HTMLColorizer.php
index 6067e5e..07b69d1 100644
--- a/src/Colorizers/HTMLColorizer.php
+++ b/src/Colorizers/HTMLColorizer.php
@@ -8,7 +8,7 @@
* Class HTMLColorizer
* @package noximo\PHPColoredAsciiLinechart\Colorizers
*/
-final class HTMLColorizer implements IColorizer
+final class HTMLColorizer implements ColorizerInterface
{
/**
* @param array|null $styles
@@ -21,14 +21,14 @@ public function colorize(string $text, ?array $styles = null): string
$cssStyles = implode(';', str_replace(' ', '', $styles));
- return "" . $text . '';
+ return sprintf("%s", $cssStyles, $text);
}
-
+
public function getEOL(): string
{
return '
';
}
-
+
public function processFinalText(string $text): string
{
$div = "";
diff --git a/src/Colorizers/ImageColorizer.php b/src/Colorizers/ImageColorizer.php
index 8cd05f8..2fe9271 100644
--- a/src/Colorizers/ImageColorizer.php
+++ b/src/Colorizers/ImageColorizer.php
@@ -8,7 +8,7 @@
* Class HTMLColorizer
* @package noximo\PHPColoredAsciiLinechart\Colorizers
*/
-final class ImageColorizer implements IColorizer
+final class ImageColorizer implements ColorizerInterface
{
/**
* @param array|null $styles
@@ -17,12 +17,12 @@ public function colorize(string $text, ?array $styles = null): string
{
return $text;
}
-
+
public function getEOL(): string
{
return PHP_EOL;
}
-
+
public function processFinalText(string $text): string
{
return $text;
diff --git a/src/Linechart.php b/src/Linechart.php
index bd54de7..5b73ee6 100644
--- a/src/Linechart.php
+++ b/src/Linechart.php
@@ -4,9 +4,9 @@
namespace noximo\PHPColoredAsciiLinechart;
-use noximo\PHPColoredAsciiLinechart\Colorizers\IColorizer;
-use function in_array;
+use noximo\PHPColoredAsciiLinechart\Colorizers\ColorizerInterface;
use function strlen;
+use function in_array;
/**
* Class LineGraph
@@ -14,30 +14,39 @@
*/
final class Linechart
{
+ /** @var string */
public const CROSS = 'cross';
+ /** @var string */
public const POINT = 'point';
+ /** @var string */
public const DASHED_LINE = 'dashedLine';
+ /** @var string */
public const POINT_X = 'x';
+ /** @var string */
public const POINT_Y = 'y';
+ /** @var string */
public const VALUE = 'value';
+ /** @var string */
public const COLORS = 'colors';
+ /** @var string */
public const FULL_LINE = 'fullLIne';
+ /** @var string */
public const MARKERS = 'markers';
+ /** @var string */
public const COLORS_DOWN = 'colorsDown';
+ /** @var string */
public const SPREADS = 'spreads';
- private $width;
-
/**
* @var array = [
* [['markers' => [1,2,3.45], SELF::COLORS => [1,2,3]]];
@@ -45,40 +54,43 @@ final class Linechart
*/
private $allmarkers = [];
+ /** @var int */
+ private $width;
+
/**
* @var array|null
*/
private $currentColors;
/**
- * @var float|null
+ * @var float
*/
- private $range;
+ private $range = 0.0;
/**
- * @var float|null
+ * @var float
*/
- private $ratio;
+ private $ratio = 0.0;
/**
- * @var float|null
+ * @var float
*/
- private $min2;
+ private $min2 = 0.0;
/**
- * @var float|null
+ * @var float
*/
- private $max2;
+ private $max2 = 0.0;
/**
- * @var int|null
+ * @var int
*/
- private $rows;
+ private $rows = 1;
/**
- * @var int|null
+ * @var int
*/
- private $offset;
+ private $offset = 0;
/**
* @var float|null
@@ -96,7 +108,7 @@ final class Linechart
private $settings;
/**
- * @var IColorizer|null
+ * @var ColorizerInterface
*/
private $colorizer;
@@ -109,6 +121,7 @@ final class Linechart
*/
public function addPoint(int $x, float $y, ?array $colors = null, ?string $appearance = null): self
{
+ $markers = [];
$markers[0] = $y;
$markers[$x] = $y;
if (!in_array($appearance, [self::CROSS, self::POINT], true)) {
@@ -119,43 +132,6 @@ public function addPoint(int $x, float $y, ?array $colors = null, ?string $appea
return $this;
}
- /**
- * @param array $markers
- * @param array|null $colors
- * @param array|null $colorsDown
- * @param string|null $point
- * @return Linechart
- */
- private function addMarkerData(array $markers, ?array $colors = null, ?array $colorsDown = null, ?string $point = null): self
- {
- $markersData = [
- self::MARKERS => $this->normalizeData($markers),
- self::COLORS => $colors ?? [],
- self::COLORS_DOWN => $colorsDown ?? $colors ?? [],
- self::POINT => $point,
- ];
-
- $this->allmarkers[] = $markersData;
-
- return $this;
- }
-
- private function normalizeData(array $markers): array
- {
- $markers = array_filter($markers, '\is_int', ARRAY_FILTER_USE_KEY);
- ksort($markers);
-
- reset($markers);
- $firstKey = key($markers);
-
- $keys = [];
- foreach (array_keys($markers) as $key) {
- $keys[] = $key - $firstKey;
- }
-
- return array_combine($keys, $markers);
- }
-
/**
* @param array $markers
* @param array|null $colors
@@ -176,25 +152,7 @@ public function chart(): Chart
$this->prepareData();
foreach ($this->allmarkers as $markersData) {
- $markersData[self::MARKERS] = $this->adjustMarkerValues($markersData[self::MARKERS]);
- $this->currentColors = $this->currentColors ?? $markersData[self::COLORS];
- $result = $this->prepareResult();
-
- $result = $this->processBorder($result, $markersData);
- $isPoint = in_array($markersData[self::POINT], [self::CROSS, self::POINT], true);
- $isLine = in_array($markersData[self::POINT], [self::DASHED_LINE, self::FULL_LINE], true);
-
- foreach ($markersData[self::MARKERS] as $x => $value) {
- $y0 = (int)(round($value * $this->ratio) - $this->min2);
-
- if ($this->isPresent($markersData[self::MARKERS], $x + 1)) {
- $result = $this->processLinearGraph($result, $markersData, $x, $y0);
- } else if ($x !== 0 && $isPoint) {
- $result = $this->processPoint($result, $markersData, $y0, $x);
- } else if ($x === 0 && $isLine) {
- $result = $this->processLine($result, $y0, $markersData[self::POINT]);
- }
- }
+ $result = $this->getResultFromMarkersData($markersData);
$this->currentColors = null;
$graph->addResult($result);
@@ -221,9 +179,90 @@ public function setSettings(Settings $settings): self
return $this;
}
+ public function clearAllMarkers(): self
+ {
+ $this->allmarkers = [];
+
+ return $this;
+ }
+
+ /**
+ * @param string $value
+ * @param string[] $color
+ */
+ public function addText(string $value, array $color): void
+ {
+ $this->text[] = [
+ self::VALUE => $value,
+ self::COLORS => $color,
+ ];
+ }
+
+ /**
+ * @param array $values
+ * @param float $mainValue
+ * @param array $colors
+ */
+ public function addSpread(array $values, float $mainValue, array $colors): void
+ {
+ foreach ($values as $value) {
+ $colors = $colors ?? [];
+ $appearance = $value === 1 ? self::FULL_LINE : self::DASHED_LINE;
+ $this->addLine($value * $mainValue, $colors ?? [], $appearance);
+ }
+ }
+
+ /**
+ * @param float $value alias y coordinate
+ * @param array|null $colors
+ * @param string|null $appearance
+ * @return Linechart
+ */
+ public function addLine(float $value, ?array $colors = null, ?string $appearance = null): self
+ {
+ $markers = [];
+ $markers[0] = $value;
+ if (!in_array($appearance, [self::DASHED_LINE, self::FULL_LINE], true)) {
+ $appearance = self::DASHED_LINE;
+ }
+ $this->addMarkerData($markers, $colors, null, $appearance);
+
+ return $this;
+ }
+
+ public function getText(): array
+ {
+ return $this->text;
+ }
+
+ public function clearText(): void
+ {
+ $this->text = [];
+ }
+
+ /**
+ * @param array $markers
+ * @param array|null $colors
+ * @param array|null $colorsDown
+ * @param string|null $point
+ * @return Linechart
+ */
+ private function addMarkerData(array $markers, ?array $colors = null, ?array $colorsDown = null, ?string $point = null): self
+ {
+ $markersData = [
+ self::MARKERS => $this->normalizeData($markers),
+ self::COLORS => $colors ?? [],
+ self::COLORS_DOWN => $colorsDown ?? $colors ?? [],
+ self::POINT => $point,
+ ];
+
+ $this->allmarkers[] = $markersData;
+
+ return $this;
+ }
+
private function prepareData(): void
{
- $this->colorizer = $this->getSettings()->getColorizer();
[$min, $max, $width] = $this->findMinMax($this->allmarkers);
$this->adjuster = $this->findAdjuster($min, $max);
@@ -232,19 +271,66 @@ private function prepareData(): void
$this->range = max(1, abs($max - $min));
- $height = (int)($this->getSettings()->getHeight() ?? $this->range);
+ $height = (int) ($this->getSettings()->getHeight() ?? $this->range);
$this->ratio = $height / $this->range;
$this->min2 = $min * $this->ratio;
$this->max2 = $max * $this->ratio;
- $this->rows = (int)max(0, abs(round($this->max2 - $this->min2)));
+ $this->rows = (int) max(0, abs(round($this->max2 - $this->min2)));
$this->offset = $this->getSettings()->getOffset();
$this->width = $width + $this->offset;
}
+ private function getResultFromMarkersData(array $markersData): array
+ {
+ $markersData[self::MARKERS] = $this->adjustMarkerValues($markersData[self::MARKERS]);
+ $this->currentColors = $this->currentColors ?? $markersData[self::COLORS];
+
+ $result = $this->processBorder($this->prepareResult(), $markersData);
+
+ $isPoint = in_array($markersData[self::POINT], [self::CROSS, self::POINT], true);
+ $isLine = in_array($markersData[self::POINT], [self::DASHED_LINE, self::FULL_LINE], true);
+
+ foreach ($markersData[self::MARKERS] as $x => $value) {
+ $y0 = (int) (round($value * $this->ratio) - $this->min2);
+
+ if ($this->isPresent($markersData[self::MARKERS], $x + 1)) {
+ $result = $this->processLinearGraph($result, $markersData, $x, $y0);
+ } elseif ($x !== 0 && $isPoint) {
+ $result = $this->processPoint($result, $markersData, $y0, $x);
+ } elseif ($x === 0 && $isLine) {
+ $result = $this->processLine($result, $y0, $markersData[self::POINT]);
+ }
+ }
+
+ return $result;
+ }
+
+ private function normalizeData(array $markers): array
+ {
+ $markers = array_filter($markers, '\is_int', ARRAY_FILTER_USE_KEY);
+ ksort($markers);
+
+ reset($markers);
+ $firstKey = key($markers);
+
+ $keys = [];
+ foreach (array_keys($markers) as $key) {
+ $keys[] = $key - $firstKey;
+ }
+
+ $combined = array_combine($keys, $markers);
+
+ if ($combined === false) {
+ return [];
+ }
+
+ return $combined;
+ }
+
private function findMinMax(array $allmarkers): array
{
$width = 0;
@@ -252,7 +338,7 @@ private function findMinMax(array $allmarkers): array
$max = -PHP_INT_MAX;
foreach ($allmarkers as $markers) {
end($markers[self::MARKERS]);
- $width = (int)max($width, key($markers[self::MARKERS]));
+ $width = (int) max($width, key($markers[self::MARKERS]));
/** @var int[][] $markers */
foreach ($markers[self::MARKERS] as $value) {
@@ -294,28 +380,16 @@ private function adjustMarkerValues(array $markers): array
}
return array_map(function ($value) {
- return $value * $this->adjuster;
+ return $this->adjuster !== null ? $value * $this->adjuster : $value;
}, $markers);
}
- private function prepareResult(): array
- {
- $result = [];
-
- /** @noinspection ForeachInvariantsInspection */
- for ($i = 0; $i <= $this->rows; $i++) {
- $result[$i] = array_fill(0, $this->width, ' ');
- }
-
- return $result;
- }
-
private function processBorder(array $result, array $markersData): array
{
$format = $this->getSettings()->getFormat();
- $y0 = (int)(round($markersData[self::MARKERS][0] * $this->ratio) - $this->min2);
- $y = (int)floor($this->min2);
- $yMax = (int)ceil($this->max2);
+ $y0 = (int) (round($markersData[self::MARKERS][0] * $this->ratio) - $this->min2);
+ $y = (int) floor($this->min2);
+ $yMax = (int) ceil($this->max2);
for (; $y <= $yMax; ++$y) {
$rows = $this->rows === 0 ? 1 : $this->rows;
@@ -324,9 +398,9 @@ private function processBorder(array $result, array $markersData): array
$label = $format($rawLabel, $this->getSettings());
$border = '┤';
- if ($y - $this->min2 === $rows - $y0) {
- $label = $this->colorizer->colorize($label, $this->currentColors);
- $border = $this->colorizer->colorize('┼', $this->currentColors);
+ if ($y - $this->min2 === (float) ($rows - $y0)) {
+ $label = $this->colorize($label, $this->currentColors);
+ $border = $this->colorize('┼', $this->currentColors);
}
$result[$y - $this->min2][max($this->offset - strlen($label), 0)] = $label;
@@ -336,13 +410,16 @@ private function processBorder(array $result, array $markersData): array
return $result;
}
- private function deadjust(float $number): float
+ private function prepareResult(): array
{
- if ($this->adjuster !== null) {
- $number /= $this->adjuster;
+ $result = [];
+
+ /** @noinspection ForeachInvariantsInspection */
+ for ($i = 0; $i <= $this->rows; $i++) {
+ $result[$i] = array_fill(0, $this->width, ' ');
}
- return $number;
+ return $result;
}
private function isPresent(array $markers, int $x): bool
@@ -352,9 +429,9 @@ private function isPresent(array $markers, int $x): bool
private function processLinearGraph(array $result, array $markersData, int $x, int $y): array
{
- $y1 = (int)(round($markersData[self::MARKERS][$x + 1] * $this->ratio) - $this->min2);
+ $y1 = (int) (round($markersData[self::MARKERS][$x + 1] * $this->ratio) - $this->min2);
if ($y === $y1) {
- $result[$this->rows - $y][$x + $this->offset] = $this->colorizer->colorize('─', $this->currentColors);
+ $result[$this->rows - $y][$x + $this->offset] = $this->colorize('─', $this->currentColors);
} else {
if ($y > $y1) {
$connectA = '╰';
@@ -367,13 +444,13 @@ private function processLinearGraph(array $result, array $markersData, int $x, i
$this->currentColors = $markersData[self::COLORS];
}
- $result[$this->rows - $y1][$x + $this->offset] = $this->colorizer->colorize($connectA, $this->currentColors);
- $result[$this->rows - $y][$x + $this->offset] = $this->colorizer->colorize($connectB, $this->currentColors);
+ $result[$this->rows - $y1][$x + $this->offset] = $this->colorize($connectA, $this->currentColors);
+ $result[$this->rows - $y][$x + $this->offset] = $this->colorize($connectB, $this->currentColors);
$from = min($y, $y1);
$to = max($y, $y1);
for ($i = $from + 1; $i < $to; $i++) {
- $result[$this->rows - $i][$x + $this->offset] = $this->colorizer->colorize('│', $this->currentColors);
+ $result[$this->rows - $i][$x + $this->offset] = $this->colorize('│', $this->currentColors);
}
}
@@ -384,14 +461,14 @@ private function processPoint(array $result, array $markersData, int $y, int $x)
{
if ($markersData[self::POINT] === self::CROSS) {
for ($i = 0; $i <= $this->width - $this->offset - 2; $i++) {
- $result[$this->rows - $y][$i + $this->offset] = $this->colorizer->colorize('╌', $this->currentColors);
+ $result[$this->rows - $y][$i + $this->offset] = $this->colorize('╌', $this->currentColors);
}
for ($i = 0; $i <= $this->rows; $i++) {
- $result[$this->rows - $i][$x + $this->offset] = $this->colorizer->colorize('╎', $this->currentColors);
+ $result[$this->rows - $i][$x + $this->offset] = $this->colorize('╎', $this->currentColors);
}
}
- $result[$this->rows - $y][$x + $this->offset] = $this->colorizer->colorize('o', $this->currentColors);
+ $result[$this->rows - $y][$x + $this->offset] = $this->colorize('o', $this->currentColors);
return $result;
}
@@ -404,69 +481,27 @@ private function processLine(array $result, int $y, string $lineStyle): array
}
for ($i = 0; $i <= $this->width - $this->offset - 2; $i++) {
- $result[$this->rows - $y][$i + $this->offset] = $this->colorizer->colorize($line, $this->currentColors);
+ $result[$this->rows - $y][$i + $this->offset] = $this->colorize($line, $this->currentColors);
}
return $result;
}
- public function clearAllMarkers(): self
- {
- $this->allmarkers = [];
-
- return $this;
- }
-
- /**
- * @param string $value
- * @param string[] $color
- */
- public function addText(string $value, array $color): void
- {
- $this->text[] = [
- self::VALUE => $value,
- self::COLORS => $color,
- ];
- }
-
- /**
- * @param array $values
- * @param float $mainValue
- * @param array $colors
- */
- public function addSpread(array $values, float $mainValue, array $colors): void
- {
- foreach ($values as $value) {
- $colors = $colors ?? [];
- $appearance = $value === 1 ? self::FULL_LINE : self::DASHED_LINE;
- $this->addLine($value * $mainValue, $colors ?? [], $appearance);
- }
- }
-
- /**
- * @param float $value alias y coordinate
- * @param array|null $colors
- * @param string|null $appearance
- * @return Linechart
- */
- public function addLine(float $value, ?array $colors = null, ?string $appearance = null): self
+ private function deadjust(float $number): float
{
- $markers[0] = $value;
- if (!in_array($appearance, [self::DASHED_LINE, self::FULL_LINE], true)) {
- $appearance = self::DASHED_LINE;
+ if ($this->adjuster !== null) {
+ $number /= $this->adjuster;
}
- $this->addMarkerData($markers, $colors, null, $appearance);
- return $this;
+ return $number;
}
- public function getText(): array
+ private function colorize(string $label, ?array $currentColors = null): string
{
- return $this->text;
- }
+ if ($this->colorizer === null) {
+ $this->colorizer = $this->getSettings()->getColorizer();
+ }
- public function clearText(): void
- {
- $this->text = [];
+ return $this->colorizer->colorize($label, $currentColors);
}
}
diff --git a/src/Settings.php b/src/Settings.php
index 7b9ee91..fec5392 100644
--- a/src/Settings.php
+++ b/src/Settings.php
@@ -5,7 +5,7 @@
namespace noximo\PHPColoredAsciiLinechart;
use noximo\PHPColoredAsciiLinechart\Colorizers\AsciiColorizer;
-use noximo\PHPColoredAsciiLinechart\Colorizers\IColorizer;
+use noximo\PHPColoredAsciiLinechart\Colorizers\ColorizerInterface;
/**
* Class Config
@@ -39,7 +39,7 @@ final class Settings
private $fps = 12;
/**
- * @var IColorizer
+ * @var ColorizerInterface
*/
private $colorizer;
@@ -78,7 +78,7 @@ public function getHeight(): ?int
return $this->height;
}
- public function setHeight(?int $height): self
+ public function setHeight(int $height): self
{
$this->height = $height;
@@ -129,12 +129,12 @@ public function setFPS(int $fps): self
return $this;
}
- public function getColorizer(): IColorizer
+ public function getColorizer(): ColorizerInterface
{
return $this->colorizer ?? new AsciiColorizer();
}
- public function setColorizer(IColorizer $colorizer): self
+ public function setColorizer(ColorizerInterface $colorizer): self
{
$this->colorizer = $colorizer;