dyi 1.1.2 → 1.2.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.2.0 / 2012-04-02
4
+ * Minor Enhancement
5
+ * Marker support.
6
+ * LineChart support markers.
7
+ * Bug Fixes
8
+ * Factory method of Animation is invalid.
9
+ * Event handers are not attached properly.
10
+
3
11
  == Version 1.1.2 / 2012-03-01
4
12
  * Bug Fixes
5
13
  * Calls data_label_format property instead of baloon_format when it draws the baloon of PieChart.
data/lib/dyi.rb CHANGED
@@ -24,7 +24,7 @@
24
24
  module DYI
25
25
 
26
26
  # DYI program version
27
- VERSION = '1.1.2'
27
+ VERSION = '1.2.0'
28
28
 
29
29
  # URL of DYI Project
30
30
  # @since 0.0.2
data/lib/dyi/animation.rb CHANGED
@@ -243,15 +243,15 @@ module DYI
243
243
  new(shape, :scale, options)
244
244
  end
245
245
 
246
- def scale(rotate, options)
246
+ def rotate(shape, options)
247
247
  new(shape, :rotate, options)
248
248
  end
249
249
 
250
- def skew_x(rotate, options)
250
+ def skew_x(shape, options)
251
251
  new(shape, :skewX, options)
252
252
  end
253
253
 
254
- def skew_y(rotate, options)
254
+ def skew_y(shape, options)
255
255
  new(shape, :skewY, options)
256
256
  end
257
257
  end
data/lib/dyi/canvas.rb CHANGED
@@ -259,7 +259,7 @@ module DYI
259
259
  if @init_script
260
260
  @init_script.append_body(script_body)
261
261
  else
262
- @init_script = Script::EcmaScript::EventListener.new(script_body, 'init')
262
+ @init_script = Script::EcmaScript::EventListener.new(script_body)
263
263
  add_event_listener(:load, @init_script)
264
264
  end
265
265
  end
@@ -243,6 +243,10 @@ module DYI
243
243
  # Returns or sets the CSS class of the image body of the chart.
244
244
  opt_accessor :canvas_css_class, :type => :string
245
245
 
246
+ # Returns or sets whether to output chart's data as metadata in a SVG file.
247
+ # @since 1.2.0
248
+ opt_accessor :output_chart_data, :type => :boolean, :default => false
249
+
246
250
  # @param [Length] width width of the chart image
247
251
  # @param [Length] height height of the chart image
248
252
  # @param [Hash{Symbol => Object}] options the options to creat the chart
@@ -373,6 +377,7 @@ module DYI
373
377
  @canvas.add_css_class(canvas_css_class) if canvas_css_class && !canvas_css_class.empty?
374
378
  @canvas.add_script(script_body) if script_body && !script_body.empty?
375
379
  @canvas.add_stylesheet(css_body) if css_body && !css_body.empty?
380
+ @canvas.metadata = data if output_chart_data?
376
381
  script_files && script_files.each do |script_file|
377
382
  @canvas.reference_script_file(script_file)
378
383
  end
@@ -29,7 +29,13 @@ module DYI
29
29
  include AxisUtil
30
30
  include Legend
31
31
  CHART_TYPES = [:line, :area, :bar, :stackedbar]
32
+
33
+ # @since 1.2.0
34
+ DEFAULT_MARKERS = [:circle, :square, :traiangle, :pentagon, :rhombus, :inverted_triangle]
35
+
32
36
  attr_reader :axis_back_canvas, :chart_back_canvas, :scale_canvas, :chart_front_canvas, :axis_front_canvas, :legend_canvas
37
+ # @since 1.2.0
38
+ attr_reader :x_scale_canvas, :y_scale_canvas, :guid_front_canvas, :chart_region
33
39
 
34
40
  opt_accessor :chart_margins, {:type => :hash, :default => {}, :keys => [:top,:right,:bottom,:left], :item_type => :length}
35
41
  opt_accessor :chart_colors, {:type => :array, :item_type => :color}
@@ -56,7 +62,19 @@ module DYI
56
62
  opt_accessor :use_effect, {:type => :boolean, :default => true}
57
63
  opt_accessor :bar_seriese_interval, {:type => :float, :default => 0.3}
58
64
  opt_accessor :color_columns, {:type => :array, :item_type => :integer}
59
-
65
+
66
+ # Returns or sets whether to show marker on the line chart.
67
+ # @since 1.2.0
68
+ opt_accessor :show_markers, :type => :boolean
69
+
70
+ # Returns or sets marker types on the line-chart.
71
+ # @since 1.2.0
72
+ opt_accessor :markers, {:type => :array, :item_type => :symbol}
73
+
74
+ # Returns or sets a marker size on the line-chart.
75
+ # @since 1.2.0
76
+ opt_accessor :marker_size, {:type => :float, :default => 2.5}
77
+
60
78
  def margin_top
61
79
  chart_margins[:top] || Length.new(16)
62
80
  end
@@ -196,18 +214,30 @@ module DYI
196
214
  def init_container
197
215
  # mask = Drawing::ColorEffect::Mask.new(@canvas)
198
216
  # mask.add_shapes(Shape::Rectangle.new(Drawing::Brush.new(:color => '#FFFFFF'), [margin_left, margin_top], chart_width, chart_height))
199
- @axis_back_canvas = Shape::ShapeGroup.draw_on(@canvas) unless @axis_back_canvas
217
+ @back_canvas = Shape::ShapeGroup.draw_on(@canvas)
218
+ @axis_back_canvas = Shape::ShapeGroup.draw_on(@canvas)
200
219
  # @chart_front_canvas = Shape::ShapeGroup.draw_on(@canvas, :mask => "url(##{mask.id})") unless @chart_front_canvas
201
- @chart_back_canvas = Shape::ShapeGroup.draw_on(@canvas) unless @chart_back_canvas
220
+ chart_clip = Drawing::Clipping.new(Shape::Rectangle.new([margin_left, margin_top], width - margin_left - margin_right, height - margin_top - margin_bottom))
221
+ unless @chart_back_canvas
222
+ clip_container = Shape::ShapeGroup.draw_on(@canvas)
223
+ @chart_back_canvas = Shape::ShapeGroup.draw_on(clip_container)
224
+ clip_container.set_clipping(chart_clip)
225
+ end
202
226
  @scale_canvas = Shape::ShapeGroup.draw_on(@canvas) unless @scale_canvas
203
- @chart_front_canvas = Shape::ShapeGroup.draw_on(@canvas) unless @chart_front_canvas
227
+ unless @chart_front_canvas
228
+ clip_container = Shape::ShapeGroup.draw_on(@canvas)
229
+ @chart_front_canvas = Shape::ShapeGroup.draw_on(clip_container)
230
+ clip_container.set_clipping(chart_clip)
231
+ @chart_region = Shape::Rectangle.new([margin_left, margin_top], width - margin_left - margin_right, height - margin_top - margin_bottom, :painting => {:stroke_width => 0})
232
+ @chart_region.draw_on(clip_container)
233
+ @guid_front_canvas = Shape::ShapeGroup.draw_on(clip_container)
234
+ end
235
+ @x_scale_canvas = Shape::ShapeGroup.draw_on(@canvas) unless @x_scale_canvas
236
+ @y_scale_canvas = Shape::ShapeGroup.draw_on(@canvas) unless @y_scale_canvas
204
237
  @axis_front_canvas = Shape::ShapeGroup.draw_on(@canvas) unless @axis_front_canvas
205
238
  @legend_canvas = Shape::ShapeGroup.draw_on(@canvas) unless @legend_canvas
206
239
  @chart_options = {}
207
240
  # @chart_options[:filter] = "url(##{Drawing::Filter::DropShadow.new(@canvas, dropshadow_blur_std, dropshadow_dx, dropshadow_dy).id})" if show_dropshadow?
208
- chart_clip = Drawing::Clipping.new(Shape::Rectangle.new([margin_left, margin_top], width - margin_left - margin_right, height - margin_top - margin_bottom))
209
- @chart_back_canvas.set_clipping(chart_clip)
210
- @chart_front_canvas.set_clipping(chart_clip)
211
241
  end
212
242
 
213
243
  def draw_axis(settings, sub_settings)
@@ -241,7 +271,7 @@ module DYI
241
271
  y = value_position_on_chart(margin_top, settings, settings[:min], true)
242
272
  if use_y_second_axis? || main_y_axis == :left
243
273
  text_pen.draw_text(
244
- @axis_front_canvas,
274
+ @y_scale_canvas,
245
275
  [margin_left - text_margin, y],
246
276
  main_y_axis == :left ? settings[:min] : sub_settings[:min],
247
277
  :text_anchor=>'end',
@@ -249,7 +279,7 @@ module DYI
249
279
  end
250
280
  if use_y_second_axis? || main_y_axis == :right
251
281
  text_pen.draw_text(
252
- @axis_front_canvas,
282
+ @y_scale_canvas,
253
283
  [width - margin_right + text_margin, y],
254
284
  main_y_axis == :right ? settings[:min] : sub_settings[:min],
255
285
  :format => (main_y_axis == :right ? axis_format : second_axis_format))
@@ -294,7 +324,7 @@ module DYI
294
324
 
295
325
  if use_y_second_axis? || main_y_axis == :left
296
326
  text_pen.draw_text(
297
- @axis_back_canvas,
327
+ @y_scale_canvas,
298
328
  [margin_left - text_margin, y],
299
329
  main_y_axis == :left ? value : sub_axis_value,
300
330
  :alignment_baseline=>'middle',
@@ -305,7 +335,7 @@ module DYI
305
335
 
306
336
  if use_y_second_axis? || main_y_axis == :right
307
337
  text_pen.draw_text(
308
- @axis_front_canvas,
338
+ @y_scale_canvas,
309
339
  [width - margin_right + text_margin, y],
310
340
  main_y_axis == :right ? value : sub_axis_value,
311
341
  :alignment_baseline=>'middle',
@@ -333,13 +363,13 @@ module DYI
333
363
  text_x = order_position_on_chart(margin_left, chart_width, data.records_size, i, x_axis_type)
334
364
  scale_x = x_axis_type == :range ? order_position_on_chart(margin_left, chart_width, data.records_size + 1, i) : text_x
335
365
  text_pen.draw_text(
336
- @axis_front_canvas,
366
+ @x_scale_canvas,
337
367
  [text_x, height - margin_bottom + text_margin],
338
368
  format_x_label(data.name_values[i]),
339
369
  :text_anchor => 'middle', :alignment_baseline => 'top') if show_x_labels?
340
370
 
341
371
  sub_pen.draw_line_on_direction(
342
- @axis_front_canvas,
372
+ @guid_front_canvas,
343
373
  [scale_x, height - margin_bottom],
344
374
  0,
345
375
  -(axis_font ? axis_font.draw_size : Font::DEFAULT_SIZE) * 0.5) if i > 0 && i < data.records_size - (x_axis_type == :range ? 0 : 1)
@@ -365,13 +395,17 @@ module DYI
365
395
  x = order_position_on_chart(margin_left, chart_width, values.size, first_index, x_axis_type)
366
396
  y = value_position_on_chart(margin_top, settings, values[first_index], true)
367
397
  pen.linejoin = 'bevel'
368
- pen.draw_polyline(@chart_front_canvas, [x, y], @chart_options) {|polyline|
369
- ((first_index + 1)...values.size).each do |i|
370
- x = order_position_on_chart(margin_left, chart_width, values.size, i, x_axis_type)
371
- y = value_position_on_chart(margin_top, settings, values[i], true)
372
- polyline.line_to([x, y])
373
- end
374
- }
398
+ polyline = pen.draw_polyline(@chart_front_canvas, [x, y], @chart_options) {|polyline|
399
+ ((first_index + 1)...values.size).each do |i|
400
+ x = order_position_on_chart(margin_left, chart_width, values.size, i, x_axis_type)
401
+ y = value_position_on_chart(margin_top, settings, values[i], true)
402
+ polyline.line_to([x, y])
403
+ end
404
+ }
405
+ if show_markers?
406
+ marker_type = (markers && markers[id % markers.size]) || DEFAULT_MARKERS[id % DEFAULT_MARKERS.size]
407
+ polyline.set_marker(:all, marker_type, :size => marker_size)
408
+ end
375
409
  pen.linejoin = 'bevel'
376
410
  end
377
411
 
data/lib/dyi/element.rb CHANGED
@@ -163,7 +163,7 @@ module DYI
163
163
  @event_listeners ||= {}
164
164
  end
165
165
 
166
- # Adds a animation of painting to the element.
166
+ # Sets an event to this element.
167
167
  # @param [Event] event an event that is set to the element
168
168
  # @return [String] id for this element
169
169
  def set_event(event)
@@ -172,34 +172,43 @@ module DYI
172
172
  publish_id
173
173
  end
174
174
 
175
+ # Registers event listeners on this element.
176
+ # @param [String] event_name an event name for which the user is registering
177
+ # @param [Script::EcmaScript::EventListener, ] event_listener an event name for which the user is registering
178
+ # @return [String] id for this element
179
+ def add_event_listener(event_name, event_listener)
180
+
181
+ end
182
+
175
183
  # Returns whether an event is set to the element.
176
184
  # @return [Boolean] true if an event is set to the element, false otherwise
177
185
  def event_target?
178
186
  !(@events.nil? || @events.empty?)
179
187
  end
180
188
 
181
- # Associates the element with a event listener.
182
- # @param [Symbol] event_name a event name
183
- # @param [Script::SimpleScript] event_listener a event listener
184
- def add_event_listener(event_name, event_listener)
185
- event_listener.related_to(DYI::Event.new(event_name, self))
189
+ # Registers event listeners on this element.
190
+ # @param [Symbol] event_name an event name for which the user is registering
191
+ # @param [Script::SimpleScript] listener an event listener which contains
192
+ # the methods to be called when the event occurs.
193
+ def add_event_listener(event_name, listener)
194
+ listener.related_to(DYI::Event.new(event_name, self))
186
195
  if event_listeners.key?(event_name)
187
- unless event_listeners[event_name].include?(event_listener)
188
- event_listeners[event_name] << event_listener
189
- canvas.add_script(event_listener)
196
+ unless event_listeners[event_name].include?(listener)
197
+ event_listeners[event_name] << listener
198
+ canvas.add_script(listener)
190
199
  end
191
200
  else
192
- event_listeners[event_name] = [event_listener]
193
- canvas.add_script(event_listener)
201
+ event_listeners[event_name] = [listener]
202
+ canvas.add_script(listener)
194
203
  end
195
204
  end
196
205
 
197
- # Removes asociation with given event listener
198
- # @param [Symbol] event_name a event name
199
- # @param [Script::SimpleScript] event_listener a event listener
200
- def remove_event_listener(event_name, event_listener)
206
+ # Removes event listeners from this element.
207
+ # @param [Symbol] event_name an event name for which the user is registering
208
+ # @param [Script::SimpleScript] listener an event listener to be removed
209
+ def remove_event_listener(event_name, listener)
201
210
  if event_listeners.key?(event_name)
202
- event_listeners[event_name].delete(event_listener)
211
+ event_listeners[event_name].delete(listener)
203
212
  end
204
213
  end
205
214
  end
@@ -75,7 +75,8 @@ module DYI
75
75
  "#{listener.name}(evt)"
76
76
  end
77
77
  end
78
- attrs["on#{event_name}"] = methods.compact.join(';')
78
+ methods.compact!
79
+ attrs["on#{event_name}"] = methods.join(';') unless methods.empty?
79
80
  end
80
81
  end
81
82
  sio = StringIO.new
@@ -357,6 +358,23 @@ module DYI
357
358
  }
358
359
  end
359
360
 
361
+ # @since 1.2.0
362
+ def write_marker(marker, io)
363
+ attrs = {:id => marker.id,
364
+ :viewBox => marker.view_box,
365
+ :refX => marker.ref_point.x,
366
+ :refY => marker.ref_point.y,
367
+ :markerUnits => marker.marker_units,
368
+ :markerWidth => marker.width,
369
+ :markerHeight => marker.height}
370
+ attrs[:orient] = marker.orient.to_s if marker.orient
371
+ create_node(io, 'marker', attrs) {
372
+ marker.shapes.each_with_index do |shape, i|
373
+ shape.write_as(self, io)
374
+ end
375
+ }
376
+ end
377
+
360
378
  # @since 1.0.0
361
379
  def write_painting_animation(anim, shape, io)
362
380
  anim.animation_attributes.each do |anim_attr, (from_value, to_value)|
@@ -556,6 +574,14 @@ module DYI
556
574
  if element.respond_to?(:attributes) && element.attributes[:show_border]
557
575
  @text_border_elements << element
558
576
  end
577
+ if element.respond_to?(:has_marker?)
578
+ [:start, :mid, :end].each do |point_type|
579
+ if element.has_marker?(point_type) && !@defs.value?(element.marker(point_type))
580
+ def_id = element.marker(point_type).id
581
+ @defs[def_id] = element.marker(point_type)
582
+ end
583
+ end
584
+ end
559
585
  element.child_elements.each do |child_element|
560
586
  examin_descendant_elements(child_element)
561
587
  end
@@ -619,8 +645,11 @@ module DYI
619
645
  transform = create_transform(shape)
620
646
  attributes[:transform] = transform if transform
621
647
  attributes[:'clip-path'] = "url(##{shape.clipping.id})" if shape.clipping
648
+ attributes[:'marker-start'] = "url(##{shape.marker(:start).id})" if shape.has_marker?(:start)
649
+ attributes[:'marker-mid'] = "url(##{shape.marker(:mid).id})" if shape.has_marker?(:mid)
650
+ attributes[:'marker-end'] = "url(##{shape.marker(:end).id})" if shape.has_marker?(:end)
622
651
  attributes[:id] = shape.id if shape.inner_id
623
- attributes[:'pointer-events'] = 'all' if shape.event_target?
652
+ attributes[:'pointer-events'] = 'visible' if shape.event_target?
624
653
  attributes
625
654
  end
626
655
 
@@ -330,11 +330,19 @@ EOS
330
330
  # Class representing a function of ECMAScript. The scripting becomes
331
331
  # effective only when it is output by SVG format.
332
332
  class Function < SimpleScript
333
- attr_reader :name, :arguments
334
333
 
335
- # @param [String] body body of client scripting
336
- # @param [String] name a function name
337
- # @param [Array] arguments a list of argument's name
334
+ # Returns a function identifier on ECMAScript.
335
+ # @return [String, nil] a function identifier if the function has a
336
+ # identifier on ECMAScript, nil otherwise
337
+ attr_reader :name
338
+ # Returns an array of formal parameter identifiers on ECMAScript.
339
+ # @return [Array<String>] an array of formal parameter identifiers
340
+ attr_reader :arguments
341
+
342
+ # @param [String] body function body on ECMAScript
343
+ # @param [String] name a function identifier on ECMAScript
344
+ # @param [Array<String>] arguments a list of formal parameter
345
+ # identifiers on ECMAScript
338
346
  def initialize(body, name=nil, *arguments)
339
347
  super(body)
340
348
  if name && name !~ /\A[\$A-Z_a-z][\$0-9A-Z_a-z]*\z/
@@ -349,6 +357,8 @@ EOS
349
357
  end
350
358
  end
351
359
 
360
+ # Returns string expression of this function in ECMAScript
361
+ # @return [String] expression in ECMAScript
352
362
  # @since 1.0.3
353
363
  def contents
354
364
  parts = []
@@ -356,9 +366,9 @@ EOS
356
366
  parts << " #{name}" if name
357
367
  parts << '('
358
368
  parts << arguments.join(', ')
359
- parts << ") {\n"
369
+ parts << "){\n"
360
370
  parts << @body
361
- parts << "}\n"
371
+ parts << "\n}"
362
372
  parts.join
363
373
  end
364
374
  end
@@ -389,17 +399,19 @@ EOS
389
399
  @events.delete(event)
390
400
  end
391
401
 
402
+ # Returns string expression of this function in ECMAScript
403
+ # @return [String] expression in ECMAScript
392
404
  # @since 1.0.3
393
405
  def contents
394
406
  if name
395
407
  super
396
408
  else
397
409
  parts = []
398
- parts << "addEventListener(\"load\", function(evt) {\n"
410
+ parts << "document.addEventListener(\"DOMContentLoaded\", function(evt){\n"
399
411
  @events.each do |event|
400
412
  if event.event_name == :load
401
413
  parts << @body
402
- elsif
414
+ else
403
415
  if event.target.root_element?
404
416
  parts << ' document.documentElement.addEventListener("'
405
417
  else
@@ -408,14 +420,12 @@ EOS
408
420
  parts << '").addEventListener("'
409
421
  end
410
422
  parts << event.event_name
411
- parts << '", function('
412
- parts << arguments.join(', ')
413
- parts << ") {\n"
414
- parts << @body
415
- parts << " }, false);\n"
423
+ parts << '", '
424
+ parts << super
425
+ parts << ", false);\n"
416
426
  end
417
427
  end
418
- parts << "}, false);\n"
428
+ parts << "\n}, false);\n"
419
429
  parts.join
420
430
  end
421
431
  end
data/lib/dyi/shape.rb CHANGED
@@ -23,6 +23,7 @@
23
23
 
24
24
  base
25
25
  path
26
+ marker
26
27
 
27
28
  ).each do |file_name|
28
29
  require File.join(File.dirname(__FILE__), 'shape', file_name)
@@ -24,6 +24,95 @@ require 'enumerator'
24
24
  module DYI
25
25
  module Shape
26
26
 
27
+ # This module defines the method to attach a marker symbol to the lines,
28
+ # the polylines, the polygons or the paths.
29
+ # @since 1.2.0
30
+ module Markable
31
+
32
+ # Returns a marker symbol at the specified position.
33
+ # @param [Symbol] position the position where a marker symbol is drawn.
34
+ # Specifies the following values: +:start+, +:mid+, +:end+
35
+ # @return [Marker] a marker symbol at the specified position
36
+ def marker(position)
37
+ @marker[position]
38
+ end
39
+
40
+ # Attaches a marker symbol to the shape.
41
+ # @overload set_marker(position, marker)
42
+ # Attaches the specified marker symbol at the specified position.
43
+ # @param [Symbol] position the position where a marker symbol is drawn.
44
+ # Specifies the following values: +:start+, +:mid+, +:end+,
45
+ # +:start_end+, +:start_mid+, +:mid_end+, +:all+
46
+ # @param [Marker] marker the marker symbol that is attached
47
+ # @overload set_marker(position, marker_type, options = {})
48
+ # Attaches a pre-defined marker symbol at the specified position.
49
+ # @param [Symbol] position the position where a marker symbol is drawn.
50
+ # Specifies the following values: +:start+, +:mid+, +:end+,
51
+ # +:start_end+, +:start_mid+, +:mid_end+, +:all+
52
+ # @param [Symbol] marker_type the type of pre-defined marker symbol that
53
+ # +:square+ is attached. Specifies the following values: +:circle+,
54
+ # +:triangle+, +:rhombus+, +:pentagon+, +:hexagon+
55
+ # @param [Hash] options a customizable set of options
56
+ # @option options [Number] :size size of the marker symbol. Specifies
57
+ # the relative size to line width
58
+ # @option options [Painting] :painting painting of the marker symbol
59
+ # @option options [Number, "auto"] :orient how the marker is rotated.
60
+ # Specifies a rotated angle or <tt>"auto"</tt>. <tt>"auto"</tt> means
61
+ # the marker symbol rotate the orientation of the line
62
+ def set_marker(position, *args)
63
+ pos = case position
64
+ when :start then 0x1
65
+ when :mid then 0x2
66
+ when :end then 0x4
67
+ when :start_mid then 0x3
68
+ when :start_end then 0x5
69
+ when :mid_end then 0x6
70
+ when :all then 0x7
71
+ else raise ArgumentError, "illegal argument: #{position.inspect}"
72
+ end
73
+ case args.first
74
+ when Symbol
75
+ opts = args[1].clone || {}
76
+ opts[:painting] ||= Painting.new(:fill => painting.stroke,
77
+ :fill_opacity => painting.stroke_opacity,
78
+ :opacity => painting.opacity)
79
+ if opts[:orient] == 'auto'
80
+ opts[:direction] = position == :end ? :to_end : :to_start
81
+ end
82
+ marker = Marker.new(args.first, opts)
83
+ when Marker
84
+ marker = args.first
85
+ else
86
+ raise TypeError, "illegal argument: #{value}"
87
+ end
88
+ marker.set_canvas(canvas)
89
+ @marker[:start] = marker if pos & 0x01 != 0
90
+ @marker[:mid] = marker if pos & 0x02 != 0
91
+ if pos & 0x04 != 0
92
+ if pos & 0x01 != 0 && args.first.is_a?(Symbol) && opts[:orient] == 'auto'
93
+ opts[:painting] ||= Painting.new(:fill => painting.stroke,
94
+ :fill_opacity => painting.stroke_opacity,
95
+ :opacity => painting.opacity)
96
+ opts[:direction] = :to_end
97
+ marker = Marker.new(args.first, opts)
98
+ marker.set_canvas(canvas)
99
+ @marker[:end] = marker
100
+ else
101
+ @marker[:end] = marker
102
+ end
103
+ end
104
+ end
105
+
106
+ # Returns whether this shape has a marker symbol.
107
+ # @param [Symbol] position the position where a marker symbol is drawn.
108
+ # Specifies the following values: +:start+, +:mid+, +:end+
109
+ # @return [Boolean] true if the shape has a marker at the cpecified point,
110
+ # false otherwise
111
+ def has_marker?(position)
112
+ !@marker[position].nil?
113
+ end
114
+ end
115
+
27
116
  # Base class of all graphical shapes.
28
117
  # @abstract
29
118
  # @since 0.0.0
@@ -201,6 +290,14 @@ module DYI
201
290
  set_clipping(Drawing::Clipping.new(*shapes))
202
291
  end
203
292
 
293
+ # Returns whether this shape has a marker symbol.
294
+ # @param [Symbol] position the position where a marker symbol is drawn.
295
+ # Specifies the following values: +:start+, +:mid+, +:end+
296
+ # @return [Boolean] always false
297
+ def has_marker?(position)
298
+ return false
299
+ end
300
+
204
301
  # Returns registed animations.
205
302
  # @return [Array<Animation::Base>] amination list.
206
303
  # since 1.0.0
@@ -505,12 +602,14 @@ module DYI
505
602
  end
506
603
 
507
604
  class Line < Base
605
+ include Markable
508
606
  attr_coordinate :start_point, :end_point
509
607
 
510
608
  def initialize(start_point, end_point, options={})
511
609
  @start_point = Coordinate.new(start_point)
512
610
  @end_point = Coordinate.new(end_point)
513
611
  @attributes = init_attributes(options)
612
+ @marker = {}
514
613
  end
515
614
 
516
615
  def left
@@ -550,10 +649,12 @@ module DYI
550
649
  end
551
650
 
552
651
  class Polyline < Base
652
+ include Markable
553
653
 
554
654
  def initialize(start_point, options={})
555
655
  @points = [Coordinate.new(start_point)]
556
656
  @attributes = init_attributes(options)
657
+ @marker = {}
557
658
  end
558
659
 
559
660
  def line_to(*points)
@@ -0,0 +1,296 @@
1
+ # -*- encoding: UTF-8 -*-
2
+
3
+ # Copyright (c) 2009-2012 Sound-F Co., Ltd. All rights reserved.
4
+ #
5
+ # Author:: Mamoru Yuo
6
+ #
7
+ # This file is part of DYI.
8
+ #
9
+ # DYI is free software: you can redistribute it and/or modify it
10
+ # under the terms of the GNU General Public License as published by
11
+ # the Free Software Foundation, either version 3 of the License, or
12
+ # (at your option) any later version.
13
+ #
14
+ # DYI is distributed in the hope that it will be useful,
15
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ # GNU General Public License for more details.
18
+ #
19
+ # You should have received a copy of the GNU General Public License
20
+ # along with DYI. If not, see <http://www.gnu.org/licenses/>.
21
+
22
+ #
23
+ module DYI
24
+ module Shape
25
+ # Marker object represents a symbol at One or more vertices of the lines.
26
+ #
27
+ # Marker provides some pre-defined shapes and a custom marker defined freely.
28
+ # @since 1.2.0
29
+ class Marker < Element
30
+
31
+ attr_accessor :view_box, :ref_point, :marker_units, :width, :height, :orient, :shapes, :canvas
32
+
33
+ @@predefined_markers = {
34
+ :circle => {
35
+ :view_box => "-1 -1 2 2",
36
+ :magnify => 1.0,
37
+ :creator => proc{|painting, direction|
38
+ Shape::Circle.new([0, 0], 1, :painting => painting)
39
+ }},
40
+ :triangle => {
41
+ :view_box => "-1 -1 2 2",
42
+ :magnify => 1.1954339629,
43
+ :creator => proc{|painting, direction|
44
+ case direction
45
+ when :to_end
46
+ shape = Shape::Polygon.new([1, 0], :painting => painting)
47
+ shape.line_to([-0.5, 0.8660254038], [-0.5, -0.8660254038])
48
+ when :to_start
49
+ shape = Shape::Polygon.new([-1, 0], :painting => painting)
50
+ shape.line_to([0.5, -0.8660254038], [0.5, 0.8660254038])
51
+ else
52
+ shape = Shape::Polygon.new([0, -1], :painting => painting)
53
+ shape.line_to([0.8660254038, 0.5], [-0.8660254038, 0.5])
54
+ end
55
+ shape
56
+ }},
57
+ :square => {
58
+ :view_box => "-1 -1 2 2",
59
+ :magnify => 0.8862269255,
60
+ :creator => proc{|painting, direction|
61
+ Shape::Rectangle.new([-1, -1], 2, 2, :painting => painting)
62
+ }},
63
+ :rhombus => {
64
+ :view_box => "-1 -1 2 2",
65
+ :magnify => 1.2533141373,
66
+ :creator => proc{|painting, direction|
67
+ shape = Shape::Polygon.new([1, 0], :painting => painting)
68
+ shape.line_to([0, 1], [-1, 0], [0, -1])
69
+ shape
70
+ }},
71
+ :pentagon => {
72
+ :view_box => "-1 -1 2 2",
73
+ :magnify => 1.1494809262,
74
+ :creator => proc{|painting, direction|
75
+ case direction
76
+ when :to_end
77
+ shape = Shape::Polygon.new([1, 0], :painting => painting)
78
+ shape.line_to([0.3090169944, 0.9510565163],
79
+ [-0.8090169944, 0.5877852523],
80
+ [-0.8090169944, -0.5877852523],
81
+ [0.3090169944, -0.9510565163])
82
+ when :to_start
83
+ shape = Shape::Polygon.new([-1, 0], :painting => painting)
84
+ shape.line_to([-0.3090169944, -0.9510565163],
85
+ [0.8090169944, -0.5877852523],
86
+ [0.8090169944, 0.5877852523],
87
+ [-0.3090169944, 0.9510565163])
88
+ else
89
+ shape = Shape::Polygon.new([0, -1], :painting => painting)
90
+ shape.line_to([0.9510565163, -0.3090169944],
91
+ [0.5877852523, 0.8090169944],
92
+ [-0.5877852523, 0.8090169944],
93
+ [-0.9510565163, -0.3090169944])
94
+ end
95
+ shape
96
+ }},
97
+ :hexagon => {
98
+ :view_box => "-1 -1 2 2",
99
+ :magnify => 1.0996361108,
100
+ :creator => proc{|painting, direction|
101
+ case direction
102
+ when :to_end, :to_start
103
+ shape = Shape::Polygon.new([1, 0], :painting => painting)
104
+ shape.line_to([0.5, 0.8660254038],
105
+ [-0.5, 0.8660254038],
106
+ [-1, 0],
107
+ [-0.5, -0.8660254038],
108
+ [0.5, -0.8660254038])
109
+ else
110
+ shape = Shape::Polygon.new([0, -1], :painting => painting)
111
+ shape.line_to([0.8660254038, -0.5],
112
+ [0.8660254038, 0.5],
113
+ [0, 1],
114
+ [-0.8660254038, 0.5],
115
+ [-0.8660254038, -0.5])
116
+ end
117
+ shape
118
+ }}}
119
+ =begin
120
+ @@predefined_arrows = {
121
+ :triangle => {
122
+ :view_box => {:to_end => "0 -3 8 6", :to_start => "-8 -3 8 6"},
123
+ :magnify => {:width => 4.0 / 3.0, :height => 1.0},
124
+ :creator => proc{|painting, direction|
125
+ if direction == :to_start
126
+ shape = Shape::Polygon.new([-8, 0], :painting => painting)
127
+ shape.line_to([0, -3], [0, 3])
128
+ else
129
+ shape = Shape::Polygon.new([8, 0], :painting => painting)
130
+ shape.line_to([0, -3], [0, 3])
131
+ end
132
+ shape
133
+ },
134
+ :ref_point_getter => proc{|size, direction|
135
+ Coordinate.new(direction == :to_start ? (1 - size) : (size - 1), 0)
136
+ }},
137
+ :open => {
138
+ :view_box => {:to_end => "0 -3 8 6", :to_start => "-8 -3 8 6"},
139
+ :magnify => {:width => 4.0 / 3.0, :height => 1.0},
140
+ :creator => proc{|painting, direction|
141
+ if direction == :to_start
142
+ shape = Shape::Polygon.new([-8, 0], :painting => painting)
143
+ shape.line_to([0, -3], [0, 3])
144
+ else
145
+ shape = Shape::Polygon.new([8, 0], :painting => painting)
146
+ shape.line_to([0, -3], [0, 3])
147
+ end
148
+ shape
149
+ },
150
+ :ref_point_getter => proc{|size, direction|
151
+ Coordinate.new(direction == :to_start ? (1 - size) : (size - 1), 0)
152
+ }},
153
+ :stealth => {
154
+ :view_box => {:to_end => "0 -3 8 6", :to_start => "-8 -3 8 6"},
155
+ :magnify => {:width => 4.0 / 3.0, :height => 1.0},
156
+ :creator => proc{|painting, direction|
157
+ if direction == :to_start
158
+ shape = Shape::Polygon.new([-8, 0], :painting => painting)
159
+ shape.line_to([0, -3], [-1, -0.5], [-1, 0.5], [0, 3])
160
+ else
161
+ shape = Shape::Polygon.new([8, 0], :painting => painting)
162
+ shape.line_to([0, -3], [1, -0.5], [1, 0.5], [0, 3])
163
+ end
164
+ shape
165
+ },
166
+ :ref_point_getter => proc{|size, direction|
167
+ Coordinate.new(direction == :to_start ? (1 - size) : (size - 1), 0)
168
+ }}}
169
+ =end
170
+
171
+ # @overload initialize(marker_type, options = {})
172
+ # Creates a new pre-defined marker.
173
+ # @param [Symbol] marker_type a type of the marker. Specifies the
174
+ # following: +:circle+, +:triangle+, +:inverted_triangle+, +:square+,
175
+ # +:rhombus+, +:inverted_pentagon+, +:hexagon+
176
+ # @option options [Number] :size size of the marker. Specifies the
177
+ # relative size to line width
178
+ # @option options [Painting] :painting painting of the marker
179
+ # @option options [Number, "auto"] :orient how the marker is rotated.
180
+ # Specifies a rotated angle or <tt>"auto"</tt>. <tt>"auto"</tt> means
181
+ # the marker rotate the orientation of the line
182
+ # @option options [Symbol] :direction a direction of the marker. This
183
+ # option is valid if option +:orient+ value is <tt>"auto"</tt>.
184
+ # Specifies the following: +:to_start+, +:to_end+
185
+ # @overload initialize(shapes, options = {})
186
+ # Creates a new custom marker.
187
+ # @param [Shape::Base, Array<Shape::Base>] shapes a shape that represents
188
+ # marker
189
+ # @option options [String] :units a setting to define the coordinate
190
+ # system of the custom marker.
191
+ # @option options [String] :view_box
192
+ # @option options [Coordinate] :ref_point
193
+ # @option options [Length] :width
194
+ # @option options [Length] :height
195
+ # @option options [Number, nil] :orient
196
+ # @raise [ArgumentError]
197
+ def initialize(shape, options={})
198
+ case shape
199
+ when Symbol
200
+ inverted = !!(shape.to_s =~ /^inverted_/)
201
+ marker_source = @@predefined_markers[inverted ? $'.to_sym : shape]
202
+ raise ArgumentError, "`#{shape}' is unknown marker" unless marker_source
203
+ @ref_point = Coordinate::ZERO
204
+ if options[:orient] == 'auto'
205
+ direction = (inverted ^ (options[:direction] == :to_start)) ? :to_start : :to_end
206
+ @orient = 'auto'
207
+ else
208
+ direction = nil
209
+ @orient = (options[:orient] || 0) + (inverted ? 180 : 0)
210
+ end
211
+ @shapes = [marker_source[:creator].call(options[:painting] || {}, direction)]
212
+ @view_box = marker_source[:view_box]
213
+ @marker_units = 'strokeWidth'
214
+ @width = @height = Length.new(options[:size] || 3) * marker_source[:magnify]
215
+ when Shape::Base, Array
216
+ @ref_point = options[:ref_point] || Coordinate::ZERO
217
+ @shapes = shape.is_a?(Shape::Base) ? [shape] : shape
218
+ @view_box = options[:view_box] || "0 0 3 3"
219
+ @marker_units = options[:units] || 'strokeWidth'
220
+ @width = Length.new(options[:width] || 3)
221
+ @height = Length.new(options[:height] || 3)
222
+ @orient = options[:orient]
223
+ else
224
+ raise ArgumentError, "argument is a wrong class"
225
+ end
226
+ end
227
+
228
+ def set_canvas(canvas)
229
+ if @canvas.nil?
230
+ @canvas = canvas
231
+ elsif @canvas != canvas
232
+ raise Arguments, "the clipping is registered to another canvas"
233
+ end
234
+ end
235
+
236
+ def child_elements
237
+ @shapes
238
+ end
239
+
240
+ def write_as(formatter, io=$>)
241
+ formatter.write_marker(self, io)
242
+ end
243
+
244
+ class << self
245
+ =begin
246
+ # @overload new_arrow(options = {})
247
+ # Creates a new pre-defined triangle-arrow-marker.
248
+ # @option options [Number] :size size of the marker. Specifies the
249
+ # relative size to line width
250
+ # @option options [Painting] :painting painting of the marker
251
+ # @option options [Symbol] :direction a direction of the marker.
252
+ # Specifies the following: +:to_start+, +:to_end+
253
+ # @overload new_arrow(arrow_type, options = {})
254
+ # Creates a new pre-defined arrow-marker.
255
+ # @param [Symbol] arrow_type a type of the arrow-marker. Specifies the
256
+ # following: +:triangle+, +:open+, +:stealth+
257
+ # @option options [Number] :size size of the marker. Specifies the
258
+ # relative size to line width
259
+ # @option options [Painting] :painting painting of the marker
260
+ # @option options [Symbol] :direction a direction of the marker.
261
+ # Specifies the following: +:to_start+, +:to_end+
262
+ # @raise [ArgumentError]
263
+ def new_arrow(*args)
264
+ arrow_type = :triangle
265
+ options = {}
266
+ case args.first
267
+ when Symbol
268
+ raise ArgumentError, "wrong number of arguments (#{args.size} for 2)" if 2 < args.size
269
+ arrow_type = args.first
270
+ if args.size == 2
271
+ options = args[1]
272
+ end
273
+ when nil
274
+ raise ArgumentError, "arrow_type is nil" if args.size != 0
275
+ else
276
+ raise ArgumentError, "wrong number of arguments (#{args.size} for 1)" if args.size != 1
277
+ arrow_type = :triangle
278
+ options = args.first
279
+ end
280
+
281
+ marker_source = @@predefined_arrows[arrow_type]
282
+ direction = options[:direction] == :to_start ? :to_start : :to_end
283
+ size = options[:size] || 3
284
+ raise ArgumentError, "option `size' must be greater than 1" if size < 1
285
+ new(marker_source[:creator].call(options[:painting] || {}, direction),
286
+ :ref_point => marker_source[:ref_point_getter].call(size, direction),
287
+ :view_box => marker_source[:view_box][direction],
288
+ :width => Length.new(marker_source[:magnify][:width]) * size,
289
+ :height => Length.new(marker_source[:magnify][:height]) * size,
290
+ :orient => 'auto')
291
+ end
292
+ =end
293
+ end
294
+ end
295
+ end
296
+ end
@@ -55,6 +55,7 @@ module DYI
55
55
  #
56
56
  # @since 0.0.0
57
57
  class Path < Base
58
+ include Markable
58
59
 
59
60
  def initialize(start_point, options={})
60
61
  @path_data = case start_point
@@ -69,66 +70,156 @@ module DYI
69
70
  # coordinate. The new current points become the given point.
70
71
  #
71
72
  # When multiple points is given as arguments, starts a new sub-path at the
72
- # first point and draws straight line to the subsequent points. (i.e.
73
- # <tt>path.move_to(pt1,pt2,pt3,...)</tt> equals to <tt>path.move_to(pt1);
74
- # path.line_to(pt2,pt3,...)</tt>)
73
+ # first point and draws straight line to the subsequent points. see
74
+ # example.
75
75
  # @param [Coordinate] point the absolute coordinate of the start point of
76
76
  # the new sub-path. The second and subsequent arguments are the absolute
77
77
  # point to which the line is drawn from previous point
78
+ # @example
79
+ # canvas = DYI::Canvas.new(100,100)
80
+ # pen = DYI::Drawing::Pen.black_pen
81
+ # pen.draw_path(canvas, [20, 20]) {|path|
82
+ # path.line_to([20, 50])
83
+ # path.move_to([30, 20], [30, 50], [40, 50])
84
+ # # The last expression equals to following expressions
85
+ # # path.move_to([30, 20])
86
+ # # path.line_to([30, 50])
87
+ # # path.line_to([40, 50])
88
+ # }
78
89
  # @see #rmove_to
79
90
  def move_to(*points)
80
91
  push_command(:move_to, *points)
81
92
  end
82
93
 
83
94
  # Starts a new sub-path at a given point, which is specified a relative
84
- # coordinate to current point. The new current point becomes the last
95
+ # coordinate to current point. The new current point becomes the finally
85
96
  # given point.
86
97
  #
87
98
  # When multiple points is given as arguments, starts a new sub-path at the
88
- # first point and draws straight line to the subsequent points. (i.e.
89
- # <tt>path.move_to(pt1,pt2,pt3,...)</tt> equals to <tt>path.move_to(pt1);
90
- # path.line_to(pt2,pt3,...)</tt>)
99
+ # first point and draws straight line to the subsequent points. see
100
+ # example.
91
101
  # @param [Coordinate] point the relative coordinate of the start point of
92
102
  # the new sub-path. The second and subsequent arguments are the relative
93
103
  # point to which the line is drawn from previous point
104
+ # @example
105
+ # canvas = DYI::Canvas.new(100,100)
106
+ # pen = DYI::Drawing::Pen.black_pen
107
+ # pen.draw_path(canvas, [20, 20]) {|path|
108
+ # path.rline_to([0, 30])
109
+ # path.rmove_to([10, -30], [0, 30], [10, 0])
110
+ # # The last expression equals to following expressions
111
+ # # path.rmove_to([10, -30])
112
+ # # path.rline_to([0, 30])
113
+ # # path.rline_to([10, 0])
114
+ # }
94
115
  # @see #move_to
95
116
  def rmove_to(*points)
96
117
  push_command(:rmove_to, *points)
97
118
  end
98
119
 
99
- # Draws straight lines from the current point, which is specified a
100
- # absolute coordinate. The new current point becomes the last given point.
120
+ # Draws straight lines from the current point to a given point, which is
121
+ # specified a absolute coordinate. The new current point becomes the
122
+ # finally given point.
101
123
  #
102
- # When multiple points is given as argument, draws a polyline. (i.e.
103
- # <tt>path.line_to(pt1,pt2,pt3,...)</tt> equals to <tt>path.line_to(pt1);
104
- # path.line_to(pt2); path.line_to(pt3); ...</tt>)
124
+ # When multiple points is given as argument, draws a polyline. see
125
+ # example.
105
126
  # @param [Coordinate] point the absolute coordinate which the line is
106
127
  # drawn from current point to
128
+ # @example
129
+ # canvas = DYI::Canvas.new(100,100)
130
+ # pen = DYI::Drawing::Pen.black_pen
131
+ # pen.draw_path(canvas, [20, 20]) {|path|
132
+ # path.line_to([20, 50], [30, 20], [30, 50])
133
+ # # The last expression equals to following expressions
134
+ # # path.line_to([20, 50])
135
+ # # path.line_to([30, 20])
136
+ # # path.line_to([30, 50])
137
+ # }
107
138
  # @see #rline_to
108
139
  def line_to(*points)
109
140
  push_command(:line_to, *points)
110
141
  end
111
142
 
112
- # Draws straight lines from the current point, which is specified a
113
- # relative coordinate to current point. The new current point becomes the
114
- # last given point.
143
+ # Draws straight lines from the current point to a given point, which is
144
+ # specified a relative coordinate to current point. The new current point
145
+ # becomes the finally given point.
115
146
  #
116
- # When multiple points is given as arguments, draws a polyline. (i.e.
117
- # <tt>path.rline_to(pt1,pt2,pt3,...)</tt> equals to <tt>path.rline_to(pt1);
118
- # path.rline_to(pt2); path.rline_to(pt3); ...</tt>)
147
+ # When multiple points is given as arguments, draws a polyline. see
148
+ # example.
119
149
  # @param [Coordinate] point the relavive coordinate which the line is
120
150
  # drawn from current point to
151
+ # @example
152
+ # canvas = DYI::Canvas.new(100,100)
153
+ # pen = DYI::Drawing::Pen.black_pen
154
+ # pen.draw_path(canvas, [20, 20]) {|path|
155
+ # path.rline_to([0, 30], [10, -30], [0, 30])
156
+ # # The last expression equals to following expressions
157
+ # # path.rline_to([0, 30])
158
+ # # path.rline_to([10, -30])
159
+ # # path.rline_to([0, 30])
160
+ # }
121
161
  # @see #line_to
122
162
  def rline_to(*points)
123
163
  push_command(:rline_to, *points)
124
164
  end
125
165
 
166
+ # Draws quadratic Bézier curves from the current point to the second
167
+ # argument point using first argument point as control-point. The
168
+ # control-point and pass-point are specified a absolute coordinate. The
169
+ # new current point becomes the point to specify in second argument.
170
+ #
171
+ # When three or more points is given as the argument, draws
172
+ # polybézier-curves. In this case, the control-point is assumed to be the
173
+ # reflection of the control-point on the previouse quadratic Bézier curve
174
+ # relative to the current point. see example.
175
+ # @param [Coordinate] point0 the absolute coordinate of the control-point
176
+ # of the quadratic Bézier curve
177
+ # @param [Coordinate] point1 the absolute coordinate which the curve is
178
+ # drawn from current point to
179
+ # @example
180
+ # canvas = DYI::Canvas.new(100,100)
181
+ # pen = DYI::Drawing::Pen.black_pen
182
+ # pen.draw_path(canvas, [20, 20]) {|path|
183
+ # path.quadratic_curve_to([40, 20], [60, 50], [60, 80])
184
+ # # The last expression equals to following expressions
185
+ # # path.quadratic_curve_to([40, 20], [60, 50])
186
+ # # path.quadratic_curve_to([80, 80], [60, 80])
187
+ # # control-point [80,80] is reflection of first curve's control-point [40, 20]
188
+ # # across current point [60, 50].
189
+ # }
190
+ # @see #rquadratic_curve_to
126
191
  def quadratic_curve_to(*points)
127
192
  raise ArgumentError, "number of points must be 2 or more" if points.size < 2
128
193
  push_command(:quadratic_curve_to, points[0], points[1])
129
194
  push_command(:shorthand_quadratic_curve_to, *points[2..-1]) if points.size > 2
130
195
  end
131
196
 
197
+ # Draws quadratic Bézier curves from the current point to the second
198
+ # argument point using first argument point as control-point. The
199
+ # control-point and pass-point are specified a relative coordinate to
200
+ # current point. The new current point becomes the point to specify in
201
+ # second argument.
202
+ #
203
+ # When three or more points is given as the argument, draws
204
+ # polybézier-curves. In this case, the control-point is assumed to be the
205
+ # reflection of the control-point on the previouse quadratic Bézier curve
206
+ # relative to the current point. see example.
207
+ # @param [Coordinate] point0 the relative coordinate of the control-point
208
+ # of the quadratic Bézier curve
209
+ # @param [Coordinate] point1 the relative coordinate which the curve is
210
+ # drawn from current point to
211
+ # @example
212
+ # canvas = DYI::Canvas.new(100,100)
213
+ # pen = DYI::Drawing::Pen.black_pen
214
+ # pen.draw_path(canvas, [20, 20]) {|path|
215
+ # path.rquadratic_curve_to([20, 0], [40, 30], [0, 30])
216
+ # # The last expression equals to following expressions
217
+ # # path.quadratic_curve_to([20, 0], [40, 30])
218
+ # # path.quadratic_curve_to([20, 30], [0, 30])
219
+ # # control-point [20, 30] is reflection of first curve's control-point [-20, -30].
220
+ # # (that is relative coordinate to current point. i.e. [20, 0] - [40, 30])
221
+ # }
222
+ # @see #rquadratic_curve_to
132
223
  def rquadratic_curve_to(*points)
133
224
  raise ArgumentError, "number of points must be 2 or more" if points.size < 2
134
225
  push_command(:rquadratic_curve_to, points[0], points[1])
metadata CHANGED
@@ -1,8 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dyi
3
3
  version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 1.1.2
4
+ hash: 31
5
+ prerelease: false
6
+ segments:
7
+ - 1
8
+ - 2
9
+ - 0
10
+ version: 1.2.0
6
11
  platform: ruby
7
12
  authors:
8
13
  - Mamoru Yuo
@@ -10,7 +15,8 @@ autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
17
 
13
- date: 2012-03-01 00:00:00 Z
18
+ date: 2012-04-03 00:00:00 +09:00
19
+ default_executable:
14
20
  dependencies: []
15
21
 
16
22
  description: " DYI is a 2D graphics library, very rich and expressive.\n DYI have been optimized for SVG format, but it is also possible\n to output other format; for example, EPS.\n"
@@ -22,68 +28,70 @@ extensions: []
22
28
  extra_rdoc_files: []
23
29
 
24
30
  files:
25
- - CHANGES
26
- - COPYING
27
- - examples/animation.rb
28
- - examples/class_diagram.rb
29
- - examples/css.rb
30
- - examples/data/03311056.xlsx
31
- - examples/data/currency.xlsx
32
- - examples/data/money.csv
33
- - examples/line_and_bar.rb
34
- - examples/line_chart.rb
35
- - examples/logo.rb
36
- - examples/pie_chart.rb
37
- - examples/simple_shapes.rb
38
- - lib/dyi/animation.rb
31
+ - lib/ironruby.rb
39
32
  - lib/dyi/canvas.rb
40
- - lib/dyi/chart/array_reader.rb
41
- - lib/dyi/chart/axis_util.rb
42
- - lib/dyi/chart/base.rb
43
- - lib/dyi/chart/csv_reader.rb
44
- - lib/dyi/chart/excel_reader.rb
45
- - lib/dyi/chart/legend.rb
46
- - lib/dyi/chart/line_chart.rb
47
- - lib/dyi/chart/pie_chart.rb
48
- - lib/dyi/chart/table.rb
49
33
  - lib/dyi/chart.rb
50
- - lib/dyi/color.rb
51
- - lib/dyi/coordinate.rb
34
+ - lib/dyi/stylesheet.rb
35
+ - lib/dyi/event.rb
52
36
  - lib/dyi/drawing/clipping.rb
53
- - lib/dyi/drawing/color_effect.rb
54
37
  - lib/dyi/drawing/filter.rb
55
- - lib/dyi/drawing/pen.rb
38
+ - lib/dyi/drawing/color_effect.rb
56
39
  - lib/dyi/drawing/pen_3d.rb
57
- - lib/dyi/drawing.rb
40
+ - lib/dyi/drawing/pen.rb
41
+ - lib/dyi/script/simple_script.rb
42
+ - lib/dyi/script/ecmascript.rb
43
+ - lib/dyi/color.rb
58
44
  - lib/dyi/element.rb
59
- - lib/dyi/event.rb
60
- - lib/dyi/font.rb
61
- - lib/dyi/formatter/base.rb
45
+ - lib/dyi/shape/base.rb
46
+ - lib/dyi/shape/marker.rb
47
+ - lib/dyi/shape/path.rb
62
48
  - lib/dyi/formatter/emf_formatter.rb
63
- - lib/dyi/formatter/eps_formatter.rb
64
- - lib/dyi/formatter/svg_formatter.rb
65
49
  - lib/dyi/formatter/svg_reader.rb
66
50
  - lib/dyi/formatter/xaml_formatter.rb
67
- - lib/dyi/formatter.rb
68
- - lib/dyi/length.rb
69
- - lib/dyi/matrix.rb
70
- - lib/dyi/painting.rb
71
- - lib/dyi/script/ecmascript.rb
72
- - lib/dyi/script/simple_script.rb
51
+ - lib/dyi/formatter/base.rb
52
+ - lib/dyi/formatter/svg_formatter.rb
53
+ - lib/dyi/formatter/eps_formatter.rb
73
54
  - lib/dyi/script.rb
74
- - lib/dyi/shape/base.rb
75
- - lib/dyi/shape/path.rb
55
+ - lib/dyi/drawing.rb
56
+ - lib/dyi/animation.rb
57
+ - lib/dyi/matrix.rb
58
+ - lib/dyi/coordinate.rb
59
+ - lib/dyi/chart/array_reader.rb
60
+ - lib/dyi/chart/csv_reader.rb
61
+ - lib/dyi/chart/table.rb
62
+ - lib/dyi/chart/line_chart.rb
63
+ - lib/dyi/chart/pie_chart.rb
64
+ - lib/dyi/chart/legend.rb
65
+ - lib/dyi/chart/base.rb
66
+ - lib/dyi/chart/axis_util.rb
67
+ - lib/dyi/chart/excel_reader.rb
76
68
  - lib/dyi/shape.rb
77
- - lib/dyi/stylesheet.rb
78
- - lib/dyi/svg_element.rb
79
- - lib/dyi/type.rb
80
69
  - lib/dyi/util.rb
70
+ - lib/dyi/painting.rb
71
+ - lib/dyi/type.rb
72
+ - lib/dyi/length.rb
73
+ - lib/dyi/font.rb
74
+ - lib/dyi/formatter.rb
75
+ - lib/dyi/svg_element.rb
81
76
  - lib/dyi.rb
82
- - lib/ironruby.rb
83
77
  - lib/util.rb
84
- - README
78
+ - CHANGES
85
79
  - test/path_command_test.rb
86
80
  - test/test_length.rb
81
+ - examples/class_diagram.rb
82
+ - examples/line_and_bar.rb
83
+ - examples/line_chart.rb
84
+ - examples/data/money.csv
85
+ - examples/data/currency.xlsx
86
+ - examples/data/03311056.xlsx
87
+ - examples/simple_shapes.rb
88
+ - examples/pie_chart.rb
89
+ - examples/animation.rb
90
+ - examples/css.rb
91
+ - examples/logo.rb
92
+ - README
93
+ - COPYING
94
+ has_rdoc: true
87
95
  homepage: https://sourceforge.net/projects/dyi/
88
96
  licenses:
89
97
  - GPL-3
@@ -97,17 +105,25 @@ required_ruby_version: !ruby/object:Gem::Requirement
97
105
  requirements:
98
106
  - - ">="
99
107
  - !ruby/object:Gem::Version
108
+ hash: 57
109
+ segments:
110
+ - 1
111
+ - 8
112
+ - 7
100
113
  version: 1.8.7
101
114
  required_rubygems_version: !ruby/object:Gem::Requirement
102
115
  none: false
103
116
  requirements:
104
117
  - - ">="
105
118
  - !ruby/object:Gem::Version
119
+ hash: 3
120
+ segments:
121
+ - 0
106
122
  version: "0"
107
123
  requirements: []
108
124
 
109
125
  rubyforge_project:
110
- rubygems_version: 1.8.10
126
+ rubygems_version: 1.3.7
111
127
  signing_key:
112
128
  specification_version: 3
113
129
  summary: 2D graphics library