bakame/period-visualizer

A Visualizer for League Period.

0.4.0 2019-06-17 20:16 UTC

README

Author Build Status Total Downloads Latest Stable Version Software License

This package contains a visualizer for League Period.

It is inspired from the work of @thecrypticace on the following PR Visualization Helper.

<?php

use Bakame\Period\Visualizer\Viewer;
use League\Period\Period;
use League\Period\Sequence;

$view = new Viewer();
echo $view->sequence(new Sequence(
    new Period('2018-01-01', '2018-02-01'),
    new Period('2018-01-15', '2018-02-01')
));

results:

 A    [==============================================================================)
 B                                        [==========================================)

System Requirements

You need:

  • PHP >= 7.2 but the latest stable version of PHP is recommended
  • League/Period 4.4+ but the latest stable version is recommended

Installation

$ composer require bakame/period-visualizer

Usage

Basic Usage

Viewing a Sequence collection.

<?php

use Bakame\Period\Visualizer\Viewer;
use League\Period\Period;
use League\Period\Sequence;

$view = new Viewer();
echo $view->sequence(new Sequence(
    new Period('2018-01-01', '2018-02-01'),
    new Period('2018-01-01', '2018-01-15')
));

results:

 A    [==============================================================================)
 B                                        [==========================================)

Viewing a Sequence gaps.

$view = new Viewer();
echo $view->gaps(new Sequence(
    new Period('2018-01-01', '2018-03-01'),
    new Period('2018-05-01', '2018-08-01')
));

results:

 A       [=====================)                                                         
 B                                                    [=================================)
 GAPS                          [======================)    

Viewing a Sequence intersections.

$view = new Viewer();
echo $view->intersections(new Sequence(
    new Period('2018-01-01 08:00:00', '2018-01-01 12:00:00'),
    new Period('2018-01-01 10:00:00', '2018-01-01 14:00:00')
));

results:

 A                [====================================================)                          
 B                                          [====================================================)
 INTERSECTIONS                              [==========================) 

Viewing a Period difference.

$view = new Viewer();
echo $view->diff(
    new Period('2018-01-01 08:00:00', '2018-01-01 12:00:00'),
    new Period('2018-01-01 10:00:00', '2018-01-01 14:00:00')
);

results:

 A       [====================================================)                          
 B                                 [====================================================)
 DIFF    [=========================)                          [=========================)

Advance Usage

Customize the line labels

The Bakame\Period\Visualizer\Viewer class can be further formatter by providing a object to improve line index generation. By default the class is instantiated with the letter index strategy which starts incrementing the labels from the 'A' index. You can choose between the following strategies to modify the default behaviour

Letter strategy

use Bakame\Period\Visualizer\Viewer;
use Bakame\Period\Visualizer\Label\LetterGenerator;
use League\Period\Period;
use League\Period\Sequence;

$view = new Viewer(new LetterGenerator('aa'));
echo $view->sequence(new Sequence(
    new Period('2018-01-01', '2018-02-01'),
    new Period('2018-01-01', '2018-01-15')
));

results:

 aa    [==============================================================================)
 ab    [===================================)     

Integer strategy

use Bakame\Period\Visualizer\Viewer;
use Bakame\Period\Visualizer\Label\IntegerGenerator;
use League\Period\Period;
use League\Period\Sequence;

$view = new Viewer(new IntegerGenerator(42));
echo $view->sequence(new Sequence(
    new Period('2018-01-01', '2018-02-01'),
    new Period('2018-01-01', '2018-01-15')
));

results:

 42    [==============================================================================)
 43    [===================================)     

Roman Number strategy

use Bakame\Period\Visualizer\Viewer;
use Bakame\Period\Visualizer\Label\IntegerGenerator;
use Bakame\Period\Visualizer\Label\RomanGenerator;
use League\Period\Period;
use League\Period\Sequence;

$labelGenerator = new RomanGenerator(new IntegerGenerator(5), RomanGenerator::LOWER);

$view = new Viewer($labelGenerator);
echo $view->sequence(new Sequence(
    new Period('2018-01-01', '2018-02-01'),
    new Period('2018-01-01', '2018-01-15')
));

results:

 v     [==============================================================================)
 vi    [===================================)    

Affix strategy

use Bakame\Period\Visualizer\Viewer;
use Bakame\Period\Visualizer\Label\IntegerGenerator;
use Bakame\Period\Visualizer\Label\RomanGenerator;
use Bakame\Period\Visualizer\Label\AffixGenerator;
use League\Period\Period;
use League\Period\Sequence;

$labelGenerator = new AffixGenerator(
    new RomanGenerator(new IntegerGenerator(5), RomanGenerator::LOWER),
    '*', //prefix
    '.)'    //suffix
);
$view = new Viewer($labelGenerator);
echo $view->sequence(new Sequence(
    new Period('2018-01-01', '2018-02-01'),
    new Period('2018-01-01', '2018-01-15')
));

results:

 *v.)     [==============================================================================)
 *vi.)    [===================================)      

Reverse strategy

use Bakame\Period\Visualizer\Viewer;
use Bakame\Period\Visualizer\Label\IntegerGenerator;
use Bakame\Period\Visualizer\Label\RomanGenerator;
use Bakame\Period\Visualizer\Label\AffixGenerator;
use Bakame\Period\Visualizer\Label\ReverseGenerator;
use League\Period\Period;
use League\Period\Sequence;

$labelGenerator = new AffixGenerator(new RomanGenerator(new IntegerGenerator(5), RomanGenerator::LOWER));
$labelGenerator = new ReverseGenerator($labelGenerator->withSuffix('.'));

$view = new Viewer($labelGenerator);
echo $view->sequence(new Sequence(
    new Period('2018-01-01', '2018-02-01'),
    new Period('2018-01-01', '2018-01-15')
));

results:

 vi.   [==============================================================================)
 v.    [===================================)     

Custom strategy

You can create your own strategy by implementing the Bakame\Period\Visualizer\Label\LabelGenerator interface like shown below:

use Bakame\Period\Visualizer\Label\AffixGenerator;
use Bakame\Period\Visualizer\Label\LabelGenerator;
use Bakame\Period\Visualizer\Viewer;
use League\Period\Period;
use League\Period\Sequence;

$samelabel = new class implements LabelGenerator {
    public function generate(Sequence $sequence): array
    {
        return array_fill(0, count($sequence), 'foobar');
    }
        
    public function format($str): string
    {
        return (string) $str;
    }
};

$labelGenerator = (new AffixGenerator($samelabel))->withSuffix('.');

$view = new Viewer($labelGenerator);
echo $view->sequence(new Sequence(
    new Period('2018-01-01', '2018-02-01'),
    new Period('2018-01-01', '2018-01-15')
));

results:

 foobar.    [==============================================================================)
 foobar.    [===================================)     

Customize the output

Under the hood, the Viewer class uses the ConsoleOutput class to generate your graph.

use Bakame\Period\Visualizer\ConsoleOutput;
use League\Period\Period;

$view = new ConsoleOutput();
echo $view->display([
    ['first', new Period('2018-01-01 08:00:00', '2018-01-01 12:00:00')],
    ['last', new Period('2018-01-01 10:00:00', '2018-01-01 14:00:00')],
]);

results:

 first    [====================================================)                          
 last                               [====================================================)

The ConsoleOutput::display methods expects a tuple as its unique argument where:

  • the first value of the tuple represents the label name
  • the second and last value represents a Period or Sequence object.

The ConsoleOutput class can be customized by providing a ConsoleConfig which defines the output settings.

use Bakame\Period\Visualizer\ConsoleConfig;
use Bakame\Period\Visualizer\ConsoleOutput;
use Bakame\Period\Visualizer\Label\LabelGenerator;
use Bakame\Period\Visualizer\Viewer;
use League\Period\Period;

$config = (new ConsoleConfig())
    ->withStartExcluded('🍕')
    ->withStartIncluded('🍅')
    ->withEndExcluded('🎾')
    ->withEndIncluded('🍔')
    ->withWidth(30)
    ->withSpace('💩')
    ->withBody('😊')
    ->withColors('yellow', 'red')
;

$fixedLabels = new class implements LabelGenerator {
    public function generate(Sequence $sequence): array
    {
        return ['first', 'last'];
    }
    
    public function format($str): string
    {
        return (string) $str;
    }
};

$output = new ConsoleOutput($config);
$viewer = new Viewer($fixedLabels, $output);

echo $viewer->sequence(new Sequence(
    new Period('2018-01-01 08:00:00', '2018-01-01 12:00:00', Period::EXCLUDE_ALL),
    new Period('2018-01-01 10:00:00', '2018-01-01 14:00:00', Period::INCLUDE_ALL)
));

results:

 first    🍕😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊🎾💩💩💩💩💩💩💩💩💩💩
 last     💩💩💩💩💩💩💩💩💩💩🍅😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊😊🍔

On a POSIX compliant console the first line will be yellow and the second red

ConsoleConfig is immutable, modifying its properties returns a new instance with the updated values.

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Contributions are welcome and will be fully credited. Please see CONTRIBUTING for details.

Testing

The library has a :

  • a PHPUnit test suite
  • a coding style compliance test suite using PHP CS Fixer.
  • a code analysis compliance test suite using PHPStan.

To run the tests, run the following command from the project folder.

$ composer test

Security

If you discover any security related issues, please email nyamsprod@gmail.com instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.