line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Chart::Clicker::Drawing::ColorAllocator; |
2
|
|
|
|
|
|
|
$Chart::Clicker::Drawing::ColorAllocator::VERSION = '2.88'; |
3
|
9
|
|
|
9
|
|
1444487
|
use Moose; |
|
9
|
|
|
|
|
572612
|
|
|
9
|
|
|
|
|
85
|
|
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
# ABSTRACT: Color picker |
6
|
|
|
|
|
|
|
|
7
|
9
|
|
|
9
|
|
72731
|
use Graphics::Color::RGB; |
|
9
|
|
|
|
|
965429
|
|
|
9
|
|
|
|
|
317
|
|
8
|
9
|
|
|
9
|
|
15624
|
use Color::Scheme; |
|
9
|
|
|
|
|
113228
|
|
|
9
|
|
|
|
|
6352
|
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
has 'colors' => ( |
13
|
|
|
|
|
|
|
traits => [ 'Array' ], |
14
|
|
|
|
|
|
|
is => 'rw', |
15
|
|
|
|
|
|
|
isa => 'ArrayRef', |
16
|
|
|
|
|
|
|
default => sub { [] }, |
17
|
|
|
|
|
|
|
handles => { |
18
|
|
|
|
|
|
|
'add_to_colors' => 'push', |
19
|
|
|
|
|
|
|
'clear_colors' => 'clear', |
20
|
|
|
|
|
|
|
'color_count' => 'count', |
21
|
|
|
|
|
|
|
'get_color' => 'get' |
22
|
|
|
|
|
|
|
} |
23
|
|
|
|
|
|
|
); |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
has 'position' => ( is => 'rw', isa => 'Int', default => -1 ); |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
has 'color_scheme' => ( |
30
|
|
|
|
|
|
|
is => 'rw', |
31
|
|
|
|
|
|
|
isa => 'Color::Scheme', |
32
|
|
|
|
|
|
|
lazy_build => 1, |
33
|
|
|
|
|
|
|
); |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
has 'seed_hue' => ( |
37
|
|
|
|
|
|
|
is => 'rw', |
38
|
|
|
|
|
|
|
isa => 'Int', |
39
|
|
|
|
|
|
|
required => 1, |
40
|
|
|
|
|
|
|
default => sub { 270 }, |
41
|
|
|
|
|
|
|
); |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
has hues => ( |
45
|
|
|
|
|
|
|
is => 'rw', |
46
|
|
|
|
|
|
|
isa => 'ArrayRef', |
47
|
|
|
|
|
|
|
required => 1, |
48
|
|
|
|
|
|
|
lazy => 1, |
49
|
|
|
|
|
|
|
default => sub { |
50
|
|
|
|
|
|
|
my $seed = shift->seed_hue; |
51
|
|
|
|
|
|
|
[ map { ($seed + $_) % 360 } (0, 45, 75, 15, 60, 30) ] |
52
|
|
|
|
|
|
|
}, |
53
|
|
|
|
|
|
|
); |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
has shade_order => ( |
57
|
|
|
|
|
|
|
is => 'rw', |
58
|
|
|
|
|
|
|
isa => 'ArrayRef', |
59
|
|
|
|
|
|
|
required => 1, |
60
|
|
|
|
|
|
|
default => sub { [1, 3, 0, 2] }, |
61
|
|
|
|
|
|
|
); |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
sub _build_color_scheme { |
64
|
1
|
|
|
1
|
|
1
|
my $self = shift; |
65
|
1
|
|
|
|
|
13
|
my $scheme = Color::Scheme->new; |
66
|
1
|
|
|
|
|
455
|
$scheme->scheme('tetrade'); |
67
|
1
|
|
|
|
|
17
|
$scheme->web_safe(1); |
68
|
1
|
|
|
|
|
10
|
$scheme->distance(1); |
69
|
1
|
|
|
|
|
62
|
return $scheme; |
70
|
|
|
|
|
|
|
} |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
sub next { |
74
|
|
|
|
|
|
|
my $self = shift; |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
$self->position($self->position + 1); |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
return $self->colors->[$self->position]; |
79
|
|
|
|
|
|
|
} |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
# Before we attempt to get the next color, we'll instantiate it if we need it |
82
|
|
|
|
|
|
|
# that way we don't waste a bunch of memory with useless colors. |
83
|
|
|
|
|
|
|
before 'next' => sub { |
84
|
|
|
|
|
|
|
my $self = shift; |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
my $pos = $self->position; |
87
|
|
|
|
|
|
|
if(!defined($self->colors->[$pos + 1])) { |
88
|
|
|
|
|
|
|
$self->add_to_colors($self->allocate_color); |
89
|
|
|
|
|
|
|
} |
90
|
|
|
|
|
|
|
}; |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
sub allocate_color { |
94
|
97
|
|
|
97
|
1
|
150
|
my $self = shift; |
95
|
|
|
|
|
|
|
|
96
|
97
|
|
|
|
|
4003
|
my $pos = $self->position + 1; |
97
|
97
|
|
|
|
|
4182
|
my $scheme = $self->color_scheme; |
98
|
|
|
|
|
|
|
|
99
|
97
|
|
|
|
|
153
|
my $hue_cnt = @{ $self->hues }; |
|
97
|
|
|
|
|
3914
|
|
100
|
97
|
|
|
|
|
248
|
my $hue_pos = int($pos / 4) % $hue_cnt; |
101
|
97
|
|
|
|
|
4748
|
$scheme->from_hue($self->hues->[$hue_pos]); |
102
|
|
|
|
|
|
|
|
103
|
97
|
|
|
|
|
8645
|
my $shade_pos = int($pos / ( $hue_cnt * 4)) % 4; |
104
|
97
|
|
|
|
|
4301
|
my $shade_idx = $self->shade_order->[$shade_pos]; |
105
|
97
|
|
|
|
|
167
|
my $color_idx = $pos % 4; |
106
|
|
|
|
|
|
|
|
107
|
97
|
|
|
|
|
304
|
my $color_hex = $scheme->colorset->[$color_idx]->[$shade_idx]; |
108
|
97
|
|
|
|
|
109263
|
my ($r,$g,$b) = ( map{ hex } ($color_hex =~ /(..)(..)(..)/)); |
|
291
|
|
|
|
|
543
|
|
109
|
97
|
|
|
|
|
3854
|
my $color = Graphics::Color::RGB->new( |
110
|
|
|
|
|
|
|
red => $r / 255, |
111
|
|
|
|
|
|
|
green => $g / 255, |
112
|
|
|
|
|
|
|
blue => $b / 255, |
113
|
|
|
|
|
|
|
alpha => 1, |
114
|
|
|
|
|
|
|
) |
115
|
|
|
|
|
|
|
} |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
sub reset { |
119
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
120
|
|
|
|
|
|
|
|
121
|
0
|
|
|
|
|
|
$self->position(-1); |
122
|
0
|
|
|
|
|
|
return 1; |
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
__PACKAGE__->meta->make_immutable; |
126
|
|
|
|
|
|
|
|
127
|
9
|
|
|
9
|
|
132
|
no Moose; |
|
9
|
|
|
|
|
21
|
|
|
9
|
|
|
|
|
113
|
|
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
1; |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
__END__ |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
=pod |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
=head1 NAME |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
Chart::Clicker::Drawing::ColorAllocator - Color picker |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
=head1 VERSION |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
version 2.88 |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
=head1 SYNOPSIS |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
use Graphics::Color::RGB; |
146
|
|
|
|
|
|
|
use Chart::Clicker::Drawing::ColorAllocator; |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
my $ca = Chart::Clicker::Drawing::ColorAllocator->new({ |
149
|
|
|
|
|
|
|
colors => [ |
150
|
|
|
|
|
|
|
Graphics::Color::RGB->new( |
151
|
|
|
|
|
|
|
red => 1.0, green => 0, blue => 0, alpha => 1.0 |
152
|
|
|
|
|
|
|
), |
153
|
|
|
|
|
|
|
#... |
154
|
|
|
|
|
|
|
] |
155
|
|
|
|
|
|
|
}); |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
my $red = $ca->get(0); |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
#or let Chart::Clicker autmatically pick complementing colors for you |
160
|
|
|
|
|
|
|
my $ca2 = Chart::Clicker::Drawing::ColorAllocator->new({ |
161
|
|
|
|
|
|
|
seed_hue => 0, #red |
162
|
|
|
|
|
|
|
}); |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
=head1 DESCRIPTION |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
Allocates colors for use in the chart. The position in the color allocator |
167
|
|
|
|
|
|
|
corresponds to the series that will be colored. |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
=head1 AUTOMATIC COLOR ALLOCATION |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
This module has the capacity to automatically allocate 96 individual colors |
172
|
|
|
|
|
|
|
using L<Color::Scheme>. It does so by picking 4 hues equally spaced in the |
173
|
|
|
|
|
|
|
color wheel from the C<seed_hue> (0 (red) would be complimented by 270 (blue), |
174
|
|
|
|
|
|
|
180 (green) and 90 (yellow)). After those colors are allocated it moves on to |
175
|
|
|
|
|
|
|
picking from the colors between those ( 45, 135, 215, 305 ) etc. Once all |
176
|
|
|
|
|
|
|
values of C<hues> have been utilized, it repeats them using a different shade. |
177
|
|
|
|
|
|
|
This has the effect of generating evenly spaced complementing colors to ensure |
178
|
|
|
|
|
|
|
colors are well ditinguishable from one another and have appropriate contrast. |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
=head2 position |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
Gets the current position. |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
=head1 ATTRIBUTES |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
=head2 colors |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
An arrayref of colors that will be used for series that Clicker draws. |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
=head2 color_scheme |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
A lazy-building L<Color::Scheme> object used to generate the color scheme of |
193
|
|
|
|
|
|
|
the chart; |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
=head2 seed_hue |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
The interger value of the first hue used when computing the tetrade color |
198
|
|
|
|
|
|
|
scheme. Setting this will affect the hue of the first color allocated. |
199
|
|
|
|
|
|
|
Subsequent colors will be allocated based on their distance from this color |
200
|
|
|
|
|
|
|
to maintain sifficient contrast between colors. If not specified the seed_hue |
201
|
|
|
|
|
|
|
will default to 270, blue. |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
=head2 hues |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
An array reference of evenly spaced seed hues for color allocation. By default |
206
|
|
|
|
|
|
|
it will use the seed hue plus 0, 45, 75, 15, 60 and 30 which is enough to cover |
207
|
|
|
|
|
|
|
all web-safe colors when using a tetrade color scheme. |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
=head2 shade_order |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
An array reference of the order in which the different shades of each color |
212
|
|
|
|
|
|
|
will be used for every color scheme generated. It defaults to 1, 3, 0, 2 for |
213
|
|
|
|
|
|
|
optimum color spacing. |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
=head1 METHODS |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
=head2 add_to_colors |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
Add a color to this allocator. |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
=head2 clear_colors |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
Clear this allocator's colors |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
=head2 color_count |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
Get the number of colors in this allocator. |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
=head2 get_color ($index) |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
Gets the color at the specified index. Returns undef if that position has no |
232
|
|
|
|
|
|
|
color. |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
=head2 next |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
Returns the next color. Each call to next increments the position, so |
237
|
|
|
|
|
|
|
subsequent calls will return different colors. |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
=head2 allocate_color |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
Determines what the next color should be. |
242
|
|
|
|
|
|
|
|
243
|
|
|
|
|
|
|
=head2 reset |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
Resets this allocator back to the beginning. |
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
=head1 AUTHOR |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
Cory G Watson <gphat@cpan.org> |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
This software is copyright (c) 2014 by Cold Hard Code, LLC. |
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
This is free software; you can redistribute it and/or modify it under |
256
|
|
|
|
|
|
|
the same terms as the Perl 5 programming language system itself. |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
=cut |