ctioga 1.11.1

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 (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