dyi 1.0.3 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES CHANGED
@@ -1,5 +1,13 @@
1
1
  = DYI Changelog
2
2
 
3
+ == Version 1.1.0
4
+ * Major Enhancements
5
+ * Add DYI::Util module
6
+ * Can draw a toroid.
7
+ * Add properties of PieChart.
8
+ * Support namespace on XML output.
9
+ * Support Inline-XML mode.
10
+
3
11
  == Version 1.0.3
4
12
  * Bug Fixes
5
13
  * DataReader is not working properly in Ruby 1.9.
data/lib/dyi.rb CHANGED
@@ -21,13 +21,14 @@
21
21
 
22
22
 
23
23
  module DYI
24
- VERSION = '1.0.3'
24
+ VERSION = '1.1.0'
25
25
  URL = 'http://sourceforge.net/projects/dyi/'
26
26
  end
27
27
 
28
28
  %w(
29
29
 
30
30
  util
31
+ dyi/util
31
32
  dyi/length
32
33
  dyi/coordinate
33
34
  dyi/color
@@ -89,15 +89,15 @@ module DYI #:nodoc:
89
89
  end
90
90
 
91
91
  def save(file_name, format=nil, options={})
92
- get_formatter(format).save(file_name, options)
92
+ get_formatter(format, options).save(file_name)
93
93
  end
94
94
 
95
- def puts_in_io(format=nil, io=$>)
96
- get_formatter(format).puts(io)
95
+ def puts_in_io(format=nil, io=$>, options={})
96
+ get_formatter(format, options).puts(io)
97
97
  end
98
98
 
99
- def string(format=nil)
100
- get_formatter(format).string
99
+ def string(format=nil, options={})
100
+ get_formatter(format, options).string
101
101
  end
102
102
 
103
103
  def attributes #:nodoc:
@@ -172,10 +172,14 @@ module DYI #:nodoc:
172
172
 
173
173
  private
174
174
 
175
- def get_formatter(format=nil) #:nodoc:
175
+ def get_formatter(format=nil, options={}) #:nodoc:
176
176
  case format
177
- when :svg, nil then Formatter::SvgFormatter.new(self, 2)
178
- when :xaml then Formatter::XamlFormatter.new(self, 2)
177
+ when :svg, nil
178
+ options[:indent] = 2 unless options.key?(:indent)
179
+ Formatter::SvgFormatter.new(self, options)
180
+ when :xaml
181
+ options[:indent] = 2 unless options.key?(:indent)
182
+ Formatter::XamlFormatter.new(self, options)
179
183
  when :eps then Formatter::EpsFormatter.new(self)
180
184
  when :png then Formatter::PngFormatter.new(self)
181
185
  else raise ArgumentError, "`#{format}' is unknown format"
@@ -115,6 +115,12 @@ module DYI #:nodoc:
115
115
  self
116
116
  end
117
117
 
118
+ # @return [Array] a array of a field's name (as Symbol)
119
+ # @since 1.1.0
120
+ def members
121
+ @schema.members.map{|name| name.to_sym}
122
+ end
123
+
118
124
  private
119
125
 
120
126
  def primitive_value(value, type=nil)
@@ -247,15 +247,15 @@ module DYI #:nodoc:
247
247
  end
248
248
 
249
249
  def save(file_name, format=nil, options={})
250
- @canvas.save(file_name, format)
250
+ @canvas.save(file_name, format, options)
251
251
  end
252
252
 
253
- def puts_in_io(format=nil, io=$>)
254
- @canvas.puts_in_io(format, io)
253
+ def puts_in_io(format=nil, io=$>, options={})
254
+ @canvas.puts_in_io(format, io, options)
255
255
  end
256
256
 
257
- def string(format=nil)
258
- @canvas.string(format)
257
+ def string(format=nil, options={})
258
+ @canvas.string(format, options)
259
259
  end
260
260
 
261
261
  private
@@ -143,12 +143,17 @@ module DYI #:nodoc:
143
143
 
144
144
  private
145
145
 
146
+ def initialize(*args)
147
+ super
148
+ init_container
149
+ end
150
+
146
151
  def default_legend_point #:nodoc:
147
152
  Coordinate.new(margin_left, 0)
148
153
  end
149
154
 
150
155
  def create_vector_image #:nodoc:
151
- init_container
156
+ super
152
157
 
153
158
  main_series_data = []
154
159
  sub_series_data = []
@@ -235,7 +240,6 @@ module DYI #:nodoc:
235
240
  @axis_front_canvas,
236
241
  [margin_left - text_margin, y],
237
242
  main_y_axis == :left ? settings[:min] : sub_settings[:min],
238
- :alignment_baseline=>'middle',
239
243
  :text_anchor=>'end',
240
244
  :format => (main_y_axis == :left ? axis_format : second_axis_format))
241
245
  end
@@ -244,7 +248,6 @@ module DYI #:nodoc:
244
248
  @axis_front_canvas,
245
249
  [width - margin_right + text_margin, y],
246
250
  main_y_axis == :right ? settings[:min] : sub_settings[:min],
247
- :alignment_baseline=>'middle',
248
251
  :format => (main_y_axis == :right ? axis_format : second_axis_format))
249
252
  end
250
253
  end
@@ -24,13 +24,13 @@ module DYI #:nodoc:
24
24
 
25
25
  class PieChart < Base
26
26
  include Legend
27
- include DYI::Script::EcmaScript::DomLevel2
28
27
 
29
28
  attr_reader :chart_canvas, :data_label_canvas, :legend_canvas
30
29
 
31
30
  opt_accessor :center_point, {:type => :point, :default_method => :default_center_point}
32
31
  opt_accessor :chart_radius_x, {:type => :length, :default_method => :default_chart_radius_x}
33
32
  opt_accessor :chart_radius_y, {:type => :length, :default_method => :default_chart_radius_y}
33
+ opt_accessor :inner_radius, {:type => :float, :default => 0.0, :range => 0.0 ... 1.0}
34
34
  opt_accessor :represent_3d, {:type => :boolean}
35
35
  opt_accessor :_3d_settings, {:type => :hash, :default => {}, :keys => [:dy], :item_type => :float}
36
36
  opt_accessor :chart_colors, {:type => :array, :item_type => :color}
@@ -182,7 +182,7 @@ module DYI #:nodoc:
182
182
  chart_radius_y,
183
183
  accumulation * 360.0 / total_value - 90,
184
184
  value * 360.0 / total_value,
185
- attrs)
185
+ attrs.merge(:inner_radius => inner_radius))
186
186
  @sectors[index] = pie_sector
187
187
 
188
188
  if moved_elements && (dr = moved_elements[index])
@@ -241,7 +241,7 @@ module DYI #:nodoc:
241
241
  :duration => animation_duration,
242
242
  :fill => 'freeze',
243
243
  :begin_event => Event.mouseout(pie_sector))
244
- if show_legend?
244
+ if @legends
245
245
  text.add_painting_animation(:to => {:opacity => 1},
246
246
  :duration => animation_duration,
247
247
  :fill => 'freeze',
@@ -274,7 +274,7 @@ module DYI #:nodoc:
274
274
  end
275
275
  maxs
276
276
  end
277
- canvas.add_initialize_script(form_legend_labels(legend_canvas))
277
+ canvas.add_initialize_script(Script::EcmaScript::DomLevel2.form_legend_labels(legend_canvas))
278
278
  records.each_with_index do |record, i|
279
279
  y = legend_font_size * (1.2 * (i + 1))
280
280
  attrs = {}
@@ -184,7 +184,7 @@ module DYI #:nodoc:
184
184
  end
185
185
 
186
186
  def polar_coordinates(radius, theta)
187
- new(radius * Math.cos(theta * Math::PI / 180), radius * Math.sin(theta * Math::PI / 180))
187
+ new(radius * DYI::Util.cos(theta), radius * DYI::Util.sin(theta))
188
188
  end
189
189
 
190
190
  def set_default_format(format)
@@ -66,15 +66,25 @@ module DYI #:nodoc:
66
66
  Shape::Line.create_on_direction(start_point, direction_x, direction_y, merge_option(options)).draw_on(canvas)
67
67
  end
68
68
 
69
- def draw_polyline(canvas, point, options={}, &block)
70
- polyline = Shape::Polyline.new(point, merge_option(options))
71
- yield polyline
69
+ def draw_polyline(canvas, points, options={})
70
+ if block_given?
71
+ polyline = Shape::Polyline.new(points, merge_option(options))
72
+ yield polyline
73
+ else
74
+ polyline = Shape::Polyline.new(points.first, merge_option(options))
75
+ polyline.line_to(*points[1..-1])
76
+ end
72
77
  polyline.draw_on(canvas)
73
78
  end
74
79
 
75
- def draw_polygon(canvas, point, options={}, &block)
76
- polygon = Shape::Polygon.new(point, merge_option(options))
77
- yield polygon
80
+ def draw_polygon(canvas, points, options={})
81
+ if block_given?
82
+ polygon = Shape::Polygon.new(points, merge_option(options))
83
+ yield polygon
84
+ else
85
+ polygon = Shape::Polygon.new(points.first, merge_option(options))
86
+ polygon.line_to(*points[1..-1])
87
+ end
78
88
  polygon.draw_on(canvas)
79
89
  end
80
90
 
@@ -115,25 +125,62 @@ module DYI #:nodoc:
115
125
  end
116
126
 
117
127
  def draw_sector(canvas, center_point, radius_x, radius_y, start_angle, center_angle, options={})
118
- raise ArgumentError, "center_angle is out of range: #{center_angle}" if center_angle.abs > 360
128
+ start_angle = (center_angle > 0 ? start_angle : (start_angle + center_angle)) % 360
129
+ center_angle = center_angle.abs
130
+ options = merge_option(options)
131
+ inner_radius = options.delete(:inner_radius).to_f
119
132
  center_point = Coordinate.new(center_point)
120
- radius_x = Length.new(radius_x)
121
- radius_y = Length.new(radius_y)
133
+ radius_x = Length.new(radius_x).abs
134
+ radius_y = Length.new(radius_y).abs
122
135
  large_arc = (center_angle.abs > 180)
123
136
 
124
- arc_start_pt = Coordinate.new(radius_x * Math.cos(Math::PI * start_angle / 180), radius_y * Math.sin(Math::PI * start_angle / 180)) + center_point
125
- arc_end_pt = Coordinate.new(radius_x * Math.cos(Math::PI * (start_angle + center_angle) / 180), radius_y * Math.sin(Math::PI * (start_angle + center_angle) / 180)) + center_point
126
-
127
- draw_path(canvas, center_point, merge_option(options)) {|path|
128
- path.line_to(arc_start_pt)
129
- if center_angle.abs > 270
130
- transit_pt = center_point * 2 - arc_start_pt
131
- path.arc_to(transit_pt, radius_x, radius_y, 0, true)
132
- path.arc_to(arc_end_pt, radius_x, radius_y, 0, false)
137
+ if inner_radius >= 1 || 0 > inner_radius
138
+ raise ArgumentError, "inner_radius option is out of range: #{inner_radius}"
139
+ end
140
+ if 360 <= center_angle
141
+ if inner_radius == 0.0
142
+ draw_ellipse(canvas, center_point, radius_x, radius_y, options)
133
143
  else
134
- path.arc_to(arc_end_pt, radius_x, radius_y, 0, large_arc)
144
+ draw_toroid(canvas, center_point, radius_x, radius_y, inner_radius, options)
135
145
  end
136
- path.line_to(center_point)
146
+ else
147
+ arc_start_pt = Coordinate.new(
148
+ radius_x * DYI::Util.cos(start_angle),
149
+ radius_y * DYI::Util.sin(start_angle)) + center_point
150
+ arc_end_pt = Coordinate.new(
151
+ radius_x * DYI::Util.cos(start_angle + center_angle),
152
+ radius_y * DYI::Util.sin(start_angle + center_angle)) + center_point
153
+
154
+ draw_sector_internal(canvas, center_point,
155
+ radius_x, radius_y, inner_radius,
156
+ arc_start_pt, arc_end_pt,
157
+ start_angle, center_angle, options)
158
+ end
159
+ end
160
+
161
+ # @since 1.1.0
162
+ def draw_toroid(canvas, center_point, radius_x, radius_y, inner_radius, options={})
163
+ if inner_radius >= 1 || 0 > inner_radius
164
+ raise ArgumentError, "inner_radius option is out of range: #{inner_radius}"
165
+ end
166
+ radius_x, radius_y = Length.new(radius_x).abs, Length.new(radius_y).abs
167
+ center_point = Coordinate.new(center_point)
168
+ arc_start_pt = center_point + [radius_x, 0]
169
+ arc_opposite_pt = center_point - [radius_x, 0]
170
+ inner_arc_start_pt = center_point + [radius_x * inner_radius, 0]
171
+ inner_arc_opposite_pt = center_point - [radius_x * inner_radius, 0]
172
+
173
+ draw_closed_path(canvas, arc_start_pt, options) {|path|
174
+ path.arc_to(arc_opposite_pt, radius_x, radius_y, 0, true)
175
+ path.arc_to(arc_start_pt, radius_x, radius_y, 0, true)
176
+ path.close_path
177
+ path.move_to(inner_arc_start_pt)
178
+ path.arc_to(inner_arc_opposite_pt,
179
+ radius_x * inner_radius,
180
+ radius_y * inner_radius, 0, true, false)
181
+ path.arc_to(inner_arc_start_pt,
182
+ radius_x * inner_radius,
183
+ radius_y * inner_radius, 0, true, false)
137
184
  }
138
185
  end
139
186
 
@@ -146,6 +193,27 @@ module DYI #:nodoc:
146
193
  def merge_option(options)
147
194
  {:painting=>@painting, :font=>@font}.merge(options)
148
195
  end
196
+
197
+ # @since 1.1.0
198
+ def draw_sector_internal(canvas, center_point,
199
+ radius_x, radius_y, inner_radius,
200
+ arc_start_pt, arc_end_pt,
201
+ start_angle, center_angle, merged_options)
202
+ draw_closed_path(canvas, arc_start_pt, merged_options) {|path|
203
+ path.arc_to(arc_end_pt, radius_x, radius_y, 0, (180 < center_angle))
204
+ if inner_radius == 0
205
+ path.line_to(center_point) if center_angle != 180
206
+ else
207
+ inner_arc_start_pt = center_point * (1 - inner_radius) + arc_end_pt * inner_radius
208
+ inner_arc_end_pt = center_point * (1 - inner_radius) + arc_start_pt * inner_radius
209
+
210
+ path.line_to(inner_arc_start_pt)
211
+ path.arc_to(inner_arc_end_pt,
212
+ radius_x * inner_radius,
213
+ radius_y * inner_radius, 0, (180 < center_angle), false)
214
+ end
215
+ }
216
+ end
149
217
  end
150
218
 
151
219
  class Pen < PenBase
@@ -111,6 +111,7 @@ module DYI #:nodoc:
111
111
 
112
112
  class CylinderBrush < Brush
113
113
 
114
+ # @since 1.1.0
114
115
  def initialize(options={})
115
116
  self.ry = options.delete(:ry)
116
117
  super
@@ -177,6 +178,12 @@ module DYI #:nodoc:
177
178
 
178
179
  class ColumnBrush < Brush
179
180
 
181
+ def initialize(options={})
182
+ self.flank_color = options.delete(:flank_color)
183
+ self.dy = options.delete(:dy)
184
+ super
185
+ end
186
+
180
187
  def dy
181
188
  @dy || Length.new(16)
182
189
  end
@@ -185,85 +192,275 @@ module DYI #:nodoc:
185
192
  @dy = Length.new_or_nil(value)
186
193
  end
187
194
 
188
- def draw_sector(canvas, center_point, radius_x, radius_y, start_angle, center_angle, options={})
189
- @fill = color
195
+ # Returns a flank color
196
+ # @since 1.1.0
197
+ def flank_color
198
+ @flank_color || color.merge('black', 0.2)
199
+ end
200
+
201
+ # Set a flank color
202
+ # @since 1.1.0
203
+ def flank_color=(color)
204
+ @flank_color = Color.new_or_nil(color)
205
+ end
206
+
207
+ # Draw a cylinder by specifying the upper surface, which is a circle
208
+ # @since 1.1.0
209
+ def draw_circle(canvas, center_point, radius, options={})
210
+ radius = Length.new(radius).abs
211
+ center_point = Coordinate.new(center_point)
212
+ group_options = {}
213
+ parts_options = merge_option(options)
214
+ (flank_painting = @painting.dup).fill = flank_color
215
+ flank_options = parts_options.merge(:painting => flank_painting)
216
+ [:anchor_href, :anchor_target, :css_class, :id].each do |key|
217
+ group_options[key] = parts_options.delete(key)
218
+ end
219
+ shape = Shape::ShapeGroup.draw_on(canvas, group_options)
220
+ super(shape, center_point + [0, dy], radius, parts_options)
221
+ draw_closed_path(shape, center_point - [radius, 0], flank_options) {|path|
222
+ path.rarc_to([radius * 2, 0], radius, radius)
223
+ path.rline_to([0, dy])
224
+ path.rarc_to([- radius * 2, 0], radius, radius, 0, false, false)
225
+ }
226
+ draw_closed_path(shape, center_point - [radius, 0], flank_options) {|path|
227
+ path.rarc_to([radius * 2, 0], radius, radius, 0, false, false)
228
+ path.rline_to([0, dy])
229
+ path.rarc_to([- radius * 2, 0], radius, radius)
230
+ }
231
+ super(shape, center_point, radius, parts_options)
232
+ shape
233
+ end
234
+
235
+ # Draw a cylinder by specifying the upper surface, which is a ellipse
236
+ # @since 1.1.0
237
+ def draw_ellipse(canvas, center_point, radius_x, radius_y, options={})
238
+ radius_x, radius_y = Length.new(radius_x).abs, Length.new(radius_y).abs
239
+ center_point = Coordinate.new(center_point)
240
+ group_options = {}
241
+ parts_options = merge_option(options)
242
+ (flank_painting = @painting.dup).fill = flank_color
243
+ flank_options = parts_options.merge(:painting => flank_painting)
244
+ [:anchor_href, :anchor_target, :css_class, :id].each do |key|
245
+ group_options[key] = parts_options.delete(key)
246
+ end
247
+ shape = Shape::ShapeGroup.draw_on(canvas, group_options)
248
+ super(shape, center_point + [0, dy], radius_x, radius_y, parts_options)
249
+ draw_closed_path(shape, center_point - [radius_x, 0], flank_options) {|path|
250
+ path.rarc_to([radius_x * 2, 0], radius_x, radius_y)
251
+ path.rline_to([0, dy])
252
+ path.rarc_to([- radius_x * 2, 0], radius_x, radius_y, 0, false, false)
253
+ }
254
+ draw_closed_path(shape, center_point - [radius_x, 0], flank_options) {|path|
255
+ path.rarc_to([radius_x * 2, 0], radius_x, radius_y, 0, false, false)
256
+ path.rline_to([0, dy])
257
+ path.rarc_to([- radius_x * 2, 0], radius_x, radius_y)
258
+ }
259
+ super(shape, center_point, radius_x, radius_y, parts_options)
260
+ shape
261
+ end
190
262
 
191
- start_angle = (center_angle > 0 ? start_angle : (start_angle + center_angle)) % 360
192
- center_angle = center_angle.abs % 360
263
+ # @since 1.1.0
264
+ def draw_toroid(canvas, center_point, radius_x, radius_y, inner_radius, options={})
265
+ if inner_radius >= 1 || 0 > inner_radius
266
+ raise ArgumentError, "inner_radius option is out of range: #{inner_radius}"
267
+ end
268
+ radius_x, radius_y = Length.new(radius_x).abs, Length.new(radius_y).abs
193
269
  center_point = Coordinate.new(center_point)
194
- radius_x = Length.new(radius_x)
195
- radius_y = Length.new(radius_y)
196
- large_arc = (center_angle > 180)
270
+ arc_right_pt = center_point + [radius_x, 0]
271
+ arc_left_pt = center_point - [radius_x , 0]
272
+ inner_radius_x = radius_x * inner_radius
273
+ inner_radius_y = radius_y * inner_radius
274
+ inner_arc_right_pt = center_point + [inner_radius_x , 0]
275
+ inner_arc_left_pt = center_point - [inner_radius_x, 0]
276
+ group_options = {}
277
+ parts_options = merge_option(options)
278
+ (flank_painting = @painting.dup).fill = flank_color
279
+ flank_options = parts_options.merge(:painting => flank_painting)
280
+ [:anchor_href, :anchor_target, :css_class, :id].each do |key|
281
+ group_options[key] = parts_options.delete(key)
282
+ end
283
+ shape = Shape::ShapeGroup.draw_on(canvas, group_options)
284
+
285
+ super(shape, center_point + [0, dy], radius_x, radius_y, inner_radius, parts_options)
286
+ draw_sector_back_flank(shape, center_point,
287
+ radius_x, radius_y,
288
+ arc_left_pt, arc_right_pt,
289
+ 180, 180, flank_options)
290
+ draw_sector_back_flank(shape, center_point,
291
+ inner_radius_x, inner_radius_y,
292
+ inner_arc_left_pt, inner_arc_right_pt,
293
+ 180, 180, flank_options)
294
+ draw_sector_front_flank(shape, center_point,
295
+ inner_radius_x, inner_radius_y,
296
+ inner_arc_right_pt, inner_arc_left_pt,
297
+ 0, 180, flank_options)
298
+ draw_sector_front_flank(shape, center_point,
299
+ radius_x, radius_y,
300
+ arc_right_pt, arc_left_pt,
301
+ 0, 180, flank_options)
302
+ super(shape, center_point, radius_x, radius_y, inner_radius, parts_options)
303
+ end
197
304
 
198
- arc_start_pt = Coordinate.new(radius_x * Math.cos(Math::PI * start_angle / 180), radius_y * Math.sin(Math::PI * start_angle / 180)) + center_point
199
- arc_end_pt = Coordinate.new(radius_x * Math.cos(Math::PI * (start_angle + center_angle) / 180), radius_y * Math.sin(Math::PI * (start_angle + center_angle) / 180)) + center_point
305
+ private
200
306
 
201
- org_opacity = opacity
202
- if org_color = color
203
- self.color = color.merge('black', 0.2)
307
+ # @since 1.1.0
308
+ def draw_sector_internal(canvas, center_point,
309
+ radius_x, radius_y, inner_radius,
310
+ arc_start_pt, arc_end_pt,
311
+ start_angle, center_angle, merged_options)
312
+ if inner_radius == 0
313
+ inner_arc_start_pt = inner_arc_end_pt = center_point
204
314
  else
205
- self.color = 'black'
206
- self.opacity = 0.2
315
+ inner_arc_start_pt = center_point * (1 - inner_radius) + arc_end_pt * inner_radius
316
+ inner_arc_end_pt = center_point * (1 - inner_radius) + arc_start_pt * inner_radius
317
+ inner_radius_x = radius_x * inner_radius
318
+ inner_radius_y = radius_y * inner_radius
319
+ end
320
+ group_options = {}
321
+ parts_options = merged_options.dup
322
+ (flank_painting = @painting.dup).fill = flank_color
323
+ flank_options = parts_options.merge(:painting => flank_painting)
324
+ [:anchor_href, :anchor_target, :css_class, :id].each do |key|
325
+ group_options[key] = parts_options.delete(key)
207
326
  end
327
+ shape = Shape::ShapeGroup.draw_on(canvas, group_options)
208
328
 
209
- if (90..270).include?(start_angle) && center_angle < 180
210
- draw_polygon(canvas, center_point, options) {|polygon|
211
- polygon.line_to(center_point + [0, dy])
212
- polygon.line_to(arc_end_pt + [0, dy])
213
- polygon.line_to(arc_end_pt)
214
- }
215
- draw_polygon(canvas, center_point, options) {|polygon|
216
- polygon.line_to(center_point + [0, dy])
217
- polygon.line_to(arc_start_pt + [0, dy])
218
- polygon.line_to(arc_start_pt)
329
+ super(shape, center_point + [0, dy],
330
+ radius_x, radius_y, inner_radius,
331
+ arc_start_pt + [0, dy], arc_end_pt + [0, dy],
332
+ start_angle, center_angle, parts_options)
333
+
334
+ draw_sector_back_flank(shape, center_point,
335
+ radius_x, radius_y,
336
+ arc_start_pt, arc_end_pt,
337
+ start_angle, center_angle, flank_options)
338
+
339
+ if center_angle == 180 && inner_radius == 0
340
+ draw_polygon(shape, arc_start_pt, flank_options) {|polygon|
341
+ polygon.line_to(arc_start_pt + [0, dy], arc_end_pt + [0, dy], arc_end_pt)
219
342
  }
220
343
  else
221
- draw_polygon(canvas, center_point, options) {|polygon|
222
- polygon.line_to(center_point + [0, dy])
223
- polygon.line_to(arc_start_pt + [0, dy])
224
- polygon.line_to(arc_start_pt)
225
- }
226
- draw_polygon(canvas, center_point, options) {|polygon|
227
- polygon.line_to(center_point + [0, dy])
228
- polygon.line_to(arc_end_pt + [0, dy])
229
- polygon.line_to(arc_end_pt)
230
- }
344
+ pt_ys = [[arc_start_pt.y, proc {
345
+ draw_polygon(shape, inner_arc_end_pt, flank_options) {|polygon|
346
+ polygon.line_to(inner_arc_end_pt + [0, dy], arc_start_pt + [0, dy], arc_start_pt)
347
+ }
348
+ }],
349
+ [arc_end_pt.y, proc {
350
+ draw_polygon(shape, inner_arc_start_pt, flank_options) {|polygon|
351
+ polygon.line_to(inner_arc_start_pt + [0, dy], arc_end_pt + [0, dy], arc_end_pt)
352
+ }
353
+ }],
354
+ [center_point.y, proc {
355
+ if inner_radius != 0
356
+ draw_sector_back_flank(shape, center_point,
357
+ inner_radius_x, inner_radius_y,
358
+ inner_arc_end_pt, inner_arc_start_pt,
359
+ start_angle, center_angle, flank_options)
360
+ draw_sector_front_flank(shape, center_point,
361
+ inner_radius_x, inner_radius_y,
362
+ inner_arc_end_pt, inner_arc_start_pt,
363
+ start_angle, center_angle, flank_options)
364
+ end
365
+ }]]
366
+
367
+ pt_ys.sort{|a,b| a[0] <=> b[0]}.each do |pt_y|
368
+ pt_y[1].call
369
+ end
231
370
  end
232
- if (0..180).include?(start_angle)
233
- draw_path(canvas, arc_start_pt, options) {|path|
234
- path.line_to(arc_start_pt + [0, dy])
235
- if arc_end_pt.y >= center_point.y
236
- path.arc_to(arc_end_pt + [0, dy], radius_x, radius_y, 0, false)
237
- path.line_to(arc_end_pt)
238
- path.arc_to(arc_start_pt, radius_x, radius_y, 0, false, false)
239
- else
240
- path.arc_to(center_point + [-(radius_x.abs), dy], radius_x, radius_y, 0, false)
241
- path.line_to(center_point + [-(radius_x.abs), 0])
242
- path.arc_to(arc_start_pt, radius_x, radius_y, 0, false, false)
371
+
372
+ draw_sector_front_flank(shape, center_point,
373
+ radius_x, radius_y,
374
+ arc_start_pt, arc_end_pt,
375
+ start_angle, center_angle, flank_options)
376
+
377
+ super(shape, center_point,
378
+ radius_x, radius_y, inner_radius,
379
+ arc_start_pt, arc_end_pt,
380
+ start_angle, center_angle, parts_options)
381
+ shape
382
+ end
383
+
384
+ # @since 1.1.0
385
+ def draw_sector_back_flank(canvas, center_point,
386
+ radius_x, radius_y,
387
+ arc_start_pt, arc_end_pt,
388
+ start_angle, center_angle, options)
389
+ if start_angle < 180
390
+ if 360 < start_angle + center_angle
391
+ draw_closed_path(canvas, center_point - [radius_x, 0], options) {|path|
392
+ path.rarc_to([radius_x * 2, 0], radius_x, radius_y)
393
+ path.rline_to([0, dy])
394
+ path.rarc_to([- radius_x * 2, 0], radius_x, radius_y, 0, false, false)
395
+ }
396
+ elsif 180 < start_angle + center_angle
397
+ draw_closed_path(canvas, center_point - [radius_x, 0], options) {|path|
398
+ path.arc_to(arc_end_pt, radius_x, radius_y)
399
+ path.rline_to([0, dy])
400
+ path.arc_to(center_point + [-radius_x, dy], radius_x, radius_y, 0, false, false)
401
+ }
402
+ end
403
+ elsif 360 < start_angle + center_angle
404
+ draw_closed_path(canvas, arc_start_pt, options) {|path|
405
+ path.arc_to(center_point + [radius_x, 0], radius_x, radius_y)
406
+ path.rline_to([0, dy])
407
+ path.arc_to(arc_start_pt + [0, dy], radius_x, radius_y, 0, false, false)
408
+ if 540 < start_angle + center_angle
409
+ path.close_path
410
+ path.move_to(center_point - [radius_x, 0])
411
+ path.arc_to(arc_end_pt, radius_x, radius_y)
412
+ path.rline_to([0, dy])
413
+ path.arc_to(center_point + [-radius_x, dy], radius_x, radius_y, 0, false, false)
243
414
  end
244
415
  }
245
- elsif (270..360).include?(start_angle) && start_angle + center_angle > 360
246
- draw_path(canvas, center_point + [radius_x.abs, 0], options) {|path|
247
- path.line_to(center_point + [radius_x.abs, dy])
248
- if arc_end_pt.y >= center_point.y
249
- path.arc_to(arc_end_pt + [0, dy], radius_x, radius_y, 0, false)
250
- path.line_to(arc_end_pt)
251
- path.arc_to(center_point + [radius_x.abs, 0], radius_x, radius_y, 0, false, false)
252
- else
253
- path.arc_to(center_point + [-(radius_x.abs), dy], radius_x, radius_y, 0, false)
254
- path.line_to(center_point + [-(radius_x.abs), 0])
255
- path.arc_to(center_point + [radius_x.abs, 0], radius_x, radius_y, 0, false, false)
256
- end
416
+ else
417
+ draw_closed_path(canvas, arc_start_pt, options) {|path|
418
+ path.arc_to(arc_end_pt, radius_x, radius_y)
419
+ path.rline_to([0, dy])
420
+ path.arc_to(arc_start_pt + [0, dy], radius_x, radius_y, 0, false, false)
257
421
  }
258
422
  end
259
- self.color = org_color
260
- self.opacity = org_opacity
423
+ end
261
424
 
262
- draw_path(canvas, center_point, options) {|path|
263
- path.line_to(arc_start_pt)
264
- path.arc_to(arc_end_pt, radius_x, radius_y, 0, large_arc)
265
- path.line_to(center_point)
266
- }
425
+ # @since 1.1.0
426
+ def draw_sector_front_flank(canvas, center_point,
427
+ radius_x, radius_y,
428
+ arc_start_pt, arc_end_pt,
429
+ start_angle, center_angle, options)
430
+ if start_angle < 180
431
+ if 180 < start_angle + center_angle
432
+ draw_closed_path(canvas, arc_start_pt, options) {|path|
433
+ path.arc_to(center_point - [radius_x, 0], radius_x, radius_y)
434
+ path.rline_to([0, dy])
435
+ path.arc_to(arc_start_pt + [0, dy], radius_x, radius_y, 0, false, false)
436
+ if 360 < start_angle + center_angle
437
+ path.close_path
438
+ path.move_to(center_point + [radius_x, 0])
439
+ path.arc_to(arc_end_pt, radius_x, radius_y)
440
+ path.rline_to([0, dy])
441
+ path.arc_to(center_point + [radius_x, dy], radius_x, radius_y, 0, false, false)
442
+ end
443
+ }
444
+ else
445
+ draw_closed_path(canvas, arc_start_pt, options) {|path|
446
+ path.arc_to(arc_end_pt, radius_x, radius_y)
447
+ path.rline_to([0, dy])
448
+ path.arc_to(arc_start_pt + [0, dy], radius_x, radius_y, 0, false, false)
449
+ }
450
+ end
451
+ elsif 540 < start_angle + center_angle
452
+ draw_closed_path(canvas, center_point + [radius_x, 0], options) {|path|
453
+ path.arc_to(center_point - [radius_x, 0], radius_x, radius_y)
454
+ path.rline_to([0, dy])
455
+ path.arc_to(center_point + [radius_x, dy], radius_x, radius_y, 0, false, false)
456
+ }
457
+ elsif 360 < start_angle + center_angle
458
+ draw_closed_path(canvas, center_point + [radius_x, 0], options) {|path|
459
+ path.arc_to(arc_end_pt, radius_x, radius_y)
460
+ path.rline_to([0, dy])
461
+ path.arc_to(center_point + [radius_x, dy], radius_x, radius_y, 0, false, false)
462
+ }
463
+ end
267
464
  end
268
465
  end
269
466
  end