dyi 1.1.1 → 1.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +7 -1
- data/lib/dyi.rb +3 -1
- data/lib/dyi/animation.rb +5 -4
- data/lib/dyi/canvas.rb +5 -8
- data/lib/dyi/chart.rb +1 -1
- data/lib/dyi/chart/array_reader.rb +104 -10
- data/lib/dyi/chart/axis_util.rb +31 -17
- data/lib/dyi/chart/base.rb +104 -7
- data/lib/dyi/chart/csv_reader.rb +56 -8
- data/lib/dyi/chart/excel_reader.rb +27 -4
- data/lib/dyi/chart/legend.rb +10 -8
- data/lib/dyi/chart/line_chart.rb +29 -25
- data/lib/dyi/chart/pie_chart.rb +192 -29
- data/lib/dyi/chart/table.rb +12 -10
- data/lib/dyi/color.rb +9 -7
- data/lib/dyi/coordinate.rb +177 -61
- data/lib/dyi/drawing.rb +1 -1
- data/lib/dyi/drawing/clipping.rb +9 -3
- data/lib/dyi/drawing/color_effect.rb +7 -4
- data/lib/dyi/drawing/filter.rb +10 -7
- data/lib/dyi/drawing/pen.rb +421 -11
- data/lib/dyi/drawing/pen_3d.rb +12 -7
- data/lib/dyi/element.rb +5 -4
- data/lib/dyi/event.rb +3 -3
- data/lib/dyi/font.rb +6 -4
- data/lib/dyi/formatter.rb +1 -1
- data/lib/dyi/formatter/base.rb +24 -15
- data/lib/dyi/formatter/emf_formatter.rb +6 -5
- data/lib/dyi/formatter/eps_formatter.rb +15 -14
- data/lib/dyi/formatter/svg_formatter.rb +16 -14
- data/lib/dyi/formatter/svg_reader.rb +4 -3
- data/lib/dyi/formatter/xaml_formatter.rb +9 -7
- data/lib/dyi/length.rb +213 -114
- data/lib/dyi/matrix.rb +4 -2
- data/lib/dyi/painting.rb +161 -87
- data/lib/dyi/script.rb +1 -1
- data/lib/dyi/script/ecmascript.rb +18 -29
- data/lib/dyi/script/simple_script.rb +4 -8
- data/lib/dyi/shape.rb +1 -1
- data/lib/dyi/shape/base.rb +8 -17
- data/lib/dyi/shape/path.rb +102 -19
- data/lib/dyi/stylesheet.rb +4 -3
- data/lib/dyi/svg_element.rb +9 -7
- data/lib/dyi/type.rb +5 -2
- data/lib/dyi/util.rb +36 -1
- data/lib/ironruby.rb +1 -1
- data/lib/util.rb +53 -5
- metadata +4 -19
data/CHANGES
CHANGED
@@ -1,10 +1,16 @@
|
|
1
1
|
= DYI Changelog
|
2
2
|
|
3
|
+
== Version 1.1.2 / 2012-03-01
|
4
|
+
* Bug Fixes
|
5
|
+
* Calls data_label_format property instead of baloon_format when it draws the baloon of PieChart.
|
6
|
+
* Changes the order of overlapping charts of LineChart.
|
7
|
+
* Calcuration of second-axis settings of LineChart.
|
8
|
+
|
3
9
|
== Version 1.1.1 / 2012-02-02
|
4
10
|
* Minor Enhancements
|
5
11
|
* Adds a String parsing to CsvReader.
|
6
12
|
* Spports metadata.
|
7
|
-
* Adds
|
13
|
+
* Adds 'title' and 'description' attribute to DYI::Element.
|
8
14
|
|
9
15
|
== Version 1.1.0 / 2012-01-06
|
10
16
|
* Major Enhancements
|
data/lib/dyi.rb
CHANGED
@@ -20,12 +20,14 @@
|
|
20
20
|
# along with DYI. If not, see <http://www.gnu.org/licenses/>.
|
21
21
|
|
22
22
|
# Root namespace of DYI.
|
23
|
+
# @since 0.0.0
|
23
24
|
module DYI
|
24
25
|
|
25
26
|
# DYI program version
|
26
|
-
VERSION = '1.1.
|
27
|
+
VERSION = '1.1.2'
|
27
28
|
|
28
29
|
# URL of DYI Project
|
30
|
+
# @since 0.0.2
|
29
31
|
URL = 'http://sourceforge.net/projects/dyi/'
|
30
32
|
end
|
31
33
|
|
data/lib/dyi/animation.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- encoding: UTF-8 -*-
|
2
2
|
|
3
|
-
# Copyright (c) 2009-
|
3
|
+
# Copyright (c) 2009-2012 Sound-F Co., Ltd. All rights reserved.
|
4
4
|
#
|
5
5
|
# Author:: Mamoru Yuo
|
6
6
|
#
|
@@ -23,11 +23,12 @@
|
|
23
23
|
#
|
24
24
|
# This file provides the classes of animation. The event becomes effective
|
25
25
|
# only when it is output by SVG format.
|
26
|
+
|
26
27
|
#
|
27
|
-
|
28
|
+
module DYI
|
28
29
|
|
29
|
-
|
30
|
-
module Animation
|
30
|
+
# @since 1.0.0
|
31
|
+
module Animation
|
31
32
|
|
32
33
|
# Base class for animation classes.
|
33
34
|
# @abstract
|
data/lib/dyi/canvas.rb
CHANGED
@@ -19,6 +19,7 @@
|
|
19
19
|
# You should have received a copy of the GNU General Public License
|
20
20
|
# along with DYI. If not, see <http://www.gnu.org/licenses/>.
|
21
21
|
|
22
|
+
#
|
22
23
|
module DYI
|
23
24
|
|
24
25
|
# The body of Vector-Image. This class is a container for all graphical
|
@@ -30,21 +31,17 @@ module DYI
|
|
30
31
|
IMPLEMENT_ATTRIBUTES = [:view_box, :preserve_aspect_ratio]
|
31
32
|
|
32
33
|
# Returns width of the vector-image on user unit.
|
33
|
-
# @attribute width
|
34
|
-
# @return [Length] width of vector-image on user unit
|
35
34
|
attr_length :width
|
36
35
|
|
37
36
|
# Returns heigth of the vector-image on user unit.
|
38
|
-
# @attribute height
|
39
|
-
# @return [Length] heigth of vector-image on user unit
|
40
37
|
attr_length :height
|
41
38
|
|
42
|
-
# Returns the value of the view_box.
|
43
39
|
# @attribute view_box
|
40
|
+
# Returns the value of the view_box.
|
44
41
|
# @return [String]
|
45
|
-
|
46
|
-
# Returns the value of the preserve_aspect_ratio.
|
42
|
+
#+++
|
47
43
|
# @attribute preserve_aspect_ratio
|
44
|
+
# Returns the value of the preserve_aspect_ratio.
|
48
45
|
# @return [String] the value of preserve_aspect_ratio
|
49
46
|
attr_reader *IMPLEMENT_ATTRIBUTES
|
50
47
|
|
@@ -220,7 +217,7 @@ module DYI
|
|
220
217
|
# @param [String, Script::SimpleScript] script_body a string that is a
|
221
218
|
# script body or a script object that is registered
|
222
219
|
# @param [String] content_type a content-type of the script. If parameter
|
223
|
-
#
|
220
|
+
# 'script_body' is {Script::SimpleScript} object, this parameter is ignored
|
224
221
|
# @since 1.0.0
|
225
222
|
def add_script(script_body, content_type = 'application/ecmascript')
|
226
223
|
if script_body.respond_to?(:include_external_file?)
|
data/lib/dyi/chart.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- encoding: UTF-8 -*-
|
2
2
|
|
3
|
-
# Copyright (c) 2009-
|
3
|
+
# Copyright (c) 2009-2012 Sound-F Co., Ltd. All rights reserved.
|
4
4
|
#
|
5
5
|
# Author:: Mamoru Yuo
|
6
6
|
#
|
@@ -19,38 +19,102 @@
|
|
19
19
|
# You should have received a copy of the GNU General Public License
|
20
20
|
# along with DYI. If not, see <http://www.gnu.org/licenses/>.
|
21
21
|
|
22
|
-
|
23
|
-
|
22
|
+
#
|
23
|
+
module DYI
|
24
|
+
module Chart
|
24
25
|
|
26
|
+
# +ArrayReader+ converts the ruby array into a readable format for the
|
27
|
+
# chart object of DYI.
|
28
|
+
#
|
29
|
+
# If any ruby object or something (file, database, etc...) is used as the
|
30
|
+
# data source of DYI's chart, the object of the inheritance class of
|
31
|
+
# +ArrayReader+ avails. For example, using a CSV data, {CsvReader} class
|
32
|
+
# avails.
|
33
|
+
#
|
34
|
+
#= Basic Usage
|
35
|
+
#
|
36
|
+
# Using +PieChart+ and ArrayReader (or sub class of ArrayReader), you can
|
37
|
+
# create the pie chart as the following:
|
38
|
+
# require 'rubygems'
|
39
|
+
# require 'dyi'
|
40
|
+
#
|
41
|
+
# # Nominal GDP of Asian Countries (2010)
|
42
|
+
# chart_data = [['China', 5878],
|
43
|
+
# ['Japan', 5459],
|
44
|
+
# ['India', 1538],
|
45
|
+
# ['South Koria', 1007],
|
46
|
+
# ['Other Countries', 2863]]
|
47
|
+
# reader = DYI::Chart::ArrayReader.read(chart_data, :schema => [:name, :value])
|
48
|
+
#
|
49
|
+
# # Creates the Pie Chart
|
50
|
+
# chart = DYI::Chart::PieChart.new(450,250)
|
51
|
+
# chart.load_data(reader)
|
52
|
+
# chart.save('asian_gdp.svg')
|
53
|
+
# Creating the instance, you should not call +new+ method but {.read} method.
|
54
|
+
#
|
55
|
+
# The optional argument +:schema+ means a field name. The field name +:value+
|
56
|
+
# is the particular name, that is to say, the chart object generate a chart
|
57
|
+
# using a value of the field named +:value+. If +:schema+ option is not
|
58
|
+
# specified, the +ArrayReader+ object looks upon all feilds as +:vlaue+
|
59
|
+
# field. The field names other than +:name+ are used in the format string
|
60
|
+
# and so on, as following:
|
61
|
+
# # Nominal GDP of Asian Countries (2010)
|
62
|
+
# chart_data = [['China', 'People\'s Republic of China', 5878, 'red'],
|
63
|
+
# ['Japan', 'Japan', 5459, 'blue'],
|
64
|
+
# ['India', 'Republic of India', 1538, 'yellow'],
|
65
|
+
# ['South Koria', 'Republic of Korea', 1007, 'green'],
|
66
|
+
# ['Others', 'Other Asian Countries', 2863, 'gray']]
|
67
|
+
# reader = DYI::Chart::ArrayReader.read(chart_data,
|
68
|
+
# :schema => [:name, :long, :value, :color])
|
69
|
+
#
|
70
|
+
# # Creates the Pie Chart
|
71
|
+
# chart = DYI::Chart::PieChart.new(450,250,
|
72
|
+
# :legend_format => '{?long}')
|
73
|
+
# chart.load_data(reader)
|
74
|
+
# chart.save('asian_gdp.svg')
|
75
|
+
# See {ArrayReader.read ArrayReader.read} for other optional arguments.
|
76
|
+
# @since 0.0.0
|
25
77
|
class ArrayReader
|
26
78
|
include Enumerable
|
27
79
|
|
80
|
+
# Returns the value at index.
|
81
|
+
# @param [Integer] i the index of records
|
82
|
+
# @param [Integer] j the index of series
|
83
|
+
# @return [Numeric] the value at index
|
28
84
|
def [](i, j)
|
29
85
|
@records[i].values[j]
|
30
86
|
end
|
31
87
|
|
32
|
-
#
|
88
|
+
# Returns the array of the records.
|
89
|
+
# @return [Array<Struct>] the array of the records
|
33
90
|
# @since 1.0.0
|
34
91
|
def records
|
35
92
|
@records.clone
|
36
93
|
end
|
37
94
|
|
95
|
+
# Returns number of the records.
|
38
96
|
# @return [Integer] number of the records
|
39
97
|
# @since 1.0.0
|
40
98
|
def records_size
|
41
99
|
@records.size
|
42
100
|
end
|
43
101
|
|
102
|
+
# Returns number of the values in the record
|
44
103
|
# @return [Integer] number of the values
|
45
104
|
# @since 1.0.0
|
46
105
|
def values_size
|
47
106
|
@records.first.values.size rescue 0
|
48
107
|
end
|
49
108
|
|
109
|
+
# Clears all records
|
50
110
|
def clear_data
|
51
111
|
@records.clear
|
52
112
|
end
|
53
113
|
|
114
|
+
# Calls block once for each record, passing the values that records as a
|
115
|
+
# parameter.
|
116
|
+
# @yield [values] iteration block
|
117
|
+
# @yieldparam [Array<Numeric>] values the values that the record has
|
54
118
|
# @since 1.0.0
|
55
119
|
def values_each(&block)
|
56
120
|
@records.each do |record|
|
@@ -58,8 +122,9 @@ module DYI #:nodoc:
|
|
58
122
|
end
|
59
123
|
end
|
60
124
|
|
61
|
-
#
|
62
|
-
# @
|
125
|
+
# Returns an array of values of the specified series.
|
126
|
+
# @param [Integer] index an index of the series
|
127
|
+
# @return [Array<Numeric>] an array of values
|
63
128
|
# @since 1.0.0
|
64
129
|
def series(index)
|
65
130
|
@records.map do |record|
|
@@ -67,16 +132,23 @@ module DYI #:nodoc:
|
|
67
132
|
end
|
68
133
|
end
|
69
134
|
|
135
|
+
# Returns whether the record has the field.
|
136
|
+
# @param [Symbol, String] field_name field name
|
137
|
+
# @return [Bolean] true if the record has the field, false otherwise
|
70
138
|
# @since 1.0.0
|
71
139
|
def has_field?(field_name)
|
72
140
|
@schema.members.include?(RUBY_VERSION >= '1.9' ? field_name.to_sym : field_name.to_s)
|
73
141
|
end
|
74
142
|
|
143
|
+
# Calls block once for each record, passing that records as a parameter.
|
144
|
+
# @yield [record] iteration block
|
145
|
+
# @yieldparam [Struct] record the record in self
|
75
146
|
# @since 1.0.0
|
76
147
|
def each(&block)
|
77
148
|
@records.each(&block)
|
78
149
|
end
|
79
150
|
|
151
|
+
# @private
|
80
152
|
def initialize
|
81
153
|
@records = []
|
82
154
|
end
|
@@ -85,8 +157,8 @@ module DYI #:nodoc:
|
|
85
157
|
# @param [Array<Array>] array_of_array two dimensional array
|
86
158
|
# @option options [Range] :row_range a range of rows
|
87
159
|
# @option options [Range] :column_range a range of columns
|
88
|
-
# @option options [Array<Symbol>] :schema array of field names
|
89
|
-
#
|
160
|
+
# @option options [Array<Symbol>] :schema array of field names. see
|
161
|
+
# Overview of {ArrayReader}.
|
90
162
|
# @option options [Boolean] :transposed whether the array-of-array is
|
91
163
|
# transposed
|
92
164
|
def read(array_of_array, options={})
|
@@ -121,7 +193,8 @@ module DYI #:nodoc:
|
|
121
193
|
self
|
122
194
|
end
|
123
195
|
|
124
|
-
#
|
196
|
+
# Returns an array of the field's name
|
197
|
+
# @return [Array<Symbol>] an array of the field's name
|
125
198
|
# @since 1.1.0
|
126
199
|
def members
|
127
200
|
@schema.members.map{|name| name.to_sym}
|
@@ -152,6 +225,7 @@ module DYI #:nodoc:
|
|
152
225
|
|
153
226
|
# @param [Array] schema of the record
|
154
227
|
# @return [Class] subclass of Struct class
|
228
|
+
# @raise [ArgumentError]
|
155
229
|
# @since 1.0.0
|
156
230
|
def record_schema(schema)
|
157
231
|
struct_schema =
|
@@ -172,7 +246,7 @@ module DYI #:nodoc:
|
|
172
246
|
Struct.new(*struct_schema)
|
173
247
|
end
|
174
248
|
|
175
|
-
# Makes the instance respond to xxx_values method.
|
249
|
+
# Makes the instance respond to +xxx_values+ method.
|
176
250
|
# @example
|
177
251
|
# data = ArrayReader.read([['Smith', 20, 3432], ['Thomas', 25, 9721]],
|
178
252
|
# :schema => [:name, :age, :value])
|
@@ -193,6 +267,26 @@ module DYI #:nodoc:
|
|
193
267
|
# @param (see #read)
|
194
268
|
# @option (see #read)
|
195
269
|
# @return [ArrayReader] a new instance of ArrayReader
|
270
|
+
# @example
|
271
|
+
# # example of using :row_range option
|
272
|
+
# chart_data = [['Country', 'Nominal GDP'],
|
273
|
+
# ['China', 5878],
|
274
|
+
# ['Japan', 5459],
|
275
|
+
# ['India', 1538],
|
276
|
+
# ['South Koria', 1007],
|
277
|
+
# ['Other Countries', 2863]]
|
278
|
+
# # skips the first row
|
279
|
+
# reader = DYI::Chart::ArrayReader.read(chart_data,
|
280
|
+
# :schema => [:name, :value],
|
281
|
+
# :row_range => (1..-1))
|
282
|
+
# @example
|
283
|
+
# # example of using :transposed option
|
284
|
+
# chart_data = [['China', 'Japan', 'India', 'South Koria', 'Other Countries'],
|
285
|
+
# [5878, 5459, 1538, 1007, 2863]]
|
286
|
+
# # transposes the rows and the columns
|
287
|
+
# reader = DYI::Chart::ArrayReader.read(chart_data,
|
288
|
+
# :schema => [:name, :value],
|
289
|
+
# :transposed => true)
|
196
290
|
def read(array_of_array, options={})
|
197
291
|
new.read(array_of_array, options)
|
198
292
|
end
|
data/lib/dyi/chart/axis_util.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- encoding: UTF-8 -*-
|
2
2
|
|
3
|
-
# Copyright (c) 2009-
|
3
|
+
# Copyright (c) 2009-2012 Sound-F Co., Ltd. All rights reserved.
|
4
4
|
#
|
5
5
|
# Author:: Mamoru Yuo
|
6
6
|
#
|
@@ -21,9 +21,10 @@
|
|
21
21
|
|
22
22
|
require 'csv'
|
23
23
|
|
24
|
-
module DYI
|
25
|
-
module Chart
|
24
|
+
module DYI
|
25
|
+
module Chart
|
26
26
|
|
27
|
+
# @since 0.0.0
|
27
28
|
module AxisUtil
|
28
29
|
|
29
30
|
private
|
@@ -56,11 +57,11 @@ module DYI #:nodoc:
|
|
56
57
|
}
|
57
58
|
end
|
58
59
|
|
59
|
-
def top_digit(num, n=1)
|
60
|
+
def top_digit(num, n=1)
|
60
61
|
num.div(10 ** (figures_count(num) - n + 1))
|
61
62
|
end
|
62
63
|
|
63
|
-
def suitable_1digit_value(a, b)
|
64
|
+
def suitable_1digit_value(a, b)
|
64
65
|
return a if a == b
|
65
66
|
a, b = b, a if a > b
|
66
67
|
return 0 if a == 0
|
@@ -71,11 +72,11 @@ module DYI #:nodoc:
|
|
71
72
|
8
|
72
73
|
end
|
73
74
|
|
74
|
-
def figures_count(num)
|
75
|
+
def figures_count(num)
|
75
76
|
Math.log10(num).floor
|
76
77
|
end
|
77
78
|
|
78
|
-
def base_value(a, b, allow_under=true, allow_over=true)
|
79
|
+
def base_value(a, b, allow_under=true, allow_over=true)
|
79
80
|
return 0 if a * b <= 0 || a == b
|
80
81
|
a, b = -a, -b if negative = (a < 0)
|
81
82
|
a, b = b, a if a > b
|
@@ -83,7 +84,7 @@ module DYI #:nodoc:
|
|
83
84
|
suitable_value_positive(a, b) * (negative ? -1 : 1)
|
84
85
|
end
|
85
86
|
|
86
|
-
def suitable_value_positive(a, b)
|
87
|
+
def suitable_value_positive(a, b)
|
87
88
|
if figures_count(a) != (dig = figures_count(b))
|
88
89
|
return 10 ** dig
|
89
90
|
end
|
@@ -92,7 +93,7 @@ module DYI #:nodoc:
|
|
92
93
|
(suitable_1digit_value(dig_a - dig_a.div(10) * 10 + (dig_a == dig_a.div(10) * 10 ? 0 : 1), dig_b - dig_b.div(10) * 10) + dig_a.div(10) * 10) * (10 ** (dig - figures_count(dig_a)))
|
93
94
|
end
|
94
95
|
|
95
|
-
def scale_interval(base_value, data_min, data_max, scale_count_limit)
|
96
|
+
def scale_interval(base_value, data_min, data_max, scale_count_limit)
|
96
97
|
if base_value - data_min < data_max - base_value
|
97
98
|
allocate_scale_count = (data_max - base_value).div((data_max - data_min).quo(scale_count_limit))
|
98
99
|
scale_interval_base2edge(base_value, data_max, allocate_scale_count)
|
@@ -102,7 +103,7 @@ module DYI #:nodoc:
|
|
102
103
|
end
|
103
104
|
end
|
104
105
|
|
105
|
-
def scale_interval_base2edge(base_value, edge_value, scale_count_limit)
|
106
|
+
def scale_interval_base2edge(base_value, edge_value, scale_count_limit)
|
106
107
|
raise ArgumentError, 'base_value should not equal edge_value' if edge_value == base_value
|
107
108
|
range = (base_value - edge_value).abs
|
108
109
|
|
@@ -217,11 +218,24 @@ module DYI #:nodoc:
|
|
217
218
|
base_value = base_value(data_min, data_max, min.nil?, max.nil?)
|
218
219
|
|
219
220
|
scale_interval = scale_interval(base_value, data_min, data_max, scale_count)
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
max
|
221
|
+
scale_ratio = scale_interval.quo(main_axis_settings[:scale_interval])
|
222
|
+
if min
|
223
|
+
min_scale_value = scale_ratio * (main_axis_settings[:min_scale_value] - main_axis_settings[:min]) + min
|
224
|
+
max = scale_ratio * (main_axis_settings[:max] - main_axis_settings[:min_scale_value]) + min_scale_value
|
225
|
+
elsif max
|
226
|
+
min_scale_value = max - scale_ratio * (main_axis_settings[:max] - main_axis_settings[:min_scale_value])
|
227
|
+
min = min_scale_value - scale_ratio * (main_axis_settings[:min_scale_value] - main_axis_settings[:min])
|
228
|
+
else
|
229
|
+
min_scale_value = nil
|
230
|
+
(base_value + scale_interval).step(data_min, -scale_interval) {|n| min_scale_value = n}
|
231
|
+
min_scale_value ||= base_value + scale_interval
|
232
|
+
min = min_scale_value - scale_ratio * (main_axis_settings[:min_scale_value] - main_axis_settings[:min])
|
233
|
+
if data_min < min
|
234
|
+
min_scale_value -= scale_interval
|
235
|
+
min -= scale_interval
|
236
|
+
end
|
237
|
+
max = scale_ratio * (main_axis_settings[:max] - main_axis_settings[:min_scale_value]) + min_scale_value
|
238
|
+
end
|
225
239
|
|
226
240
|
{
|
227
241
|
:min => min || min_scale_value - scale_interval,
|
@@ -276,12 +290,12 @@ module DYI #:nodoc:
|
|
276
290
|
axis_length * pos + chart_margin
|
277
291
|
end
|
278
292
|
|
279
|
-
def round_top_2_digit(max, min)
|
293
|
+
def round_top_2_digit(max, min)
|
280
294
|
digit = Math.log10([max.abs, min.abs].max).floor - 1
|
281
295
|
[max.quo(10 ** digit).ceil * (10 ** digit), min.quo(10 ** digit).floor * (10 ** digit)]
|
282
296
|
end
|
283
297
|
|
284
|
-
def min_scale_value(max, min, scale_interval)
|
298
|
+
def min_scale_value(max, min, scale_interval)
|
285
299
|
return scale_interval if min == 0
|
286
300
|
if (max_digit = Math.log10(max).to_i) != Math.log10(min).to_i
|
287
301
|
base_value = 10 ** max_digit
|
data/lib/dyi/chart/base.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- encoding: UTF-8 -*-
|
2
2
|
|
3
|
-
# Copyright (c) 2009-
|
3
|
+
# Copyright (c) 2009-2012 Sound-F Co., Ltd. All rights reserved.
|
4
4
|
#
|
5
5
|
# Author:: Mamoru Yuo
|
6
6
|
#
|
@@ -21,9 +21,11 @@
|
|
21
21
|
|
22
22
|
require 'csv'
|
23
23
|
|
24
|
-
module DYI
|
25
|
-
module Chart
|
24
|
+
module DYI
|
25
|
+
module Chart
|
26
26
|
|
27
|
+
# @private
|
28
|
+
# @since 1.0.0
|
27
29
|
module OptionCreator
|
28
30
|
|
29
31
|
# Difines a read property.
|
@@ -188,22 +190,64 @@ module DYI #:nodoc:
|
|
188
190
|
end
|
189
191
|
end
|
190
192
|
|
193
|
+
# Base class of all the chart classes.
|
194
|
+
# @abstract
|
195
|
+
# @since 0.0.0
|
191
196
|
class Base
|
192
197
|
extend OptionCreator
|
193
198
|
|
194
199
|
DEFAULT_CHART_COLOR = ['#ff0f00', '#ff6600', '#ff9e01', '#fcd202', '#f8ff01', '#b0de09', '#04d215', '#0d8ecf', '#0d52d1', '#2a0cd0', '#8a0ccf', '#cd0d74']
|
195
|
-
attr_reader :options, :data, :canvas
|
196
200
|
|
201
|
+
# @private
|
202
|
+
attr_reader :options
|
203
|
+
|
204
|
+
# Returns the data for the chart.
|
205
|
+
# @return [Chart::ArrayReader] the data for the chart
|
206
|
+
attr_reader :data
|
207
|
+
|
208
|
+
# Returns the canvas of the image body.
|
209
|
+
# @return [Canvas] the canvas of the image body
|
210
|
+
attr_reader :canvas
|
211
|
+
|
212
|
+
# Returns or sets the URI of the background image of the chart. The URL is
|
213
|
+
# included the chart image.
|
197
214
|
opt_accessor :background_image_url, :type => :string
|
215
|
+
|
216
|
+
# Returns or sets the background image of the chart. The image files is
|
217
|
+
# read and included when the chart image is created. The hash includes the
|
218
|
+
# following key:
|
219
|
+
# [+:path+] (+String+) the file path of the background image file
|
220
|
+
# [+:content_type+] (+String+) the content-type of the background image
|
221
|
+
# file
|
198
222
|
opt_accessor :background_image_file, :type => :hash, :default => {}, :keys => [:path, :content_type], :item_type => :string
|
223
|
+
|
224
|
+
# Returns or sets the opacity of the background image of the chart.
|
225
|
+
# Default to 1.0.
|
199
226
|
opt_accessor :background_image_opacity, :type => :float, :default => 1.0
|
227
|
+
|
228
|
+
# Returns or sets the script string of the chart.
|
200
229
|
opt_accessor :script_body, :type => :string
|
230
|
+
|
231
|
+
# Returns or sets the CSS styles of the image body of the chart.
|
201
232
|
opt_accessor :css_body, :type => :string
|
233
|
+
|
234
|
+
# Returns or sets the URIs of the script files that the chart includes.
|
202
235
|
opt_accessor :script_files, :type => :array, :item_type => :string
|
236
|
+
|
237
|
+
# Returns or sets the URIs of the CSS files that the chart includes.
|
203
238
|
opt_accessor :css_files, :type => :array, :item_type => :string
|
239
|
+
|
240
|
+
# Returns or sets the URIs of the XSL files that the chart includes.
|
204
241
|
opt_accessor :xsl_files, :type => :array, :item_type => :string
|
242
|
+
|
243
|
+
# Returns or sets the CSS class of the image body of the chart.
|
205
244
|
opt_accessor :canvas_css_class, :type => :string
|
206
245
|
|
246
|
+
# @param [Length] width width of the chart image
|
247
|
+
# @param [Length] height height of the chart image
|
248
|
+
# @param [Hash{Symbol => Object}] options the options to creat the chart
|
249
|
+
# image. See <em>Instance Attribute</em> of the each chart class
|
250
|
+
# ({Base}, {PieChart}, {LineChart}, etc...).
|
207
251
|
def initialize(width, height, options={})
|
208
252
|
@canvas = Canvas.new(width, height)
|
209
253
|
@options = {}
|
@@ -212,56 +256,109 @@ module DYI #:nodoc:
|
|
212
256
|
end
|
213
257
|
end
|
214
258
|
|
259
|
+
# Returns width of the chart image on user unit.
|
260
|
+
# @return [Length] width of the chart image on user unit
|
215
261
|
def width
|
216
262
|
@canvas.width
|
217
263
|
end
|
218
264
|
|
265
|
+
# Sets width of the chart image on user unit.
|
266
|
+
# @param [Length] width width of the chart image on user unit
|
219
267
|
def width=(width)
|
220
268
|
@canvas.width = width
|
221
269
|
end
|
222
270
|
|
271
|
+
# Returns height of the chart image on user unit.
|
272
|
+
# @return [Length] height of the chart image on user unit
|
223
273
|
def height
|
224
274
|
@canvas.height
|
225
275
|
end
|
226
276
|
|
277
|
+
# Sets height of the chart image on user unit.
|
278
|
+
# @param [Length] height height of the chart image on user unit
|
227
279
|
def height=(height)
|
228
280
|
@canvas.height = height
|
229
281
|
end
|
230
282
|
|
283
|
+
# Sets size of the chart image.
|
284
|
+
# @param [Length] width width of the chart image
|
285
|
+
# @param [Length] height height of the chart image
|
231
286
|
def set_real_size(width, height)
|
232
287
|
@canvas.real_width = Length.new(width)
|
233
288
|
@canvas.real_height = Length.new(height)
|
234
289
|
end
|
235
290
|
|
291
|
+
# Clears <em>real size</em> of the chart image, and sets chart size as
|
292
|
+
# values of +width+ and +height+ properties. See {#set_real_size},
|
293
|
+
# {#width}, {#height}, {Canvas#real_width} and {Canvas#real_height}.
|
236
294
|
def clear_real_size
|
237
295
|
@canvas.real_width = nil
|
238
296
|
@canvas.real_height = nil
|
239
297
|
end
|
240
298
|
|
299
|
+
# Loads the data, and creates chart image.
|
300
|
+
# @param [ArrayReader] reader the +ArrayReader+ or its sub class that has
|
301
|
+
# the data of the chart
|
241
302
|
def load_data(reader)
|
242
303
|
@data = reader
|
243
304
|
create_vector_image
|
244
305
|
end
|
245
306
|
|
307
|
+
# Save the chart image as a file.
|
308
|
+
# @param [String] file_name the file name which is saved the chart image
|
309
|
+
# as
|
310
|
+
# @param [Symbol] format the file format. Supports the following formats:
|
311
|
+
# [+:svg+] SVG (Scalable Vector Graphics). If +format+ equals nil,
|
312
|
+
# output SVG format.
|
313
|
+
# [+:eps+] EPS (Encapsulated Post Script).
|
314
|
+
# [+:xaml+] XAML (Extensible Application Markup Language).
|
315
|
+
# [+:emf+] EMF (Enhanced Metafile). Using _IronRuby_ only.
|
316
|
+
# [+:png+] PNG (Portable Network Graphics). _librsvg_ must have been
|
317
|
+
# installed on the system.
|
318
|
+
# @option options [Boolean] :inline_mode true if outputs the inlime-mode, false
|
319
|
+
# otherwise. _SVG_ format only.
|
246
320
|
def save(file_name, format=nil, options={})
|
247
321
|
@canvas.save(file_name, format, options)
|
248
322
|
end
|
249
323
|
|
324
|
+
# Outputs the chart image to IO stream.
|
325
|
+
# @param [Symbol] format the file format. Supports the following formats:
|
326
|
+
# [+:svg+] SVG (Scalable Vector Graphics). If +format+ equals nil,
|
327
|
+
# output SVG format.
|
328
|
+
# [+:eps+] EPS (Encapsulated Post Script).
|
329
|
+
# [+:xaml+] XAML (Extensible Application Markup Language).
|
330
|
+
# [+:emf+] EMF (Enhanced Metafile). Using _IronRuby_ only.
|
331
|
+
# [+:png+] PNG (Portable Network Graphics). _librsvg_ must have been
|
332
|
+
# installed on the system.
|
333
|
+
# @param [IO] io the io which the chart image is outputed to
|
334
|
+
# @option options [Boolean] :inline_mode true if outputs the inlime-mode, false
|
335
|
+
# otherwise. _SVG_ format only.
|
250
336
|
def puts_in_io(format=nil, io=$>, options={})
|
251
337
|
@canvas.puts_in_io(format, io, options)
|
252
338
|
end
|
253
339
|
|
340
|
+
# Outputs the chart image as a +String+ (binary).
|
341
|
+
# @param [Symbol] format the file format. Supports the following formats:
|
342
|
+
# [+:svg+] SVG (Scalable Vector Graphics). If +format+ equals nil,
|
343
|
+
# output SVG format.
|
344
|
+
# [+:eps+] EPS (Encapsulated Post Script).
|
345
|
+
# [+:xaml+] XAML (Extensible Application Markup Language).
|
346
|
+
# [+:emf+] EMF (Enhanced Metafile). Using _IronRuby_ only.
|
347
|
+
# [+:png+] PNG (Portable Network Graphics). _librsvg_ must have been
|
348
|
+
# installed on the system.
|
349
|
+
# @option options [Boolean] :inline_mode true if outputs the inlime-mode, false
|
350
|
+
# otherwise. _SVG_ format only.
|
254
351
|
def string(format=nil, options={})
|
255
352
|
@canvas.string(format, options)
|
256
353
|
end
|
257
354
|
|
258
355
|
private
|
259
356
|
|
260
|
-
def options
|
357
|
+
def options
|
261
358
|
@options
|
262
359
|
end
|
263
360
|
|
264
|
-
def chart_color(index)
|
361
|
+
def chart_color(index)
|
265
362
|
if data.has_field?(:color)
|
266
363
|
color = Color.new_or_nil(data.records[index].color)
|
267
364
|
end
|
@@ -272,7 +369,7 @@ module DYI #:nodoc:
|
|
272
369
|
end
|
273
370
|
|
274
371
|
# @since 1.0.0
|
275
|
-
def create_vector_image
|
372
|
+
def create_vector_image
|
276
373
|
@canvas.add_css_class(canvas_css_class) if canvas_css_class && !canvas_css_class.empty?
|
277
374
|
@canvas.add_script(script_body) if script_body && !script_body.empty?
|
278
375
|
@canvas.add_stylesheet(css_body) if css_body && !css_body.empty?
|