Visualizing Period and Sequence instances

If you need to visualize multiple Period or Sequence instances you can now visualize them easily with the provided charting feature.

The Sequence class is introduced in version 4.10.

Here’s a complex example which highlights most of the features introduces along visualizing Period and Sequance instances:


use League\Period\Chart\AffixLabel;
use League\Period\Chart\ConsoleOutput;
use League\Period\Chart\Dataset;
use League\Period\Chart\DecimalNumber;
use League\Period\Chart\GanttChart;
use League\Period\Chart\GanttChartConfig;
use League\Period\Chart\ReverseLabel;
use League\Period\Chart\RomanNumber;
use League\Period\Datepoint;
use League\Period\Period;
use League\Period\Sequence;

$config = GanttChartConfig::createFromRainbow()
    ->withOutput(new ConsoleOutput(STDOUT))

$labelGenerator = new DecimalNumber(42);
$labelGenerator = new RomanNumber($labelGenerator, RomanNumber::UPPER);
$labelGenerator = new AffixLabel($labelGenerator, '', '.');
$labelGenerator = new ReverseLabel($labelGenerator);

$sequence = new Sequence(
    Datepoint::create('2018-05-29')->getMonth()->expand('3 MONTH'),
    Period::around('2016-06-01', '3 MONTHS', Period::INCLUDE_ALL)
$dataset = Dataset::fromItems($sequence, $labelGenerator);
$dataset->append($labelGenerator->format('gaps'), $sequence->gaps());
$graph = new GanttChart($config);

which will output in your console:

   XLV.  πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ•πŸ˜ŠπŸ˜ŠπŸ˜ŠπŸ˜ŠπŸ˜ŠπŸ˜ŠπŸ˜ŠπŸ˜ŠπŸ˜ŠπŸ”
  XLIV.  πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ…πŸ˜ŠπŸ˜ŠπŸ˜ŠπŸ˜ŠπŸ˜ŠπŸŽΎπŸ’©πŸ’©πŸ’©
 XLIII.  πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ•πŸ˜ŠπŸ˜ŠπŸŽΎπŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©
  XLII.  πŸ…πŸ˜ŠπŸ˜ŠπŸ˜ŠπŸ˜ŠπŸ”πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©
  GAPS.  πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ•πŸ˜ŠπŸ˜ŠπŸ”πŸ’©πŸ’©πŸ…πŸ˜ŠπŸ˜ŠπŸ˜ŠπŸ˜ŠπŸ˜ŠπŸ˜ŠπŸ˜ŠπŸ”πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©πŸ’©

On a POSIX compliant console all lines have different colors

Generating a simple graph.

To generate a graph you need to give to the Dataset constructor a list of pairs. Each pair is an array containing 2 values:


use League\Period\Chart\Dataset;
use League\Period\Chart\GanttChart;
use League\Period\Period;

$dataset = new Dataset([
    ['A', new Period('2018-01-01', '2018-02-01')],
    ['B', new Period('2018-01-15', '2018-02-01')], 
(new GanttChart())->stroke($dataset);


 A [----------------------------------------------)
 B                      [-------------------------)

Appending items to display

If you want to display a Sequence and some of its operations. You can append the operation results using the Dataset::append method.


use League\Period\Chart\Dataset;
use League\Period\Chart\GanttChart;
use League\Period\Period;
use League\Period\Sequence;

$sequence = new Sequence(
    new Period('2018-01-01', '2018-03-01'),
    new Period('2018-05-01', '2018-08-01')
$dataset = new Dataset();
$dataset->append('A', $sequence[0]);
$dataset->append('B', $sequence[1]);
$dataset->append('GAPS', $sequence->gaps());
(new GanttChart())->stroke($dataset);


 A    [-------------)                                                         
 B                               [----------------)
 GAPS               [------------)    

The Dataset implements the Countable and the IteratorAggregate interface. It also exposes the following methods:

public function Dataset::fromItems($items, ?LabelGenerator $labelGenerator = null): self; //Creates a new Dataset from a collection of Sequence/Periods and a LabelGenerator.
public function Dataset::fromIterable(iterable $iterable): self; //Creates a new Dataset from a generic iterable structure of Sequence/Periods.
public function Dataset::appendAll(iterable $pairs): void; //adds multiple pairs at once.
public function Dataset::isEmpty(): bool; //Tells whether the collection is empty.
public function Dataset::labels(): string[]; //the current labels used
public function Dataset::items(): Sequence[]; //the current objects inside the Dataset
public function Dataset::boundaries(): ?Period;  //Returns the collection boundaries or null if it is empty.
public function Dataset::labelMaxLength(): int;  //Returns the label max length.
public function Dataset::withLabels(LabelGenerator $labelGenerator): self; //Update the labels used for the dataset.

Displaying the Dataset

The GanttChart class is responsible for generating the graph from the Dataset by implementing the Graph interface for the console.

The GanttChart::stroke methods expects a Dataset object as its unique argument.

If you wish to present the graph on another medium like a web browser or an image, you will need to implement the interface for your implementation.


use League\Period\Chart\Dataset;
use League\Period\Chart\GanttChart;
use League\Period\Period;

$graph = new GanttChart();
$graph->stroke(new Dataset([
    ['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')],


 first [---------------------------)
 last            [------------------------------)

Customized the graph looks

The GanttChart class can be customized by providing a GanttChartConfig which defines:

You can easily create a OutputWriter implementing class with libraries like League CLImate or Symfony Console to output the resulting graph. If you don’t, the package ships with a minimal ConsoleOutput class which is used if you do not provide you own implementation.

The GanttChartConfig class exposes the following additional constants and methods:

const GanttChartConfig::ALIGN_LEFT = 1;
const GanttChartConfig::ALIGN_RIGHT = 0;
const GanttChartConfig::ALIGN_CENTER = 2;
public function GanttChartConfig::__construct(OutputWriter $output);
public function GanttChartConfig::output(): OutputWriter;  //Returns the OutputWriter instance.
public function GanttChartConfig::startExcluded(): string; //Retrieves the excluded start block character.
public function GanttChartConfig::startIncluded(): string; //Retrieves the included start block character.
public function GanttChartConfig::endExcluded(): string;   //Retrieves the excluded end block character.
public function GanttChartConfig::endIncluded(): string;   //Retrieves the included end block character.
public function GanttChartConfig::width(): int;            //Retrieves the max size width.
public function GanttChartConfig::body(): string;          //Retrieves the body block character.
public function GanttChartConfig::space(): string;         //Retrieves the space block character.
public function GanttChartConfig::colors(): string[];      //The selected colors for each row.
public function GanttChartConfig::gapSize(): int;          //Retrieves the gap sequence between the label and the line.
public function GanttChartConfig::labelAlign(): int;       //Returns how label should be aligned.
public function GanttChartConfig::leftMarginSize(): int;   //Retrieves the margin between the label and the console left side.

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