dyi 0.0.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES CHANGED
@@ -1,5 +1,18 @@
1
1
  = DYI Changelog
2
2
 
3
+ == Version 1.0.0 / 2011-09-05
4
+
5
+ * Major Enhancements
6
+ * Support events on SVG.
7
+ * Support animations on SVG.
8
+ * Support scripts (ex. ECMAScript) on SVG.
9
+ * Support hyperlinks on SVG.
10
+ * Support a SVG file that includes style-sheet (ex. CSS, XLST).
11
+ * Support PNG output. (Needs rsvg-convert)
12
+ * Support raster image handling (ex. PNG, JPEG) on SVG.
13
+ * Add Pie-Chart options.
14
+ * Modify the handling of Reader classes.
15
+
3
16
  == Version 0.0.2 / 2011-09-05
4
17
 
5
18
  * Minor Enhancements
@@ -0,0 +1,28 @@
1
+ # -*- encoding: UTF-8 -*-
2
+
3
+ require 'rubygems'
4
+ require 'dyi'
5
+
6
+ canvas = DYI::Canvas.new(400, 300)
7
+
8
+ rect = DYI::Drawing::Brush.new(:color=>'#51ADE2').draw_rectangle(canvas, [10,10], 300, 200)
9
+ rect.add_painting_animation(:from => {:fill => '#51ADE2'},
10
+ :to => {:fill => 'red'},
11
+ :duration => 3,
12
+ :begin_event => DYI::Event.mouseover(rect),
13
+ :end_event => DYI::Event.mouseout(rect),
14
+ :fill => 'freeze')
15
+ text = DYI::Drawing::Brush.new.draw_text(canvas,
16
+ [100,250],
17
+ 'click me!',
18
+ :show_border => true,
19
+ :border_color=>'#325BA8',
20
+ :padding => 8,
21
+ :border_rx => 10,
22
+ :border_width => 3,
23
+ :background_color=>'#A5C7F8')
24
+ rect.add_painting_animation(:to => {:fill => 'green'},
25
+ :begin_event => DYI::Event.click(text),
26
+ :fill => 'freeze')
27
+
28
+ canvas.save('output/animation.svg')
@@ -78,7 +78,7 @@ class ArrowPen < DYI::Drawing::Pen
78
78
  end
79
79
  end
80
80
 
81
- canvas = DYI::Drawing::Canvas.new 1300, 1300
81
+ canvas = DYI::Canvas.new 1300, 1300
82
82
 
83
83
  pen = ArrowPen.new
84
84
  dashed_pen = ArrowPen.new(:stroke_dasharray => [3])
data/examples/css.rb ADDED
@@ -0,0 +1,34 @@
1
+ # -*- encoding: UTF-8 -*-
2
+
3
+ require 'rubygems'
4
+ require 'dyi'
5
+
6
+ canvas = DYI::Canvas.new(300, 250)
7
+
8
+ pen = DYI::Drawing::Pen.new(:color => 'red')
9
+ pen.draw_rectangle(canvas, [20, 20], 240, 100)
10
+ pen.draw_rectangle(canvas, [20, 140], 240, 100, :css_class => 'sample-css')
11
+ pen = DYI::Drawing::Brush.new(:color => 'red')
12
+ pen.draw_circle(canvas, [120, 130], 40)
13
+ pen.draw_circle(canvas, [230, 130], 40, :css_class => 'transparent')
14
+
15
+ css =<<-EOS
16
+ rect {
17
+ fill: yellow;
18
+ stroke-dasharray: 10 5;
19
+ }
20
+ rect.sample-css {
21
+ fill: skyblue;
22
+ stroke: blue;
23
+ stroke-width: 5;
24
+ }
25
+ .transparent {
26
+ fill: none;
27
+ stroke: green;
28
+ stroke-width: 3;
29
+ }
30
+ EOS
31
+
32
+ canvas.add_stylesheet(css)
33
+
34
+ canvas.save 'output/css.svg'
@@ -13,13 +13,12 @@ chart = DYI::Chart::LineChart.new 800,500,
13
13
  :chart_types => [:line, :bar],
14
14
  :line_width => 3,
15
15
  :show_dropshadow => true,
16
- :color_columns => [nil, 2],
17
16
  # :represent_3d => true,
18
17
  # :_3d_settings => {:dx => 30, :dy => -10},
19
18
  :show_legend => false,
20
19
  :legend_point => [50, 480]
21
20
 
22
- reader = DYI::Chart::CsvReader.read('data/money.csv', :data_types => [:number, :number, :string], :title_column=>0, :column_skip => 1)
21
+ reader = DYI::Chart::CsvReader.read('data/money.csv', :data_types => [:string, :number, :number, :string], :schema => [:name, :value, :value, :color])
23
22
  chart.load_data reader
24
23
 
25
24
  chart.save 'output/line_and_bar.svg'
@@ -10,19 +10,18 @@ gr.add_color(1, '#D5EEF2')
10
10
  chart = DYI::Chart::LineChart.new 720,300,
11
11
  # :represent_3d => true,
12
12
  :axis_format => '#,##0',
13
- :data_columns => [0, 3, 1],
14
- :use_y_second_axises => [nil, nil, true],
15
- :chart_types => [:line, :line, :area],
13
+ :use_y_second_axises => [false, true, false],
14
+ :chart_types => [:line, :area, :line],
16
15
  :x_axis_format => '%Y/%m/%d',
17
16
  :axis_font => {:font_family => 'HGPGOTHICM', :size => 12},
18
17
  :show_legend => true,
19
18
  # :axis_settings => {:min=>4000, :max=> 16000},
20
- :chart_colors => ['#F68C23', '#89C549', gr],
19
+ :chart_colors => ['#F68C23', gr, '#89C549'],
21
20
  :line_width => 3,
22
21
  :legend_font => {},
23
- :legend_texts => ['Constant value (left axis)', 'Constant value of Dividend Reinvestment (left axis)', 'Net Assets (right axis)']
22
+ :legend_texts => ['Constant value (left axis)', 'Net Assets (right axis)', 'Constant value of Dividend Reinvestment (left axis)']
24
23
 
25
- reader = DYI::Chart::ExcelReader.read('data/03311056.xlsx', :sheet => 'Sheet2', :title_column=>1, :column_skip=>2, :title_row=>1, :row_skip=>2)
24
+ reader = DYI::Chart::ExcelReader.read('data/03311056.xlsx', :sheet => 'Sheet2', :schema => [:name, :value, :value, :profit, :value], :column_range => 1..5, :row_range => 2..-1 )
26
25
  chart.load_data reader
27
26
 
28
27
  chart.save 'output/line_chart.svg'
data/examples/logo.rb CHANGED
@@ -3,7 +3,7 @@
3
3
  require 'rubygems'
4
4
  require 'dyi'
5
5
 
6
- canvas = DYI::Drawing::Canvas.new(287.008, 162.637)
6
+ canvas = DYI::Canvas.new(287.008, 162.637)
7
7
 
8
8
  DYI::Drawing::Brush.new(:color=>'#51ADE2').draw_closed_path(canvas, [287.008,0]) {|path|
9
9
  path.rline_to([0,162.637], [-39.41,0])
@@ -4,14 +4,21 @@ require 'rubygems'
4
4
  require 'dyi'
5
5
 
6
6
  chart = DYI::Chart::PieChart.new 400,500,
7
- :data_label_format => "{name}\n{percent}",
7
+ :data_label_format => "{?name}\n{?percent}",
8
+ :data_label_font => {:size => 20, :font_family=>'Serif'},
8
9
  :represent_3d => true,
9
- :moved_elements => [0.2,nil,nil,0.5],
10
- :chart_colors => ['blue', 'red', 'yellow', 'green'],
10
+ :show_data_label => false,
11
+ :show_baloon => true,
12
+ :baloon_opacity => 0.3,
13
+ :baloon_format => "{?name}\n{?percent}",
14
+ # :moved_elements => [0.2,nil,nil,0.5],
15
+ # :chart_colors => ['blue', 'red', 'yellow', 'green'],
11
16
  :_3d_settings => {:dy => 30},
17
+ :background_image_opacity => 0.1,
18
+ :legend_format => "{?name}\t{!e}{?value:#,##0}\t{!e}({?percent:0.00%})",
12
19
  :chart_stroke_color => 'white'
13
20
 
14
- reader = DYI::Chart::ExcelReader.read('data/currency.xlsx', :title_column=>0, :column_skip=>1)
21
+ reader = DYI::Chart::ExcelReader.read('data/currency.xlsx', :schema => [:name, :value])
15
22
  chart.load_data reader
16
23
 
17
24
  chart.save 'output/pie_chart.svg'
@@ -3,7 +3,7 @@
3
3
  require 'rubygems'
4
4
  require 'dyi'
5
5
 
6
- canvas = DYI::Drawing::Canvas.new(500, 500)
6
+ canvas = DYI::Canvas.new(500, 500)
7
7
 
8
8
  pen = DYI::Drawing::Pen.new(:color => 'blue')
9
9
  pen.draw_rectangle(canvas, [30, 30], 30, 30)
data/lib/dyi.rb CHANGED
@@ -21,7 +21,7 @@
21
21
 
22
22
 
23
23
  module DYI
24
- VERSION = '0.0.2'
24
+ VERSION = '1.0.0'
25
25
  URL = 'http://sourceforge.net/projects/dyi/'
26
26
  end
27
27
 
@@ -36,8 +36,14 @@ dyi/font
36
36
  dyi/matrix
37
37
  dyi/type
38
38
  dyi/svg_element
39
- dyi/drawing
39
+ dyi/element
40
+ dyi/canvas
40
41
  dyi/shape
42
+ dyi/drawing
43
+ dyi/event
44
+ dyi/animation
45
+ dyi/script
46
+ dyi/stylesheet
41
47
  dyi/formatter
42
48
  dyi/chart
43
49
 
@@ -0,0 +1,259 @@
1
+ # -*- encoding: UTF-8 -*-
2
+
3
+ # Copyright (c) 2009-2011 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
+ # == Overview
23
+ #
24
+ # This file provides the classes of animation. The event becomes effective
25
+ # only when it is output by SVG format.
26
+ #
27
+ # @since 1.0.0
28
+
29
+ module DYI #:nodoc:
30
+ module Animation #:nodoc:
31
+
32
+ # Base class for animation classes.
33
+ # @abstract
34
+ # @attr [Object] from a starting value of the animation
35
+ # @attr [Object] to a ending value of the animation
36
+ # @attr [Numeric] duration a simple duration of the animation
37
+ # @attr [Numeric] begin_offset a offset that determine the animation begin
38
+ # @attr [Event] begin_event an event that determine the element begin
39
+ # @attr [Numeric] end_offset a offset that determine the animation end
40
+ # @attr [Event] end_event an event that determine the element end
41
+ # @attr [String] fill the effect of animation when the animation is over,
42
+ # either 'freeze' or 'remove'
43
+ # @attr [String] additive a value that means whether or not the animation is
44
+ # additive, either 'replace' or 'sum'
45
+ # @attr [String] restart a value for the restart, either 'always',
46
+ # 'whenNotActive'or 'never'
47
+ class Base
48
+ IMPLEMENT_ATTRIBUTES = [:from, :to, :duration, :begin_offset,
49
+ :begin_event, :end_offset, :end_event, :fill,
50
+ :additive, :restart]
51
+ VALID_VALUES = {
52
+ :fill => ['freeze','remove'],
53
+ :additive => ['replace', 'sum'],
54
+ :restart => ['always', 'whenNotActive', 'never']
55
+ }
56
+
57
+ attr_reader *IMPLEMENT_ATTRIBUTES
58
+
59
+ VALID_VALUES.each do |attr, valid_values|
60
+ define_method("#{attr.to_s}=") {|value|
61
+ if (value = value.to_s).size == 0
62
+ instance_variable_set("@#{attr}", nil)
63
+ else
64
+ unless VALID_VALUES[attr].include?(value)
65
+ raise ArgumentError, "`#{value}' is invalid #{attr}"
66
+ end
67
+ instance_variable_set("@#{attr}", value)
68
+ end
69
+ }
70
+ end
71
+
72
+ def duration=(duration)
73
+ @duration = duration
74
+ end
75
+
76
+ def begin_offset=(offset)
77
+ @begin_offset = offset
78
+ end
79
+
80
+ def begin_event=(event)
81
+ @begin_event = event
82
+ end
83
+
84
+ def end_offset=(offset)
85
+ @end_offset = offset
86
+ end
87
+
88
+ def end_event=(event)
89
+ @end_event = event
90
+ end
91
+
92
+ # @param [Shape::Base] shape a target element for an animation
93
+ # @param [Hash] options an option for an animation
94
+ def initialize(shape, options)
95
+ raise ArgumentError, "`:to' option is required" unless options.key?(:to)
96
+ @shape = shape
97
+ options.each do |attr, value|
98
+ if IMPLEMENT_ATTRIBUTES.include?(attr.to_sym)
99
+ __send__("#{attr}=", value)
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+ # Class representing an animation of a painting
106
+ # @attr [Painting] from a starting value of the animation
107
+ # @attr [Painting] to a ending value of the animation
108
+ class PaintingAnimation < Base
109
+
110
+ def from=(painting)
111
+ @from = painting && DYI::Painting.new(painting)
112
+ end
113
+
114
+ def to=(painting)
115
+ @to = DYI::Painting.new(painting)
116
+ end
117
+
118
+ def animation_attributes
119
+ DYI::Painting::IMPLEMENT_ATTRIBUTES.inject({}) do |result, attr|
120
+ from_attr, to_attr = @from && @from.__send__(attr), @to.__send__(attr)
121
+ if to_attr && from_attr != to_attr
122
+ result[attr] = [from_attr, to_attr]
123
+ end
124
+ result
125
+ end
126
+ end
127
+
128
+ def write_as(formatter, shape, io=$>)
129
+ formatter.write_painting_animation(self, shape, io,
130
+ &(block_given? ? Proc.new : nil))
131
+ end
132
+ end
133
+
134
+ # Class representing an animation of transform
135
+ # @attr [Symbol] type a type of transform, either 'translate', 'scale',
136
+ # 'rotate', 'skewX' or 'skewY'
137
+ # @attr [Numeric|Array] from a starting value of the animation
138
+ # @attr [Numeric|Array] to a ending value of the animation
139
+ class TransformAnimation < Base
140
+ IMPLEMENT_ATTRIBUTES = [:type]
141
+ VALID_VALUES = {
142
+ :type => [:translate, :scale, :rotate, :skewX, :skewY]
143
+ }
144
+
145
+ attr_reader *IMPLEMENT_ATTRIBUTES
146
+
147
+ VALID_VALUES.each do |attr, valid_values|
148
+ define_method("#{attr.to_s}=") {|value|
149
+ if (value = value.to_s).size == 0
150
+ instance_variable_set("@#{attr}", nil)
151
+ else
152
+ unless VALID_VALUES[attr].include?(value)
153
+ raise ArgumentError, "`#{value}' is invalid #{attr}"
154
+ end
155
+ instance_variable_set("@#{attr}", value)
156
+ end
157
+ }
158
+ end
159
+
160
+ def from=(value)
161
+ case type
162
+ when :translate
163
+ case value
164
+ when Array
165
+ case value.size
166
+ when 2 then @from = value.map{|v| v.to_f}
167
+ else raise ArgumentError, "illegal size of Array: #{value.size}"
168
+ end
169
+ when Numeric, Length
170
+ @from = [value.to_f, 0]
171
+ when nil
172
+ @from = nil
173
+ else
174
+ raise TypeError, "illegal argument: #{value}"
175
+ end
176
+ when :scale
177
+ case value
178
+ when Array
179
+ case value.size
180
+ when 2 then @from = value.map{|v| v.to_f}
181
+ else raise ArgumentError, "illegal size of Array: #{value.size}"
182
+ end
183
+ when Numeric
184
+ @from = [value.to_f, value.to_f]
185
+ when nil
186
+ @from = nil
187
+ else
188
+ raise TypeError, "illegal argument: #{value}"
189
+ end
190
+ when :rotate, :skewX, :skewY
191
+ @from = value.nil? ? nil : value.to_f
192
+ end
193
+ end
194
+
195
+ def to=(value)
196
+ case type
197
+ when :translate
198
+ case value
199
+ when Array
200
+ case value.size
201
+ when 2 then @to = value.map{|v| v.to_f}
202
+ else raise ArgumentError, "illegal size of Array: #{value.size}"
203
+ end
204
+ when Numeric, Length
205
+ @to = [value.to_f, 0]
206
+ else
207
+ raise TypeError, "illegal argument: #{value}"
208
+ end
209
+ when :scale
210
+ case value
211
+ when Array
212
+ case value.size
213
+ when 2 then @to = value.map{|v| v.to_f}
214
+ else raise ArgumentError, "illegal size of Array: #{value.size}"
215
+ end
216
+ when Numeric
217
+ @to = [value.to_f, value.to_f]
218
+ else
219
+ raise TypeError, "illegal argument: #{value}"
220
+ end
221
+ when :rotate, :skewX, :skewY
222
+ @to = value.to_f
223
+ end
224
+ end
225
+
226
+ def initialize(shape, type, options)
227
+ @type = type
228
+ super(shape, options)
229
+ end
230
+
231
+ def write_as(formatter, shape, io=$>)
232
+ formatter.write_transform_animation(self, shape, io,
233
+ &(block_given? ? Proc.new : nil))
234
+ end
235
+
236
+ class << self
237
+ def translate(shape, options)
238
+ new(shape, :translate, options)
239
+ end
240
+
241
+ def scale(shape, options)
242
+ new(shape, :scale, options)
243
+ end
244
+
245
+ def scale(rotate, options)
246
+ new(shape, :rotate, options)
247
+ end
248
+
249
+ def skew_x(rotate, options)
250
+ new(shape, :skewX, options)
251
+ end
252
+
253
+ def skew_y(rotate, options)
254
+ new(shape, :skewY, options)
255
+ end
256
+ end
257
+ end
258
+ end
259
+ end