4
4
5
5
namespace Brendt \SparkLine ;
6
6
7
- use DateTimeImmutable ;
8
- use Illuminate \Support \Collection ;
9
7
use Ramsey \Uuid \Uuid ;
10
- use Spatie \Period \Period ;
11
8
12
9
final class SparkLine
13
10
{
14
- private Collection $ days ;
11
+ /** @var \Brendt\SparkLine\SparkLineEntry[] */
12
+ private array $ entries ;
15
13
16
14
private int $ maxValue ;
17
15
@@ -23,40 +21,30 @@ final class SparkLine
23
21
24
22
private int $ strokeWidth = 2 ;
25
23
26
- private array $ colors = [ ' #c82161 ' , ' #fe2977 ' , ' #b848f5 ' , ' #b848f5 ' ] ;
24
+ private array $ colors ;
27
25
28
- public static function new (Collection $ days ): self
29
- {
30
- return new self ($ days );
31
- }
26
+ private string $ id ;
32
27
33
- public function __construct (Collection $ days )
28
+ public function __construct (SparkLineEntry | int ... $ entries )
34
29
{
35
- $ this ->days = $ days
36
- ->sortBy (fn (SparkLineDay $ day ) => $ day ->day ->getTimestamp ())
37
- ->mapWithKeys (fn (SparkLineDay $ day ) => [$ day ->day ->format ('Y-m-d ' ) => $ day ]);
30
+ $ this ->id = Uuid::uuid4 ()->toString ();
38
31
39
- $ this ->maxValue = $ this ->resolveMaxValueFromDays ();
40
- $ this ->maxItemAmount = $ this ->resolveMaxItemAmountFromDays ();
41
- }
32
+ $ this ->entries = array_map (
33
+ fn (SparkLineEntry |int $ entry ) => is_int ($ entry ) ? new SparkLineEntry ($ entry ) : $ entry ,
34
+ $ entries
35
+ );
42
36
43
- public function getTotal (): int
44
- {
45
- return $ this ->days -> sum ( fn ( SparkLineDay $ day ) => $ day -> count ) ?? 0 ;
37
+ $ this -> maxValue = $ this -> resolveMaxValue ( $ this -> entries );
38
+ $ this -> maxItemAmount = $ this -> resolveMaxItemAmount ( $ this -> entries );
39
+ $ this ->colors = $ this -> resolveColors ([ ' #c82161 ' , ' #fe2977 ' , ' #b848f5 ' , ' #b848f5 ' ]) ;
46
40
}
47
41
48
- public function getPeriod (): ? Period
42
+ public function getTotal (): int
49
43
{
50
- $ start = $ this ->days ->first ()?->day;
51
- $ end = $ this ->days ->last ()?->day;
52
-
53
- if (! $ start || ! $ end ) {
54
- return null ;
55
- }
56
-
57
- return Period::make (
58
- $ start ,
59
- $ end ,
44
+ return array_reduce (
45
+ $ this ->entries ,
46
+ fn (int $ carry , SparkLineEntry $ entry ) => $ carry + $ entry ->count ,
47
+ 0
60
48
);
61
49
}
62
50
@@ -83,7 +71,7 @@ public function withMaxValue(?int $maxValue): self
83
71
{
84
72
$ clone = clone $ this ;
85
73
86
- $ clone ->maxValue = $ maxValue ?? $ clone ->resolveMaxValueFromDays ( );
74
+ $ clone ->maxValue = $ maxValue ?? $ clone ->resolveMaxValue ( $ this -> entries );
87
75
88
76
return $ clone ;
89
77
}
@@ -92,7 +80,7 @@ public function withMaxItemAmount(?int $maxItemAmount): self
92
80
{
93
81
$ clone = clone $ this ;
94
82
95
- $ clone ->maxItemAmount = $ maxItemAmount ?? $ clone ->resolveMaxItemAmountFromDays ( );
83
+ $ clone ->maxItemAmount = $ maxItemAmount ?? $ clone ->resolveMaxItemAmount ( $ this -> entries );
96
84
97
85
return $ clone ;
98
86
}
@@ -101,20 +89,13 @@ public function withColors(string ...$colors): self
101
89
{
102
90
$ clone = clone $ this ;
103
91
104
- $ clone ->colors = $ colors ;
92
+ $ clone ->colors = $ this -> resolveColors ( $ colors) ;
105
93
106
94
return $ clone ;
107
95
}
108
96
109
97
public function make (): string
110
98
{
111
- $ coordinates = $ this ->resolveCoordinates ();
112
- $ colors = $ this ->resolveColors ();
113
- $ width = $ this ->width ;
114
- $ height = $ this ->height ;
115
- $ strokeWidth = $ this ->strokeWidth ;
116
- $ id = Uuid::uuid4 ()->toString ();
117
-
118
99
ob_start ();
119
100
120
101
include __DIR__ . '/sparkLine.view.php ' ;
@@ -131,55 +112,47 @@ public function __toString(): string
131
112
return $ this ->make ();
132
113
}
133
114
134
- private function resolveColors (): array
115
+ public function getCoordinates (): string
135
116
{
136
- $ percentageStep = floor (100 / count ($ this ->colors ));
117
+ $ divider = min ($ this ->width , $ this ->maxItemAmount );
118
+
119
+ $ step = floor ($ this ->width / $ divider );
120
+
121
+ $ coordinates = [];
122
+
123
+ foreach ($ this ->entries as $ index => $ entry ) {
124
+ $ coordinates [] = $ index * $ step . ', ' . $ entry ->rebase ($ this ->height - 5 , $ this ->maxValue )->count ;
125
+ }
126
+
127
+ return implode (' ' , $ coordinates );
128
+ }
129
+
130
+ private function resolveColors (array $ colors ): array
131
+ {
132
+ $ percentageStep = floor (100 / count ($ colors ));
137
133
138
134
$ colorsWithPercentage = [];
139
135
140
- foreach ($ this -> colors as $ i => $ color ) {
136
+ foreach ($ colors as $ i => $ color ) {
141
137
$ colorsWithPercentage [$ i * $ percentageStep ] = $ color ;
142
138
}
143
139
144
140
return $ colorsWithPercentage ;
145
141
}
146
142
147
- private function resolveMaxValueFromDays ( ): int
143
+ private function resolveMaxValue ( array $ entries ): int
148
144
{
149
- if ($ this -> days -> isEmpty () ) {
145
+ if ($ entries === [] ) {
150
146
return 0 ;
151
147
}
152
148
153
- return $ this ->days
154
- ->sortByDesc (fn (SparkLineDay $ day ) => $ day ->count )
155
- ->first ()
156
- ->count ;
157
- }
149
+ usort ($ entries , fn (SparkLineEntry $ a , SparkLineEntry $ b ) => $ a ->count <=> $ b ->count );
158
150
159
- private function resolveMaxItemAmountFromDays (): int
160
- {
161
- return max ($ this ->days ->count (), 1 );
151
+ return $ entries [array_key_last ($ entries )]->count ;
162
152
}
163
153
164
- private function resolveCoordinates ( ): string
154
+ private function resolveMaxItemAmount ( array $ entries ): int
165
155
{
166
- $ step = floor ($ this ->width / $ this ->maxItemAmount );
167
-
168
- return collect (range (0 , $ this ->maxItemAmount ))
169
- ->map (fn (int $ days ) => (new DateTimeImmutable ("- {$ days } days " ))->format ('Y-m-d ' ))
170
- ->reverse ()
171
- ->mapWithKeys (function (string $ key ) {
172
- /** @var SparkLineDay|null $day */
173
- $ day = $ this ->days [$ key ] ?? null ;
174
-
175
- return [
176
- $ key => $ day
177
- ? $ day ->rebase ($ this ->height - 5 , $ this ->maxValue )->count
178
- : 1 , // Default value is 1 because 0 renders too small a line
179
- ];
180
- })
181
- ->values ()
182
- ->map (fn (int $ count , int $ index ) => $ index * $ step . ', ' . $ count )
183
- ->implode (' ' );
156
+ return max (count ($ entries ), 1 );
184
157
}
185
158
}
0 commit comments