smart_chart 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +5 -0
- data/LICENSE +20 -0
- data/README.rdoc +187 -0
- data/Rakefile +56 -0
- data/lib/smart_chart/base_chart.rb +428 -0
- data/lib/smart_chart/charts/bar.rb +20 -0
- data/lib/smart_chart/charts/line.rb +22 -0
- data/lib/smart_chart/charts/map.rb +163 -0
- data/lib/smart_chart/charts/meter.rb +13 -0
- data/lib/smart_chart/charts/pie.rb +32 -0
- data/lib/smart_chart/charts/qr_code.rb +85 -0
- data/lib/smart_chart/charts/radar.rb +14 -0
- data/lib/smart_chart/charts/scatter.rb +21 -0
- data/lib/smart_chart/charts/venn.rb +13 -0
- data/lib/smart_chart/data_set.rb +15 -0
- data/lib/smart_chart/encoder.rb +226 -0
- data/lib/smart_chart/exceptions.rb +43 -0
- data/lib/smart_chart/features/axis_lines.rb +29 -0
- data/lib/smart_chart/features/grid_lines.rb +47 -0
- data/lib/smart_chart/features/labels.rb +23 -0
- data/lib/smart_chart/multiple_data_set_chart.rb +128 -0
- data/lib/smart_chart/single_data_set_chart.rb +56 -0
- data/lib/smart_chart.rb +30 -0
- data/test/smart_charts_test.rb +400 -0
- data/test/test_helper.rb +42 -0
- metadata +82 -0
@@ -0,0 +1,20 @@
|
|
1
|
+
module SmartChart
|
2
|
+
class Bar < MultipleDataSetChart
|
3
|
+
include GridLines
|
4
|
+
|
5
|
+
private # ---------------------------------------------------------------
|
6
|
+
|
7
|
+
##
|
8
|
+
# Specify the Google Chart type.
|
9
|
+
#
|
10
|
+
def type
|
11
|
+
"b" +
|
12
|
+
(orientation == :horizontal ? "h" : "v") +
|
13
|
+
(style == :stacked ? "s" : "g")
|
14
|
+
end
|
15
|
+
|
16
|
+
# zero line
|
17
|
+
def chp
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module SmartChart
|
2
|
+
class Line < MultipleDataSetChart
|
3
|
+
include GridLines
|
4
|
+
|
5
|
+
|
6
|
+
private # ---------------------------------------------------------------
|
7
|
+
|
8
|
+
##
|
9
|
+
# Specify the Google Chart type.
|
10
|
+
#
|
11
|
+
def type
|
12
|
+
"lc"
|
13
|
+
end
|
14
|
+
|
15
|
+
##
|
16
|
+
# Array of all possible query string parameters.
|
17
|
+
#
|
18
|
+
def query_string_params
|
19
|
+
super + [:chg]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,163 @@
|
|
1
|
+
module SmartChart
|
2
|
+
class Map < SingleDataSetChart
|
3
|
+
|
4
|
+
##
|
5
|
+
# Array of valid ISO 3166-1-alpha-2 country codes.
|
6
|
+
# Source: http://code.google.com/apis/chart/isocodes.html
|
7
|
+
#
|
8
|
+
def self.country_codes
|
9
|
+
%w[
|
10
|
+
AF AX AL DZ AS AD AO AI AQ AG AR AM AW AU AT AZ BS BH BD BB BY BE
|
11
|
+
BZ BJ BM BT BO BA BW BV BR IO BN BG BF BI KH CM CA CV KY CF TD CL
|
12
|
+
CN CX CC CO KM CG CD CK CR CI HR CU CY CZ DK DJ DM DO EC EG SV GQ
|
13
|
+
ER EE ET FK FO FJ FI FR GF PF TF GA GM GE DE GH GI GR GL GD GP GU
|
14
|
+
GT GG GN GW GY HT HM VA HN HK HU IS IN ID IR IQ IE IM IL IT JM JP
|
15
|
+
JE JO KZ KE KI KP KR KW KG LA LV LB LS LR LY LI LT LU MO MK MG MW
|
16
|
+
MY MV ML MT MH MQ MR MU YT MX FM MD MC MN ME MS MA MZ MM NA NR NP
|
17
|
+
NL AN NC NZ NI NE NG NU NF MP NO OM PK PW PS PA PG PY PE PH PN PL
|
18
|
+
PT PR QA RE RO RU RW BL SH KN LC MF PM VC WS SM ST SA SN RS SC SL
|
19
|
+
SG SK SI SB SO ZA GS ES LK SD SR SJ SZ SE CH SY TW TJ TZ TH TL TG
|
20
|
+
TK TO TT TN TR TM TC TV UG UA AE GB US UM UY UZ VU VE VN VG VI WF
|
21
|
+
EH YE ZM ZW
|
22
|
+
]
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Array of valid US state codes.
|
27
|
+
# Source: http://code.google.com/apis/chart/statecodes.html
|
28
|
+
#
|
29
|
+
def self.us_state_codes
|
30
|
+
%w[
|
31
|
+
AK AL AR AZ CA CO CT DE FL GA HI IA ID IL IN KS KY LA MA MD ME MI
|
32
|
+
MN MO MS MT NC ND NE NH NJ NM NV NY OH OK OR PA RI SC SD TN TX UT
|
33
|
+
VA VT WA WI WV WY
|
34
|
+
]
|
35
|
+
end
|
36
|
+
|
37
|
+
##
|
38
|
+
# Array of valid map regions.
|
39
|
+
#
|
40
|
+
def self.regions
|
41
|
+
%w[
|
42
|
+
africa
|
43
|
+
asia
|
44
|
+
europe
|
45
|
+
middle_east
|
46
|
+
south_america
|
47
|
+
usa
|
48
|
+
world
|
49
|
+
]
|
50
|
+
end
|
51
|
+
|
52
|
+
# region to be depicted (default "world", see Map.regions for choices)
|
53
|
+
attr_accessor :region
|
54
|
+
|
55
|
+
# color of countries or states with no data (default white)
|
56
|
+
attr_accessor :foreground
|
57
|
+
|
58
|
+
|
59
|
+
private # ---------------------------------------------------------------
|
60
|
+
|
61
|
+
##
|
62
|
+
# Specify the Google Chart type.
|
63
|
+
#
|
64
|
+
def type
|
65
|
+
"t"
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# Array of all possible query string parameters.
|
70
|
+
#
|
71
|
+
def query_string_params
|
72
|
+
super + [
|
73
|
+
:chtm, # region
|
74
|
+
:chld, # countries/states
|
75
|
+
]
|
76
|
+
end
|
77
|
+
|
78
|
+
##
|
79
|
+
# Map region query string parameter.
|
80
|
+
#
|
81
|
+
def chtm
|
82
|
+
region || "world"
|
83
|
+
end
|
84
|
+
|
85
|
+
##
|
86
|
+
# Countries or states to be indicated on the map.
|
87
|
+
#
|
88
|
+
def chld
|
89
|
+
labels.join
|
90
|
+
end
|
91
|
+
|
92
|
+
##
|
93
|
+
# Chart color parameter: default ("foreground") plus gradient.
|
94
|
+
#
|
95
|
+
def chco
|
96
|
+
([foreground || "FFFFFF"] + super.to_a).join(",")
|
97
|
+
end
|
98
|
+
|
99
|
+
##
|
100
|
+
# Get the labels (auto-upcase).
|
101
|
+
#
|
102
|
+
def labels
|
103
|
+
super.map{ |i| i.to_s.upcase } unless super.nil?
|
104
|
+
end
|
105
|
+
|
106
|
+
##
|
107
|
+
# Array of validations to be run on the chart.
|
108
|
+
#
|
109
|
+
def validations
|
110
|
+
super + [:map_region]
|
111
|
+
end
|
112
|
+
|
113
|
+
##
|
114
|
+
# Validate the given map region against Google's available options.
|
115
|
+
#
|
116
|
+
def validate_map_region
|
117
|
+
unless region.nil? or Map.regions.include?(region.to_s)
|
118
|
+
raise DataFormatError,
|
119
|
+
"Map region must be one of: #{Map.regions.join(', ')}"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
##
|
124
|
+
# Make sure colors are valid hex codes.
|
125
|
+
#
|
126
|
+
def validate_colors
|
127
|
+
super
|
128
|
+
validate_color(foreground) if foreground
|
129
|
+
end
|
130
|
+
|
131
|
+
##
|
132
|
+
# Make sure the given country codes are specified by ISO 3316.
|
133
|
+
#
|
134
|
+
def validate_labels
|
135
|
+
return if labels.nil?
|
136
|
+
# validate states
|
137
|
+
if region.to_s == "usa"
|
138
|
+
invalids = labels - Map.us_state_codes
|
139
|
+
unless invalids.size == 0
|
140
|
+
raise DataFormatError,
|
141
|
+
"Invalid state code(s): #{invalids.join(', ')}"
|
142
|
+
end
|
143
|
+
# validate countries
|
144
|
+
else
|
145
|
+
invalids = labels - Map.country_codes
|
146
|
+
unless invalids.size == 0
|
147
|
+
raise DataFormatError,
|
148
|
+
"Invalid country code(s): #{invalids.join(', ')}"
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
##
|
154
|
+
# Make sure chart dimensions are within Google's 440x220 limit.
|
155
|
+
#
|
156
|
+
def validate_dimensions
|
157
|
+
if width > 440 or height > 220
|
158
|
+
raise DimensionsError,
|
159
|
+
"Map dimensions may not exceed 440x220 pixels"
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module SmartChart
|
2
|
+
class Pie < SingleDataSetChart
|
3
|
+
|
4
|
+
# number of degrees to rotate start of first slice from 12 o'clock
|
5
|
+
attr_accessor :rotate
|
6
|
+
|
7
|
+
|
8
|
+
private # ---------------------------------------------------------------
|
9
|
+
|
10
|
+
##
|
11
|
+
# Specify the Google Chart type.
|
12
|
+
#
|
13
|
+
def type
|
14
|
+
case style.to_s
|
15
|
+
when "concentric": "pc"
|
16
|
+
when "3d": "p3"
|
17
|
+
else "p"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
##
|
22
|
+
# Rotation. Google expects radians from 3 o'clock.
|
23
|
+
#
|
24
|
+
def chp
|
25
|
+
r = rotate || 0
|
26
|
+
s = SmartChart.decimal_string(
|
27
|
+
((r - 90) % 360) * Math::PI / 180.0
|
28
|
+
)
|
29
|
+
s == "0" ? nil : s # omit parameter if zero
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module SmartChart
|
2
|
+
class QRCode < SingleDataSetChart
|
3
|
+
|
4
|
+
# output encoding
|
5
|
+
# :utf8 (default), :shift_jis, :iso88591
|
6
|
+
attr_accessor :encoding
|
7
|
+
|
8
|
+
# error correction level
|
9
|
+
# :l (default), :m, :q, or :h
|
10
|
+
attr_accessor :ec_level
|
11
|
+
|
12
|
+
# chart margin, in rows/columns
|
13
|
+
attr_accessor :margin
|
14
|
+
|
15
|
+
def self.ec_levels
|
16
|
+
%w[L M Q H]
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
private # ---------------------------------------------------------------
|
21
|
+
|
22
|
+
##
|
23
|
+
# Specify the Google Chart type.
|
24
|
+
#
|
25
|
+
def type
|
26
|
+
"qr"
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# Array of all possible query string parameters.
|
31
|
+
#
|
32
|
+
def query_string_params
|
33
|
+
[:cht, :chs, :chl, :chld, :choe]
|
34
|
+
end
|
35
|
+
|
36
|
+
##
|
37
|
+
# Raise an exception unless the provided data is given as a string and
|
38
|
+
# not too long.
|
39
|
+
#
|
40
|
+
def validate_data_format
|
41
|
+
unless data.is_a?(String)
|
42
|
+
raise DataFormatError, "Barcode data should be given as a string"
|
43
|
+
end
|
44
|
+
ecs = self.class.ec_levels
|
45
|
+
unless ec_level.nil? or ecs.include?(ec_level.to_s.upcase)
|
46
|
+
raise DataFormatError, "Error correction level must be #{ecs.join(', ')}"
|
47
|
+
end
|
48
|
+
#unless data.size <= 4296
|
49
|
+
# raise DataFormatError, "Barcode data can be at most 4296 characters"
|
50
|
+
#end
|
51
|
+
end
|
52
|
+
|
53
|
+
##
|
54
|
+
# Label query string parameter (text to be encoded).
|
55
|
+
#
|
56
|
+
def chl
|
57
|
+
data
|
58
|
+
end
|
59
|
+
|
60
|
+
##
|
61
|
+
# Error correction and margins.
|
62
|
+
#
|
63
|
+
def chld
|
64
|
+
# only return non-nil if non-default value given
|
65
|
+
return nil unless (
|
66
|
+
(ec_level and ![:l, "l", "L"].include?(ec_level)) or
|
67
|
+
(margin and margin != 4)
|
68
|
+
)
|
69
|
+
ec = ec_level || "L"
|
70
|
+
m = margin || 4
|
71
|
+
ec.to_s.upcase + (m != 4 ? "|#{m}" : "")
|
72
|
+
end
|
73
|
+
|
74
|
+
##
|
75
|
+
# Output encoding query string parameter.
|
76
|
+
#
|
77
|
+
def choe
|
78
|
+
case encoding
|
79
|
+
when :shift_jis: "Shift_JIS"
|
80
|
+
when :iso88591: "ISO-8859-1"
|
81
|
+
else "UTF-8"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module SmartChart
|
2
|
+
class Radar < MultipleDataSetChart
|
3
|
+
include GridLines
|
4
|
+
|
5
|
+
private # ---------------------------------------------------------------
|
6
|
+
|
7
|
+
##
|
8
|
+
# Specify the Google Chart type.
|
9
|
+
#
|
10
|
+
def type
|
11
|
+
"r" + (style == :filled ? "s" : "")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module SmartChart
|
2
|
+
class Scatter < MultipleDataSetChart
|
3
|
+
include GridLines
|
4
|
+
|
5
|
+
private # ---------------------------------------------------------------
|
6
|
+
|
7
|
+
##
|
8
|
+
# Specify the Google Chart type.
|
9
|
+
#
|
10
|
+
def type
|
11
|
+
"s"
|
12
|
+
end
|
13
|
+
|
14
|
+
##
|
15
|
+
# Array of all possible query string parameters.
|
16
|
+
#
|
17
|
+
def query_string_params
|
18
|
+
super + [:chg]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,226 @@
|
|
1
|
+
module SmartChart
|
2
|
+
module Encoder
|
3
|
+
|
4
|
+
##
|
5
|
+
# Choose the best encoder, instantiate, and return.
|
6
|
+
#
|
7
|
+
def self.encode(data, min = nil, max = nil)
|
8
|
+
Simple.new(data, min, max)
|
9
|
+
end
|
10
|
+
|
11
|
+
##
|
12
|
+
# The Base encoder defines a public interface for all Encoders. To create
|
13
|
+
# an actual Encoder, your subclass should implement _only_ these private
|
14
|
+
# methods:
|
15
|
+
#
|
16
|
+
# token # the single character encoding name
|
17
|
+
# digits # the "alphabet" of the encoding (array)
|
18
|
+
# missing # digit used for missing data
|
19
|
+
# delimiter # between data points
|
20
|
+
# separator # between data series
|
21
|
+
#
|
22
|
+
class Base
|
23
|
+
|
24
|
+
attr_accessor :data_sets, :min, :max
|
25
|
+
|
26
|
+
def initialize(data_sets, min = nil, max = nil)
|
27
|
+
self.data_sets = data_sets
|
28
|
+
self.min = min || data_sets.flatten.compact.min
|
29
|
+
self.max = max || data_sets.flatten.compact.max
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# The data, encoded as a string (eg: "s:e5Gf4").
|
34
|
+
#
|
35
|
+
def to_s
|
36
|
+
token + ":" + encode
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
private # -------------------------------------------------------------
|
41
|
+
|
42
|
+
##
|
43
|
+
# The business end: map arrays of numbers onto a range of characters.
|
44
|
+
# See http://code.google.com/apis/chart/formats.html for specs.
|
45
|
+
#
|
46
|
+
def encode
|
47
|
+
encoded = []
|
48
|
+
data_sets.each_with_index do |set,i|
|
49
|
+
encoded[i] = []
|
50
|
+
set.each do |d|
|
51
|
+
if d.nil?
|
52
|
+
char = missing
|
53
|
+
else
|
54
|
+
if min == max # don't die when only one data point given
|
55
|
+
char = digits.last
|
56
|
+
else
|
57
|
+
n = (d - min).to_f / (max - min).to_f
|
58
|
+
n = (n * (digits.size - 1)).floor
|
59
|
+
char = digits[n]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
encoded[i] << char
|
63
|
+
end
|
64
|
+
end
|
65
|
+
encoded.map{ |set| set.join(delimiter) }.join(separator)
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# The single-character name of the encoding, as specified in URLs.
|
70
|
+
# All encoders must implement this method.
|
71
|
+
#
|
72
|
+
def token
|
73
|
+
fail
|
74
|
+
end
|
75
|
+
|
76
|
+
##
|
77
|
+
# An array of "digits": the encoding's alphabet, in order.
|
78
|
+
# All encoders must implement this method.
|
79
|
+
#
|
80
|
+
def digits
|
81
|
+
fail
|
82
|
+
end
|
83
|
+
|
84
|
+
##
|
85
|
+
# String used for missing data point.
|
86
|
+
# All encoders must implement this method.
|
87
|
+
#
|
88
|
+
def missing
|
89
|
+
fail
|
90
|
+
end
|
91
|
+
|
92
|
+
##
|
93
|
+
# Data series separator.
|
94
|
+
#
|
95
|
+
def separator
|
96
|
+
fail
|
97
|
+
end
|
98
|
+
|
99
|
+
##
|
100
|
+
# Data point delimiter.
|
101
|
+
#
|
102
|
+
def delimiter
|
103
|
+
""
|
104
|
+
end
|
105
|
+
|
106
|
+
##
|
107
|
+
# Array of uppercase letters.
|
108
|
+
#
|
109
|
+
def uppers
|
110
|
+
chars = ["A"]
|
111
|
+
chars << chars.last.succ while chars.size < 26
|
112
|
+
chars
|
113
|
+
end
|
114
|
+
|
115
|
+
##
|
116
|
+
# Array of lowercase letters.
|
117
|
+
#
|
118
|
+
def lowers
|
119
|
+
chars = ["a"]
|
120
|
+
chars << chars.last.succ while chars.size < 26
|
121
|
+
chars
|
122
|
+
end
|
123
|
+
|
124
|
+
##
|
125
|
+
# Array of numerals.
|
126
|
+
#
|
127
|
+
def numerals
|
128
|
+
chars = ["0"]
|
129
|
+
chars << chars.last.succ while chars.size < 10
|
130
|
+
chars
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
|
135
|
+
##
|
136
|
+
# Simple encoding (http://code.google.com/apis/chart/formats.html#simple).
|
137
|
+
#
|
138
|
+
class Simple < Base
|
139
|
+
private
|
140
|
+
|
141
|
+
def token
|
142
|
+
"s"
|
143
|
+
end
|
144
|
+
|
145
|
+
##
|
146
|
+
# ABC...XYZabc...xyz0123456789
|
147
|
+
#
|
148
|
+
def digits
|
149
|
+
uppers + lowers + numerals
|
150
|
+
end
|
151
|
+
|
152
|
+
def missing
|
153
|
+
"_"
|
154
|
+
end
|
155
|
+
|
156
|
+
def separator
|
157
|
+
","
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
|
162
|
+
##
|
163
|
+
# Text encoding (http://code.google.com/apis/chart/formats.html#text).
|
164
|
+
#
|
165
|
+
class Text < Base
|
166
|
+
private
|
167
|
+
|
168
|
+
def token
|
169
|
+
"t"
|
170
|
+
end
|
171
|
+
|
172
|
+
##
|
173
|
+
# ABC...XYZabc...xyz0123456789
|
174
|
+
#
|
175
|
+
def digits
|
176
|
+
(0..100).to_a.map{ |i| i.to_s }
|
177
|
+
end
|
178
|
+
|
179
|
+
def missing
|
180
|
+
"-1"
|
181
|
+
end
|
182
|
+
|
183
|
+
def separator
|
184
|
+
"|"
|
185
|
+
end
|
186
|
+
|
187
|
+
def delimiter
|
188
|
+
","
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
|
193
|
+
##
|
194
|
+
# Extended encoding (http://code.google.com/apis/chart/formats.html#extended).
|
195
|
+
#
|
196
|
+
class Extended < Base
|
197
|
+
private
|
198
|
+
|
199
|
+
def token
|
200
|
+
"e"
|
201
|
+
end
|
202
|
+
|
203
|
+
##
|
204
|
+
# AA, AB, AC, ..., .8, .9, .-, ..
|
205
|
+
#
|
206
|
+
def digits
|
207
|
+
chars = uppers + lowers + numerals + %w[- .]
|
208
|
+
arr = []
|
209
|
+
chars.each do |c1|
|
210
|
+
chars.each do |c2|
|
211
|
+
arr << c1 + c2
|
212
|
+
end
|
213
|
+
end
|
214
|
+
arr
|
215
|
+
end
|
216
|
+
|
217
|
+
def missing
|
218
|
+
"__"
|
219
|
+
end
|
220
|
+
|
221
|
+
def separator
|
222
|
+
","
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module SmartChart
|
2
|
+
|
3
|
+
class SmartChartError < StandardError #:nodoc:
|
4
|
+
end
|
5
|
+
|
6
|
+
class DataFormatError < SmartChartError #:nodoc:
|
7
|
+
end
|
8
|
+
|
9
|
+
class ColorFormatError < SmartChartError #:nodoc:
|
10
|
+
end
|
11
|
+
|
12
|
+
class NoAttributeError < SmartChartError #:nodoc:
|
13
|
+
def initialize(chart, param)
|
14
|
+
chart_type = chart.class.to_s.sub(/^SmartChart::/, "")
|
15
|
+
super("The #{chart_type} chart type does not accept the '#{param}' parameter")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
# --- validations ---------------------------------------------------------
|
21
|
+
|
22
|
+
class ValidationError < SmartChartError #:nodoc:
|
23
|
+
end
|
24
|
+
|
25
|
+
class MissingRequiredAttributeError < ValidationError #:nodoc:
|
26
|
+
def initialize(chart, param)
|
27
|
+
chart_type = chart.class.to_s.sub(/^SmartChart::/, "")
|
28
|
+
super("The #{chart_type} chart type requires the '#{param}' parameter")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class DimensionsError < ValidationError #:nodoc:
|
33
|
+
def initialize(message = nil)
|
34
|
+
super(message || "Chart dimensions must result in at most 300,000 pixels")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class UrlLengthError < ValidationError #:nodoc:
|
39
|
+
def initialize(message = nil)
|
40
|
+
super(message || "URL too long (must not exceed #{SmartChart::URL_MAX_LENGTH} characters)")
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module SmartChart
|
2
|
+
module AxisLines
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.class_eval do
|
6
|
+
attr_accessor :axis
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
private # ---------------------------------------------------------------
|
12
|
+
|
13
|
+
##
|
14
|
+
# Axis type parameter.
|
15
|
+
#
|
16
|
+
def chxt
|
17
|
+
#return nil unless (axis.is_a?(Hash) and (axis[:sides].is_a?(Array))
|
18
|
+
"TODO"
|
19
|
+
end
|
20
|
+
|
21
|
+
##
|
22
|
+
# Axis style parameter.
|
23
|
+
#
|
24
|
+
def chxs
|
25
|
+
#return nil unless (axis.is_a?(Hash) and (axis[:color] or axis[:style]))
|
26
|
+
"TODO"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|