tk-parallelcoordinates 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,42 @@
1
+ # rcov generated
2
+ coverage
3
+
4
+ # rdoc generated
5
+ rdoc
6
+
7
+ # yard generated
8
+ doc
9
+ .yardoc
10
+
11
+ # bundler
12
+ .bundle
13
+
14
+ # jeweler generated
15
+ pkg
16
+
17
+ # Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
18
+ #
19
+ # * Create a file at ~/.gitignore
20
+ # * Include files you want ignored
21
+ # * Run: git config --global core.excludesfile ~/.gitignore
22
+ #
23
+ # After doing this, these files will be ignored in all your git projects,
24
+ # saving you from having to 'pollute' every project you touch with them
25
+ #
26
+ # Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
27
+ #
28
+ # For MacOS:
29
+ #
30
+ #.DS_Store
31
+ #
32
+ # For TextMate
33
+ #*.tmproj
34
+ #tmtags
35
+ #
36
+ # For emacs:
37
+ #*~
38
+ #\#*
39
+ #.\#*
40
+ #
41
+ # For vim:
42
+ #*.swp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in tk-doubleslider.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,17 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ tk-parallelcoordinates (0.1.1)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ rake (0.8.7)
10
+
11
+ PLATFORMS
12
+ ruby
13
+
14
+ DEPENDENCIES
15
+ bundler (~> 1.3)
16
+ rake
17
+ tk-parallelcoordinates!
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Chris Lee, PhD
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,109 @@
1
+ # Tk::ParallelCoordinates
2
+
3
+ A parallel coordinate plot has multiple axes that are parallel to each other, as opposed to the normal perpendicular axes. The advantage with parallel axes is that you can have more than just two axes so that you can represent higher-dimensional data. However, when the data gets dense, it can quickly obscure details.
4
+
5
+ This implementation is for Ruby-Tk and has been tested in:
6
+ * ruby-1.8.7-p371
7
+ * ruby-1.9.3-p392
8
+ * ruby-2.0.0-p0
9
+
10
+ RVM install command example (rvm doesn't install with tk or tcl by default):
11
+
12
+ rvm reinstall 1.9.3 --enable-shared --enable-pthread --with-tk --with-tcl
13
+
14
+ ## Installation
15
+
16
+ Add this line to your application's Gemfile:
17
+
18
+ gem 'tk-parallelcoordinates'
19
+
20
+ And then execute:
21
+
22
+ $ bundle
23
+
24
+ Or install it yourself as:
25
+
26
+ $ gem install tk-parallelcoordinates
27
+
28
+ ## Usage
29
+
30
+ Within a Tk project, you'll need to have a Window with a Frame to place the ParallelCoordinate within. Here is an example with a few of the features turned on:
31
+
32
+ require 'tk'
33
+
34
+ class TkPC_Callback
35
+ def call(tuples)
36
+ tuples.each do |t|
37
+ puts t.join(" ")
38
+ end
39
+ end
40
+ end
41
+
42
+ def full_example
43
+ # create the root window for this Tk app
44
+ root = TkRoot.new() {
45
+ title "Tk::ParallelCoordinates Test"
46
+ protocol('WM_DELETE_WINDOW', proc{ exit })
47
+ }
48
+ # bind ctrl-c to exit
49
+ root.bind('Control-c', proc{ exit })
50
+ # create a frame to place the ParallelCoordinate within
51
+ left_frame = TkFrame.new(root)
52
+ left_frame.grid(:row=>0,:column=>0,:sticky=>'new')
53
+ # create a model of the data to display
54
+ model = [
55
+ # model is an array of axes. One hash per axis. This model has two axes.
56
+ # the first axis is called "Port", is a range, is scaled by the 3rd square root
57
+ # has a min of 0, and max of 65535
58
+ # formated by %d
59
+ {
60
+ :name => 'Port',
61
+ :type => 'range',
62
+ :scale => '3rt',
63
+ :min => 0,
64
+ :max => 65535,
65
+ :ofmt => '%d',
66
+ #:items => [1,22,80,137,443,1024,5900,6667,31337,65335]
67
+ },
68
+ # the second axes is called "Host", contains a list of items.
69
+ {
70
+ :name => 'Host',
71
+ :type => 'list',
72
+ :list => ['192.168.0.1','192.168.0.4','192.168.0.2','192.168.0.3']
73
+ }
74
+ ]
75
+ # create the parallel coordinates frame
76
+ pcp = Tk::ParallelCoordinates.new(left_frame, 500, 360, model)
77
+ # add items to the parallel coordinates frame
78
+ [[53,'192.168.0.1'],[53,'192.168.0.2'],[80,'192.168.0.2'],[43099,'192.168.0.3']].each do |t|
79
+ key = t[0].to_s+":"+t[1]
80
+ pcp.addtuple(key,Tk::ParallelCoordinates::STATE_NORMAL,t)
81
+ end
82
+ # install the select callback
83
+ pcp.set_select_cb(TkPC_Callback.new)
84
+ # enter the Tk mainloop
85
+ Tk.mainloop()
86
+ end
87
+
88
+ Great, so what options can Tk::ParallelCoordinates models take?
89
+
90
+ name # the name of the axes, any string you want
91
+ type # the type of data: range, list, or date
92
+ min # minimal value, not applicable to list type data
93
+ max # maximum value, not applicable to list type data
94
+ ofmt # the formating string or function
95
+ ifmt # the parsing string for date data
96
+ items # items for a list, OR items to display in a range
97
+
98
+ ## Contributing
99
+
100
+ 1. Fork it
101
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
102
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
103
+ 4. Push to the branch (`git push origin my-new-feature`)
104
+ 5. Create new Pull Request
105
+
106
+ ## Copyright
107
+
108
+ Copyright (c) 2011 Chris Lee, PhD. See LICENSE.txt for
109
+ further details.
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ require 'rake/testtask'
5
+
6
+ Rake::TestTask.new do |t|
7
+ t.libs << 'lib'
8
+ t.test_files = FileList['test/test_*.rb']
9
+ t.verbose = true
10
+ end
11
+
12
+ task :default => :test
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,282 @@
1
+ # DESCRIPTION: provides a TK widget of a parallel coordinate plot.
2
+
3
+ # Chris' note: My memory tells me that I lifted the basic design of this from somewhere on the web, but I don't remember where. My guess is that I added more than 80% new functionality.
4
+
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+ module Tk
18
+ class ParallelCoordinates
19
+ STATE_NORMAL = 0
20
+ STATE_FILTERED = 1
21
+ STATE_SELECTED = 2
22
+ STATE_CURRENT = 3
23
+ STATES = [ 'normal', 'filtered', 'selected', 'current' ]
24
+
25
+ @@default_colors = {
26
+ 'labels' => 'grey75',
27
+ 'axis' => 'steelblue',
28
+ 'labels' => 'steelblue',
29
+ 'selector' => 'red',
30
+ 'state' => [ 'grey70', 'grey40', '#999900', 'purple' ]
31
+ }
32
+ @@scales_in = {
33
+ 'lin' => proc { |x| x },
34
+ 'log' => proc { |x| (x<=0) ? 0 : Math.log(x) },
35
+ 'log2' => proc { |x| (x<=0) ? 0 : Math.log(x)/Math.log(2) },
36
+ 'log10' => proc { |x| Math.log10(x) },
37
+ 'sqrt' => proc { |x| Math.sqrt(x) },
38
+ '3rt' => proc { |x| x ** (1/3.0) },
39
+ }
40
+ @@scales_out = {
41
+ 'lin' => proc { |x| x },
42
+ 'log' => proc { |x| Math.exp(x) },
43
+ 'log2' => proc { |x| 2 ** x },
44
+ 'log10' => proc { |x| 10 ** x },
45
+ 'sqrt' => proc { |x| x ** 2 },
46
+ '3rt' => proc { |x| x ** 3 },
47
+ }
48
+
49
+ attr_accessor :field_separator
50
+
51
+ def initialize(parent, h, w, model)
52
+ @model = model
53
+ @canvas = TkCanvas.new(parent) {
54
+ height h
55
+ width w
56
+ }
57
+ @canvas.pack
58
+ @left_margin = 50
59
+ @right_margin = w - 90
60
+ @top_margin = 10
61
+ @bottom_margin = h - 10
62
+ @draw_width = @right_margin - @left_margin
63
+ @draw_height = @bottom_margin - @top_margin
64
+ @canvas.bind("1", proc{|e| do_press(e.x, e.y)})
65
+ @canvas.bind("B1-Motion", proc{|x, y| do_motion(x, y)}, "%x %y")
66
+ @canvas.bind("ButtonRelease-1", proc{|x, y| do_release(x, y)}, "%x %y")
67
+ @colors = @@default_colors
68
+ @tuples = {}
69
+ @field_separator = ":"
70
+ draw_axis
71
+ end
72
+
73
+ def pack(*args)
74
+ @canvas.pack(*args)
75
+ end
76
+
77
+ def update
78
+ @tuples.each do |k,t|
79
+ @canvas.itemconfigure k, :fill => @colors['state'][t[0]]
80
+ end
81
+ end
82
+
83
+ def set_tuple_state(key,state)
84
+ @canvas.itemconfigure key, :fill => @colors['state'][state]
85
+ @tuples[key][0] = state
86
+ @canvas.raise key, 'all'
87
+ end
88
+
89
+ def addtuple(tuple,key=tuple.join(@field_separator),state=STATE_NORMAL)
90
+ if tuple.length != @model.length
91
+ puts "grr... what do I do now? the tuple you gave me is a different length than the number of axes I have"
92
+ return
93
+ end
94
+ axis = 0
95
+ cx = cy = 0
96
+ tuple.each do |item|
97
+ x = axis2x(axis)
98
+ y = item2y(axis, item)
99
+ if cx > 0
100
+ TkcLine.new(@canvas, cx, cy, x, y, :tags => [ key ], :fill => @colors['state'][state] )
101
+ end
102
+ cx = x
103
+ cy = y
104
+ axis += 1
105
+ end
106
+ @tuples[key] = [state,tuple]
107
+ end
108
+
109
+ def addtuples(tuples)
110
+ tuples.each do |tuple|
111
+ addtuple(tuple)
112
+ end
113
+ end
114
+
115
+ def axis2x(axis)
116
+ @model[axis][:x]
117
+ end
118
+
119
+ def item2y(axis, item)
120
+ m = @model[axis]
121
+ if m[:type] == 'range'
122
+ scale = m[:scale]
123
+ s_in = @@scales_in[scale]
124
+ s_out = @@scales_out[scale]
125
+ min = s_in.call m[:min]
126
+ max = s_in.call m[:max]
127
+ del = max - min
128
+ y = @top_margin + (@draw_height * ((s_in.call(item) - min)/(del - min)))
129
+ return y
130
+ elsif m[:type] == 'list'
131
+ c = 0
132
+ m[:list].each do |i|
133
+ break if item == i
134
+ c += 1
135
+ end
136
+ y = @top_margin + (@draw_height * (c.to_f/m[:list].length))
137
+ return y
138
+ elsif m[:type] == 'date'
139
+ raise "I must have fmt_in and fmt_out for a time axis. Use the strftime codes for formatting. E.g., %s => unix timestamp, %Y-%m-%d => SQL date (2007-12-12)" if m[:ifmt] == nil
140
+ min = Date.strptime(m[:min],m[:ifmt])
141
+ max = Date.strptime(m[:max],m[:ifmt])
142
+ del = (max - min).to_i
143
+ y = @top_margin + (@draw_height * ((Date.strptime(item,m[:ifmt]) - min)/(del - min)))
144
+ return y
145
+ end
146
+ end
147
+
148
+ def draw_axis
149
+ axes = @model.length
150
+ axes_spacing = @draw_width / (axes - 1.0)
151
+ offset = @left_margin
152
+ axis = 0
153
+ @model.each do |m|
154
+ m[:x] = offset
155
+ #puts "#{offset} #{@top_margin} #{offset} #{@bottom_margin}"
156
+ TkcLine.new(@canvas, offset, @top_margin, offset, @bottom_margin, :tags => ['axis'], :fill => @colors['axis'])
157
+ offset += axes_spacing
158
+ # lin, log, log10, sqrt, 3rt
159
+ if m[:type] == 'range'
160
+ scale = m[:scale]
161
+ s_in = @@scales_in[scale]
162
+ s_out = @@scales_out[scale]
163
+ min = s_in.call m[:min]
164
+ max = s_in.call m[:max]
165
+ del = max - min
166
+ if m[:items]
167
+ m[:items].each do |itemx|
168
+ item = s_in.call itemx
169
+ y = @top_margin + (@draw_height * ((item - min)/(del - min)))
170
+ text = itemx
171
+ text = sprintf m[:ofmt], text if m[:ofmt]
172
+ TkcText.new(@canvas, m[:x], y, :text => text, :anchor => (axis==0) ? 'e' : 'w', :fill => @colors['labels'], :tags => ['axislabel'])
173
+ end
174
+ else
175
+ points = m[:points] || 20.0
176
+ step = del / points.to_f
177
+ item = min
178
+ items = []
179
+ ctext = nil
180
+ (0..points).each do |i|
181
+ y = @top_margin + (@draw_height * ((item - min)/(del - min)))
182
+ text = s_out.call(item)
183
+ text = sprintf m[:ofmt], text if m[:ofmt]
184
+ unless text == ctext
185
+ TkcText.new(@canvas, m[:x], y, :text => text, :anchor => (axis==0) ? 'e' : 'w', :fill => @colors['labels'], :tags => ['axislabel'])
186
+ end
187
+ ctext = text
188
+ items.push item
189
+ item += step
190
+ end
191
+ m[:items] = items
192
+ end
193
+ elsif m[:type] == 'list'
194
+ # skip helps to mitigate overlap. 10.0 is what I assume the font size to be
195
+ skip = (((m[:list].length * 10.0)/@draw_height) + 1).to_i
196
+ item = 0
197
+ items = []
198
+ m[:list].each do |i|
199
+ if item % skip == 0
200
+ y = @top_margin + (@draw_height * (item.to_f/m[:list].length))
201
+ i = sprintf m[:ofmt], i if m[:ofmt]
202
+ TkcText.new(@canvas, m[:x], y, :text => i, :anchor => (axis==0) ? 'e' : 'w', :fill => @colors['labels'], :tags => ['axislabel'])
203
+ items.push i
204
+ end
205
+ item += 1
206
+ end
207
+ elsif m[:type] == 'date'
208
+ min = Date.strptime(m[:min],m[:ifmt])
209
+ max = Date.strptime(m[:max],m[:ifmt])
210
+ item = min
211
+ del = (max - min).to_i
212
+ points = m[:points] || 20.0
213
+ step = del / points.to_f
214
+ (0..points).each do |i|
215
+ y = @top_margin + (@draw_height * (item - min)/(del - min))
216
+ text = item.strftime m[:ofmt]
217
+ TkcText.new(@canvas, m[:x], y, :text => text, :anchor => (axis==0) ? 'e' : 'w', :fill => @colors['labels'], :tags => ['axislabel'])
218
+ item += step
219
+ end
220
+ end
221
+ axis += 1
222
+ end
223
+ end
224
+
225
+ def set_select_cb(callback)
226
+ @select_cb = callback
227
+ end
228
+
229
+ def do_press(x, y)
230
+ @start_x = x
231
+ @start_y = y
232
+ @current_rect = TkcRectangle.new(@canvas, x, y, x, y, :dash => '-', :outline => @colors['selector'])
233
+ end
234
+
235
+ def do_motion(x, y)
236
+ if @current_rect
237
+ @current_rect.coords @start_x, @start_y, x, y
238
+ @canvas.itemconfigure 'selected', :fill => @colors['state'][STATE_NORMAL]
239
+ @canvas.dtag 'selected'
240
+ @canvas.addtag_overlapping 'selected', @start_x, @start_y, x, y
241
+ @canvas.itemconfigure 'selected', :fill => @colors['state'][STATE_SELECTED]
242
+ @current_rect.fill = ''
243
+ @canvas.itemconfigure 'axis', :fill => @colors['axis']
244
+ @canvas.itemconfigure 'axislabel', :fill => @colors['labels']
245
+ # the below is slow, we need to find a faster way
246
+ @tuples.each do |k,t|
247
+ if t[0] == STATE_FILTERED
248
+ @canvas.itemconfigure k, :fill => @colors['state'][STATE_FILTERED]
249
+ end
250
+ end
251
+ end
252
+ end
253
+
254
+ def do_release(x, y)
255
+ if @current_rect
256
+ #@canvas.addtag_overlapping 'selected', @start_x, @start_y, x, y
257
+ #@canvas.itemconfigure 'selected', :fill => @colors['state'][STATE_SELECTED]
258
+ @current_rect.delete
259
+ @current_rect = nil
260
+ tuples = []
261
+ items = @canvas.find_withtag 'selected'
262
+ items.each do |item|
263
+ item.gettags.each do |tag|
264
+ if tag =~ /\:/
265
+ if @tuples[tag] == nil or @tuples[tag][0] != STATE_FILTERED
266
+ tuples.push( tag.split(/#{@field_separator}/) )
267
+ end
268
+ end
269
+ end
270
+ end
271
+ @select_cb.call(tuples) if @select_cb and tuples.length > 0
272
+ end
273
+ end
274
+
275
+ def setPalette(*args)
276
+ return unless args.length > 0
277
+ args[0].each do |k,v|
278
+ @colors[k] = v
279
+ end
280
+ end
281
+ end
282
+ end
@@ -0,0 +1,5 @@
1
+ module Tk
2
+ class ParallelCoordinates
3
+ VERSION = "0.1.1"
4
+ end
5
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,3 @@
1
+ require 'test/unit'
2
+ require 'tk'
3
+ require File.expand_path('../../lib/tk/parallelcoordinates.rb', __FILE__)
@@ -0,0 +1,64 @@
1
+ unless Kernel.respond_to?(:require_relative)
2
+ module Kernel
3
+ def require_relative(path)
4
+ require File.join(File.dirname(caller[0]), path.to_str)
5
+ end
6
+ end
7
+ end
8
+
9
+ require_relative 'helper'
10
+
11
+ class TkPC_Callback
12
+ def call(tuples)
13
+ tuples.each do |t|
14
+ puts t.join(" ")
15
+ end
16
+ end
17
+ end
18
+
19
+ class TestTkParallelCoordinates < Test::Unit::TestCase
20
+ def test_instantiate
21
+ # create the root window for this Tk app
22
+ root = TkRoot.new() {
23
+ title "Tk::ParallelCoordinates Test"
24
+ protocol('WM_DELETE_WINDOW', proc{ exit })
25
+ }
26
+ # bind ctrl-c to exit
27
+ root.bind('Control-c', proc{ exit })
28
+ # create a frame to place the ParallelCoordinate within
29
+ left_frame = TkFrame.new(root)
30
+ left_frame.grid(:row=>0,:column=>0,:sticky=>'new')
31
+ # create a model of the data to display
32
+ model = [
33
+ # model is an array of axes. One hash per axis. This model has two axes.
34
+ # the first axis is called "Port", is a range, is scaled by the 3rd square root
35
+ # has a min of 0, and max of 65535
36
+ # formated by %d
37
+ {
38
+ :name => 'Port',
39
+ :type => 'range',
40
+ :scale => '3rt',
41
+ :min => 0,
42
+ :max => 65535,
43
+ :ofmt => '%d',
44
+ :items => [1,22,80,137,443,1024,5900,6667,31337,65335]
45
+ },
46
+ # the second axes is called "Host", contains a list of items.
47
+ {
48
+ :name => 'Host',
49
+ :type => 'list',
50
+ :list => ['192.168.0.1','192.168.0.4','192.168.0.2','192.168.0.3']
51
+ }
52
+ ]
53
+ # create the parallel coordinates frame
54
+ pcp = Tk::ParallelCoordinates.new(left_frame, 500, 360, model)
55
+ # add items to the parallel coordinates frame
56
+ [[53,'192.168.0.1'],[53,'192.168.0.2'],[80,'192.168.0.2'],[43099,'192.168.0.3']].each do |t|
57
+ pcp.addtuple(t)
58
+ end
59
+ # install the select callback
60
+ pcp.set_select_cb(TkPC_Callback.new)
61
+ # enter the Tk mainloop
62
+ Tk.mainloop()
63
+ end
64
+ end
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'tk/parallelcoordinates/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "tk-parallelcoordinates"
8
+ spec.version = Tk::ParallelCoordinates::VERSION
9
+ spec.summary = %q{A Parallel Coordinates widget for Tk}
10
+ spec.description = %q{This provides a rich Tk widget for displaying data across multiple axes with scaling.}
11
+ spec.email = ["rubygems@chrislee.dhs.org"]
12
+ spec.authors = ["chrislee35"]
13
+ spec.homepage = "https://rubyspecs.org/specs/tk-parallelcoordinates"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+
24
+ # spec.add_runtime_dependency "tk"
25
+
26
+ #spec.signing_key = "#{File.dirname(__FILE__)}/../gem-private_key.pem"
27
+ #spec.cert_chain = ["#{File.dirname(__FILE__)}/../gem-public_cert.pem"]
28
+ spec.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
29
+ end
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tk-parallelcoordinates
3
+ version: !ruby/object:Gem::Version
4
+ hash: 25
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 1
10
+ version: 0.1.1
11
+ platform: ruby
12
+ authors:
13
+ - chrislee35
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2013-05-10 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: bundler
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ hash: 9
29
+ segments:
30
+ - 1
31
+ - 3
32
+ version: "1.3"
33
+ type: :development
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: rake
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :development
48
+ version_requirements: *id002
49
+ description: This provides a rich Tk widget for displaying data across multiple axes with scaling.
50
+ email:
51
+ - rubygems@chrislee.dhs.org
52
+ executables: []
53
+
54
+ extensions: []
55
+
56
+ extra_rdoc_files: []
57
+
58
+ files:
59
+ - .gitignore
60
+ - Gemfile
61
+ - Gemfile.lock
62
+ - LICENSE.txt
63
+ - README.md
64
+ - Rakefile
65
+ - VERSION
66
+ - lib/tk/parallelcoordinates.rb
67
+ - lib/tk/parallelcoordinates/version.rb
68
+ - test/helper.rb
69
+ - test/test_tk-parallelcoordinates.rb
70
+ - tk-parallelcoordinates.gemspec
71
+ homepage: https://rubyspecs.org/specs/tk-parallelcoordinates
72
+ licenses:
73
+ - MIT
74
+ post_install_message:
75
+ rdoc_options: []
76
+
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ none: false
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ hash: 3
85
+ segments:
86
+ - 0
87
+ version: "0"
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ hash: 3
94
+ segments:
95
+ - 0
96
+ version: "0"
97
+ requirements: []
98
+
99
+ rubyforge_project:
100
+ rubygems_version: 1.8.25
101
+ signing_key:
102
+ specification_version: 3
103
+ summary: A Parallel Coordinates widget for Tk
104
+ test_files:
105
+ - test/helper.rb
106
+ - test/test_tk-parallelcoordinates.rb