tufted-rails 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +7 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/README.md +80 -0
- data/Rakefile +48 -0
- data/lib/tufted-rails.rb +12 -0
- data/lib/tufted-rails/engine.rb +6 -0
- data/lib/tufted-rails/railtie.rb +5 -0
- data/lib/tufted-rails/version.rb +5 -0
- data/tufted-rails.gemspec +22 -0
- data/vendor/assets/javascripts/tufted-rails/index.js +1 -0
- data/vendor/assets/javascripts/tufted-rails/tufted.js +760 -0
- data/vendor/assets/stylesheets/tufted-rails/index.css +3 -0
- data/vendor/assets/stylesheets/tufted-rails/tufted.css +70 -0
- metadata +130 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 327ac673e02c42119ebc487a18d4740b30decf8a
|
4
|
+
data.tar.gz: b673f2c19b52377868953f287819a4ae47b9e698
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 849416507e5bb5270aa9b0d34255b062440deaea05c60abc77c2ec0dd18d4c299ca274d63057e658b245bb15c21564e020f90ada26cc670cc585741bb010c34d
|
7
|
+
data.tar.gz: d89ec405fe9436e3f37abea8bfcfe649c237757e5222123f213e3307756154694a10c1dc290023d12b2a4b5f2b3258e75f5400eade48f5f892c4dab5e3517339
|
data/.gitignore
ADDED
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
tufted-rails
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby-2.0.0-p247
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
# Tufted JS for Rails
|
2
|
+
|
3
|
+
### Terse D3 Charts
|
4
|
+
|
5
|
+
tufted-rails integrates [Tufted.js][tufted] by [allthesignals](https://github.com/allthesignals) with the Rails 3 assets pipeline.
|
6
|
+
|
7
|
+
[tufted]: https://github.com/MAPC/tufted.js
|
8
|
+
|
9
|
+
http://github.com/mapc/tufted-rails
|
10
|
+
|
11
|
+
http://github.com/mapc/tufted.js
|
12
|
+
|
13
|
+
## Rails > 3.1
|
14
|
+
|
15
|
+
Include tufted-rails in Gemfile:
|
16
|
+
|
17
|
+
``` ruby
|
18
|
+
gem 'tufted-rails'
|
19
|
+
```
|
20
|
+
|
21
|
+
or you can install from latest build:
|
22
|
+
|
23
|
+
``` ruby
|
24
|
+
gem 'tufted-rails', require: 'tufted-rails',
|
25
|
+
git: 'git://github.com/mapc/tufted-rails.git'
|
26
|
+
```
|
27
|
+
|
28
|
+
and run `bundle install`.
|
29
|
+
|
30
|
+
|
31
|
+
## Setup with Rails
|
32
|
+
|
33
|
+
Add this line to `app/assets/javascripts/application.js`
|
34
|
+
|
35
|
+
```javascript
|
36
|
+
//= require tufted-rails
|
37
|
+
```
|
38
|
+
|
39
|
+
Add the following line to `app/assets/stylesheets/application.css` to get a simple styling.
|
40
|
+
|
41
|
+
|
42
|
+
```css
|
43
|
+
*= require tufted-rails
|
44
|
+
```
|
45
|
+
|
46
|
+
## Using tufted-rails
|
47
|
+
|
48
|
+
To come. We're still preparing the final build and the website.
|
49
|
+
|
50
|
+
|
51
|
+
## Contributing
|
52
|
+
|
53
|
+
Feel free to add issues to this repository if you find a bug or would like a feature.
|
54
|
+
|
55
|
+
To contribute code, fork this repository and issue a pull request.
|
56
|
+
|
57
|
+
|
58
|
+
## License
|
59
|
+
|
60
|
+
The MIT License (MIT)
|
61
|
+
|
62
|
+
Copyright (c) 2014 Metropolitan Area Planning Council
|
63
|
+
|
64
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
65
|
+
of this software and associated documentation files (the "Software"), to deal
|
66
|
+
in the Software without restriction, including without limitation the rights
|
67
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
68
|
+
copies of the Software, and to permit persons to whom the Software is
|
69
|
+
furnished to do so, subject to the following conditions:
|
70
|
+
|
71
|
+
The above copyright notice and this permission notice shall be included in all
|
72
|
+
copies or substantial portions of the Software.
|
73
|
+
|
74
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
75
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
76
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
77
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
78
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
79
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
80
|
+
SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require File.expand_path('../lib/tufted-rails/version', __FILE__)
|
5
|
+
|
6
|
+
desc "Update assets"
|
7
|
+
task :update do
|
8
|
+
if Dir.exist?('tufted-src')
|
9
|
+
system("cd tufted-src && git pull && cd ..")
|
10
|
+
else
|
11
|
+
system("git clone git@github.com:MAPC/tufted.js.git tufted-src")
|
12
|
+
end
|
13
|
+
|
14
|
+
if Dir.exist?('tufted-css-src')
|
15
|
+
system("cd tufted-css-src && git pull && cd ..")
|
16
|
+
else
|
17
|
+
system("git clone git@github.com:MAPC/tufted.js-tufted.css.git tufted-css-src")
|
18
|
+
end
|
19
|
+
|
20
|
+
# Copy Javascript into vendor/assets
|
21
|
+
system("cp tufted-src/tufted.js vendor/assets/javascripts/tufted-rails/tufted.js")
|
22
|
+
|
23
|
+
# Copy stylesheet into vendor/assets
|
24
|
+
system("cp tufted-css-src/tufted.css vendor/assets/stylesheets/tufted-rails/tufted.css")
|
25
|
+
|
26
|
+
system("git status")
|
27
|
+
|
28
|
+
puts "\n"
|
29
|
+
puts "tufted.js version: #{JSON.parse(File.read('./tufted-src/package.json'))['version']}"
|
30
|
+
puts "tufted-rails version: #{TuftedRails::Rails::VERSION}"
|
31
|
+
end
|
32
|
+
|
33
|
+
desc "Build"
|
34
|
+
task "build" do
|
35
|
+
system("gem build tufted-rails.gemspec")
|
36
|
+
end
|
37
|
+
|
38
|
+
desc "Build and publish the gem"
|
39
|
+
task :publish => :build do
|
40
|
+
tags = `git tag`.split
|
41
|
+
current_version = TuftedRails::Rails::VERSION
|
42
|
+
system("git tag -a #{current_version} -m 'Release #{current_version}'") unless tags.include?(current_version)
|
43
|
+
system("gem push tufted-rails-#{current_version}.gem")
|
44
|
+
system("git push --follow-tags")
|
45
|
+
end
|
46
|
+
|
47
|
+
task :release => :publish do
|
48
|
+
end
|
data/lib/tufted-rails.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/tufted-rails/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Matt Cloyd", "W. Matt Gardner"]
|
6
|
+
gem.email = ["mcloyd@gmail.com"]
|
7
|
+
gem.description = "Terse D3 Charts for Rails"
|
8
|
+
gem.homepage = "https://github.com/mapc/tufted-rails"
|
9
|
+
gem.summary = "Load Tufted.js (by allthesignals) into Rails asset pipeline"
|
10
|
+
gem.license = 'MIT'
|
11
|
+
|
12
|
+
gem.name = "tufted-rails"
|
13
|
+
gem.require_paths = ["lib"]
|
14
|
+
gem.files = `git ls-files`.split("\n").reject { |i| i=~/testapp/}
|
15
|
+
gem.version = TuftedRails::Rails::VERSION
|
16
|
+
|
17
|
+
gem.add_dependency "railties", ">= 3.0"
|
18
|
+
gem.add_development_dependency "bundler", ">= 1.0"
|
19
|
+
gem.add_development_dependency "rake"
|
20
|
+
gem.add_development_dependency "pry"
|
21
|
+
gem.add_development_dependency "json"
|
22
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
//= require ./tufted
|
@@ -0,0 +1,760 @@
|
|
1
|
+
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
2
|
+
var basechart = require('./lib/baseChart');
|
3
|
+
var barchart = require('./lib/barChart');
|
4
|
+
var groupedbarchart = require('./lib/groupedBarChart');
|
5
|
+
var linechart = require('./lib/lineChart');
|
6
|
+
var stackedbarchart = require('./lib/stackedBarChart');
|
7
|
+
|
8
|
+
module.exports = {
|
9
|
+
basechart: basechart,
|
10
|
+
barchart: barchart,
|
11
|
+
groupedbarchart: groupedbarchart,
|
12
|
+
linechart: linechart,
|
13
|
+
stackedbarchart: stackedbarchart
|
14
|
+
}
|
15
|
+
},{"./lib/barChart":2,"./lib/baseChart":3,"./lib/groupedBarChart":4,"./lib/lineChart":5,"./lib/stackedBarChart":6}],2:[function(require,module,exports){
|
16
|
+
d3.chart("BaseChart").extend("BarChart", {
|
17
|
+
|
18
|
+
initialize: function() {
|
19
|
+
var chart = this;
|
20
|
+
|
21
|
+
chart.xScale = d3.scale.ordinal().rangeRoundBands([0, chart.width()], 0.1);
|
22
|
+
chart.yScale = d3.scale.linear().range([chart.height(), 0]);
|
23
|
+
chart.color = d3.scale.category10();
|
24
|
+
chart.duration = 500;
|
25
|
+
|
26
|
+
chart.on('change:width', function(newWidth) {
|
27
|
+
chart.xScale.rangeRoundBands([0, newWidth], 0.1);
|
28
|
+
});
|
29
|
+
|
30
|
+
chart.on('change:height', function(newHeight) {
|
31
|
+
chart.yScale.range([newHeight, 0]);
|
32
|
+
});
|
33
|
+
|
34
|
+
chart.areas = {};
|
35
|
+
|
36
|
+
chart.layers = {};
|
37
|
+
|
38
|
+
chart.areas.yAxisLayer = chart.base.select('g').append('g')
|
39
|
+
.classed('ylabels', true)
|
40
|
+
|
41
|
+
chart.layers.bars = chart.base.select('g').append('g')
|
42
|
+
.classed('bars', true)
|
43
|
+
|
44
|
+
// create a layer of circles that will go into
|
45
|
+
// a new group element on the base of the chart
|
46
|
+
chart.layer('bars', chart.layers.bars, {
|
47
|
+
|
48
|
+
// select the elements we wish to bind to and
|
49
|
+
// bind the data to them.
|
50
|
+
dataBind: function(data) {
|
51
|
+
|
52
|
+
var yAxis = d3.svg.axis()
|
53
|
+
.scale(chart.yScale)
|
54
|
+
.tickSize(-(chart.width()), 0, 0)
|
55
|
+
.orient("left")
|
56
|
+
.tickFormat(d3.format(".2s"));
|
57
|
+
|
58
|
+
chart.areas.yAxisLayer
|
59
|
+
.call(yAxis)
|
60
|
+
.append("text")
|
61
|
+
.attr("transform", "rotate(-90)")
|
62
|
+
.attr("y", -35)
|
63
|
+
.attr("dy", ".71em")
|
64
|
+
.style("text-anchor", "end")
|
65
|
+
.text("Percent");
|
66
|
+
|
67
|
+
var xAxis = d3.svg.axis()
|
68
|
+
.scale(chart.xScale)
|
69
|
+
.orient("bottom");
|
70
|
+
|
71
|
+
chart.base.select('g').append('g')
|
72
|
+
.classed('x axis',true)
|
73
|
+
.attr("transform", "translate(0," + chart.height() + ")")
|
74
|
+
.call(xAxis)
|
75
|
+
.selectAll("text")
|
76
|
+
.call(chart.wrap, 50)
|
77
|
+
|
78
|
+
return this.selectAll('.bar')
|
79
|
+
.data(data);
|
80
|
+
},
|
81
|
+
|
82
|
+
// insert actual rects
|
83
|
+
insert: function() {
|
84
|
+
return this.append('rect')
|
85
|
+
.attr('class', function(d,i){
|
86
|
+
return "bar-" + i;
|
87
|
+
});
|
88
|
+
},
|
89
|
+
|
90
|
+
|
91
|
+
// define lifecycle events
|
92
|
+
events: {
|
93
|
+
'enter': function() {
|
94
|
+
var chart = this.chart();
|
95
|
+
|
96
|
+
this.attr('x', function(d) { return chart.xScale(d.name); })
|
97
|
+
.attr("title", function(d) { return d.name })
|
98
|
+
.attr("data-content", function(d) { return "Estimate: " + d.value + '%' })
|
99
|
+
.attr('y', function(d) { return chart.yScale(0); })
|
100
|
+
.attr('fill', function(d) {return chart.color(d.name);})
|
101
|
+
.attr('width', chart.xScale.rangeBand())
|
102
|
+
.attr('height', 0);
|
103
|
+
},
|
104
|
+
|
105
|
+
'enter:transition': function() {
|
106
|
+
var chart = this.chart();
|
107
|
+
|
108
|
+
this.duration(chart.duration)
|
109
|
+
.attr('y', function(d) { return chart.yScale(d3.max([0, d.value])); })
|
110
|
+
.attr('height', function(d) { return Math.abs(chart.yScale(d.value) - chart.yScale(0)); });
|
111
|
+
|
112
|
+
$(document).ready(function () {
|
113
|
+
$("svg rect").popover({
|
114
|
+
'container': 'body',
|
115
|
+
'placement': 'right',
|
116
|
+
'trigger': 'hover',
|
117
|
+
'html': true
|
118
|
+
});
|
119
|
+
});
|
120
|
+
}
|
121
|
+
}
|
122
|
+
});
|
123
|
+
|
124
|
+
|
125
|
+
|
126
|
+
},
|
127
|
+
// set/get the color to use for the circles as they are
|
128
|
+
// rendered.
|
129
|
+
transform: function(data) {
|
130
|
+
var chart = this;
|
131
|
+
|
132
|
+
// // update the scales
|
133
|
+
chart.xScale.domain(data.map(function(d) { return d.name; }));
|
134
|
+
chart.yScale.domain(d3.extent(data, function(d) {return d.value;}));
|
135
|
+
|
136
|
+
return data;
|
137
|
+
}
|
138
|
+
});
|
139
|
+
},{}],3:[function(require,module,exports){
|
140
|
+
d3.chart("BaseChart", {
|
141
|
+
|
142
|
+
initialize: function () {
|
143
|
+
this._margin = {top: 20, right: 20, bottom: 90, left: 40};
|
144
|
+
this._width = this.base.attr('width') ? this.base.attr('width') - this._margin.left - this._margin.right : 20;
|
145
|
+
this._height = this.base.attr('height') ? this.base.attr('height') - this._margin.top - this._margin.bottom : 20;
|
146
|
+
|
147
|
+
this.updateContainerWidth();
|
148
|
+
this.updateContainerHeight();
|
149
|
+
|
150
|
+
this.base.append('g')
|
151
|
+
.attr('transform', 'translate(' + this._margin.left + ',' + this._margin.top + ')');
|
152
|
+
},
|
153
|
+
|
154
|
+
updateContainerWidth: function() { this.base.attr('width', this._width + this._margin.left + this._margin.right); },
|
155
|
+
|
156
|
+
updateContainerHeight: function() { this.base.attr('height', this._height + this._margin.top + this._margin.bottom); },
|
157
|
+
|
158
|
+
width: function(newWidth) {
|
159
|
+
if (arguments.length === 0) {
|
160
|
+
return this._width;
|
161
|
+
}
|
162
|
+
|
163
|
+
// only if the width actually changed:
|
164
|
+
if (this._width !== newWidth) {
|
165
|
+
|
166
|
+
var oldWidth = this._width;
|
167
|
+
|
168
|
+
this._width = newWidth;
|
169
|
+
|
170
|
+
// set higher container width
|
171
|
+
this.updateContainerWidth();
|
172
|
+
|
173
|
+
// trigger a change event
|
174
|
+
this.trigger('change:width', newWidth, oldWidth);
|
175
|
+
}
|
176
|
+
|
177
|
+
// always return the chart, for chaining magic.
|
178
|
+
return this;
|
179
|
+
},
|
180
|
+
|
181
|
+
height: function(newHeight) {
|
182
|
+
if (arguments.length === 0) {
|
183
|
+
return this._height;
|
184
|
+
}
|
185
|
+
|
186
|
+
var oldHeight = this._height;
|
187
|
+
|
188
|
+
this._height = newHeight;
|
189
|
+
|
190
|
+
if (this._height !== oldHeight) {
|
191
|
+
|
192
|
+
this.updateContainerHeight();
|
193
|
+
|
194
|
+
this.trigger('change:height', newHeight, oldHeight);
|
195
|
+
}
|
196
|
+
|
197
|
+
return this;
|
198
|
+
},
|
199
|
+
|
200
|
+
parseDate: function(string) {
|
201
|
+
|
202
|
+
this.parseDate = d3.time.format("%Y").parse;
|
203
|
+
return this.parseDate(string);
|
204
|
+
},
|
205
|
+
|
206
|
+
wrap: function(text, width) {
|
207
|
+
text.each(function() {
|
208
|
+
var text = d3.select(this),
|
209
|
+
words = text.text().split(/\s+/).reverse(),
|
210
|
+
word,
|
211
|
+
line = [],
|
212
|
+
lineNumber = 0,
|
213
|
+
lineHeight = 1.1, // ems
|
214
|
+
y = text.attr("y"),
|
215
|
+
dy = parseFloat(text.attr("dy")),
|
216
|
+
tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
|
217
|
+
while (word = words.pop()) {
|
218
|
+
line.push(word);
|
219
|
+
tspan.text(line.join(" "));
|
220
|
+
if (tspan.node().getComputedTextLength() > width) {
|
221
|
+
line.pop();
|
222
|
+
tspan.text(line.join(" "));
|
223
|
+
line = [word];
|
224
|
+
tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
|
225
|
+
}
|
226
|
+
}
|
227
|
+
});
|
228
|
+
}
|
229
|
+
});
|
230
|
+
},{}],4:[function(require,module,exports){
|
231
|
+
d3.chart('BaseChart').extend('GroupedBarChart', {
|
232
|
+
initialize : function() {
|
233
|
+
var chart = this;
|
234
|
+
|
235
|
+
chart.xScale = d3.scale.ordinal()
|
236
|
+
.rangeRoundBands([0, chart.width()], 0.1);
|
237
|
+
chart.x1Scale = d3.scale.ordinal();
|
238
|
+
chart.yScale = d3.scale.linear()
|
239
|
+
.range([chart.height(), 0]);
|
240
|
+
chart.color = d3.scale.category10();
|
241
|
+
chart.duration = 500;
|
242
|
+
|
243
|
+
chart.yAxis = d3.svg.axis()
|
244
|
+
.scale(chart.yScale)
|
245
|
+
.tickSize(-chart.width(), 0, 0)
|
246
|
+
.orient("left")
|
247
|
+
.tickFormat(d3.format(".2s"));
|
248
|
+
|
249
|
+
chart.on("change:width", function(newWidth) {
|
250
|
+
chart.xScale.rangeRoundBands([0, newWidth], 0.1);
|
251
|
+
});
|
252
|
+
|
253
|
+
chart.on("change:height", function(newHeight) {
|
254
|
+
chart.yScale.range([newHeight, 0]);
|
255
|
+
});
|
256
|
+
|
257
|
+
|
258
|
+
chart.areas = {};
|
259
|
+
|
260
|
+
// cache for selections that are layer bases.
|
261
|
+
chart.layers = {};
|
262
|
+
|
263
|
+
chart.areas.yAxisLayer = chart.base.select('g').append('g')
|
264
|
+
.classed('ylabels', true)
|
265
|
+
|
266
|
+
// -- actual layers
|
267
|
+
chart.layers.bars = chart.base.select('g').append('g')
|
268
|
+
.classed('bars', true)
|
269
|
+
|
270
|
+
chart.layer('bars', chart.layers.bars, {
|
271
|
+
dataBind: function(data) {
|
272
|
+
var chart = this.chart();
|
273
|
+
|
274
|
+
var yAxis = d3.svg.axis()
|
275
|
+
.scale(chart.yScale)
|
276
|
+
.tickSize(-(chart.width()), 0, 0)
|
277
|
+
.orient("left")
|
278
|
+
.tickFormat(d3.format(".2s"));
|
279
|
+
|
280
|
+
chart.areas.yAxisLayer
|
281
|
+
.call(yAxis)
|
282
|
+
.append("text")
|
283
|
+
.attr("transform", "rotate(-90)")
|
284
|
+
.attr("y", -35)
|
285
|
+
.attr("dy", ".71em")
|
286
|
+
.style("text-anchor", "end")
|
287
|
+
.text("Percent");
|
288
|
+
|
289
|
+
var xAxis = d3.svg.axis()
|
290
|
+
.scale(chart.xScale)
|
291
|
+
.orient("bottom");
|
292
|
+
|
293
|
+
chart.base.select('g').append('g')
|
294
|
+
.classed('x axis', true)
|
295
|
+
.attr("transform", "translate(0," + chart.height() + ")")
|
296
|
+
.call(xAxis)
|
297
|
+
.selectAll("text")
|
298
|
+
.call(chart.wrap, chart.xScale.rangeBand())
|
299
|
+
|
300
|
+
// Bind the data
|
301
|
+
return this.selectAll('.category')
|
302
|
+
.data(data);
|
303
|
+
},
|
304
|
+
|
305
|
+
insert: function() {
|
306
|
+
var chart = this.chart();
|
307
|
+
|
308
|
+
// Append the bars
|
309
|
+
return this.append('g')
|
310
|
+
.attr('class', 'category');
|
311
|
+
},
|
312
|
+
|
313
|
+
events: {
|
314
|
+
|
315
|
+
"enter": function() {
|
316
|
+
var chart = this.chart();
|
317
|
+
|
318
|
+
this.attr("transform", function(d, i) { return "translate(" + chart.xScale(d.series) + ",0)"; })
|
319
|
+
.selectAll(".bar")
|
320
|
+
.data(function(d) {return d.values;})
|
321
|
+
.enter()
|
322
|
+
.append("rect")
|
323
|
+
.attr("title", function(d) { return d.name })
|
324
|
+
.attr("data-content", function(d) { return "Estimate: " + d.value + '%' })
|
325
|
+
.attr('class', 'bar')
|
326
|
+
.attr("width", chart.x1Scale.rangeBand())
|
327
|
+
.style("fill", function(d) { return chart.color(d.name); })
|
328
|
+
.attr("x", function(d) { return chart.x1Scale(d.name); })
|
329
|
+
.attr("y", chart.height())
|
330
|
+
.attr("height", 0);
|
331
|
+
|
332
|
+
this.selectAll("text")
|
333
|
+
.data(function(d) { return d.values})
|
334
|
+
.enter().append("text")
|
335
|
+
.style("text-anchor", "middle")
|
336
|
+
.attr("x", function(d) { return chart.x1Scale(d.name) + chart.x1Scale.rangeBand()/2 })
|
337
|
+
.attr("y", function(d) { return chart.yScale(d.value/2); })
|
338
|
+
.text(function(d) { return d.value })
|
339
|
+
|
340
|
+
this.selectAll("line")
|
341
|
+
.data(function(d) { return d.values })
|
342
|
+
.enter().append("line")
|
343
|
+
.attr("class", "error")
|
344
|
+
.attr("x1", function(d) { return chart.x1Scale(d.name) + (chart.x1Scale.rangeBand()/2); })
|
345
|
+
.attr("y1", function(d) { return chart.yScale((d.value + d.error)) })
|
346
|
+
.attr("x2", function(d) { return chart.x1Scale(d.name) + (chart.x1Scale.rangeBand()/2); })
|
347
|
+
.attr("y2", function(d) { return chart.yScale((d.value - d.error)) })
|
348
|
+
},
|
349
|
+
|
350
|
+
"merge:transition": function() {
|
351
|
+
var chart = this.chart();
|
352
|
+
|
353
|
+
this.duration(chart.duration)
|
354
|
+
.attr("transform", function(d, i) {return "translate(" + chart.xScale(d.series) + ",0)"; })
|
355
|
+
.selectAll(".bar")
|
356
|
+
.attr("width", chart.x1Scale.rangeBand())
|
357
|
+
.attr("x", function(d) { return chart.x1Scale(d.name); })
|
358
|
+
.attr("y", function(d, i) { return chart.yScale(d.value); })
|
359
|
+
.attr("height", function(d, i) { return chart.height() - chart.yScale(d.value); });
|
360
|
+
|
361
|
+
$(document).ready(function () {
|
362
|
+
$("svg rect").popover({
|
363
|
+
'container': 'body',
|
364
|
+
'placement': 'right',
|
365
|
+
'trigger': 'hover',
|
366
|
+
'html': true
|
367
|
+
});
|
368
|
+
});
|
369
|
+
}
|
370
|
+
},
|
371
|
+
});
|
372
|
+
|
373
|
+
},
|
374
|
+
|
375
|
+
transform: function(data) {
|
376
|
+
var _data = data;
|
377
|
+
|
378
|
+
var chart = this;
|
379
|
+
|
380
|
+
chart.xScale.domain(_data.map(function(d) { return d.series; }));
|
381
|
+
chart.x1Scale.domain(['2000', '2007-11']).rangeRoundBands([0, chart.xScale.rangeBand()]);
|
382
|
+
chart.yScale.domain([0, d3.max(_data, function(d) { return d3.max(d.values, function(d) { return d.value; }); })]);
|
383
|
+
|
384
|
+
return data;
|
385
|
+
}
|
386
|
+
});
|
387
|
+
},{}],5:[function(require,module,exports){
|
388
|
+
d3.chart("BaseChart").extend("LineChart", {
|
389
|
+
|
390
|
+
initialize: function() {
|
391
|
+
var chart = this;
|
392
|
+
|
393
|
+
chart._callouts = [];
|
394
|
+
|
395
|
+
chart.xScale = d3.time.scale()
|
396
|
+
.range([0, chart.width()]);
|
397
|
+
chart.yScale = d3.scale.linear()
|
398
|
+
.range([chart.height(), 0]);
|
399
|
+
chart.color = d3.scale.category10();
|
400
|
+
|
401
|
+
chart.renderLine = d3.svg.line()
|
402
|
+
.x(function(d) { return chart.xScale(d.year); })
|
403
|
+
.y(function(d) { return chart.yScale(d.value); });
|
404
|
+
|
405
|
+
chart.duration = 500;
|
406
|
+
|
407
|
+
chart.on('change:width', function(newWidth) {
|
408
|
+
chart.xScale.range([0, newWidth]);
|
409
|
+
});
|
410
|
+
|
411
|
+
chart.on('change:height', function(newHeight) {
|
412
|
+
chart.yScale.range([newHeight, 0]);
|
413
|
+
});
|
414
|
+
|
415
|
+
chart.areas = {};
|
416
|
+
|
417
|
+
chart.layers = {};
|
418
|
+
|
419
|
+
chart.areas.yAxisLayer = chart.base.select('g').append('g')
|
420
|
+
.classed('ylabels', true)
|
421
|
+
|
422
|
+
chart.layers.lines = chart.base.select('g').append('g')
|
423
|
+
.classed('lines', true)
|
424
|
+
|
425
|
+
chart.layers.circles = chart.base.select('g').append('g')
|
426
|
+
.classed('circles', true)
|
427
|
+
|
428
|
+
chart.layers.labels = chart.base.select('g').append('g')
|
429
|
+
.classed('text-labels', true)
|
430
|
+
|
431
|
+
// create a layer of circles that will go into
|
432
|
+
// a new group element on the base of the chart
|
433
|
+
chart.layer('lines', chart.layers.lines, {
|
434
|
+
|
435
|
+
// select the elements we wish to bind to and
|
436
|
+
// bind the data to them.
|
437
|
+
dataBind: function(data) {
|
438
|
+
var chart = this.chart();
|
439
|
+
|
440
|
+
var yAxis = d3.svg.axis()
|
441
|
+
.scale(chart.yScale)
|
442
|
+
.tickSize(-chart.width(), 0, 0)
|
443
|
+
.orient("left");
|
444
|
+
|
445
|
+
chart.areas.yAxisLayer
|
446
|
+
.call(yAxis)
|
447
|
+
.append("text")
|
448
|
+
.attr("transform", "rotate(-90)")
|
449
|
+
.attr("y", -35)
|
450
|
+
.attr("dy", ".71em")
|
451
|
+
.style("text-anchor", "end")
|
452
|
+
.text("Percent");
|
453
|
+
|
454
|
+
var xAxis = d3.svg.axis()
|
455
|
+
.scale(chart.xScale)
|
456
|
+
.orient("bottom");
|
457
|
+
|
458
|
+
chart.base.select('g').append('g')
|
459
|
+
.classed('x axis', true)
|
460
|
+
.attr("transform", "translate(0," + chart.height() + ")")
|
461
|
+
.call(xAxis)
|
462
|
+
.selectAll("text")
|
463
|
+
.call(chart.wrap, 50)
|
464
|
+
|
465
|
+
return this.selectAll('.line')
|
466
|
+
.data(data);
|
467
|
+
},
|
468
|
+
|
469
|
+
// insert actual rects
|
470
|
+
insert: function() {
|
471
|
+
return this.append('path')
|
472
|
+
.attr('class', function(d,i) {
|
473
|
+
return "line-" + i;
|
474
|
+
});
|
475
|
+
},
|
476
|
+
|
477
|
+
// define lifecycle events
|
478
|
+
events: {
|
479
|
+
'enter': function() {
|
480
|
+
var chart = this.chart();
|
481
|
+
this.attr('d', function(d) { return chart.renderLine(d.values); })
|
482
|
+
.attr("class", "line")
|
483
|
+
.style("stroke", function(d) {
|
484
|
+
if (chart.matchWithCallouts(d.series) || chart.callouts() == false) {
|
485
|
+
return chart.color(d.series)
|
486
|
+
} else {
|
487
|
+
return "Lightgray"
|
488
|
+
}
|
489
|
+
})
|
490
|
+
.on("mouseover", function(d,i) {
|
491
|
+
d3.select(this)
|
492
|
+
.style("stroke-width", "7");
|
493
|
+
})
|
494
|
+
.on("mouseout", function(d,i) {
|
495
|
+
d3.select(this)
|
496
|
+
.transition()
|
497
|
+
.duration(350)
|
498
|
+
.style("stroke-width", "3");
|
499
|
+
});
|
500
|
+
|
501
|
+
// this.append("text")
|
502
|
+
// .datum(function(d) { return { name: d.series, value: d.values[d.values.length - 1] }; })
|
503
|
+
// .attr("transform", function(d) { return "translate(" + (chart.xScale(d.value.year) + 10) + "," + chart.yScale(d.value.value) + ")"; })
|
504
|
+
// .attr("x", 3)
|
505
|
+
// .attr("dy", ".15em")
|
506
|
+
// .attr("id", function(d,i) { return "label" + i })
|
507
|
+
// .text(function(d) { return d.name; });
|
508
|
+
},
|
509
|
+
|
510
|
+
'enter:transition': function() {
|
511
|
+
var chart = this.chart();
|
512
|
+
|
513
|
+
// this.duration(chart.duration)
|
514
|
+
// .attr('y', function(d) { return chart.yScale(d3.max([0, d.value])); })
|
515
|
+
// .attr('height', function(d) { return Math.abs(chart.yScale(d.value) - chart.yScale(0)); });
|
516
|
+
|
517
|
+
$(document).ready(function () {
|
518
|
+
$("svg circle").popover({
|
519
|
+
'container': 'body',
|
520
|
+
'placement': 'right',
|
521
|
+
'trigger': 'hover',
|
522
|
+
'html': true
|
523
|
+
});
|
524
|
+
});
|
525
|
+
}
|
526
|
+
}
|
527
|
+
});
|
528
|
+
|
529
|
+
chart.layer('circles', chart.layers.circles, {
|
530
|
+
|
531
|
+
dataBind: function(data) {
|
532
|
+
return this.selectAll("circles")
|
533
|
+
.data(data);
|
534
|
+
},
|
535
|
+
|
536
|
+
insert: function() {
|
537
|
+
return this.append('g')
|
538
|
+
.attr('class', 'data-points');
|
539
|
+
},
|
540
|
+
|
541
|
+
events: {
|
542
|
+
|
543
|
+
'enter': function () {
|
544
|
+
|
545
|
+
var chart = this.chart();
|
546
|
+
|
547
|
+
this.selectAll("circle")
|
548
|
+
.data(function(d) {return d.values; })
|
549
|
+
.enter()
|
550
|
+
.append("svg:circle")
|
551
|
+
.attr("r", 3)
|
552
|
+
.attr("cx", function(d) { return chart.xScale(d.year) })
|
553
|
+
.attr("cy", function(d) { return chart.yScale(d.value) })
|
554
|
+
.attr("title", function(d) { return (d.year).getFullYear() })
|
555
|
+
.attr("data-content", function(d) { return "Estimate: " + d.value + "%" })
|
556
|
+
.attr("fill", "black")
|
557
|
+
.on("mouseover", function(d, i) {
|
558
|
+
d3.select(this)
|
559
|
+
.attr("r", "6");
|
560
|
+
})
|
561
|
+
.on("mouseout", function(d) {
|
562
|
+
d3.select(this)
|
563
|
+
.transition()
|
564
|
+
.duration(150)
|
565
|
+
.attr("r", "3")
|
566
|
+
});
|
567
|
+
},
|
568
|
+
|
569
|
+
'enter:transition': function () {
|
570
|
+
$(document).ready( function () {
|
571
|
+
$("svg circle").popover({
|
572
|
+
'container': 'body',
|
573
|
+
'placement': 'right',
|
574
|
+
'trigger': 'hover',
|
575
|
+
'html': true
|
576
|
+
});
|
577
|
+
});
|
578
|
+
}
|
579
|
+
}
|
580
|
+
});
|
581
|
+
|
582
|
+
chart.layer('text-labels', chart.layers.labels, {
|
583
|
+
dataBind: function(data) {
|
584
|
+
return this.selectAll("text-labels")
|
585
|
+
.data(data);
|
586
|
+
},
|
587
|
+
|
588
|
+
insert: function () {
|
589
|
+
return this.append("text")
|
590
|
+
.attr("class", "text-labels")
|
591
|
+
|
592
|
+
},
|
593
|
+
events: {
|
594
|
+
'enter': function () {
|
595
|
+
var chart = this.chart();
|
596
|
+
|
597
|
+
this.attr("transform", function(d,i) { return "translate(" + (chart.xScale((d.values[d.values.length - 1]).year) + 10) + "," + chart.yScale((d.values[d.values.length - 1]).value) + ")"; })
|
598
|
+
.attr("x", 3)
|
599
|
+
.attr("dy", ".15em")
|
600
|
+
.attr("id", function(d,i) { return "label" + i })
|
601
|
+
.text(function(d) { return d.series; });
|
602
|
+
|
603
|
+
}
|
604
|
+
}
|
605
|
+
});
|
606
|
+
|
607
|
+
},
|
608
|
+
|
609
|
+
callouts: function(collection) {
|
610
|
+
if (arguments.length === 0) {
|
611
|
+
return this._callouts;
|
612
|
+
}
|
613
|
+
|
614
|
+
if (Array.isArray(collection)) {
|
615
|
+
this._callouts = collection
|
616
|
+
}
|
617
|
+
|
618
|
+
return this;
|
619
|
+
},
|
620
|
+
|
621
|
+
matchWithCallouts: function (comparator) {
|
622
|
+
return this._callouts.indexOf(comparator) !== -1
|
623
|
+
},
|
624
|
+
|
625
|
+
// set/get the color to use for the circles as they are
|
626
|
+
// rendered.
|
627
|
+
transform: function(data) {
|
628
|
+
var chart = this;
|
629
|
+
// update the scales
|
630
|
+
|
631
|
+
chart.xScale.domain(d3.extent([2005,2006,2007,2008,2009,2010,2011,2012].map(function(d) { return chart.parseDate(d.toString()) })));
|
632
|
+
chart.yScale.domain([30,60]);
|
633
|
+
|
634
|
+
return data;
|
635
|
+
}
|
636
|
+
});
|
637
|
+
},{}],6:[function(require,module,exports){
|
638
|
+
d3.chart('BaseChart').extend('StackedBarChart', {
|
639
|
+
initialize : function() {
|
640
|
+
var chart = this;
|
641
|
+
|
642
|
+
chart.xScale = d3.scale.ordinal()
|
643
|
+
.rangeRoundBands([0, chart.width()], .1);
|
644
|
+
chart.yScale = d3.scale.linear()
|
645
|
+
.rangeRound([chart.height(), 0]);
|
646
|
+
chart.color = d3.scale.category10();
|
647
|
+
chart.duration = 500;
|
648
|
+
|
649
|
+
chart.yAxis = d3.svg.axis()
|
650
|
+
.scale(chart.yScale)
|
651
|
+
.tickSize(-chart.width(), 0, 0)
|
652
|
+
.orient("left")
|
653
|
+
.tickFormat(d3.format(".2s"));
|
654
|
+
|
655
|
+
chart.on("change:width", function(newWidth) {
|
656
|
+
chart.xScale.rangeRoundBands([0, newWidth], 0.1);
|
657
|
+
});
|
658
|
+
|
659
|
+
chart.on("change:height", function(newHeight) {
|
660
|
+
chart.yScale.range([newHeight, 0]);
|
661
|
+
});
|
662
|
+
|
663
|
+
|
664
|
+
chart.areas = {};
|
665
|
+
|
666
|
+
// cache for selections that are layer bases.
|
667
|
+
chart.layers = {};
|
668
|
+
|
669
|
+
chart.areas.yAxisLayer = chart.base.select('g').append('g')
|
670
|
+
.classed('ylabels', true)
|
671
|
+
|
672
|
+
// -- actual layers
|
673
|
+
chart.layers.bars = chart.base.select('g').append('g')
|
674
|
+
.classed('bars', true)
|
675
|
+
|
676
|
+
chart.layer('bars', chart.layers.bars, {
|
677
|
+
dataBind: function(data) {
|
678
|
+
var chart = this.chart();
|
679
|
+
|
680
|
+
var yAxis = d3.svg.axis()
|
681
|
+
.scale(chart.yScale)
|
682
|
+
.tickSize(-(chart.width()), 0, 0)
|
683
|
+
.orient("left")
|
684
|
+
.tickFormat(d3.format(".2s"));
|
685
|
+
|
686
|
+
chart.areas.yAxisLayer
|
687
|
+
.call(yAxis)
|
688
|
+
.append("text")
|
689
|
+
.attr("transform", "rotate(-90)")
|
690
|
+
.attr("y", -35)
|
691
|
+
.attr("dy", ".71em")
|
692
|
+
.style("text-anchor", "end")
|
693
|
+
.text("Percent");
|
694
|
+
|
695
|
+
var xAxis = d3.svg.axis()
|
696
|
+
.scale(chart.xScale)
|
697
|
+
.orient("bottom");
|
698
|
+
|
699
|
+
chart.base.select('g').append('g')
|
700
|
+
.classed('x axis', true)
|
701
|
+
.attr("transform", "translate(0," + chart.height() + ")")
|
702
|
+
.call(xAxis)
|
703
|
+
.selectAll("text")
|
704
|
+
.call(chart.wrap, chart.xScale.rangeBand())
|
705
|
+
|
706
|
+
// Bind the data
|
707
|
+
return this.selectAll('.category')
|
708
|
+
.data(data);
|
709
|
+
},
|
710
|
+
|
711
|
+
insert: function() {
|
712
|
+
var chart = this.chart();
|
713
|
+
|
714
|
+
// Append the bars
|
715
|
+
return this.append('g')
|
716
|
+
.attr('class', 'category');
|
717
|
+
},
|
718
|
+
|
719
|
+
events: {
|
720
|
+
|
721
|
+
"enter": function() {
|
722
|
+
var chart = this.chart();
|
723
|
+
|
724
|
+
this.attr("transform", function(d, i) { return "translate(" + chart.xScale(d.State) + ",0)"; })
|
725
|
+
.selectAll(".category")
|
726
|
+
.data(function(d) { return d.groups; })
|
727
|
+
.enter().append("rect")
|
728
|
+
.attr("class", "bar")
|
729
|
+
// .attr("transform", function(d) { return "translate(" + chart.xScale(d.State) + ",0)"; })
|
730
|
+
.attr("width", chart.xScale.rangeBand())
|
731
|
+
.attr("y", function(d) { return chart.yScale(d.y1); })
|
732
|
+
.attr("height", function(d) { return chart.yScale(d.y0) - chart.yScale(d.y1); })
|
733
|
+
.style("fill", function(d) { return chart.color(d.name); });
|
734
|
+
}
|
735
|
+
},
|
736
|
+
});
|
737
|
+
|
738
|
+
},
|
739
|
+
|
740
|
+
transform: function(data) {
|
741
|
+
var _data = data;
|
742
|
+
var chart = this;
|
743
|
+
|
744
|
+
chart.color.domain(d3.keys(data[0]).filter(function(key) { return key !== "State"; }));
|
745
|
+
|
746
|
+
_data.forEach(function(d) {
|
747
|
+
var y0 = 0;
|
748
|
+
d.groups = chart.color.domain().map(function(name) { return {name: name, y0: y0, y1: y0 += +d[name]}; });
|
749
|
+
d.total = d.groups[d.groups.length - 1].y1;
|
750
|
+
});
|
751
|
+
|
752
|
+
data.sort(function(a, b) { return b.total - a.total; });
|
753
|
+
|
754
|
+
chart.xScale.domain(data.map(function(d) { return d.State; }));
|
755
|
+
chart.yScale.domain([0, d3.max(data, function(d) { return d.total; })]);
|
756
|
+
|
757
|
+
return data;
|
758
|
+
}
|
759
|
+
});
|
760
|
+
},{}]},{},[1])
|
@@ -0,0 +1,70 @@
|
|
1
|
+
text {
|
2
|
+
font: 10px sans-serif;
|
3
|
+
}
|
4
|
+
|
5
|
+
.charts {
|
6
|
+
height:300px;
|
7
|
+
width:400px;
|
8
|
+
}
|
9
|
+
|
10
|
+
body {
|
11
|
+
font: 12px sans-serif;
|
12
|
+
}
|
13
|
+
|
14
|
+
circle:hover {
|
15
|
+
cursor: pointer;
|
16
|
+
}
|
17
|
+
|
18
|
+
path:hover {
|
19
|
+
cursor: pointer;
|
20
|
+
}
|
21
|
+
|
22
|
+
.category text {
|
23
|
+
fill: white;
|
24
|
+
}
|
25
|
+
|
26
|
+
.axis path,
|
27
|
+
.axis line {
|
28
|
+
fill: none;
|
29
|
+
stroke: #000;
|
30
|
+
shape-rendering: crispEdges;
|
31
|
+
}
|
32
|
+
|
33
|
+
.recession {
|
34
|
+
fill: lightgrey;
|
35
|
+
}
|
36
|
+
|
37
|
+
.line {
|
38
|
+
fill: none;
|
39
|
+
stroke: steelblue;
|
40
|
+
stroke-width: 3px;
|
41
|
+
}
|
42
|
+
|
43
|
+
.tick.major line {
|
44
|
+
stroke: lightgrey;
|
45
|
+
/*opacity: 0.7;*/
|
46
|
+
}
|
47
|
+
|
48
|
+
.bar {
|
49
|
+
fill: steelblue;
|
50
|
+
}
|
51
|
+
|
52
|
+
.error {
|
53
|
+
stroke: black;
|
54
|
+
stroke-width:2;
|
55
|
+
}
|
56
|
+
|
57
|
+
.average {
|
58
|
+
|
59
|
+
stroke-width:2;
|
60
|
+
|
61
|
+
}
|
62
|
+
|
63
|
+
#average0 {
|
64
|
+
stroke: black;
|
65
|
+
stroke-dasharray: 6, 1;
|
66
|
+
}
|
67
|
+
|
68
|
+
#average1 {
|
69
|
+
stroke: black;
|
70
|
+
}
|
metadata
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tufted-rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Matt Cloyd
|
8
|
+
- W. Matt Gardner
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-05-06 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: railties
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - '>='
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '3.0'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - '>='
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '3.0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: bundler
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - '>='
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '1.0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - '>='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '1.0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rake
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - '>='
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: pry
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: json
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
description: Terse D3 Charts for Rails
|
85
|
+
email:
|
86
|
+
- mcloyd@gmail.com
|
87
|
+
executables: []
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files: []
|
90
|
+
files:
|
91
|
+
- .gitignore
|
92
|
+
- .ruby-gemset
|
93
|
+
- .ruby-version
|
94
|
+
- Gemfile
|
95
|
+
- README.md
|
96
|
+
- Rakefile
|
97
|
+
- lib/tufted-rails.rb
|
98
|
+
- lib/tufted-rails/engine.rb
|
99
|
+
- lib/tufted-rails/railtie.rb
|
100
|
+
- lib/tufted-rails/version.rb
|
101
|
+
- tufted-rails.gemspec
|
102
|
+
- vendor/assets/javascripts/tufted-rails/index.js
|
103
|
+
- vendor/assets/javascripts/tufted-rails/tufted.js
|
104
|
+
- vendor/assets/stylesheets/tufted-rails/index.css
|
105
|
+
- vendor/assets/stylesheets/tufted-rails/tufted.css
|
106
|
+
homepage: https://github.com/mapc/tufted-rails
|
107
|
+
licenses:
|
108
|
+
- MIT
|
109
|
+
metadata: {}
|
110
|
+
post_install_message:
|
111
|
+
rdoc_options: []
|
112
|
+
require_paths:
|
113
|
+
- lib
|
114
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - '>='
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - '>='
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
requirements: []
|
125
|
+
rubyforge_project:
|
126
|
+
rubygems_version: 2.1.10
|
127
|
+
signing_key:
|
128
|
+
specification_version: 4
|
129
|
+
summary: Load Tufted.js (by allthesignals) into Rails asset pipeline
|
130
|
+
test_files: []
|