Initial commit, console stuff works
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace NoccyLabs\Histogram;
|
||||
|
||||
use Countable;
|
||||
|
||||
class Buffer implements Countable
|
||||
{
|
||||
|
||||
private $samples = [];
|
||||
|
||||
private $maxSamples = 50;
|
||||
|
||||
public function __construct(int $maxSamples=50)
|
||||
{
|
||||
$this->maxSamples = max(1, $maxSamples);
|
||||
}
|
||||
|
||||
public function count(): int
|
||||
{
|
||||
return count($this->samples);
|
||||
}
|
||||
|
||||
public function pushSamples(...$samples)
|
||||
{
|
||||
array_push($this->samples, ...$samples);
|
||||
$this->trim();
|
||||
}
|
||||
|
||||
public function getSampleMax(): float
|
||||
{
|
||||
return (float)max($this->samples);
|
||||
}
|
||||
|
||||
public function getSampleMin(): float
|
||||
{
|
||||
return (float)min($this->samples);
|
||||
}
|
||||
|
||||
public function getSampleAverage(): ?float
|
||||
{
|
||||
$clean = array_filter($this->samples, function ($s) { return $s !== null; });
|
||||
if (count($clean) === 0)
|
||||
return null;
|
||||
|
||||
$total = array_sum($clean);
|
||||
$average = $total / count($clean);
|
||||
return (float)$average;
|
||||
}
|
||||
|
||||
public function getMappedSamples(float $inMin, float $inMax, float $outMin=0.0, float $outMax=1.0, ?int $numSamples=null)
|
||||
{
|
||||
$map = function ($v) use ($inMin, $inMax, $outMin, $outMax) {
|
||||
if ($v === null) return null;
|
||||
$v = max($inMin, min($inMax, $v));
|
||||
return (($v - $inMin) / ($inMax - $inMin)) * ($outMax - $outMin) + $outMin;
|
||||
};
|
||||
return array_map($map, $numSamples?array_slice($this->samples,-$numSamples,$numSamples):$this->samples);
|
||||
}
|
||||
|
||||
public function getSamples(?int $numSamples=null)
|
||||
{
|
||||
return $numSamples?array_slice($this->samples,-$numSamples,$numSamples):$this->samples;
|
||||
}
|
||||
|
||||
private function trim()
|
||||
{
|
||||
while (count($this->samples) > $this->maxSamples)
|
||||
array_shift($this->samples);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
namespace NoccyLabs\Histogram\Output;
|
||||
|
||||
use NoccyLabs\Histogram\Buffer;
|
||||
|
||||
class TerminalHistogram
|
||||
{
|
||||
|
||||
public static $MaxWidth = 50;
|
||||
|
||||
private $width;
|
||||
|
||||
private $max = null;
|
||||
|
||||
/** @var Buffer */
|
||||
private $buffer;
|
||||
|
||||
private $bars = [
|
||||
" ",
|
||||
"\u{2581}",
|
||||
"\u{2582}",
|
||||
"\u{2583}",
|
||||
"\u{2584}",
|
||||
"\u{2585}",
|
||||
"\u{2586}",
|
||||
"\u{2587}",
|
||||
"\u{2588}",
|
||||
];
|
||||
|
||||
public function __construct(int $width, Buffer $buffer=null)
|
||||
{
|
||||
$this->width = max(1, min($width, self::$MaxWidth));
|
||||
$this->buffer = $buffer ?? new Buffer(50);
|
||||
}
|
||||
|
||||
public function getBuffer(): Buffer
|
||||
{
|
||||
return $this->buffer;
|
||||
}
|
||||
|
||||
public function setMax(?float $max)
|
||||
{
|
||||
$this->max = $max;
|
||||
}
|
||||
|
||||
public function getHistogram()
|
||||
{
|
||||
$max = ($this->max === null)?1.0:$this->max;
|
||||
$samples = $this->buffer->getMappedSamples(0.0, $max, 0, 8, $this->width);
|
||||
$output = null;
|
||||
if (count($samples) < $this->width) {
|
||||
$output .= str_repeat(" ", $this->width - count($samples));
|
||||
}
|
||||
foreach ($samples as $sample) {
|
||||
if ($sample === null) {
|
||||
$output .= "\u{2a09}";
|
||||
} else {
|
||||
$output .= $this->bars[floor($sample)];
|
||||
}
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function getMultiHistogram(int $lines): array
|
||||
{
|
||||
$max = ($this->max === null)?1.0:$this->max;
|
||||
$samples = $this->buffer->getMappedSamples(0.0, $max, 0, 8*$lines, $this->width);
|
||||
$result = [];
|
||||
$topmin = 8*($lines-1);
|
||||
for ($line = 0; $line < $lines; $line++) {
|
||||
$rowmin = $topmin - ($line * 8);
|
||||
$output = null;
|
||||
if (count($samples) < $this->width) {
|
||||
$output .= str_repeat(" ", $this->width - count($samples));
|
||||
}
|
||||
foreach ($samples as $sample) {
|
||||
if ($sample === null) {
|
||||
$output .= "\u{2a09}";
|
||||
} else {
|
||||
$remain = $sample - $rowmin;
|
||||
if ($remain <= 0) {
|
||||
$output.= " ";
|
||||
} else {
|
||||
$sample = min(8, $remain);
|
||||
$output .= $this->bars[floor($sample)];
|
||||
}
|
||||
}
|
||||
}
|
||||
$result[] = $output;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getHistogram();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user