mooktakim-cloud-crowd 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- data/EPIGRAPHS +17 -0
- data/LICENSE +22 -0
- data/README +93 -0
- data/actions/graphics_magick.rb +43 -0
- data/actions/process_pdfs.rb +92 -0
- data/actions/word_count.rb +16 -0
- data/bin/crowd +5 -0
- data/config/config.example.ru +23 -0
- data/config/config.example.yml +55 -0
- data/config/database.example.yml +16 -0
- data/examples/graphics_magick_example.rb +44 -0
- data/examples/process_pdfs_example.rb +40 -0
- data/examples/word_count_example.rb +42 -0
- data/lib/cloud-crowd.rb +188 -0
- data/lib/cloud_crowd/action.rb +125 -0
- data/lib/cloud_crowd/asset_store/filesystem_store.rb +39 -0
- data/lib/cloud_crowd/asset_store/s3_store.rb +43 -0
- data/lib/cloud_crowd/asset_store.rb +41 -0
- data/lib/cloud_crowd/command_line.rb +242 -0
- data/lib/cloud_crowd/exceptions.rb +46 -0
- data/lib/cloud_crowd/helpers/authorization.rb +52 -0
- data/lib/cloud_crowd/helpers/resources.rb +25 -0
- data/lib/cloud_crowd/helpers.rb +8 -0
- data/lib/cloud_crowd/inflector.rb +19 -0
- data/lib/cloud_crowd/models/job.rb +190 -0
- data/lib/cloud_crowd/models/node_record.rb +107 -0
- data/lib/cloud_crowd/models/work_unit.rb +170 -0
- data/lib/cloud_crowd/models.rb +40 -0
- data/lib/cloud_crowd/node.rb +199 -0
- data/lib/cloud_crowd/schema.rb +50 -0
- data/lib/cloud_crowd/server.rb +123 -0
- data/lib/cloud_crowd/worker.rb +149 -0
- data/mooktakim-cloud-crowd.gemspec +116 -0
- data/public/css/admin_console.css +243 -0
- data/public/css/reset.css +42 -0
- data/public/images/bullet_green.png +0 -0
- data/public/images/bullet_white.png +0 -0
- data/public/images/cloud_hand.png +0 -0
- data/public/images/header_back.png +0 -0
- data/public/images/logo.png +0 -0
- data/public/images/queue_fill.png +0 -0
- data/public/images/server.png +0 -0
- data/public/images/server_busy.png +0 -0
- data/public/images/server_error.png +0 -0
- data/public/images/sidebar_bottom.png +0 -0
- data/public/images/sidebar_top.png +0 -0
- data/public/images/worker_info.png +0 -0
- data/public/images/worker_info_loading.gif +0 -0
- data/public/js/admin_console.js +197 -0
- data/public/js/excanvas.js +1 -0
- data/public/js/flot.js +1 -0
- data/public/js/jquery.js +19 -0
- data/test/acceptance/test_failing_work_units.rb +33 -0
- data/test/acceptance/test_node.rb +20 -0
- data/test/acceptance/test_server.rb +66 -0
- data/test/acceptance/test_word_count.rb +40 -0
- data/test/blueprints.rb +25 -0
- data/test/config/actions/failure_testing.rb +13 -0
- data/test/config/config.ru +17 -0
- data/test/config/config.yml +6 -0
- data/test/config/database.yml +3 -0
- data/test/test_helper.rb +19 -0
- data/test/unit/test_action.rb +70 -0
- data/test/unit/test_configuration.rb +48 -0
- data/test/unit/test_job.rb +103 -0
- data/test/unit/test_node.rb +41 -0
- data/test/unit/test_node_record.rb +42 -0
- data/test/unit/test_work_unit.rb +53 -0
- data/test/unit/test_worker.rb +48 -0
- data/views/operations_center.erb +82 -0
- metadata +290 -0
@@ -0,0 +1,243 @@
|
|
1
|
+
body {
|
2
|
+
background: #979797;
|
3
|
+
font-family: Arial;
|
4
|
+
font-size: 12px;
|
5
|
+
color: #252525;
|
6
|
+
}
|
7
|
+
|
8
|
+
.small_caps {
|
9
|
+
font: 11px Arial, sans-serif;
|
10
|
+
text-transform: uppercase;
|
11
|
+
}
|
12
|
+
|
13
|
+
#header {
|
14
|
+
height: 110px;
|
15
|
+
position: absolute;
|
16
|
+
top: 0; left: 0; right: 0;
|
17
|
+
background: url(../images/header_back.png);
|
18
|
+
}
|
19
|
+
#logo {
|
20
|
+
position: absolute;
|
21
|
+
left: 37px; top: 9px;
|
22
|
+
width: 236px; height: 91px;
|
23
|
+
background: url(../images/logo.png);
|
24
|
+
}
|
25
|
+
|
26
|
+
#disconnected {
|
27
|
+
position: absolute;
|
28
|
+
top: 122px; right: 15px;
|
29
|
+
background: #7f7f7f;
|
30
|
+
color: #333;
|
31
|
+
border: 1px solid #555;
|
32
|
+
font-size: 10px;
|
33
|
+
line-height: 18px;
|
34
|
+
padding: 3px 4px 1px 4px;
|
35
|
+
-moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px;
|
36
|
+
}
|
37
|
+
#disconnected .server_error {
|
38
|
+
float: left;
|
39
|
+
width: 16px; height: 16px;
|
40
|
+
background: url(../images/server_error.png);
|
41
|
+
opacity: 0.7;
|
42
|
+
margin-right: 3px;
|
43
|
+
}
|
44
|
+
|
45
|
+
#queue {
|
46
|
+
position: absolute;
|
47
|
+
top: 16px; left: 327px; right: 15px;
|
48
|
+
height: 77px;
|
49
|
+
overflow: hidden;
|
50
|
+
}
|
51
|
+
#no_jobs {
|
52
|
+
text-align: left;
|
53
|
+
position: absolute;
|
54
|
+
bottom: 8px; right: 8px;
|
55
|
+
color: #999;
|
56
|
+
display: none;
|
57
|
+
}
|
58
|
+
#queue.no_jobs #no_jobs {
|
59
|
+
display: block;
|
60
|
+
}
|
61
|
+
#queue_fill {
|
62
|
+
position: absolute;
|
63
|
+
left: 0; right: 0; top: 0;
|
64
|
+
height: 75px;
|
65
|
+
border: 1px solid #5c5c5c;
|
66
|
+
-moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius: 10px;
|
67
|
+
background: transparent url(../images/queue_fill.png) repeat-x 0px -1px;
|
68
|
+
}
|
69
|
+
#queue.no_jobs #queue_fill {
|
70
|
+
opacity: 0.3;
|
71
|
+
}
|
72
|
+
#queue .job {
|
73
|
+
position: relative;
|
74
|
+
margin-top: 1px;
|
75
|
+
height: 75px;
|
76
|
+
background: blue;
|
77
|
+
float: left;
|
78
|
+
overflow: hidden;
|
79
|
+
-moz-border-radius: 10px;
|
80
|
+
-webkit-border-radius: 10px;
|
81
|
+
}
|
82
|
+
#queue .completion {
|
83
|
+
position: absolute;
|
84
|
+
bottom: -1px;
|
85
|
+
height: 30px;
|
86
|
+
background: black;
|
87
|
+
border: 1px solid white;
|
88
|
+
-moz-border-radius: 10px; -webkit-border-radius: 10px;
|
89
|
+
opacity: 0.5;
|
90
|
+
overflow: hidden;
|
91
|
+
}
|
92
|
+
#queue .completion.zero {
|
93
|
+
border: 0;
|
94
|
+
}
|
95
|
+
#queue .percent_complete {
|
96
|
+
position: absolute;
|
97
|
+
bottom: 8px; left: 8px;
|
98
|
+
color: #c7c7c7;
|
99
|
+
z-index: 10;
|
100
|
+
}
|
101
|
+
#queue .job_id {
|
102
|
+
color: #333;
|
103
|
+
font-size: 14px;
|
104
|
+
position: absolute;
|
105
|
+
top: 8px; left: 8px;
|
106
|
+
z-index: 10;
|
107
|
+
}
|
108
|
+
|
109
|
+
#sidebar {
|
110
|
+
position: absolute;
|
111
|
+
top: 120px; left: 10px; bottom: 10px;
|
112
|
+
width: 300px;
|
113
|
+
overflow: hidden;
|
114
|
+
}
|
115
|
+
#sidebar_background {
|
116
|
+
position: absolute;
|
117
|
+
top: 21px; bottom: 21px;
|
118
|
+
width: 298px;
|
119
|
+
background: #e0e0e0;
|
120
|
+
border: 1px solid #8b8b8b;
|
121
|
+
border-top: 0; border-bottom: 0;
|
122
|
+
}
|
123
|
+
.sidebar_back {
|
124
|
+
position: absolute;
|
125
|
+
height: 21px; width: 300px;
|
126
|
+
}
|
127
|
+
#sidebar_top {
|
128
|
+
top: 0px;
|
129
|
+
background: url(../images/sidebar_top.png);
|
130
|
+
}
|
131
|
+
#sidebar_bottom {
|
132
|
+
bottom: 0px;
|
133
|
+
background: url(../images/sidebar_bottom.png);
|
134
|
+
}
|
135
|
+
#sidebar_header {
|
136
|
+
position: absolute;
|
137
|
+
width: 250px;
|
138
|
+
top: 5px; left: 8px;
|
139
|
+
color: #404040;
|
140
|
+
text-shadow: 0px 1px 1px #eee;
|
141
|
+
}
|
142
|
+
#sidebar_header.no_nodes .no_nodes,
|
143
|
+
#sidebar_header .has_nodes {
|
144
|
+
display: block;
|
145
|
+
}
|
146
|
+
#sidebar_header .no_nodes,
|
147
|
+
#sidebar_header.no_nodes .has_nodes {
|
148
|
+
display: none;
|
149
|
+
}
|
150
|
+
#nodes {
|
151
|
+
position: absolute;
|
152
|
+
padding: 2px 0;
|
153
|
+
top: 21px; left: 0; bottom: 21px;
|
154
|
+
width: 298px;
|
155
|
+
overflow-y: auto; overflow-x: hidden;
|
156
|
+
}
|
157
|
+
#nodes .node, #nodes .worker {
|
158
|
+
border: 1px solid transparent;
|
159
|
+
margin: 1px 7px;
|
160
|
+
padding-left: 18px;
|
161
|
+
background-position: left center;
|
162
|
+
background-repeat: no-repeat;
|
163
|
+
}
|
164
|
+
#nodes .node {
|
165
|
+
font-size: 11px;
|
166
|
+
line-height: 22px;
|
167
|
+
background-image: url(../images/server.png);
|
168
|
+
}
|
169
|
+
#nodes .node.busy {
|
170
|
+
background-image: url(../images/server_busy.png);
|
171
|
+
}
|
172
|
+
#nodes .node.busy span.busy {
|
173
|
+
font-size: 9px;
|
174
|
+
color: #7f7f7f;
|
175
|
+
text-transform: uppercase;
|
176
|
+
}
|
177
|
+
#nodes .worker {
|
178
|
+
font-size: 10px;
|
179
|
+
line-height: 18px;
|
180
|
+
cursor: pointer;
|
181
|
+
background-image: url(../images/bullet_green.png);
|
182
|
+
}
|
183
|
+
#nodes .worker:hover {
|
184
|
+
border: 1px solid #aaa;
|
185
|
+
border-radius: 4px; -moz-border-radius: 4px; -webkit-border-radius: 4px;
|
186
|
+
background-color: #ccc;
|
187
|
+
}
|
188
|
+
|
189
|
+
#worker_info {
|
190
|
+
position: absolute;
|
191
|
+
width: 231px; height: 79px;
|
192
|
+
margin: -9px 0 0 -20px;
|
193
|
+
background: url(../images/worker_info.png);
|
194
|
+
cursor: pointer;
|
195
|
+
}
|
196
|
+
#worker_info_inner {
|
197
|
+
margin: 15px 15px 15px 32px;
|
198
|
+
line-height: 15px;
|
199
|
+
color: #333;
|
200
|
+
text-shadow: 0px 1px 1px #eee;
|
201
|
+
overflow: hidden;
|
202
|
+
}
|
203
|
+
#worker_info.loading #worker_info_inner {
|
204
|
+
background: url(../images/worker_info_loading.gif) no-repeat right bottom;
|
205
|
+
width: 45px; height: 9px;
|
206
|
+
}
|
207
|
+
#worker_info.awake #worker_details,
|
208
|
+
#worker_sleeping {
|
209
|
+
display: block;
|
210
|
+
}
|
211
|
+
#worker_details, #worker_info.loading #worker_details,
|
212
|
+
#worker_info.loading #worker_sleeping, #worker_info.awake #worker_sleeping {
|
213
|
+
display: none;
|
214
|
+
}
|
215
|
+
|
216
|
+
#graphs {
|
217
|
+
position: absolute;
|
218
|
+
padding: 17px 15px 15px 17px;
|
219
|
+
top: 110px; left: 310px; right: 0px; bottom: 0;
|
220
|
+
overflow: hidden;
|
221
|
+
overflow-y: auto;
|
222
|
+
}
|
223
|
+
.graph_container {
|
224
|
+
margin-bottom: 25px;
|
225
|
+
}
|
226
|
+
.graph_title {
|
227
|
+
color: #333;
|
228
|
+
font-size: 16px;
|
229
|
+
text-shadow: 0px 1px 1px #eee;
|
230
|
+
margin-bottom: 10px;
|
231
|
+
}
|
232
|
+
.legend_box {
|
233
|
+
display: inline-block;
|
234
|
+
width: 10px; height: 10px;
|
235
|
+
border: 1px solid #bbb;
|
236
|
+
position: relative;
|
237
|
+
top: 1px;
|
238
|
+
margin: 0 1px;
|
239
|
+
background-color: #a1003d;
|
240
|
+
}
|
241
|
+
.graph {
|
242
|
+
height: 150px;
|
243
|
+
}
|
@@ -0,0 +1,42 @@
|
|
1
|
+
/*------------------------------ RESET + DEFAULT STYLES ---------------------------------*/
|
2
|
+
|
3
|
+
/*
|
4
|
+
Eric Meyer's final reset.css
|
5
|
+
Source: http://meyerweb.com/eric/thoughts/2007/05/01/reset-reloaded/
|
6
|
+
*/
|
7
|
+
html, body, div, span, applet, object, iframe,
|
8
|
+
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
9
|
+
a, abbr, acronym, address, big, cite, code,
|
10
|
+
del, dfn, em, font, img, ins, kbd, q, s, samp,
|
11
|
+
small, strike, strong, sub, sup, tt, var,
|
12
|
+
dl, dt, dd, ol, ul, li,
|
13
|
+
fieldset, form, label, legend {
|
14
|
+
margin: 0;
|
15
|
+
padding: 0;
|
16
|
+
border: 0;
|
17
|
+
outline: 0;
|
18
|
+
font-weight: inherit;
|
19
|
+
font-style: inherit;
|
20
|
+
font-size: 100%;
|
21
|
+
font-family: inherit;
|
22
|
+
vertical-align: baseline;
|
23
|
+
}
|
24
|
+
/* remember to define focus styles! */
|
25
|
+
:focus {
|
26
|
+
outline: 0;
|
27
|
+
}
|
28
|
+
body {
|
29
|
+
line-height: 1;
|
30
|
+
color: black;
|
31
|
+
background: white;
|
32
|
+
}
|
33
|
+
ol, ul {
|
34
|
+
list-style: none;
|
35
|
+
}
|
36
|
+
blockquote:before, blockquote:after,
|
37
|
+
q:before, q:after {
|
38
|
+
content: "";
|
39
|
+
}
|
40
|
+
blockquote, q {
|
41
|
+
quotes: "" "";
|
42
|
+
}
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,197 @@
|
|
1
|
+
// The Console handles all of the Admin interaction with the active workers
|
2
|
+
// and job queue.
|
3
|
+
//
|
4
|
+
// Think about pulling in the DCJS framework, instead of just raw jQuery here.
|
5
|
+
// Leaving it hacked together like this just cries out for templates, dunnit?
|
6
|
+
window.Console = {
|
7
|
+
|
8
|
+
// Maximum number of data points to record and graph.
|
9
|
+
MAX_DATA_POINTS : 100,
|
10
|
+
|
11
|
+
// Milliseconds between polling the central server for updates to Job progress.
|
12
|
+
POLL_INTERVAL : 3000,
|
13
|
+
|
14
|
+
// Default speed for all animations.
|
15
|
+
ANIMATION_SPEED : 300,
|
16
|
+
|
17
|
+
// Keep this in sync with the map in cloud-crowd.rb
|
18
|
+
DISPLAY_STATUS_MAP : ['unknown', 'processing', 'succeeded', 'failed', 'splitting', 'merging'],
|
19
|
+
|
20
|
+
// Images to preload
|
21
|
+
PRELOAD_IMAGES : ['images/server_error.png'],
|
22
|
+
|
23
|
+
// All options for drawing the system graphs.
|
24
|
+
GRAPH_OPTIONS : {
|
25
|
+
xaxis : {mode : 'time', timeformat : '%M:%S'},
|
26
|
+
yaxis : {tickDecimals : 0},
|
27
|
+
legend : {show : false},
|
28
|
+
grid : {backgroundColor : '#7f7f7f', color : '#555', tickColor : '#666', borderWidth : 2}
|
29
|
+
},
|
30
|
+
JOBS_COLOR : '#db3a0f',
|
31
|
+
NODES_COLOR : '#1870ab',
|
32
|
+
WORKERS_COLOR : '#45a4e5',
|
33
|
+
WORK_UNITS_COLOR : '#ffba14',
|
34
|
+
|
35
|
+
// Starting the console begins polling the server.
|
36
|
+
initialize : function() {
|
37
|
+
this._jobsHistory = [];
|
38
|
+
this._nodesHistory = [];
|
39
|
+
this._workersHistory = [];
|
40
|
+
this._workUnitsHistory = [];
|
41
|
+
this._histories = [this._jobsHistory, this._nodesHistory, this._workersHistory, this._workUnitsHistory];
|
42
|
+
this._queue = $('#jobs');
|
43
|
+
this._workerInfo = $('#worker_info');
|
44
|
+
this._disconnected = $('#disconnected');
|
45
|
+
$(window).bind('resize', Console.renderGraphs);
|
46
|
+
$('#nodes .worker').live('click', Console.getWorkerInfo);
|
47
|
+
$('#workers_legend').css({background : this.WORKERS_COLOR});
|
48
|
+
$('#nodes_legend').css({background : this.NODES_COLOR});
|
49
|
+
this.getStatus();
|
50
|
+
$.each(this.PRELOAD_IMAGES, function(){ var i = new Image(); i.src = this; });
|
51
|
+
},
|
52
|
+
|
53
|
+
// Request the lastest status of all jobs and workers, re-render or update
|
54
|
+
// the DOM to reflect.
|
55
|
+
getStatus : function() {
|
56
|
+
$.ajax({url : 'status', dataType : 'json', success : function(resp) {
|
57
|
+
Console._jobs = resp.jobs;
|
58
|
+
Console._nodes = resp.nodes;
|
59
|
+
Console._workUnitCount = resp.work_unit_count;
|
60
|
+
Console._workerCount = Console.countWorkers();
|
61
|
+
Console.recordDataPoint();
|
62
|
+
if (Console._disconnected.is(':visible')) Console._disconnected.fadeOut(Console.ANIMATION_SPEED);
|
63
|
+
$('#queue').toggleClass('no_jobs', Console._jobs.length <= 0);
|
64
|
+
Console.renderJobs();
|
65
|
+
Console.renderNodes();
|
66
|
+
Console.renderGraphs();
|
67
|
+
setTimeout(Console.getStatus, Console.POLL_INTERVAL);
|
68
|
+
}, error : function(request, status, errorThrown) {
|
69
|
+
if (!Console._disconnected.is(':visible')) Console._disconnected.fadeIn(Console.ANIMATION_SPEED);
|
70
|
+
setTimeout(Console.getStatus, Console.POLL_INTERVAL);
|
71
|
+
}});
|
72
|
+
},
|
73
|
+
|
74
|
+
// Count the total number of workers in the current list of nodes.
|
75
|
+
countWorkers : function() {
|
76
|
+
var sum = 0;
|
77
|
+
for (var i=0; i < this._nodes.length; i++) sum += this._nodes[i].workers.length;
|
78
|
+
return sum;
|
79
|
+
},
|
80
|
+
|
81
|
+
// Render an individual job afresh.
|
82
|
+
renderJob : function(job) {
|
83
|
+
this._queue.append('<div class="job" id="job_' + job.id + '" style="width:' + job.width + '%; background: #' + job.color + ';"><div class="completion ' + (job.percent_complete <= 0 ? 'zero' : '') + '" style="width:' + job.percent_complete + '%;"></div><div class="percent_complete">' + job.percent_complete + '%</div><div class="job_id">#' + job.id + '</div></div>');
|
84
|
+
},
|
85
|
+
|
86
|
+
// Animate the update to an existing job in the queue.
|
87
|
+
updateJob : function(job, jobEl) {
|
88
|
+
jobEl.animate({width : job.width + '%'}, this.ANIMATION_SPEED);
|
89
|
+
var completion = $('.completion', jobEl);
|
90
|
+
if (job.percent_complete > 0) completion.removeClass('zero');
|
91
|
+
completion.animate({width : job.percent_complete + '%'}, this.ANIMATION_SPEED);
|
92
|
+
$('.percent_complete', jobEl).html(job.percent_complete + '%');
|
93
|
+
},
|
94
|
+
|
95
|
+
// Render all jobs, calculating relative widths and completions.
|
96
|
+
renderJobs : function() {
|
97
|
+
var totalUnits = 0;
|
98
|
+
var totalWidth = this._queue.width();
|
99
|
+
var jobIds = [];
|
100
|
+
$.each(this._jobs, function() {
|
101
|
+
jobIds.push(this.id);
|
102
|
+
totalUnits += this.work_units;
|
103
|
+
});
|
104
|
+
$.each($('.job'), function() {
|
105
|
+
var el = this;
|
106
|
+
if (jobIds.indexOf(parseInt(el.id.replace(/\D/g, ''), 10)) < 0) {
|
107
|
+
$(el).animate({width : '0%'}, Console.ANIMATION_SPEED - 50, 'linear', function() {
|
108
|
+
$(el).remove();
|
109
|
+
});
|
110
|
+
}
|
111
|
+
});
|
112
|
+
$.each(this._jobs, function() {
|
113
|
+
this.width = (this.work_units / totalUnits) * 100;
|
114
|
+
var jobEl = $('#job_' + this.id);
|
115
|
+
jobEl[0] ? Console.updateJob(this, jobEl) : Console.renderJob(this);
|
116
|
+
});
|
117
|
+
},
|
118
|
+
|
119
|
+
// Re-render all workers from scratch each time.
|
120
|
+
// This method is desperately in need of Javascript templates...
|
121
|
+
renderNodes : function() {
|
122
|
+
var header = $('#sidebar_header');
|
123
|
+
var nc = this._nodes.length, wc = this._workerCount;
|
124
|
+
$('.has_nodes', header).html(nc + " Node" + (nc != 1 ? 's' : '') + " / " + wc + " Worker" + (wc != 1 ? 's' : ''));
|
125
|
+
header.toggleClass('no_nodes', this._nodes.length <= 0);
|
126
|
+
$('#nodes').html($.map(this._nodes, function(node) {
|
127
|
+
var html = "";
|
128
|
+
var extra = node.status == 'busy' ? ' <span class="busy">[busy]</span>' : '';
|
129
|
+
html += '<div class="node ' + node.status + '">' + node.host + extra + '</div>';
|
130
|
+
html += $.map(node.workers, function(pid) {
|
131
|
+
var name = pid + '@' + node.host;
|
132
|
+
return '<div class="worker" rel="' + name + '">' + name + '</div>';
|
133
|
+
}).join('');
|
134
|
+
return html;
|
135
|
+
}).join(''));
|
136
|
+
},
|
137
|
+
|
138
|
+
// Record the current state and re-render all graphs.
|
139
|
+
recordDataPoint : function() {
|
140
|
+
var timestamp = (new Date()).getTime();
|
141
|
+
this._jobsHistory.push([timestamp, this._jobs.length]);
|
142
|
+
this._nodesHistory.push([timestamp, this._nodes.length]);
|
143
|
+
this._workersHistory.push([timestamp, this._workerCount]);
|
144
|
+
this._workUnitsHistory.push([timestamp, this._workUnitCount]);
|
145
|
+
$.each(this._histories, function() {
|
146
|
+
if (this.length > Console.MAX_DATA_POINTS) this.shift();
|
147
|
+
});
|
148
|
+
},
|
149
|
+
|
150
|
+
// Convert our recorded data points into a format Flot can understand.
|
151
|
+
renderGraphs : function() {
|
152
|
+
$.plot($('#work_units_graph'), [
|
153
|
+
{label : 'Work Units in Queue', color : Console.WORK_UNITS_COLOR, data : Console._workUnitsHistory}
|
154
|
+
], Console.GRAPH_OPTIONS);
|
155
|
+
$.plot($('#jobs_graph'), [
|
156
|
+
{label : 'Jobs in Queue', color : Console.JOBS_COLOR, data : Console._jobsHistory}
|
157
|
+
], Console.GRAPH_OPTIONS);
|
158
|
+
$.plot($('#workers_graph'), [
|
159
|
+
{label : 'Nodes', color : Console.NODES_COLOR, data : Console._nodesHistory},
|
160
|
+
{label : 'Workers', color : Console.WORKERS_COLOR, data : Console._workersHistory}
|
161
|
+
], Console.GRAPH_OPTIONS);
|
162
|
+
},
|
163
|
+
|
164
|
+
// Request the Worker info from the central server.
|
165
|
+
getWorkerInfo : function(e) {
|
166
|
+
e.stopImmediatePropagation();
|
167
|
+
var info = Console._workerInfo;
|
168
|
+
var row = $(this);
|
169
|
+
info.addClass('loading');
|
170
|
+
$.get('worker/' + row.attr('rel'), null, Console.renderWorkerInfo, 'json');
|
171
|
+
info.css({top : row.offset().top, left : 325});
|
172
|
+
info.fadeIn(Console.ANIMATION_SPEED);
|
173
|
+
$(document).bind('click', Console.hideWorkerInfo);
|
174
|
+
return false;
|
175
|
+
},
|
176
|
+
|
177
|
+
// When we receieve worker info, update the bubble.
|
178
|
+
renderWorkerInfo : function(resp) {
|
179
|
+
var info = Console._workerInfo;
|
180
|
+
info.toggleClass('awake', !!resp.status);
|
181
|
+
info.removeClass('loading');
|
182
|
+
if (!resp.status) return;
|
183
|
+
$('.status', info).html(Console.DISPLAY_STATUS_MAP[resp.status]);
|
184
|
+
$('.action', info).html(resp.action);
|
185
|
+
$('.job_id', info).html(resp.job_id);
|
186
|
+
$('.work_unit_id', info).html(resp.id);
|
187
|
+
},
|
188
|
+
|
189
|
+
// Hide worker info and unbind the global hide handler.
|
190
|
+
hideWorkerInfo : function() {
|
191
|
+
$(document).unbind('click', Console.hideWorkerInfo);
|
192
|
+
Console._workerInfo.fadeOut(Console.ANIMATION_SPEED);
|
193
|
+
}
|
194
|
+
|
195
|
+
};
|
196
|
+
|
197
|
+
$(document).ready(function() { Console.initialize(); });
|
@@ -0,0 +1 @@
|
|
1
|
+
if(!window.CanvasRenderingContext2D){(function(){var m=Math;var mr=m.round;var ms=m.sin;var mc=m.cos;var Z=10;var Z2=Z/2;var G_vmlCanvasManager_={init:function(opt_doc){var doc=opt_doc||document;if(/MSIE/.test(navigator.userAgent)&&!window.opera){var self=this;doc.attachEvent("onreadystatechange",function(){self.init_(doc)})}},init_:function(doc){if(doc.readyState=="complete"){if(!doc.namespaces["g_vml_"]){doc.namespaces.add("g_vml_","urn:schemas-microsoft-com:vml")}var ss=doc.createStyleSheet();ss.cssText="canvas{display:inline-block;overflow:hidden;"+"text-align:left;width:300px;height:150px}"+"g_vml_\\:*{behavior:url(#default#VML)}";var els=doc.getElementsByTagName("canvas");for(var i=0;i<els.length;i++){if(!els[i].getContext){this.initElement(els[i])}}}},fixElement_:function(el){var outerHTML=el.outerHTML;var newEl=el.ownerDocument.createElement(outerHTML);if(outerHTML.slice(-2)!="/>"){var tagName="/"+el.tagName;var ns;while((ns=el.nextSibling)&&ns.tagName!=tagName){ns.removeNode()}if(ns){ns.removeNode()}}el.parentNode.replaceChild(newEl,el);return newEl},initElement:function(el){el=this.fixElement_(el);el.getContext=function(){if(this.context_){return this.context_}return this.context_=new CanvasRenderingContext2D_(this)};el.attachEvent('onpropertychange',onPropertyChange);el.attachEvent('onresize',onResize);var attrs=el.attributes;if(attrs.width&&attrs.width.specified){el.style.width=attrs.width.nodeValue+"px"}else{el.width=el.clientWidth}if(attrs.height&&attrs.height.specified){el.style.height=attrs.height.nodeValue+"px"}else{el.height=el.clientHeight}return el}};function onPropertyChange(e){var el=e.srcElement;switch(e.propertyName){case'width':el.style.width=el.attributes.width.nodeValue+"px";el.getContext().clearRect();break;case'height':el.style.height=el.attributes.height.nodeValue+"px";el.getContext().clearRect();break}}function onResize(e){var el=e.srcElement;if(el.firstChild){el.firstChild.style.width=el.clientWidth+'px';el.firstChild.style.height=el.clientHeight+'px'}}G_vmlCanvasManager_.init();var dec2hex=[];for(var i=0;i<16;i++){for(var j=0;j<16;j++){dec2hex[i*16+j]=i.toString(16)+j.toString(16)}}function createMatrixIdentity(){return[[1,0,0],[0,1,0],[0,0,1]]}function matrixMultiply(m1,m2){var result=createMatrixIdentity();for(var x=0;x<3;x++){for(var y=0;y<3;y++){var sum=0;for(var z=0;z<3;z++){sum+=m1[x][z]*m2[z][y]}result[x][y]=sum}}return result}function copyState(o1,o2){o2.fillStyle=o1.fillStyle;o2.lineCap=o1.lineCap;o2.lineJoin=o1.lineJoin;o2.lineWidth=o1.lineWidth;o2.miterLimit=o1.miterLimit;o2.shadowBlur=o1.shadowBlur;o2.shadowColor=o1.shadowColor;o2.shadowOffsetX=o1.shadowOffsetX;o2.shadowOffsetY=o1.shadowOffsetY;o2.strokeStyle=o1.strokeStyle;o2.arcScaleX_=o1.arcScaleX_;o2.arcScaleY_=o1.arcScaleY_}function processStyle(styleString){var str,alpha=1;styleString=String(styleString);if(styleString.substring(0,3)=="rgb"){var start=styleString.indexOf("(",3);var end=styleString.indexOf(")",start+1);var guts=styleString.substring(start+1,end).split(",");str="#";for(var i=0;i<3;i++){str+=dec2hex[Number(guts[i])]}if((guts.length==4)&&(styleString.substr(3,1)=="a")){alpha=guts[3]}}else{str=styleString}return[str,alpha]}function processLineCap(lineCap){switch(lineCap){case"butt":return"flat";case"round":return"round";case"square":default:return"square"}}function CanvasRenderingContext2D_(surfaceElement){this.m_=createMatrixIdentity();this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.strokeStyle="#000";this.fillStyle="#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=Z*1;this.globalAlpha=1;this.canvas=surfaceElement;var el=surfaceElement.ownerDocument.createElement('div');el.style.width=surfaceElement.clientWidth+'px';el.style.height=surfaceElement.clientHeight+'px';el.style.overflow='hidden';el.style.position='absolute';surfaceElement.appendChild(el);this.element_=el;this.arcScaleX_=1;this.arcScaleY_=1}var contextPrototype=CanvasRenderingContext2D_.prototype;contextPrototype.clearRect=function(){this.element_.innerHTML="";this.currentPath_=[]};contextPrototype.beginPath=function(){this.currentPath_=[]};contextPrototype.moveTo=function(aX,aY){this.currentPath_.push({type:"moveTo",x:aX,y:aY});this.currentX_=aX;this.currentY_=aY};contextPrototype.lineTo=function(aX,aY){this.currentPath_.push({type:"lineTo",x:aX,y:aY});this.currentX_=aX;this.currentY_=aY};contextPrototype.bezierCurveTo=function(aCP1x,aCP1y,aCP2x,aCP2y,aX,aY){this.currentPath_.push({type:"bezierCurveTo",cp1x:aCP1x,cp1y:aCP1y,cp2x:aCP2x,cp2y:aCP2y,x:aX,y:aY});this.currentX_=aX;this.currentY_=aY};contextPrototype.quadraticCurveTo=function(aCPx,aCPy,aX,aY){var cp1x=this.currentX_+2.0/3.0*(aCPx-this.currentX_);var cp1y=this.currentY_+2.0/3.0*(aCPy-this.currentY_);var cp2x=cp1x+(aX-this.currentX_)/3.0;var cp2y=cp1y+(aY-this.currentY_)/3.0;this.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,aX,aY)};contextPrototype.arc=function(aX,aY,aRadius,aStartAngle,aEndAngle,aClockwise){aRadius*=Z;var arcType=aClockwise?"at":"wa";var xStart=aX+(mc(aStartAngle)*aRadius)-Z2;var yStart=aY+(ms(aStartAngle)*aRadius)-Z2;var xEnd=aX+(mc(aEndAngle)*aRadius)-Z2;var yEnd=aY+(ms(aEndAngle)*aRadius)-Z2;if(xStart==xEnd&&!aClockwise){xStart+=0.125}this.currentPath_.push({type:arcType,x:aX,y:aY,radius:aRadius,xStart:xStart,yStart:yStart,xEnd:xEnd,yEnd:yEnd})};contextPrototype.rect=function(aX,aY,aWidth,aHeight){this.moveTo(aX,aY);this.lineTo(aX+aWidth,aY);this.lineTo(aX+aWidth,aY+aHeight);this.lineTo(aX,aY+aHeight);this.closePath()};contextPrototype.strokeRect=function(aX,aY,aWidth,aHeight){this.beginPath();this.moveTo(aX,aY);this.lineTo(aX+aWidth,aY);this.lineTo(aX+aWidth,aY+aHeight);this.lineTo(aX,aY+aHeight);this.closePath();this.stroke()};contextPrototype.fillRect=function(aX,aY,aWidth,aHeight){this.beginPath();this.moveTo(aX,aY);this.lineTo(aX+aWidth,aY);this.lineTo(aX+aWidth,aY+aHeight);this.lineTo(aX,aY+aHeight);this.closePath();this.fill()};contextPrototype.createLinearGradient=function(aX0,aY0,aX1,aY1){var gradient=new CanvasGradient_("gradient");return gradient};contextPrototype.createRadialGradient=function(aX0,aY0,aR0,aX1,aY1,aR1){var gradient=new CanvasGradient_("gradientradial");gradient.radius1_=aR0;gradient.radius2_=aR1;gradient.focus_.x=aX0;gradient.focus_.y=aY0;return gradient};contextPrototype.drawImage=function(image,var_args){var dx,dy,dw,dh,sx,sy,sw,sh;var oldRuntimeWidth=image.runtimeStyle.width;var oldRuntimeHeight=image.runtimeStyle.height;image.runtimeStyle.width='auto';image.runtimeStyle.height='auto';var w=image.width;var h=image.height;image.runtimeStyle.width=oldRuntimeWidth;image.runtimeStyle.height=oldRuntimeHeight;if(arguments.length==3){dx=arguments[1];dy=arguments[2];sx=sy=0;sw=dw=w;sh=dh=h}else if(arguments.length==5){dx=arguments[1];dy=arguments[2];dw=arguments[3];dh=arguments[4];sx=sy=0;sw=w;sh=h}else if(arguments.length==9){sx=arguments[1];sy=arguments[2];sw=arguments[3];sh=arguments[4];dx=arguments[5];dy=arguments[6];dw=arguments[7];dh=arguments[8]}else{throw"Invalid number of arguments";}var d=this.getCoords_(dx,dy);var w2=sw/2;var h2=sh/2;var vmlStr=[];var W=10;var H=10;vmlStr.push(' <g_vml_:group',' coordsize="',Z*W,',',Z*H,'"',' coordorigin="0,0"',' style="width:',W,';height:',H,';position:absolute;');if(this.m_[0][0]!=1||this.m_[0][1]){var filter=[];filter.push("M11='",this.m_[0][0],"',","M12='",this.m_[1][0],"',","M21='",this.m_[0][1],"',","M22='",this.m_[1][1],"',","Dx='",mr(d.x/Z),"',","Dy='",mr(d.y/Z),"'");var max=d;var c2=this.getCoords_(dx+dw,dy);var c3=this.getCoords_(dx,dy+dh);var c4=this.getCoords_(dx+dw,dy+dh);max.x=Math.max(max.x,c2.x,c3.x,c4.x);max.y=Math.max(max.y,c2.y,c3.y,c4.y);vmlStr.push("padding:0 ",mr(max.x/Z),"px ",mr(max.y/Z),"px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",filter.join(""),", sizingmethod='clip');")}else{vmlStr.push("top:",mr(d.y/Z),"px;left:",mr(d.x/Z),"px;")}vmlStr.push(' ">','<g_vml_:image src="',image.src,'"',' style="width:',Z*dw,';',' height:',Z*dh,';"',' cropleft="',sx/w,'"',' croptop="',sy/h,'"',' cropright="',(w-sx-sw)/w,'"',' cropbottom="',(h-sy-sh)/h,'"',' />','</g_vml_:group>');this.element_.insertAdjacentHTML("BeforeEnd",vmlStr.join(""))};contextPrototype.stroke=function(aFill){var lineStr=[];var lineOpen=false;var a=processStyle(aFill?this.fillStyle:this.strokeStyle);var color=a[0];var opacity=a[1]*this.globalAlpha;var W=10;var H=10;lineStr.push('<g_vml_:shape',' fillcolor="',color,'"',' filled="',Boolean(aFill),'"',' style="position:absolute;width:',W,';height:',H,';"',' coordorigin="0 0" coordsize="',Z*W,' ',Z*H,'"',' stroked="',!aFill,'"',' strokeweight="',this.lineWidth,'"',' strokecolor="',color,'"',' path="');var newSeq=false;var min={x:null,y:null};var max={x:null,y:null};for(var i=0;i<this.currentPath_.length;i++){var p=this.currentPath_[i];if(p.type=="moveTo"){lineStr.push(" m ");var c=this.getCoords_(p.x,p.y);lineStr.push(mr(c.x),",",mr(c.y))}else if(p.type=="lineTo"){lineStr.push(" l ");var c=this.getCoords_(p.x,p.y);lineStr.push(mr(c.x),",",mr(c.y))}else if(p.type=="close"){lineStr.push(" x ")}else if(p.type=="bezierCurveTo"){lineStr.push(" c ");var c=this.getCoords_(p.x,p.y);var c1=this.getCoords_(p.cp1x,p.cp1y);var c2=this.getCoords_(p.cp2x,p.cp2y);lineStr.push(mr(c1.x),",",mr(c1.y),",",mr(c2.x),",",mr(c2.y),",",mr(c.x),",",mr(c.y))}else if(p.type=="at"||p.type=="wa"){lineStr.push(" ",p.type," ");var c=this.getCoords_(p.x,p.y);var cStart=this.getCoords_(p.xStart,p.yStart);var cEnd=this.getCoords_(p.xEnd,p.yEnd);lineStr.push(mr(c.x-this.arcScaleX_*p.radius),",",mr(c.y-this.arcScaleY_*p.radius)," ",mr(c.x+this.arcScaleX_*p.radius),",",mr(c.y+this.arcScaleY_*p.radius)," ",mr(cStart.x),",",mr(cStart.y)," ",mr(cEnd.x),",",mr(cEnd.y))}if(c){if(min.x==null||c.x<min.x){min.x=c.x}if(max.x==null||c.x>max.x){max.x=c.x}if(min.y==null||c.y<min.y){min.y=c.y}if(max.y==null||c.y>max.y){max.y=c.y}}}lineStr.push(' ">');if(typeof this.fillStyle=="object"){var focus={x:"50%",y:"50%"};var width=(max.x-min.x);var height=(max.y-min.y);var dimension=(width>height)?width:height;focus.x=mr((this.fillStyle.focus_.x/width)*100+50)+"%";focus.y=mr((this.fillStyle.focus_.y/height)*100+50)+"%";var colors=[];if(this.fillStyle.type_=="gradientradial"){var inside=(this.fillStyle.radius1_/dimension*100);var expansion=(this.fillStyle.radius2_/dimension*100)-inside}else{var inside=0;var expansion=100}var insidecolor={offset:null,color:null};var outsidecolor={offset:null,color:null};this.fillStyle.colors_.sort(function(cs1,cs2){return cs1.offset-cs2.offset});for(var i=0;i<this.fillStyle.colors_.length;i++){var fs=this.fillStyle.colors_[i];colors.push((fs.offset*expansion)+inside,"% ",fs.color,",");if(fs.offset>insidecolor.offset||insidecolor.offset==null){insidecolor.offset=fs.offset;insidecolor.color=fs.color}if(fs.offset<outsidecolor.offset||outsidecolor.offset==null){outsidecolor.offset=fs.offset;outsidecolor.color=fs.color}}colors.pop();lineStr.push('<g_vml_:fill',' color="',outsidecolor.color,'"',' color2="',insidecolor.color,'"',' type="',this.fillStyle.type_,'"',' focusposition="',focus.x,', ',focus.y,'"',' colors="',colors.join(""),'"',' opacity="',opacity,'" />')}else if(aFill){lineStr.push('<g_vml_:fill color="',color,'" opacity="',opacity,'" />')}else{lineStr.push('<g_vml_:stroke',' opacity="',opacity,'"',' joinstyle="',this.lineJoin,'"',' miterlimit="',this.miterLimit,'"',' endcap="',processLineCap(this.lineCap),'"',' weight="',this.lineWidth,'px"',' color="',color,'" />')}lineStr.push("</g_vml_:shape>");this.element_.insertAdjacentHTML("beforeEnd",lineStr.join(""))};contextPrototype.fill=function(){this.stroke(true)};contextPrototype.closePath=function(){this.currentPath_.push({type:"close"})};contextPrototype.getCoords_=function(aX,aY){return{x:Z*(aX*this.m_[0][0]+aY*this.m_[1][0]+this.m_[2][0])-Z2,y:Z*(aX*this.m_[0][1]+aY*this.m_[1][1]+this.m_[2][1])-Z2}};contextPrototype.save=function(){var o={};copyState(this,o);this.aStack_.push(o);this.mStack_.push(this.m_);this.m_=matrixMultiply(createMatrixIdentity(),this.m_)};contextPrototype.restore=function(){copyState(this.aStack_.pop(),this);this.m_=this.mStack_.pop()};contextPrototype.translate=function(aX,aY){var m1=[[1,0,0],[0,1,0],[aX,aY,1]];this.m_=matrixMultiply(m1,this.m_)};contextPrototype.rotate=function(aRot){var c=mc(aRot);var s=ms(aRot);var m1=[[c,s,0],[-s,c,0],[0,0,1]];this.m_=matrixMultiply(m1,this.m_)};contextPrototype.scale=function(aX,aY){this.arcScaleX_*=aX;this.arcScaleY_*=aY;var m1=[[aX,0,0],[0,aY,0],[0,0,1]];this.m_=matrixMultiply(m1,this.m_)};contextPrototype.clip=function(){};contextPrototype.arcTo=function(){};contextPrototype.createPattern=function(){return new CanvasPattern_};function CanvasGradient_(aType){this.type_=aType;this.radius1_=0;this.radius2_=0;this.colors_=[];this.focus_={x:0,y:0}}CanvasGradient_.prototype.addColorStop=function(aOffset,aColor){aColor=processStyle(aColor);this.colors_.push({offset:1-aOffset,color:aColor})};function CanvasPattern_(){}G_vmlCanvasManager=G_vmlCanvasManager_;CanvasRenderingContext2D=CanvasRenderingContext2D_;CanvasGradient=CanvasGradient_;CanvasPattern=CanvasPattern_})()}
|
data/public/js/flot.js
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
(function(F){function D(AO,e,f){var W=[],o={colors:["#edc240","#afd8f8","#cb4b4b","#4da74d","#9440ed"],legend:{show:true,noColumns:1,labelFormatter:null,labelBoxBorderColor:"#ccc",container:null,position:"ne",margin:5,backgroundColor:null,backgroundOpacity:0.85},xaxis:{mode:null,min:null,max:null,autoscaleMargin:null,ticks:null,tickFormatter:null,labelWidth:null,labelHeight:null,tickDecimals:null,tickSize:null,minTickSize:null,monthNames:null,timeformat:null},yaxis:{autoscaleMargin:0.02},x2axis:{autoscaleMargin:null},y2axis:{autoscaleMargin:0.02},points:{show:false,radius:3,lineWidth:2,fill:true,fillColor:"#ffffff"},lines:{show:false,lineWidth:2,fill:false,fillColor:null},bars:{show:false,lineWidth:2,barWidth:1,fill:true,fillColor:null,align:"left"},grid:{color:"#545454",backgroundColor:null,tickColor:"#dddddd",labelMargin:5,borderWidth:2,markings:null,markingsColor:"#f4f4f4",markingsLineWidth:2,clickable:false,hoverable:false,autoHighlight:true,mouseActiveRadius:10},selection:{mode:null,color:"#e8cfac"},shadowSize:4},X=null,AP=null,AQ=null,g=null,AX=null,K=AO,AA={xaxis:{},yaxis:{},x2axis:{},y2axis:{}},m={left:0,right:0,top:0,bottom:0},AI=0,Z=0,N=0,AB=0,S={};this.setData=n;this.setupGrid=s;this.draw=AU;this.clearSelection=I;this.setSelection=AC;this.getCanvas=function(){return X};this.getPlotOffset=function(){return m};this.getData=function(){return W};this.getAxes=function(){return AA};this.highlight=AS;this.unhighlight=AH;y(f);n(e);j();s();AU();function n(AY){W=U(AY);c();t()}function U(Ac){var Aa=[];for(var AZ=0;AZ<Ac.length;++AZ){var Ab;if(Ac[AZ].data){Ab={};for(var AY in Ac[AZ]){Ab[AY]=Ac[AZ][AY]}}else{Ab={data:Ac[AZ]}}Aa.push(Ab)}return Aa}function y(AY){F.extend(true,o,AY);if(o.xaxis.noTicks&&o.xaxis.ticks==null){o.xaxis.ticks=o.xaxis.noTicks}if(o.yaxis.noTicks&&o.yaxis.ticks==null){o.yaxis.ticks=o.yaxis.noTicks}if(o.grid.coloredAreas){o.grid.markings=o.grid.coloredAreas}if(o.grid.coloredAreasColor){o.grid.markingsColor=o.grid.coloredAreasColor}}function c(){var Ad;var Ai=W.length,AY=[],Ab=[];for(Ad=0;Ad<W.length;++Ad){var Ah=W[Ad].color;if(Ah!=null){--Ai;if(typeof Ah=="number"){Ab.push(Ah)}else{AY.push(E(W[Ad].color))}}}for(Ad=0;Ad<Ab.length;++Ad){Ai=Math.max(Ai,Ab[Ad]+1)}var AZ=[],Ac=0;Ad=0;while(AZ.length<Ai){var Ag;if(o.colors.length==Ad){Ag=new G(100,100,100)}else{Ag=E(o.colors[Ad])}var Aa=Ac%2==1?-1:1;var Af=1+Aa*Math.ceil(Ac/2)*0.2;Ag.scale(Af,Af,Af);AZ.push(Ag);++Ad;if(Ad>=o.colors.length){Ad=0;++Ac}}var Ae=0,Aj;for(Ad=0;Ad<W.length;++Ad){Aj=W[Ad];if(Aj.color==null){Aj.color=AZ[Ae].toString();++Ae}else{if(typeof Aj.color=="number"){Aj.color=AZ[Aj.color].toString()}}Aj.lines=F.extend(true,{},o.lines,Aj.lines);Aj.points=F.extend(true,{},o.points,Aj.points);Aj.bars=F.extend(true,{},o.bars,Aj.bars);if(Aj.shadowSize==null){Aj.shadowSize=o.shadowSize}if(Aj.xaxis&&Aj.xaxis==2){Aj.xaxis=AA.x2axis}else{Aj.xaxis=AA.xaxis}if(Aj.yaxis&&Aj.yaxis==2){Aj.yaxis=AA.y2axis}else{Aj.yaxis=AA.yaxis}}}function t(){var Aa=Number.POSITIVE_INFINITY,AZ=Number.NEGATIVE_INFINITY,Ab;for(Ab in AA){AA[Ab].datamin=Aa;AA[Ab].datamax=AZ;AA[Ab].used=false}for(var Ae=0;Ae<W.length;++Ae){var Ad=W[Ae].data,Aj=W[Ae].xaxis,Ai=W[Ae].yaxis,AY=0,Ah=0;if(W[Ae].bars.show){AY=W[Ae].bars.align=="left"?0:-W[Ae].bars.barWidth/2;Ah=AY+W[Ae].bars.barWidth}Aj.used=Ai.used=true;for(var Ac=0;Ac<Ad.length;++Ac){if(Ad[Ac]==null){continue}var Ag=Ad[Ac][0],Af=Ad[Ac][1];if(Ag!=null&&!isNaN(Ag=+Ag)){if(Ag+AY<Aj.datamin){Aj.datamin=Ag+AY}if(Ag+Ah>Aj.datamax){Aj.datamax=Ag+Ah}}if(Af!=null&&!isNaN(Af=+Af)){if(Af<Ai.datamin){Ai.datamin=Af}if(Af>Ai.datamax){Ai.datamax=Af}}if(Ag==null||Af==null||isNaN(Ag)||isNaN(Af)){Ad[Ac]=null}}}for(Ab in AA){if(AA[Ab].datamin==Aa){AA[Ab].datamin=0}if(AA[Ab].datamax==AZ){AA[Ab].datamax=1}}}function j(){AI=K.width();Z=K.height();K.html("");K.css("position","relative");if(AI<=0||Z<=0){throw"Invalid dimensions for plot, width = "+AI+", height = "+Z}X=F('<canvas width="'+AI+'" height="'+Z+'"></canvas>').appendTo(K).get(0);if(F.browser.msie){X=window.G_vmlCanvasManager.initElement(X)}g=X.getContext("2d");AP=F('<canvas style="position:absolute;left:0px;top:0px;" width="'+AI+'" height="'+Z+'"></canvas>').appendTo(K).get(0);if(F.browser.msie){AP=window.G_vmlCanvasManager.initElement(AP)}AX=AP.getContext("2d");AQ=F([AP,X]);if(o.selection.mode!=null||o.grid.hoverable){AQ.each(function(){this.onmousemove=J});if(o.selection.mode!=null){AQ.mousedown(AN)}}if(o.grid.clickable){AQ.click(k)}}function s(){function AY(Ab,Aa){Q(Ab,Aa);L(Ab,Aa);w(Ab,Aa);if(Ab==AA.xaxis||Ab==AA.x2axis){Ab.p2c=function(Ac){return(Ac-Ab.min)*Ab.scale};Ab.c2p=function(Ac){return Ab.min+Ac/Ab.scale}}else{Ab.p2c=function(Ac){return(Ab.max-Ac)*Ab.scale};Ab.c2p=function(Ac){return Ab.max-Ac/Ab.scale}}}for(var AZ in AA){AY(AA[AZ],o[AZ])}AW();p();AV()}function Q(Ab,Ad){var Aa=Ad.min!=null?Ad.min:Ab.datamin;var AY=Ad.max!=null?Ad.max:Ab.datamax;if(AY-Aa==0){var AZ;if(AY==0){AZ=1}else{AZ=0.01}Aa-=AZ;AY+=AZ}else{var Ac=Ad.autoscaleMargin;if(Ac!=null){if(Ad.min==null){Aa-=(AY-Aa)*Ac;if(Aa<0&&Ab.datamin>=0){Aa=0}}if(Ad.max==null){AY+=(AY-Aa)*Ac;if(AY>0&&Ab.datamax<=0){AY=0}}}}Ab.min=Aa;Ab.max=AY}function L(Ad,Ag){var Ac;if(typeof Ag.ticks=="number"&&Ag.ticks>0){Ac=Ag.ticks}else{if(Ad==AA.xaxis||Ad==AA.x2axis){Ac=AI/100}else{Ac=Z/60}}var Al=(Ad.max-Ad.min)/Ac;var Ao,Ah,Aj,Ak,Af,Aa,AZ;if(Ag.mode=="time"){function An(Av,Ap,Ar){var Aq=function(Ax){Ax=""+Ax;return Ax.length==1?"0"+Ax:Ax};var Au=[];var At=false;if(Ar==null){Ar=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]}for(var As=0;As<Ap.length;++As){var Aw=Ap.charAt(As);if(At){switch(Aw){case"h":Aw=""+Av.getUTCHours();break;case"H":Aw=Aq(Av.getUTCHours());break;case"M":Aw=Aq(Av.getUTCMinutes());break;case"S":Aw=Aq(Av.getUTCSeconds());break;case"d":Aw=""+Av.getUTCDate();break;case"m":Aw=""+(Av.getUTCMonth()+1);break;case"y":Aw=""+Av.getUTCFullYear();break;case"b":Aw=""+Ar[Av.getUTCMonth()];break}Au.push(Aw);At=false}else{if(Aw=="%"){At=true}else{Au.push(Aw)}}}return Au.join("")}var Ai={second:1000,minute:60*1000,hour:60*60*1000,day:24*60*60*1000,month:30*24*60*60*1000,year:365.2425*24*60*60*1000};var Am=[[1,"second"],[2,"second"],[5,"second"],[10,"second"],[30,"second"],[1,"minute"],[2,"minute"],[5,"minute"],[10,"minute"],[30,"minute"],[1,"hour"],[2,"hour"],[4,"hour"],[8,"hour"],[12,"hour"],[1,"day"],[2,"day"],[3,"day"],[0.25,"month"],[0.5,"month"],[1,"month"],[2,"month"],[3,"month"],[6,"month"],[1,"year"]];var Ab=0;if(Ag.minTickSize!=null){if(typeof Ag.tickSize=="number"){Ab=Ag.tickSize}else{Ab=Ag.minTickSize[0]*Ai[Ag.minTickSize[1]]}}for(Af=0;Af<Am.length-1;++Af){if(Al<(Am[Af][0]*Ai[Am[Af][1]]+Am[Af+1][0]*Ai[Am[Af+1][1]])/2&&Am[Af][0]*Ai[Am[Af][1]]>=Ab){break}}Ao=Am[Af][0];Aj=Am[Af][1];if(Aj=="year"){Aa=Math.pow(10,Math.floor(Math.log(Al/Ai.year)/Math.LN10));AZ=(Al/Ai.year)/Aa;if(AZ<1.5){Ao=1}else{if(AZ<3){Ao=2}else{if(AZ<7.5){Ao=5}else{Ao=10}}}Ao*=Aa}if(Ag.tickSize){Ao=Ag.tickSize[0];Aj=Ag.tickSize[1]}Ah=function(Ar){var Aw=[],Au=Ar.tickSize[0],Ax=Ar.tickSize[1],Av=new Date(Ar.min);var Aq=Au*Ai[Ax];if(Ax=="second"){Av.setUTCSeconds(C(Av.getUTCSeconds(),Au))}if(Ax=="minute"){Av.setUTCMinutes(C(Av.getUTCMinutes(),Au))}if(Ax=="hour"){Av.setUTCHours(C(Av.getUTCHours(),Au))}if(Ax=="month"){Av.setUTCMonth(C(Av.getUTCMonth(),Au))}if(Ax=="year"){Av.setUTCFullYear(C(Av.getUTCFullYear(),Au))}Av.setUTCMilliseconds(0);if(Aq>=Ai.minute){Av.setUTCSeconds(0)}if(Aq>=Ai.hour){Av.setUTCMinutes(0)}if(Aq>=Ai.day){Av.setUTCHours(0)}if(Aq>=Ai.day*4){Av.setUTCDate(1)}if(Aq>=Ai.year){Av.setUTCMonth(0)}var Az=0,Ay=Number.NaN,As;do{As=Ay;Ay=Av.getTime();Aw.push({v:Ay,label:Ar.tickFormatter(Ay,Ar)});if(Ax=="month"){if(Au<1){Av.setUTCDate(1);var Ap=Av.getTime();Av.setUTCMonth(Av.getUTCMonth()+1);var At=Av.getTime();Av.setTime(Ay+Az*Ai.hour+(At-Ap)*Au);Az=Av.getUTCHours();Av.setUTCHours(0)}else{Av.setUTCMonth(Av.getUTCMonth()+Au)}}else{if(Ax=="year"){Av.setUTCFullYear(Av.getUTCFullYear()+Au)}else{Av.setTime(Ay+Aq)}}}while(Ay<Ar.max&&Ay!=As);return Aw};Ak=function(Ap,As){var At=new Date(Ap);if(Ag.timeformat!=null){return An(At,Ag.timeformat,Ag.monthNames)}var Aq=As.tickSize[0]*Ai[As.tickSize[1]];var Ar=As.max-As.min;if(Aq<Ai.minute){fmt="%h:%M:%S"}else{if(Aq<Ai.day){if(Ar<2*Ai.day){fmt="%h:%M"}else{fmt="%b %d %h:%M"}}else{if(Aq<Ai.month){fmt="%b %d"}else{if(Aq<Ai.year){if(Ar<Ai.year){fmt="%b"}else{fmt="%b %y"}}else{fmt="%y"}}}}return An(At,fmt,Ag.monthNames)}}else{var AY=Ag.tickDecimals;var Ae=-Math.floor(Math.log(Al)/Math.LN10);if(AY!=null&&Ae>AY){Ae=AY}Aa=Math.pow(10,-Ae);AZ=Al/Aa;if(AZ<1.5){Ao=1}else{if(AZ<3){Ao=2;if(AZ>2.25&&(AY==null||Ae+1<=AY)){Ao=2.5;++Ae}}else{if(AZ<7.5){Ao=5}else{Ao=10}}}Ao*=Aa;if(Ag.minTickSize!=null&&Ao<Ag.minTickSize){Ao=Ag.minTickSize}if(Ag.tickSize!=null){Ao=Ag.tickSize}Ad.tickDecimals=Math.max(0,(AY!=null)?AY:Ae);Ah=function(Ar){var At=[];var Au=C(Ar.min,Ar.tickSize),Aq=0,Ap=Number.NaN,As;do{As=Ap;Ap=Au+Aq*Ar.tickSize;At.push({v:Ap,label:Ar.tickFormatter(Ap,Ar)});++Aq}while(Ap<Ar.max&&Ap!=As);return At};Ak=function(Ap,Aq){return Ap.toFixed(Aq.tickDecimals)}}Ad.tickSize=Aj?[Ao,Aj]:Ao;Ad.tickGenerator=Ah;if(F.isFunction(Ag.tickFormatter)){Ad.tickFormatter=function(Ap,Aq){return""+Ag.tickFormatter(Ap,Aq)}}else{Ad.tickFormatter=Ak}if(Ag.labelWidth!=null){Ad.labelWidth=Ag.labelWidth}if(Ag.labelHeight!=null){Ad.labelHeight=Ag.labelHeight}}function w(Ac,Ae){Ac.ticks=[];if(!Ac.used){return }if(Ae.ticks==null){Ac.ticks=Ac.tickGenerator(Ac)}else{if(typeof Ae.ticks=="number"){if(Ae.ticks>0){Ac.ticks=Ac.tickGenerator(Ac)}}else{if(Ae.ticks){var Ad=Ae.ticks;if(F.isFunction(Ad)){Ad=Ad({min:Ac.min,max:Ac.max})}var Ab,AY;for(Ab=0;Ab<Ad.length;++Ab){var AZ=null;var Aa=Ad[Ab];if(typeof Aa=="object"){AY=Aa[0];if(Aa.length>1){AZ=Aa[1]}}else{AY=Aa}if(AZ==null){AZ=Ac.tickFormatter(AY,Ac)}Ac.ticks[Ab]={v:AY,label:AZ}}}}}if(Ae.autoscaleMargin!=null&&Ac.ticks.length>0){if(Ae.min==null){Ac.min=Math.min(Ac.min,Ac.ticks[0].v)}if(Ae.max==null&&Ac.ticks.length>1){Ac.max=Math.min(Ac.max,Ac.ticks[Ac.ticks.length-1].v)}}}function AW(){function AZ(Ac){if(Ac.labelWidth==null){Ac.labelWidth=AI/6}if(Ac.labelHeight==null){labels=[];for(i=0;i<Ac.ticks.length;++i){l=Ac.ticks[i].label;if(l){labels.push('<div class="tickLabel" style="float:left;width:'+Ac.labelWidth+'px">'+l+"</div>")}}Ac.labelHeight=0;if(labels.length>0){var Ab=F('<div style="position:absolute;top:-10000px;width:10000px;font-size:smaller">'+labels.join("")+'<div style="clear:left"></div></div>').appendTo(K);Ac.labelHeight=Ab.height();Ab.remove()}}}function AY(Ae){if(Ae.labelWidth==null||Ae.labelHeight==null){var Ad,Af=[],Ac;for(Ad=0;Ad<Ae.ticks.length;++Ad){Ac=Ae.ticks[Ad].label;if(Ac){Af.push('<div class="tickLabel">'+Ac+"</div>")}}if(Af.length>0){var Ab=F('<div style="position:absolute;top:-10000px;font-size:smaller">'+Af.join("")+"</div>").appendTo(K);if(Ae.labelWidth==null){Ae.labelWidth=Ab.width()}if(Ae.labelHeight==null){Ae.labelHeight=Ab.find("div").height()}Ab.remove()}if(Ae.labelWidth==null){Ae.labelWidth=0}if(Ae.labelHeight==null){Ae.labelHeight=0}}}AZ(AA.xaxis);AY(AA.yaxis);AZ(AA.x2axis);AY(AA.y2axis);var Aa=o.grid.borderWidth/2;for(i=0;i<W.length;++i){Aa=Math.max(Aa,2*(W[i].points.radius+W[i].points.lineWidth/2))}m.left=m.right=m.top=m.bottom=Aa;if(AA.xaxis.labelHeight>0){m.bottom=Math.max(Aa,AA.xaxis.labelHeight+o.grid.labelMargin)}if(AA.yaxis.labelWidth>0){m.left=Math.max(Aa,AA.yaxis.labelWidth+o.grid.labelMargin)}if(AA.x2axis.labelHeight>0){m.top=Math.max(Aa,AA.x2axis.labelHeight+o.grid.labelMargin)}if(AA.y2axis.labelWidth>0){m.right=Math.max(Aa,AA.y2axis.labelWidth+o.grid.labelMargin)}N=AI-m.left-m.right;AB=Z-m.bottom-m.top;AA.xaxis.scale=N/(AA.xaxis.max-AA.xaxis.min);AA.yaxis.scale=AB/(AA.yaxis.max-AA.yaxis.min);AA.x2axis.scale=N/(AA.x2axis.max-AA.x2axis.min);AA.y2axis.scale=AB/(AA.y2axis.max-AA.y2axis.min)}function AU(){a();for(var AY=0;AY<W.length;AY++){AK(W[AY])}}function V(AZ,Af){var Ac=Af+"axis",AY=Af+"2axis",Ab,Ae,Ad,Aa;if(AZ[Ac]){Ab=AA[Ac];Ae=AZ[Ac].from;Ad=AZ[Ac].to}else{if(AZ[AY]){Ab=AA[AY];Ae=AZ[AY].from;Ad=AZ[AY].to}else{Ab=AA[Ac];Ae=AZ[Af+"1"];Ad=AZ[Af+"2"]}}if(Ae!=null&&Ad!=null&&Ae>Ad){return{from:Ad,to:Ae,axis:Ab}}return{from:Ae,to:Ad,axis:Ab}}function a(){var Ac;g.save();g.clearRect(0,0,AI,Z);g.translate(m.left,m.top);if(o.grid.backgroundColor){g.fillStyle=o.grid.backgroundColor;g.fillRect(0,0,N,AB)}if(o.grid.markings){var AZ=o.grid.markings;if(F.isFunction(AZ)){AZ=AZ({xmin:AA.xaxis.min,xmax:AA.xaxis.max,ymin:AA.yaxis.min,ymax:AA.yaxis.max,xaxis:AA.xaxis,yaxis:AA.yaxis,x2axis:AA.x2axis,y2axis:AA.y2axis})}for(Ac=0;Ac<AZ.length;++Ac){var AY=AZ[Ac],Ae=V(AY,"x"),Ab=V(AY,"y");if(Ae.from==null){Ae.from=Ae.axis.min}if(Ae.to==null){Ae.to=Ae.axis.max}if(Ab.from==null){Ab.from=Ab.axis.min}if(Ab.to==null){Ab.to=Ab.axis.max}if(Ae.to<Ae.axis.min||Ae.from>Ae.axis.max||Ab.to<Ab.axis.min||Ab.from>Ab.axis.max){continue}Ae.from=Math.max(Ae.from,Ae.axis.min);Ae.to=Math.min(Ae.to,Ae.axis.max);Ab.from=Math.max(Ab.from,Ab.axis.min);Ab.to=Math.min(Ab.to,Ab.axis.max);if(Ae.from==Ae.to&&Ab.from==Ab.to){continue}Ae.from=Ae.axis.p2c(Ae.from);Ae.to=Ae.axis.p2c(Ae.to);Ab.from=Ab.axis.p2c(Ab.from);Ab.to=Ab.axis.p2c(Ab.to);if(Ae.from==Ae.to||Ab.from==Ab.to){g.strokeStyle=AY.color||o.grid.markingsColor;g.lineWidth=AY.lineWidth||o.grid.markingsLineWidth;g.moveTo(Math.floor(Ae.from),Math.floor(Ab.from));g.lineTo(Math.floor(Ae.to),Math.floor(Ab.to));g.stroke()}else{g.fillStyle=AY.color||o.grid.markingsColor;g.fillRect(Math.floor(Ae.from),Math.floor(Ab.to),Math.floor(Ae.to-Ae.from),Math.floor(Ab.from-Ab.to))}}}g.lineWidth=1;g.strokeStyle=o.grid.tickColor;g.beginPath();var Aa,Ad=AA.xaxis;for(Ac=0;Ac<Ad.ticks.length;++Ac){Aa=Ad.ticks[Ac].v;if(Aa<=Ad.min||Aa>=AA.xaxis.max){continue}g.moveTo(Math.floor(Ad.p2c(Aa))+g.lineWidth/2,0);g.lineTo(Math.floor(Ad.p2c(Aa))+g.lineWidth/2,AB)}Ad=AA.yaxis;for(Ac=0;Ac<Ad.ticks.length;++Ac){Aa=Ad.ticks[Ac].v;if(Aa<=Ad.min||Aa>=Ad.max){continue}g.moveTo(0,Math.floor(Ad.p2c(Aa))+g.lineWidth/2);g.lineTo(N,Math.floor(Ad.p2c(Aa))+g.lineWidth/2)}Ad=AA.x2axis;for(Ac=0;Ac<Ad.ticks.length;++Ac){Aa=Ad.ticks[Ac].v;if(Aa<=Ad.min||Aa>=Ad.max){continue}g.moveTo(Math.floor(Ad.p2c(Aa))+g.lineWidth/2,-5);g.lineTo(Math.floor(Ad.p2c(Aa))+g.lineWidth/2,5)}Ad=AA.y2axis;for(Ac=0;Ac<Ad.ticks.length;++Ac){Aa=Ad.ticks[Ac].v;if(Aa<=Ad.min||Aa>=Ad.max){continue}g.moveTo(N-5,Math.floor(Ad.p2c(Aa))+g.lineWidth/2);g.lineTo(N+5,Math.floor(Ad.p2c(Aa))+g.lineWidth/2)}g.stroke();if(o.grid.borderWidth){g.lineWidth=o.grid.borderWidth;g.strokeStyle=o.grid.color;g.lineJoin="round";g.strokeRect(0,0,N,AB)}g.restore()}function p(){K.find(".tickLabels").remove();var AY='<div class="tickLabels" style="font-size:smaller;color:'+o.grid.color+'">';function AZ(Ac,Ad){for(var Ab=0;Ab<Ac.ticks.length;++Ab){var Aa=Ac.ticks[Ab];if(!Aa.label||Aa.v<Ac.min||Aa.v>Ac.max){continue}AY+=Ad(Aa,Ac)}}AZ(AA.xaxis,function(Aa,Ab){return'<div style="position:absolute;top:'+(m.top+AB+o.grid.labelMargin)+"px;left:"+(m.left+Ab.p2c(Aa.v)-Ab.labelWidth/2)+"px;width:"+Ab.labelWidth+'px;text-align:center" class="tickLabel">'+Aa.label+"</div>"});AZ(AA.yaxis,function(Aa,Ab){return'<div style="position:absolute;top:'+(m.top+Ab.p2c(Aa.v)-Ab.labelHeight/2)+"px;right:"+(m.right+N+o.grid.labelMargin)+"px;width:"+Ab.labelWidth+'px;text-align:right" class="tickLabel">'+Aa.label+"</div>"});AZ(AA.x2axis,function(Aa,Ab){return'<div style="position:absolute;bottom:'+(m.bottom+AB+o.grid.labelMargin)+"px;left:"+(m.left+Ab.p2c(Aa.v)-Ab.labelWidth/2)+"px;width:"+Ab.labelWidth+'px;text-align:center" class="tickLabel">'+Aa.label+"</div>"});AZ(AA.y2axis,function(Aa,Ab){return'<div style="position:absolute;top:'+(m.top+Ab.p2c(Aa.v)-Ab.labelHeight/2)+"px;left:"+(m.left+N+o.grid.labelMargin)+"px;width:"+Ab.labelWidth+'px;text-align:left" class="tickLabel">'+Aa.label+"</div>"});AY+="</div>";K.append(AY)}function AK(AY){if(AY.lines.show||(!AY.bars.show&&!AY.points.show)){h(AY)}if(AY.bars.show){u(AY)}if(AY.points.show){v(AY)}}function h(Aa){function AZ(Aj,Ah,An,Am){var Ag,Ao=null,Ad=null,Ap=null;g.beginPath();for(var Ai=0;Ai<Aj.length;++Ai){Ag=Ao;Ao=Aj[Ai];if(Ag==null||Ao==null){continue}var Af=Ag[0],Al=Ag[1],Ae=Ao[0],Ak=Ao[1];if(Al<=Ak&&Al<Am.min){if(Ak<Am.min){continue}Af=(Am.min-Al)/(Ak-Al)*(Ae-Af)+Af;Al=Am.min}else{if(Ak<=Al&&Ak<Am.min){if(Al<Am.min){continue}Ae=(Am.min-Al)/(Ak-Al)*(Ae-Af)+Af;Ak=Am.min}}if(Al>=Ak&&Al>Am.max){if(Ak>Am.max){continue}Af=(Am.max-Al)/(Ak-Al)*(Ae-Af)+Af;Al=Am.max}else{if(Ak>=Al&&Ak>Am.max){if(Al>Am.max){continue}Ae=(Am.max-Al)/(Ak-Al)*(Ae-Af)+Af;Ak=Am.max}}if(Af<=Ae&&Af<An.min){if(Ae<An.min){continue}Al=(An.min-Af)/(Ae-Af)*(Ak-Al)+Al;Af=An.min}else{if(Ae<=Af&&Ae<An.min){if(Af<An.min){continue}Ak=(An.min-Af)/(Ae-Af)*(Ak-Al)+Al;Ae=An.min}}if(Af>=Ae&&Af>An.max){if(Ae>An.max){continue}Al=(An.max-Af)/(Ae-Af)*(Ak-Al)+Al;Af=An.max}else{if(Ae>=Af&&Ae>An.max){if(Af>An.max){continue}Ak=(An.max-Af)/(Ae-Af)*(Ak-Al)+Al;Ae=An.max}}if(Ad!=An.p2c(Af)||Ap!=Am.p2c(Al)+Ah){g.moveTo(An.p2c(Af),Am.p2c(Al)+Ah)}Ad=An.p2c(Ae);Ap=Am.p2c(Ak)+Ah;g.lineTo(Ad,Ap)}g.stroke()}function Ab(Aj,Aq,Ao){var Ah,Ar=null;var Ad=Math.min(Math.max(0,Ao.min),Ao.max);var Am,Ag=0;var Ap=false;for(var Ai=0;Ai<Aj.length;++Ai){Ah=Ar;Ar=Aj[Ai];if(Ap&&Ah!=null&&Ar==null){g.lineTo(Aq.p2c(Ag),Ao.p2c(Ad));g.fill();Ap=false;continue}if(Ah==null||Ar==null){continue}var Af=Ah[0],An=Ah[1],Ae=Ar[0],Al=Ar[1];if(Af<=Ae&&Af<Aq.min){if(Ae<Aq.min){continue}An=(Aq.min-Af)/(Ae-Af)*(Al-An)+An;Af=Aq.min}else{if(Ae<=Af&&Ae<Aq.min){if(Af<Aq.min){continue}Al=(Aq.min-Af)/(Ae-Af)*(Al-An)+An;Ae=Aq.min}}if(Af>=Ae&&Af>Aq.max){if(Ae>Aq.max){continue}An=(Aq.max-Af)/(Ae-Af)*(Al-An)+An;Af=Aq.max}else{if(Ae>=Af&&Ae>Aq.max){if(Af>Aq.max){continue}Al=(Aq.max-Af)/(Ae-Af)*(Al-An)+An;Ae=Aq.max}}if(!Ap){g.beginPath();g.moveTo(Aq.p2c(Af),Ao.p2c(Ad));Ap=true}if(An>=Ao.max&&Al>=Ao.max){g.lineTo(Aq.p2c(Af),Ao.p2c(Ao.max));g.lineTo(Aq.p2c(Ae),Ao.p2c(Ao.max));continue}else{if(An<=Ao.min&&Al<=Ao.min){g.lineTo(Aq.p2c(Af),Ao.p2c(Ao.min));g.lineTo(Aq.p2c(Ae),Ao.p2c(Ao.min));continue}}var As=Af,Ak=Ae;if(An<=Al&&An<Ao.min&&Al>=Ao.min){Af=(Ao.min-An)/(Al-An)*(Ae-Af)+Af;An=Ao.min}else{if(Al<=An&&Al<Ao.min&&An>=Ao.min){Ae=(Ao.min-An)/(Al-An)*(Ae-Af)+Af;Al=Ao.min}}if(An>=Al&&An>Ao.max&&Al<=Ao.max){Af=(Ao.max-An)/(Al-An)*(Ae-Af)+Af;An=Ao.max}else{if(Al>=An&&Al>Ao.max&&An<=Ao.max){Ae=(Ao.max-An)/(Al-An)*(Ae-Af)+Af;Al=Ao.max}}if(Af!=As){if(An<=Ao.min){Am=Ao.min}else{Am=Ao.max}g.lineTo(Aq.p2c(As),Ao.p2c(Am));g.lineTo(Aq.p2c(Af),Ao.p2c(Am))}g.lineTo(Aq.p2c(Af),Ao.p2c(An));g.lineTo(Aq.p2c(Ae),Ao.p2c(Al));if(Ae!=Ak){if(Al<=Ao.min){Am=Ao.min}else{Am=Ao.max}g.lineTo(Aq.p2c(Ak),Ao.p2c(Am));g.lineTo(Aq.p2c(Ae),Ao.p2c(Am))}Ag=Math.max(Ae,Ak)}if(Ap){g.lineTo(Aq.p2c(Ag),Ao.p2c(Ad));g.fill()}}g.save();g.translate(m.left,m.top);g.lineJoin="round";var Ac=Aa.lines.lineWidth;var AY=Aa.shadowSize;if(AY>0){g.lineWidth=AY/2;g.strokeStyle="rgba(0,0,0,0.1)";AZ(Aa.data,Ac/2+AY/2+g.lineWidth/2,Aa.xaxis,Aa.yaxis);g.lineWidth=AY/2;g.strokeStyle="rgba(0,0,0,0.2)";AZ(Aa.data,Ac/2+g.lineWidth/2,Aa.xaxis,Aa.yaxis)}g.lineWidth=Ac;g.strokeStyle=Aa.color;AD(Aa.lines,Aa.color);if(Aa.lines.fill){Ab(Aa.data,Aa.xaxis,Aa.yaxis)}AZ(Aa.data,0,Aa.xaxis,Aa.yaxis);g.restore()}function v(AZ){function Ac(Ag,Ae,Ah,Ak,Ai){for(var Af=0;Af<Ag.length;++Af){if(Ag[Af]==null){continue}var Ad=Ag[Af][0],Aj=Ag[Af][1];if(Ad<Ak.min||Ad>Ak.max||Aj<Ai.min||Aj>Ai.max){continue}g.beginPath();g.arc(Ak.p2c(Ad),Ai.p2c(Aj),Ae,0,2*Math.PI,true);if(Ah){g.fill()}g.stroke()}}function Ab(Ag,Ai,Ae,Ak,Ah){for(var Af=0;Af<Ag.length;++Af){if(Ag[Af]==null){continue}var Ad=Ag[Af][0],Aj=Ag[Af][1];if(Ad<Ak.min||Ad>Ak.max||Aj<Ah.min||Aj>Ah.max){continue}g.beginPath();g.arc(Ak.p2c(Ad),Ah.p2c(Aj)+Ai,Ae,0,Math.PI,false);g.stroke()}}g.save();g.translate(m.left,m.top);var Aa=AZ.lines.lineWidth;var AY=AZ.shadowSize;if(AY>0){g.lineWidth=AY/2;g.strokeStyle="rgba(0,0,0,0.1)";Ab(AZ.data,AY/2+g.lineWidth/2,AZ.points.radius,AZ.xaxis,AZ.yaxis);g.lineWidth=AY/2;g.strokeStyle="rgba(0,0,0,0.2)";Ab(AZ.data,g.lineWidth/2,AZ.points.radius,AZ.xaxis,AZ.yaxis)}g.lineWidth=AZ.points.lineWidth;g.strokeStyle=AZ.color;AD(AZ.points,AZ.color);Ac(AZ.data,AZ.points.radius,AZ.points.fill,AZ.xaxis,AZ.yaxis);g.restore()}function AM(Aj,Ah,Ac,Ai,Aa,Ao,An,Ak,Af){var Am=true,Ae=true,Ab=true,Ad=false,AZ=Aj+Ac,Al=Aj+Ai,AY=0,Ag=Ah;if(Ag<AY){Ag=0;AY=Ah;Ad=true;Ab=false}if(Al<An.min||AZ>An.max||Ag<Ak.min||AY>Ak.max){return }if(AZ<An.min){AZ=An.min;Am=false}if(Al>An.max){Al=An.max;Ae=false}if(AY<Ak.min){AY=Ak.min;Ad=false}if(Ag>Ak.max){Ag=Ak.max;Ab=false}if(Ao){Af.beginPath();Af.moveTo(An.p2c(AZ),Ak.p2c(AY)+Aa);Af.lineTo(An.p2c(AZ),Ak.p2c(Ag)+Aa);Af.lineTo(An.p2c(Al),Ak.p2c(Ag)+Aa);Af.lineTo(An.p2c(Al),Ak.p2c(AY)+Aa);Af.fill()}if(Am||Ae||Ab||Ad){Af.beginPath();AZ=An.p2c(AZ);AY=Ak.p2c(AY);Al=An.p2c(Al);Ag=Ak.p2c(Ag);Af.moveTo(AZ,AY+Aa);if(Am){Af.lineTo(AZ,Ag+Aa)}else{Af.moveTo(AZ,Ag+Aa)}if(Ab){Af.lineTo(Al,Ag+Aa)}else{Af.moveTo(Al,Ag+Aa)}if(Ae){Af.lineTo(Al,AY+Aa)}else{Af.moveTo(Al,AY+Aa)}if(Ad){Af.lineTo(AZ,AY+Aa)}else{Af.moveTo(AZ,AY+Aa)}Af.stroke()}}function u(Aa){function AZ(Ae,Ab,Ad,Ah,Af,Ai,Ag){for(var Ac=0;Ac<Ae.length;Ac++){if(Ae[Ac]==null){continue}AM(Ae[Ac][0],Ae[Ac][1],Ab,Ad,Ah,Af,Ai,Ag,g)}}g.save();g.translate(m.left,m.top);g.lineJoin="round";g.lineWidth=Aa.bars.lineWidth;g.strokeStyle=Aa.color;AD(Aa.bars,Aa.color);var AY=Aa.bars.align=="left"?0:-Aa.bars.barWidth/2;AZ(Aa.data,AY,AY+Aa.bars.barWidth,0,Aa.bars.fill,Aa.xaxis,Aa.yaxis);g.restore()}function AD(Aa,AY){var AZ=Aa.fill;if(!AZ){return }if(Aa.fillColor){g.fillStyle=Aa.fillColor}else{var Ab=E(AY);Ab.a=typeof AZ=="number"?AZ:0.4;Ab.normalize();g.fillStyle=Ab.toString()}}function AV(){K.find(".legend").remove();if(!o.legend.show){return }var Ae=[];var Ac=false;for(i=0;i<W.length;++i){if(!W[i].label){continue}if(i%o.legend.noColumns==0){if(Ac){Ae.push("</tr>")}Ae.push("<tr>");Ac=true}var Ag=W[i].label;if(o.legend.labelFormatter!=null){Ag=o.legend.labelFormatter(Ag)}Ae.push('<td class="legendColorBox"><div style="border:1px solid '+o.legend.labelBoxBorderColor+';padding:1px"><div style="width:14px;height:10px;background-color:'+W[i].color+';overflow:hidden"></div></div></td><td class="legendLabel">'+Ag+"</td>")}if(Ac){Ae.push("</tr>")}if(Ae.length==0){return }var Ai='<table style="font-size:smaller;color:'+o.grid.color+'">'+Ae.join("")+"</table>";if(o.legend.container!=null){o.legend.container.html(Ai)}else{var Af="";var AZ=o.legend.position,Aa=o.legend.margin;if(AZ.charAt(0)=="n"){Af+="top:"+(Aa+m.top)+"px;"}else{if(AZ.charAt(0)=="s"){Af+="bottom:"+(Aa+m.bottom)+"px;"}}if(AZ.charAt(1)=="e"){Af+="right:"+(Aa+m.right)+"px;"}else{if(AZ.charAt(1)=="w"){Af+="left:"+(Aa+m.left)+"px;"}}var Ah=F('<div class="legend">'+Ai.replace('style="','style="position:absolute;'+Af+";")+"</div>").appendTo(K);if(o.legend.backgroundOpacity!=0){var Ad=o.legend.backgroundColor;if(Ad==null){var Ab;if(o.grid.backgroundColor){Ab=o.grid.backgroundColor}else{Ab=A(Ah)}Ad=E(Ab).adjust(null,null,null,1).toString()}var AY=Ah.children();F('<div style="position:absolute;width:'+AY.width()+"px;height:"+AY.height()+"px;"+Af+"background-color:"+Ad+';"> </div>').prependTo(Ah).css("opacity",o.legend.backgroundOpacity)}}}var AG={pageX:null,pageY:null},d={first:{x:-1,y:-1},second:{x:-1,y:-1},show:false,active:false},AF=[],P=false,O=null,z=null;function AT(Ae,Ac){var Al=o.grid.mouseActiveRadius,Ar=Al*Al+1,At=null,An=false;function Ai(Ay,Ax){return{datapoint:W[Ay].data[Ax],dataIndex:Ax,series:W[Ay],seriesIndex:Ay}}for(var Aq=0;Aq<W.length;++Aq){var Aw=W[Aq].data,Ad=W[Aq].xaxis,Ab=W[Aq].yaxis,Am=Ad.c2p(Ae),Ak=Ab.c2p(Ac),AZ=Al/Ad.scale,AY=Al/Ab.scale,Av=W[Aq].bars.show,Au=!(W[Aq].bars.show&&!(W[Aq].lines.show||W[Aq].points.show)),Aa=W[Aq].bars.align=="left"?0:-W[Aq].bars.barWidth/2,As=Aa+W[Aq].bars.barWidth;for(var Ap=0;Ap<Aw.length;++Ap){if(Aw[Ap]==null){continue}var Ag=Aw[Ap][0],Af=Aw[Ap][1];if(Av){if(!An&&Am>=Ag+Aa&&Am<=Ag+As&&Ak>=Math.min(0,Af)&&Ak<=Math.max(0,Af)){At=Ai(Aq,Ap)}}if(Au){if((Ag-Am>AZ||Ag-Am<-AZ)||(Af-Ak>AY||Af-Ak<-AY)){continue}var Aj=Math.abs(Ad.p2c(Ag)-Ae),Ah=Math.abs(Ab.p2c(Af)-Ac),Ao=Aj*Aj+Ah*Ah;if(Ao<Ar){Ar=Ao;An=true;At=Ai(Aq,Ap)}}}}return At}function J(AZ){var Aa=AZ||window.event;if(Aa.pageX==null&&Aa.clientX!=null){var Ab=document.documentElement,AY=document.body;AG.pageX=Aa.clientX+(Ab&&Ab.scrollLeft||AY.scrollLeft||0);AG.pageY=Aa.clientY+(Ab&&Ab.scrollTop||AY.scrollTop||0)}else{AG.pageX=Aa.pageX;AG.pageY=Aa.pageY}if(o.grid.hoverable&&!z){z=setTimeout(R,100)}if(d.active){AL(AG)}}function AN(AY){if(AY.which!=1){return }document.body.focus();if(document.onselectstart!==undefined&&S.onselectstart==null){S.onselectstart=document.onselectstart;document.onselectstart=function(){return false}}if(document.ondrag!==undefined&&S.ondrag==null){S.ondrag=document.ondrag;document.ondrag=function(){return false}}AR(d.first,AY);AG.pageX=null;d.active=true;F(document).one("mouseup",Y)}function k(AY){if(P){P=false;return }M("plotclick",AY)}function R(){M("plothover",AG);z=null}function M(AZ,AY){var Aa=AQ.offset(),Af={pageX:AY.pageX,pageY:AY.pageY},Ad=AY.pageX-Aa.left-m.left,Ab=AY.pageY-Aa.top-m.top;if(AA.xaxis.used){Af.x=AA.xaxis.c2p(Ad)}if(AA.yaxis.used){Af.y=AA.yaxis.c2p(Ab)}if(AA.x2axis.used){Af.x2=AA.x2axis.c2p(Ad)}if(AA.y2axis.used){Af.y2=AA.y2axis.c2p(Ab)}var Ag=AT(Ad,Ab);if(Ag){Ag.pageX=parseInt(Ag.series.xaxis.p2c(Ag.datapoint[0])+Aa.left+m.left);Ag.pageY=parseInt(Ag.series.yaxis.p2c(Ag.datapoint[1])+Aa.top+m.top)}if(o.grid.autoHighlight){for(var Ac=0;Ac<AF.length;++Ac){var Ae=AF[Ac];if(Ae.auto&&!(Ag&&Ae.series==Ag.series&&Ae.point==Ag.datapoint)){AH(Ae.series,Ae.point)}}if(Ag){AS(Ag.series,Ag.datapoint,true)}}K.trigger(AZ,[Af,Ag])}function x(){if(!O){O=setTimeout(T,50)}}function T(){O=null;AX.save();AX.clearRect(0,0,AI,Z);AX.translate(m.left,m.top);var Ab,Aa;for(Ab=0;Ab<AF.length;++Ab){Aa=AF[Ab];if(Aa.series.bars.show){AJ(Aa.series,Aa.point)}else{AE(Aa.series,Aa.point)}}AX.restore();if(d.show&&b()){AX.strokeStyle=E(o.selection.color).scale(null,null,null,0.8).toString();AX.lineWidth=1;g.lineJoin="round";AX.fillStyle=E(o.selection.color).scale(null,null,null,0.4).toString();var AY=Math.min(d.first.x,d.second.x),Ad=Math.min(d.first.y,d.second.y),AZ=Math.abs(d.second.x-d.first.x),Ac=Math.abs(d.second.y-d.first.y);AX.fillRect(AY+m.left,Ad+m.top,AZ,Ac);AX.strokeRect(AY+m.left,Ad+m.top,AZ,Ac)}}function AS(Aa,AY,Ab){if(typeof Aa=="number"){Aa=W[Aa]}if(typeof AY=="number"){AY=Aa.data[AY]}var AZ=q(Aa,AY);if(AZ==-1){AF.push({series:Aa,point:AY,auto:Ab});x()}else{if(!Ab){AF[AZ].auto=false}}}function AH(Aa,AY){if(typeof Aa=="number"){Aa=W[Aa]}if(typeof AY=="number"){AY=Aa.data[AY]}var AZ=q(Aa,AY);if(AZ!=-1){AF.splice(AZ,1);x()}}function q(Aa,Ab){for(var AY=0;AY<AF.length;++AY){var AZ=AF[AY];if(AZ.series==Aa&&AZ.point[0]==Ab[0]&&AZ.point[1]==Ab[1]){return AY}}return -1}function AE(Ab,Aa){var AZ=Aa[0],Af=Aa[1],Ae=Ab.xaxis,Ad=Ab.yaxis;if(AZ<Ae.min||AZ>Ae.max||Af<Ad.min||Af>Ad.max){return }var Ac=Ab.points.radius+Ab.points.lineWidth/2;AX.lineWidth=Ac;AX.strokeStyle=E(Ab.color).scale(1,1,1,0.5).toString();var AY=1.5*Ac;AX.beginPath();AX.arc(Ae.p2c(AZ),Ad.p2c(Af),AY,0,2*Math.PI,true);AX.stroke()}function AJ(Aa,AY){AX.lineJoin="round";AX.lineWidth=Aa.bars.lineWidth;AX.strokeStyle=E(Aa.color).scale(1,1,1,0.5).toString();AX.fillStyle=E(Aa.color).scale(1,1,1,0.5).toString();var AZ=Aa.bars.align=="left"?0:-Aa.bars.barWidth/2;AM(AY[0],AY[1],AZ,AZ+Aa.bars.barWidth,0,true,Aa.xaxis,Aa.yaxis,AX)}function r(){var AZ=Math.min(d.first.x,d.second.x),AY=Math.max(d.first.x,d.second.x),Ab=Math.max(d.first.y,d.second.y),Aa=Math.min(d.first.y,d.second.y);var Ac={};if(AA.xaxis.used){Ac.xaxis={from:AA.xaxis.c2p(AZ),to:AA.xaxis.c2p(AY)}}if(AA.x2axis.used){Ac.x2axis={from:AA.x2axis.c2p(AZ),to:AA.x2axis.c2p(AY)}}if(AA.yaxis.used){Ac.yaxis={from:AA.yaxis.c2p(Ab),to:AA.yaxis.c2p(Aa)}}if(AA.y2axis.used){Ac.yaxis={from:AA.y2axis.c2p(Ab),to:AA.y2axis.c2p(Aa)}}K.trigger("plotselected",[Ac]);if(AA.xaxis.used&&AA.yaxis.used){K.trigger("selected",[{x1:Ac.xaxis.from,y1:Ac.yaxis.from,x2:Ac.xaxis.to,y2:Ac.yaxis.to}])}}function Y(AY){if(document.onselectstart!==undefined){document.onselectstart=S.onselectstart}if(document.ondrag!==undefined){document.ondrag=S.ondrag}d.active=false;AL(AY);if(b()){r();P=true}return false}function AR(Aa,AY){var AZ=AQ.offset();if(o.selection.mode=="y"){if(Aa==d.first){Aa.x=0}else{Aa.x=N}}else{Aa.x=AY.pageX-AZ.left-m.left;Aa.x=Math.min(Math.max(0,Aa.x),N)}if(o.selection.mode=="x"){if(Aa==d.first){Aa.y=0}else{Aa.y=AB}}else{Aa.y=AY.pageY-AZ.top-m.top;Aa.y=Math.min(Math.max(0,Aa.y),AB)}}function AL(AY){if(AY.pageX==null){return }AR(d.second,AY);if(b()){d.show=true;x()}else{I()}}function I(){if(d.show){d.show=false;x()}}function AC(AZ,AY){var Aa;if(o.selection.mode=="y"){d.first.x=0;d.second.x=N}else{Aa=V(AZ,"x");d.first.x=Aa.axis.p2c(Aa.from);d.second.x=Aa.axis.p2c(Aa.to)}if(o.selection.mode=="x"){d.first.y=0;d.second.y=AB}else{Aa=V(AZ,"y");d.first.y=Aa.axis.p2c(Aa.from);d.second.y=Aa.axis.p2c(Aa.to)}d.show=true;x();if(!AY){r()}}function b(){var AY=5;return Math.abs(d.second.x-d.first.x)>=AY&&Math.abs(d.second.y-d.first.y)>=AY}}F.plot=function(L,J,I){var K=new D(L,J,I);return K};function C(J,I){return I*Math.floor(J/I)}function H(J,K,I){if(K<J){return K}else{if(K>I){return I}else{return K}}}function G(O,N,J,L){var M=["r","g","b","a"];var I=4;while(-1<--I){this[M[I]]=arguments[I]||((I==3)?1:0)}this.toString=function(){if(this.a>=1){return"rgb("+[this.r,this.g,this.b].join(",")+")"}else{return"rgba("+[this.r,this.g,this.b,this.a].join(",")+")"}};this.scale=function(R,Q,S,P){I=4;while(-1<--I){if(arguments[I]!=null){this[M[I]]*=arguments[I]}}return this.normalize()};this.adjust=function(R,Q,S,P){I=4;while(-1<--I){if(arguments[I]!=null){this[M[I]]+=arguments[I]}}return this.normalize()};this.clone=function(){return new G(this.r,this.b,this.g,this.a)};var K=function(Q,P,R){return Math.max(Math.min(Q,R),P)};this.normalize=function(){this.r=K(parseInt(this.r),0,255);this.g=K(parseInt(this.g),0,255);this.b=K(parseInt(this.b),0,255);this.a=K(this.a,0,1);return this};this.normalize()}var B={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]};function A(J){var I,K=J;do{I=K.css("background-color").toLowerCase();if(I!=""&&I!="transparent"){break}K=K.parent()}while(!F.nodeName(K.get(0),"body"));if(I=="rgba(0, 0, 0, 0)"){return"transparent"}return I}function E(K){var I;if(I=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(K)){return new G(parseInt(I[1],10),parseInt(I[2],10),parseInt(I[3],10))}if(I=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(K)){return new G(parseInt(I[1],10),parseInt(I[2],10),parseInt(I[3],10),parseFloat(I[4]))}if(I=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(K)){return new G(parseFloat(I[1])*2.55,parseFloat(I[2])*2.55,parseFloat(I[3])*2.55)}if(I=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(K)){return new G(parseFloat(I[1])*2.55,parseFloat(I[2])*2.55,parseFloat(I[3])*2.55,parseFloat(I[4]))}if(I=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(K)){return new G(parseInt(I[1],16),parseInt(I[2],16),parseInt(I[3],16))}if(I=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(K)){return new G(parseInt(I[1]+I[1],16),parseInt(I[2]+I[2],16),parseInt(I[3]+I[3],16))}var J=F.trim(K).toLowerCase();if(J=="transparent"){return new G(255,255,255,0)}else{I=B[J];return new G(I[0],I[1],I[2])}}})(jQuery);
|