dyi 1.1.1 → 1.1.2
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/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?
|