mountain-goat 0.0.12 → 0.0.13
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/lib/flotilla.rb +136 -135
- data/lib/mountain-goat/version.rb +1 -1
- metadata +3 -3
data/lib/flotilla.rb
CHANGED
@@ -4,61 +4,44 @@ rescue LoadError
|
|
4
4
|
p "Flotilla will not work without the 'json' gem"
|
5
5
|
end
|
6
6
|
|
7
|
-
module
|
7
|
+
module Flotilla
|
8
8
|
module Helpers
|
9
|
-
module ScriptaculousHelper
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
10
|
+
# Insert a flot chart into the page. <tt>placeholder</tt> should be the
|
11
|
+
# name of the div that will hold the chart, <tt>collections</tt> is a hash
|
12
|
+
# of legends (as strings) and datasets with options as hashes, <tt>options</tt>
|
13
|
+
# contains graph-wide options.
|
14
|
+
#
|
15
|
+
# Example usage:
|
16
|
+
#
|
17
|
+
# chart("graph_div", {
|
18
|
+
# "January" => { :collection => @january, :x => :day, :y => :sales, :options => { :lines => {:show =>true}} },
|
19
|
+
# "February" => { :collection => @february, :x => :day, :y => :sales, :options => { :points => {:show =>true} } },
|
20
|
+
# :grid => { :backgroundColor => "#fffaff" })
|
21
|
+
#
|
22
|
+
# Options:
|
23
|
+
# :js_includes - includes flot library inline
|
24
|
+
# :js_tags - wraps resulting javascript in javascript tags if true. Defaults to true.
|
25
|
+
# :placeholder_tag - appends a placeholder div for graph
|
26
|
+
# :placeholder_size - specifys the size of the placeholder div
|
27
|
+
def chart(placeholder, series, options = {}, html_options = {})
|
28
|
+
html_options.reverse_merge!({ :js_includes => true, :js_tags => true, :placeholder_tag => true, :placeholder_size => "800x300", :pie_hover => false, :pie_hover_absolute => false })
|
29
|
+
width, height = html_options[:placeholder_size].split("x") if html_options[:placeholder_size].respond_to?(:split)
|
30
|
+
additional_js = get_additional_js(placeholder, html_options)
|
31
|
+
|
32
|
+
data, x_is_date, y_is_date = series_to_json(series)
|
33
|
+
if x_is_date
|
34
|
+
options[:xaxis] ||= {}
|
35
|
+
options[:xaxis].merge!({ :mode => 'time' })
|
36
|
+
end
|
37
|
+
if y_is_date
|
38
|
+
options[:yaxis] ||= {}
|
39
|
+
options[:yaxis].merge!({ :mode => 'time' })
|
40
|
+
end
|
42
41
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
(function () {
|
47
|
-
if (typeof(jQuery) == 'undefined') {
|
48
|
-
alert("Please include jQuery to view flot");
|
49
|
-
} else {
|
50
|
-
if (typeof(jQuery.plot) == 'undefined') {
|
51
|
-
$('##{placeholder}').html("<span class='flot-error'>Please include jQuery.plot to view flot</span>");
|
52
|
-
} else {
|
53
|
-
var plot = jQuery.plot($('##{placeholder}'), #{data}, #{options.to_json});
|
54
|
-
#{additional_js}
|
55
|
-
}
|
56
|
-
}
|
57
|
-
})();
|
58
|
-
</script>
|
59
|
-
EOF
|
60
|
-
else
|
61
|
-
chart_js = <<-EOF
|
42
|
+
if html_options[:js_includes]
|
43
|
+
chart_js = <<-EOF
|
44
|
+
<script type="text/javascript">
|
62
45
|
(function () {
|
63
46
|
if (typeof(jQuery) == 'undefined') {
|
64
47
|
alert("Please include jQuery to view flot");
|
@@ -71,99 +54,117 @@ module ActionView
|
|
71
54
|
}
|
72
55
|
}
|
73
56
|
})();
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
57
|
+
</script>
|
58
|
+
EOF
|
59
|
+
else
|
60
|
+
chart_js = <<-EOF
|
61
|
+
(function () {
|
62
|
+
if (typeof(jQuery) == 'undefined') {
|
63
|
+
alert("Please include jQuery to view flot");
|
64
|
+
} else {
|
65
|
+
if (typeof(jQuery.plot) == 'undefined') {
|
66
|
+
$('##{placeholder}').html("<span class='flot-error'>Please include jQuery.plot to view flot</span>");
|
67
|
+
} else {
|
68
|
+
var plot = jQuery.plot($('##{placeholder}'), #{data}, #{options.to_json});
|
69
|
+
#{additional_js}
|
70
|
+
}
|
71
|
+
}
|
72
|
+
})();
|
73
|
+
EOF
|
74
|
+
end
|
75
|
+
|
76
|
+
html_options[:js_tags] ? javascript_tag(chart_js) : chart_js
|
77
|
+
output = html_options[:placeholder_tag] ? content_tag(:div, nil, :id => placeholder, :style => "width:#{width}px;height:#{height}px;", :class => "chart") + chart_js : chart_js
|
78
|
+
output.html_safe
|
79
|
+
end
|
81
80
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
end
|
81
|
+
private
|
82
|
+
def series_to_json(series)
|
83
|
+
data_sets = []
|
84
|
+
x_is_date, y_is_date = false, false
|
85
|
+
series.each do |name, values|
|
86
|
+
set, data = {}, []
|
87
|
+
set[:label] = name
|
88
|
+
first = values[:collection].first
|
89
|
+
logger.warn "Collection is: #{values[:collection].inspect}"
|
90
|
+
if first #&& !values[:collection].is_a?(Array)
|
91
|
+
if first.is_a?(Hash)
|
92
|
+
x_is_date = first[values[:x]].acts_like?(:date) || first[values[:x]].acts_like?(:time)
|
93
|
+
y_is_date = first[values[:y]].acts_like?(:date) || first[values[:y]].acts_like?(:time)
|
94
|
+
else
|
95
|
+
x_is_date = first.send(values[:x]).acts_like?(:date) || first.send(values[:x]).acts_like?(:time)
|
96
|
+
y_is_date = first.send(values[:y]).acts_like?(:date) || first.send(values[:y]).acts_like?(:time)
|
99
97
|
end
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
x = x_is_date ? x_value.to_time.to_i * 1000 : x_value.to_f
|
109
|
-
y = y_is_date ? y_value.to_time.to_i * 1000 : y_value.to_f
|
110
|
-
#logger.warn "Tally x,y: #{[x, y]}"
|
111
|
-
data << [x,y]
|
98
|
+
end
|
99
|
+
values[:collection].each do |object|
|
100
|
+
if values[:collection].is_a?(Hash) || object.is_a?(Hash)
|
101
|
+
x_value, y_value = object[values[:x]], object[values[:y]]
|
102
|
+
#logger.warn "A: Object is: #{object}, x,y: #{[x_value, y_value]} from #{[values[:x], values[:y]]}"
|
103
|
+
else
|
104
|
+
x_value, y_value = object.send(values[:x]), object.send(values[:y])
|
105
|
+
#logger.warn "B: Object is: #{object}, x,y: #{[x_value, y_value]}"
|
112
106
|
end
|
113
|
-
|
114
|
-
|
115
|
-
|
107
|
+
x = x_is_date ? x_value.to_time.to_i * 1000 : x_value.to_f
|
108
|
+
y = y_is_date ? y_value.to_time.to_i * 1000 : y_value.to_f
|
109
|
+
#logger.warn "Tally x,y: #{[x, y]}"
|
110
|
+
data << [x,y]
|
116
111
|
end
|
117
|
-
|
112
|
+
set[:data] = data
|
113
|
+
values[:options].each {|option, parameters| set[option] = parameters } if values[:options]
|
114
|
+
data_sets << set
|
118
115
|
end
|
116
|
+
return data_sets.to_json, x_is_date, y_is_date
|
117
|
+
end
|
119
118
|
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
plot.unhighlight();
|
148
|
-
plot.highlight(item.series, item.datapoint);
|
149
|
-
$(this).data('previous-post', item.seriesIndex);
|
150
|
-
}
|
151
|
-
$("#tooltip").remove();
|
152
|
-
#{ options[:line_hover_absolute] ? "y = 'on ' + (new Date(item.datapoint[0])).toDateString() + ': ' + item.datapoint[1] + ' #{options[:item_title] || ''}'" : !options[:pie_hover_absolute] ? "y = item.datapoint[0].toFixed(0) + '%';" : "y = item.datapoint[1][0][1] + ' #{options[:item_title] || ''}'" }
|
153
|
-
showTooltip(pos.pageX, pos.pageY, item.series.label + " " + y);
|
154
|
-
} else {
|
155
|
-
//console.log('unhighlight (3)');
|
119
|
+
def get_additional_js(placeholder, options)
|
120
|
+
res = ""
|
121
|
+
if options[:pie_hover]
|
122
|
+
res << <<-EOF
|
123
|
+
function showTooltip(x, y, contents) {
|
124
|
+
$('<div id="tooltip">' + contents + '</div>').css( {
|
125
|
+
position: 'absolute',
|
126
|
+
//display: 'none',
|
127
|
+
top: y + 5,
|
128
|
+
left: x + 5,
|
129
|
+
border: '1px solid #fdd',
|
130
|
+
padding: '2px',
|
131
|
+
'background-color': '#fee',
|
132
|
+
opacity: 0.80
|
133
|
+
}).appendTo("body");//.fadeIn(200);
|
134
|
+
}
|
135
|
+
|
136
|
+
var previousPoint = null;
|
137
|
+
$('##{placeholder}').bind('mouseout', function() {
|
138
|
+
plot.unhighlight();
|
139
|
+
$("#tooltip").remove();
|
140
|
+
$(this).data('previous-post', -1);
|
141
|
+
});
|
142
|
+
|
143
|
+
$('##{placeholder}').bind('plothover', function(event, pos, item) {
|
144
|
+
if (item) {
|
145
|
+
if ($(this).data('previous-post') != item.seriesIndex) {
|
156
146
|
plot.unhighlight();
|
157
|
-
|
158
|
-
|
147
|
+
plot.highlight(item.series, item.datapoint);
|
148
|
+
$(this).data('previous-post', item.seriesIndex);
|
159
149
|
}
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
150
|
+
$("#tooltip").remove();
|
151
|
+
#{ options[:line_hover_absolute] ? "y = 'on ' + (new Date(item.datapoint[0])).toDateString() + ': ' + item.datapoint[1] + ' #{options[:item_title] || ''}'" : !options[:pie_hover_absolute] ? "y = item.datapoint[0].toFixed(0) + '%';" : "y = item.datapoint[1][0][1] + ' #{options[:item_title] || ''}'" }
|
152
|
+
showTooltip(pos.pageX, pos.pageY, item.series.label + " " + y);
|
153
|
+
} else {
|
154
|
+
//console.log('unhighlight (3)');
|
155
|
+
plot.unhighlight();
|
156
|
+
$("#tooltip").remove();
|
157
|
+
previousPost = $(this).data('previous-post', -1);
|
158
|
+
}
|
159
|
+
});
|
160
|
+
EOF
|
165
161
|
end
|
162
|
+
|
163
|
+
res
|
166
164
|
end
|
167
165
|
end
|
168
166
|
end
|
169
167
|
|
168
|
+
class ActionView::Base
|
169
|
+
include Flotilla::Helpers
|
170
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mountain-goat
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 5
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 13
|
10
|
+
version: 0.0.13
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Geoffrey Hayes
|