d3_rails 2.9.1 → 2.9.2.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/.DS_Store +0 -0
- data/Gemfile +0 -1
- data/README.md +3 -36
- data/lib/.DS_Store +0 -0
- data/{vendor/assets/javascripts/morris → lib/d3_rails}/.DS_Store +0 -0
- data/lib/d3_rails/version.rb +1 -1
- data/vendor/.DS_Store +0 -0
- data/vendor/assets/.DS_Store +0 -0
- data/vendor/assets/javascripts/.DS_Store +0 -0
- data/vendor/assets/javascripts/d3.v2.js +7 -5
- data/vendor/assets/stylesheets/.DS_Store +0 -0
- metadata +13 -72
- data/vendor/assets/javascripts/chart/box.js +0 -297
- data/vendor/assets/javascripts/chart/bullet.js +0 -237
- data/vendor/assets/javascripts/chart/chart.js +0 -1
- data/vendor/assets/javascripts/chart/horizon.js +0 -203
- data/vendor/assets/javascripts/chart/qq.js +0 -245
- data/vendor/assets/javascripts/d3_chart_module.js +0 -1
- data/vendor/assets/javascripts/morris.js +0 -1
- data/vendor/assets/javascripts/morris/Makefile +0 -10
- data/vendor/assets/javascripts/morris/README.md +0 -87
- data/vendor/assets/javascripts/morris/examples/_template.html +0 -18
- data/vendor/assets/javascripts/morris/examples/days.html +0 -36
- data/vendor/assets/javascripts/morris/examples/decimal.html +0 -31
- data/vendor/assets/javascripts/morris/examples/lib/example.css +0 -13
- data/vendor/assets/javascripts/morris/examples/lib/example.js +0 -4
- data/vendor/assets/javascripts/morris/examples/lib/prettify.css +0 -1
- data/vendor/assets/javascripts/morris/examples/lib/prettify.js +0 -28
- data/vendor/assets/javascripts/morris/examples/months-no-smooth.html +0 -37
- data/vendor/assets/javascripts/morris/examples/negative.html +0 -35
- data/vendor/assets/javascripts/morris/examples/non-date.html +0 -36
- data/vendor/assets/javascripts/morris/examples/quarters.html +0 -53
- data/vendor/assets/javascripts/morris/examples/timestamps.html +0 -37
- data/vendor/assets/javascripts/morris/examples/weeks.html +0 -52
- data/vendor/assets/javascripts/morris/morris.coffee +0 -444
- data/vendor/assets/javascripts/morris/morris.js +0 -493
- data/vendor/assets/javascripts/morris/morris.min.js +0 -1
- data/vendor/assets/javascripts/tesseract.js +0 -1
- data/vendor/assets/javascripts/tesseract/.gitignore +0 -2
- data/vendor/assets/javascripts/tesseract/LICENSE +0 -12
- data/vendor/assets/javascripts/tesseract/Makefile +0 -48
- data/vendor/assets/javascripts/tesseract/README.md +0 -11
- data/vendor/assets/javascripts/tesseract/index.js +0 -1
- data/vendor/assets/javascripts/tesseract/lib/dart/AUTHORS +0 -9
- data/vendor/assets/javascripts/tesseract/lib/dart/LICENSE +0 -25
- data/vendor/assets/javascripts/tesseract/lib/dart/dual_pivot_quicksort.dart +0 -342
- data/vendor/assets/javascripts/tesseract/package.json +0 -11
- data/vendor/assets/javascripts/tesseract/src/array.js +0 -32
- data/vendor/assets/javascripts/tesseract/src/bisect.js +0 -44
- data/vendor/assets/javascripts/tesseract/src/filter.js +0 -19
- data/vendor/assets/javascripts/tesseract/src/heap.js +0 -44
- data/vendor/assets/javascripts/tesseract/src/heapselect.js +0 -36
- data/vendor/assets/javascripts/tesseract/src/identity.js +0 -3
- data/vendor/assets/javascripts/tesseract/src/insertionsort.js +0 -18
- data/vendor/assets/javascripts/tesseract/src/null.js +0 -3
- data/vendor/assets/javascripts/tesseract/src/package.js +0 -14
- data/vendor/assets/javascripts/tesseract/src/permute.js +0 -8
- data/vendor/assets/javascripts/tesseract/src/quicksort.js +0 -282
- data/vendor/assets/javascripts/tesseract/src/reduce.js +0 -19
- data/vendor/assets/javascripts/tesseract/src/tesseract.js +0 -663
- data/vendor/assets/javascripts/tesseract/src/version.js +0 -1
- data/vendor/assets/javascripts/tesseract/src/zero.js +0 -3
- data/vendor/assets/javascripts/tesseract/tesseract.js +0 -1177
- data/vendor/assets/javascripts/tesseract/tesseract.min.js +0 -1
- data/vendor/assets/javascripts/tesseract/test/benchmark.js +0 -177
- data/vendor/assets/javascripts/tesseract/test/bisect-test.js +0 -206
- data/vendor/assets/javascripts/tesseract/test/heap-test.js +0 -44
- data/vendor/assets/javascripts/tesseract/test/permute-test.js +0 -51
- data/vendor/assets/javascripts/tesseract/test/select-test.js +0 -63
- data/vendor/assets/javascripts/tesseract/test/sort-test.js +0 -83
- data/vendor/assets/javascripts/tesseract/test/tesseract-test.js +0 -655
- data/vendor/assets/javascripts/tesseract/test/version-test.js +0 -16
@@ -1,52 +0,0 @@
|
|
1
|
-
<!doctype html>
|
2
|
-
<head>
|
3
|
-
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
|
4
|
-
<script src="https://raw.github.com/DmitryBaranovskiy/raphael/300aa589f5a0ba7fce667cd62c7cdda0bd5ad904/raphael-min.js"></script>
|
5
|
-
<script src="../morris.js"></script>
|
6
|
-
<script src="lib/prettify.js"></script>
|
7
|
-
<script src="lib/example.js"></script>
|
8
|
-
<link rel="stylesheet" href="lib/example.css">
|
9
|
-
<link rel="stylesheet" href="lib/prettify.css">
|
10
|
-
</head>
|
11
|
-
<body>
|
12
|
-
<h1>Formatting Dates With Weeks</h1>
|
13
|
-
<div id="graph"></div>
|
14
|
-
<pre id="code" class="prettyprint linenums">
|
15
|
-
var week_data = [
|
16
|
-
{"period": "2011 W27", "licensed": 3407, "sorned": 660},
|
17
|
-
{"period": "2011 W26", "licensed": 3351, "sorned": 629},
|
18
|
-
{"period": "2011 W25", "licensed": 3269, "sorned": 618},
|
19
|
-
{"period": "2011 W24", "licensed": 3246, "sorned": 661},
|
20
|
-
{"period": "2011 W23", "licensed": 3257, "sorned": 667},
|
21
|
-
{"period": "2011 W22", "licensed": 3248, "sorned": 627},
|
22
|
-
{"period": "2011 W21", "licensed": 3171, "sorned": 660},
|
23
|
-
{"period": "2011 W20", "licensed": 3171, "sorned": 676},
|
24
|
-
{"period": "2011 W19", "licensed": 3201, "sorned": 656},
|
25
|
-
{"period": "2011 W18", "licensed": 3215, "sorned": 622},
|
26
|
-
{"period": "2011 W17", "licensed": 3148, "sorned": 632},
|
27
|
-
{"period": "2011 W16", "licensed": 3155, "sorned": 681},
|
28
|
-
{"period": "2011 W15", "licensed": 3190, "sorned": 667},
|
29
|
-
{"period": "2011 W14", "licensed": 3226, "sorned": 620},
|
30
|
-
{"period": "2011 W13", "licensed": 3245, "sorned": null},
|
31
|
-
{"period": "2011 W12", "licensed": 3289, "sorned": null},
|
32
|
-
{"period": "2011 W11", "licensed": 3263, "sorned": null},
|
33
|
-
{"period": "2011 W10", "licensed": 3189, "sorned": null},
|
34
|
-
{"period": "2011 W09", "licensed": 3079, "sorned": null},
|
35
|
-
{"period": "2011 W08", "licensed": 3085, "sorned": null},
|
36
|
-
{"period": "2011 W07", "licensed": 3055, "sorned": null},
|
37
|
-
{"period": "2011 W06", "licensed": 3063, "sorned": null},
|
38
|
-
{"period": "2011 W05", "licensed": 2943, "sorned": null},
|
39
|
-
{"period": "2011 W04", "licensed": 2806, "sorned": null},
|
40
|
-
{"period": "2011 W03", "licensed": 2674, "sorned": null},
|
41
|
-
{"period": "2011 W02", "licensed": 1702, "sorned": null},
|
42
|
-
{"period": "2011 W01", "licensed": 1732, "sorned": null}
|
43
|
-
];
|
44
|
-
Morris.Line({
|
45
|
-
element: 'graph',
|
46
|
-
data: week_data,
|
47
|
-
xkey: 'period',
|
48
|
-
ykeys: ['licensed', 'sorned'],
|
49
|
-
labels: ['Licensed', 'SORN']
|
50
|
-
});
|
51
|
-
</pre>
|
52
|
-
</body>
|
@@ -1,444 +0,0 @@
|
|
1
|
-
# The original line graph.
|
2
|
-
#
|
3
|
-
$ = jQuery
|
4
|
-
|
5
|
-
Morris = {}
|
6
|
-
class Morris.Line
|
7
|
-
# Initialise the graph.
|
8
|
-
#
|
9
|
-
# @param {Object} options
|
10
|
-
constructor: (options) ->
|
11
|
-
if not (this instanceof Morris.Line)
|
12
|
-
return new Morris.Line(options)
|
13
|
-
if typeof options.element is 'string'
|
14
|
-
@el = $ document.getElementById(options.element)
|
15
|
-
else
|
16
|
-
@el = $ options.element
|
17
|
-
@options = $.extend {}, @defaults, options
|
18
|
-
# bail if there's no data
|
19
|
-
if @options.data is undefined or @options.data.length is 0
|
20
|
-
return
|
21
|
-
@el.addClass 'graph-initialised'
|
22
|
-
@precalc()
|
23
|
-
@redraw()
|
24
|
-
|
25
|
-
# Default configuration
|
26
|
-
#
|
27
|
-
defaults:
|
28
|
-
lineWidth: 3
|
29
|
-
pointSize: 4
|
30
|
-
lineColors: [
|
31
|
-
'#0b62a4'
|
32
|
-
'#7A92A3'
|
33
|
-
'#4da74d'
|
34
|
-
'#afd8f8'
|
35
|
-
'#edc240'
|
36
|
-
'#cb4b4b'
|
37
|
-
'#9440ed'
|
38
|
-
]
|
39
|
-
ymax: 'auto'
|
40
|
-
ymin: 'auto 0'
|
41
|
-
marginTop: 25
|
42
|
-
marginRight: 25
|
43
|
-
marginBottom: 30
|
44
|
-
marginLeft: 25
|
45
|
-
numLines: 5
|
46
|
-
gridLineColor: '#aaa'
|
47
|
-
gridTextColor: '#888'
|
48
|
-
gridTextSize: 12
|
49
|
-
gridStrokeWidth: 0.5
|
50
|
-
hoverPaddingX: 10
|
51
|
-
hoverPaddingY: 5
|
52
|
-
hoverMargin: 10
|
53
|
-
hoverFillColor: '#fff'
|
54
|
-
hoverBorderColor: '#ccc'
|
55
|
-
hoverBorderWidth: 2
|
56
|
-
hoverOpacity: 0.95
|
57
|
-
hoverLabelColor: '#444'
|
58
|
-
hoverFontSize: 12
|
59
|
-
smooth: true
|
60
|
-
hideHover: false
|
61
|
-
parseTime: true
|
62
|
-
units: ''
|
63
|
-
dateFormat: (x) -> new Date(x).toString()
|
64
|
-
|
65
|
-
# Do any necessary pre-processing for a new dataset
|
66
|
-
#
|
67
|
-
precalc: ->
|
68
|
-
# sort data
|
69
|
-
@options.data.sort (a, b) => (a[@options.xkey] < b[@options.xkey]) - (b[@options.xkey] < a[@options.xkey])
|
70
|
-
# extract labels
|
71
|
-
@columnLabels = $.map @options.data, (d) => d[@options.xkey]
|
72
|
-
@seriesLabels = @options.labels
|
73
|
-
|
74
|
-
# extract series data
|
75
|
-
@series = []
|
76
|
-
for ykey in @options.ykeys
|
77
|
-
series_data = []
|
78
|
-
for d in @options.data
|
79
|
-
series_data.push(d[ykey])
|
80
|
-
@series.push(series_data)
|
81
|
-
|
82
|
-
# translate x labels into nominal dates
|
83
|
-
# note: currently using decimal years to specify dates
|
84
|
-
if @options.parseTime
|
85
|
-
@xvals = $.map @columnLabels, (x) => @parseYear x
|
86
|
-
else
|
87
|
-
@xvals = [(@columnLabels.length-1)..0]
|
88
|
-
# translate column labels, if they're timestamps
|
89
|
-
if @options.parseTime
|
90
|
-
@columnLabels = $.map @columnLabels, (d) =>
|
91
|
-
if typeof d is 'number'
|
92
|
-
@options.dateFormat(d)
|
93
|
-
else
|
94
|
-
d
|
95
|
-
@xmin = Math.min.apply null, @xvals
|
96
|
-
@xmax = Math.max.apply null, @xvals
|
97
|
-
if @xmin is @xmax
|
98
|
-
@xmin -= 1
|
99
|
-
@xmax += 1
|
100
|
-
|
101
|
-
# Compute the vertical range of the graph if desired
|
102
|
-
if typeof @options.ymax is 'string' and @options.ymax[0..3] is 'auto'
|
103
|
-
# use Array.concat to flatten arrays and find the max y value
|
104
|
-
ymax = Math.max.apply null, Array.prototype.concat.apply([], @series)
|
105
|
-
if @options.ymax.length > 5
|
106
|
-
@options.ymax = Math.max parseInt(@options.ymax[5..], 10), ymax
|
107
|
-
else
|
108
|
-
@options.ymax = ymax
|
109
|
-
if typeof @options.ymin is 'string' and @options.ymin[0..3] is 'auto'
|
110
|
-
ymin = Math.min.apply null, Array.prototype.concat.apply([], @series)
|
111
|
-
if @options.ymin.length > 5
|
112
|
-
@options.ymin = Math.min parseInt(@options.ymin[5..], 10), ymin
|
113
|
-
else
|
114
|
-
@options.ymin = ymin
|
115
|
-
|
116
|
-
# Some instance variables for later
|
117
|
-
@pointGrow = Raphael.animation r: @options.pointSize + 3, 25, 'linear'
|
118
|
-
@pointShrink = Raphael.animation r: @options.pointSize, 25, 'linear'
|
119
|
-
@elementWidth = null
|
120
|
-
@elementHeight = null
|
121
|
-
# column hilight events
|
122
|
-
@prevHilight = null
|
123
|
-
@el.mousemove (evt) =>
|
124
|
-
@updateHilight evt.pageX
|
125
|
-
if @options.hideHover
|
126
|
-
@el.mouseout (evt) =>
|
127
|
-
@hilight null
|
128
|
-
touchHandler = (evt) =>
|
129
|
-
touch = evt.originalEvent.touches[0] or evt.originalEvent.changedTouches[0]
|
130
|
-
@updateHilight touch.pageX
|
131
|
-
return touch
|
132
|
-
@el.bind 'touchstart', touchHandler
|
133
|
-
@el.bind 'touchmove', touchHandler
|
134
|
-
@el.bind 'touchend', touchHandler
|
135
|
-
|
136
|
-
# Do any size-related calculations
|
137
|
-
#
|
138
|
-
calc: ->
|
139
|
-
w = @el.width()
|
140
|
-
h = @el.height()
|
141
|
-
if @elementWidth != w or @elementHeight != h
|
142
|
-
# calculate grid dimensions
|
143
|
-
@maxYLabelWidth = Math.max(
|
144
|
-
@measureText(@options.ymin + @options.units, @options.gridTextSize).width,
|
145
|
-
@measureText(@options.ymax + @options.units, @options.gridTextSize).width)
|
146
|
-
@left = @maxYLabelWidth + @options.marginLeft
|
147
|
-
@width = @el.width() - @left - @options.marginRight
|
148
|
-
@height = @el.height() - @options.marginTop - @options.marginBottom
|
149
|
-
@dx = @width / (@xmax - @xmin)
|
150
|
-
@dy = @height / (@options.ymax - @options.ymin)
|
151
|
-
# calculate series data point coordinates
|
152
|
-
@columns = (@transX(x) for x in @xvals)
|
153
|
-
@seriesCoords = []
|
154
|
-
for s in @series
|
155
|
-
scoords = []
|
156
|
-
$.each s, (i, y) =>
|
157
|
-
if y == null
|
158
|
-
scoords.push(null)
|
159
|
-
else
|
160
|
-
scoords.push(x: @columns[i], y: @transY(y))
|
161
|
-
@seriesCoords.push(scoords)
|
162
|
-
# calculate hover margins
|
163
|
-
@hoverMargins = $.map @columns.slice(1), (x, i) => (x + @columns[i]) / 2
|
164
|
-
|
165
|
-
# quick translation helpers
|
166
|
-
#
|
167
|
-
transX: (x) =>
|
168
|
-
if @xvals.length is 1
|
169
|
-
@left + @width / 2
|
170
|
-
else
|
171
|
-
@left + (x - @xmin) * @dx
|
172
|
-
|
173
|
-
transY: (y) =>
|
174
|
-
return @options.marginTop + @height - (y - @options.ymin) * @dy
|
175
|
-
|
176
|
-
# Clear and redraw the graph
|
177
|
-
#
|
178
|
-
redraw: ->
|
179
|
-
# remove child elements (get rid of old drawings)
|
180
|
-
@el.empty()
|
181
|
-
|
182
|
-
# the raphael drawing instance
|
183
|
-
@r = new Raphael(@el[0])
|
184
|
-
|
185
|
-
@calc()
|
186
|
-
@drawGrid()
|
187
|
-
@drawSeries()
|
188
|
-
@drawHover()
|
189
|
-
@hilight(if @options.hideHover then null else 0)
|
190
|
-
|
191
|
-
# draw the grid, and axes labels
|
192
|
-
#
|
193
|
-
drawGrid: ->
|
194
|
-
# draw y axis labels, horizontal lines
|
195
|
-
yInterval = (@options.ymax - @options.ymin) / (@options.numLines - 1)
|
196
|
-
firstY = Math.ceil(@options.ymin / yInterval) * yInterval
|
197
|
-
lastY = Math.floor(@options.ymax / yInterval) * yInterval
|
198
|
-
for lineY in [firstY..lastY] by yInterval
|
199
|
-
v = Math.floor(lineY)
|
200
|
-
y = @transY(v)
|
201
|
-
@r.text(@left - @options.marginLeft/2, y, @commas(v) + @options.units)
|
202
|
-
.attr('font-size', @options.gridTextSize)
|
203
|
-
.attr('fill', @options.gridTextColor)
|
204
|
-
.attr('text-anchor', 'end')
|
205
|
-
@r.path("M#{@left},#{y}H#{@left + @width}")
|
206
|
-
.attr('stroke', @options.gridLineColor)
|
207
|
-
.attr('stroke-width', @options.gridStrokeWidth)
|
208
|
-
|
209
|
-
## draw x axis labels
|
210
|
-
prevLabelMargin = null
|
211
|
-
xLabelMargin = 50 # make this an option?
|
212
|
-
if @options.parseTime
|
213
|
-
x1 = new Date(@xmin).getFullYear()
|
214
|
-
x2 = new Date(@xmax).getFullYear()
|
215
|
-
else
|
216
|
-
x1 = @xmin
|
217
|
-
x2 = @xmax
|
218
|
-
for i in [x1..x2]
|
219
|
-
if @options.parseTime
|
220
|
-
xpos = new Date(i, 0, 1).getTime()
|
221
|
-
if xpos < @xmin
|
222
|
-
continue
|
223
|
-
else
|
224
|
-
xpos = i
|
225
|
-
labelText = if @options.parseTime then i else @columnLabels[@columnLabels.length-i-1]
|
226
|
-
label = @r.text(@transX(xpos), @options.marginTop + @height + @options.marginBottom / 2, labelText)
|
227
|
-
.attr('font-size', @options.gridTextSize)
|
228
|
-
.attr('fill', @options.gridTextColor)
|
229
|
-
labelBox = label.getBBox()
|
230
|
-
# ensure a minimum of `xLabelMargin` pixels between labels
|
231
|
-
if prevLabelMargin is null or prevLabelMargin <= labelBox.x
|
232
|
-
prevLabelMargin = labelBox.x + labelBox.width + xLabelMargin
|
233
|
-
else
|
234
|
-
label.remove()
|
235
|
-
|
236
|
-
# draw the data series
|
237
|
-
#
|
238
|
-
drawSeries: ->
|
239
|
-
for i in [@seriesCoords.length-1..0]
|
240
|
-
coords = @seriesCoords[i]
|
241
|
-
if coords.length > 1
|
242
|
-
path = @createPath coords, @options.marginTop, @left, @options.marginTop + @height, @left + @width
|
243
|
-
@r.path(path)
|
244
|
-
.attr('stroke', @options.lineColors[i])
|
245
|
-
.attr('stroke-width', @options.lineWidth)
|
246
|
-
@seriesPoints = ([] for i in [0..@seriesCoords.length-1])
|
247
|
-
for i in [@seriesCoords.length-1..0]
|
248
|
-
for c in @seriesCoords[i]
|
249
|
-
if c == null
|
250
|
-
circle = null
|
251
|
-
else
|
252
|
-
circle = @r.circle(c.x, c.y, @options.pointSize)
|
253
|
-
.attr('fill', @options.lineColors[i])
|
254
|
-
.attr('stroke-width', 1)
|
255
|
-
.attr('stroke', '#ffffff')
|
256
|
-
@seriesPoints[i].push(circle)
|
257
|
-
|
258
|
-
# create a path for a data series
|
259
|
-
#
|
260
|
-
createPath: (all_coords, top, left, bottom, right) ->
|
261
|
-
path = ""
|
262
|
-
coords = $.map(all_coords, (c) -> c)
|
263
|
-
if @options.smooth
|
264
|
-
grads = @gradients coords
|
265
|
-
for i in [0..coords.length-1]
|
266
|
-
c = coords[i]
|
267
|
-
if i is 0
|
268
|
-
path += "M#{c.x},#{c.y}"
|
269
|
-
else
|
270
|
-
g = grads[i]
|
271
|
-
lc = coords[i - 1]
|
272
|
-
lg = grads[i - 1]
|
273
|
-
ix = (c.x - lc.x) / 4
|
274
|
-
x1 = lc.x + ix
|
275
|
-
y1 = Math.min(bottom, lc.y + ix * lg)
|
276
|
-
x2 = c.x - ix
|
277
|
-
y2 = Math.min(bottom, c.y - ix * g)
|
278
|
-
path += "C#{x1},#{y1},#{x2},#{y2},#{c.x},#{c.y}"
|
279
|
-
else
|
280
|
-
path = "M" + $.map(coords, (c) -> "#{c.x},#{c.y}").join("L")
|
281
|
-
return path
|
282
|
-
|
283
|
-
# calculate a gradient at each point for a series of points
|
284
|
-
#
|
285
|
-
gradients: (coords) ->
|
286
|
-
$.map coords, (c, i) ->
|
287
|
-
if i is 0
|
288
|
-
(coords[1].y - c.y) / (coords[1].x - c.x)
|
289
|
-
else if i is (coords.length - 1)
|
290
|
-
(c.y - coords[i - 1].y) / (c.x - coords[i - 1].x)
|
291
|
-
else
|
292
|
-
(coords[i + 1].y - coords[i - 1].y) / (coords[i + 1].x - coords[i - 1].x)
|
293
|
-
|
294
|
-
# draw the hover tooltip
|
295
|
-
#
|
296
|
-
drawHover: ->
|
297
|
-
# hover labels
|
298
|
-
@hoverHeight = @options.hoverFontSize * 1.5 * (@series.length + 1)
|
299
|
-
@hover = @r.rect(-10, -@hoverHeight / 2 - @options.hoverPaddingY, 20, @hoverHeight + @options.hoverPaddingY * 2, 10)
|
300
|
-
.attr('fill', @options.hoverFillColor)
|
301
|
-
.attr('stroke', @options.hoverBorderColor)
|
302
|
-
.attr('stroke-width', @options.hoverBorderWidth)
|
303
|
-
.attr('opacity', @options.hoverOpacity)
|
304
|
-
@xLabel = @r.text(0, (@options.hoverFontSize * 0.75) - @hoverHeight / 2, '')
|
305
|
-
.attr('fill', @options.hoverLabelColor)
|
306
|
-
.attr('font-weight', 'bold')
|
307
|
-
.attr('font-size', @options.hoverFontSize)
|
308
|
-
@hoverSet = @r.set()
|
309
|
-
@hoverSet.push(@hover)
|
310
|
-
@hoverSet.push(@xLabel)
|
311
|
-
@yLabels = []
|
312
|
-
for i in [0..@series.length-1]
|
313
|
-
yLabel = @r.text(0, @options.hoverFontSize * 1.5 * (i + 1.5) - @hoverHeight / 2, '')
|
314
|
-
.attr('fill', @options.lineColors[i])
|
315
|
-
.attr('font-size', @options.hoverFontSize)
|
316
|
-
@yLabels.push(yLabel)
|
317
|
-
@hoverSet.push(yLabel)
|
318
|
-
|
319
|
-
updateHover: (index) =>
|
320
|
-
@hoverSet.show()
|
321
|
-
@xLabel.attr('text', @columnLabels[index])
|
322
|
-
for i in [0..@series.length-1]
|
323
|
-
@yLabels[i].attr('text', "#{@seriesLabels[i]}: #{@commas(@series[i][index])}#{@options.units}")
|
324
|
-
# recalculate hover box width
|
325
|
-
maxLabelWidth = Math.max.apply null, $.map @yLabels, (l) ->
|
326
|
-
l.getBBox().width
|
327
|
-
maxLabelWidth = Math.max maxLabelWidth, @xLabel.getBBox().width
|
328
|
-
@hover.attr 'width', maxLabelWidth + @options.hoverPaddingX * 2
|
329
|
-
@hover.attr 'x', -@options.hoverPaddingX - maxLabelWidth / 2
|
330
|
-
# move to y pos
|
331
|
-
yloc = Math.min.apply null, $.map @series, (s) =>
|
332
|
-
@transY s[index]
|
333
|
-
if yloc > @hoverHeight + @options.hoverPaddingY * 2 + @options.hoverMargin + @options.marginTop
|
334
|
-
yloc = yloc - @hoverHeight / 2 - @options.hoverPaddingY - @options.hoverMargin
|
335
|
-
else
|
336
|
-
yloc = yloc + @hoverHeight / 2 + @options.hoverPaddingY + @options.hoverMargin
|
337
|
-
yloc = Math.max @options.marginTop + @hoverHeight / 2 + @options.hoverPaddingY, yloc
|
338
|
-
yloc = Math.min @options.marginTop + @height - @hoverHeight / 2 - @options.hoverPaddingY, yloc
|
339
|
-
xloc = Math.min @left + @width - maxLabelWidth / 2 - @options.hoverPaddingX, @columns[index]
|
340
|
-
xloc = Math.max @left + maxLabelWidth / 2 + @options.hoverPaddingX, xloc
|
341
|
-
@hoverSet.attr 'transform', "t#{xloc},#{yloc}"
|
342
|
-
|
343
|
-
hideHover: ->
|
344
|
-
@hoverSet.hide()
|
345
|
-
|
346
|
-
hilight: (index) =>
|
347
|
-
if @prevHilight isnt null and @prevHilight isnt index
|
348
|
-
for i in [0..@seriesPoints.length-1]
|
349
|
-
if @seriesPoints[i][@prevHilight]
|
350
|
-
@seriesPoints[i][@prevHilight].animate @pointShrink
|
351
|
-
if index isnt null and @prevHilight isnt index
|
352
|
-
for i in [0..@seriesPoints.length-1]
|
353
|
-
if @seriesPoints[i][index]
|
354
|
-
@seriesPoints[i][index].animate @pointGrow
|
355
|
-
@updateHover index
|
356
|
-
@prevHilight = index
|
357
|
-
if index is null
|
358
|
-
@hideHover()
|
359
|
-
|
360
|
-
updateHilight: (x) =>
|
361
|
-
x -= @el.offset().left
|
362
|
-
for hoverIndex in [@hoverMargins.length..0]
|
363
|
-
if hoverIndex == 0 || @hoverMargins[hoverIndex - 1] > x
|
364
|
-
@hilight hoverIndex
|
365
|
-
break
|
366
|
-
|
367
|
-
measureText: (text, fontSize = 12) ->
|
368
|
-
tt = @r.text(100, 100, text).attr('font-size', fontSize)
|
369
|
-
ret = tt.getBBox()
|
370
|
-
tt.remove()
|
371
|
-
return ret
|
372
|
-
|
373
|
-
parseYear: (date) ->
|
374
|
-
if typeof date is 'number'
|
375
|
-
return date
|
376
|
-
m = date.match /^(\d+) Q(\d)$/
|
377
|
-
n = date.match /^(\d+)-(\d+)$/
|
378
|
-
o = date.match /^(\d+)-(\d+)-(\d+)$/
|
379
|
-
p = date.match /^(\d+) W(\d+)$/
|
380
|
-
q = date.match /^(\d+)-(\d+)-(\d+) (\d+):(\d+)$/
|
381
|
-
r = date.match /^(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+(\.\d+)?)$/
|
382
|
-
if m
|
383
|
-
new Date(
|
384
|
-
parseInt(m[1], 10),
|
385
|
-
parseInt(m[2], 10) * 3 - 1,
|
386
|
-
1).getTime()
|
387
|
-
else if n
|
388
|
-
new Date(
|
389
|
-
parseInt(n[1], 10),
|
390
|
-
parseInt(n[2], 10) - 1,
|
391
|
-
1).getTime()
|
392
|
-
else if o
|
393
|
-
new Date(
|
394
|
-
parseInt(o[1], 10),
|
395
|
-
parseInt(o[2], 10) - 1,
|
396
|
-
parseInt(o[3], 10)).getTime()
|
397
|
-
else if p
|
398
|
-
# calculate number of weeks in year given
|
399
|
-
ret = new Date(parseInt(p[1], 10), 0, 1);
|
400
|
-
# first thursday in year (ISO 8601 standard)
|
401
|
-
if ret.getDay() isnt 4
|
402
|
-
ret.setMonth(0, 1 + ((4 - ret.getDay()) + 7) % 7);
|
403
|
-
# add weeks
|
404
|
-
ret.getTime() + parseInt(p[2], 10) * 604800000
|
405
|
-
else if q
|
406
|
-
new Date(
|
407
|
-
parseInt(q[1], 10),
|
408
|
-
parseInt(q[2], 10) - 1,
|
409
|
-
parseInt(q[3], 10),
|
410
|
-
parseInt(q[4], 10),
|
411
|
-
parseInt(q[5], 10)).getTime()
|
412
|
-
else if r
|
413
|
-
secs = parseFloat(r[6])
|
414
|
-
isecs = Math.floor(secs)
|
415
|
-
msecs = Math.floor((secs - isecs) * 1000)
|
416
|
-
new Date(
|
417
|
-
parseInt(r[1], 10),
|
418
|
-
parseInt(r[2], 10) - 1,
|
419
|
-
parseInt(r[3], 10),
|
420
|
-
parseInt(r[4], 10),
|
421
|
-
parseInt(r[5], 10),
|
422
|
-
isecs,
|
423
|
-
msecs).getTime()
|
424
|
-
else
|
425
|
-
new Date(parseInt(date, 10), 0, 1)
|
426
|
-
|
427
|
-
# make long numbers prettier by inserting commas
|
428
|
-
# eg: commas(1234567) -> '1,234,567'
|
429
|
-
#
|
430
|
-
commas: (num) ->
|
431
|
-
if num is null
|
432
|
-
"n/a"
|
433
|
-
else
|
434
|
-
ret = if num < 0 then "-" else ""
|
435
|
-
absnum = Math.abs(num)
|
436
|
-
intnum = Math.floor(absnum).toFixed(0)
|
437
|
-
ret += intnum.replace(/(?=(?:\d{3})+$)(?!^)/g, ',')
|
438
|
-
strabsnum = absnum.toString()
|
439
|
-
if strabsnum.length > intnum.length
|
440
|
-
ret += strabsnum.slice(intnum.length)
|
441
|
-
ret
|
442
|
-
|
443
|
-
window.Morris = Morris
|
444
|
-
# vim: set et ts=2 sw=2 sts=2
|