ctioga2 0.11 → 0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -40,6 +40,7 @@ require 'ctioga2/graphics/styles/background'
40
40
  require 'ctioga2/graphics/styles/plot'
41
41
 
42
42
  require 'ctioga2/graphics/styles/legend'
43
+ require 'ctioga2/graphics/styles/scope'
43
44
 
44
45
 
45
46
 
@@ -35,7 +35,12 @@ module CTioga2
35
35
  typed_attribute "#{e}_color".to_sym, 'color'
36
36
  end
37
37
 
38
- def draw_arrow(t, x1, y1, x2, y2)
38
+ TiogaDefaults = {
39
+ 'head_marker' => Tioga::MarkerConstants::Arrowhead,
40
+ 'tail_marker' => Tioga::MarkerConstants::BarThin
41
+ }
42
+
43
+ def old_draw_arrow(t, x1, y1, x2, y2)
39
44
  dict = self.to_hash
40
45
  dict.rename_key('width', 'line_width')
41
46
  dict.rename_key('style', 'line_style')
@@ -49,7 +54,142 @@ module CTioga2
49
54
  t.show_arrow(dict)
50
55
  end
51
56
 
57
+
58
+ # Draws an arrow.
59
+ def draw_arrow(t, x1, y1, x2, y2)
60
+ dx = x2 - x1
61
+ dy = y2 - y1
62
+
63
+ angle = Types::Dimension.get_angle(t, dx, dy)
64
+
65
+ len = Types::Dimension.get_distance(t, dx, dy)
66
+
67
+ rs = symbol_size(t, "head")
68
+ ls = symbol_size(t, "tail")
69
+
70
+ x1n, y1n, x2n, y2n = *Types::Dimension::adjust_line(t, x1, y1, x2, y2, -ls, -rs)
71
+
72
+ # Must shorten the path first...
73
+ sv = t.line_cap
74
+
75
+ # This has for effect to disable changing the line cap when
76
+ # there are now arrows to draw.
77
+ if ! (has_marker?('head') || has_marker?('tail'))
78
+ sv = Tioga::FigureConstants::LINE_CAP_BUTT
79
+ end
80
+ if sv != Tioga::FigureConstants::LINE_CAP_BUTT
81
+ t.line_cap = Tioga::FigureConstants::LINE_CAP_BUTT
82
+ end
83
+ draw_line(t, x1n, y1n, x2n, y2n)
84
+ if sv != Tioga::FigureConstants::LINE_CAP_BUTT
85
+ t.line_cap = sv
86
+ end
87
+
88
+ # Then, draw the arrow heads/tails
89
+ draw_symbol(t, 'head', angle, x2, y2)
90
+ draw_symbol(t, 'tail', angle - 180, x1, y1)
91
+
92
+ end
93
+
94
+ protected
95
+
96
+ # Return the dimension of the arrow size
97
+ def symbol_size(t, name)
98
+ sz = Types::Dimension.new(:dy,self.send("#{name}_scale") || 1.0)
99
+ sz.value *= case just(name)
100
+ when Tioga::FigureConstants::CENTERED
101
+ 0
102
+ when Tioga::FigureConstants::RIGHT_JUSTIFIED
103
+ 0.5
104
+ end
105
+ return sz
106
+ end
107
+
108
+ def just(name)
109
+ mkr = self.send("#{name}_marker")
110
+ if mkr == Tioga::MarkerConstants::Arrowhead or
111
+ mkr == Tioga::MarkerConstants::ArrowheadOpen
112
+ Tioga::FigureConstants::RIGHT_JUSTIFIED
113
+ else
114
+ Tioga::FigureConstants::CENTERED
115
+ end
116
+ end
117
+
118
+ def has_marker?(name)
119
+ mkr = self.send("#{name}_marker")
120
+ if ! mkr or mkr == 'None'
121
+ return false
122
+ else
123
+ return true
124
+ end
125
+ end
126
+
127
+ # Draw the arrow symbol for the given name (head or tail),
128
+ # with the given base angle and at the given position
129
+ def draw_symbol(t, name, angle, x, y)
130
+ hsh = {}
131
+ for k in %w(marker scale color angle)
132
+ tmp = self.send("#{name}_#{k}")
133
+ if tmp
134
+ hsh[k] = tmp
135
+ end
136
+ end
137
+ mkr = hsh['marker']
138
+ if ! mkr or mkr == 'None'
139
+ return
140
+ end
141
+
142
+ hsh['angle'] ||= 0
143
+ hsh['angle'] += angle
144
+
145
+ hsh['x'] = x
146
+ hsh['y'] = y
147
+
148
+ # Color defaults to line color
149
+ if @color and !hsh.key?('color')
150
+ hsh['color'] = @color
151
+ end
152
+
153
+ hsh['justification'] = just(name)
154
+ t.show_marker(hsh)
155
+ end
156
+
52
157
  end
158
+
159
+ # This class represents all the stylistic information necessary
160
+ # to draw a line parallel to a certain direction, indicated by
161
+ # an angle (default to horizontal)
162
+ class OrientedLineStyle < ArrowStyle
163
+ # The angle, in degrees.
164
+ typed_attribute :angle, 'float'
165
+
166
+ # The alignment of the line with respect to the point given.
167
+ typed_attribute :origin, 'justification'
168
+
169
+ # len is a dimension
170
+ def draw_oriented_arrow(t, xo, yo, len)
171
+
172
+ angle = @angle || 0.0
173
+
174
+ dx,dy = *len.to_figure(t, angle)
175
+
176
+ case @origin || Tioga::FigureConstants::LEFT_JUSTIFIED
177
+ when Tioga::FigureConstants::LEFT_JUSTIFIED
178
+ x1, y1 = xo, yo
179
+ x2, y2 = xo + dx, yo + dy
180
+ when Tioga::FigureConstants::CENTERED
181
+ x1, y1 = xo - 0.5 * dx, yo - 0.5 * dy
182
+ x2, y2 = xo + 0.5 * dx, yo + 0.5 * dy
183
+ when Tioga::FigureConstants::RIGHT_JUSTIFIED
184
+ x1, y1 = xo - dx, yo - dy
185
+ x2, y2 = xo, yo
186
+ end
187
+
188
+ draw_arrow(t, x1, y1, x2, y2)
189
+ end
190
+
191
+ end
192
+
53
193
  end
54
194
  end
55
195
  end
@@ -67,6 +67,12 @@ module CTioga2
67
67
  # The color of the stroke for the lines of the axis
68
68
  typed_attribute :stroke_color, 'color'
69
69
 
70
+ # The line width
71
+ typed_attribute :line_width, 'float'
72
+
73
+ # The line style
74
+ # typed_attribute :line_style,
75
+
70
76
  typed_attribute :major_tick_length, 'float'
71
77
  typed_attribute :major_tick_width, 'float'
72
78
 
@@ -144,7 +150,18 @@ minor_tick_length minor_tick_width)
144
150
  else
145
151
  spec['type']
146
152
  end
147
- t.show_axis(spec)
153
+ t.context do
154
+ if @line_width
155
+ # Holy gods, there is no way in Tioga to choose the line
156
+ # width.
157
+ #
158
+ # Here is essentially the proof that I must reimplement
159
+ # the axes.
160
+ t.xaxis_line_width = @line_width
161
+ t.yaxis_line_width = @line_width
162
+ end
163
+ t.show_axis(spec)
164
+ end
148
165
  # Now, we draw axis ticks
149
166
  if (type == Tioga::FigureConstants::AXIS_WITH_MAJOR_TICKS_AND_NUMERIC_LABELS) || (type == Tioga::FigureConstants::AXIS_WITH_TICKS_AND_NUMERIC_LABELS)
150
167
 
@@ -216,7 +216,7 @@ module CTioga2
216
216
  ret[key % k] = v
217
217
  end
218
218
  end
219
-
219
+
220
220
  if @sub_styles # Not always present too
221
221
  for sub in @sub_styles
222
222
  sym, cls, fmt, fc = *sub
@@ -239,7 +239,18 @@ module CTioga2
239
239
  end
240
240
 
241
241
  def self.sub_styles
242
- return @sub_styles
242
+ # p [:ss, self]
243
+ rv = if self.superclass.respond_to?(:sub_styles)
244
+ self.superclass.sub_styles
245
+ else
246
+ []
247
+ end
248
+ # p [:sparents, self, rv]
249
+ if @sub_styles
250
+ rv += @sub_styles
251
+ end
252
+ # p [:sparents_own, self, rv]
253
+ return rv
243
254
  end
244
255
 
245
256
  # Sets the values of the attributes from the given
@@ -275,7 +286,9 @@ module CTioga2
275
286
  cur_var = cls.new
276
287
  set_after = true
277
288
  end
289
+ # p :bef, fmt
278
290
  fmt = name % fmt
291
+ # p :aft, fmt
279
292
  nb = cur_var.set_from_hash(hash, fmt)
280
293
 
281
294
  # Here, this means that missing attributes do not get
@@ -325,6 +338,18 @@ module CTioga2
325
338
  end
326
339
  end
327
340
  end
341
+
342
+ # Now, substyles
343
+ for sb in self.class.sub_styles
344
+ symb, cls, fmt, fc = *sb
345
+ if instance_variable_defined?("@#{symb.to_s}")
346
+ sub = instance_variable_get("@#{symb.to_s}")
347
+ fmt = name % fmt
348
+ if ! sub.nil?
349
+ retval.update(sub.to_hash(fmt))
350
+ end
351
+ end
352
+ end
328
353
  return retval
329
354
  end
330
355
 
@@ -333,6 +358,20 @@ module CTioga2
333
358
  set_from_hash(other_object.to_hash)
334
359
  end
335
360
 
361
+ # Sets the style from the given hash or other object, if the
362
+ # style is not present yet.
363
+ def use_defaults_from(hsh)
364
+ if hsh.is_a? BasicStyle
365
+ hsh = hsh.to_hash
366
+ end
367
+ at = self.class.attribute_types
368
+ for k, v in hsh
369
+ if at.key?(k.to_sym) and ! instance_variable_defined?("@#{k}".to_sym)
370
+ self.send("#{k}=", v)
371
+ end
372
+ end
373
+ end
374
+
336
375
  # Converts a hash in text format into a format suitable for
337
376
  # feeding to #set_from_hash. Only relevant keys are
338
377
  # converted. Keys that exist in the options hash but are not
@@ -1,4 +1,4 @@
1
- # arrows.rb: style objects for lines and arrows
1
+ # box.rb: style objects for boxes
2
2
  # copyright (c) 2012 by Vincent Fourmond
3
3
 
4
4
  # This program is free software; you can redistribute it and/or modify
@@ -59,39 +59,6 @@ module CTioga2
59
59
 
60
60
  end
61
61
 
62
- # This class represents all the stylistic information necessary
63
- # to draw a line parallel to a certain direction, indicated by
64
- # an angle (default to horizontal)
65
- class OrientedLineStyle < StrokeStyle
66
- # The angle, in degrees.
67
- typed_attribute :angle, 'float'
68
-
69
- # The alignment of the line with respect to the point given.
70
- typed_attribute :origin, 'justification'
71
-
72
- # len is a dimension
73
- def draw_oriented_line(t, xo, yo, len)
74
-
75
- angle = @angle || 0.0
76
-
77
- dx,dy = *len.to_figure(t, angle)
78
-
79
- case @origin || Tioga::FigureConstants::LEFT_JUSTIFIED
80
- when Tioga::FigureConstants::LEFT_JUSTIFIED
81
- x1, y1 = xo, yo
82
- x2, y2 = xo + dx, yo + dy
83
- when Tioga::FigureConstants::CENTERED
84
- x1, y1 = xo - 0.5 * dx, yo - 0.5 * dy
85
- x2, y2 = xo + 0.5 * dx, yo + 0.5 * dy
86
- when Tioga::FigureConstants::RIGHT_JUSTIFIED
87
- x1, y1 = xo - dx, yo - dy
88
- x2, y2 = xo, yo
89
- end
90
-
91
- draw_line(t, x1, y1, x2, y2)
92
- end
93
-
94
- end
95
62
 
96
63
  # This class represents all the stylistic information to draw a
97
64
  # Marker.
@@ -102,42 +69,81 @@ module CTioga2
102
69
  # be handled directly in the marker specification...
103
70
  class MarkerStyle < BasicStyle
104
71
 
105
- # The color
106
- typed_attribute :color, 'color'
107
-
108
72
  # The marker
109
73
  typed_attribute :marker, 'marker'
110
74
 
111
75
  # The marker scale
112
76
  typed_attribute :scale, 'float'
113
77
 
78
+ # The angle
79
+ typed_attribute :angle, 'float'
80
+
81
+ # The default for color
82
+ typed_attribute :color, 'color-or-false'
83
+
84
+ # The stroke color
85
+ typed_attribute :line_color, 'color-or-false'
86
+
87
+ # The fill color
88
+ typed_attribute :fill_color, 'color-or-false'
89
+
90
+ # The stroke width
91
+ typed_attribute :line_width, 'float'
92
+
114
93
  # Shows the marker at a given location/set of locations.
115
94
  #
116
95
  # \p override is a hash that can override part of the
117
96
  # dictionnary specification.
118
97
  def draw_markers_at(t, x, y, override = nil)
119
98
  return if (! @marker || @marker == 'None')
99
+
100
+ dict = {
101
+ 'marker' => @marker
102
+ }
103
+ if @line_width
104
+ dict['stroke_width'] = @line_width
105
+ end
106
+ if !(@fill_color.nil?) || !(@line_color.nil?)
107
+ dict['fill_color'] = @fill_color.nil? ? @color : @fill_color
108
+ dict['stroke_color'] = @line_color.nil? ? @color : @line_color
109
+ dict['rendering_mode'] =
110
+ if dict['fill_color']
111
+ if dict['stroke_color']
112
+ Tioga::FigureConstants::FILL_AND_STROKE
113
+ else
114
+ Tioga::FigureConstants::FILL
115
+ end
116
+ else
117
+ Tioga::FigureConstants::STROKE
118
+ end
119
+ dict.strip_if_false!(%w{fill_color stroke_color})
120
+ else
121
+ dict['color'] = @color
122
+ if ! @color
123
+ return # Nothing to do !
124
+ end
125
+ end
126
+ if @angle
127
+ dict['angle'] = @angle
128
+ end
129
+
130
+ if x.is_a? Numeric
131
+ dict['x'] = x
132
+ dict['y'] = y
133
+ else
134
+ dict['Xs'] = x
135
+ dict['Ys'] = y
136
+ end
137
+
138
+ if @scale
139
+ dict['scale'] = @scale
140
+ end
141
+ if override
142
+ dict.merge!(override)
143
+ end
120
144
  t.context do
121
145
  ## \todo allow custom line types for markers ?
122
146
  t.line_type = LineStyles::Solid
123
- dict = {
124
- 'marker' => @marker,
125
- 'color' => @color
126
- }
127
- if x.is_a? Numeric
128
- dict['x'] = x
129
- dict['y'] = y
130
- else
131
- dict['Xs'] = x
132
- dict['Ys'] = y
133
- end
134
-
135
- if @scale
136
- dict['scale'] = @scale
137
- end
138
- if override
139
- dict.merge!(override)
140
- end
141
147
  t.show_marker(dict)
142
148
  end
143
149
  end
@@ -26,7 +26,12 @@ module CTioga2
26
26
  # This class represents the stylistic information necessary to
27
27
  # draw an error bar. It derives from StrokeStyle, as it is
28
28
  # essentially a stroke.
29
- class ErrorBarStyle < StrokeStyle
29
+ class ErrorBarStyle < BasicStyle
30
+
31
+ # The style of the line that is drawn, as a StrokeStyle.
32
+ sub_style :line, StrokeStyle
33
+
34
+ alias_for :color, :line_color
30
35
 
31
36
  # The error bar style. For now, not much here.
32
37
  attr_accessor :style
@@ -42,8 +47,8 @@ module CTioga2
42
47
  def show_error_bar(t, x, xmin, xmax, y, ymin, ymax)
43
48
  d = { 'x' => x,
44
49
  'y' => y,
45
- 'color' => @color || Tioga::ColorConstants::Black,
46
- 'line_width' => @width || 1.0,
50
+ 'color' => @line.color || Tioga::ColorConstants::Black,
51
+ 'line_width' => @line.width || 1.0,
47
52
  }
48
53
  has = false
49
54
  if (xmin && xmax && (xmax - xmin != 0))
@@ -60,6 +65,8 @@ module CTioga2
60
65
  # We won't draw something when there isn't anything to draw
61
66
  # !
62
67
  if(has)
68
+ # We should stop relying on Tioga for that.
69
+ # Probably this is the place to reimplement that ?
63
70
  t.show_error_bars(d)
64
71
  end
65
72
  end