morris-rails 0.4.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.
- data/Gemfile +3 -0
- data/Gemfile.lock +97 -0
- data/LICENSE +20 -0
- data/README.md +58 -0
- data/Rakefile +8 -0
- data/VERSION +1 -0
- data/app/assets/javascripts/morris.area.coffee +42 -0
- data/app/assets/javascripts/morris.bar.coffee +165 -0
- data/app/assets/javascripts/morris.coffee +42 -0
- data/app/assets/javascripts/morris.donut.coffee +182 -0
- data/app/assets/javascripts/morris.grid.coffee +392 -0
- data/app/assets/javascripts/morris.hover.coffee +41 -0
- data/app/assets/javascripts/morris.line.coffee +354 -0
- data/app/assets/stylesheets/morris.core.less +27 -0
- data/lib/morris-rails/rails.rb +1 -0
- data/morris-rails.gemspec +30 -0
- data/spec/dummy/README.rdoc +261 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +15 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +65 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/production.rb +67 -0
- data/spec/dummy/config/environments/test.rb +37 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +58 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/test.log +6 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +25 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/dummy/tmp/cache/assets/C87/360/sprockets%2F7f2a79129bb3445603eb704843de5397 +0 -0
- data/spec/dummy/tmp/cache/assets/D5B/040/sprockets%2F5d0b7809f616213c43a3ba43cbcda91d +0 -0
- data/spec/dummy/tmp/cache/assets/DAE/5D0/sprockets%2Fae427ff9e5b67de97e2ad285c5b623b6 +0 -0
- data/spec/morris-rails_spec.rb +12 -0
- data/spec/spec_helper.rb +16 -0
- metadata +271 -0
@@ -0,0 +1,41 @@
|
|
1
|
+
class Morris.Hover
|
2
|
+
# Displays contextual information in a floating HTML div.
|
3
|
+
|
4
|
+
@defaults:
|
5
|
+
class: 'morris-hover morris-default-style'
|
6
|
+
|
7
|
+
constructor: (options = {}) ->
|
8
|
+
@options = $.extend {}, Morris.Hover.defaults, options
|
9
|
+
@el = $ "<div class='#{@options.class}'></div>"
|
10
|
+
@el.hide()
|
11
|
+
@options.parent.append(@el)
|
12
|
+
|
13
|
+
update: (html, x, y) ->
|
14
|
+
@html(html)
|
15
|
+
@show()
|
16
|
+
@moveTo(x, y)
|
17
|
+
|
18
|
+
html: (content) ->
|
19
|
+
@el.html(content)
|
20
|
+
|
21
|
+
moveTo: (x, y) ->
|
22
|
+
parentWidth = @options.parent.innerWidth()
|
23
|
+
parentHeight = @options.parent.innerHeight()
|
24
|
+
hoverWidth = @el.outerWidth()
|
25
|
+
hoverHeight = @el.outerHeight()
|
26
|
+
left = Math.min(Math.max(0, x - hoverWidth / 2), parentWidth - hoverWidth)
|
27
|
+
if y?
|
28
|
+
top = y - hoverHeight - 10
|
29
|
+
if top < 0
|
30
|
+
top = y + 10
|
31
|
+
if top + hoverHeight > parentHeight
|
32
|
+
top = parentHeight / 2 - hoverHeight / 2
|
33
|
+
else
|
34
|
+
top = parentHeight / 2 - hoverHeight / 2
|
35
|
+
@el.css(left: left + "px", top: top + "px")
|
36
|
+
|
37
|
+
show: ->
|
38
|
+
@el.show()
|
39
|
+
|
40
|
+
hide: ->
|
41
|
+
@el.hide()
|
@@ -0,0 +1,354 @@
|
|
1
|
+
class Morris.Line extends Morris.Grid
|
2
|
+
# Initialise the graph.
|
3
|
+
#
|
4
|
+
constructor: (options) ->
|
5
|
+
return new Morris.Line(options) unless (@ instanceof Morris.Line)
|
6
|
+
super(options)
|
7
|
+
|
8
|
+
init: ->
|
9
|
+
# Some instance variables for later
|
10
|
+
@pointGrow = Raphael.animation r: @options.pointSize + 3, 25, 'linear'
|
11
|
+
@pointShrink = Raphael.animation r: @options.pointSize, 25, 'linear'
|
12
|
+
|
13
|
+
if @options.hideHover isnt 'always'
|
14
|
+
@hover = new Morris.Hover(parent: @el)
|
15
|
+
@on('hovermove', @onHoverMove)
|
16
|
+
@on('hoverout', @onHoverOut)
|
17
|
+
|
18
|
+
# Default configuration
|
19
|
+
#
|
20
|
+
defaults:
|
21
|
+
lineWidth: 3
|
22
|
+
pointSize: 4
|
23
|
+
lineColors: [
|
24
|
+
'#0b62a4'
|
25
|
+
'#7A92A3'
|
26
|
+
'#4da74d'
|
27
|
+
'#afd8f8'
|
28
|
+
'#edc240'
|
29
|
+
'#cb4b4b'
|
30
|
+
'#9440ed'
|
31
|
+
]
|
32
|
+
pointWidths: [1]
|
33
|
+
pointStrokeColors: ['#ffffff']
|
34
|
+
pointFillColors: []
|
35
|
+
smooth: true
|
36
|
+
xLabels: 'auto'
|
37
|
+
xLabelFormat: null
|
38
|
+
xLabelMargin: 50
|
39
|
+
continuousLine: true
|
40
|
+
hideHover: false
|
41
|
+
|
42
|
+
# Do any size-related calculations
|
43
|
+
#
|
44
|
+
# @private
|
45
|
+
calc: ->
|
46
|
+
@calcPoints()
|
47
|
+
@generatePaths()
|
48
|
+
|
49
|
+
# calculate series data point coordinates
|
50
|
+
#
|
51
|
+
# @private
|
52
|
+
calcPoints: ->
|
53
|
+
for row in @data
|
54
|
+
row._x = @transX(row.x)
|
55
|
+
row._y = for y in row.y
|
56
|
+
if y? then @transY(y) else y
|
57
|
+
row._ymax = Math.min.apply(null, [@bottom].concat(y for y in row._y when y?))
|
58
|
+
|
59
|
+
# hit test - returns the index of the row beneath the given coordinate
|
60
|
+
#
|
61
|
+
hitTest: (x, y) ->
|
62
|
+
return null if @data.length == 0
|
63
|
+
# TODO better search algo
|
64
|
+
for r, index in @data.slice(1)
|
65
|
+
break if x < (r._x + @data[index]._x) / 2
|
66
|
+
index
|
67
|
+
|
68
|
+
# hover movement event handler
|
69
|
+
#
|
70
|
+
# @private
|
71
|
+
onHoverMove: (x, y) =>
|
72
|
+
index = @hitTest(x, y)
|
73
|
+
@displayHoverForRow(index)
|
74
|
+
|
75
|
+
# hover out event handler
|
76
|
+
#
|
77
|
+
# @private
|
78
|
+
onHoverOut: =>
|
79
|
+
if @options.hideHover is 'auto'
|
80
|
+
@displayHoverForRow(null)
|
81
|
+
|
82
|
+
# display a hover popup over the given row
|
83
|
+
#
|
84
|
+
# @private
|
85
|
+
displayHoverForRow: (index) ->
|
86
|
+
if index?
|
87
|
+
@hover.update(@hoverContentForRow(index)...)
|
88
|
+
@hilight(index)
|
89
|
+
else
|
90
|
+
@hover.hide()
|
91
|
+
@hilight()
|
92
|
+
|
93
|
+
# hover content for a point
|
94
|
+
#
|
95
|
+
# @private
|
96
|
+
hoverContentForRow: (index) ->
|
97
|
+
row = @data[index]
|
98
|
+
if typeof @options.hoverCallback is 'function'
|
99
|
+
content = @options.hoverCallback(index, @options)
|
100
|
+
else
|
101
|
+
content = "<div class='morris-hover-row-label'>#{row.label}</div>"
|
102
|
+
for y, j in row.y
|
103
|
+
content += """
|
104
|
+
<div class='morris-hover-point' style='color: #{@colorFor(row, j, 'label')}'>
|
105
|
+
#{@options.labels[j]}:
|
106
|
+
#{@yLabelFormat(y)}
|
107
|
+
</div>
|
108
|
+
"""
|
109
|
+
[content, row._x, row._ymax]
|
110
|
+
|
111
|
+
|
112
|
+
# generate paths for series lines
|
113
|
+
#
|
114
|
+
# @private
|
115
|
+
generatePaths: ->
|
116
|
+
@paths = for i in [0...@options.ykeys.length]
|
117
|
+
smooth = @options.smooth is true or @options.ykeys[i] in @options.smooth
|
118
|
+
coords = ({x: r._x, y: r._y[i]} for r in @data when r._y[i] isnt undefined)
|
119
|
+
coords = (c for c in coords when c.y isnt null) if @options.continuousLine
|
120
|
+
|
121
|
+
if coords.length > 1
|
122
|
+
Morris.Line.createPath coords, smooth, @bottom
|
123
|
+
else
|
124
|
+
null
|
125
|
+
|
126
|
+
# Draws the line chart.
|
127
|
+
#
|
128
|
+
draw: ->
|
129
|
+
@drawXAxis() if @options.axes
|
130
|
+
@drawSeries()
|
131
|
+
if @options.hideHover is false
|
132
|
+
@displayHoverForRow(@data.length - 1)
|
133
|
+
|
134
|
+
# draw the x-axis labels
|
135
|
+
#
|
136
|
+
# @private
|
137
|
+
drawXAxis: ->
|
138
|
+
# draw x axis labels
|
139
|
+
ypos = @bottom + @options.gridTextSize * 1.25
|
140
|
+
prevLabelMargin = null
|
141
|
+
drawLabel = (labelText, xpos) =>
|
142
|
+
label = @drawXAxisLabel(@transX(xpos), ypos, labelText)
|
143
|
+
labelBox = label.getBBox()
|
144
|
+
# ensure a minimum of `xLabelMargin` pixels between labels, and ensure
|
145
|
+
# labels don't overflow the container
|
146
|
+
if (not prevLabelMargin? or prevLabelMargin >= labelBox.x + labelBox.width) and
|
147
|
+
labelBox.x >= 0 and (labelBox.x + labelBox.width) < @el.width()
|
148
|
+
prevLabelMargin = labelBox.x - @options.xLabelMargin
|
149
|
+
else
|
150
|
+
label.remove()
|
151
|
+
if @options.parseTime
|
152
|
+
if @data.length == 1 and @options.xLabels == 'auto'
|
153
|
+
# where there's only one value in the series, we can't make a
|
154
|
+
# sensible guess for an x labelling scheme, so just use the original
|
155
|
+
# column label
|
156
|
+
labels = [[@data[0].label, @data[0].x]]
|
157
|
+
else
|
158
|
+
labels = Morris.labelSeries(@xmin, @xmax, @width, @options.xLabels, @options.xLabelFormat)
|
159
|
+
else
|
160
|
+
labels = ([row.label, row.x] for row in @data)
|
161
|
+
labels.reverse()
|
162
|
+
for l in labels
|
163
|
+
drawLabel(l[0], l[1])
|
164
|
+
|
165
|
+
# draw the data series
|
166
|
+
#
|
167
|
+
# @private
|
168
|
+
drawSeries: ->
|
169
|
+
for i in [@options.ykeys.length-1..0]
|
170
|
+
path = @paths[i]
|
171
|
+
if path isnt null
|
172
|
+
@drawLinePath(path, @colorFor(row, i, 'line')) #row isn't available here?
|
173
|
+
@seriesPoints = ([] for i in [0...@options.ykeys.length])
|
174
|
+
for i in [@options.ykeys.length-1..0]
|
175
|
+
for row in @data
|
176
|
+
if row._y[i]?
|
177
|
+
circle = @drawLinePoint(row._x, row._y[i], @options.pointSize, @colorFor(row, i, 'point'), i)
|
178
|
+
else
|
179
|
+
circle = null
|
180
|
+
@seriesPoints[i].push(circle)
|
181
|
+
|
182
|
+
# create a path for a data series
|
183
|
+
#
|
184
|
+
# @private
|
185
|
+
@createPath: (coords, smooth, bottom) ->
|
186
|
+
path = ""
|
187
|
+
grads = Morris.Line.gradients(coords) if smooth
|
188
|
+
|
189
|
+
prevCoord = {y: null}
|
190
|
+
for coord, i in coords
|
191
|
+
if coord.y?
|
192
|
+
if prevCoord.y?
|
193
|
+
if smooth
|
194
|
+
g = grads[i]
|
195
|
+
lg = grads[i - 1]
|
196
|
+
ix = (coord.x - prevCoord.x) / 4
|
197
|
+
x1 = prevCoord.x + ix
|
198
|
+
y1 = Math.min(bottom, prevCoord.y + ix * lg)
|
199
|
+
x2 = coord.x - ix
|
200
|
+
y2 = Math.min(bottom, coord.y - ix * g)
|
201
|
+
path += "C#{x1},#{y1},#{x2},#{y2},#{coord.x},#{coord.y}"
|
202
|
+
else
|
203
|
+
path += "L#{coord.x},#{coord.y}"
|
204
|
+
else
|
205
|
+
if not smooth or grads[i]?
|
206
|
+
path += "M#{coord.x},#{coord.y}"
|
207
|
+
prevCoord = coord
|
208
|
+
return path
|
209
|
+
|
210
|
+
# calculate a gradient at each point for a series of points
|
211
|
+
#
|
212
|
+
# @private
|
213
|
+
@gradients: (coords) ->
|
214
|
+
grad = (a, b) -> (a.y - b.y) / (a.x - b.x)
|
215
|
+
for coord, i in coords
|
216
|
+
if coord.y?
|
217
|
+
nextCoord = coords[i + 1] or {y: null}
|
218
|
+
prevCoord = coords[i - 1] or {y: null}
|
219
|
+
if prevCoord.y? and nextCoord.y?
|
220
|
+
grad(prevCoord, nextCoord)
|
221
|
+
else if prevCoord.y?
|
222
|
+
grad(prevCoord, coord)
|
223
|
+
else if nextCoord.y?
|
224
|
+
grad(coord, nextCoord)
|
225
|
+
else
|
226
|
+
null
|
227
|
+
else
|
228
|
+
null
|
229
|
+
|
230
|
+
# @private
|
231
|
+
hilight: (index) =>
|
232
|
+
if @prevHilight isnt null and @prevHilight isnt index
|
233
|
+
for i in [0..@seriesPoints.length-1]
|
234
|
+
if @seriesPoints[i][@prevHilight]
|
235
|
+
@seriesPoints[i][@prevHilight].animate @pointShrink
|
236
|
+
if index isnt null and @prevHilight isnt index
|
237
|
+
for i in [0..@seriesPoints.length-1]
|
238
|
+
if @seriesPoints[i][index]
|
239
|
+
@seriesPoints[i][index].animate @pointGrow
|
240
|
+
@prevHilight = index
|
241
|
+
|
242
|
+
colorFor: (row, sidx, type) ->
|
243
|
+
if typeof @options.lineColors is 'function'
|
244
|
+
@options.lineColors.call(@, row, sidx, type)
|
245
|
+
else if type is 'point'
|
246
|
+
@options.pointFillColors[sidx % @options.pointFillColors.length] || @options.lineColors[sidx % @options.lineColors.length]
|
247
|
+
else
|
248
|
+
@options.lineColors[sidx % @options.lineColors.length]
|
249
|
+
|
250
|
+
drawXAxisLabel: (xPos, yPos, text) ->
|
251
|
+
@raphael.text(xPos, yPos, text)
|
252
|
+
.attr('font-size', @options.gridTextSize)
|
253
|
+
.attr('fill', @options.gridTextColor)
|
254
|
+
|
255
|
+
drawLinePath: (path, lineColor) ->
|
256
|
+
@raphael.path(path)
|
257
|
+
.attr('stroke', lineColor)
|
258
|
+
.attr('stroke-width', @options.lineWidth)
|
259
|
+
|
260
|
+
drawLinePoint: (xPos, yPos, size, pointColor, lineIndex) ->
|
261
|
+
@raphael.circle(xPos, yPos, size)
|
262
|
+
.attr('fill', pointColor)
|
263
|
+
.attr('stroke-width', @strokeWidthForSeries(lineIndex))
|
264
|
+
.attr('stroke', @strokeForSeries(lineIndex))
|
265
|
+
|
266
|
+
# @private
|
267
|
+
strokeWidthForSeries: (index) ->
|
268
|
+
@options.pointWidths[index % @options.pointWidths.length]
|
269
|
+
|
270
|
+
# @private
|
271
|
+
strokeForSeries: (index) ->
|
272
|
+
@options.pointStrokeColors[index % @options.pointStrokeColors.length]
|
273
|
+
|
274
|
+
# generate a series of label, timestamp pairs for x-axis labels
|
275
|
+
#
|
276
|
+
# @private
|
277
|
+
Morris.labelSeries = (dmin, dmax, pxwidth, specName, xLabelFormat) ->
|
278
|
+
ddensity = 200 * (dmax - dmin) / pxwidth # seconds per `margin` pixels
|
279
|
+
d0 = new Date(dmin)
|
280
|
+
spec = Morris.LABEL_SPECS[specName]
|
281
|
+
# if the spec doesn't exist, search for the closest one in the list
|
282
|
+
if spec is undefined
|
283
|
+
for name in Morris.AUTO_LABEL_ORDER
|
284
|
+
s = Morris.LABEL_SPECS[name]
|
285
|
+
if ddensity >= s.span
|
286
|
+
spec = s
|
287
|
+
break
|
288
|
+
# if we run out of options, use second-intervals
|
289
|
+
if spec is undefined
|
290
|
+
spec = Morris.LABEL_SPECS["second"]
|
291
|
+
# check if there's a user-defined formatting function
|
292
|
+
if xLabelFormat
|
293
|
+
spec = $.extend({}, spec, {fmt: xLabelFormat})
|
294
|
+
# calculate labels
|
295
|
+
d = spec.start(d0)
|
296
|
+
ret = []
|
297
|
+
while (t = d.getTime()) <= dmax
|
298
|
+
if t >= dmin
|
299
|
+
ret.push [spec.fmt(d), t]
|
300
|
+
spec.incr(d)
|
301
|
+
return ret
|
302
|
+
|
303
|
+
# @private
|
304
|
+
minutesSpecHelper = (interval) ->
|
305
|
+
span: interval * 60 * 1000
|
306
|
+
start: (d) -> new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours())
|
307
|
+
fmt: (d) -> "#{Morris.pad2(d.getHours())}:#{Morris.pad2(d.getMinutes())}"
|
308
|
+
incr: (d) -> d.setMinutes(d.getMinutes() + interval)
|
309
|
+
|
310
|
+
# @private
|
311
|
+
secondsSpecHelper = (interval) ->
|
312
|
+
span: interval * 1000
|
313
|
+
start: (d) -> new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes())
|
314
|
+
fmt: (d) -> "#{Morris.pad2(d.getHours())}:#{Morris.pad2(d.getMinutes())}:#{Morris.pad2(d.getSeconds())}"
|
315
|
+
incr: (d) -> d.setSeconds(d.getSeconds() + interval)
|
316
|
+
|
317
|
+
Morris.LABEL_SPECS =
|
318
|
+
"decade":
|
319
|
+
span: 172800000000 # 10 * 365 * 24 * 60 * 60 * 1000
|
320
|
+
start: (d) -> new Date(d.getFullYear() - d.getFullYear() % 10, 0, 1)
|
321
|
+
fmt: (d) -> "#{d.getFullYear()}"
|
322
|
+
incr: (d) -> d.setFullYear(d.getFullYear() + 10)
|
323
|
+
"year":
|
324
|
+
span: 17280000000 # 365 * 24 * 60 * 60 * 1000
|
325
|
+
start: (d) -> new Date(d.getFullYear(), 0, 1)
|
326
|
+
fmt: (d) -> "#{d.getFullYear()}"
|
327
|
+
incr: (d) -> d.setFullYear(d.getFullYear() + 1)
|
328
|
+
"month":
|
329
|
+
span: 2419200000 # 28 * 24 * 60 * 60 * 1000
|
330
|
+
start: (d) -> new Date(d.getFullYear(), d.getMonth(), 1)
|
331
|
+
fmt: (d) -> "#{d.getFullYear()}-#{Morris.pad2(d.getMonth() + 1)}"
|
332
|
+
incr: (d) -> d.setMonth(d.getMonth() + 1)
|
333
|
+
"day":
|
334
|
+
span: 86400000 # 24 * 60 * 60 * 1000
|
335
|
+
start: (d) -> new Date(d.getFullYear(), d.getMonth(), d.getDate())
|
336
|
+
fmt: (d) -> "#{d.getFullYear()}-#{Morris.pad2(d.getMonth() + 1)}-#{Morris.pad2(d.getDate())}"
|
337
|
+
incr: (d) -> d.setDate(d.getDate() + 1)
|
338
|
+
"hour": minutesSpecHelper(60)
|
339
|
+
"30min": minutesSpecHelper(30)
|
340
|
+
"15min": minutesSpecHelper(15)
|
341
|
+
"10min": minutesSpecHelper(10)
|
342
|
+
"5min": minutesSpecHelper(5)
|
343
|
+
"minute": minutesSpecHelper(1)
|
344
|
+
"30sec": secondsSpecHelper(30)
|
345
|
+
"15sec": secondsSpecHelper(15)
|
346
|
+
"10sec": secondsSpecHelper(10)
|
347
|
+
"5sec": secondsSpecHelper(5)
|
348
|
+
"second": secondsSpecHelper(1)
|
349
|
+
|
350
|
+
Morris.AUTO_LABEL_ORDER = [
|
351
|
+
"decade", "year", "month", "day", "hour",
|
352
|
+
"30min", "15min", "10min", "5min", "minute",
|
353
|
+
"30sec", "15sec", "10sec", "5sec", "second"
|
354
|
+
]
|
@@ -0,0 +1,27 @@
|
|
1
|
+
.morris-hover {
|
2
|
+
position: absolute;
|
3
|
+
z-index: 1000;
|
4
|
+
|
5
|
+
&.morris-default-style {
|
6
|
+
border-radius: 10px;
|
7
|
+
padding: 6px;
|
8
|
+
color: #666;
|
9
|
+
background: rgba(255, 255, 255, 0.8);
|
10
|
+
border: solid 2px rgba(230, 230, 230, 0.8);
|
11
|
+
|
12
|
+
font-family: sans-serif;
|
13
|
+
font-size: 12px;
|
14
|
+
text-align: center;
|
15
|
+
|
16
|
+
.morris-hover-row-label {
|
17
|
+
font-weight: bold;
|
18
|
+
margin: 0.25em 0;
|
19
|
+
}
|
20
|
+
|
21
|
+
.morris-hover-point {
|
22
|
+
white-space: nowrap;
|
23
|
+
margin: 0.1em 0;
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'morris-rails/rails/engine'
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
|
5
|
+
# Variables
|
6
|
+
s.name = Pathname.new(__FILE__).basename('.gemspec').to_s
|
7
|
+
s.author = 'Ryan Scott Lewis'
|
8
|
+
s.email = 'ryan@rynet.us'
|
9
|
+
s.summary = 'morris.js for the Rails asset pipeline.'
|
10
|
+
s.description = s.summary
|
11
|
+
s.license = 'MIT'
|
12
|
+
|
13
|
+
# Dependencies
|
14
|
+
s.add_dependency 'version', '~> 1.0'
|
15
|
+
s.add_dependency 'railties', '>= 3.2.0', '< 5.0'
|
16
|
+
s.add_dependency 'jquery-rails', '~> 2.0'
|
17
|
+
s.add_dependency 'raphaeljs-rails', '~> 1.0'
|
18
|
+
s.add_development_dependency 'rake', '~> 10.0'
|
19
|
+
s.add_development_dependency 'fancy_logger', '~> 0.1'
|
20
|
+
s.add_development_dependency 'rspec', '~> 2.13'
|
21
|
+
s.add_development_dependency 'fuubar', '~> 1.1'
|
22
|
+
|
23
|
+
# Pragmatically set variables
|
24
|
+
s.homepage = "http://github.com/RyanScottLewis/#{s.name}"
|
25
|
+
s.version = Pathname.glob('VERSION*').first.read rescue '0.0.0'
|
26
|
+
s.require_paths = ['lib']
|
27
|
+
s.files = Dir['{{Rake,Gem}file{.lock,},README*,VERSION,LICENSE,*.gemspec,lib/morris-rails**/*.rb,spec/**/*.rb,app/**/*}']
|
28
|
+
s.test_files = Dir['{examples,spec,test}/**/*']
|
29
|
+
|
30
|
+
end
|