8ctopus / stats-table
Create statistics tables
Requires
- php: ^8.3
- symfony/polyfill-php84: ^1.31
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.8
- phpmd/phpmd: ^2.13
- phpoffice/phpspreadsheet: ^1.9.0
- phpstan/phpstan: ^1.9
- phpunit/phpunit: ^10.0|^11.0
- twig/twig: ^1.0|^2.0|^3.0
Replaces
- dev-master
- 1.5.3
- 1.5.2
- 1.5.1
- 1.5.0
- 1.4.6
- 1.4.5
- 1.4.4
- 1.4.3
- 1.4.2
- 1.4.1
- 1.4.0
- 1.3.0
- 1.2.0
- 1.1.2
- 1.1.1
- 1.1.0
- 1.0.0
- 0.10.0
- 0.9.0
- dev-cleanup-html-table
- dev-improve-readme
- dev-add-text-dump
- dev-cleanup-code
- dev-fix-php-8.4-compatibility
- dev-fix-dynamic-property-creation-deprecated
- dev-fix-tests-on-windows
This package is auto-updated.
Last update: 2025-01-17 07:24:11 UTC
README
Create statistics tables and export them to text, JSON, CSV or Excel.
introduction
This package facilitates the creation of statistical tables from datasets. It provides features including data aggregation (sum, count, average), dynamic column calculations, data grouping and sorting. The generated tables can be exported to text, JSON, CSV, or Excel.
This package is a fork of paxal/stats-table. Migrating from the parent package shouldn't be too hard, but except a bit of work.
installation
composer require 8ctopus/stats-table
usage
The StatsTableBuilder
class helps combine data from multiple tables, build aggregations (column sum, count, average, ...), create calculated columns, and add grouping. While the second class StatsTable
allows to sort the table and remove columns.
examples
Play with the examples in demo.php
.
example 1
First example shows aggregation, dynamic column and table sorting.
$data = [ [ 'name' => 'Pierre', 'age' => 32, 'weight' => 100, 'height' => 1.87, ], [ 'name' => 'Jacques', 'age' => 28, 'weight' => 60, 'height' => 1.67, ], [ 'name' => 'Jean', 'age' => 32, 'weight' => 80, 'height' => 1.98, ], [ 'name' => 'Paul', 'age' => 25, 'weight' => 75, 'height' => 1.82, ], ]; $headers = [ 'name' => 'Name', 'age' => 'Age', 'weight' => 'Weight', 'height' => 'Height', ]; $formats = [ 'name' => Format::String, 'age' => Format::Integer, 'weight' => Format::Float, 'height' => Format::Float, ]; $aggregations = [ new CountAggregation('name', Format::Integer), new AverageAggregation('age', Format::Integer), new AverageAggregation('weight', Format::Integer), new AverageAggregation('height', Format::Float), ]; $builder = new StatsTableBuilder($data, $headers, $formats, $aggregations); // add body mass index row to table $dynamicColumn = new CallbackColumnBuilder(function (array $row) : float { return $row['weight'] / ($row['height'] * $row['height']); }); $table = $builder ->addDynamicColumn('BMI', $dynamicColumn, 'BMI', Format::Float, new AverageAggregation('BMI', Format::Float)) ->build(); $table->sortByColumns([ 'age' => Direction::Ascending, 'height' => Direction::Ascending, ]); $dumper = new TextDumper(); echo $dumper->dump($table);
Name Age Weight Height BMI Paul 25 75.00 1.82 22.64 Jacques 28 60.00 1.67 21.51 Pierre 32 100.00 1.87 28.60 Jean 32 80.00 1.98 20.41 4 29 78 1.84 23.29
example 2
Here's another example with a dynamic column which depends on the aggregation result. We add a column that calculates the percentage of each status. This is useful, for example, when your data comes from a database request, as it drastically simplifies the of the database query.
$data = [ [ 'status' => 'active', 'count' => 80, ], [ 'status' => 'cancelled', 'count' => 20, ], ]; $headers = []; $formats = [ 'status' => Format::String, 'count' => Format::Integer, ]; $aggregations = [ 'count' => new SumAggregation('count', Format::Integer), ]; $builder = new StatsTableBuilder($data, $headers, $formats, $aggregations); // get count column total $total = $aggregations['count']->aggregate($builder); // add percentage column $dynamicColumn = new CallbackColumnBuilder(function (array $row) use ($total) : float { return $row['count'] / $total; }); $table = $builder ->addDynamicColumn('percentage', $dynamicColumn, 'percentage', Format::Percent, new SumAggregation('percentage', Format::Percent)) ->build(); echo (new TextDumper()) ->dump($table);
status count percentage active 80 80% cancelled 20 20% 100 100%
example 3
The third example demonstrates a dynamic column containing consolidated revenue and group by date.
<?php use Oct8pus\StatsTable\Aggregation\SumAggregation; use Oct8pus\StatsTable\Dumper\TextDumper; use Oct8pus\StatsTable\DynamicColumn\CallbackColumnBuilder; use Oct8pus\StatsTable\Format; use Oct8pus\StatsTable\StatsTableBuilder; $data = [ [ 'date' => '2025-01', 'currency' => 'USD', 'amount' => 80, ], [ 'date' => '2025-01', 'currency' => 'USD', 'amount' => 40, ], [ 'date' => '2025-01', 'currency' => 'EUR', 'amount' => 80, ], [ 'date' => '2025-01', 'currency' => 'EUR', 'amount' => 40, ], [ 'date' => '2024-12', 'currency' => 'USD', 'amount' => 80, ], [ 'date' => '2024-12', 'currency' => 'USD', 'amount' => 20, ], [ 'date' => '2024-12', 'currency' => 'EUR', 'amount' => 20, ], [ 'date' => '2024-12', 'currency' => 'EUR', 'amount' => 40, ], ]; $headers = []; $formats = [ 'date' => Format::String, 'currency' => Format::String, 'amount' => Format::Integer, ]; $aggregations = []; $builder = new StatsTableBuilder($data, $headers, $formats, $aggregations); // dynamic column with consolidated revenue in USD $dynamicColumn = new CallbackColumnBuilder(function (array $row) : float { if ($row['currency'] === 'USD') { return $row['amount']; } $EURtoUSD = 1.0295998; return $row['amount'] * $EURtoUSD; }); $builder->addDynamicColumn('consolidated', $dynamicColumn, 'consolidated', Format::Integer, new SumAggregation('consolidated', Format::Integer)); $dumper = new TextDumper(); $table = $builder ->groupBy(['date'], ['currency', 'amount']) ->build(); echo $dumper->dump($table);
date consolidated 2025-01 243 2024-12 161 405