graphit 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c108e26abb3a716171d6ae8e24c54e7db4f5c10a
4
+ data.tar.gz: 05ac30a8f0c4970d1ec56add3d6ad3913f64f228
5
+ SHA512:
6
+ metadata.gz: 0df3f512f487b5bce2e3cd01d8cc17d8556688dae9340066e88404366ec9a63c10ba831c8d3a58033dbe80803cbdbb342436f98fc0049b8624e19538b8f6399f
7
+ data.tar.gz: fb776f32eb97e94520ae93b26a775a8b60a23b3014f0c16d19031e2413d31d01130bb7f9ac7dde184069e95bcab170e37e77149e900a1a4395d24e358ee9c371
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.gem
11
+ .DS_Store
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in graphit.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Jeff McFadden
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,15 @@
1
+ # MRTG2XY
2
+
3
+ A very simple utility to convert data from mrtg log files to a simple x:y format.
4
+
5
+ I use this to send data to a graph utility.
6
+
7
+ ## Installation
8
+
9
+ Install it yourself:
10
+
11
+ $ gem install mrtg2xy
12
+
13
+ ## Usage
14
+
15
+ $ mrtg2xy
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "mrtg2xy"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
data/exe/graphit ADDED
@@ -0,0 +1,448 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bin_utils' # For Speed
4
+
5
+ @characters = {}
6
+
7
+ @characters["0"] = [[0,0,1,0,0],
8
+ [0,1,0,1,0],
9
+ [1,0,0,0,1],
10
+ [1,0,0,0,1],
11
+ [1,0,0,0,1],
12
+ [1,0,0,0,1],
13
+ [0,1,0,1,0],
14
+ [0,0,1,0,0]]
15
+
16
+ @characters["1"] = [[0,0,1,0,0],
17
+ [0,1,1,0,0],
18
+ [1,0,1,0,0],
19
+ [0,0,1,0,0],
20
+ [0,0,1,0,0],
21
+ [0,0,1,0,0],
22
+ [0,0,1,0,0],
23
+ [1,1,1,1,1]]
24
+
25
+
26
+ @characters["2"] = [[0,1,1,1,0],
27
+ [1,0,0,0,1],
28
+ [0,0,0,1,0],
29
+ [0,0,1,0,0],
30
+ [0,1,0,0,0],
31
+ [1,0,0,0,0],
32
+ [1,0,0,0,0],
33
+ [1,1,1,1,1]]
34
+
35
+ @characters["3"] = [[0,1,1,1,0],
36
+ [1,0,0,0,1],
37
+ [0,0,0,0,1],
38
+ [0,0,1,1,0],
39
+ [0,0,0,0,1],
40
+ [0,0,0,0,1],
41
+ [1,0,0,0,1],
42
+ [0,1,1,1,0]]
43
+
44
+ @characters["4"] = [[0,0,0,0,1],
45
+ [0,0,0,1,1],
46
+ [0,0,1,0,1],
47
+ [0,1,0,0,1],
48
+ [1,1,1,1,1],
49
+ [0,0,0,0,1],
50
+ [1,0,0,0,1],
51
+ [0,0,0,0,1]]
52
+
53
+ @characters["5"] = [[1,1,1,1,1],
54
+ [1,0,0,0,0],
55
+ [1,0,0,0,0],
56
+ [1,1,1,1,0],
57
+ [1,0,0,0,1],
58
+ [0,0,0,0,1],
59
+ [1,0,0,0,1],
60
+ [0,1,1,1,0]]
61
+
62
+ @characters["6"] = [[0,0,1,1,1],
63
+ [0,1,0,0,0],
64
+ [1,0,0,0,0],
65
+ [1,1,1,1,0],
66
+ [1,0,0,0,1],
67
+ [1,0,0,0,1],
68
+ [1,0,0,0,1],
69
+ [0,1,1,1,0]]
70
+
71
+ @characters["7"] = [[1,1,1,1,1],
72
+ [0,0,0,0,1],
73
+ [0,0,0,0,1],
74
+ [0,0,0,1,0],
75
+ [0,0,0,1,0],
76
+ [0,0,0,1,0],
77
+ [0,0,1,0,0],
78
+ [0,0,1,0,0]]
79
+
80
+ @characters["8"] = [[0,1,1,1,0],
81
+ [1,0,0,0,1],
82
+ [1,0,0,0,1],
83
+ [0,1,1,1,0],
84
+ [1,0,0,0,1],
85
+ [1,0,0,0,1],
86
+ [1,0,0,0,1],
87
+ [0,1,1,1,0]]
88
+
89
+ @characters["9"] = [[0,1,1,1,0],
90
+ [1,0,0,0,1],
91
+ [1,0,0,0,1],
92
+ [1,0,0,0,1],
93
+ [0,1,1,1,1],
94
+ [0,0,0,0,1],
95
+ [1,0,0,0,1],
96
+ [0,1,1,1,0]]
97
+
98
+
99
+ @characters["A"] = [[0,0,1,0,0],
100
+ [0,1,0,1,0],
101
+ [1,0,0,0,1],
102
+ [1,1,1,1,1],
103
+ [1,0,0,0,1],
104
+ [1,0,0,0,1],
105
+ [1,0,0,0,1],
106
+ [1,0,0,0,1]]
107
+
108
+ @h = 300
109
+ @w = 1050
110
+
111
+ @ymin = 40
112
+ @ymax = 95
113
+ @xmin = 1458621300
114
+ @xmax = 1458770444
115
+
116
+ @bottom_padding = 25
117
+ @top_padding = 10
118
+ @left_padding = 100
119
+ @right_padding = 10
120
+
121
+ @y_tics_mod = 10
122
+ @x_tics_mod = 3600
123
+
124
+ @graph_width = @w - @left_padding - @right_padding
125
+ @graph_height = @h - @bottom_padding - @top_padding
126
+
127
+ def recalculate_pixels_per_unit
128
+ @x_pixels_per_unit = @graph_width.to_f / (@xmax.to_f - @xmin.to_f)
129
+ @y_pixels_per_unit = @graph_height.to_f / (@ymax.to_f - @ymin.to_f)
130
+
131
+ if @xmax - @xmin < (86400 * 3.5)
132
+ @x_tics_mod = 3600
133
+ elsif @xmax - @xmin < (86400 * 7.5)
134
+ @x_tics_mod = (86400 * 24)
135
+ elsif @xmax - @xmin < (86400 * 50)
136
+ @x_tics_mod = (86400 * 24 * 7)
137
+ elsif @xmax - @xmin < (86400 * 800)
138
+ @x_tics_mod = (86400 * 24 * 30)
139
+ else
140
+ @x_tics_mod = 3600
141
+ end
142
+
143
+ puts "@x_pixels_per_unit: #{@x_pixels_per_unit}"
144
+ puts "@y_pixels_per_unit: #{@y_pixels_per_unit}"
145
+ end
146
+
147
+ def translate_data_point_to_graph_point( point )
148
+ #puts "In x: #{point[:x]}, y: #{point[:y]}"
149
+
150
+ if point[:x] < @xmin
151
+ point[:x] = @xmin
152
+ elsif point[:x] > @xmax
153
+ point[:x] = @xmax
154
+ end
155
+
156
+ if point[:y] < @ymin
157
+ point[:y] = @ymin
158
+ elsif point[:y] > @ymax
159
+ point[:y] = @ymax
160
+ end
161
+
162
+ #puts "Mid x: #{point[:x]}, y: #{point[:y]}"
163
+
164
+ x = @left_padding + (point[:x] - @xmin) * @x_pixels_per_unit
165
+ y = @h - @bottom_padding - ((point[:y] - @ymin) * @y_pixels_per_unit)
166
+
167
+ #puts "Out x: #{x}, y: #{y}"
168
+
169
+ return { x: x, y: y }
170
+ end
171
+
172
+ def draw_text( text, px, py, pixels, color )
173
+ text.each_char do |c|
174
+ if @characters[c].nil?
175
+ # skip
176
+ else
177
+ @characters[c].each_with_index do |row, y|
178
+ row.each_with_index do |col, x|
179
+ if col == 0
180
+ # Do nothing
181
+ else
182
+ thisY = px + x
183
+ thisX = py + y
184
+
185
+ pixels[thisX][thisY] = color unless pixels[thisX][thisY].nil?
186
+ end
187
+ end
188
+ end
189
+
190
+ px += @characters[c].size + 1
191
+ end
192
+ end
193
+
194
+ return pixels
195
+ end
196
+
197
+ def draw_line( x1, y1, x2, y2, pixels, color )
198
+ len = Math.sqrt( (x2-x1)**2 + (y2 - y1)**2 )
199
+
200
+ d = 0.0
201
+
202
+ while d < 1
203
+ if x2 == x1
204
+ x = x1
205
+ else
206
+ x = x1 + (x2.to_f-x1.to_f) * d
207
+ end
208
+
209
+ y = y1 + (y2.to_f-y1.to_f) * d
210
+
211
+ pixels[y.to_i][x.to_i] = color unless pixels[y.to_i][x.to_i].nil?
212
+
213
+ d += 1.0 / ( len.to_f * 2.0 )
214
+ end
215
+
216
+ return pixels
217
+ end
218
+
219
+ def graph_data( data, pixels, color )
220
+
221
+ # Horizontal Grid lines
222
+ (@ymin..@ymax).each do |y|
223
+ if y % @y_tics_mod == 0
224
+ p1 = translate_data_point_to_graph_point( { y: y, x: @xmin } )
225
+ p2 = translate_data_point_to_graph_point( { y: y, x: @xmax } )
226
+
227
+ pixels = draw_line( p1[:x], p1[:y], p2[:x], p2[:y], pixels, [0xAA,0xAA,0xAA] )
228
+
229
+ # Dunno why 60. Can't figure it out. I'm sure it's because I'm dumb.
230
+ pixels = draw_text( "#{y}", p1[:x] - (10 * y.to_s.size), p1[:y], pixels, [0x00,0x00,0x00] )
231
+ end
232
+ end
233
+
234
+ #Vertical Grid Lines
235
+ (@xmin..@xmax).each do |x|
236
+ if x % @x_tics_mod == 0
237
+ p1 = translate_data_point_to_graph_point( { x: x, y: @ymin } )
238
+ p2 = translate_data_point_to_graph_point( { x: x, y: @ymax } )
239
+
240
+ #Manual offset for GMT-7
241
+ if (x + (3600*-7)) % 86400 == 0
242
+ lcolor = [0x00,0x00,0xFF]
243
+ else
244
+ lcolor = [0xAA,0xAA,0xAA]
245
+ end
246
+
247
+
248
+ pixels = draw_line( p1[:x], p1[:y], p2[:x], p2[:y], pixels, lcolor )
249
+ end
250
+ end
251
+
252
+ # Graph Outline
253
+ p1 = translate_data_point_to_graph_point( { x: @xmin, y: @ymin } )
254
+ p2 = translate_data_point_to_graph_point( { x: @xmax, y: @ymin } )
255
+ pixels = draw_line( p1[:x], p1[:y], p2[:x], p2[:y], pixels, [0x22,0x22,0x22] )
256
+ p1 = translate_data_point_to_graph_point( { x: @xmax, y: @ymin } )
257
+ p2 = translate_data_point_to_graph_point( { x: @xmax, y: @ymax } )
258
+ pixels = draw_line( p1[:x], p1[:y], p2[:x], p2[:y], pixels, [0x22,0x22,0x22] )
259
+ p1 = translate_data_point_to_graph_point( { x: @xmax, y: @ymax } )
260
+ p2 = translate_data_point_to_graph_point( { x: @xmin, y: @ymax } )
261
+ pixels = draw_line( p1[:x], p1[:y], p2[:x], p2[:y], pixels, [0x22,0x22,0x22] )
262
+ p1 = translate_data_point_to_graph_point( { x: @xmin, y: @ymax } )
263
+ p2 = translate_data_point_to_graph_point( { x: @xmin, y: @ymin } )
264
+ pixels = draw_line( p1[:x], p1[:y], p2[:x], p2[:y], pixels, [0x22,0x22,0x22] )
265
+
266
+
267
+ data.each_with_index do |p, i|
268
+ data[i] = translate_data_point_to_graph_point( p )
269
+ end
270
+
271
+ data.each_with_index do |point, i|
272
+ if i < data.size - 1
273
+ x1 = point[:x]
274
+ y1 = point[:y]
275
+
276
+ x2 = data[i+1][:x]
277
+ y2 = data[i+1][:y]
278
+
279
+ pixels = draw_line( x1, y1, x2, y2, pixels, color )
280
+ end
281
+ end
282
+
283
+ pixels
284
+ end
285
+
286
+ File.open( 'test-01.bmp', 'w') do |f|
287
+
288
+ start = Time.now.to_f
289
+
290
+ h = @h
291
+ w = @w
292
+
293
+ pixels = []
294
+ (1..h).each do |y|
295
+ row = []
296
+ (1..w).each do |x|
297
+ row.push( [0xEE,0xEE,0xEE] )
298
+ end
299
+ pixels.push(row)
300
+ end
301
+
302
+ puts "Generating pixels: #{Time.now.to_f - start}"
303
+
304
+ # (0..499).each do |n|
305
+ #
306
+ # i = (n/100.0) * (2 * Math::PI)
307
+ #
308
+ # y = 50 + (40 * Math.sin(i))
309
+ #
310
+ # pixels[y][n] = [0x00,0x00,0xFF]
311
+ # end
312
+ #
313
+ # (0..499).each do |n|
314
+ #
315
+ # i = (n/100.0) * (2 * Math::PI)
316
+ #
317
+ # y = 50 + (40 * Math.cos(i))
318
+ #
319
+ # pixels[y][n] = [0xFF,0x00,0x00]
320
+ # end
321
+
322
+ # pixels = draw_line( 50, 75, 900, 250, pixels, [0x00,0x00,0xFF] )
323
+ # pixels = draw_line( 40, 65, 900, 250, pixels, [0x00,0xFF,0xFF] )
324
+ #
325
+ # pixels = draw_line( 50, 50, w, 50, pixels, [0xAA,0xAA,0xAA] )
326
+ # pixels = draw_line( 50, 100, w, 100, pixels, [0xAA,0xAA,0xAA] )
327
+ # pixels = draw_line( 50, 150, w, 150, pixels, [0xAA,0xAA,0xAA] )
328
+
329
+ data_to_graph = []
330
+
331
+ @xmin = 9999999999
332
+ @xmax = 0
333
+
334
+ ARGF.each_line do |line|
335
+ puts line
336
+ l = line.strip.split(":")
337
+
338
+ next unless l.size == 2
339
+
340
+ x = l[0].to_i
341
+ y = l[1].to_f
342
+
343
+ @xmin = x if x < @xmin
344
+ @xmax = x if x > @xmax
345
+
346
+ data_to_graph.push( { x: x, y: y } )
347
+ end
348
+
349
+ puts data_to_graph.size
350
+ puts "Data points ^"
351
+
352
+ puts "Max: #{@xmax}, Min: #{@xmin}"
353
+
354
+ recalculate_pixels_per_unit
355
+
356
+ # (0..140).each do |n|
357
+ # point = { x: n * 10, y: @ymax - rand( @ymax ).to_i }
358
+ # data_to_graph.push( translate_data_point_to_graph_point( point ) )
359
+ # end
360
+
361
+ graph_data( data_to_graph, pixels, [0xEE,0x00,0x00] )
362
+
363
+ @xmin = @xmax if @xmin > @xmax
364
+
365
+ (@xmin..@xmax).each do |x|
366
+
367
+ if x % 3600 == 0
368
+ x_offset = translate_data_point_to_graph_point( { x: x, y: 10 } )[:x].to_i
369
+
370
+ h = Time.at(x).hour
371
+
372
+ if h % 2 == 0
373
+ puts "h: #{h.to_s}, x: #{x_offset}"
374
+ pixels = draw_text( h.to_s, x_offset, @h - 15, pixels, [0x00,0x00,0x00] )
375
+ end
376
+ end
377
+ end
378
+
379
+
380
+ pixel_data = ""
381
+
382
+ #pixels = [["0000FF", "FFFFFF", "0000FF", "FFFFFF"],
383
+ # ["FF0000", "00FF00", "FF0000", "00FF00"] ]
384
+
385
+ height = pixels.size
386
+ width = pixels[0].size
387
+
388
+ start = Time.now.to_f
389
+
390
+ pixels.reverse.each_with_index do |row, i|
391
+ row_bytes = 0
392
+ row.each do |pixel|
393
+
394
+ BinUtils.append_int8!(pixel_data, pixel[0])
395
+ BinUtils.append_int8!(pixel_data, pixel[1])
396
+ BinUtils.append_int8!(pixel_data, pixel[2])
397
+
398
+ #pixel_data += [pixel[0,2].hex].pack( "C" )
399
+ #pixel_data += [pixel[2,2].hex].pack( "C" )
400
+ #pixel_data += [pixel[4,2].hex].pack( "C" )
401
+
402
+ row_bytes += 3
403
+ end
404
+
405
+ # Padding
406
+ bytes_to_pad = row_bytes % 4
407
+
408
+ # puts "Row: #{i}, bytes: #{row_bytes}, padding: #{bytes_to_pad}"
409
+
410
+ bytes_to_pad.times do
411
+ BinUtils.append_int8!(pixel_data, 0x00)
412
+ end
413
+ end
414
+
415
+ puts "Generating pixel data string: #{Time.now.to_f - start}"
416
+
417
+
418
+ file_size = 54 + pixel_data.size
419
+
420
+ f.print [0x42].pack ("C")
421
+ f.print [0x4D].pack( "C" )
422
+ f.print [file_size].pack( "L" )
423
+
424
+ f.print [0x00].pack( "C" ) # Unused
425
+ f.print [0x00].pack( "C" )
426
+ f.print [0x00].pack( "C" )
427
+ f.print [0x00].pack( "C" )
428
+
429
+ f.print [54].pack( "L" ) # Pixel Array Offset
430
+
431
+ f.print [0x28, 0x00, 0x00, 0x00].pack( "L" ) #Number of bytes in the DIB header (from this point)
432
+
433
+ f.print [width].pack( "L" ) #Width of the bitmap in pixels
434
+ f.print [height].pack( "L" ) #Height
435
+
436
+ f.print [0x01, 0x00].pack( "S" ) # Number of color planes being used
437
+ f.print [0x18, 0x00].pack( "S" ) # Number of bits per pixel
438
+ f.print [0x00].pack( "L" ) # BI_RGB, no pixel array compression used
439
+ f.print [pixel_data.size].pack( "L" ) # Size of the raw bitmap data (including padding)
440
+ f.print [0x130B].pack( "L" ) #2835 pixels/meter horizontal
441
+ f.print [0x130B].pack( "L" ) #2835 pixels/meter vertical
442
+ f.print [0x00].pack( "L" ) # Number of colors in the palette
443
+ f.print [0x00].pack( "L" ) #0 means all colors are important
444
+
445
+ f.print pixel_data
446
+ end
447
+
448
+ `convert test-01.bmp test-01.png`
@@ -0,0 +1,3 @@
1
+ module Mrtg2xy
2
+ VERSION = "1.0.1"
3
+ end
data/graphit.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # coding: utf-8 #
2
+
3
+
4
+ lib = File.expand_path('../lib', __FILE__)
5
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
+ require 'graphit/version'
7
+
8
+ Gem::Specification.new do |spec|
9
+ spec.name = "graphit"
10
+ spec.version = Graphit::VERSION
11
+ spec.authors = ["jeffmcfadden"]
12
+ spec.email = ["jeff@forgeapps.com"]
13
+
14
+ spec.summary = %q{Super basic graphic library that writes data to BMP files.}
15
+ spec.description = %q{Probably not robust enough to do what you want. I use it to conver mrtg data to scalable graphs.}
16
+ spec.homepage = "https://github.com/jeffmcfadden/graphit"
17
+ spec.license = "MIT"
18
+
19
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
20
+ spec.bindir = "exe"
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.9"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ end
@@ -0,0 +1,3 @@
1
+ module Graphit
2
+ VERSION = "0.0.2"
3
+ end
data/lib/graphit.rb ADDED
File without changes
data/test-01.bmp ADDED
Binary file
data/test-01.png ADDED
Binary file