grapht 0.1.6 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: adef126a08ae6cb39155222993129db005f510e7
4
- data.tar.gz: 82e6e783ee8f20bbd2b35860981080e9b2694dc1
3
+ metadata.gz: 1c81c4cd2f0ae2bead5fae5316a8f4143a81a5f7
4
+ data.tar.gz: bbfcabd60418b98db230be8ee8a2b4d374fc1359
5
5
  SHA512:
6
- metadata.gz: e766ffdae1d35882a7493ac5c83296a864c2b21568bd5c525947b1bcf2beb2c8d2c8c2286d9e16d68696346ce8eb8910f21b766bf81f5d114995d6ed7159ea8d
7
- data.tar.gz: cd0b67ebf3bf5da3ec4b55b38fcf615a697477556da11dca440abd17be9cb1365f9fd80a004e8616c43b944ab4c48bfdd8e5947ef5f8eb8d9e0c4d9616394d7c
6
+ metadata.gz: 746748c55ed22100d08010c4ce3c48fe1339a2af7d03d57ba7ce9bacdc8290be16ab56d9d7bf12b3f618ab39ef6df98b48f844ed5cbc160fc91fe836f0010afb
7
+ data.tar.gz: 1a864c3901bf0d638db817c969ba69e437e979b9398cf3342d63a60301cb4dd56020bf384b6d46a5965bf7366a1620221d860de999846bee8071f3a2c5842743
@@ -0,0 +1,22 @@
1
+ language: ruby
2
+ cache: bundler
3
+ rvm:
4
+ - 1.9.2
5
+ - 1.9.3
6
+ - 2.0.0
7
+ - 2.1.0
8
+ - 2.1.1
9
+ - ruby-head
10
+ - rbx-2
11
+ matrix:
12
+ include:
13
+ - rvm: jruby-18mode
14
+ env: JRUBY_OPTS="$JRUBY_OPTS --debug"
15
+ - rvm: jruby-19mode
16
+ env: JRUBY_OPTS="$JRUBY_OPTS --debug"
17
+ - rvm: jruby-head
18
+ env: JRUBY_OPTS="$JRUBY_OPTS --debug"
19
+ allow_failures:
20
+ - rvm: ruby-head
21
+ - rvm: jruby-head
22
+ fast_finish: true
data/Gemfile CHANGED
@@ -1,6 +1,2 @@
1
- source 'https://rubygems.org'
2
- ruby '2.0.0'
3
-
4
- group :test do
5
- gem 'rspec'
6
- end
1
+ source 'https://rubygems.org'
2
+ gemspec
data/README.md CHANGED
@@ -2,6 +2,9 @@
2
2
 
3
3
  # Grapht
4
4
 
5
+ [![Build Status](http://img.shields.io/travis/trade-informatics/grapht.svg?style=flat)](https://travis-ci.org/trade-informatics/grapht)
6
+ [![Gem Version](http://img.shields.io/gem/v/grapht.svg?style=flat)](https://rubygems.org/gems/grapht)
7
+
5
8
  Grapht is a server-side graphing library built on [PhantomJS](https://github.com/ariya/phantomjs/wiki)
6
9
  and utilizing [D3.js](http://d3js.org/). Grapht provides a CLI for simple Bash scripting.
7
10
  It also profides a light-weight [Ruby](https://www.ruby-lang.org/en/)
@@ -65,81 +68,87 @@ Grapht provides a CLI, accessed using the `bin/grapht` command. The basic invoc
65
68
  requires one argument specifying the desired graph type, and a JSON string provided
66
69
  via `STDIN`. For example, if we want a **horizontal bar graph**:
67
70
 
68
- bin/grapht bar-horizontal < ~/my-data.json
71
+ ```bash
72
+ bin/grapht bar-horizontal < ~/my-data.json
73
+ ```
69
74
 
70
75
  The result will be a string of **svg** markup:
71
76
 
72
- <svg width="200" height="200">
73
- <rect class="bar" x="0" y="13" width="0" height="50"></rect>
74
- <rect class="bar" x="0" y="75" width="200" height="50"></rect>
75
- <rect class="bar" x="0" y="137" width="150" height="50"></rect>
76
- <g class="x axis" transform="translate(0,200)">
77
- <g class="tick" style="opacity: 1; " transform="translate(0,0)">
78
- <line y2="-200" x2="0"></line>
79
- <text y="3" x="0" dy=".71em" style="text-anchor: middle; ">20</text>
80
- </g>
81
- <g class="tick" style="opacity: 1; " transform="translate(20,0)">
82
- <line y2="-200" x2="0"></line>
83
- <text y="3" x="0" dy=".71em" style="text-anchor: middle; ">22</text>
84
- </g>
85
- <g class="tick" style="opacity: 1; " transform="translate(40,0)">
86
- <line y2="-200" x2="0"></line>
87
- <text y="3" x="0" dy=".71em" style="text-anchor: middle; ">24</text>
88
- </g>
89
- <g class="tick" style="opacity: 1; " transform="translate(60.00000000000001,0)">
90
- <line y2="-200" x2="0"></line>
91
- <text y="3" x="0" dy=".71em" style="text-anchor: middle; ">26</text>
92
- </g>
93
- <g class="tick" style="opacity: 1; " transform="translate(80,0)">
94
- <line y2="-200" x2="0"></line>
95
- <text y="3" x="0" dy=".71em" style="text-anchor: middle; ">28</text>
96
- </g>
97
- <g class="tick" style="opacity: 1; " transform="translate(100,0)">
98
- <line y2="-200" x2="0"></line>
99
- <text y="3" x="0" dy=".71em" style="text-anchor: middle; ">30</text>
100
- </g>
101
- <g class="tick" style="opacity: 1; " transform="translate(120.00000000000001,0)">
102
- <line y2="-200" x2="0"></line>
103
- <text y="3" x="0" dy=".71em" style="text-anchor: middle; ">32</text>
104
- </g>
105
- <g class="tick" style="opacity: 1; " transform="translate(140,0)">
106
- <line y2="-200" x2="0"></line>
107
- <text y="3" x="0" dy=".71em" style="text-anchor: middle; ">34</text>
108
- </g>
109
- <g class="tick" style="opacity: 1; " transform="translate(160,0)">
110
- <line y2="-200" x2="0"></line>
111
- <text y="3" x="0" dy=".71em" style="text-anchor: middle; ">36</text>
112
- </g>
113
- <g class="tick" style="opacity: 1; " transform="translate(180,0)">
114
- <line y2="-200" x2="0"></line>
115
- <text y="3" x="0" dy=".71em" style="text-anchor: middle; ">38</text>
116
- </g>
117
- <g class="tick" style="opacity: 1; " transform="translate(200,0)">
118
- <line y2="-200" x2="0"></line>
119
- <text y="3" x="0" dy=".71em" style="text-anchor: middle; ">40</text>
120
- </g>
121
- <path class="domain" d="M0,-200V0H200V-200"></path>
122
- </g>
123
- <g class="y axis">
124
- <g class="tick" style="opacity: 1; " transform="translate(0,38)">
125
- <line x2="6" y2="0"></line>
126
- <text x="9" y="0" dy=".32em" style="text-anchor: start; ">foo</text>
127
- </g>
128
- <g class="tick" style="opacity: 1; " transform="translate(0,100)">
129
- <line x2="6" y2="0"></line>
130
- <text x="9" y="0" dy=".32em" style="text-anchor: start; ">bar</text>
131
- </g>
132
- <g class="tick" style="opacity: 1; " transform="translate(0,162)">
133
- <line x2="6" y2="0"></line>
134
- <text x="9" y="0" dy=".32em" style="text-anchor: start; ">baz</text>
135
- </g>
136
- <path class="domain" d="M6,0H0V200H6"></path>
137
- </g>
138
- </svg>
77
+ ```html
78
+ <svg width="200" height="200">
79
+ <rect class="bar" x="0" y="13" width="0" height="50"></rect>
80
+ <rect class="bar" x="0" y="75" width="200" height="50"></rect>
81
+ <rect class="bar" x="0" y="137" width="150" height="50"></rect>
82
+ <g class="x axis" transform="translate(0,200)">
83
+ <g class="tick" style="opacity: 1; " transform="translate(0,0)">
84
+ <line y2="-200" x2="0"></line>
85
+ <text y="3" x="0" dy=".71em" style="text-anchor: middle; ">20</text>
86
+ </g>
87
+ <g class="tick" style="opacity: 1; " transform="translate(20,0)">
88
+ <line y2="-200" x2="0"></line>
89
+ <text y="3" x="0" dy=".71em" style="text-anchor: middle; ">22</text>
90
+ </g>
91
+ <g class="tick" style="opacity: 1; " transform="translate(40,0)">
92
+ <line y2="-200" x2="0"></line>
93
+ <text y="3" x="0" dy=".71em" style="text-anchor: middle; ">24</text>
94
+ </g>
95
+ <g class="tick" style="opacity: 1; " transform="translate(60.00000000000001,0)">
96
+ <line y2="-200" x2="0"></line>
97
+ <text y="3" x="0" dy=".71em" style="text-anchor: middle; ">26</text>
98
+ </g>
99
+ <g class="tick" style="opacity: 1; " transform="translate(80,0)">
100
+ <line y2="-200" x2="0"></line>
101
+ <text y="3" x="0" dy=".71em" style="text-anchor: middle; ">28</text>
102
+ </g>
103
+ <g class="tick" style="opacity: 1; " transform="translate(100,0)">
104
+ <line y2="-200" x2="0"></line>
105
+ <text y="3" x="0" dy=".71em" style="text-anchor: middle; ">30</text>
106
+ </g>
107
+ <g class="tick" style="opacity: 1; " transform="translate(120.00000000000001,0)">
108
+ <line y2="-200" x2="0"></line>
109
+ <text y="3" x="0" dy=".71em" style="text-anchor: middle; ">32</text>
110
+ </g>
111
+ <g class="tick" style="opacity: 1; " transform="translate(140,0)">
112
+ <line y2="-200" x2="0"></line>
113
+ <text y="3" x="0" dy=".71em" style="text-anchor: middle; ">34</text>
114
+ </g>
115
+ <g class="tick" style="opacity: 1; " transform="translate(160,0)">
116
+ <line y2="-200" x2="0"></line>
117
+ <text y="3" x="0" dy=".71em" style="text-anchor: middle; ">36</text>
118
+ </g>
119
+ <g class="tick" style="opacity: 1; " transform="translate(180,0)">
120
+ <line y2="-200" x2="0"></line>
121
+ <text y="3" x="0" dy=".71em" style="text-anchor: middle; ">38</text>
122
+ </g>
123
+ <g class="tick" style="opacity: 1; " transform="translate(200,0)">
124
+ <line y2="-200" x2="0"></line>
125
+ <text y="3" x="0" dy=".71em" style="text-anchor: middle; ">40</text>
126
+ </g>
127
+ <path class="domain" d="M0,-200V0H200V-200"></path>
128
+ </g>
129
+ <g class="y axis">
130
+ <g class="tick" style="opacity: 1; " transform="translate(0,38)">
131
+ <line x2="6" y2="0"></line>
132
+ <text x="9" y="0" dy=".32em" style="text-anchor: start; ">foo</text>
133
+ </g>
134
+ <g class="tick" style="opacity: 1; " transform="translate(0,100)">
135
+ <line x2="6" y2="0"></line>
136
+ <text x="9" y="0" dy=".32em" style="text-anchor: start; ">bar</text>
137
+ </g>
138
+ <g class="tick" style="opacity: 1; " transform="translate(0,162)">
139
+ <line x2="6" y2="0"></line>
140
+ <text x="9" y="0" dy=".32em" style="text-anchor: start; ">baz</text>
141
+ </g>
142
+ <path class="domain" d="M6,0H0V200H6"></path>
143
+ </g>
144
+ </svg>
145
+ ```
139
146
 
140
147
  ### Usage
141
148
 
142
- bin/grapht GRAPH_TYPE [options] < JSON_INPUT
149
+ ```bash
150
+ bin/grapht GRAPH_TYPE [options] < JSON_INPUT
151
+ ```
143
152
 
144
153
  ### Options
145
154
 
@@ -167,9 +176,11 @@ Currently supported flags:
167
176
  To generate the same **horizontal bar graph** generated in the CLI
168
177
  section--using the Ruby API--we can do the following:
169
178
 
170
- json = "[{ \"name\": \"foo\", \"value\": 20 },{ \"name\": \"bar\", \"value\": 40 },{ \"name\": \"baz\", \"value\": 35 }]"
171
- type = Grapht::Type::BAR_HORIZONTAL
172
- graph = Grapht::Shell.exec type, json
179
+ ```ruby
180
+ json = "[{ \"name\": \"foo\", \"value\": 20 },{ \"name\": \"bar\", \"value\": 40 },{ \"name\": \"baz\", \"value\": 35 }]"
181
+ type = Grapht::Type::BAR_HORIZONTAL
182
+ graph = Grapht::Shell.exec type, json
183
+ ```
173
184
 
174
185
  ## Supported Graphs
175
186
 
@@ -191,8 +202,10 @@ For example, if we have our custom definitions stored in
191
202
  `~/Development/my_project/my_graph_defs`, we set our environment variable to this
192
203
  path:
193
204
 
194
- export EXT_GRAPHT_DEFINITIONS_HOME=~/Development/my_project/my_graph_defs
195
- bin/grapht my-scatterplot < ~/my-data.json
205
+ ```bash
206
+ export EXT_GRAPHT_DEFINITIONS_HOME=~/Development/my_project/my_graph_defs
207
+ bin/grapht my-scatterplot < ~/my-data.json
208
+ ```
196
209
 
197
210
  In the example above, we supply the name of our new graph definition
198
211
  (`my-scatterplot`) to the Grapht CLI. Grapht will first look in
@@ -209,17 +222,19 @@ All graph definitions must comply with a short set of rules:
209
222
 
210
223
  Here's an example of a valid graph definition:
211
224
 
212
- function(data) { // <- our wrapper fuction
213
- var width = 200,
214
- height = 200;
225
+ ```javascript
226
+ function(data) { // <- our wrapper fuction
227
+ var width = 200,
228
+ height = 200;
215
229
 
216
- // our single root node added to document.body
217
- var svg = d3.select("body").append("svg")
218
- .attr("width", width)
219
- .attr("height", height);
230
+ // our single root node added to document.body
231
+ var svg = d3.select("body").append("svg")
232
+ .attr("width", width)
233
+ .attr("height", height);
220
234
 
221
- // a bunch of D3 operations on svg...
222
- }
235
+ // a bunch of D3 operations on svg...
236
+ }
237
+ ```
223
238
 
224
239
  ## Error Handling
225
240
 
@@ -245,11 +260,14 @@ While Rails integration is not scripted by the Grapht library, it is quite
245
260
  simple to integrate. The following steps are all that is required for integration:
246
261
 
247
262
  - Add the following to your `Gemfile`:
248
- <pre>gem 'grapht', git: 'https://github.com/ibpinc/grapht.git'</pre>
263
+ ```ruby
264
+ gem 'grapht'
265
+ ```
249
266
  - In the Rails `app` directory, create a directory named `graph-definitions`
250
267
  - Create the file `config/initializers/grapht.rb`. In the file add the following:
251
- <pre>ENV['EXT_GRAPHT_DEFINITIONS_HOME'] =
252
- Rails.root.join('app/graph-definitions')</pre>
268
+ ```ruby
269
+ ENV['EXT_GRAPHT_DEFINITIONS_HOME'] = Rails.root.join('app/graph-definitions')
270
+ ```
253
271
  - Place all user-defined graph definitions in the `app/graph-definitions`
254
272
 
255
273
  ## Contributing
data/Rakefile CHANGED
@@ -1 +1,7 @@
1
1
  require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
7
+
@@ -19,6 +19,6 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rspec", "~> 3.0"
22
23
  spec.add_development_dependency "rake"
23
- spec.add_development_dependency "rspec"
24
24
  end
@@ -10,7 +10,9 @@ module Grapht
10
10
  def self.exec(type, json_data, options={})
11
11
  options = *options.select { |k,v| ALLOWED_OPTIONS.include? k }.flatten
12
12
 
13
- out, err, status = Open3.capture3 CMD, type, *options, stdin_data: json_data
13
+ out, err, status =
14
+ Open3.capture3 CMD, type, *options, stdin_data: json_data, binmode: true
15
+
14
16
  raise Grapht::Shell::Error, err unless status.success?
15
17
  out
16
18
  end
@@ -1,5 +1,8 @@
1
1
  module Grapht
2
2
  module Type
3
- BAR_HORIZONTAL = 'bar-horizontal'
3
+ BAR_HORIZONTAL = 'bar-horizontal'
4
+ BAR_VERTICAL = 'bar-vertical'
5
+ DONUT = 'donut'
6
+ LINE = 'line'
4
7
  end
5
8
  end
@@ -1,3 +1,3 @@
1
1
  module Grapht
2
- VERSION = "0.1.6"
2
+ VERSION = "0.1.7"
3
3
  end
@@ -11,6 +11,7 @@ defsPath = "#{scriptPath}../lib/graph-definitions/"
11
11
  userDefsPath = system.env['EXT_GRAPHT_DEFINITIONS_HOME']
12
12
  dependencies = ['d3.min.js', 'json2.js']
13
13
  niceDirPathRX = /\/$|$/
14
+ naughtyPathRX = /(?:\.{1,2}\/)+/
14
15
 
15
16
  # -----------------------------------------------------------------------------
16
17
  # Helper Functions
@@ -28,10 +29,20 @@ fns =
28
29
 
29
30
  phantom.exit(1)
30
31
 
32
+ # Scrubs-out any leading '/' characters from the type, and raises an error
33
+ # if any naughtier path manipulation is detected.
34
+ sanitizeType: (type) ->
35
+ if naughtyPathRX.test(type)
36
+ @logError "Naughty! There will be no backing out of the definition directory!"
37
+
38
+ type.replace(/^\/+/, '')
39
+
31
40
  # Searchs for a valid graph definition in the supplied definition paths. If
32
41
  # no definition is found, we log an error to STDERR and exit with an exitcode
33
42
  # of 1.
34
43
  findDef: (type, defPaths...) ->
44
+ type = @sanitizeType(type)
45
+
35
46
  for dir in defPaths when dir?
36
47
  dir = dir.replace(niceDirPathRX, '/')
37
48
  path = "#{dir}#{type}.js"
@@ -84,7 +95,9 @@ fns =
84
95
  # Configure the page context.
85
96
  page.libraryPath = vendorPath
86
97
  page.onError = fns.logError
87
- dependencies.forEach (dp) -> page.injectJs(dp) || Helper.logError "could not load #{dp}!"
98
+
99
+ dependencies.forEach (dp) ->
100
+ page.injectJs(dp) || fns.logError "could not load #{dp}!"
88
101
 
89
102
  # load and evaluate the graph definition within the context of the JSON, supplied
90
103
  # via STDIN.
@@ -23,11 +23,33 @@ describe Grapht::Shell do
23
23
  context 'when given an unknown type' do
24
24
  let(:type) { 'some-invalid-graph-type' }
25
25
 
26
- it "should raise a Grapht::Shell:Error" do
26
+ it "should raise a Grapht::Shell::Error" do
27
27
  expect { subject }.to raise_error(Grapht::Shell::Error, /No graph definition could be found/)
28
28
  end
29
29
  end
30
30
 
31
+ context 'when a known type is provided with a leading forward-slash' do
32
+ let(:type) { "/#{Grapht::Type::BAR_HORIZONTAL}" }
33
+ it { should match(/^<svg/) }
34
+ end
35
+
36
+ context 'when a naughty types are provided' do
37
+ [ "../buck-wild/corn-dogs",
38
+ "../../born-wild/chicken-skin",
39
+ "innocent-path/../../rootpath"
40
+ ].each do |path|
41
+ context "for path: '#{path}'" do
42
+ let(:type) { path }
43
+
44
+ it 'should raise a Grapht::Shell::Error' do
45
+ expect { subject }.to raise_error(
46
+ Grapht::Shell::Error,
47
+ /Naughty! There will be no backing out of the definition directory!/)
48
+ end
49
+ end
50
+ end
51
+ end
52
+
31
53
  context 'when well-formed data is provided' do
32
54
  it { should match(/^<svg/) }
33
55
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grapht
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Lowrimore
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-11 00:00:00.000000000 Z
11
+ date: 2014-08-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -25,21 +25,21 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.3'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: rspec
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ~>
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: '3.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ~>
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: '3.0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: rspec
42
+ name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - '>='
@@ -64,8 +64,8 @@ extra_rdoc_files: []
64
64
  files:
65
65
  - .gitignore
66
66
  - .rspec
67
+ - .travis.yml
67
68
  - Gemfile
68
- - Gemfile.lock
69
69
  - LICENSE.txt
70
70
  - README.md
71
71
  - Rakefile