ctioga 1.11.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. data/COPYING +340 -0
  2. data/ctioga/bin/ctable +28 -0
  3. data/ctioga/bin/ctioga +37 -0
  4. data/ctioga/doc/ctable.1 +156 -0
  5. data/ctioga/doc/ctioga.1 +2363 -0
  6. data/ctioga/examples/README +46 -0
  7. data/ctioga/examples/ctioga.gnuplot +4 -0
  8. data/ctioga/examples/ctioga_within_tioga.rb +53 -0
  9. data/ctioga/examples/ctiogarc.rb +24 -0
  10. data/ctioga/examples/include_1.rb +15 -0
  11. data/ctioga/examples/noise.dat +100 -0
  12. data/ctioga/examples/noise.rb +13 -0
  13. data/ctioga/examples/trig.csv +100 -0
  14. data/ctioga/examples/trig.dat +100 -0
  15. data/ctioga/examples/trig.rb +14 -0
  16. data/ctioga/examples/trigh.dat +100 -0
  17. data/ctioga/examples/trigh.rb +10 -0
  18. data/ctioga/examples/tutorial +763 -0
  19. data/ctioga/examples/tutorial.sh +269 -0
  20. data/ctioga/tests/README +14 -0
  21. data/ctioga/tests/axes.sh +40 -0
  22. data/ctioga/tests/basic.sh +11 -0
  23. data/ctioga/tests/draw.sh +24 -0
  24. data/ctioga/tests/histograms.sh +14 -0
  25. data/ctioga/tests/insets.sh +41 -0
  26. data/ctioga/tests/layouts.sh +29 -0
  27. data/ctioga/tests/legends.sh +113 -0
  28. data/ctioga/tests/styles.sh +43 -0
  29. data/ctioga/tests/test_style.sh +8 -0
  30. data/ctioga/tests/tests.sh +24 -0
  31. data/ctioga/tests/text_backend.sh +83 -0
  32. data/ctioga/tests/tioga_defaults.rb +18 -0
  33. data/lib/CTioga/axes.rb +904 -0
  34. data/lib/CTioga/backends.rb +88 -0
  35. data/lib/CTioga/boundaries.rb +224 -0
  36. data/lib/CTioga/ctable.rb +134 -0
  37. data/lib/CTioga/curve_style.rb +246 -0
  38. data/lib/CTioga/debug.rb +199 -0
  39. data/lib/CTioga/dimension.rb +133 -0
  40. data/lib/CTioga/elements.rb +17 -0
  41. data/lib/CTioga/elements/base.rb +84 -0
  42. data/lib/CTioga/elements/containers.rb +578 -0
  43. data/lib/CTioga/elements/curves.rb +368 -0
  44. data/lib/CTioga/elements/tioga_primitives.rb +440 -0
  45. data/lib/CTioga/layout.rb +595 -0
  46. data/lib/CTioga/legends.rb +29 -0
  47. data/lib/CTioga/legends/cmdline.rb +187 -0
  48. data/lib/CTioga/legends/item.rb +164 -0
  49. data/lib/CTioga/legends/style.rb +257 -0
  50. data/lib/CTioga/log.rb +73 -0
  51. data/lib/CTioga/movingarrays.rb +131 -0
  52. data/lib/CTioga/partition.rb +271 -0
  53. data/lib/CTioga/plot_style.rb +230 -0
  54. data/lib/CTioga/plotmaker.rb +1677 -0
  55. data/lib/CTioga/shortcuts.rb +69 -0
  56. data/lib/CTioga/structures.rb +82 -0
  57. data/lib/CTioga/styles.rb +140 -0
  58. data/lib/CTioga/themes.rb +581 -0
  59. data/lib/CTioga/themes/classical.rb +82 -0
  60. data/lib/CTioga/themes/demo.rb +63 -0
  61. data/lib/CTioga/themes/fits.rb +91 -0
  62. data/lib/CTioga/themes/mono.rb +33 -0
  63. data/lib/CTioga/tioga.rb +32 -0
  64. data/lib/CTioga/utils.rb +173 -0
  65. data/lib/MetaBuilder/Parameters/dates.rb +38 -0
  66. data/lib/MetaBuilder/Parameters/lists.rb +132 -0
  67. data/lib/MetaBuilder/Parameters/numbers.rb +69 -0
  68. data/lib/MetaBuilder/Parameters/strings.rb +86 -0
  69. data/lib/MetaBuilder/Parameters/styles.rb +75 -0
  70. data/lib/MetaBuilder/Qt4/Parameters/dates.rb +51 -0
  71. data/lib/MetaBuilder/Qt4/Parameters/numbers.rb +65 -0
  72. data/lib/MetaBuilder/Qt4/Parameters/strings.rb +106 -0
  73. data/lib/MetaBuilder/Qt4/parameter.rb +172 -0
  74. data/lib/MetaBuilder/Qt4/parameters.rb +9 -0
  75. data/lib/MetaBuilder/descriptions.rb +603 -0
  76. data/lib/MetaBuilder/factory.rb +101 -0
  77. data/lib/MetaBuilder/group.rb +57 -0
  78. data/lib/MetaBuilder/metabuilder.rb +10 -0
  79. data/lib/MetaBuilder/parameter.rb +374 -0
  80. data/lib/MetaBuilder/parameters.rb +11 -0
  81. data/lib/MetaBuilder/qt4.rb +8 -0
  82. data/lib/SciYAG/Backends/backend.rb +379 -0
  83. data/lib/SciYAG/Backends/binner.rb +168 -0
  84. data/lib/SciYAG/Backends/cache.rb +102 -0
  85. data/lib/SciYAG/Backends/dataset.rb +158 -0
  86. data/lib/SciYAG/Backends/descriptions.rb +469 -0
  87. data/lib/SciYAG/Backends/filters.rb +25 -0
  88. data/lib/SciYAG/Backends/filters/average.rb +134 -0
  89. data/lib/SciYAG/Backends/filters/cumulate.rb +37 -0
  90. data/lib/SciYAG/Backends/filters/filter.rb +70 -0
  91. data/lib/SciYAG/Backends/filters/norm.rb +39 -0
  92. data/lib/SciYAG/Backends/filters/smooth.rb +63 -0
  93. data/lib/SciYAG/Backends/filters/sort.rb +43 -0
  94. data/lib/SciYAG/Backends/filters/strip.rb +34 -0
  95. data/lib/SciYAG/Backends/filters/trim.rb +64 -0
  96. data/lib/SciYAG/Backends/gnuplot.rb +131 -0
  97. data/lib/SciYAG/Backends/math.rb +108 -0
  98. data/lib/SciYAG/Backends/mdb.rb +462 -0
  99. data/lib/SciYAG/Backends/multitext.rb +96 -0
  100. data/lib/SciYAG/Backends/source.rb +64 -0
  101. data/lib/SciYAG/Backends/text.rb +339 -0
  102. data/lib/SciYAG/backends.rb +16 -0
  103. metadata +191 -0
@@ -0,0 +1,29 @@
1
+ # legends.rb: legend implementation of CTioga
2
+ # copyright (c) 2008 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 'CTioga/log'
15
+ require 'CTioga/debug'
16
+ require 'CTioga/curve_style'
17
+ require 'CTioga/dimension'
18
+
19
+ require 'CTioga/boundaries'
20
+
21
+ require 'CTioga/legends/item'
22
+ require 'CTioga/legends/style'
23
+ require 'CTioga/legends/cmdline'
24
+
25
+ module CTioga
26
+
27
+ Version::register_svn_info('$Revision: 838 $', '$Date: 2008-10-11 13:27:05 +0200 (Sat, 11 Oct 2008) $')
28
+
29
+ end
@@ -0,0 +1,187 @@
1
+ # legends.rb: command-line parsing for legends
2
+ # copyright (c) 2008 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 'CTioga/log'
15
+ require 'CTioga/debug'
16
+ require 'CTioga/curve_style'
17
+ require 'CTioga/dimension'
18
+
19
+ module CTioga
20
+
21
+ Version::register_svn_info('$Revision: 870 $', '$Date: 2009-01-20 14:28:32 +0100 (Tue, 20 Jan 2009) $')
22
+
23
+ # A module to deal with legends...
24
+ module Legends
25
+
26
+ # Parse the legend positions
27
+ def self.legend_position(spec)
28
+ specs = {}
29
+ begin
30
+ margins = Utils::inset_margins(spec)
31
+ specs = margins.to_frame("legend_%s_margin")
32
+ rescue # in case of an incorrect margin
33
+ # Then we look for a position in the spirit of:
34
+ if spec =~ /\s*([tbc])([rlc])\s*(?::\s*([\d.eE+-]+),([\d.eE+-]+))?\s*$/
35
+ if($3 && $4)
36
+ x = Float($3)
37
+ y = Float($4)
38
+ else
39
+ x = y = nil
40
+ end
41
+ if $1 == 't'
42
+ specs['legend_top'] = y || 0.95
43
+ elsif $1 == 'b'
44
+ specs['legend_bottom'] = y || 0.05
45
+ else
46
+ specs['legend_vcenter'] = y || 0.5
47
+ end
48
+ if $2 == 'l'
49
+ specs['legend_left'] = x || 0.05
50
+ elsif $2 == 'r'
51
+ specs['legend_right'] = x || 0.95
52
+ else
53
+ specs['legend_hcenter'] = x || 0.5
54
+ end
55
+ else
56
+ raise "Incorrect legend (inside) position: '#{spec}'"
57
+ end
58
+ end
59
+ return specs
60
+ end
61
+
62
+ # Fills up an OptionParser, _parser_ with legend-related command-line
63
+ # options. Takes a Plotmaker _target_
64
+ def self.fill_option_parser(parser, target)
65
+
66
+ parser.separator "\nLegends:"
67
+
68
+ parser.on("-l","--[no-]legend [LEGEND]",
69
+ "Sets the legend of the next curve.") do |l|
70
+ target.override_style.legend = l
71
+ end
72
+
73
+ parser.on("--[no-]auto-legend",
74
+ "Whether to automatically add legends",
75
+ "to curves") do |l|
76
+ target.autolegends = l
77
+ end
78
+
79
+ parser.on('-N', "--no-legends",
80
+ "Alias for --no-auto-legend") do
81
+ target.autolegends = false
82
+ end
83
+
84
+ ## Legend scale
85
+ parser.on("--legend-scale FACT",
86
+ "Sets the scale for the legends") do |l|
87
+ target.add_elem_funcall(:legend_scale=, Float(l))
88
+ end
89
+
90
+ parser.on("--legend-line TEXT",
91
+ "Adds the line TEXT in the legend") do |l|
92
+ target.current_object.add_legend_info(LegendLine.new(l))
93
+ end
94
+
95
+
96
+ parser.on("--legend-dy DIM",
97
+ "The distance between two legend lines, ",
98
+ "expressed in terms of text line size") do |l|
99
+ target.current_object.plot_style.legend_style.dy =
100
+ TextDimension.new(l)
101
+ end
102
+
103
+ parser.on("--legend-pos SPEC",
104
+ "Sets the legend position and its size.",
105
+ "SPEC looks like pos,size[,delta]") do |a|
106
+ w,s,d = a.split /\s*,\s*/
107
+ if d
108
+ warn "The delta specification (#{d}) for #{a} is ignored"
109
+ end
110
+ target.debug "Legend position #{w.inspect} #{s.inspect}"
111
+ target.current_object.layout_preferences.legend_position = w.to_sym
112
+ target.current_object.layout_preferences.legend_size = Dimension.new(s)
113
+ end
114
+
115
+ parser.on("--legend-inside SPEC",
116
+ "Makes a legend inside the plot.",
117
+ "See --inset for the format of SPEC") do |a|
118
+ specs = legend_position(a)
119
+ target.debug "Specs: #{specs.inspect}"
120
+ target.current_object.layout_preferences.legend_position = :inside
121
+ target.current_object.layout_preferences.legend_spec = specs
122
+ end
123
+
124
+ # Frames around legends:
125
+ parser.on("--[no-]legend-frame [WHAT]",
126
+ "Which frame should ctioga draw around legends ?") do |l|
127
+ if l =~ /square|round/i
128
+ l = l.downcase.to_sym
129
+ elsif l =~ /none/i || (!l)
130
+ l = false
131
+ else
132
+ warn "Incorrect legend frame: '#{l}'"
133
+ end
134
+ target.current_object.plot_style.legend_style.box_style = l
135
+ end
136
+
137
+ # TODO: make all the legend styles...
138
+ parser.on("--[no-]legend-background [COLOR]",
139
+ "Background color for the legend") do |c|
140
+ c = CTioga.get_tioga_color(c) if c
141
+ target.current_object.plot_style.legend_style.background_color = c
142
+ end
143
+
144
+ parser.on("--[no-]legend-transparency [VALUE]",
145
+ "Transparency for the background") do |f|
146
+ if !f
147
+ f = 0.0
148
+ else
149
+ f = f.to_f
150
+ end
151
+ target.current_object.plot_style.legend_style.
152
+ background_transparency = f
153
+ end
154
+
155
+ parser.on("--[no-]legend-color [COLOR]",
156
+ "Color for the line around the legend") do |c|
157
+ c = CTioga.get_tioga_color(c) if c
158
+ target.current_object.plot_style.legend_style.line_color = c
159
+ end
160
+
161
+ parser.on("--legend-line-width WIDTH",
162
+ "Line width for drawing the legend") do |c|
163
+ c = Float(c)
164
+ target.current_object.plot_style.legend_style.line_width = c
165
+ end
166
+
167
+ parser.on("--legend-line-style STYLE",
168
+ "Line style for drawing the legend") do |c|
169
+ c = MetaBuilder::ParameterType.from_string(:line_style,c)
170
+ target.current_object.plot_style.legend_style.line_style = c
171
+ end
172
+
173
+ parser.on("--[no-]separate-legends",
174
+ "If set, PDF files are produced that contain",
175
+ "what the legend pictogram would look like") do |l|
176
+ target.separate_legends = l
177
+ if l
178
+ # Switches off autolegends by default
179
+ target.autolegends = false
180
+ end
181
+ end
182
+
183
+ end
184
+
185
+ end
186
+
187
+ end
@@ -0,0 +1,164 @@
1
+ # legends.rb: legend implementation of CTioga
2
+ # copyright (c) 2008 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 'CTioga/log'
15
+ require 'CTioga/debug'
16
+ require 'CTioga/curve_style'
17
+ require 'CTioga/dimension'
18
+
19
+ module CTioga
20
+
21
+ Version::register_svn_info('$Revision: 839 $', '$Date: 2008-10-11 14:47:08 +0200 (Sat, 11 Oct 2008) $')
22
+
23
+ # The base class for all legends items (real legends, spacing, lines).
24
+ class LegendItem
25
+
26
+ include Debug
27
+ include Log
28
+
29
+ # This class-wide variable is used to number text
30
+ # in a unique fashion
31
+ @@legend_item_numbering = 0
32
+
33
+ def initialize
34
+ @legend_number = @@legend_item_numbering
35
+ @@legend_item_numbering += 1
36
+ end
37
+
38
+ # Returns the (width, height) in figure coordinates
39
+ # of the legend element with the given LegendStyle
40
+ # and FigureMaker reference objects.
41
+ #
42
+ # The returned values can be inaccurate to some extent.
43
+ def size(t, legend_style)
44
+ return [0, 0]
45
+ end
46
+
47
+ # Draws the legend at the given top left position (x,y)
48
+ # in figure coordinates.
49
+ def draw(t, legend_style, x, y)
50
+ end
51
+
52
+ # For internal use
53
+ def legend_name
54
+ return "legend-#{@legend_number}"
55
+ end
56
+
57
+ # We put the baseline so that the space above and below in the
58
+ # box of height legend_style.dy is even.
59
+ def get_baseline_y(t, legend_style, y)
60
+ return y - 0.5 * ( TextDimension.new(1.0).to_figure(t, :y) +
61
+ legend_style.dy.to_figure(t, :y))
62
+ end
63
+
64
+
65
+ end
66
+
67
+ # A class representing the style of a single legend line (unrelated
68
+ # to a curve)
69
+ class LegendLine < LegendItem
70
+
71
+ # The text of the line
72
+ attr_accessor :text
73
+
74
+ def initialize(text = "")
75
+ super()
76
+ @text = text
77
+ end
78
+
79
+ # Draw one single text line
80
+ def draw(t, legend_style, x, y)
81
+ y = get_baseline_y(t, legend_style, y)
82
+ t.show_text('x' => x, 'y' => y,
83
+ 'text' => @text,
84
+ 'justification' => LEFT_JUSTIFIED,
85
+ 'measure' => legend_name
86
+ )
87
+ end
88
+
89
+ # Computes the size of the line. Height should always
90
+ # be accurate, but width can be 0 sometimes...
91
+ def size(t, legend_style)
92
+ height = legend_style.dy.to_figure(t, :y)
93
+ info = t.get_text_size(legend_name)
94
+ if info.key? 'width'
95
+ width = t.convert_output_to_figure_dx(10*info['width'])
96
+ else
97
+ width = 0
98
+ end
99
+
100
+ return [ width, height ]
101
+ end
102
+
103
+ end
104
+
105
+ # The class handling the drawing of one Curve
106
+ class CurveLegend < LegendItem
107
+
108
+ attr_accessor :curve_style
109
+
110
+ def initialize(style)
111
+ super()
112
+ @curve_style = style
113
+ end
114
+
115
+ # Draw one single text line
116
+ def draw(t, legend_style, x, y)
117
+ y = get_baseline_y(t, legend_style, y)
118
+ t.context do
119
+ # Position specification for the legend pictogram
120
+ margin_specs = { 'left' => x,
121
+ 'right' => 1 - x - legend_style.picto_width.to_figure(t, :x),
122
+ 'bottom' => y,
123
+ 'top' => 1 - y - legend_style.picto_height.to_figure(t, :y)
124
+ }
125
+ debug "Legend margins for '#{@curve_style.legend}' : #{margin_specs.inspect}"
126
+ t.subfigure(margin_specs) do
127
+ # We scale the text back to normal so the markers have the right
128
+ # size
129
+ # t.line_width = 0.1
130
+ # t.stroke_rect(0,0,1,1)
131
+ t.rescale_text(1/legend_style.text_scale)
132
+ @curve_style.output_legend_pictogram(t)
133
+ end
134
+ end
135
+ t.show_text('x' => x +
136
+ legend_style.picto_width.to_figure(t, :x) +
137
+ legend_style.picto_to_text.to_figure(t, :x),
138
+ 'y' => y, 'text' => @curve_style.legend,
139
+ 'measure' => legend_name,
140
+ 'justification' => LEFT_JUSTIFIED)
141
+ end
142
+
143
+ # Computes the size of the line. Height should always
144
+ # be accurate, but width can be 0 sometimes...
145
+ def size(t, legend_style)
146
+ height = legend_style.dy.to_figure(t, :y)
147
+
148
+ width = legend_style.picto_width.to_figure(t, :x) +
149
+ legend_style.picto_to_text.to_figure(t, :x)
150
+
151
+ info = t.get_text_size(legend_name)
152
+
153
+ if info.key? 'width'
154
+ width += t.convert_output_to_figure_dx(10*info['width'])
155
+ end
156
+
157
+ return [ width, height ]
158
+ end
159
+
160
+
161
+ end
162
+
163
+
164
+ end
@@ -0,0 +1,257 @@
1
+ # legends.rb: legend implementation of CTioga
2
+ # copyright (c) 2008 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 'CTioga/log'
15
+ require 'CTioga/debug'
16
+ require 'CTioga/curve_style'
17
+ require 'CTioga/dimension'
18
+
19
+ module CTioga
20
+
21
+ Version::register_svn_info('$Revision: 858 $', '$Date: 2009-01-07 13:39:07 +0100 (Wed, 07 Jan 2009) $')
22
+
23
+ # A class that provides style information and display facilities
24
+ # for legends.
25
+ #
26
+ # It does not provide contents for the legends themselves
27
+ class LegendStyle
28
+ include Debug
29
+ include Log
30
+
31
+ # The distance between two legend lines
32
+ attr_accessor :dy
33
+
34
+ # The legend scale
35
+ attr_accessor :scale
36
+
37
+ # The padding between the legend and anything else around
38
+ attr_accessor :padding
39
+
40
+ # The width of the pictogram
41
+ attr_accessor :picto_width
42
+
43
+ # The height of the pictogram
44
+ attr_accessor :picto_height
45
+
46
+ # The distance between the pictogram and the text
47
+ attr_accessor :picto_to_text
48
+
49
+ # Scales all the text by that factor:
50
+ attr_accessor :text_scale
51
+
52
+ # Style of the box around the legend : (none/round/box)
53
+ attr_accessor :box_style
54
+
55
+ # The amount of space that should be left around the legend
56
+ # when drawing the box.
57
+ attr_accessor :margin
58
+
59
+ # The color of the background. false means no background
60
+ # Only meaningful when the #box_style is set to something
61
+ # different of none.
62
+ attr_accessor :background_color
63
+
64
+ # The color for the lines
65
+ attr_accessor :line_color
66
+
67
+ # The color for the lines
68
+ attr_accessor :line_width
69
+
70
+ # The color for the lines
71
+ attr_accessor :line_style
72
+
73
+ # The transparency of the background
74
+ attr_accessor :background_transparency
75
+
76
+ def initialize
77
+ # All in relative units ;-)...
78
+ @dy = TextDimension.new(1.9)
79
+ @padding = TextDimension.new(0.5)
80
+ @picto_width = TextDimension.new(1.5)
81
+ @picto_height = TextDimension.new(0.75)
82
+ @picto_to_text = TextDimension.new(0.5)
83
+ @scale = 1.0
84
+
85
+ @box_style = false # For no box.
86
+
87
+ # Frame styles:
88
+ @background_color = false
89
+ @background_transparency = 0.0
90
+ @line_color = Tioga::FigureConstants::Black
91
+ @line_width = 1.0
92
+ @line_style = false
93
+
94
+
95
+ @margin = TextDimension.new(0.4)
96
+
97
+ end
98
+
99
+
100
+
101
+ # Prepares the context in which the legend is made, and run
102
+ # the corresponding code
103
+ def legend_context(t, legend_specs,plot_margins)
104
+ subfigure_margins = {}
105
+
106
+ if legend_specs.key?('legend_left_margin')
107
+ # Now, we enter a subfigure:
108
+ for pos in %w{left right top bottom}
109
+ subfigure_margins[pos] = legend_specs["legend_#{pos}_margin"]
110
+ end
111
+ debug "Legend margins #{subfigure_margins.inspect}"
112
+ else # We make a subfigure relative to the plot
113
+ if plot_margins
114
+ subfigure_margins = plot_margins.dup
115
+ else
116
+ plot_margins = false
117
+ end
118
+ end
119
+
120
+ t.context do
121
+ t.set_subframe(subfigure_margins) if subfigure_margins
122
+ t.rescale(@scale)
123
+ t.rescale_text(@text_scale)
124
+ yield
125
+ end
126
+
127
+ end
128
+
129
+ # Prepare the frame path
130
+ def prepare_frame_path(t,xl,yt, total_width, total_height)
131
+ case @box_style
132
+ when :square
133
+ t.append_rect_to_path(xl - @margin.to_figure(t, :x),
134
+ yt + @margin.to_figure(t, :y),
135
+ total_width + 2 * @margin.to_figure(t, :x),
136
+ - total_height - 2 * @margin.to_figure(t, :y))
137
+ when :round
138
+ # For some reason, the append_rounded_rect_to_path does not
139
+ # work so well...
140
+ dx = @margin.to_figure(t, :x)
141
+ dy = @margin.to_figure(t, :y)
142
+ xr = xl + total_width
143
+ yb = yt - total_height
144
+ t.move_to_point(xl - dx, yt)
145
+ t.append_curve_to_path(xl - dx, yt + 0.5 * dy, # First control point
146
+ xl - 0.5 * dx, yt + dy,
147
+ xl, yt + dy)
148
+ t.append_point_to_path(xr, yt + dy)
149
+ t.append_curve_to_path(xr + 0.5 * dx, yt + dy, # First control point
150
+ xr + dx, yt + 0.5 * dy,
151
+ xr + dx, yt)
152
+ t.append_point_to_path(xr + dx, yb)
153
+ t.append_curve_to_path(xr + dx, yb - 0.5 * dy, # First control point
154
+ xr + 0.5 * dx, yb - dy,
155
+ xr, yb - dy)
156
+ t.append_point_to_path(xl, yb - dy)
157
+ t.append_curve_to_path(xl - 0.5 * dx, yb - dy, # First control point
158
+ xl - dx, yb - 0.5 * dy,
159
+ xl - dx, yb)
160
+ t.close_path
161
+ end
162
+ end
163
+
164
+ # Displays legends _legend_info_ to the FigureMaker object _t_ using
165
+ # boundaries given by _legend_specs_ for the plot with the
166
+ # given _plot_margins_
167
+ def show_legends(t, legend_specs, plot_margins, legend_info)
168
+ debug "Plotting legends: #{legend_specs.inspect}"
169
+ @text_scale ||= t.legend_scale
170
+
171
+ # First, we collect data on the legend_info
172
+ widths = []
173
+ heights = []
174
+ total_height = 0
175
+ total_width = 0
176
+ legend_context(t, legend_specs, plot_margins) do
177
+ for item in legend_info
178
+ w, h = item.size(t, self)
179
+ widths << w
180
+ heights << h
181
+ total_height += h
182
+ total_width = w if total_width < w
183
+ end
184
+ end
185
+
186
+ debug "Total height: #{total_height}\tTotal width: #{total_width}"
187
+
188
+ # Need to scope them now, so the context down actually modifies them !
189
+ xl = 0
190
+ yl = 0
191
+ if legend_specs.key?('legend_left_margin')
192
+ legend_context(t, legend_specs, plot_margins) do
193
+ yl = 1
194
+ xl = @padding.to_figure(t, :x)
195
+ end
196
+ elsif legend_specs.key?('legend_left') or
197
+ legend_specs.key?('legend_right') or
198
+ legend_specs.key?('legend_hcenter')
199
+
200
+ legend_context(t, legend_specs, plot_margins) do
201
+ if legend_specs.key?('legend_left')
202
+ xl = t.convert_frame_to_figure_x(legend_specs['legend_left'])
203
+ elsif legend_specs.key?('legend_right')
204
+ xl = t.convert_frame_to_figure_x(legend_specs['legend_right']) -
205
+ total_width
206
+ else
207
+ xl = t.convert_frame_to_figure_x(legend_specs['legend_hcenter']) -
208
+ total_width * 0.5
209
+ end
210
+
211
+ if legend_specs.key?('legend_top')
212
+ yl = t.convert_frame_to_figure_y(legend_specs['legend_top'])
213
+ elsif legend_specs.key?('legend_bottom')
214
+ yl = t.convert_frame_to_figure_y(legend_specs['legend_bottom']) +
215
+ total_height
216
+ else
217
+ yl = t.convert_frame_to_figure_y(legend_specs['legend_vcenter']) +
218
+ total_height * 0.5
219
+ end
220
+ end
221
+ else
222
+ # Silently do nothing:
223
+ return
224
+ end
225
+
226
+ # Always wrapping within a context call ;-)...
227
+ legend_context(t, legend_specs, plot_margins) do
228
+ # First, we draw the box if necessary
229
+ if @box_style
230
+ t.context do
231
+ if @background_color
232
+ t.fill_color = @background_color
233
+ t.fill_transparency = @background_transparency
234
+ prepare_frame_path(t, xl, yl, total_width, total_height)
235
+ t.fill
236
+ end
237
+ if @line_color
238
+ t.stroke_color = @line_color
239
+ t.line_width = @line_width
240
+ t.line_type = @line_style if @line_style
241
+ prepare_frame_path(t, xl, yl, total_width, total_height)
242
+ t.stroke
243
+ end
244
+ end
245
+ end
246
+
247
+ for item in legend_info
248
+ w, h = item.size(t, self)
249
+ item.draw(t, self, xl, yl)
250
+ yl -= h
251
+ end
252
+ end
253
+ end
254
+
255
+ end
256
+
257
+ end