line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Tk::Graph;
|
2
|
|
|
|
|
|
|
#------------------------------------------------
|
3
|
|
|
|
|
|
|
# automagically updated versioning variables -- CVS modifies these!
|
4
|
|
|
|
|
|
|
#------------------------------------------------
|
5
|
|
|
|
|
|
|
our $Revision = '$Revision: 1.58 $';
|
6
|
|
|
|
|
|
|
our $CheckinDate = '$Date: 2002/12/12 16:04:55 $';
|
7
|
|
|
|
|
|
|
our $CheckinUser = '$Author: xpix $';
|
8
|
|
|
|
|
|
|
# we need to clean these up right here
|
9
|
|
|
|
|
|
|
$Revision =~ s/^\$\S+:\s*(.*?)\s*\$$/$1/sx;
|
10
|
|
|
|
|
|
|
$CheckinDate =~ s/^\$\S+:\s*(.*?)\s*\$$/$1/sx;
|
11
|
|
|
|
|
|
|
$CheckinUser =~ s/^\$\S+:\s*(.*?)\s*\$$/$1/sx;
|
12
|
|
|
|
|
|
|
#-------------------------------------------------
|
13
|
|
|
|
|
|
|
#-- package Tk::Graph ----------------------------
|
14
|
|
|
|
|
|
|
#-------------------------------------------------
|
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
=head1 NAME
|
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
Tk::Graph - A graphical Chartmaker at Canvas (Realtime).
|
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
=head1 SYNOPSIS
|
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
use Tk;
|
23
|
|
|
|
|
|
|
use Tk::Graph;
|
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
$mw = MainWindow->new;
|
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
my $data = {
|
28
|
|
|
|
|
|
|
Sleep => 51,
|
29
|
|
|
|
|
|
|
Work => 135,
|
30
|
|
|
|
|
|
|
Access => 124,
|
31
|
|
|
|
|
|
|
mySQL => 5
|
32
|
|
|
|
|
|
|
};
|
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
my $ca = $mw->Graph(
|
35
|
|
|
|
|
|
|
-type => 'BARS',
|
36
|
|
|
|
|
|
|
)->pack(
|
37
|
|
|
|
|
|
|
-expand => 1,
|
38
|
|
|
|
|
|
|
-fill => 'both',
|
39
|
|
|
|
|
|
|
);
|
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
$ca->configure(-variable => $data); # bind to data
|
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
# or ...
|
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
$ca->set($data); # set data
|
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
MainLoop;
|
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
=head1 DESCRIPTION
|
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
A graphical Chartmaker at Canvas (Realtime). This is a real Canvas widget,
|
53
|
|
|
|
|
|
|
so you can draw with the standard routines in the Canvas object.
|
54
|
|
|
|
|
|
|
For example, you can draw a line with I<$chart>->I. This is useful for you when you will
|
55
|
|
|
|
|
|
|
add a logo or write some text in your created Chart.
|
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
=cut
|
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
# -------------------------------------------------------
|
61
|
|
|
|
|
|
|
#
|
62
|
|
|
|
|
|
|
# Graph.pm
|
63
|
|
|
|
|
|
|
#
|
64
|
|
|
|
|
|
|
# A graphical Chartmaker at Canvas (Realtime)
|
65
|
|
|
|
|
|
|
# -------------------------------------------------------
|
66
|
|
|
|
|
|
|
|
67
|
1
|
|
|
1
|
|
1109
|
use Carp;
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
90
|
|
68
|
1
|
|
|
1
|
|
6
|
use base qw/Tk::Derived Tk::Canvas/;
|
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
1552
|
|
69
|
|
|
|
|
|
|
use Math::Trig qw(rad2deg acos);
|
70
|
|
|
|
|
|
|
use Tie::Watch;
|
71
|
|
|
|
|
|
|
use strict;
|
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
Construct Tk::Widget 'Graph';
|
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
#-------------------------------------------------
|
76
|
|
|
|
|
|
|
sub Populate {
|
77
|
|
|
|
|
|
|
#-------------------------------------------------
|
78
|
|
|
|
|
|
|
my ($self, $args) = @_;
|
79
|
|
|
|
|
|
|
$self->SUPER::Populate($args);
|
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
=head1 WIDGET-SPECIFIC OPTIONS
|
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
=cut
|
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
my %specs;
|
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
#-------------------------------------------------
|
88
|
|
|
|
|
|
|
$specs{-debug} = [qw/PASSIVE debug Debug/, undef];
|
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
=head2 -debug [I<0>|1]
|
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
This is the switch for debug output at the normal console (STDOUT)
|
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
=cut
|
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
#-------------------------------------------------
|
97
|
|
|
|
|
|
|
$specs{-type} = [qw/PASSIVE type Type/, undef];
|
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
=head2 -type (I, Line, Bars, HBars, Circle)
|
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
This is the type of Graph to display the data.
|
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
I - analyze the datahash and choose a Chart:
|
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
Hash with values -> PieChart
|
106
|
|
|
|
|
|
|
Hash with keys with hashes or values (not all) -> Barchart per Key
|
107
|
|
|
|
|
|
|
Hash with keys with arrays -> Linechart per Key
|
108
|
|
|
|
|
|
|
Array -> Linechart
|
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
I - Linechart,
|
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
I - Barchart with vertical Bars,
|
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
I - Barchart with horizontal bars,
|
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
I - PieChart
|
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
=cut
|
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
#-------------------------------------------------
|
121
|
|
|
|
|
|
|
$specs{-foreground} = [qw/PASSIVE foreground Foreground/, 'black'];
|
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
=head2 -foreground (I)
|
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
Color for the Axis, Legend and Labels.
|
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
=cut
|
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
#-------------------------------------------------
|
130
|
|
|
|
|
|
|
$specs{-titlecolor} = [qw/PASSIVE titlecolor TitleColor brown/];
|
131
|
|
|
|
|
|
|
$specs{-title} = [qw/PASSIVE title Title/, ' '];
|
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
=head2 -title -titlecolor (I)
|
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
Message at the top of the Widget.
|
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
=cut
|
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
#-------------------------------------------------
|
140
|
|
|
|
|
|
|
$specs{-headroom} = [qw/PASSIVE headroom HeadRoom/, 20];
|
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
=head2 -headroom (I<20>)
|
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
The headroom in percent. This is a clean area at the top of the widget.
|
145
|
|
|
|
|
|
|
When a value is in this area, the graph is redrawn to preserve this headroom.
|
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
=cut
|
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
#-------------------------------------------------
|
150
|
|
|
|
|
|
|
$specs{-threed} = [qw/PASSIVE threed Threed/, undef];
|
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
=head2 -threed (I)
|
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
This switch a three dimensional Display on. The Value is deep in Pixel.
|
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
=cut
|
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
#-------------------------------------------------
|
159
|
|
|
|
|
|
|
$specs{-light} = [qw/PASSIVE light Light/, [10,5,0]];
|
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
=head2 -light (I<[10,5,0]>)
|
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
How many percent is the color in top, side and front (in this direction)
|
164
|
|
|
|
|
|
|
lighter or darker in 3d?
|
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
=cut
|
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
#-------------------------------------------------
|
170
|
|
|
|
|
|
|
$specs{-max} = [qw/PASSIVE max Max/, undef];
|
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
=head2 -max
|
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
Maximum Value for the axis. If this set,
|
175
|
|
|
|
|
|
|
the axis is not dynamically redrawn to the
|
176
|
|
|
|
|
|
|
next maximum value from the data.
|
177
|
|
|
|
|
|
|
Only used in Lines and Bars!
|
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
=cut
|
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
#-------------------------------------------------
|
182
|
|
|
|
|
|
|
$specs{-sortnames} = [qw/PASSIVE sortnames SortNames/, 'alpha'];
|
183
|
|
|
|
|
|
|
$specs{-sortreverse} = [qw/PASSIVE sortreverse SortReverse/, undef];
|
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
=head2 -sortnames ('I' | 'num') -sortreverse (0, 1)
|
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
sort the keys from the data hash.
|
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
=cut
|
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
#-------------------------------------------------
|
192
|
|
|
|
|
|
|
$specs{-config} = [qw/PASSIVE config Config/, undef];
|
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
=head2 -config (\%cfghash)
|
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
A config hash with optional added parameters for more flexibility. The first is the name
|
197
|
|
|
|
|
|
|
of the key from your data hash, followed by a config hash with parameters.
|
198
|
|
|
|
|
|
|
example:
|
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
-config => {
|
201
|
|
|
|
|
|
|
'fr' => {
|
202
|
|
|
|
|
|
|
-title => 'Free',
|
203
|
|
|
|
|
|
|
-color => 'green',
|
204
|
|
|
|
|
|
|
-range => {
|
205
|
|
|
|
|
|
|
'red' => [0, 50],
|
206
|
|
|
|
|
|
|
'yellow'=> [50, 100],
|
207
|
|
|
|
|
|
|
'green' => [100, 200],
|
208
|
|
|
|
|
|
|
},
|
209
|
|
|
|
|
|
|
},
|
210
|
|
|
|
|
|
|
'sl' => {
|
211
|
|
|
|
|
|
|
-title => 'Sleep',
|
212
|
|
|
|
|
|
|
-color => 'yellow',
|
213
|
|
|
|
|
|
|
},
|
214
|
|
|
|
|
|
|
...
|
215
|
|
|
|
|
|
|
},
|
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
I<-title>
|
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
Here you can write another Name to display.
|
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
I<-color>
|
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
Key name displayed in this color.
|
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
I<-range>
|
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
A range to display the values in variable colors. You can say values from 0 to 50 display in
|
228
|
|
|
|
|
|
|
green or above in red. if value not in something range, then this draw in original color.
|
229
|
|
|
|
|
|
|
This is only use in LINE (ToDo: BARS and HBARS!)
|
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
=cut
|
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
#-------------------------------------------------
|
235
|
|
|
|
|
|
|
$specs{-fill} = [qw/PASSIVE fill Fill/, 'both'];
|
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
=head2 -fill (I<'both'>)
|
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
The same as in perl/tk pack. Redraw only in
|
240
|
|
|
|
|
|
|
I,I or I direction(s).
|
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
=cut
|
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
#-------------------------------------------------
|
245
|
|
|
|
|
|
|
$specs{-ylabel} = [qw/PASSIVE ylabel YLabel/, undef];
|
246
|
|
|
|
|
|
|
$specs{-xlabel} = [qw/PASSIVE xlabel XLabel/, undef];
|
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
=head2 -xlabel -ylabel (I)
|
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
This displays a description for x and y axis.
|
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
=cut
|
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
#-------------------------------------------------
|
255
|
|
|
|
|
|
|
$specs{-ytick} = [qw/PASSIVE ytick YTick/, 5];
|
256
|
|
|
|
|
|
|
$specs{-xtick} = [qw/PASSIVE xtick XTick/, 5];
|
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
=head2 -xtick -ytick (I<5>)
|
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
Number of ticks at the x or y axis.
|
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
=cut
|
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
#-------------------------------------------------
|
265
|
|
|
|
|
|
|
$specs{-yformat} = [qw/PASSIVE yformat YFormat/, '%g'];
|
266
|
|
|
|
|
|
|
$specs{-xformat} = [qw/PASSIVE xformat XFormat/, '%s'];
|
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
=head2 -xformat (I<'%s'>) -yformat (I<'%g'>)
|
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
This if the sprintf format for display
|
271
|
|
|
|
|
|
|
of the value or key for the axis.
|
272
|
|
|
|
|
|
|
example:
|
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
-xformat => '%d%%' # This will eg. Display '50%'
|
275
|
|
|
|
|
|
|
-yformat => '%s host' # This will eg. Display 'first host'
|
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
=cut
|
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
#-------------------------------------------------
|
280
|
|
|
|
|
|
|
$specs{-padding} = [qw/PASSIVE padding Padding/, [15,20,20,50]];
|
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
=head2 -padding (I<[15,20,20,50]>)
|
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
Margin display from the Widget border, in this order top, right, bottom,
|
285
|
|
|
|
|
|
|
left.
|
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
=cut
|
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
#-------------------------------------------------
|
290
|
|
|
|
|
|
|
$specs{-linewidth} = [qw/PASSIVE linewidth Linewidth 1/];
|
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
=head2 -linewidth (I<1>)
|
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
The weight of the border for the dots, circle and lines.
|
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
=cut
|
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
#-------------------------------------------------
|
300
|
|
|
|
|
|
|
$specs{-printvalue} = [qw/PASSIVE printvalue Printvalue/, undef];
|
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
=head2 -printvalue
|
303
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
This is the sprintf format and switch for display of the value.
|
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
=cut
|
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
#-------------------------------------------------
|
309
|
|
|
|
|
|
|
$specs{-maxmin} = [qw/PASSIVE maxmin MaxMin/, undef];
|
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
=head2 -maxmin
|
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
Draw max/average/min value lines in Bars and Line charts
|
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
=cut
|
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
#-------------------------------------------------
|
318
|
|
|
|
|
|
|
$specs{-legend} = [qw/PASSIVE legend Legend/, 1];
|
319
|
|
|
|
|
|
|
|
320
|
|
|
|
|
|
|
=head2 -legend [0|I<1>]
|
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
Switch on/off the legend in Circle or Lines
|
323
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
=cut
|
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
#-------------------------------------------------
|
327
|
|
|
|
|
|
|
$specs{-colors} = [qw/PASSIVE colors Colors/, 'blue,brown,seashell3,red,green,yellow,darkgreen,darkblue,darkred,orange,olivedrab,magenta,black,salmon'];
|
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
=head2 -colors (I)
|
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
A comma-separated list with the allowed colors.
|
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
=cut
|
335
|
|
|
|
|
|
|
|
336
|
|
|
|
|
|
|
#-------------------------------------------------
|
337
|
|
|
|
|
|
|
$specs{-shadow} = [qw/PASSIVE shadow Shadow/, 'gray50'];
|
338
|
|
|
|
|
|
|
$specs{-shadowdepth} = [qw/PASSIVE shadowdepth Shadowdepth/, undef];
|
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
=head2 -shadow (I<'gray50'>) -shadowdepth (I<0>)
|
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
You can add a shadow to all Charts, the
|
343
|
|
|
|
|
|
|
switch is -shadowdepth. This is also the depth in Pixels for the shadow.
|
344
|
|
|
|
|
|
|
-shadow is the color for the shadow. This Option is autoaticly switch off when use 3d.
|
345
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
=cut
|
347
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
#-------------------------------------------------
|
349
|
|
|
|
|
|
|
$specs{-wire} = [qw/PASSIVE wire Wire/, 'white'];
|
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
=head2 -wire (I<'white'>)
|
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
Switch on/off a wire grid in background from line and bars chart.
|
354
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
=cut
|
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
#-------------------------------------------------
|
358
|
|
|
|
|
|
|
$specs{-reference} = [qw/PASSIVE reference Reference/, undef];
|
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
=head2 -reference (I<'name'>, I<'value'>)
|
361
|
|
|
|
|
|
|
|
362
|
|
|
|
|
|
|
This give a Reference value for the keys in datahash. I.e. the data values are displayed relative to this reference value.
|
363
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
example:
|
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
-reference => 'Free, 1024', # Free space at host
|
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
=cut
|
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
#-------------------------------------------------
|
371
|
|
|
|
|
|
|
$specs{-look} = [qw/PASSIVE look Look/, 10];
|
372
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
=head2 -look (I<10>)
|
374
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
The number of values to display in a line chart.
|
376
|
|
|
|
|
|
|
When you refresh the data hash (maybe with the methods set or variable), then this will display
|
377
|
|
|
|
|
|
|
eg. the last 50 values.
|
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
example:
|
380
|
|
|
|
|
|
|
|
381
|
|
|
|
|
|
|
-look => 50, # 50 values to display pro key
|
382
|
|
|
|
|
|
|
|
383
|
|
|
|
|
|
|
=cut
|
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
#-------------------------------------------------
|
386
|
|
|
|
|
|
|
$specs{-dots} = [qw/PASSIVE dots Dots/, undef];
|
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
=head2 -dots (I<'width'>)
|
389
|
|
|
|
|
|
|
|
390
|
|
|
|
|
|
|
The width and switch for the dots in line chart.
|
391
|
|
|
|
|
|
|
|
392
|
|
|
|
|
|
|
=cut
|
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
#-------------------------------------------------
|
395
|
|
|
|
|
|
|
$specs{-barwidth} = [qw/PASSIVE barwidth Barwidth/, 30];
|
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
=head2 -barwidth (I<30>)
|
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
The width for bars in bar charts.
|
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
=cut
|
402
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
#-------------------------------------------------
|
404
|
|
|
|
|
|
|
$specs{-balloon} = [qw/PASSIVE balloon Balloon/, 1];
|
405
|
|
|
|
|
|
|
|
406
|
|
|
|
|
|
|
=head2 -balloon (0|I<1>)
|
407
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
Switch on/off ballon help for segements or lines.
|
409
|
|
|
|
|
|
|
The text format is used from the -printvalue option.
|
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
=cut
|
412
|
|
|
|
|
|
|
|
413
|
|
|
|
|
|
|
#-------------------------------------------------
|
414
|
|
|
|
|
|
|
$specs{-font} = [qw/PASSIVE font Font/, '-*-Helvetica-Medium-R-Normal--*-100-*-*-*-*-*-*'];
|
415
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
=head2 -font (I<'-*-Helvetica-Medium-R-Normal--*-100-*-*-*-*-*-*'>)
|
417
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
Draw text in this font.
|
419
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
=cut
|
421
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
#-------------------------------------------------
|
423
|
|
|
|
|
|
|
$specs{-lineheight} = [qw/PASSIVE lineheight LineHeight/, 15];
|
424
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
=head2 -lineheight (I<15>)
|
426
|
|
|
|
|
|
|
|
427
|
|
|
|
|
|
|
The line height in pixels for text in the legend.
|
428
|
|
|
|
|
|
|
|
429
|
|
|
|
|
|
|
=cut
|
430
|
|
|
|
|
|
|
|
431
|
|
|
|
|
|
|
#-------------------------------------------------
|
432
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
=head1 METHODS
|
435
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
Here come the methods that you can use with this Widget.
|
437
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
=cut
|
439
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
#-------------------------------------------------
|
442
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
#-------------------------------------------------
|
444
|
|
|
|
|
|
|
$specs{-set} = [qw/METHOD set Set/, undef];
|
445
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
=head2 $chart->I($data);
|
447
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
Set the data hash to display.
|
449
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
=cut
|
451
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
#-------------------------------------------------
|
453
|
|
|
|
|
|
|
$specs{-variable} = [qw/METHOD variable Variable/, undef];
|
454
|
|
|
|
|
|
|
|
455
|
|
|
|
|
|
|
=head2 $chart->I($data);
|
456
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
Bind the data hash to display the data, write to $data will redraw the widget.
|
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
=cut
|
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
#-------------------------------------------------
|
462
|
|
|
|
|
|
|
$specs{-register} = [qw/METHOD register Register/, undef];
|
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
=head2 $chart->I($to_register);
|
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
Set the data hash to register. When you have data for Linegraph
|
467
|
|
|
|
|
|
|
then can you this register with method register. This data
|
468
|
|
|
|
|
|
|
is the registered for the following linegraph, when you set
|
469
|
|
|
|
|
|
|
new datas with 'set' or 'variable' then if this startet at
|
470
|
|
|
|
|
|
|
the end from this data. if you call register without data the
|
471
|
|
|
|
|
|
|
you get the actual datacache.
|
472
|
|
|
|
|
|
|
|
473
|
|
|
|
|
|
|
my $to_register = {
|
474
|
|
|
|
|
|
|
'one' => [0,5,4,8,6,8],
|
475
|
|
|
|
|
|
|
'two' => [2,5,9,4,6,2],
|
476
|
|
|
|
|
|
|
'three' => [0,5,6,8,6,8],
|
477
|
|
|
|
|
|
|
};
|
478
|
|
|
|
|
|
|
$ca->register($to_register);
|
479
|
|
|
|
|
|
|
|
480
|
|
|
|
|
|
|
=cut
|
481
|
|
|
|
|
|
|
|
482
|
|
|
|
|
|
|
|
483
|
|
|
|
|
|
|
#-------------------------------------------------
|
484
|
|
|
|
|
|
|
$specs{-redraw} = [qw/METHOD redraw Redraw/, undef];
|
485
|
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
=head2 $chart->I();
|
487
|
|
|
|
|
|
|
|
488
|
|
|
|
|
|
|
Redraw chart
|
489
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
=cut
|
491
|
|
|
|
|
|
|
|
492
|
|
|
|
|
|
|
#-------------------------------------------------
|
493
|
|
|
|
|
|
|
$specs{-clear} = [qw/METHOD clear Clear/, undef];
|
494
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
=head2 $chart->I();
|
496
|
|
|
|
|
|
|
|
497
|
|
|
|
|
|
|
Clear the canvas.
|
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
=cut
|
500
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
|
502
|
|
|
|
|
|
|
$self->ConfigSpecs(
|
503
|
|
|
|
|
|
|
%specs,
|
504
|
|
|
|
|
|
|
);
|
505
|
|
|
|
|
|
|
|
506
|
|
|
|
|
|
|
# Bindings
|
507
|
|
|
|
|
|
|
$self->Tk::bind('', [ \&redraw, $self ] ); # Redraw
|
508
|
|
|
|
|
|
|
|
509
|
|
|
|
|
|
|
# Help (CanvasBalloon)
|
510
|
|
|
|
|
|
|
# $self->{balloon} = $self->Balloon;
|
511
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
} # end Populate
|
513
|
|
|
|
|
|
|
|
514
|
|
|
|
|
|
|
#-------------------------------------------------
|
515
|
|
|
|
|
|
|
sub draw_horizontal_bars {
|
516
|
|
|
|
|
|
|
#-------------------------------------------------
|
517
|
|
|
|
|
|
|
my $self = shift || return error("No Objekt!");
|
518
|
|
|
|
|
|
|
return undef unless(ref $self eq __PACKAGE__);
|
519
|
|
|
|
|
|
|
my $data = shift || return;
|
520
|
|
|
|
|
|
|
|
521
|
|
|
|
|
|
|
# Check
|
522
|
|
|
|
|
|
|
return warn("Your data is incorrect, i need a Hashreference!")
|
523
|
|
|
|
|
|
|
unless(ref $data eq 'HASH');
|
524
|
|
|
|
|
|
|
|
525
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
my $werte = $self->reference($data);
|
527
|
|
|
|
|
|
|
my $conf = $self->ReadConfig($werte) || return;
|
528
|
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
$self->delete('all');
|
530
|
|
|
|
|
|
|
|
531
|
|
|
|
|
|
|
# MaxMin Werte ermitteln und ggf Linien zeichnen
|
532
|
|
|
|
|
|
|
$self->maxmin($conf, $werte);
|
533
|
|
|
|
|
|
|
|
534
|
|
|
|
|
|
|
# Gitter zeichnen
|
535
|
|
|
|
|
|
|
$self->wire($conf)
|
536
|
|
|
|
|
|
|
if( $self->cget(-wire) );
|
537
|
|
|
|
|
|
|
|
538
|
|
|
|
|
|
|
# Axis (Titel ... usw
|
539
|
|
|
|
|
|
|
$self->axis($conf, $werte);
|
540
|
|
|
|
|
|
|
|
541
|
|
|
|
|
|
|
|
542
|
|
|
|
|
|
|
$self->debug("Count: %d,Typ: %s, Max: %s", $conf->{count}, $conf->{typ}, $conf->{max_value});
|
543
|
|
|
|
|
|
|
if($conf->{count} > 0 && $conf->{typ} eq 'HASH' && $conf->{max_value} > 0)
|
544
|
|
|
|
|
|
|
{
|
545
|
|
|
|
|
|
|
my $i = -0.5;
|
546
|
|
|
|
|
|
|
my @linepoints;
|
547
|
|
|
|
|
|
|
my $c;
|
548
|
|
|
|
|
|
|
my $shadowcolor = $self->cget(-shadow);
|
549
|
|
|
|
|
|
|
my $sd = $self->cget(-shadowdepth);
|
550
|
|
|
|
|
|
|
my $td = $self->cget(-threed) || 0;
|
551
|
|
|
|
|
|
|
|
552
|
|
|
|
|
|
|
foreach my $point (sort { $self->sorter } keys %$werte ) {
|
553
|
|
|
|
|
|
|
next if(ref $werte->{$point});
|
554
|
|
|
|
|
|
|
next unless($conf->{max_value});
|
555
|
|
|
|
|
|
|
$i++;
|
556
|
|
|
|
|
|
|
|
557
|
|
|
|
|
|
|
my $xi = ($conf->{x_null} + round( ( ($conf->{width} - $conf->{x_null}) / $conf->{max_value} ) * $werte->{$point}));
|
558
|
|
|
|
|
|
|
my $yi = ($conf->{y_null}) - (round(($conf->{y_null} - $conf->{ypad}) / $conf->{count}) * $i);
|
559
|
|
|
|
|
|
|
$yi-=($self->cget(-barwidth) / 2);
|
560
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
# Values
|
562
|
|
|
|
|
|
|
$self->createText($xi+12, $yi + ($self->cget(-barwidth) / 2),
|
563
|
|
|
|
|
|
|
-text => sprintf($self->cget(-printvalue), '', $werte->{$point}),
|
564
|
|
|
|
|
|
|
-anchor => 'w',
|
565
|
|
|
|
|
|
|
-font => $conf->{font},
|
566
|
|
|
|
|
|
|
-fill => $self->cget(-titlecolor)
|
567
|
|
|
|
|
|
|
) if($self->cget(-printvalue));
|
568
|
|
|
|
|
|
|
|
569
|
|
|
|
|
|
|
|
570
|
|
|
|
|
|
|
# Shadow Bar
|
571
|
|
|
|
|
|
|
if($sd && $werte->{$point} && ! $td) {
|
572
|
|
|
|
|
|
|
my $bar = $self->createRectangle(
|
573
|
|
|
|
|
|
|
($xi+$sd), ($yi+$sd),
|
574
|
|
|
|
|
|
|
($conf->{x_null}), ($yi + $self->cget(-barwidth) + $sd),
|
575
|
|
|
|
|
|
|
-fill => $shadowcolor,
|
576
|
|
|
|
|
|
|
-outline => $shadowcolor,
|
577
|
|
|
|
|
|
|
);
|
578
|
|
|
|
|
|
|
}
|
579
|
|
|
|
|
|
|
|
580
|
|
|
|
|
|
|
# ThreeD Bar
|
581
|
|
|
|
|
|
|
# Oben
|
582
|
|
|
|
|
|
|
$self->createPolygon(
|
583
|
|
|
|
|
|
|
$conf->{x_null}, $yi,
|
584
|
|
|
|
|
|
|
($conf->{x_null} + $td), ($yi - $td),
|
585
|
|
|
|
|
|
|
($xi + $td), ($yi - $td),
|
586
|
|
|
|
|
|
|
($xi), ($yi ),
|
587
|
|
|
|
|
|
|
-fill => $self->color_change( $self->{colors}->{$point}, $conf->{light_top}),
|
588
|
|
|
|
|
|
|
-outline => 'black',
|
589
|
|
|
|
|
|
|
) if($td);
|
590
|
|
|
|
|
|
|
|
591
|
|
|
|
|
|
|
# Side
|
592
|
|
|
|
|
|
|
$self->createPolygon(
|
593
|
|
|
|
|
|
|
($xi ), ($yi + $self->cget(-barwidth)) ,
|
594
|
|
|
|
|
|
|
($xi + $td ), ($yi + $self->cget(-barwidth) - $td) ,
|
595
|
|
|
|
|
|
|
($xi + $td), ($yi - $td),
|
596
|
|
|
|
|
|
|
($xi ), ($yi ),
|
597
|
|
|
|
|
|
|
-fill => $self->color_change( $self->{colors}->{$point}, $conf->{light_side}),
|
598
|
|
|
|
|
|
|
-outline => 'black',
|
599
|
|
|
|
|
|
|
) if($td);
|
600
|
|
|
|
|
|
|
|
601
|
|
|
|
|
|
|
# Normaler Bar
|
602
|
|
|
|
|
|
|
$self->{elements}->{$point} = $self->createRectangle($xi, $yi,
|
603
|
|
|
|
|
|
|
$conf->{x_null}, ($yi + $self->cget(-barwidth)),
|
604
|
|
|
|
|
|
|
-fill => ( $self->cget(-threed) ? $self->color_change( $self->{colors}->{$point}, $conf->{light_front}) : $self->{colors}->{$point} ),
|
605
|
|
|
|
|
|
|
-width => 1,
|
606
|
|
|
|
|
|
|
) if($werte->{$point});
|
607
|
|
|
|
|
|
|
}
|
608
|
|
|
|
|
|
|
|
609
|
|
|
|
|
|
|
# balloon
|
610
|
|
|
|
|
|
|
$self->balloon($self->{elements}, $werte);
|
611
|
|
|
|
|
|
|
|
612
|
|
|
|
|
|
|
}
|
613
|
|
|
|
|
|
|
}
|
614
|
|
|
|
|
|
|
|
615
|
|
|
|
|
|
|
|
616
|
|
|
|
|
|
|
#-------------------------------------------------
|
617
|
|
|
|
|
|
|
sub draw_bars {
|
618
|
|
|
|
|
|
|
#-------------------------------------------------
|
619
|
|
|
|
|
|
|
my $self = shift || return error("No Objekt!");
|
620
|
|
|
|
|
|
|
return undef unless(ref $self eq __PACKAGE__);
|
621
|
|
|
|
|
|
|
my $data = shift || return;
|
622
|
|
|
|
|
|
|
|
623
|
|
|
|
|
|
|
# Check
|
624
|
|
|
|
|
|
|
return warn("Your data is incorrect, i need a Hashreference!")
|
625
|
|
|
|
|
|
|
unless(ref $data eq 'HASH');
|
626
|
|
|
|
|
|
|
|
627
|
|
|
|
|
|
|
|
628
|
|
|
|
|
|
|
my $werte = $self->reference($data);
|
629
|
|
|
|
|
|
|
my $conf = $self->ReadConfig($werte) || return;
|
630
|
|
|
|
|
|
|
|
631
|
|
|
|
|
|
|
$self->delete('all');
|
632
|
|
|
|
|
|
|
|
633
|
|
|
|
|
|
|
# MaxMin Werte ermitteln und ggf Linien zeichnen
|
634
|
|
|
|
|
|
|
$self->maxmin($conf, $werte);
|
635
|
|
|
|
|
|
|
|
636
|
|
|
|
|
|
|
# Gitter zeichnen
|
637
|
|
|
|
|
|
|
$self->wire($conf)
|
638
|
|
|
|
|
|
|
if( $self->cget(-wire) );
|
639
|
|
|
|
|
|
|
|
640
|
|
|
|
|
|
|
# Axis (Titel ... usw
|
641
|
|
|
|
|
|
|
$self->axis($conf, $werte);
|
642
|
|
|
|
|
|
|
|
643
|
|
|
|
|
|
|
|
644
|
|
|
|
|
|
|
|
645
|
|
|
|
|
|
|
if($conf->{count} > 0 && $conf->{typ} eq 'HASH')
|
646
|
|
|
|
|
|
|
{
|
647
|
|
|
|
|
|
|
my $i = 0;
|
648
|
|
|
|
|
|
|
my ($xi, $yi);
|
649
|
|
|
|
|
|
|
my @linepoints;
|
650
|
|
|
|
|
|
|
my $c;
|
651
|
|
|
|
|
|
|
my $td = $self->cget(-threed) || 0;
|
652
|
|
|
|
|
|
|
|
653
|
|
|
|
|
|
|
foreach my $point (sort { $self->sorter } keys %$werte ) {
|
654
|
|
|
|
|
|
|
next if(ref $werte->{$point});
|
655
|
|
|
|
|
|
|
next unless($conf->{max_value});
|
656
|
|
|
|
|
|
|
$werte->{$point} = 0
|
657
|
|
|
|
|
|
|
unless(defined $werte->{$point});
|
658
|
|
|
|
|
|
|
$i++;
|
659
|
|
|
|
|
|
|
|
660
|
|
|
|
|
|
|
$xi = $self->calc_x($i) - ($self->cget(-barwidth) / 2);
|
661
|
|
|
|
|
|
|
$yi = $self->calc_y($werte->{$point});
|
662
|
|
|
|
|
|
|
|
663
|
|
|
|
|
|
|
$self->debug("---------------------");
|
664
|
|
|
|
|
|
|
$self->debug("DrawBar: Name: %s, Wert: %d", $point, $werte->{$point});
|
665
|
|
|
|
|
|
|
|
666
|
|
|
|
|
|
|
$self->bar( $point, $werte->{$point}, $i );
|
667
|
|
|
|
|
|
|
}
|
668
|
|
|
|
|
|
|
} else {
|
669
|
|
|
|
|
|
|
return $self->error("I need a hash to display Bars!");
|
670
|
|
|
|
|
|
|
}
|
671
|
|
|
|
|
|
|
|
672
|
|
|
|
|
|
|
# balloon
|
673
|
|
|
|
|
|
|
$self->balloon($self->{elements}, $werte);
|
674
|
|
|
|
|
|
|
}
|
675
|
|
|
|
|
|
|
|
676
|
|
|
|
|
|
|
#-------------------------------------------------
|
677
|
|
|
|
|
|
|
sub bar {
|
678
|
|
|
|
|
|
|
#-------------------------------------------------
|
679
|
|
|
|
|
|
|
my $self = shift || return error("No Objekt!");
|
680
|
|
|
|
|
|
|
return undef unless(ref $self eq __PACKAGE__);
|
681
|
|
|
|
|
|
|
my $name = shift || return error('No Name!');
|
682
|
|
|
|
|
|
|
my $wert = shift || 0;
|
683
|
|
|
|
|
|
|
my $i = shift;
|
684
|
|
|
|
|
|
|
|
685
|
|
|
|
|
|
|
my $conf = $self->{cfg};
|
686
|
|
|
|
|
|
|
my $xi = $self->calc_x($i) - round($self->cget(-barwidth) / 2);
|
687
|
|
|
|
|
|
|
my $yi = $self->calc_y($wert);
|
688
|
|
|
|
|
|
|
my $width = $self->cget(-barwidth);
|
689
|
|
|
|
|
|
|
my $height = $conf->{y_null};
|
690
|
|
|
|
|
|
|
my $td = $self->cget(-threed) || 0;
|
691
|
|
|
|
|
|
|
|
692
|
|
|
|
|
|
|
$self->debug('Name: %s, X: %d, Y:%d, Width: %d, Hight: %d, 3D: %d',
|
693
|
|
|
|
|
|
|
$name, $xi, $yi, $width, $height, $td);
|
694
|
|
|
|
|
|
|
|
695
|
|
|
|
|
|
|
|
696
|
|
|
|
|
|
|
# ThreeD Bar
|
697
|
|
|
|
|
|
|
# -----------------------------------
|
698
|
|
|
|
|
|
|
if( $td ) {
|
699
|
|
|
|
|
|
|
# Oben
|
700
|
|
|
|
|
|
|
$self->createPolygon(
|
701
|
|
|
|
|
|
|
$xi, $yi,
|
702
|
|
|
|
|
|
|
($xi + $td), ($yi - $td),
|
703
|
|
|
|
|
|
|
($xi + $width + $td), ($yi - $td),
|
704
|
|
|
|
|
|
|
($xi + $width ), ($yi ),
|
705
|
|
|
|
|
|
|
-fill => $self->color_change( $self->{colors}->{$name}, $conf->{light_top}),
|
706
|
|
|
|
|
|
|
-outline => 'black',
|
707
|
|
|
|
|
|
|
);
|
708
|
|
|
|
|
|
|
# Side
|
709
|
|
|
|
|
|
|
$self->createPolygon(
|
710
|
|
|
|
|
|
|
($xi + $width ), $conf->{y_null} ,
|
711
|
|
|
|
|
|
|
($xi + $width+$td ), ($conf->{y_null} - $td) ,
|
712
|
|
|
|
|
|
|
($xi + $width+$td), ($yi - $td),
|
713
|
|
|
|
|
|
|
($xi + $width ), ($yi ),
|
714
|
|
|
|
|
|
|
-fill => $self->color_change( $self->{colors}->{$name}, $conf->{light_side}),
|
715
|
|
|
|
|
|
|
-outline => 'black',
|
716
|
|
|
|
|
|
|
);
|
717
|
|
|
|
|
|
|
}
|
718
|
|
|
|
|
|
|
|
719
|
|
|
|
|
|
|
# Shadow Bar
|
720
|
|
|
|
|
|
|
if($wert && $self->cget(-shadowdepth) && (my $shadowcolor = $self->cget(-shadow)) && (my $sd = $self->cget(-shadowdepth)) && ! $self->cget(-threed)) {
|
721
|
|
|
|
|
|
|
$self->createRectangle(
|
722
|
|
|
|
|
|
|
($xi+$sd), ($yi+$sd),
|
723
|
|
|
|
|
|
|
($xi + $self->cget(-barwidth)+$sd), $conf->{y_null},
|
724
|
|
|
|
|
|
|
-fill => $shadowcolor,
|
725
|
|
|
|
|
|
|
-outline => $shadowcolor,
|
726
|
|
|
|
|
|
|
);
|
727
|
|
|
|
|
|
|
}
|
728
|
|
|
|
|
|
|
|
729
|
|
|
|
|
|
|
# Normaler Bar
|
730
|
|
|
|
|
|
|
$self->{elements}->{$name} = $self->createRectangle(
|
731
|
|
|
|
|
|
|
$xi, $yi,
|
732
|
|
|
|
|
|
|
($xi + $width), $height,
|
733
|
|
|
|
|
|
|
-fill => ( $self->cget(-threed) ? $self->color_change( $self->{colors}->{$name}, $conf->{light_front}) : $self->{colors}->{$name} ),
|
734
|
|
|
|
|
|
|
-width => 1,
|
735
|
|
|
|
|
|
|
) if($wert);
|
736
|
|
|
|
|
|
|
# -----------------------------------
|
737
|
|
|
|
|
|
|
|
738
|
|
|
|
|
|
|
# Values
|
739
|
|
|
|
|
|
|
$self->createText($xi+12+$td, $yi-12-$td,
|
740
|
|
|
|
|
|
|
-text => sprintf($self->cget(-printvalue), '', $wert),
|
741
|
|
|
|
|
|
|
-anchor => 'n',
|
742
|
|
|
|
|
|
|
-font => $conf->{font},
|
743
|
|
|
|
|
|
|
-fill => $self->cget(-titlecolor)
|
744
|
|
|
|
|
|
|
) if($self->cget(-printvalue));
|
745
|
|
|
|
|
|
|
|
746
|
|
|
|
|
|
|
|
747
|
|
|
|
|
|
|
|
748
|
|
|
|
|
|
|
|
749
|
|
|
|
|
|
|
}
|
750
|
|
|
|
|
|
|
|
751
|
|
|
|
|
|
|
#-------------------------------------------------
|
752
|
|
|
|
|
|
|
sub color_change {
|
753
|
|
|
|
|
|
|
#-------------------------------------------------
|
754
|
|
|
|
|
|
|
my $self = shift || return error("No Objekt!");
|
755
|
|
|
|
|
|
|
return undef unless(ref $self eq __PACKAGE__);
|
756
|
|
|
|
|
|
|
my $col = shift || return error("No Color!");
|
757
|
|
|
|
|
|
|
my $fac = shift || return $col;
|
758
|
|
|
|
|
|
|
|
759
|
|
|
|
|
|
|
my @colors = $self->rgb($col);
|
760
|
|
|
|
|
|
|
my $wert = '#';
|
761
|
|
|
|
|
|
|
foreach (@colors) {
|
762
|
|
|
|
|
|
|
my $dec = $_;
|
763
|
|
|
|
|
|
|
my $w = ($dec + (($dec * $fac) / 100));
|
764
|
|
|
|
|
|
|
$w = 0xFFFF if($w > 0xFFFF);
|
765
|
|
|
|
|
|
|
$w = 0 if($w < 0);
|
766
|
|
|
|
|
|
|
$wert .= sprintf('%X', $w);
|
767
|
|
|
|
|
|
|
}
|
768
|
|
|
|
|
|
|
|
769
|
|
|
|
|
|
|
$self->debug(
|
770
|
|
|
|
|
|
|
'Col: %s, Fac: %s, ColAfter: %s',
|
771
|
|
|
|
|
|
|
$col, $fac, $wert);
|
772
|
|
|
|
|
|
|
|
773
|
|
|
|
|
|
|
return $wert;
|
774
|
|
|
|
|
|
|
}
|
775
|
|
|
|
|
|
|
|
776
|
|
|
|
|
|
|
#-------------------------------------------------
|
777
|
|
|
|
|
|
|
sub draw_line {
|
778
|
|
|
|
|
|
|
#-------------------------------------------------
|
779
|
|
|
|
|
|
|
my $self = shift || return error("No Objekt!");
|
780
|
|
|
|
|
|
|
return undef unless(ref $self eq __PACKAGE__);
|
781
|
|
|
|
|
|
|
my $data = shift || return;
|
782
|
|
|
|
|
|
|
my $werte = $self->reference($data);
|
783
|
|
|
|
|
|
|
my $conf = $self->ReadConfig($werte) || return;
|
784
|
|
|
|
|
|
|
my $MAX;
|
785
|
|
|
|
|
|
|
|
786
|
|
|
|
|
|
|
$self->delete('all');
|
787
|
|
|
|
|
|
|
|
788
|
|
|
|
|
|
|
# Zeitverfolgung
|
789
|
|
|
|
|
|
|
$self->look($werte) if($data);
|
790
|
|
|
|
|
|
|
|
791
|
|
|
|
|
|
|
# MaxMin Werte ermitteln und ggf. Linien zeichnen
|
792
|
|
|
|
|
|
|
$self->maxmin($conf, $werte);
|
793
|
|
|
|
|
|
|
|
794
|
|
|
|
|
|
|
# Gitter zeichnen
|
795
|
|
|
|
|
|
|
$self->wire($conf, $data);
|
796
|
|
|
|
|
|
|
|
797
|
|
|
|
|
|
|
# Axis (Titel ... usw
|
798
|
|
|
|
|
|
|
$self->axis($conf, $werte);
|
799
|
|
|
|
|
|
|
|
800
|
|
|
|
|
|
|
if( $conf->{count} > 0 && ( $conf->{typ} eq 'HASH' || $self->cget(-look)))
|
801
|
|
|
|
|
|
|
{
|
802
|
|
|
|
|
|
|
my $z = 0;
|
803
|
|
|
|
|
|
|
my $data = ($self->cget(-look) ? $self->{look} : $werte);
|
804
|
|
|
|
|
|
|
my $w;
|
805
|
|
|
|
|
|
|
my $td = $self->cget(-threed) || 0;
|
806
|
|
|
|
|
|
|
my $th = round($td / 3) if(defined $td);
|
807
|
|
|
|
|
|
|
my $ti = -1;
|
808
|
|
|
|
|
|
|
|
809
|
|
|
|
|
|
|
foreach my $name (sort { $self->sorter } keys %{$data}) {
|
810
|
|
|
|
|
|
|
$ti++;
|
811
|
|
|
|
|
|
|
my @linepoints;
|
812
|
|
|
|
|
|
|
my $i = 0;
|
813
|
|
|
|
|
|
|
my ($xi, $yi, $xi_old, $yi_old);
|
814
|
|
|
|
|
|
|
|
815
|
|
|
|
|
|
|
foreach my $point (@{$data->{$name}}) {
|
816
|
|
|
|
|
|
|
$xi = $conf->{x_null} + ((round( ($conf->{width} - $conf->{x_null})/$conf->{count})) * $i++);
|
817
|
|
|
|
|
|
|
push(@linepoints, $xi);
|
818
|
|
|
|
|
|
|
$yi = $conf->{y_null} - (( $conf->{y_null} - $conf->{ypad_top})/$conf->{max_value} * $point);
|
819
|
|
|
|
|
|
|
push(@linepoints, $yi);
|
820
|
|
|
|
|
|
|
|
821
|
|
|
|
|
|
|
|
822
|
|
|
|
|
|
|
# 3d
|
823
|
|
|
|
|
|
|
if( $td && $#linepoints > 1 ) {
|
824
|
|
|
|
|
|
|
my $winkel = winkel( ($xi - $xi_old), ($yi - $yi_old) );
|
825
|
|
|
|
|
|
|
|
826
|
|
|
|
|
|
|
# Top
|
827
|
|
|
|
|
|
|
my $top = $self->createPolygon(
|
828
|
|
|
|
|
|
|
$xi, $yi,
|
829
|
|
|
|
|
|
|
($xi + $td), ($yi - $td),
|
830
|
|
|
|
|
|
|
($xi_old + $td), ($yi_old - $td),
|
831
|
|
|
|
|
|
|
($xi_old), ($yi_old),
|
832
|
|
|
|
|
|
|
|
833
|
|
|
|
|
|
|
-fill => $self->color_change(
|
834
|
|
|
|
|
|
|
$self->color($name, $point),
|
835
|
|
|
|
|
|
|
( $yi_old >= $yi ? $conf->{light_top} : $conf->{light_side} ),
|
836
|
|
|
|
|
|
|
),
|
837
|
|
|
|
|
|
|
-outline => $self->color($name, $point),
|
838
|
|
|
|
|
|
|
);
|
839
|
|
|
|
|
|
|
|
840
|
|
|
|
|
|
|
# Bottom
|
841
|
|
|
|
|
|
|
my $bottom = $self->createPolygon(
|
842
|
|
|
|
|
|
|
$xi, ($yi + $th),
|
843
|
|
|
|
|
|
|
($xi + $td), ($yi - $td + $th),
|
844
|
|
|
|
|
|
|
($xi_old + $td), ($yi_old - $td + $th),
|
845
|
|
|
|
|
|
|
($xi_old), ($yi_old + $th),
|
846
|
|
|
|
|
|
|
|
847
|
|
|
|
|
|
|
-fill => $self->color_change( $self->color($name, $point), $conf->{light_side} ),
|
848
|
|
|
|
|
|
|
-outline => $self->color($name, $point),
|
849
|
|
|
|
|
|
|
) if($winkel > 45 && $yi < $yi_old);
|
850
|
|
|
|
|
|
|
|
851
|
|
|
|
|
|
|
|
852
|
|
|
|
|
|
|
# Side
|
853
|
|
|
|
|
|
|
my $side = $self->createPolygon(
|
854
|
|
|
|
|
|
|
$xi, $yi,
|
855
|
|
|
|
|
|
|
($xi ), ($yi + $th),
|
856
|
|
|
|
|
|
|
$xi_old, ($yi_old + $th),
|
857
|
|
|
|
|
|
|
$xi_old , $yi_old,
|
858
|
|
|
|
|
|
|
|
859
|
|
|
|
|
|
|
-fill => $self->color_change( $self->color($name, $point), $conf->{light_front}),
|
860
|
|
|
|
|
|
|
-outline => $self->color($name, $point),
|
861
|
|
|
|
|
|
|
);
|
862
|
|
|
|
|
|
|
}
|
863
|
|
|
|
|
|
|
|
864
|
|
|
|
|
|
|
|
865
|
|
|
|
|
|
|
# Values
|
866
|
|
|
|
|
|
|
$self->createText($xi+12, $yi-12,
|
867
|
|
|
|
|
|
|
-text => sprintf($self->cget(-printvalue), '', $werte->{$point}),
|
868
|
|
|
|
|
|
|
-anchor => 'n',
|
869
|
|
|
|
|
|
|
-font => $conf->{font},
|
870
|
|
|
|
|
|
|
-fill => $self->cget(-titlecolor)
|
871
|
|
|
|
|
|
|
) if($self->cget(-printvalue));
|
872
|
|
|
|
|
|
|
|
873
|
|
|
|
|
|
|
# Dots
|
874
|
|
|
|
|
|
|
$self->createRectangle($xi-$self->cget(-dots), $yi-$self->cget(-dots),
|
875
|
|
|
|
|
|
|
$xi+$self->cget(-dots), $yi+$self->cget(-dots),
|
876
|
|
|
|
|
|
|
-fill => 'gray65',
|
877
|
|
|
|
|
|
|
-width => 1,
|
878
|
|
|
|
|
|
|
) if($self->cget(-dots));
|
879
|
|
|
|
|
|
|
|
880
|
|
|
|
|
|
|
# 3d (Abschluss)
|
881
|
|
|
|
|
|
|
if( $td && $i >= ( $#{$data->{$name}} + 1 ) ) {
|
882
|
|
|
|
|
|
|
# Side
|
883
|
|
|
|
|
|
|
$self->createPolygon(
|
884
|
|
|
|
|
|
|
$xi, $yi,
|
885
|
|
|
|
|
|
|
($xi + $td), ($yi - $td),
|
886
|
|
|
|
|
|
|
($xi + $td), ($yi - $td + $th),
|
887
|
|
|
|
|
|
|
$xi , $yi + $th,
|
888
|
|
|
|
|
|
|
|
889
|
|
|
|
|
|
|
-fill => $self->color_change( $self->color($name, $point), $conf->{light_side} ),
|
890
|
|
|
|
|
|
|
-outline => $self->color($name, $point),
|
891
|
|
|
|
|
|
|
);
|
892
|
|
|
|
|
|
|
}
|
893
|
|
|
|
|
|
|
|
894
|
|
|
|
|
|
|
# Graph Line
|
895
|
|
|
|
|
|
|
$self->{elements}->{$name} = $self->createLine(
|
896
|
|
|
|
|
|
|
$xi, $yi,
|
897
|
|
|
|
|
|
|
$xi_old, $yi_old,
|
898
|
|
|
|
|
|
|
-width => $self->cget(-linewidth),
|
899
|
|
|
|
|
|
|
-fill => $self->color($name, $point),
|
900
|
|
|
|
|
|
|
) if($xi_old);
|
901
|
|
|
|
|
|
|
|
902
|
|
|
|
|
|
|
|
903
|
|
|
|
|
|
|
$xi_old = $xi;
|
904
|
|
|
|
|
|
|
$yi_old = $yi;
|
905
|
|
|
|
|
|
|
}
|
906
|
|
|
|
|
|
|
|
907
|
|
|
|
|
|
|
}
|
908
|
|
|
|
|
|
|
|
909
|
|
|
|
|
|
|
# balloon
|
910
|
|
|
|
|
|
|
$self->balloon($self->{elements}, $werte);
|
911
|
|
|
|
|
|
|
|
912
|
|
|
|
|
|
|
# Legend
|
913
|
|
|
|
|
|
|
$self->legend($data, $conf);
|
914
|
|
|
|
|
|
|
}
|
915
|
|
|
|
|
|
|
}
|
916
|
|
|
|
|
|
|
|
917
|
|
|
|
|
|
|
#-------------------------------------------------
|
918
|
|
|
|
|
|
|
sub color {
|
919
|
|
|
|
|
|
|
#-------------------------------------------------
|
920
|
|
|
|
|
|
|
my $self = shift || return error("No Objekt!");
|
921
|
|
|
|
|
|
|
return undef unless(ref $self eq __PACKAGE__);
|
922
|
|
|
|
|
|
|
my $name = shift || return error("No Name in color");
|
923
|
|
|
|
|
|
|
my $wert = shift;
|
924
|
|
|
|
|
|
|
my $color = $self->{colors}->{$name} || 'black';
|
925
|
|
|
|
|
|
|
|
926
|
|
|
|
|
|
|
if(defined $self->{ranges}->{$name} && defined $wert) {
|
927
|
|
|
|
|
|
|
foreach $color ( keys %{$self->{ranges}->{$name}} ) {
|
928
|
|
|
|
|
|
|
my ($min, $max) = @{ $self->{ranges}->{$name}->{$color} };
|
929
|
|
|
|
|
|
|
if($wert >= $min and $wert <= $max) {
|
930
|
|
|
|
|
|
|
$self->debug('Name: %s, Color: %s, Wert: %g', $name, $color, ($wert || 'undef'));
|
931
|
|
|
|
|
|
|
return $color;
|
932
|
|
|
|
|
|
|
};
|
933
|
|
|
|
|
|
|
}
|
934
|
|
|
|
|
|
|
}
|
935
|
|
|
|
|
|
|
|
936
|
|
|
|
|
|
|
|
937
|
|
|
|
|
|
|
return $color;
|
938
|
|
|
|
|
|
|
}
|
939
|
|
|
|
|
|
|
|
940
|
|
|
|
|
|
|
|
941
|
|
|
|
|
|
|
#-------------------------------------------------
|
942
|
|
|
|
|
|
|
sub redraw {
|
943
|
|
|
|
|
|
|
#-------------------------------------------------
|
944
|
|
|
|
|
|
|
my $self = shift || return error("No Objekt!");
|
945
|
|
|
|
|
|
|
return undef unless(ref $self eq __PACKAGE__);
|
946
|
|
|
|
|
|
|
$self->debug('Redraw');
|
947
|
|
|
|
|
|
|
$self->set();
|
948
|
|
|
|
|
|
|
}
|
949
|
|
|
|
|
|
|
|
950
|
|
|
|
|
|
|
|
951
|
|
|
|
|
|
|
#-------------------------------------------------
|
952
|
|
|
|
|
|
|
sub automatic {
|
953
|
|
|
|
|
|
|
#-------------------------------------------------
|
954
|
|
|
|
|
|
|
my $self = shift || return error("No Objekt!");
|
955
|
|
|
|
|
|
|
return undef unless(ref $self eq __PACKAGE__);
|
956
|
|
|
|
|
|
|
return uc($self->cget(-type)) if($self->cget(-type));
|
957
|
|
|
|
|
|
|
|
958
|
|
|
|
|
|
|
my $data = shift || $self->{data};
|
959
|
|
|
|
|
|
|
|
960
|
|
|
|
|
|
|
my $type;
|
961
|
|
|
|
|
|
|
|
962
|
|
|
|
|
|
|
if(ref $data eq 'ARRAY') {
|
963
|
|
|
|
|
|
|
$type = 'LINE'
|
964
|
|
|
|
|
|
|
} elsif (ref $data eq 'HASH') {
|
965
|
|
|
|
|
|
|
foreach my $n (keys %$data) {
|
966
|
|
|
|
|
|
|
if(ref $data->{$n} eq 'ARRAY') {
|
967
|
|
|
|
|
|
|
$type = 'LINE';
|
968
|
|
|
|
|
|
|
last;
|
969
|
|
|
|
|
|
|
} elsif (ref $data->{$n} eq 'HASH'){
|
970
|
|
|
|
|
|
|
$type = 'BARS';
|
971
|
|
|
|
|
|
|
last;
|
972
|
|
|
|
|
|
|
} else {
|
973
|
|
|
|
|
|
|
$type = 'CIRCLE';
|
974
|
|
|
|
|
|
|
last;
|
975
|
|
|
|
|
|
|
}
|
976
|
|
|
|
|
|
|
}
|
977
|
|
|
|
|
|
|
}
|
978
|
|
|
|
|
|
|
return $type;
|
979
|
|
|
|
|
|
|
}
|
980
|
|
|
|
|
|
|
|
981
|
|
|
|
|
|
|
#-------------------------------------------------
|
982
|
|
|
|
|
|
|
sub set {
|
983
|
|
|
|
|
|
|
#-------------------------------------------------
|
984
|
|
|
|
|
|
|
my $self = shift || return error("No Objekt!");
|
985
|
|
|
|
|
|
|
return undef unless(ref $self eq __PACKAGE__);
|
986
|
|
|
|
|
|
|
my $data = shift;
|
987
|
|
|
|
|
|
|
|
988
|
|
|
|
|
|
|
return error('The Widget has no width and height values, you must pack before you can set!')
|
989
|
|
|
|
|
|
|
unless($self->width || $self->height);
|
990
|
|
|
|
|
|
|
|
991
|
|
|
|
|
|
|
# Make a LineGraph
|
992
|
|
|
|
|
|
|
if(ref $data eq 'ARRAY') {
|
993
|
|
|
|
|
|
|
my $werte;
|
994
|
|
|
|
|
|
|
$werte->{' '} = $data;
|
995
|
|
|
|
|
|
|
$data = $werte;
|
996
|
|
|
|
|
|
|
}
|
997
|
|
|
|
|
|
|
|
998
|
|
|
|
|
|
|
my $type = $self->automatic( $data );
|
999
|
|
|
|
|
|
|
|
1000
|
|
|
|
|
|
|
$self->{data} = $data if($data);
|
1001
|
|
|
|
|
|
|
|
1002
|
|
|
|
|
|
|
if( $type eq 'LINE' ) {
|
1003
|
|
|
|
|
|
|
$self->draw_line($data);
|
1004
|
|
|
|
|
|
|
|
1005
|
|
|
|
|
|
|
} elsif( $type eq 'CIRCLE' ) {
|
1006
|
|
|
|
|
|
|
$self->draw_circle($data);
|
1007
|
|
|
|
|
|
|
|
1008
|
|
|
|
|
|
|
} elsif( $type eq 'BARS' ) {
|
1009
|
|
|
|
|
|
|
$self->draw_bars($data);
|
1010
|
|
|
|
|
|
|
|
1011
|
|
|
|
|
|
|
} elsif( $type eq 'HBARS' ) {
|
1012
|
|
|
|
|
|
|
$self->draw_horizontal_bars( $data );
|
1013
|
|
|
|
|
|
|
|
1014
|
|
|
|
|
|
|
} else {
|
1015
|
|
|
|
|
|
|
return error("Option \'-type\' is incorrect! ($type)");
|
1016
|
|
|
|
|
|
|
}
|
1017
|
|
|
|
|
|
|
|
1018
|
|
|
|
|
|
|
|
1019
|
|
|
|
|
|
|
}
|
1020
|
|
|
|
|
|
|
|
1021
|
|
|
|
|
|
|
#-------------------------------------------------
|
1022
|
|
|
|
|
|
|
sub window_size {
|
1023
|
|
|
|
|
|
|
#-------------------------------------------------
|
1024
|
|
|
|
|
|
|
my $self = shift || return error("No Objekt!");
|
1025
|
|
|
|
|
|
|
return undef unless(ref $self eq __PACKAGE__);
|
1026
|
|
|
|
|
|
|
|
1027
|
|
|
|
|
|
|
my ($width, $height);
|
1028
|
|
|
|
|
|
|
my $conf = $self->{conf};
|
1029
|
|
|
|
|
|
|
$self->update;
|
1030
|
|
|
|
|
|
|
return unless( $self->cget(-fill) );
|
1031
|
|
|
|
|
|
|
unless(defined $conf->{width} && $conf->{width} > 1 && defined $conf->{height} && $conf->{height} > 1) {
|
1032
|
|
|
|
|
|
|
$width = $self->width;
|
1033
|
|
|
|
|
|
|
$height = $self->height;
|
1034
|
|
|
|
|
|
|
} else {
|
1035
|
|
|
|
|
|
|
$width = ( $self->cget(-fill) eq 'x' || $self->cget(-fill) eq 'both' ? $self->width : $conf->{width} );
|
1036
|
|
|
|
|
|
|
$height = ( $self->cget(-fill) eq 'y' || $self->cget(-fill) eq 'both' ? $self->height : $conf->{height} );
|
1037
|
|
|
|
|
|
|
}
|
1038
|
|
|
|
|
|
|
$self->debug('Width: %d, Height: %d', $width, $height);
|
1039
|
|
|
|
|
|
|
return ($width, $height);
|
1040
|
|
|
|
|
|
|
}
|
1041
|
|
|
|
|
|
|
|
1042
|
|
|
|
|
|
|
#-------------------------------------------------
|
1043
|
|
|
|
|
|
|
sub reference {
|
1044
|
|
|
|
|
|
|
#-------------------------------------------------
|
1045
|
|
|
|
|
|
|
my $self = shift || return error("No Objekt!");
|
1046
|
|
|
|
|
|
|
return undef unless(ref $self eq __PACKAGE__);
|
1047
|
|
|
|
|
|
|
my $data = shift || $self->{data} || return;
|
1048
|
|
|
|
|
|
|
my $reference = $self->cget(-reference) || return $data;
|
1049
|
|
|
|
|
|
|
my ($ref_name, $ref_value) = split(/,/, $reference);
|
1050
|
|
|
|
|
|
|
|
1051
|
|
|
|
|
|
|
if(ref $data eq 'HASH') {
|
1052
|
|
|
|
|
|
|
my %werte = %$data;
|
1053
|
|
|
|
|
|
|
my $summe;
|
1054
|
|
|
|
|
|
|
foreach (keys %werte) {
|
1055
|
|
|
|
|
|
|
$summe+=$werte{$_};
|
1056
|
|
|
|
|
|
|
}
|
1057
|
|
|
|
|
|
|
$werte{$ref_name} = $ref_value - $summe;
|
1058
|
|
|
|
|
|
|
return \%werte;
|
1059
|
|
|
|
|
|
|
}
|
1060
|
|
|
|
|
|
|
}
|
1061
|
|
|
|
|
|
|
|
1062
|
|
|
|
|
|
|
#-------------------------------------------------
|
1063
|
|
|
|
|
|
|
sub clear {
|
1064
|
|
|
|
|
|
|
#-------------------------------------------------
|
1065
|
|
|
|
|
|
|
my $self = shift || return error("No Objekt!");
|
1066
|
|
|
|
|
|
|
return undef unless(ref $self eq __PACKAGE__);
|
1067
|
|
|
|
|
|
|
$self->{data} = undef;
|
1068
|
|
|
|
|
|
|
$self->{look} = undef;
|
1069
|
|
|
|
|
|
|
$self->{colors} = undef;
|
1070
|
|
|
|
|
|
|
$self->redraw;
|
1071
|
|
|
|
|
|
|
}
|
1072
|
|
|
|
|
|
|
|
1073
|
|
|
|
|
|
|
#-------------------------------------------------
|
1074
|
|
|
|
|
|
|
sub variable {
|
1075
|
|
|
|
|
|
|
#-------------------------------------------------
|
1076
|
|
|
|
|
|
|
my ($graph, $vref) = @_;
|
1077
|
|
|
|
|
|
|
|
1078
|
|
|
|
|
|
|
$graph->{watch}->Unwatch
|
1079
|
|
|
|
|
|
|
if(defined $graph->{watch}); # Stoppen, falls ein Watch exisitiert
|
1080
|
|
|
|
|
|
|
|
1081
|
|
|
|
|
|
|
my $store = [sub {
|
1082
|
|
|
|
|
|
|
my($self, $key, $new_val) = @_;
|
1083
|
|
|
|
|
|
|
$self->Store($key, $new_val); # Stopft den neuen Wert ins Watch
|
1084
|
|
|
|
|
|
|
my $args = $self->Args(-store); # Nimmt warn Argumente
|
1085
|
|
|
|
|
|
|
$args->[0]->set($args->[1]); # Ruft warn interne Routine auf
|
1086
|
|
|
|
|
|
|
}, $graph, $vref];
|
1087
|
|
|
|
|
|
|
|
1088
|
|
|
|
|
|
|
$graph->{watch} = Tie::Watch->new(
|
1089
|
|
|
|
|
|
|
-variable => $vref,
|
1090
|
|
|
|
|
|
|
-store => $store );
|
1091
|
|
|
|
|
|
|
|
1092
|
|
|
|
|
|
|
$graph->set($vref);
|
1093
|
|
|
|
|
|
|
|
1094
|
|
|
|
|
|
|
$graph->OnDestroy( [sub {$_[0]->{watch}->Unwatch}, $graph] );
|
1095
|
|
|
|
|
|
|
} # end variable
|
1096
|
|
|
|
|
|
|
|
1097
|
|
|
|
|
|
|
#-------------------------------------------------
|
1098
|
|
|
|
|
|
|
sub ReadConfig {
|
1099
|
|
|
|
|
|
|
#-------------------------------------------------
|
1100
|
|
|
|
|
|
|
# Liest warn Daten und oder berechnet den Confighash
|
1101
|
|
|
|
|
|
|
my $self = shift || return error("No Objekt!");
|
1102
|
|
|
|
|
|
|
return undef unless(ref $self eq __PACKAGE__);
|
1103
|
|
|
|
|
|
|
my $data = shift || return error("No Data!");
|
1104
|
|
|
|
|
|
|
my $conf;
|
1105
|
|
|
|
|
|
|
|
1106
|
|
|
|
|
|
|
# Config
|
1107
|
|
|
|
|
|
|
$self->config($data);
|
1108
|
|
|
|
|
|
|
|
1109
|
|
|
|
|
|
|
# Typ der Daten
|
1110
|
|
|
|
|
|
|
$conf->{typ} = ref $data;
|
1111
|
|
|
|
|
|
|
|
1112
|
|
|
|
|
|
|
# Display Typ
|
1113
|
|
|
|
|
|
|
$conf->{type} = uc($self->cget(-type));
|
1114
|
|
|
|
|
|
|
|
1115
|
|
|
|
|
|
|
# Font
|
1116
|
|
|
|
|
|
|
$conf->{font} = $self->cget(-font);
|
1117
|
|
|
|
|
|
|
|
1118
|
|
|
|
|
|
|
# Standartcolor
|
1119
|
|
|
|
|
|
|
$conf->{fg} = $self->cget(-foreground);
|
1120
|
|
|
|
|
|
|
|
1121
|
|
|
|
|
|
|
# Headroom
|
1122
|
|
|
|
|
|
|
$conf->{headroom} = ($self->cget(-headroom) / 100) + 1;
|
1123
|
|
|
|
|
|
|
|
1124
|
|
|
|
|
|
|
# Light in 3D
|
1125
|
|
|
|
|
|
|
my $light = $self->cget(-light);
|
1126
|
|
|
|
|
|
|
$conf->{light_top} = $light->[0];
|
1127
|
|
|
|
|
|
|
$conf->{light_side} = $light->[1];
|
1128
|
|
|
|
|
|
|
$conf->{light_front} = $light->[2];
|
1129
|
|
|
|
|
|
|
|
1130
|
|
|
|
|
|
|
# Windowsize
|
1131
|
|
|
|
|
|
|
($conf->{width}, $conf->{height}) = $self->window_size();
|
1132
|
|
|
|
|
|
|
return unless($conf->{width} or $conf->{height});
|
1133
|
|
|
|
|
|
|
|
1134
|
|
|
|
|
|
|
$self->{conf}->{width} = $conf->{width};
|
1135
|
|
|
|
|
|
|
$self->{conf}->{height} = $conf->{height};
|
1136
|
|
|
|
|
|
|
|
1137
|
|
|
|
|
|
|
# Padding
|
1138
|
|
|
|
|
|
|
my $padding = $self->cget(-padding);
|
1139
|
|
|
|
|
|
|
$conf->{xpad} = $padding->[3];
|
1140
|
|
|
|
|
|
|
$conf->{xpad_right} = $padding->[1];
|
1141
|
|
|
|
|
|
|
$conf->{ypad} = $padding->[2];
|
1142
|
|
|
|
|
|
|
$conf->{ypad_top} = $padding->[0];
|
1143
|
|
|
|
|
|
|
|
1144
|
|
|
|
|
|
|
$conf->{width} -= $conf->{xpad_right};
|
1145
|
|
|
|
|
|
|
$conf->{height} -= $conf->{ypad_top};
|
1146
|
|
|
|
|
|
|
|
1147
|
|
|
|
|
|
|
# Title
|
1148
|
|
|
|
|
|
|
$conf->{title} = $self->cget(-title);
|
1149
|
|
|
|
|
|
|
$conf->{titlecolor} = $self->cget(-titlecolor);
|
1150
|
|
|
|
|
|
|
|
1151
|
|
|
|
|
|
|
# Coordinates
|
1152
|
|
|
|
|
|
|
$conf->{y_null} = $conf->{height} - $conf->{ypad}; # 0 Koordinate y-Achse
|
1153
|
|
|
|
|
|
|
$conf->{x_null} = $conf->{xpad}; # 0 Koordinate x-Achse
|
1154
|
|
|
|
|
|
|
|
1155
|
|
|
|
|
|
|
# Werte zaehlen
|
1156
|
|
|
|
|
|
|
$conf->{count} = 0;
|
1157
|
|
|
|
|
|
|
if($conf->{typ} eq 'ARRAY') {
|
1158
|
|
|
|
|
|
|
$conf->{count} = $#$data + 1;
|
1159
|
|
|
|
|
|
|
} elsif($conf->{typ} eq 'HASH' && $self->cget(-look) && $conf->{type} eq 'LINE') {
|
1160
|
|
|
|
|
|
|
$conf->{count} = $self->cget(-look);
|
1161
|
|
|
|
|
|
|
} elsif($conf->{typ} eq 'HASH' && $conf->{type} eq 'LINE') {
|
1162
|
|
|
|
|
|
|
# Durchzaehlen der Werte
|
1163
|
|
|
|
|
|
|
foreach ( keys %$data ) {
|
1164
|
|
|
|
|
|
|
$conf->{count} = $#{$data->{$_}}
|
1165
|
|
|
|
|
|
|
if(ref $data->{$_} eq 'ARRAY' && $#{$data->{$_}} > $conf->{count});
|
1166
|
|
|
|
|
|
|
}
|
1167
|
|
|
|
|
|
|
|
1168
|
|
|
|
|
|
|
} else {
|
1169
|
|
|
|
|
|
|
foreach ( keys %$data ) {
|
1170
|
|
|
|
|
|
|
next if(ref $data->{$_});
|
1171
|
|
|
|
|
|
|
$conf->{count}++;
|
1172
|
|
|
|
|
|
|
}
|
1173
|
|
|
|
|
|
|
}
|
1174
|
|
|
|
|
|
|
|
1175
|
|
|
|
|
|
|
$self->{cfg} = $conf;
|
1176
|
|
|
|
|
|
|
return $conf;
|
1177
|
|
|
|
|
|
|
}
|
1178
|
|
|
|
|
|
|
|
1179
|
|
|
|
|
|
|
#-------------------------------------------------
|
1180
|
|
|
|
|
|
|
sub axis {
|
1181
|
|
|
|
|
|
|
#-------------------------------------------------
|
1182
|
|
|
|
|
|
|
my $self = shift || return error("No Objekt!");
|
1183
|
|
|
|
|
|
|
return undef unless(ref $self eq __PACKAGE__);
|
1184
|
|
|
|
|
|
|
my $conf = shift || return error("No Config");
|
1185
|
|
|
|
|
|
|
my $werte = shift || return error("No Data");
|
1186
|
|
|
|
|
|
|
|
1187
|
|
|
|
|
|
|
|
1188
|
|
|
|
|
|
|
goto NOAXIS
|
1189
|
|
|
|
|
|
|
if($conf->{type} eq 'CIRCLE');
|
1190
|
|
|
|
|
|
|
|
1191
|
|
|
|
|
|
|
# Labels
|
1192
|
|
|
|
|
|
|
$self->labels();
|
1193
|
|
|
|
|
|
|
|
1194
|
|
|
|
|
|
|
# Threed
|
1195
|
|
|
|
|
|
|
my $td = $self->cget(-threed) || 0;
|
1196
|
|
|
|
|
|
|
|
1197
|
|
|
|
|
|
|
|
1198
|
|
|
|
|
|
|
# X - K O O R D I N A T E ------------------------------
|
1199
|
|
|
|
|
|
|
$self->createLine(
|
1200
|
|
|
|
|
|
|
$conf->{x_null}, $conf->{y_null},
|
1201
|
|
|
|
|
|
|
$conf->{width}, $conf->{y_null},
|
1202
|
|
|
|
|
|
|
-width => 1,
|
1203
|
|
|
|
|
|
|
-fill => $conf->{fg},
|
1204
|
|
|
|
|
|
|
);
|
1205
|
|
|
|
|
|
|
|
1206
|
|
|
|
|
|
|
|
1207
|
|
|
|
|
|
|
# X-Ticks
|
1208
|
|
|
|
|
|
|
if($conf->{type} eq 'HBARS' || $conf->{type} eq 'LINE') {
|
1209
|
|
|
|
|
|
|
for(my $i = 0; $i <= $self->cget(-xtick); $i++) {
|
1210
|
|
|
|
|
|
|
my $x = $conf->{x_null} + (round( ($conf->{width} - $conf->{x_null})/$self->cget(-xtick)) * $i);
|
1211
|
|
|
|
|
|
|
|
1212
|
|
|
|
|
|
|
$self->createLine(
|
1213
|
|
|
|
|
|
|
$x, ( $conf->{height} - ($conf->{ypad} + 5) ),
|
1214
|
|
|
|
|
|
|
$x, $conf->{y_null},
|
1215
|
|
|
|
|
|
|
-width => 1,
|
1216
|
|
|
|
|
|
|
-fill => $conf->{fg},
|
1217
|
|
|
|
|
|
|
);
|
1218
|
|
|
|
|
|
|
$self->createText(
|
1219
|
|
|
|
|
|
|
$x, $conf->{y_null},
|
1220
|
|
|
|
|
|
|
-text => sprintf(' '.$self->cget(-xformat), ( ($conf->{type} eq 'HBARS' ? $conf->{max_value} : $conf->{count}) / $self->cget(-xtick)) * $i),
|
1221
|
|
|
|
|
|
|
-anchor => 'n',
|
1222
|
|
|
|
|
|
|
-font => $conf->{font},
|
1223
|
|
|
|
|
|
|
-fill => $conf->{fg},
|
1224
|
|
|
|
|
|
|
) if($i);
|
1225
|
|
|
|
|
|
|
}
|
1226
|
|
|
|
|
|
|
} else {
|
1227
|
|
|
|
|
|
|
my $i = -1;
|
1228
|
|
|
|
|
|
|
foreach my $name ( sort { $self->sorter } keys %$werte) {
|
1229
|
|
|
|
|
|
|
next if(ref $werte->{$name});
|
1230
|
|
|
|
|
|
|
$i++;
|
1231
|
|
|
|
|
|
|
my $text = sprintf($self->cget(-xformat), $name);
|
1232
|
|
|
|
|
|
|
my $x = $self->calc_x($i+1);
|
1233
|
|
|
|
|
|
|
|
1234
|
|
|
|
|
|
|
$self->createLine(
|
1235
|
|
|
|
|
|
|
$x, ($conf->{height}-($conf->{ypad}+5)),
|
1236
|
|
|
|
|
|
|
$x, $conf->{y_null},
|
1237
|
|
|
|
|
|
|
-width => 1,
|
1238
|
|
|
|
|
|
|
-fill => $conf->{fg},
|
1239
|
|
|
|
|
|
|
);
|
1240
|
|
|
|
|
|
|
$self->createText($x, $conf->{y_null},
|
1241
|
|
|
|
|
|
|
-text => $text,
|
1242
|
|
|
|
|
|
|
-anchor => 'n',
|
1243
|
|
|
|
|
|
|
-font => $conf->{font},
|
1244
|
|
|
|
|
|
|
-fill => $conf->{fg},
|
1245
|
|
|
|
|
|
|
);
|
1246
|
|
|
|
|
|
|
}
|
1247
|
|
|
|
|
|
|
}
|
1248
|
|
|
|
|
|
|
# X - K O O R D I N A T E ---------BOTTOM----------------
|
1249
|
|
|
|
|
|
|
|
1250
|
|
|
|
|
|
|
|
1251
|
|
|
|
|
|
|
# Y - K O O R D I N A T E -------------------------------
|
1252
|
|
|
|
|
|
|
$self->createLine(
|
1253
|
|
|
|
|
|
|
$conf->{x_null}, $conf->{y_null},
|
1254
|
|
|
|
|
|
|
$conf->{x_null}, $conf->{ypad_top},
|
1255
|
|
|
|
|
|
|
-width => 1,
|
1256
|
|
|
|
|
|
|
-fill => $conf->{fg},
|
1257
|
|
|
|
|
|
|
);
|
1258
|
|
|
|
|
|
|
|
1259
|
|
|
|
|
|
|
$self->createLine(
|
1260
|
|
|
|
|
|
|
$conf->{x_null}+$td, $conf->{y_null}-$td,
|
1261
|
|
|
|
|
|
|
$conf->{x_null}+$td, $conf->{ypad_top}-$td,
|
1262
|
|
|
|
|
|
|
-width => 1,
|
1263
|
|
|
|
|
|
|
-fill => $self->cget(-wire),
|
1264
|
|
|
|
|
|
|
) if($td);
|
1265
|
|
|
|
|
|
|
|
1266
|
|
|
|
|
|
|
|
1267
|
|
|
|
|
|
|
if($conf->{type} eq 'HBARS') {
|
1268
|
|
|
|
|
|
|
my $i = 0.5;
|
1269
|
|
|
|
|
|
|
foreach my $name ( sort { $self->sorter } keys %$werte) {
|
1270
|
|
|
|
|
|
|
|
1271
|
|
|
|
|
|
|
my $y = ($conf->{y_null}) - (int(($conf->{y_null} - $conf->{ypad_top}) / $conf->{count} + 0.99) * $i++);
|
1272
|
|
|
|
|
|
|
|
1273
|
|
|
|
|
|
|
$self->createLine(
|
1274
|
|
|
|
|
|
|
$conf->{x_null}, $y,
|
1275
|
|
|
|
|
|
|
$conf->{x_null}-5, $y,
|
1276
|
|
|
|
|
|
|
-width => 1,
|
1277
|
|
|
|
|
|
|
-fill => $conf->{fg},
|
1278
|
|
|
|
|
|
|
);
|
1279
|
|
|
|
|
|
|
|
1280
|
|
|
|
|
|
|
$self->createText($conf->{x_null}-8, $y,
|
1281
|
|
|
|
|
|
|
-text => $name,
|
1282
|
|
|
|
|
|
|
-anchor => 'e',
|
1283
|
|
|
|
|
|
|
-font => $conf->{font},
|
1284
|
|
|
|
|
|
|
-fill => $conf->{fg},
|
1285
|
|
|
|
|
|
|
);
|
1286
|
|
|
|
|
|
|
}
|
1287
|
|
|
|
|
|
|
} else {
|
1288
|
|
|
|
|
|
|
for (my $i = 0; $i <= $self->cget(-ytick); $i++) {
|
1289
|
|
|
|
|
|
|
next unless($i);
|
1290
|
|
|
|
|
|
|
|
1291
|
|
|
|
|
|
|
my $y = ($conf->{y_null}) - (round( ( $conf->{y_null} - $conf->{ypad_top} )/$self->cget(-ytick)) * $i);
|
1292
|
|
|
|
|
|
|
$self->createLine(
|
1293
|
|
|
|
|
|
|
$conf->{x_null}, $y,
|
1294
|
|
|
|
|
|
|
$conf->{x_null}-5, $y,
|
1295
|
|
|
|
|
|
|
-width => 1,
|
1296
|
|
|
|
|
|
|
-fill => $conf->{fg},
|
1297
|
|
|
|
|
|
|
);
|
1298
|
|
|
|
|
|
|
|
1299
|
|
|
|
|
|
|
$self->createText($conf->{x_null}-8, $y,
|
1300
|
|
|
|
|
|
|
-text => sprintf($self->cget(-yformat), (($conf->{max_value}/$self->cget(-ytick)) * $i)), -anchor => 'e',
|
1301
|
|
|
|
|
|
|
-font => $conf->{font},
|
1302
|
|
|
|
|
|
|
-fill => $conf->{fg},
|
1303
|
|
|
|
|
|
|
);
|
1304
|
|
|
|
|
|
|
}
|
1305
|
|
|
|
|
|
|
}
|
1306
|
|
|
|
|
|
|
# Y - K O O R D I N A T E ---------BOTTOM----------------
|
1307
|
|
|
|
|
|
|
|
1308
|
|
|
|
|
|
|
NOAXIS:
|
1309
|
|
|
|
|
|
|
|
1310
|
|
|
|
|
|
|
# Titel
|
1311
|
|
|
|
|
|
|
$self->createText(
|
1312
|
|
|
|
|
|
|
($conf->{width} / 2), $self->cget(-lineheight),
|
1313
|
|
|
|
|
|
|
-text => $conf->{title},
|
1314
|
|
|
|
|
|
|
-justify => 'center',
|
1315
|
|
|
|
|
|
|
-fill => $conf->{titlecolor},
|
1316
|
|
|
|
|
|
|
) if($conf->{title});
|
1317
|
|
|
|
|
|
|
}
|
1318
|
|
|
|
|
|
|
|
1319
|
|
|
|
|
|
|
#-------------------------------------------------
|
1320
|
|
|
|
|
|
|
sub maxmin {
|
1321
|
|
|
|
|
|
|
#-------------------------------------------------
|
1322
|
|
|
|
|
|
|
my $self = shift || return error("No Objekt!");
|
1323
|
|
|
|
|
|
|
return undef unless(ref $self eq __PACKAGE__);
|
1324
|
|
|
|
|
|
|
my $conf = shift || return error("No Config");
|
1325
|
|
|
|
|
|
|
my $werte = shift || return error("No Data");
|
1326
|
|
|
|
|
|
|
my $MAX;
|
1327
|
|
|
|
|
|
|
|
1328
|
|
|
|
|
|
|
if($conf->{typ} eq 'HASH' && $conf->{type} eq 'LINE')
|
1329
|
|
|
|
|
|
|
{
|
1330
|
|
|
|
|
|
|
$MAX->{$conf->{title}}->{min} = 10000 unless $MAX->{$conf->{title}}->{min};
|
1331
|
|
|
|
|
|
|
$MAX->{$conf->{title}}->{max} = 0 unless $MAX->{$conf->{title}}->{max};
|
1332
|
|
|
|
|
|
|
my $data = ($self->cget(-look) ? $self->{look} : $werte);
|
1333
|
|
|
|
|
|
|
foreach my $name (keys %{$data}) {
|
1334
|
|
|
|
|
|
|
foreach my $value (@{$data->{$name}}) {
|
1335
|
|
|
|
|
|
|
$MAX->{$conf->{title}}->{max} = $value if( $MAX->{$conf->{title}}->{max} <= $value );
|
1336
|
|
|
|
|
|
|
$MAX->{$conf->{title}}->{min} = $value if( $MAX->{$conf->{title}}->{min} >= $value );
|
1337
|
|
|
|
|
|
|
$MAX->{$conf->{title}}->{avg} =
|
1338
|
|
|
|
|
|
|
( $MAX->{$conf->{title}}->{max} - $MAX->{$conf->{title}}->{min} ) / 2 +
|
1339
|
|
|
|
|
|
|
$MAX->{$conf->{title}}->{min};
|
1340
|
|
|
|
|
|
|
}
|
1341
|
|
|
|
|
|
|
}
|
1342
|
|
|
|
|
|
|
$conf->{max_value} = $self->cget(-max)
|
1343
|
|
|
|
|
|
|
? $self->cget(-max)
|
1344
|
|
|
|
|
|
|
: $MAX->{$conf->{title}}->{max} * $conf->{headroom};
|
1345
|
|
|
|
|
|
|
}
|
1346
|
|
|
|
|
|
|
elsif($conf->{typ} eq 'ARRAY')
|
1347
|
|
|
|
|
|
|
{
|
1348
|
|
|
|
|
|
|
$MAX->{$conf->{title}}->{min} = 10000 unless $MAX->{$conf->{title}}->{min};
|
1349
|
|
|
|
|
|
|
$MAX->{$conf->{title}}->{max} = 0 unless $MAX->{$conf->{title}}->{max};
|
1350
|
|
|
|
|
|
|
foreach my $value (@{$werte}) {
|
1351
|
|
|
|
|
|
|
$MAX->{$conf->{title}}->{max} = $value if( $MAX->{$conf->{title}}->{max} <= $value );
|
1352
|
|
|
|
|
|
|
$MAX->{$conf->{title}}->{min} = $value if( $MAX->{$conf->{title}}->{min} >= $value );
|
1353
|
|
|
|
|
|
|
$MAX->{$conf->{title}}->{avg} =
|
1354
|
|
|
|
|
|
|
( $MAX->{$conf->{title}}->{max} - $MAX->{$conf->{title}}->{min} ) / 2 +
|
1355
|
|
|
|
|
|
|
$MAX->{$conf->{title}}->{min};
|
1356
|
|
|
|
|
|
|
}
|
1357
|
|
|
|
|
|
|
$conf->{max_value} = $self->cget(-max)
|
1358
|
|
|
|
|
|
|
? $self->cget(-max)
|
1359
|
|
|
|
|
|
|
: $MAX->{$conf->{title}}->{max} * $conf->{headroom};
|
1360
|
|
|
|
|
|
|
}
|
1361
|
|
|
|
|
|
|
elsif ($conf->{typ} eq 'HASH')
|
1362
|
|
|
|
|
|
|
{
|
1363
|
|
|
|
|
|
|
$MAX->{$conf->{title}}->{min} = 10000 unless $MAX->{$conf->{title}}->{min};
|
1364
|
|
|
|
|
|
|
$MAX->{$conf->{title}}->{max} = 0 unless $MAX->{$conf->{title}}->{max};
|
1365
|
|
|
|
|
|
|
|
1366
|
|
|
|
|
|
|
foreach my $name (keys %{$werte}) {
|
1367
|
|
|
|
|
|
|
next if ref $werte->{$name};
|
1368
|
|
|
|
|
|
|
my $value = $werte->{$name} || 0;
|
1369
|
|
|
|
|
|
|
$MAX->{$conf->{title}}->{max} = $value if( $MAX->{$conf->{title}}->{max} <= $value );
|
1370
|
|
|
|
|
|
|
$MAX->{$conf->{title}}->{min} = $value if( $MAX->{$conf->{title}}->{min} >= $value ); $MAX->{$conf->{title}}->{avg} =
|
1371
|
|
|
|
|
|
|
$MAX->{$conf->{title}}->{avg} =
|
1372
|
|
|
|
|
|
|
( $MAX->{$conf->{title}}->{max} - $MAX->{$conf->{title}}->{min} ) / 2 +
|
1373
|
|
|
|
|
|
|
$MAX->{$conf->{title}}->{min};
|
1374
|
|
|
|
|
|
|
}
|
1375
|
|
|
|
|
|
|
$conf->{max_value} = $self->cget(-max)
|
1376
|
|
|
|
|
|
|
? $self->cget(-max)
|
1377
|
|
|
|
|
|
|
: $MAX->{$conf->{title}}->{max} * $conf->{headroom};
|
1378
|
|
|
|
|
|
|
}
|
1379
|
|
|
|
|
|
|
|
1380
|
|
|
|
|
|
|
$conf->{max_value} = 1 unless($conf->{max_value});
|
1381
|
|
|
|
|
|
|
|
1382
|
|
|
|
|
|
|
# MAX-MIN Linien
|
1383
|
|
|
|
|
|
|
if($self->cget(-maxmin) && $conf->{max_value} && ! $conf->{type} eq 'CIRCLE') {
|
1384
|
|
|
|
|
|
|
my $xa = $conf->{x_null};
|
1385
|
|
|
|
|
|
|
my $xe = $conf->{width}+10;
|
1386
|
|
|
|
|
|
|
my $y = $conf->{y_null} - int((($conf->{y_null})/$conf->{max_value}) * $MAX->{$conf->{title}}->{min});
|
1387
|
|
|
|
|
|
|
|
1388
|
|
|
|
|
|
|
if($conf->{type} !~ /BARS/) {
|
1389
|
|
|
|
|
|
|
$self->createLine($xa, $y, $xe, $y,
|
1390
|
|
|
|
|
|
|
-width => 1,
|
1391
|
|
|
|
|
|
|
-fill => 'gray65'); # MIN-Linie
|
1392
|
|
|
|
|
|
|
|
1393
|
|
|
|
|
|
|
$self->createText($xe-20, $y,
|
1394
|
|
|
|
|
|
|
-text => sprintf($self->cget(-printvalue) || '%g', $MAX->{$conf->{title}}->{min}),
|
1395
|
|
|
|
|
|
|
-anchor => 'se',
|
1396
|
|
|
|
|
|
|
-font => $conf->{font},
|
1397
|
|
|
|
|
|
|
-fill => 'gray65');
|
1398
|
|
|
|
|
|
|
|
1399
|
|
|
|
|
|
|
|
1400
|
|
|
|
|
|
|
$y = $conf->{y_null} - int((($conf->{y_null})/$conf->{max_value}) * $MAX->{$conf->{title}}->{avg});
|
1401
|
|
|
|
|
|
|
$self->createLine($xa, $y, $xe, $y,
|
1402
|
|
|
|
|
|
|
-width => 1,
|
1403
|
|
|
|
|
|
|
-fill => 'gray65'); # AVG-Linie
|
1404
|
|
|
|
|
|
|
|
1405
|
|
|
|
|
|
|
$self->createText($xe-20, $y,
|
1406
|
|
|
|
|
|
|
-text => sprintf($self->cget(-printvalue) || '%g', $MAX->{$conf->{title}}->{avg}),
|
1407
|
|
|
|
|
|
|
-anchor => 'se',
|
1408
|
|
|
|
|
|
|
-font => $conf->{font},
|
1409
|
|
|
|
|
|
|
-fill => 'gray65');
|
1410
|
|
|
|
|
|
|
|
1411
|
|
|
|
|
|
|
|
1412
|
|
|
|
|
|
|
|
1413
|
|
|
|
|
|
|
$y = $conf->{y_null} - int((($conf->{y_null})/$conf->{max_value}) * $MAX->{$conf->{title}}->{max}),
|
1414
|
|
|
|
|
|
|
$self->createLine($xa, $y, $xe, $y,
|
1415
|
|
|
|
|
|
|
-width => 1,
|
1416
|
|
|
|
|
|
|
-fill => 'gray65'); # AVG-Linie
|
1417
|
|
|
|
|
|
|
|
1418
|
|
|
|
|
|
|
$self->createText($xe-20, $y,
|
1419
|
|
|
|
|
|
|
-text => sprintf($self->cget(-printvalue) || '%g', $MAX->{$conf->{title}}->{max}),
|
1420
|
|
|
|
|
|
|
-anchor => 'se',
|
1421
|
|
|
|
|
|
|
-font => $conf->{font},
|
1422
|
|
|
|
|
|
|
-fill => 'gray65');
|
1423
|
|
|
|
|
|
|
}
|
1424
|
|
|
|
|
|
|
}
|
1425
|
|
|
|
|
|
|
# --
|
1426
|
|
|
|
|
|
|
|
1427
|
|
|
|
|
|
|
}
|
1428
|
|
|
|
|
|
|
|
1429
|
|
|
|
|
|
|
|
1430
|
|
|
|
|
|
|
#-------------------------------------------------
|
1431
|
|
|
|
|
|
|
sub draw_circle {
|
1432
|
|
|
|
|
|
|
#-------------------------------------------------
|
1433
|
|
|
|
|
|
|
# Plot LineStats
|
1434
|
|
|
|
|
|
|
my $self = shift || return error("No Objekt!");
|
1435
|
|
|
|
|
|
|
return undef unless(ref $self eq __PACKAGE__);
|
1436
|
|
|
|
|
|
|
my $data = shift || return;
|
1437
|
|
|
|
|
|
|
|
1438
|
|
|
|
|
|
|
# Check
|
1439
|
|
|
|
|
|
|
return warn("Your data is incorrect, i need a Hashreference!")
|
1440
|
|
|
|
|
|
|
unless(ref $data eq 'HASH');
|
1441
|
|
|
|
|
|
|
|
1442
|
|
|
|
|
|
|
|
1443
|
|
|
|
|
|
|
my $werte = $self->reference($data);
|
1444
|
|
|
|
|
|
|
my $conf = $self->ReadConfig($werte) || return;
|
1445
|
|
|
|
|
|
|
|
1446
|
|
|
|
|
|
|
$self->delete('all');
|
1447
|
|
|
|
|
|
|
|
1448
|
|
|
|
|
|
|
# MaxMin Werte ermitteln und ggf Linien zeichnen
|
1449
|
|
|
|
|
|
|
$self->maxmin($conf, $werte);
|
1450
|
|
|
|
|
|
|
|
1451
|
|
|
|
|
|
|
# Axis (Titel ... usw
|
1452
|
|
|
|
|
|
|
$self->axis($conf, $werte);
|
1453
|
|
|
|
|
|
|
|
1454
|
|
|
|
|
|
|
# Sizes
|
1455
|
|
|
|
|
|
|
my $width = ($self->cget(-legend) ? $conf->{height} : $conf->{width});
|
1456
|
|
|
|
|
|
|
my $height = $conf->{y_null};
|
1457
|
|
|
|
|
|
|
|
1458
|
|
|
|
|
|
|
# Shadow
|
1459
|
|
|
|
|
|
|
$self->createOval(
|
1460
|
|
|
|
|
|
|
($conf->{x_null} + $self->cget(-shadowdepth) ), ($conf->{ypad_top} + $self->cget(-shadowdepth)),
|
1461
|
|
|
|
|
|
|
($width + $self->cget(-shadowdepth)), ($height + $self->cget(-shadowdepth)),
|
1462
|
|
|
|
|
|
|
-fill => $self->cget(-shadow),
|
1463
|
|
|
|
|
|
|
-outline => $self->cget(-shadow),
|
1464
|
|
|
|
|
|
|
-width => 0,
|
1465
|
|
|
|
|
|
|
) if($self->cget(-shadowdepth)); # Schatten
|
1466
|
|
|
|
|
|
|
|
1467
|
|
|
|
|
|
|
# Segments
|
1468
|
|
|
|
|
|
|
my ($summe, $start, $count, $grad, $x, $y);
|
1469
|
|
|
|
|
|
|
foreach ( keys %$werte ) { $summe+=$werte->{$_} };
|
1470
|
|
|
|
|
|
|
$start = 0;
|
1471
|
|
|
|
|
|
|
$count = 0;
|
1472
|
|
|
|
|
|
|
|
1473
|
|
|
|
|
|
|
foreach my $name (sort { $self->sorter } keys %$werte ) {
|
1474
|
|
|
|
|
|
|
my $col = $self->{colors}->{$name};
|
1475
|
|
|
|
|
|
|
next unless $werte->{$name};
|
1476
|
|
|
|
|
|
|
$grad = (360/$summe) * $werte->{$name};
|
1477
|
|
|
|
|
|
|
$grad = 359.99 if($grad == 360);
|
1478
|
|
|
|
|
|
|
|
1479
|
|
|
|
|
|
|
$self->{elements}->{$name} = $self->createArc(
|
1480
|
|
|
|
|
|
|
$conf->{x_null}, $conf->{ypad_top},
|
1481
|
|
|
|
|
|
|
$width, $height,
|
1482
|
|
|
|
|
|
|
-width => $self->cget(-linewidth),
|
1483
|
|
|
|
|
|
|
-fill => $col,
|
1484
|
|
|
|
|
|
|
-start => $start,
|
1485
|
|
|
|
|
|
|
-extent => $grad,
|
1486
|
|
|
|
|
|
|
);
|
1487
|
|
|
|
|
|
|
|
1488
|
|
|
|
|
|
|
$start+=$grad;
|
1489
|
|
|
|
|
|
|
}
|
1490
|
|
|
|
|
|
|
|
1491
|
|
|
|
|
|
|
# balloon
|
1492
|
|
|
|
|
|
|
$self->balloon($self->{elements}, $werte);
|
1493
|
|
|
|
|
|
|
|
1494
|
|
|
|
|
|
|
# Legend
|
1495
|
|
|
|
|
|
|
$self->legend($werte);
|
1496
|
|
|
|
|
|
|
}
|
1497
|
|
|
|
|
|
|
|
1498
|
|
|
|
|
|
|
#-------------------------------------------------
|
1499
|
|
|
|
|
|
|
sub labels {
|
1500
|
|
|
|
|
|
|
#-------------------------------------------------
|
1501
|
|
|
|
|
|
|
my $self = shift || return error("No Objekt!");
|
1502
|
|
|
|
|
|
|
return undef unless(ref $self eq __PACKAGE__);
|
1503
|
|
|
|
|
|
|
my $conf = $self->{cfg};
|
1504
|
|
|
|
|
|
|
|
1505
|
|
|
|
|
|
|
# X-Achse --------------------------------
|
1506
|
|
|
|
|
|
|
if($self->cget(-xlabel)) {
|
1507
|
|
|
|
|
|
|
$self->createLine(
|
1508
|
|
|
|
|
|
|
$conf->{width} - ($conf->{width} / 10), $conf->{y_null} - 10,
|
1509
|
|
|
|
|
|
|
$conf->{width} - 5, $conf->{y_null} - 10,
|
1510
|
|
|
|
|
|
|
-arrow => 'last',
|
1511
|
|
|
|
|
|
|
-fill => $conf->{fg},
|
1512
|
|
|
|
|
|
|
);
|
1513
|
|
|
|
|
|
|
|
1514
|
|
|
|
|
|
|
$self->createText(
|
1515
|
|
|
|
|
|
|
$conf->{width} - ($conf->{width} / 10) - 5, $conf->{y_null} - 10,
|
1516
|
|
|
|
|
|
|
-text => $self->cget(-xlabel),
|
1517
|
|
|
|
|
|
|
-font => $conf->{font},
|
1518
|
|
|
|
|
|
|
-fill => $conf->{fg},
|
1519
|
|
|
|
|
|
|
-anchor => 'e',
|
1520
|
|
|
|
|
|
|
);
|
1521
|
|
|
|
|
|
|
}
|
1522
|
|
|
|
|
|
|
# ---------------------------------------
|
1523
|
|
|
|
|
|
|
|
1524
|
|
|
|
|
|
|
# Y-Achse --------------------------------
|
1525
|
|
|
|
|
|
|
if($self->cget(-ylabel)) {
|
1526
|
|
|
|
|
|
|
$self->createLine(
|
1527
|
|
|
|
|
|
|
$conf->{x_null} + 10, $conf->{ypad_top} - 5,
|
1528
|
|
|
|
|
|
|
$conf->{x_null} + 10, $conf->{ypad_top} + ($conf->{height} / 10),
|
1529
|
|
|
|
|
|
|
-arrow => 'first',
|
1530
|
|
|
|
|
|
|
-fill => $conf->{fg},
|
1531
|
|
|
|
|
|
|
);
|
1532
|
|
|
|
|
|
|
|
1533
|
|
|
|
|
|
|
$self->createText(
|
1534
|
|
|
|
|
|
|
$conf->{x_null} + 15, $conf->{ypad_top} + ($conf->{height} / 10),
|
1535
|
|
|
|
|
|
|
-text => $self->cget(-ylabel),
|
1536
|
|
|
|
|
|
|
-font => $conf->{font},
|
1537
|
|
|
|
|
|
|
-anchor => 'w',
|
1538
|
|
|
|
|
|
|
-fill => $conf->{fg},
|
1539
|
|
|
|
|
|
|
);
|
1540
|
|
|
|
|
|
|
}
|
1541
|
|
|
|
|
|
|
# ---------------------------------------
|
1542
|
|
|
|
|
|
|
|
1543
|
|
|
|
|
|
|
}
|
1544
|
|
|
|
|
|
|
|
1545
|
|
|
|
|
|
|
|
1546
|
|
|
|
|
|
|
#-------------------------------------------------
|
1547
|
|
|
|
|
|
|
sub legend {
|
1548
|
|
|
|
|
|
|
#-------------------------------------------------
|
1549
|
|
|
|
|
|
|
my $self = shift || return error("No Objekt!");
|
1550
|
|
|
|
|
|
|
return undef unless(ref $self eq __PACKAGE__);
|
1551
|
|
|
|
|
|
|
my $data = shift || return error("No Data!");
|
1552
|
|
|
|
|
|
|
my $conf = $self->{cfg};
|
1553
|
|
|
|
|
|
|
return unless($self->cget(-legend));
|
1554
|
|
|
|
|
|
|
|
1555
|
|
|
|
|
|
|
my $c = 0;
|
1556
|
|
|
|
|
|
|
my $fw = $self->cget(-lineheight) || 15;
|
1557
|
|
|
|
|
|
|
|
1558
|
|
|
|
|
|
|
foreach my $name (sort { $self->sorter } keys %$data) {
|
1559
|
|
|
|
|
|
|
my $x = $conf->{width};
|
1560
|
|
|
|
|
|
|
my $y = $fw + ( $fw * $c ); # XXX
|
1561
|
|
|
|
|
|
|
|
1562
|
|
|
|
|
|
|
my $thick = $self->cget(-dots) || 5;
|
1563
|
|
|
|
|
|
|
|
1564
|
|
|
|
|
|
|
$self->createRectangle($x, $y,
|
1565
|
|
|
|
|
|
|
$x-$thick, $y-$thick,
|
1566
|
|
|
|
|
|
|
-fill => $self->{colors}->{$name},
|
1567
|
|
|
|
|
|
|
-width => $self->cget(-linewidth),
|
1568
|
|
|
|
|
|
|
);
|
1569
|
|
|
|
|
|
|
|
1570
|
|
|
|
|
|
|
$self->createText($x - ($thick*2), $y,
|
1571
|
|
|
|
|
|
|
-text => sprintf( $self->cget(-printvalue) || '%s: %s', $name, (ref $data->{$name} ? '' : $data->{$name}) ),
|
1572
|
|
|
|
|
|
|
-font => $conf->{font},
|
1573
|
|
|
|
|
|
|
-anchor => 'e',
|
1574
|
|
|
|
|
|
|
-fill => $conf->{fg},
|
1575
|
|
|
|
|
|
|
);
|
1576
|
|
|
|
|
|
|
$c++
|
1577
|
|
|
|
|
|
|
}
|
1578
|
|
|
|
|
|
|
}
|
1579
|
|
|
|
|
|
|
|
1580
|
|
|
|
|
|
|
|
1581
|
|
|
|
|
|
|
#-------------------------------------------------
|
1582
|
|
|
|
|
|
|
sub readData {
|
1583
|
|
|
|
|
|
|
#-------------------------------------------------
|
1584
|
|
|
|
|
|
|
my $self = shift || return error("No Objekt!");
|
1585
|
|
|
|
|
|
|
return undef unless(ref $self eq __PACKAGE__);
|
1586
|
|
|
|
|
|
|
my $c = $self->configure;
|
1587
|
|
|
|
|
|
|
my $config;
|
1588
|
|
|
|
|
|
|
foreach my $n ($c) {
|
1589
|
|
|
|
|
|
|
$config->{$n->[0]} = $n->[3];
|
1590
|
|
|
|
|
|
|
}
|
1591
|
|
|
|
|
|
|
}
|
1592
|
|
|
|
|
|
|
|
1593
|
|
|
|
|
|
|
|
1594
|
|
|
|
|
|
|
#-------------------------------------------------
|
1595
|
|
|
|
|
|
|
sub wire {
|
1596
|
|
|
|
|
|
|
#-------------------------------------------------
|
1597
|
|
|
|
|
|
|
my $self = shift || return error("No Objekt!");
|
1598
|
|
|
|
|
|
|
return undef unless(ref $self eq __PACKAGE__);
|
1599
|
|
|
|
|
|
|
my $conf = shift || warn "No Conf";
|
1600
|
|
|
|
|
|
|
my $data = shift;
|
1601
|
|
|
|
|
|
|
|
1602
|
|
|
|
|
|
|
return unless( $self->cget(-wire) );
|
1603
|
|
|
|
|
|
|
|
1604
|
|
|
|
|
|
|
# 3D
|
1605
|
|
|
|
|
|
|
my $td = $self->cget(-threed) || 0;
|
1606
|
|
|
|
|
|
|
# XXX More as one linegraphs in deep
|
1607
|
|
|
|
|
|
|
# $td *= scalar keys %$data;
|
1608
|
|
|
|
|
|
|
|
1609
|
|
|
|
|
|
|
# Y-Achse
|
1610
|
|
|
|
|
|
|
my $ytick = ($conf->{type} eq 'HBARS' ? $conf->{count} : $self->cget(-ytick));
|
1611
|
|
|
|
|
|
|
$ytick = 1 unless $ytick;
|
1612
|
|
|
|
|
|
|
|
1613
|
|
|
|
|
|
|
for (my $i = 0; $i <= $ytick; $i++) {
|
1614
|
|
|
|
|
|
|
my $y = ($conf->{y_null}) - (round( ( $conf->{y_null} - $conf->{ypad_top} )/$ytick) * $i);
|
1615
|
|
|
|
|
|
|
$self->createLine(
|
1616
|
|
|
|
|
|
|
$conf->{x_null}, $y,
|
1617
|
|
|
|
|
|
|
($conf->{x_null} + $td), ($y - $td),
|
1618
|
|
|
|
|
|
|
($conf->{width} + $td), ($y - $td),
|
1619
|
|
|
|
|
|
|
-width => 1,
|
1620
|
|
|
|
|
|
|
-fill => ($i >= $ytick ? $self->cget(-foreground) : $self->cget(-wire)),
|
1621
|
|
|
|
|
|
|
);
|
1622
|
|
|
|
|
|
|
}
|
1623
|
|
|
|
|
|
|
|
1624
|
|
|
|
|
|
|
# X-Achse
|
1625
|
|
|
|
|
|
|
my $xtick = ( $conf->{typ} eq 'HASH' && $conf->{type} ne 'HBARS' && $conf->{type} ne 'LINE' ? $conf->{count} : $self->cget(-xtick) );
|
1626
|
|
|
|
|
|
|
$xtick = 1 unless $xtick;
|
1627
|
|
|
|
|
|
|
|
1628
|
|
|
|
|
|
|
if($conf->{type} eq 'HBARS' || $conf->{type} eq 'LINE') {
|
1629
|
|
|
|
|
|
|
for(my $i = 0; $i <= $xtick; $i++) {
|
1630
|
|
|
|
|
|
|
my $x = $conf->{x_null} + (round( ($conf->{width} - $conf->{x_null})/$self->cget(-xtick)) * $i);
|
1631
|
|
|
|
|
|
|
|
1632
|
|
|
|
|
|
|
$self->createLine(
|
1633
|
|
|
|
|
|
|
$x, $conf->{y_null}, ($x + $td),
|
1634
|
|
|
|
|
|
|
($conf->{y_null} - $td), ($x + $td),
|
1635
|
|
|
|
|
|
|
($conf->{ypad_top} - $td),
|
1636
|
|
|
|
|
|
|
-width => 1,
|
1637
|
|
|
|
|
|
|
-fill => ( $i >= $xtick ? $self->cget(-foreground) : $self->cget(-wire))
|
1638
|
|
|
|
|
|
|
);
|
1639
|
|
|
|
|
|
|
}
|
1640
|
|
|
|
|
|
|
} else {
|
1641
|
|
|
|
|
|
|
for(my $i = 0; $i <= $xtick; $i++) {
|
1642
|
|
|
|
|
|
|
my $x;
|
1643
|
|
|
|
|
|
|
if( $i < $xtick ) {
|
1644
|
|
|
|
|
|
|
$x = $self->calc_x($i+1);
|
1645
|
|
|
|
|
|
|
} else {
|
1646
|
|
|
|
|
|
|
$x = $conf->{width};
|
1647
|
|
|
|
|
|
|
}
|
1648
|
|
|
|
|
|
|
$self->createLine(
|
1649
|
|
|
|
|
|
|
$x, $conf->{y_null}, ($x + $td),
|
1650
|
|
|
|
|
|
|
($conf->{y_null} - $td), ($x + $td),
|
1651
|
|
|
|
|
|
|
($conf->{ypad_top} - $td),
|
1652
|
|
|
|
|
|
|
-width => 1,
|
1653
|
|
|
|
|
|
|
-fill => ( $i >= $xtick ? $self->cget(-foreground) : $self->cget(-wire))
|
1654
|
|
|
|
|
|
|
);
|
1655
|
|
|
|
|
|
|
}
|
1656
|
|
|
|
|
|
|
}
|
1657
|
|
|
|
|
|
|
}
|
1658
|
|
|
|
|
|
|
|
1659
|
|
|
|
|
|
|
#-------------------------------------------------
|
1660
|
|
|
|
|
|
|
sub config {
|
1661
|
|
|
|
|
|
|
#-------------------------------------------------
|
1662
|
|
|
|
|
|
|
my $self = shift || return error("No Objekt!");
|
1663
|
|
|
|
|
|
|
return undef unless(ref $self eq __PACKAGE__);
|
1664
|
|
|
|
|
|
|
my $data = shift || return;
|
1665
|
|
|
|
|
|
|
my $cols = $self->cget(-colors);
|
1666
|
|
|
|
|
|
|
my @colors = split(/,/, $cols);
|
1667
|
|
|
|
|
|
|
my $config = $self->cget(-config);
|
1668
|
|
|
|
|
|
|
my $c = -1;
|
1669
|
|
|
|
|
|
|
|
1670
|
|
|
|
|
|
|
foreach my $name( keys %$data) {
|
1671
|
|
|
|
|
|
|
next if(defined $self->{colors}->{$name} && ! defined $config->{$name});
|
1672
|
|
|
|
|
|
|
$c++;
|
1673
|
|
|
|
|
|
|
$c = -1 unless($colors[$c]);
|
1674
|
|
|
|
|
|
|
|
1675
|
|
|
|
|
|
|
my $name_new = $config->{$name}->{'-title'}
|
1676
|
|
|
|
|
|
|
if(defined $config->{$name}->{'-title'});
|
1677
|
|
|
|
|
|
|
|
1678
|
|
|
|
|
|
|
# Colors
|
1679
|
|
|
|
|
|
|
$self->{colors}->{($name_new || $name)} = $config->{$name}->{'-color'} || $colors[$c];
|
1680
|
|
|
|
|
|
|
|
1681
|
|
|
|
|
|
|
# Ranges
|
1682
|
|
|
|
|
|
|
if($config->{$name}->{'-range'}) {
|
1683
|
|
|
|
|
|
|
$self->{ranges}->{($name_new || $name)} = $config->{$name}->{'-range'};
|
1684
|
|
|
|
|
|
|
}
|
1685
|
|
|
|
|
|
|
|
1686
|
|
|
|
|
|
|
# Title
|
1687
|
|
|
|
|
|
|
if($config->{$name}->{'-title'}) {
|
1688
|
|
|
|
|
|
|
$data->{$config->{$name}->{'-title'}} = delete $data->{$name};
|
1689
|
|
|
|
|
|
|
$self->{data} = $data;
|
1690
|
|
|
|
|
|
|
}
|
1691
|
|
|
|
|
|
|
|
1692
|
|
|
|
|
|
|
}
|
1693
|
|
|
|
|
|
|
}
|
1694
|
|
|
|
|
|
|
|
1695
|
|
|
|
|
|
|
#-------------------------------------------------
|
1696
|
|
|
|
|
|
|
sub register {
|
1697
|
|
|
|
|
|
|
#-------------------------------------------------
|
1698
|
|
|
|
|
|
|
my $self = shift || return error("No Objekt!");
|
1699
|
|
|
|
|
|
|
return undef unless(ref $self eq __PACKAGE__);
|
1700
|
|
|
|
|
|
|
my $data = shift || return $self->{look};
|
1701
|
|
|
|
|
|
|
|
1702
|
|
|
|
|
|
|
foreach my $name (keys %$data) {
|
1703
|
|
|
|
|
|
|
$self->{look}->{$name} = $data->{$name};
|
1704
|
|
|
|
|
|
|
}
|
1705
|
|
|
|
|
|
|
}
|
1706
|
|
|
|
|
|
|
|
1707
|
|
|
|
|
|
|
|
1708
|
|
|
|
|
|
|
#-------------------------------------------------
|
1709
|
|
|
|
|
|
|
sub look {
|
1710
|
|
|
|
|
|
|
#-------------------------------------------------
|
1711
|
|
|
|
|
|
|
my $self = shift || return error("No Objekt!");
|
1712
|
|
|
|
|
|
|
return undef unless(ref $self eq __PACKAGE__);
|
1713
|
|
|
|
|
|
|
my $data = shift || $self->{data} || return;
|
1714
|
|
|
|
|
|
|
return unless($self->cget(-look));
|
1715
|
|
|
|
|
|
|
|
1716
|
|
|
|
|
|
|
foreach my $name (keys %$data) {
|
1717
|
|
|
|
|
|
|
push(@{$self->{look}->{$name}}, $data->{$name});
|
1718
|
|
|
|
|
|
|
splice(@{$self->{look}->{$name}}, 0, ($#{$self->{look}->{$name}} - $self->cget(-look)))
|
1719
|
|
|
|
|
|
|
if($#{$self->{look}->{$name}} >= $self->cget(-look));
|
1720
|
|
|
|
|
|
|
}
|
1721
|
|
|
|
|
|
|
}
|
1722
|
|
|
|
|
|
|
|
1723
|
|
|
|
|
|
|
#-------------------------------------------------
|
1724
|
|
|
|
|
|
|
sub sorter {
|
1725
|
|
|
|
|
|
|
#-------------------------------------------------
|
1726
|
|
|
|
|
|
|
my $self = shift || return error("No Objekt!");
|
1727
|
|
|
|
|
|
|
return undef unless(ref $self eq __PACKAGE__);
|
1728
|
|
|
|
|
|
|
my $typ = shift || $self->cget(-sortnames);
|
1729
|
|
|
|
|
|
|
|
1730
|
|
|
|
|
|
|
if($self->cget(-sortreverse)) {
|
1731
|
|
|
|
|
|
|
if($typ eq 'num') {
|
1732
|
|
|
|
|
|
|
$b <=> $a
|
1733
|
|
|
|
|
|
|
} else {
|
1734
|
|
|
|
|
|
|
$b cmp $a
|
1735
|
|
|
|
|
|
|
}
|
1736
|
|
|
|
|
|
|
} else {
|
1737
|
|
|
|
|
|
|
if($typ eq 'num') {
|
1738
|
|
|
|
|
|
|
$a <=> $b
|
1739
|
|
|
|
|
|
|
} else {
|
1740
|
|
|
|
|
|
|
$a cmp $b
|
1741
|
|
|
|
|
|
|
}
|
1742
|
|
|
|
|
|
|
}
|
1743
|
|
|
|
|
|
|
|
1744
|
|
|
|
|
|
|
}
|
1745
|
|
|
|
|
|
|
|
1746
|
|
|
|
|
|
|
#-------------------------------------------------
|
1747
|
|
|
|
|
|
|
sub balloon{
|
1748
|
|
|
|
|
|
|
#-------------------------------------------------
|
1749
|
|
|
|
|
|
|
my $self = shift || return error("No Objekt!");
|
1750
|
|
|
|
|
|
|
return; # XXX produce Memory Leaks
|
1751
|
|
|
|
|
|
|
|
1752
|
|
|
|
|
|
|
return undef unless(ref $self eq __PACKAGE__);
|
1753
|
|
|
|
|
|
|
my $elements = shift || return;
|
1754
|
|
|
|
|
|
|
my $werte = shift || return error('No Values');
|
1755
|
|
|
|
|
|
|
my $bh;
|
1756
|
|
|
|
|
|
|
|
1757
|
|
|
|
|
|
|
foreach my $name (keys %$werte) {
|
1758
|
|
|
|
|
|
|
my $wert = (ref $werte->{$name} eq 'ARRAY' ? $werte->{$name}->[$#{$werte->{$name}}] : $werte->{$name});
|
1759
|
|
|
|
|
|
|
$bh->{$elements->{$name}} =
|
1760
|
|
|
|
|
|
|
sprintf(
|
1761
|
|
|
|
|
|
|
$self->cget(-printvalue) || ($name && $wert ? '%s: %s' : '%s'), $name, $wert)
|
1762
|
|
|
|
|
|
|
if($wert);
|
1763
|
|
|
|
|
|
|
}
|
1764
|
|
|
|
|
|
|
|
1765
|
|
|
|
|
|
|
$self->{balloon}->attach(
|
1766
|
|
|
|
|
|
|
$self,
|
1767
|
|
|
|
|
|
|
-balloonposition => 'mouse',
|
1768
|
|
|
|
|
|
|
-msg => $bh,
|
1769
|
|
|
|
|
|
|
) if(defined $self->{balloon});
|
1770
|
|
|
|
|
|
|
}
|
1771
|
|
|
|
|
|
|
|
1772
|
|
|
|
|
|
|
#-------------------------------------------------
|
1773
|
|
|
|
|
|
|
sub round {
|
1774
|
|
|
|
|
|
|
#-------------------------------------------------
|
1775
|
|
|
|
|
|
|
my $wert = shift || return 0;
|
1776
|
|
|
|
|
|
|
my $ret = sprintf('%d', $wert);
|
1777
|
|
|
|
|
|
|
# my $ret = int( $wert + 0.99);
|
1778
|
|
|
|
|
|
|
return $ret;
|
1779
|
|
|
|
|
|
|
}
|
1780
|
|
|
|
|
|
|
|
1781
|
|
|
|
|
|
|
#-------------------------------------------------
|
1782
|
|
|
|
|
|
|
sub winkel {
|
1783
|
|
|
|
|
|
|
#-------------------------------------------------
|
1784
|
|
|
|
|
|
|
my $a = shift; # Width
|
1785
|
|
|
|
|
|
|
my $b = shift; # Heigth
|
1786
|
|
|
|
|
|
|
|
1787
|
|
|
|
|
|
|
my $c = sqrt($a**2+$b**2);
|
1788
|
|
|
|
|
|
|
|
1789
|
|
|
|
|
|
|
my $cos_phi = ($a**2+$c**2-$b**2) / (2*$a*$c);
|
1790
|
|
|
|
|
|
|
|
1791
|
|
|
|
|
|
|
return rad2deg(acos $cos_phi);
|
1792
|
|
|
|
|
|
|
}
|
1793
|
|
|
|
|
|
|
|
1794
|
|
|
|
|
|
|
|
1795
|
|
|
|
|
|
|
|
1796
|
|
|
|
|
|
|
#-------------------------------------------------
|
1797
|
|
|
|
|
|
|
sub error {
|
1798
|
|
|
|
|
|
|
#-------------------------------------------------
|
1799
|
|
|
|
|
|
|
my ($package, $filename, $line, $subroutine, $hasargs,
|
1800
|
|
|
|
|
|
|
$wantarray, $evaltext, $is_require, $hints, $bitmask) = caller(1);
|
1801
|
|
|
|
|
|
|
my $msg = shift || return undef;
|
1802
|
|
|
|
|
|
|
warn sprintf("ERROR in %s:%s #%d: %s",
|
1803
|
|
|
|
|
|
|
$package, $subroutine, $line, sprintf($msg, @_));
|
1804
|
|
|
|
|
|
|
return undef;
|
1805
|
|
|
|
|
|
|
}
|
1806
|
|
|
|
|
|
|
|
1807
|
|
|
|
|
|
|
#-------------------------------------------------
|
1808
|
|
|
|
|
|
|
sub debug {
|
1809
|
|
|
|
|
|
|
#-------------------------------------------------
|
1810
|
|
|
|
|
|
|
my $self = shift || return error("No Objekt!");
|
1811
|
|
|
|
|
|
|
return undef unless(ref $self eq __PACKAGE__);
|
1812
|
|
|
|
|
|
|
my $msg = shift || return;
|
1813
|
|
|
|
|
|
|
return unless($self->cget(-debug));
|
1814
|
|
|
|
|
|
|
printf($msg, @_);
|
1815
|
|
|
|
|
|
|
print "\n";
|
1816
|
|
|
|
|
|
|
}
|
1817
|
|
|
|
|
|
|
|
1818
|
|
|
|
|
|
|
#-------------------------------------------------
|
1819
|
|
|
|
|
|
|
sub val2name {
|
1820
|
|
|
|
|
|
|
#-------------------------------------------------
|
1821
|
|
|
|
|
|
|
my $hash = shift || return;
|
1822
|
|
|
|
|
|
|
my $val = shift || return;
|
1823
|
|
|
|
|
|
|
|
1824
|
|
|
|
|
|
|
foreach my $name (keys %$hash) {
|
1825
|
|
|
|
|
|
|
if($hash->{$name} eq $val) {
|
1826
|
|
|
|
|
|
|
return $name
|
1827
|
|
|
|
|
|
|
}
|
1828
|
|
|
|
|
|
|
}
|
1829
|
|
|
|
|
|
|
}
|
1830
|
|
|
|
|
|
|
|
1831
|
|
|
|
|
|
|
#-------------------------------------------------
|
1832
|
|
|
|
|
|
|
sub calc_x {
|
1833
|
|
|
|
|
|
|
#-------------------------------------------------
|
1834
|
|
|
|
|
|
|
my $self = shift || return error("No Objekt!");
|
1835
|
|
|
|
|
|
|
return undef unless(ref $self eq __PACKAGE__);
|
1836
|
|
|
|
|
|
|
my $fac = shift;
|
1837
|
|
|
|
|
|
|
my $conf = $self->{cfg};
|
1838
|
|
|
|
|
|
|
|
1839
|
|
|
|
|
|
|
my $count = ($conf->{type} eq 'BARS' ? $conf->{count} : $self->cget(-xtick) ) + 1;
|
1840
|
|
|
|
|
|
|
|
1841
|
|
|
|
|
|
|
|
1842
|
|
|
|
|
|
|
my $erg = $conf->{x_null} +
|
1843
|
|
|
|
|
|
|
(round
|
1844
|
|
|
|
|
|
|
(
|
1845
|
|
|
|
|
|
|
( $conf->{width} - $conf->{x_null} )
|
1846
|
|
|
|
|
|
|
/ $count
|
1847
|
|
|
|
|
|
|
) * $fac);
|
1848
|
|
|
|
|
|
|
$self->debug("CALC_X: Width: %d, Faktor = %d, Count: %d, Ergebniss = %d",
|
1849
|
|
|
|
|
|
|
$conf->{width}, $fac, $count, $erg);
|
1850
|
|
|
|
|
|
|
|
1851
|
|
|
|
|
|
|
return $erg;
|
1852
|
|
|
|
|
|
|
}
|
1853
|
|
|
|
|
|
|
|
1854
|
|
|
|
|
|
|
#-------------------------------------------------
|
1855
|
|
|
|
|
|
|
sub calc_y {
|
1856
|
|
|
|
|
|
|
#-------------------------------------------------
|
1857
|
|
|
|
|
|
|
my $self = shift || return error("No Objekt!");
|
1858
|
|
|
|
|
|
|
return undef unless(ref $self eq __PACKAGE__);
|
1859
|
|
|
|
|
|
|
my $fac = shift || 0;
|
1860
|
|
|
|
|
|
|
my $conf = $self->{cfg};
|
1861
|
|
|
|
|
|
|
|
1862
|
|
|
|
|
|
|
my $erg = $conf->{y_null} -
|
1863
|
|
|
|
|
|
|
round(
|
1864
|
|
|
|
|
|
|
(
|
1865
|
|
|
|
|
|
|
$conf->{y_null} -
|
1866
|
|
|
|
|
|
|
$conf->{ypad_top}
|
1867
|
|
|
|
|
|
|
) / $conf->{max_value}
|
1868
|
|
|
|
|
|
|
* $fac );
|
1869
|
|
|
|
|
|
|
|
1870
|
|
|
|
|
|
|
return $erg;
|
1871
|
|
|
|
|
|
|
}
|
1872
|
|
|
|
|
|
|
|
1873
|
|
|
|
|
|
|
|
1874
|
|
|
|
|
|
|
1;
|
1875
|
|
|
|
|
|
|
|
1876
|
|
|
|
|
|
|
=head1 EXAMPLES
|
1877
|
|
|
|
|
|
|
|
1878
|
|
|
|
|
|
|
Please see for examples in 'demos' directory in this distribution.
|
1879
|
|
|
|
|
|
|
|
1880
|
|
|
|
|
|
|
=head1 AUTHOR
|
1881
|
|
|
|
|
|
|
|
1882
|
|
|
|
|
|
|
Frank Herrmann
|
1883
|
|
|
|
|
|
|
xpix@netzwert.ag
|
1884
|
|
|
|
|
|
|
http://www.netzwert.ag
|
1885
|
|
|
|
|
|
|
|
1886
|
|
|
|
|
|
|
=head1 SEE ALSO
|
1887
|
|
|
|
|
|
|
|
1888
|
|
|
|
|
|
|
Tk,
|
1889
|
|
|
|
|
|
|
Tk::Trace,
|
1890
|
|
|
|
|
|
|
Tk::Canvas,
|
1891
|
|
|
|
|
|
|
|
1892
|
|
|
|
|
|
|
=cut
|
1893
|
|
|
|
|
|
|
|
1894
|
|
|
|
|
|
|
__END__
|