Dataset   A
last analyzed

Complexity

Total Complexity 25

Size/Duplication

Total Lines 189
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 25
eloc 47
c 1
b 0
f 0
dl 0
loc 189
ccs 65
cts 65
cp 1
rs 10

15 Methods

Rating   Name   Duplication   Size   Complexity  
A count() 0 3 1
A labels() 0 3 1
A fromIterable() 0 8 2
A __construct() 0 3 1
A append() 0 19 5
A setBoundaries() 0 9 2
A labelMaxLength() 0 3 1
A items() 0 3 1
A isEmpty() 0 3 1
A boundaries() 0 3 1
A getIterator() 0 4 2
A fromItems() 0 16 2
A jsonSerialize() 0 7 1
A setLabelMaxLength() 0 5 2
A appendAll() 0 4 2
1
<?php
2
3
/**
4
 * League.Period (https://period.thephpleague.com)
5
 *
6
 * (c) Ignace Nyamagana Butera <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace League\Period\Chart;
15
16
use League\Period\Period;
17
use League\Period\Sequence;
18
use function array_column;
19
use function count;
20
use function gettype;
21
use function is_scalar;
22
use function method_exists;
23
use function strlen;
24
25
final class Dataset implements Data
26
{
27
    /**
28
     * @var array<int, array{0:string, 1:Sequence}>.
29
     */
30
    private $pairs = [];
31
32
    /**
33
     * @var int
34
     */
35
    private $labelMaxLength = 0;
36
37
    /**
38
     * @var Period|null
39
     */
40
    private $boundaries;
41
42
    /**
43
     * constructor.
44
     */
45 39
    public function __construct(iterable $pairs = [])
46
    {
47 39
        $this->appendAll($pairs);
48 33
    }
49
50
    /**
51
     * Creates a new collection from a countable iterable structure.
52
     *
53
     * @param array|(\Countable&iterable) $items
54
     * @param ?LabelGenerator             $labelGenerator
55
     */
56 9
    public static function fromItems($items, ?LabelGenerator $labelGenerator = null): self
57
    {
58 9
        $nbItems = count($items);
59
        $items = (function () use ($items): \Iterator {
60 9
            foreach ($items as $key => $value) {
61 9
                yield $key => $value;
62
            }
63 9
        })();
64
65 9
        $labelGenerator = $labelGenerator ?? new LatinLetter();
66
67 9
        $pairs = new \MultipleIterator(\MultipleIterator::MIT_NEED_ALL|\MultipleIterator::MIT_KEYS_ASSOC);
68 9
        $pairs->attachIterator($labelGenerator->generate($nbItems), '0');
69 9
        $pairs->attachIterator($items, '1');
70
71 9
        return new self($pairs);
72
    }
73
74
    /**
75
     * Creates a new collection from a generic iterable structure.
76
     */
77 15
    public static function fromIterable(iterable $iterable): self
78
    {
79 15
        $dataset = new self();
80 15
        foreach ($iterable as $label => $item) {
81 12
            $dataset->append($label, $item);
82
        }
83
84 15
        return $dataset;
85
    }
86
87
    /**
88
     * {@inheritDoc}
89
     */
90 39
    public function appendAll(iterable $pairs): void
91
    {
92 39
        foreach ($pairs as [$label, $item]) {
93 21
            $this->append($label, $item);
94
        }
95 33
    }
96
97
    /**
98
     * {@inheritDoc}
99
     */
100 33
    public function append($label, $item): void
101
    {
102 33
        if (!is_scalar($label) && !method_exists($label, '__toString')) {
103 3
            throw new \TypeError('The label passed to '.__METHOD__.' must be a scalar or an stringable object, '.gettype($label).' given.');
104
        }
105
106 30
        if ($item instanceof Period) {
107 15
            $item = new Sequence($item);
108
        }
109
110 30
        if (!$item instanceof Sequence) {
111 3
            throw new \TypeError('The item passed to '.__METHOD__.' must be a '.Period::class.' or a '.Sequence::class.' instance, '.gettype($item).' given.');
112
        }
113
114 27
        $label = (string) $label;
115 27
        $this->setLabelMaxLength($label);
116 27
        $this->setBoundaries($item);
117
118 27
        $this->pairs[] = [$label, $item];
119 27
    }
120
121
    /**
122
     * Computes the label maximum length for the dataset.
123
     */
124 27
    private function setLabelMaxLength(string $label): void
125
    {
126 27
        $labelLength = strlen($label);
127 27
        if ($this->labelMaxLength < $labelLength) {
128 27
            $this->labelMaxLength = $labelLength;
129
        }
130 27
    }
131
132
    /**
133
     * Computes the Period boundary for the dataset.
134
     */
135 27
    private function setBoundaries(Sequence $sequence): void
136
    {
137 27
        if (null === $this->boundaries) {
138 27
            $this->boundaries = $sequence->boundaries();
139
140 27
            return;
141
        }
142
143 18
        $this->boundaries = $this->boundaries->merge(...$sequence);
144 18
    }
145
146
    /**
147
     * {@inheritDoc}
148
     */
149 21
    public function count(): int
150
    {
151 21
        return count($this->pairs);
152
    }
153
154
    /**
155
     * {@inheritDoc}
156
     */
157 3
    public function getIterator(): \Iterator
158
    {
159 3
        foreach ($this->pairs as $pair) {
160 3
            yield $pair;
161
        }
162 3
    }
163
164
    /**
165
     * {@inheritDoc}
166
     */
167 3
    public function jsonSerialize(): array
168
    {
169
        $mapper = static function (array $pair): array {
170 3
            return ['label' => $pair[0], 'item' => $pair[1]];
171 3
        };
172
173 3
        return array_map($mapper, $this->pairs);
174
    }
175
176
    /**
177
     * {@inheritDoc}
178
     */
179 18
    public function isEmpty(): bool
180
    {
181 18
        return [] === $this->pairs;
182
    }
183
184
    /**
185
     * {@inheritDoc}
186
     */
187 6
    public function labels(): array
188
    {
189 6
        return array_column($this->pairs, 0);
190
    }
191
192
    /**
193
     * {@inheritDoc}
194
     */
195 9
    public function items(): array
196
    {
197 9
        return array_column($this->pairs, 1);
198
    }
199
200
    /**
201
     * {@inheritDoc}
202
     */
203 15
    public function boundaries(): ?Period
204
    {
205 15
        return $this->boundaries;
206
    }
207
208
    /**
209
     * {@inheritDoc}
210
     */
211 6
    public function labelMaxLength(): int
212
    {
213 6
        return $this->labelMaxLength;
214
    }
215
}
216