SimpleOutput 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,138 @@
1
+ =begin
2
+ SimpleOutput
3
+
4
+ Copyright 2014 Austen Higgins-Cassidy
5
+
6
+ Licensed under the Apache License, Version 2.0 (the "License");
7
+ you may not use this file except in compliance with the License.
8
+ You may obtain a copy of the License at
9
+
10
+ http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ Unless required by applicable law or agreed to in writing, software
13
+ distributed under the License is distributed on an "AS IS" BASIS,
14
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ See the License for the specific language governing permissions and
16
+ limitations under the License.
17
+ =end
18
+
19
+ class SimpleChartkick < SimpleOutput::SimpleOutputPlugin
20
+
21
+ require 'json'
22
+
23
+ def initialize(filename="results.html", title="Html Results Page", javascript_path="../include")
24
+ super()
25
+ @filename = filename
26
+ @chart_type = {}
27
+ chartkick_path = javascript_path + ((javascript_path[-1] == "/") ? "chartkick.js" : "/chartkick.js");
28
+ @html = "<html>\n<title>\n#{title}\n</title>\n<script src='http://www.google.com/jsapi'></script>\n
29
+ <script src='http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js'></script>
30
+ <script src='#{chartkick_path}'></script>\n<body>\n"
31
+
32
+ end
33
+
34
+ def options_callback(options)
35
+ if options.has_key?("chart_type")
36
+ @chart_type[@current_name] = options['chart_type']
37
+ end
38
+ end
39
+
40
+ #Rendering Functions functions
41
+ def write_html(content, index)
42
+ @html += content
43
+ end
44
+
45
+ def div(content, name = nil)
46
+ if name == nil
47
+ index = @chart_id
48
+ else
49
+ index = @chart_names[name]
50
+ end
51
+ self.write_html("<div>#{content}</div>\n", index)
52
+ end
53
+
54
+ def p(content, name = nil)
55
+ if name == nil
56
+ index = @chart_id
57
+ else
58
+ index = @chart_names[name]
59
+ end
60
+ self.write_html("<p>#{content}</p>\n", index)
61
+ end
62
+
63
+ def chart_div(data, type="LineChart", name=nil)
64
+ #Convert data to pairs
65
+ @chart_id = @chart_id + 1
66
+ if name != nil
67
+ self.div("<h1>#{name}</h1>")
68
+ end
69
+ self.write_html("<div id='chart-#{@chart_id}' style='height:450px;'></div>\n", @chart_id);
70
+ @js_block += "new Chartkick.#{type}('chart-#{@chart_id}'," + data.to_json + ", {'format':'string'});\n"
71
+ end
72
+
73
+ def linechart(data)
74
+ #Accepts a name:value hash {"Football" => 10, "Basketball" => 5}
75
+ #or a array of pairs [["Football", 10], ["Basketball", 5]]
76
+ #may also nest series with a hash {:name => "Trial1", :data => trial1_data},...
77
+ self.chart_div("LineChart",data)
78
+ end
79
+
80
+ def piechart(data)
81
+ #does not accept multiple series
82
+ self.chart_div("PieChart",data)
83
+ end
84
+
85
+ def columnchart(data)
86
+ self.chart_div("ColumnChart",data)
87
+ end
88
+
89
+ def barchart(data)
90
+ self.chart_div("BarChart",data)
91
+ end
92
+
93
+ def areachart(data)
94
+ self.chart_div("AreaChart", data)
95
+ end
96
+
97
+ def getMultiSeriesHashes
98
+ data_hash = {}
99
+
100
+ @x.each_pair do |(key, x_series)|
101
+ data_hash[key] = []
102
+ y_series = @y[key]
103
+ x_series.each_with_index do |x_data, index|
104
+
105
+ y_data = y_series[index]
106
+ series_key = @series_names[key][index]
107
+ data_hash[key] << {'name' => series_key}
108
+ data_hash[key].last['data'] = {}
109
+ x_data.each_with_index do |x_point, index|
110
+ y_point = y_data[index]
111
+ data_hash[key].last['data'][x_point] = y_point
112
+ end
113
+ end
114
+ end
115
+ return data_hash
116
+ end
117
+
118
+ def save
119
+ @chart_id = 0
120
+ @js_block = ""
121
+
122
+ self.getMultiSeriesHashes.each_pair do |(chart_name, chart_series)|
123
+ type = @chart_type.has_key?(chart_name) ? @chart_type[chart_name] : "LineChart"
124
+ if type == "PieChart"
125
+ chart_series = chart_series[0]['data']
126
+ end
127
+ self.chart_div(chart_series, type, chart_name)
128
+ if @annotations.has_key?(chart_name)
129
+ @annotations[chart_name].each {|content| self.p(content)}
130
+ end
131
+ end
132
+ @html += "<script>$(function (){#{@js_block}});</script></body></html>"
133
+ File.open(@filename, "w") do |file|
134
+ file.syswrite(@html)
135
+ end
136
+ end
137
+
138
+ end
@@ -0,0 +1,319 @@
1
+ =begin
2
+
3
+ SimpleOutput Module
4
+ Copyright 2014 Austen Higgins-Cassidy
5
+
6
+ Licensed under the Apache License, Version 2.0 (the "License");
7
+ you may not use this file except in compliance with the License.
8
+ You may obtain a copy of the License at
9
+
10
+ http://www.apache.org/licenses/LICENSE-2.0
11
+
12
+ Unless required by applicable law or agreed to in writing, software
13
+ distributed under the License is distributed on an "AS IS" BASIS,
14
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ See the License for the specific language governing permissions and
16
+ limitations under the License.
17
+ =end
18
+
19
+
20
+
21
+
22
+ module SimpleOutput
23
+ class SimpleOutputPlugin
24
+
25
+ def initialize()
26
+ @x = {}
27
+ @y = {}
28
+ @series_names = {}
29
+ @data_id = 0
30
+ @annotations = {}
31
+ @current_name = ""
32
+ @series_id = 0
33
+ end
34
+ #Virtual Functions
35
+ def options_callback(options)
36
+ end
37
+
38
+ def set_x_callback(data, name, options)
39
+ end
40
+
41
+ def set_y_callback(data, name, options)
42
+ end
43
+
44
+ def append_callback(x,y,name,options)
45
+ end
46
+
47
+ def new_series_callback(name)
48
+ end
49
+
50
+ #CORE functions
51
+ def translate_name(name)
52
+ if name == nil
53
+ name = @current_name
54
+ end
55
+ if !@x.has_key?(name)
56
+ @x[name] = []
57
+ end
58
+ if !@y.has_key?(name)
59
+ @y[name] = []
60
+ end
61
+ return name
62
+ end
63
+
64
+ def advance_series(name=nil)
65
+ @series_id += 1
66
+ @current_name = name == nil ? "series-#{@series_id}" : name
67
+ self.new_series_callback(name)
68
+ if !@series_names.has_key?(@current_name)
69
+ @series_names[@current_name] = []
70
+ end
71
+ @annotations[@current_name] = []
72
+ @current_name
73
+ end
74
+
75
+ def append_series_name(name=nil, options={})
76
+ name = translate_name(name)
77
+ if !@series_names.has_key?(name)
78
+ @series_names[name] = []
79
+ end
80
+ if options.has_key?('series')
81
+ @series_names[name] << options['series']
82
+ else
83
+ @series_names[name] << "data-#{@data_id}"
84
+ @data_id += 1
85
+ end
86
+ end
87
+
88
+ def setXData(data, name, options={})
89
+ @x[name] = []
90
+ @x[name] << data
91
+ self.set_x_callback(data, name, options)
92
+ end
93
+
94
+ def setYData(data, name, options={})
95
+ @y[name] = []
96
+ @y[name] << data
97
+ self.set_y_callback(data, name, options)
98
+ end
99
+
100
+ def newData( x=[], y=[],name=nil, options={})
101
+ name = self.advance_series(name)
102
+ self.setXData(x, name, options)
103
+ self.setYData(y, name, options)
104
+ self.append_series_name(name,options)
105
+ self.options_callback(options)
106
+ end
107
+
108
+ #Interface Functions ===================================
109
+ def appendXY( x=[], y=[],name=nil, options={})
110
+ name = translate_name(name)
111
+ @x[name] << x
112
+ @y[name] << y
113
+ self.append_series_name(name, options)
114
+ self.options_callback(options)
115
+ self.append_callback(x,y,name,options)
116
+ end
117
+
118
+ def setXY(x=[], y=[], name=nil, options={})
119
+ self.newData(x,y,name,options)
120
+ end
121
+
122
+ def appendPoints(points =[], name=nil, options={})
123
+ x = []
124
+ y = []
125
+ points.each do |point|
126
+ x << point[0]
127
+ y << point[1]
128
+ end
129
+ self.appendXY(x,y,name,options)
130
+ end
131
+
132
+ def setPoints(points = [], name=nil, options={})
133
+ x = []
134
+ y = []
135
+ points.each do |point|
136
+ x << point[0]
137
+ y << point[1]
138
+ end
139
+ self.setXY(x,y,name, options)
140
+ end
141
+
142
+ def appendHash(hash = {}, name=nil, options={})
143
+ name = translate_name(name)
144
+ x = []
145
+ y = []
146
+ hash.each_with_index do |(key, value), index|
147
+ if key.is_a? Numeric
148
+ x << key
149
+ else
150
+ x << index
151
+ end
152
+ if value.is_a? Numeric
153
+ y << value
154
+ else
155
+ y << 0
156
+ end
157
+ end
158
+ self.appendXY(x,y,name,options)
159
+ end
160
+
161
+ def setHash(hash ={}, name=nil, options={})
162
+ x = []
163
+ y = []
164
+ hash.each_with_index do |(key, value), index|
165
+ if key.is_a? Numeric
166
+ x << key
167
+ else
168
+ x << index
169
+ end
170
+ if value.is_a? Numeric
171
+ y << value
172
+ else
173
+ y << 0
174
+ end
175
+ end
176
+ self.setXY(x,y,name,options)
177
+ end
178
+
179
+ def annotate(annotation, name=nil, options = {})
180
+ name = translate_name(name)
181
+ @annotations[name] << annotation
182
+ self.options_callback(options)
183
+ end
184
+
185
+ #Internal Helpers
186
+ def getDataAsPoints
187
+ series_data = {}
188
+ @x.each_pair do |(key, x_series)|
189
+ #For each series of data
190
+ y_series = @y[key]
191
+ series_data[key] = []
192
+
193
+ x_series.each_with_index do |x_line, index|
194
+ #For each line
195
+ series_data[key] << [] #Create an empty set
196
+ y_line = y_series[index]
197
+ x_line.each_with_index do |x_point, index|
198
+ y_point = y_line[index]
199
+ series_data[key].last << [x_point, y_point]
200
+ end
201
+ end
202
+ end
203
+ return series_data
204
+ end
205
+
206
+ def getDataAsXY
207
+ series_data = {}
208
+ @x.each_pair do |(key, x_series)|
209
+ y_series = @y[key]
210
+ series_data[key] = []
211
+ x_series.each_with_index do |x_line, index|
212
+ y_line = y_series[index]
213
+ series_data[key] << [x_line, y_line]
214
+ end
215
+ end
216
+ return series_data
217
+ end
218
+
219
+ def getSeriesHashes
220
+ data_hash = {}
221
+
222
+ @x.each_pair do |(key, x_series)|
223
+
224
+ data_hash[key] = {}
225
+ y_series = @y[key]
226
+ x_series.each_with_index do |x_data, index|
227
+
228
+ y_data = y_series[index]
229
+ series_key = @series_names[key][index]
230
+ data_hash[key][series_key] = {}
231
+ x_data.each_with_index do |x_point, index|
232
+ y_point = y_data[index]
233
+ data_hash[key][series_key][x_point] = y_point
234
+ end
235
+ end
236
+ end
237
+ return data_hash
238
+ end
239
+
240
+ #Output
241
+ def save()
242
+
243
+ end
244
+
245
+ end
246
+
247
+ class SimpleOutputEngine
248
+
249
+ def initialize()
250
+ @plugins = []
251
+ @data_id = 0
252
+ end
253
+
254
+ def addPlugin(plugin)
255
+ @plugins << plugin
256
+ end
257
+
258
+ #Accept either [[x,y],[x,y]]
259
+ #Hash [name] = y
260
+ # array [x,y ]
261
+ #Interface Functions
262
+ def appendXY( x=[], y=[],name=nil, options={})
263
+ @plugins.each {|plugin| plugin.appendXY(x,y,name, options)}
264
+ end
265
+
266
+ def appendXYarray(data=[], name=nil, options={})
267
+ @plugins.each {|plugin| plugin.appendXY(data[0],data[1],name, options)}
268
+ end
269
+
270
+ def setXYarray(data = [], name=nil, options={})
271
+ @plugins.each {|plugin| plugin.setXY(data[0],data[1], name, options)}
272
+ end
273
+
274
+ def setXY(x=[], y=[], name=nil, options={})
275
+ @plugins.each {|plugin| plugin.setXY(x,y,name, options)}
276
+ end
277
+
278
+ def appendPoints(points =[], name=nil, options={})
279
+ @plugins.each {|plugin| plugin.appendPoints(points,name, options)}
280
+ end
281
+
282
+ def setPoints(points = [], name=nil, options={})
283
+ @plugins.each {|plugin| plugin.setPoints(points,name, options)}
284
+ end
285
+
286
+ def appendHash(hash = {}, name=nil, options={})
287
+ @plugins.each {|plugin| plugin.appendHash(hash,name, options)}
288
+ end
289
+
290
+ def setHash(hash ={}, name=nil, options={})
291
+ @plugins.each {|plugin| plugin.setHash(hash,name, options)}
292
+ end
293
+
294
+ def setArray(data = [], name=nil, options={})
295
+ x = []
296
+ data.count.times {|i| x << i}
297
+ y = data
298
+ self.setXY(x,y,name,options)
299
+ end
300
+
301
+ def appendArray(data = [], name=nil, options={})
302
+ x = []
303
+ data.count.times {|i| x << i}
304
+ y = data
305
+ self.appendXY(x,y,name,options)
306
+ end
307
+
308
+ def annotate(annotation, name=nil, options={})
309
+ @plugins.each {|plugin| plugin.annotate(annotation, name, options)}
310
+ end
311
+
312
+ def save()
313
+ @plugins.each {|plugin| plugin.save()}
314
+ end
315
+
316
+ end
317
+
318
+
319
+ end