ctioga2 0.10.1 → 0.11

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.
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
+