Created
September 20, 2019 23:31
-
-
Save d4rkne55/81bd746e9af651e29ed1e2a3bb1b0086 to your computer and use it in GitHub Desktop.
Class for drawing cool ASCII tables, including data
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class AsciiTable | |
{ | |
private $rows; | |
private $columns; | |
private $headers = array(); | |
private $data = array(); | |
private $separators; | |
private $headerPadMethod; | |
public function __construct($rows, $columns, $chars = '-|') { | |
$this->columns = $columns; | |
$this->rows = $rows; | |
$this->separators = str_split($chars); | |
$this->initData(); | |
} | |
/** | |
* @param array $headers | |
* @param bool $centered | |
*/ | |
public function addHeaders($headers, $centered = false) { | |
if (count($headers) == $this->columns) { | |
$this->headers = array_combine(range(1, count($headers)), $headers); | |
$this->headerPadMethod = $centered ? STR_PAD_BOTH : STR_PAD_RIGHT; | |
} else { | |
throw new LogicException('Header count must match the column count!'); | |
} | |
} | |
/** | |
* @param int $row | |
* @param int $column | |
* @param mixed $data | |
*/ | |
public function addData($row, $column, $data) { | |
if (isset($this->data[$row][$column])) { | |
$this->data[$row][$column] = $data; | |
} else { | |
trigger_error('Row or column has not been initialized', E_USER_NOTICE); | |
} | |
} | |
/** | |
* @param int $row | |
* @param array $data | |
*/ | |
public function addRowData($row, $data) { | |
$newData = array_replace(array_values($this->data[$row]), $data); | |
$this->data[$row] = array_combine(array_keys($this->data[$row]), $newData); | |
} | |
public function draw() { | |
$columnWidths = array(); | |
for ($col = 1; $col <= $this->columns; $col++) { | |
$columnWidths[$col] = $this->getMaxColumnWidth($col); | |
} | |
$gridWidth = array_sum($columnWidths) + ($this->columns * 3) + 1; | |
for ($row = 0; $row <= $this->rows; $row++) { | |
if ($row == 0 && empty($this->headers)) { | |
continue; | |
} | |
echo str_repeat($this->separators[0], $gridWidth), PHP_EOL; | |
for ($col = 1; $col <= $this->columns; $col++) { | |
if ($row == 0 && !empty($this->headers)) { | |
$content = $this->headers[$col]; | |
$padMethod = $this->headerPadMethod; | |
} else { | |
$content = $this->data[$row][$col]; | |
$padMethod = STR_PAD_RIGHT; | |
} | |
$contentLines = explode(PHP_EOL, $content); | |
//$contentLines = array_replace(array_fill(0, $this->getMaxRowHeight($row), ''), $contentLines); | |
$contentLines = array_map(function($line) use ($col, $columnWidths, $padMethod) { | |
return str_pad($line, $columnWidths[$col], ' ', $padMethod); | |
}, $contentLines); | |
foreach ($contentLines as $i => $line) { | |
echo "{$this->separators[1]} $line "; | |
if ($i < count($contentLines) - 1) { | |
echo $this->separators[1], PHP_EOL; | |
} | |
} | |
if ($col == $this->columns) { | |
echo $this->separators[1], PHP_EOL; | |
} | |
} | |
if ($row == $this->rows) { | |
echo str_repeat($this->separators[0], $gridWidth); | |
} | |
} | |
} | |
/** | |
* Creates array structure for $this->data and fills it with empty strings | |
*/ | |
private function initData() { | |
for ($row = 1; $row <= $this->rows; $row++) { | |
$this->data[$row] = array_fill(1, $this->columns, ''); | |
} | |
} | |
/** | |
* @param int $column | |
* @return int | |
*/ | |
private function getMaxColumnWidth($column) { | |
$columns = array_column($this->data, $column); | |
if (!empty($this->headers)) { | |
$columns = array_merge([$this->headers[$column]], $columns); | |
} | |
$columnLengths = array_map(function($column) { | |
return max(array_map('strlen', explode(PHP_EOL, $column))); | |
}, $columns); | |
return max($columnLengths); | |
} | |
/** | |
* @param int $row | |
* @return int | |
*/ | |
private function getMaxRowHeight($row) { | |
$columnLines = array_map(function($column) { | |
return count(explode(PHP_EOL, $column)); | |
}, $this->data[$row]); | |
return max($columnLines); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment