-
Notifications
You must be signed in to change notification settings - Fork 57
/
chart_helpers.rb
107 lines (93 loc) · 3.37 KB
/
chart_helpers.rb
1
2
3
4
5
6
7
8
9
10
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
require 'json'
require 'bigdecimal'
module Chartjs
module ChartHelpers
CHART_TYPES = %w[ bar bubble doughnut horizontal_bar line pie polar_area radar scatter ]
module Explicit
CHART_TYPES.each do |type|
define_method "chartjs_#{type}_chart" do |data, options = {}, plugins = {}| # def chartjs_polar_area_chart(data, options = {}, plugins = {})
chart type, data, options, plugins # chart 'polar_area', data, options, plugins
end # end
end
include Chartjs::ChartHelpers
end
module Implicit
CHART_TYPES.each do |type|
define_method "#{type}_chart" do |data, options = {}, plugins = {}| # def polar_area_chart(data, options = {}, plugins = {})
chart type, data, options, plugins # chart 'polar_area', data, options, plugins
end # end
end
include Chartjs::ChartHelpers
end
private
def chart(type, data, options, plugins)
opts = options.dup
@chart_id ||= -1
element_id = opts.delete(:id) || "chart-#{@chart_id += 1}"
css_class = opts.delete(:class) || 'chart'
width = opts.delete(:width) || '400'
height = opts.delete(:height) || '400'
canvas = content_tag :canvas, '', id: element_id, class: css_class, width: width, height: height
script = javascript_tag(nonce: true) do
<<-END.squish.html_safe
(function() {
var initChart = function() {
var ctx = document.getElementById(#{element_id.to_json});
var chart = new Chart(ctx, {
type: "#{camel_case type}",
data: #{to_javascript_string data},
options: #{to_javascript_string opts},
plugins: #{to_javascript_string plugins},
});
};
if (typeof Chart !== "undefined" && Chart !== null) {
initChart();
}
else {
/* W3C standard */
if (window.addEventListener) {
window.addEventListener("load", initChart, false);
}
/* IE */
else if (window.attachEvent) {
window.attachEvent("onload", initChart);
}
}
})();
END
end
canvas + script
end
# polar_area -> polarArea
def camel_case(string)
string.gsub(/_([a-z])/) { $1.upcase }
end
def to_javascript_string(element)
case element
when Hash
hash_elements = []
element.each do |key, value|
hash_elements << camel_case(key.to_s).to_json + ':' + to_javascript_string(value)
end
'{' + hash_elements.join(',') + '}'
when Array
array_elements = []
element.each do |value|
array_elements << to_javascript_string(value)
end
'[' + array_elements.join(',') + ']'
when String
if element.match(/^\s*function.*}\s*$/m)
# Raw-copy function definitions to the output without surrounding quotes.
element
else
element.to_json
end
when BigDecimal
element.to_s
else
element.to_json
end
end
end
end