PHPackages                             mistralys/column-widths-calculator - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. mistralys/column-widths-calculator

ActiveLibrary

mistralys/column-widths-calculator
==================================

PHP column widths calculator utility.

2.1.0(3w ago)01.8kMITPHPPHP &gt;=8.4

Since Jul 6Pushed 3w ago3 watchersCompare

[ Source](https://github.com/Mistralys/column-widths-calculator)[ Packagist](https://packagist.org/packages/mistralys/column-widths-calculator)[ RSS](/packages/mistralys-column-widths-calculator/feed)WikiDiscussions main Synced today

READMEChangelog (6)Dependencies (4)Versions (8)Used By (0)

Column widths calculator
========================

[](#column-widths-calculator)

Small utility that can be used to convert arbitrary numeric values to column widths. Given a list of column names and values, it will intelligently convert the values to percentages, and fill empty columns with meaningful values.

**Features:**

- Fills empty values with meaningful values
- Converts any values to percentages, using proportional calculations
- Ensures that the total always matches 100% exactly

Installation
------------

[](#installation)

Using composer, simply require the package.

Via command line:

```
composer require mistralys/column-widths-calculator

```

Via composer.json:

```
"require" :
{
    "mistralys/column-widths-calculator": "^1.0"
}

```

Usage
-----

[](#usage)

Use the factory method to instantiate the calculator:

```
$columns = array(
    'Col1' => 20,
    'Col2' => 0,
    'Col3' => 40
);

$calc =  Calculator::create($columns);

$converted = $calc->getValues();
```

This will return an array with the same keys, and the missing column value filled out:

```
array(
    'Col1' => 20,
    'Col2' => 40,
    'Col3' => 40
);
```

Fluent interface
----------------

[](#fluent-interface)

All configuration methods return the `Calculator` instance, allowing calls to be chained:

```
$calc = Calculator::create($columns)
    ->setMaxTotal(200)
    ->setMinWidth(10)
    ->setFloatValues();

$converted = $calc->getValues();
```

Switching between integers and floats
-------------------------------------

[](#switching-between-integers-and-floats)

By default, the calculator will produce integer values, even if all internal calculations are float based for precision. This can be turned off to retrieve float values:

```
$calc = Calculator::create($columns);
$calc->setFloatValues();
```

In this case, no rounding is done at all - you will have to manually handle any rounding you wish to apply.

To check whether the calculator is currently operating in integer mode, use `isIntegerMode()`:

```
$calc = Calculator::create($columns);
$calc->isIntegerMode(); // true (default)

$calc->setFloatValues();
$calc->isIntegerMode(); // false
```

Handling minimum widths
-----------------------

[](#handling-minimum-widths)

When leaving columns empty to be automatically filled, there may not be enough width left for the columns to fill. Consider this configuration of columns:

```
Col1 = 80
Col2 = 20
Col3 = 0

```

By default, the calculator will guarantee that every column has a minimum width of `1`. As a result, the list would be adjusted like this, to allow the third column to have a width:

```
Col1 = 79
Col2 = 20
Col3 = 1

```

The surplus is subtracted from all non-empty columns, proportionally to their size (without going below the minimum width).

### Setting the minimum size

[](#setting-the-minimum-size)

The minimum size can be set like this:

```
$calc = Calculator::create($columns);
$calc->setMinWidth(20);
```

This will ensure that all columns have a minimum size of 20%.

Example:

```
Col1 = 80
Col2 = 20
Col3 = 0

```

Would give the following result:

```
Col1 = 60
Col2 = 20
Col3 = 20

```

NOTE: The maximum possible value for the minimum size depends on the amount of columns. Trying to set the minimum size to 40% for 3 columns for example, will throw `\InvalidArgumentException` with code `Calculator::ERROR_INVALID_MIN_WIDTH` (61501), because 40 × 3 exceeds 100. Use `getMaxMinWidth()` to query the safe upper bound before calling `setMinWidth()`.

NOTE: Calling `setMinWidth()` on a `Calculator` created with an empty column array (`Calculator::create([])`) throws `\InvalidArgumentException` with code `Calculator::ERROR_EMPTY_COLUMN_ARRAY` (61502). Use `getMaxMinWidth()` to query the maximum safe value before calling `setMinWidth()` — it returns `0.0` on an empty array.

Arbitrary numbering
-------------------

[](#arbitrary-numbering)

The calculator can work with any number system, and converts the values proportionally.

Consider the following values:

```
Col1 = 1400
Col2 = 900
Col3 = 700

```

This will be converted to the following values:

```
Col1 = 38
Col2 = 33
Col3 = 30

= 100%

```

### Missing values

[](#missing-values)

As long as there are more than one column with values, missing values will be filled with a value based on an average of the existing values, to get realistic results.

For example, the values:

```
Col1 = 1400
Col2 = 900
Col3 = 0
Col4 = 0

```

Will be converted to this:

```
Col1 = 30
Col2 = 19
Col3 = 25
Col4 = 26

= 100%

```

Changing the target value
-------------------------

[](#changing-the-target-value)

By default, the Calculator assumes you want to work with percentages, and has the target value locked to 100. However, it is possible to adjust this value:

```
$calc = Calculator::create($columns);
$calc->setMaxTotal(1000);
```

In the example above, the column widths will be calculated to reach a total of 1000, instead of the default 100.

Edge cases
----------

[](#edge-cases)

### Negative values

[](#negative-values)

Column values that are negative are treated identically to `0` — they are considered **missing** and will be filled automatically, exactly like an empty column:

```
$calc = Calculator::create(['A' => -10, 'B' => 50, 'C' => 0]);
$result = $calc->getValues();
// 'A' receives a positive width, same as if it were 0
```

### Empty column array

[](#empty-column-array)

Passing an empty array to `Calculator::create([])` does not throw immediately. However, several methods throw `\InvalidArgumentException` with code `Calculator::ERROR_EMPTY_COLUMN_ARRAY` (61502) when called on a calculator with no columns:

- `getValues()` — guard fires at the top of the calculation pipeline.
- `setMinWidth(float $width)` — guard fires before the internal width-limit check, preventing a `DivisionByZeroError`.

```
// Both will throw \InvalidArgumentException (code 61502):
$calc = Calculator::create([]);
$calc->setMinWidth(5);    // throws
$calc->getValues();       // throws
```

`getMaxMinWidth()` is safe to call on an empty-array calculator — it returns `0.0` without performing any division:

```
$max = Calculator::create([])->getMaxMinWidth(); // 0.0, no exception
```

To handle this defensively:

```
try {
    $result = Calculator::create([])->getValues();
} catch (\InvalidArgumentException $e) {
    if ($e->getCode() === Calculator::ERROR_EMPTY_COLUMN_ARRAY) {
        // No columns were provided
    }
}
```

Always ensure at least one column is present before calling `setMinWidth()` or `getValues()`.

---

Converting to absolute pixel values
-----------------------------------

[](#converting-to-absolute-pixel-values)

For convenience, the `getPixelValues()` method can convert the column percentages to absolute pixel values, given the maximum target width.

The following example converts the column widths to reach a width of 600px:

```
$cols = array(
    'Col1' => 40,
    'Col2' => 40,
    'Col3' => 20
);

$calc = Calculator::create($columns);

$pixelWidths = $calc->getPixelValues(600);
```

The resulting widths will be:

```
Col1 = 207
Col2 = 207
Col3 = 186

= 600

```

---

Development
-----------

[](#development)

### Running the test suite

[](#running-the-test-suite)

```
composer test

```

Additional convenience aliases:

CommandPurpose`composer test`Run the full PHPUnit test suite`composer test-suite `Run a specific PHPUnit test suite by name`composer test-filter `Run tests matching a name pattern`composer test-group `Run tests belonging to a PHPUnit group### Static analysis

[](#static-analysis)

The project uses [PHPStan](https://phpstan.org/) at **level 9** (maximum strictness), configured via `docs/config/phpstan.neon`.

Run the analyser:

```
composer analyze

```

Or directly:

```
vendor/bin/phpstan analyse --configuration docs/config/phpstan.neon

```

To save the analysis report to `phpstan-result.txt` locally:

```
composer analyze-save

```

> **Note:** `analyze-save` suppresses the non-zero exit code (`|| true`) so that the report file is always written. This alias is **not suitable for CI pipelines** — use `composer analyze` there instead.

To clear the PHPStan result cache:

```
composer analyze-clear

```

### Code style

[](#code-style)

The project uses [PHP-CS-Fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) for automated code style enforcement, configured via `.php-cs-fixer.php`. The ruleset is [PSR-12](https://www.php-fig.org/psr/psr-12/) with Allman-style braces for function and OOP constructs (class, method, anonymous function declaration bodies).

Check whether any files need reformatting (dry-run, no changes written):

```
composer cs-check

```

Apply automatic fixes:

```
composer cs-fix

```

> **Note:** PHP-CS-Fixer may emit a non-fatal version-mismatch warning when the runtime PHP version differs from the project target (8.4). This does not affect correctness; the exit code remains 0. The generated cache file (`.php-cs-fixer.cache`) is excluded from version control via `.gitignore`.

###  Health Score

54

—

FairBetter than 97% of packages

Maintenance94

Actively maintained with recent releases

Popularity19

Limited adoption so far

Community10

Small or concentrated contributor base

Maturity77

Established project with proven stability

 Bus Factor1

Top contributor holds 98.4% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~411 days

Recently: every ~514 days

Total

6

Last Release

26d ago

Major Versions

1.0.3 → 2.0.02022-06-09

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/8895528?v=4)[Mistralys](/maintainers/Mistralys)[@Mistralys](https://github.com/Mistralys)

---

Top Contributors

[![Mistralys](https://avatars.githubusercontent.com/u/8895528?v=4)](https://github.com/Mistralys "Mistralys (60 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (1 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/mistralys-column-widths-calculator/health.svg)

```
[![Health](https://phpackages.com/badges/mistralys-column-widths-calculator/health.svg)](https://phpackages.com/packages/mistralys-column-widths-calculator)
```

###  Alternatives

[mistralys/text-diff

Class used to compare strings using a DIFF implementation.

27110.8k3](/packages/mistralys-text-diff)[mistralys/markdown-viewer

PHP based viewer for Markdown files, to view them with fenced code highlighting and navigation.

101.4k2](/packages/mistralys-markdown-viewer)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
