ctioga2 0.10.1 → 0.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +7 -0
  2. data/Changelog +18 -0
  3. data/bin/ctioga2 +28 -0
  4. data/lib/ctioga2/commands/commands.rb +1 -0
  5. data/lib/ctioga2/commands/doc/documentation-commands.rb +13 -0
  6. data/lib/ctioga2/commands/doc/help.rb +3 -2
  7. data/lib/ctioga2/commands/doc/html.rb +48 -0
  8. data/lib/ctioga2/commands/doc/introspection.rb +2 -2
  9. data/lib/ctioga2/commands/general-types.rb +10 -0
  10. data/lib/ctioga2/commands/parsers/file.rb +23 -2
  11. data/lib/ctioga2/data/backends/backends.rb +1 -2
  12. data/lib/ctioga2/data/backends/backends/smath.rb +129 -0
  13. data/lib/ctioga2/data/backends/backends/text.rb +1 -0
  14. data/lib/ctioga2/data/dataset.rb +1 -1
  15. data/lib/ctioga2/data/stack.rb +13 -3
  16. data/lib/ctioga2/graphics/elements.rb +2 -0
  17. data/lib/ctioga2/graphics/elements/containers.rb +3 -1
  18. data/lib/ctioga2/graphics/elements/element.rb +194 -5
  19. data/lib/ctioga2/graphics/elements/gradient-region.rb +5 -2
  20. data/lib/ctioga2/graphics/elements/histogram.rb +7 -2
  21. data/lib/ctioga2/graphics/elements/plot-elements.rb +88 -0
  22. data/lib/ctioga2/graphics/elements/primitive.rb +28 -12
  23. data/lib/ctioga2/graphics/elements/region.rb +6 -1
  24. data/lib/ctioga2/graphics/elements/style-lists.rb +2 -2
  25. data/lib/ctioga2/graphics/elements/subplot.rb +3 -3
  26. data/lib/ctioga2/graphics/elements/tangent.rb +5 -8
  27. data/lib/ctioga2/graphics/generator.rb +10 -0
  28. data/lib/ctioga2/graphics/geometry.rb +96 -0
  29. data/lib/ctioga2/graphics/legends.rb +4 -2
  30. data/lib/ctioga2/graphics/legends/area.rb +12 -4
  31. data/lib/ctioga2/graphics/root.rb +16 -14
  32. data/lib/ctioga2/graphics/styles.rb +5 -2
  33. data/lib/ctioga2/graphics/styles/arrows.rb +5 -0
  34. data/lib/ctioga2/graphics/styles/axes.rb +1 -1
  35. data/lib/ctioga2/graphics/styles/base.rb +95 -14
  36. data/lib/ctioga2/graphics/styles/curve.rb +8 -0
  37. data/lib/ctioga2/graphics/styles/drawable.rb +35 -48
  38. data/lib/ctioga2/graphics/styles/factory.rb +23 -23
  39. data/lib/ctioga2/graphics/styles/fill.rb +268 -0
  40. data/lib/ctioga2/graphics/styles/plot.rb +90 -46
  41. data/lib/ctioga2/graphics/styles/sets.rb +3 -0
  42. data/lib/ctioga2/graphics/styles/{sheet.rb → styles.rb} +70 -160
  43. data/lib/ctioga2/graphics/styles/stylesheet.rb +355 -0
  44. data/lib/ctioga2/graphics/styles/texts.rb +4 -2
  45. data/lib/ctioga2/graphics/styles/ticks.rb +44 -4
  46. data/lib/ctioga2/graphics/subplot-commands.rb +84 -9
  47. data/lib/ctioga2/graphics/types.rb +1 -1
  48. data/lib/ctioga2/graphics/types/dimensions.rb +40 -0
  49. data/lib/ctioga2/graphics/types/grid.rb +21 -5
  50. data/lib/ctioga2/graphics/types/point.rb +2 -1
  51. data/lib/ctioga2/log.rb +5 -1
  52. data/lib/ctioga2/metabuilder/types/styles.rb +11 -7
  53. data/lib/ctioga2/plotmaker.rb +2 -0
  54. data/lib/ctioga2/utils.rb +21 -6
  55. data/lib/ctioga2/version.rb +2 -2
  56. metadata +105 -108
@@ -31,9 +31,15 @@ module CTioga2
31
31
  # The style of the line that is drawn, as a StrokeStyle.
32
32
  sub_style :line, StrokeStyle
33
33
 
34
+ alias_for :color, :line_color
35
+
34
36
  # The style of markers that should be drawn, as a MarkerStyle.
35
37
  sub_style :marker, MarkerStyle
36
38
 
39
+
40
+ # Would have been nice, but that's a stupid idea, isn't it ?
41
+ alias_for :marker, :marker_marker
42
+
37
43
  # The text of the legend, if there is one.
38
44
  typed_attribute :legend, 'text'
39
45
 
@@ -43,6 +49,8 @@ module CTioga2
43
49
  # Filling of the curve, if applicable
44
50
  sub_style :fill, CurveFillStyle
45
51
 
52
+ alias_for :fill, :fill_close_type
53
+
46
54
  # Details of the location of the curve, a LocationStyle object.
47
55
  sub_style :location, LocationStyle, nil, true
48
56
 
@@ -59,6 +59,40 @@ 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
  # This class represents all the stylistic information to draw a
63
97
  # Marker.
64
98
  #
@@ -82,6 +116,7 @@ module CTioga2
82
116
  # \p override is a hash that can override part of the
83
117
  # dictionnary specification.
84
118
  def draw_markers_at(t, x, y, override = nil)
119
+ return if (! @marker || @marker == 'None')
85
120
  t.context do
86
121
  ## \todo allow custom line types for markers ?
87
122
  t.line_type = LineStyles::Solid
@@ -108,54 +143,6 @@ module CTioga2
108
143
  end
109
144
  end
110
145
 
111
- # A style that handles drawing a fill.
112
- #
113
- # \todo add ways to specify complex fills, such as patterned
114
- # fills and so on. Those would use clipping the path and base
115
- # themselves on the coordinates of the current frame -- or more
116
- # nicely use dimensions ? (which would allow to mix both to some
117
- # extent ?)
118
- #
119
- # \todo more attributes ?
120
- #
121
- # @todo This class should also provide image-based fills, with
122
- # CSS-like capacities (scaling, tiling, centering, and so on...)
123
- class FillStyle < BasicStyle
124
-
125
- # The color.
126
- typed_attribute :color, "color"
127
-
128
- # The transparency
129
- typed_attribute :transparency, 'float'
130
-
131
- # Sets up the parameters for the fill. Must be called before
132
- # any path drawing.
133
- #
134
- # \warning You *must* call FillStyle#do_fill for
135
- # filling. Directly calling FigureMaker#fill is not a good
136
- # idea, as you lose all 'hand-crafted' fills !
137
- def setup_fill(t)
138
- t.fill_color = @color if @color
139
- t.fill_transparency = @transparency if @transparency
140
- end
141
-
142
- # Does the actual filling step. Must be used within a context,
143
- # as it quite messes up with many things. Must be called after
144
- # a call to #setup_fill.
145
- def do_fill(t)
146
- t.fill
147
- end
148
-
149
- end
150
-
151
- # Same as FillStyle, but with additional parameters that handle
152
- # how the fill should be applied to curves.
153
- class CurveFillStyle < FillStyle
154
-
155
- typed_attribute :close_type, 'fill-until'
156
-
157
- end
158
-
159
146
  end
160
147
  end
161
148
  end
@@ -148,9 +148,9 @@ module CTioga2
148
148
 
149
149
  # A simple parameter is something whose target defines all, ie
150
150
  # only the name and a documentation text is necessary.
151
- def self.simple_parameter(target, text, sets = nil)
151
+ def self.simple_parameter(target, text, sets = nil, short = nil)
152
152
  name = target.gsub(/_/, '-')
153
- define_parameter(target, name, sets, text, nil)
153
+ define_parameter(target, name, sets, text, short)
154
154
  end
155
155
 
156
156
  # Returns the Hash containing the class parameters.
@@ -242,7 +242,7 @@ module CTioga2
242
242
  # Overrides as in the first ctioga
243
243
  @override_parameters = {
244
244
  'line_style' => LineStyles::Solid,
245
- 'marker_marker' => false,
245
+ 'marker' => false,
246
246
  'marker_scale' => 0.5,
247
247
  'fill_color' => '=color'.to_sym,
248
248
  'error_bar_color' => '=marker_color'.to_sym
@@ -320,16 +320,14 @@ module CTioga2
320
320
  # Now, the parameters:
321
321
 
322
322
  # Lines:
323
- define_parameter 'line_color', 'color',
324
- Sets::ColorSets, "line color", "-c"
323
+ simple_parameter 'color', "line color", Sets::ColorSets, "-c"
325
324
 
326
325
  simple_parameter 'line_width', 'line width', Sets::LineWidthSets
327
326
 
328
327
  simple_parameter 'line_style', 'line style', Sets::LineStyleSets
329
328
 
330
329
  # Markers
331
- define_parameter 'marker_marker', 'marker',
332
- Sets::MarkerSets, "marker", '-m'
330
+ simple_parameter 'marker', 'marker', Sets::MarkerSets, '-m'
333
331
 
334
332
  simple_parameter 'marker_color', "marker color", Sets::ColorSets
335
333
 
@@ -349,11 +347,12 @@ module CTioga2
349
347
  nil, "Y axis", nil, true
350
348
 
351
349
  # Now, fill style
352
- define_parameter 'fill_close_type', 'fill',
353
- {}, "Fill until", nil
350
+ simple_parameter 'fill', 'Fill until', {}
354
351
 
355
352
  simple_parameter 'fill_color', "fill color", Sets::ColorSets
356
353
 
354
+ simple_parameter 'fill_pattern', "fill pattern", nil
355
+
357
356
  simple_parameter 'clipped', "clipped", nil
358
357
 
359
358
  simple_parameter 'depth', "depth", nil
@@ -396,6 +395,21 @@ module CTioga2
396
395
  # plot command.
397
396
  PlotCommandOptions = plot_optional_arguments
398
397
 
398
+ # Converts the one-time parameters, which is a hash whose keys
399
+ # are the names of the parameters to targets.
400
+ def hash_name_to_target(h)
401
+ retval = {}
402
+ convert = self.class.name_to_target
403
+ for k,v in h
404
+ if convert.key? k
405
+ retval[convert[k]] = v
406
+ else
407
+ warn { "Unkown key for hash_name_to_target: #{k}" }
408
+ end
409
+ end
410
+ return retval
411
+ end
412
+
399
413
  protected
400
414
 
401
415
  # Returns the CurveFactoryParameterType object corresponding
@@ -413,20 +427,6 @@ module CTioga2
413
427
  return self.class.parameters
414
428
  end
415
429
 
416
- # Converts the one-time parameters, which is a hash whose keys
417
- # are the names of the parameters to targets.
418
- def hash_name_to_target(h)
419
- retval = {}
420
- convert = self.class.name_to_target
421
- for k,v in h
422
- if convert.key? k
423
- retval[convert[k]] = v
424
- else
425
- warn { "Unkown key for hash_name_to_target: #{k}" }
426
- end
427
- end
428
- return retval
429
- end
430
430
 
431
431
  # Resolve potential links in the form of :=stuff within the
432
432
  # given hash, and returns a new version of the hash.
@@ -0,0 +1,268 @@
1
+ # fill.rb: fill styles
2
+ # copyright (c) 2014 by Vincent Fourmond
3
+
4
+ # This program is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 2 of the License, or
7
+ # (at your option) any later version.
8
+
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details (in the COPYING file).
13
+
14
+ require 'ctioga2/utils'
15
+ require 'ctioga2/log'
16
+
17
+ require 'ctioga2/graphics/geometry'
18
+ require 'ctioga2/graphics/types/dimensions'
19
+
20
+ # This module contains all the classes used by ctioga
21
+ module CTioga2
22
+
23
+ module Graphics
24
+
25
+ # All the styles
26
+ module Styles
27
+
28
+
29
+ # This class handles drawing the pattern in a fill.
30
+ #
31
+ # It is a base class.
32
+ #
33
+ # Add transparency !
34
+ class FillPattern
35
+
36
+ # Draws the pattern over the whole output, with primary color
37
+ # _color_ and secondary color _secondary_ (not implemented
38
+ # yet).
39
+ #
40
+ # This does nothing. Derived classes do the job
41
+ def do(t, color, secondary = nil)
42
+ end
43
+
44
+ def self.from_text(str)
45
+ els = str.split(/\s*:\s*/)
46
+ args = []
47
+ if els.size > 1
48
+ args = els[1].split(/\s*,\s*/)
49
+ end
50
+
51
+ case els[0]
52
+ when /^hlines$/i
53
+ return SingleLineFillPattern.new(0, *args)
54
+ when /^vlines$/i
55
+ return SingleLineFillPattern.new(90, *args)
56
+ when /^lines$/i
57
+ return SingleLineFillPattern.new(*args)
58
+ when /^xlines$/i
59
+ return CrossedLinesFillPattern.new(*args)
60
+ when /^(solid|plain)$/i
61
+ return false
62
+ end
63
+ end
64
+ end
65
+
66
+ FillPatternType =
67
+ CmdType.new('fill-pattern', {
68
+ :type => :function_based,
69
+ :class => Graphics::Styles::FillPattern
70
+ }, <<EOD)
71
+ A fill pattern, one of:
72
+ * @lines@:_angle_,_distance_,_width_
73
+ * @vlines@:_distance_,_width_
74
+ * @hlines@:_distance_,_width_
75
+ * @xlines@:_distance_,_width_,_angle_
76
+ * @solid@ or @plain@
77
+
78
+ The first three are lines, of arbitrary orientation for @lines@,
79
+ vertical for @vlines@ and horizontal for @hlines@. @xlines@ correspond
80
+ to crossed perpendicular lines (the _angle_ is 45 by default). For
81
+ these styles, the _distance_ and _width_ are all optional and
82
+ correspond respectively to the distance between the lines and the line
83
+ width.
84
+
85
+ @solid@ or @plain@ correspond to solid fill (i.e. not patterned).
86
+ EOD
87
+
88
+ # @
89
+ class SingleLineFillPattern
90
+
91
+ # Line width (in line widths units ?)
92
+ attr_accessor :line_width
93
+
94
+ # Separation between the lines, a dimension
95
+ attr_accessor :distance
96
+
97
+ # Angle of the lines
98
+ attr_accessor :angle
99
+
100
+ def initialize(an = 0,dst = nil, lw = nil)
101
+ @distance = if dst
102
+ if dst.is_a? Types::Dimension
103
+ dst
104
+ else
105
+ Types::Dimension::from_text(dst, :x, :bp)
106
+ end
107
+ else
108
+ Types::Dimension.new(:bp, 5)
109
+ end
110
+ @line_width = lw ? lw.to_f : 0.8
111
+ @angle = an.to_f
112
+ end
113
+
114
+ def do(t, color, secondary = nil)
115
+ # Secondary is not used
116
+
117
+ t.context do
118
+ t.stroke_color = color
119
+ t.line_width = @line_width
120
+ # Make figure coordinates page coordinates
121
+ t.set_bounds([t.convert_frame_to_page_x(0),
122
+ t.convert_frame_to_page_x(1),
123
+ t.convert_frame_to_page_y(1),
124
+ t.convert_frame_to_page_y(0)])
125
+
126
+ # Now we can work
127
+ dx = -@distance.to_figure(t, :x) *
128
+ Math.sin(Math::PI/180 * @angle)
129
+ sx = @distance.to_figure(t, :x) *
130
+ Math.cos(Math::PI/180 * @angle)
131
+ dy = @distance.to_figure(t, :y) *
132
+ Math.cos(Math::PI/180 * @angle)
133
+ sy = @distance.to_figure(t, :y) *
134
+ Math.sin(Math::PI/180 * @angle)
135
+
136
+ if dy < 0
137
+ dy = -dy
138
+ dx = -dx
139
+ end
140
+
141
+ if dx.abs < 1e-12 # Horizontal lines
142
+ y = 0
143
+ while y <= 1
144
+ t.stroke_line(0, y, 1, y)
145
+ y += dy
146
+ end
147
+ elsif dy.abs < 1e-12
148
+ x = 0
149
+ dx = dx.abs
150
+ while x <= 1
151
+ t.stroke_line(x, 0, x, 1)
152
+ x += dx
153
+ end
154
+ else
155
+ if dx > 0
156
+ line = Line.new(0, 0, sx, sy)
157
+ else
158
+ line = Line.new(1, 0, sx, sy)
159
+ end
160
+ segs = [ Segment.new(0,0,1,0), Segment.new(1,0,1,1),
161
+ Segment.new(1,1,0,1), Segment.new(0,1,0,0)]
162
+ while true
163
+ ints = []
164
+ for s in segs
165
+ v = s.intersection(line)
166
+ ints << v if v
167
+ end
168
+ if ints.size == 0
169
+ break
170
+ elsif ints.size == 2
171
+ t.stroke_line(ints[0][0], ints[0][1],
172
+ ints[1][0], ints[1][1])
173
+ elsif ints.size == 3
174
+ # Rare case but must be handled anyway
175
+ if ints[0][0] == ints[1][0]
176
+ ints.shift
177
+ end
178
+ t.stroke_line(ints[0][0], ints[0][1],
179
+ ints[1][0], ints[1][1])
180
+ end
181
+ line.x += dx
182
+ line.y += dy
183
+ end
184
+ end
185
+ end
186
+
187
+ end
188
+ end
189
+
190
+
191
+ class CrossedLinesFillPattern
192
+
193
+ def initialize(dst1 = nil, lw1 = nil, angle = 45,
194
+ dst2 = nil, lw2 = nil, dangle = 90)
195
+ @first = SingleLineFillPattern.new(angle, dst1, lw1)
196
+ @second = SingleLineFillPattern.new(@first.angle + dangle.to_f,
197
+ dst2 || dst1, lw2 || lw1)
198
+ end
199
+
200
+
201
+ def do(t, color, secondary = nil)
202
+ @first.do(t, color)
203
+ @second.do(t, secondary || color)
204
+ end
205
+ end
206
+
207
+ # A style that handles drawing a fill.
208
+ #
209
+ # \todo add ways to specify complex fills, such as patterned
210
+ # fills and so on. Those would use clipping the path and base
211
+ # themselves on the coordinates of the current frame -- or more
212
+ # nicely use dimensions ? (which would allow to mix both to some
213
+ # extent ?)
214
+ #
215
+ # \todo more attributes ?
216
+ #
217
+ # @todo This class should also provide image-based fills, with
218
+ # CSS-like capacities (scaling, tiling, centering, and so on...)
219
+ class FillStyle < BasicStyle
220
+
221
+ # The color.
222
+ typed_attribute :color, "color"
223
+
224
+ # The transparency
225
+ typed_attribute :transparency, 'float'
226
+
227
+ # The fill pattern
228
+ typed_attribute :pattern, "fill-pattern"
229
+
230
+ # Sets up the parameters for the fill. Must be called before
231
+ # any path drawing.
232
+ #
233
+ # \warning You *must* call FillStyle#do_fill for
234
+ # filling. Directly calling FigureMaker#fill is not a good
235
+ # idea, as you lose all 'hand-crafted' fills !
236
+ def setup_fill(t)
237
+ if ! @pattern
238
+ t.fill_color = @color if @color
239
+ t.fill_transparency = @transparency if @transparency
240
+ end
241
+ end
242
+
243
+ # Does the actual filling step. Must be used within a context,
244
+ # as it quite messes up with many things. Must be called after
245
+ # a call to #setup_fill.
246
+ def do_fill(t)
247
+ if @pattern && @color
248
+ t.clip
249
+ @pattern.do(t, @color)
250
+ else
251
+ t.fill
252
+ end
253
+ end
254
+
255
+ end
256
+
257
+ # Same as FillStyle, but with additional parameters that handle
258
+ # how the fill should be applied to curves.
259
+ class CurveFillStyle < FillStyle
260
+
261
+ typed_attribute :close_type, 'fill-until'
262
+
263
+ end
264
+
265
+ end
266
+ end
267
+ end
268
+