ctioga 1.11.1
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +340 -0
- data/ctioga/bin/ctable +28 -0
- data/ctioga/bin/ctioga +37 -0
- data/ctioga/doc/ctable.1 +156 -0
- data/ctioga/doc/ctioga.1 +2363 -0
- data/ctioga/examples/README +46 -0
- data/ctioga/examples/ctioga.gnuplot +4 -0
- data/ctioga/examples/ctioga_within_tioga.rb +53 -0
- data/ctioga/examples/ctiogarc.rb +24 -0
- data/ctioga/examples/include_1.rb +15 -0
- data/ctioga/examples/noise.dat +100 -0
- data/ctioga/examples/noise.rb +13 -0
- data/ctioga/examples/trig.csv +100 -0
- data/ctioga/examples/trig.dat +100 -0
- data/ctioga/examples/trig.rb +14 -0
- data/ctioga/examples/trigh.dat +100 -0
- data/ctioga/examples/trigh.rb +10 -0
- data/ctioga/examples/tutorial +763 -0
- data/ctioga/examples/tutorial.sh +269 -0
- data/ctioga/tests/README +14 -0
- data/ctioga/tests/axes.sh +40 -0
- data/ctioga/tests/basic.sh +11 -0
- data/ctioga/tests/draw.sh +24 -0
- data/ctioga/tests/histograms.sh +14 -0
- data/ctioga/tests/insets.sh +41 -0
- data/ctioga/tests/layouts.sh +29 -0
- data/ctioga/tests/legends.sh +113 -0
- data/ctioga/tests/styles.sh +43 -0
- data/ctioga/tests/test_style.sh +8 -0
- data/ctioga/tests/tests.sh +24 -0
- data/ctioga/tests/text_backend.sh +83 -0
- data/ctioga/tests/tioga_defaults.rb +18 -0
- data/lib/CTioga/axes.rb +904 -0
- data/lib/CTioga/backends.rb +88 -0
- data/lib/CTioga/boundaries.rb +224 -0
- data/lib/CTioga/ctable.rb +134 -0
- data/lib/CTioga/curve_style.rb +246 -0
- data/lib/CTioga/debug.rb +199 -0
- data/lib/CTioga/dimension.rb +133 -0
- data/lib/CTioga/elements.rb +17 -0
- data/lib/CTioga/elements/base.rb +84 -0
- data/lib/CTioga/elements/containers.rb +578 -0
- data/lib/CTioga/elements/curves.rb +368 -0
- data/lib/CTioga/elements/tioga_primitives.rb +440 -0
- data/lib/CTioga/layout.rb +595 -0
- data/lib/CTioga/legends.rb +29 -0
- data/lib/CTioga/legends/cmdline.rb +187 -0
- data/lib/CTioga/legends/item.rb +164 -0
- data/lib/CTioga/legends/style.rb +257 -0
- data/lib/CTioga/log.rb +73 -0
- data/lib/CTioga/movingarrays.rb +131 -0
- data/lib/CTioga/partition.rb +271 -0
- data/lib/CTioga/plot_style.rb +230 -0
- data/lib/CTioga/plotmaker.rb +1677 -0
- data/lib/CTioga/shortcuts.rb +69 -0
- data/lib/CTioga/structures.rb +82 -0
- data/lib/CTioga/styles.rb +140 -0
- data/lib/CTioga/themes.rb +581 -0
- data/lib/CTioga/themes/classical.rb +82 -0
- data/lib/CTioga/themes/demo.rb +63 -0
- data/lib/CTioga/themes/fits.rb +91 -0
- data/lib/CTioga/themes/mono.rb +33 -0
- data/lib/CTioga/tioga.rb +32 -0
- data/lib/CTioga/utils.rb +173 -0
- data/lib/MetaBuilder/Parameters/dates.rb +38 -0
- data/lib/MetaBuilder/Parameters/lists.rb +132 -0
- data/lib/MetaBuilder/Parameters/numbers.rb +69 -0
- data/lib/MetaBuilder/Parameters/strings.rb +86 -0
- data/lib/MetaBuilder/Parameters/styles.rb +75 -0
- data/lib/MetaBuilder/Qt4/Parameters/dates.rb +51 -0
- data/lib/MetaBuilder/Qt4/Parameters/numbers.rb +65 -0
- data/lib/MetaBuilder/Qt4/Parameters/strings.rb +106 -0
- data/lib/MetaBuilder/Qt4/parameter.rb +172 -0
- data/lib/MetaBuilder/Qt4/parameters.rb +9 -0
- data/lib/MetaBuilder/descriptions.rb +603 -0
- data/lib/MetaBuilder/factory.rb +101 -0
- data/lib/MetaBuilder/group.rb +57 -0
- data/lib/MetaBuilder/metabuilder.rb +10 -0
- data/lib/MetaBuilder/parameter.rb +374 -0
- data/lib/MetaBuilder/parameters.rb +11 -0
- data/lib/MetaBuilder/qt4.rb +8 -0
- data/lib/SciYAG/Backends/backend.rb +379 -0
- data/lib/SciYAG/Backends/binner.rb +168 -0
- data/lib/SciYAG/Backends/cache.rb +102 -0
- data/lib/SciYAG/Backends/dataset.rb +158 -0
- data/lib/SciYAG/Backends/descriptions.rb +469 -0
- data/lib/SciYAG/Backends/filters.rb +25 -0
- data/lib/SciYAG/Backends/filters/average.rb +134 -0
- data/lib/SciYAG/Backends/filters/cumulate.rb +37 -0
- data/lib/SciYAG/Backends/filters/filter.rb +70 -0
- data/lib/SciYAG/Backends/filters/norm.rb +39 -0
- data/lib/SciYAG/Backends/filters/smooth.rb +63 -0
- data/lib/SciYAG/Backends/filters/sort.rb +43 -0
- data/lib/SciYAG/Backends/filters/strip.rb +34 -0
- data/lib/SciYAG/Backends/filters/trim.rb +64 -0
- data/lib/SciYAG/Backends/gnuplot.rb +131 -0
- data/lib/SciYAG/Backends/math.rb +108 -0
- data/lib/SciYAG/Backends/mdb.rb +462 -0
- data/lib/SciYAG/Backends/multitext.rb +96 -0
- data/lib/SciYAG/Backends/source.rb +64 -0
- data/lib/SciYAG/Backends/text.rb +339 -0
- data/lib/SciYAG/backends.rb +16 -0
- 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
|