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 +8 -0
- data/lib/dyi.rb +1 -1
- data/lib/dyi/animation.rb +3 -3
- data/lib/dyi/canvas.rb +1 -1
- data/lib/dyi/chart/base.rb +5 -0
- data/lib/dyi/chart/line_chart.rb +54 -20
- data/lib/dyi/element.rb +25 -16
- data/lib/dyi/formatter/svg_formatter.rb +31 -2
- data/lib/dyi/script/ecmascript.rb +24 -14
- data/lib/dyi/shape.rb +1 -0
- data/lib/dyi/shape/base.rb +101 -0
- data/lib/dyi/shape/marker.rb +296 -0
- data/lib/dyi/shape/path.rb +109 -18
- metadata +66 -50
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
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
|
246
|
+
def rotate(shape, options)
|
247
247
|
new(shape, :rotate, options)
|
248
248
|
end
|
249
249
|
|
250
|
-
def skew_x(
|
250
|
+
def skew_x(shape, options)
|
251
251
|
new(shape, :skewX, options)
|
252
252
|
end
|
253
253
|
|
254
|
-
def skew_y(
|
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
|
262
|
+
@init_script = Script::EcmaScript::EventListener.new(script_body)
|
263
263
|
add_event_listener(:load, @init_script)
|
264
264
|
end
|
265
265
|
end
|
data/lib/dyi/chart/base.rb
CHANGED
@@ -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
|
data/lib/dyi/chart/line_chart.rb
CHANGED
@@ -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
|
-
@
|
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
|
-
|
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
|
-
|
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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
-
@
|
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
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
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
|
-
#
|
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
|
-
#
|
182
|
-
# @param [Symbol] event_name
|
183
|
-
# @param [Script::SimpleScript]
|
184
|
-
|
185
|
-
|
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?(
|
188
|
-
event_listeners[event_name] <<
|
189
|
-
canvas.add_script(
|
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] = [
|
193
|
-
canvas.add_script(
|
201
|
+
event_listeners[event_name] = [listener]
|
202
|
+
canvas.add_script(listener)
|
194
203
|
end
|
195
204
|
end
|
196
205
|
|
197
|
-
# Removes
|
198
|
-
# @param [Symbol] event_name
|
199
|
-
# @param [Script::SimpleScript]
|
200
|
-
def remove_event_listener(event_name,
|
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(
|
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
|
-
|
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'] = '
|
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
|
-
#
|
336
|
-
# @
|
337
|
-
#
|
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 << ")
|
369
|
+
parts << "){\n"
|
360
370
|
parts << @body
|
361
|
-
parts << "
|
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(\"
|
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
|
-
|
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 << '",
|
412
|
-
parts <<
|
413
|
-
parts << ")
|
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
data/lib/dyi/shape/base.rb
CHANGED
@@ -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
|
data/lib/dyi/shape/path.rb
CHANGED
@@ -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.
|
73
|
-
#
|
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
|
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.
|
89
|
-
#
|
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
|
100
|
-
# absolute coordinate. The new current point becomes the
|
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.
|
103
|
-
#
|
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
|
113
|
-
# relative coordinate to current point. The new current point
|
114
|
-
#
|
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.
|
117
|
-
#
|
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
|
-
|
5
|
-
|
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
|
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
|
-
-
|
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/
|
51
|
-
- lib/dyi/
|
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/
|
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/
|
60
|
-
- lib/dyi/
|
61
|
-
- lib/dyi/
|
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/
|
69
|
-
- lib/dyi/
|
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/
|
75
|
-
- lib/dyi/
|
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
|
-
-
|
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.
|
126
|
+
rubygems_version: 1.3.7
|
111
127
|
signing_key:
|
112
128
|
specification_version: 3
|
113
129
|
summary: 2D graphics library
|