ctioga2 0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +339 -0
- data/Changelog +6 -0
- data/bin/ctioga2 +26 -0
- data/lib/ctioga2/commands/arguments.rb +58 -0
- data/lib/ctioga2/commands/commands.rb +258 -0
- data/lib/ctioga2/commands/doc/doc.rb +118 -0
- data/lib/ctioga2/commands/doc/documentation-commands.rb +119 -0
- data/lib/ctioga2/commands/doc/help.rb +95 -0
- data/lib/ctioga2/commands/doc/html.rb +230 -0
- data/lib/ctioga2/commands/doc/introspection.rb +211 -0
- data/lib/ctioga2/commands/doc/man.rb +279 -0
- data/lib/ctioga2/commands/doc/markup.rb +359 -0
- data/lib/ctioga2/commands/general-commands.rb +119 -0
- data/lib/ctioga2/commands/general-types.rb +118 -0
- data/lib/ctioga2/commands/groups.rb +73 -0
- data/lib/ctioga2/commands/interpreter.rb +257 -0
- data/lib/ctioga2/commands/parsers/command-line.rb +187 -0
- data/lib/ctioga2/commands/parsers/file.rb +186 -0
- data/lib/ctioga2/commands/strings.rb +303 -0
- data/lib/ctioga2/commands/type.rb +100 -0
- data/lib/ctioga2/commands/variables.rb +101 -0
- data/lib/ctioga2/data/backends/backend.rb +260 -0
- data/lib/ctioga2/data/backends/backends.rb +39 -0
- data/lib/ctioga2/data/backends/backends/gnuplot.rb +140 -0
- data/lib/ctioga2/data/backends/backends/math.rb +121 -0
- data/lib/ctioga2/data/backends/backends/text.rb +335 -0
- data/lib/ctioga2/data/backends/description.rb +405 -0
- data/lib/ctioga2/data/backends/factory.rb +73 -0
- data/lib/ctioga2/data/backends/parameter.rb +109 -0
- data/lib/ctioga2/data/datacolumn.rb +245 -0
- data/lib/ctioga2/data/dataset.rb +233 -0
- data/lib/ctioga2/data/filters.rb +131 -0
- data/lib/ctioga2/data/merge.rb +43 -0
- data/lib/ctioga2/data/point.rb +72 -0
- data/lib/ctioga2/data/stack.rb +294 -0
- data/lib/ctioga2/graphics/coordinates.rb +73 -0
- data/lib/ctioga2/graphics/elements.rb +111 -0
- data/lib/ctioga2/graphics/elements/containers.rb +111 -0
- data/lib/ctioga2/graphics/elements/curve2d.rb +155 -0
- data/lib/ctioga2/graphics/elements/element.rb +90 -0
- data/lib/ctioga2/graphics/elements/primitive.rb +256 -0
- data/lib/ctioga2/graphics/elements/subplot.rb +140 -0
- data/lib/ctioga2/graphics/generator.rb +68 -0
- data/lib/ctioga2/graphics/legends.rb +108 -0
- data/lib/ctioga2/graphics/legends/area.rb +199 -0
- data/lib/ctioga2/graphics/legends/items.rb +183 -0
- data/lib/ctioga2/graphics/legends/provider.rb +58 -0
- data/lib/ctioga2/graphics/legends/storage.rb +65 -0
- data/lib/ctioga2/graphics/root.rb +209 -0
- data/lib/ctioga2/graphics/styles.rb +30 -0
- data/lib/ctioga2/graphics/styles/axes.rb +247 -0
- data/lib/ctioga2/graphics/styles/background.rb +122 -0
- data/lib/ctioga2/graphics/styles/base.rb +115 -0
- data/lib/ctioga2/graphics/styles/carrays.rb +53 -0
- data/lib/ctioga2/graphics/styles/curve.rb +101 -0
- data/lib/ctioga2/graphics/styles/drawable.rb +87 -0
- data/lib/ctioga2/graphics/styles/factory.rb +351 -0
- data/lib/ctioga2/graphics/styles/legend.rb +63 -0
- data/lib/ctioga2/graphics/styles/plot.rb +410 -0
- data/lib/ctioga2/graphics/styles/sets.rb +64 -0
- data/lib/ctioga2/graphics/styles/texts.rb +277 -0
- data/lib/ctioga2/graphics/subplot-commands.rb +141 -0
- data/lib/ctioga2/graphics/types.rb +188 -0
- data/lib/ctioga2/graphics/types/bijection.rb +79 -0
- data/lib/ctioga2/graphics/types/boundaries.rb +170 -0
- data/lib/ctioga2/graphics/types/boxes.rb +157 -0
- data/lib/ctioga2/graphics/types/dimensions.rb +157 -0
- data/lib/ctioga2/graphics/types/point.rb +247 -0
- data/lib/ctioga2/log.rb +97 -0
- data/lib/ctioga2/metabuilder/type.rb +316 -0
- data/lib/ctioga2/metabuilder/types.rb +39 -0
- data/lib/ctioga2/metabuilder/types/coordinates.rb +124 -0
- data/lib/ctioga2/metabuilder/types/dates.rb +43 -0
- data/lib/ctioga2/metabuilder/types/lists.rb +188 -0
- data/lib/ctioga2/metabuilder/types/numbers.rb +97 -0
- data/lib/ctioga2/metabuilder/types/strings.rb +93 -0
- data/lib/ctioga2/metabuilder/types/styles.rb +178 -0
- data/lib/ctioga2/plotmaker.rb +677 -0
- data/lib/ctioga2/postprocess.rb +115 -0
- data/lib/ctioga2/utils.rb +120 -0
- data/setup.rb +1586 -0
- metadata +144 -0
@@ -0,0 +1,68 @@
|
|
1
|
+
# root.rb: the root object for creating a plot.
|
2
|
+
# copyright (c) 2009 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/coordinates'
|
18
|
+
|
19
|
+
module CTioga2
|
20
|
+
|
21
|
+
Version::register_svn_info('$Revision: 2 $', '$Date: 2009-04-25 14:03:30 +0200 (Sat, 25 Apr 2009) $')
|
22
|
+
|
23
|
+
module Graphics
|
24
|
+
|
25
|
+
# This class is in charge of generating Elements::TiogaElement,
|
26
|
+
# such as Elements::Curve2D, from a dataset. It takes care of
|
27
|
+
# generating the appropriate style and of transforming the
|
28
|
+
# coordinates.
|
29
|
+
class CurveGenerator
|
30
|
+
|
31
|
+
# A Styles::CurveStyleFactory object that handles the
|
32
|
+
# styles for every single curve that will be drawn.
|
33
|
+
attr_accessor :style_factory
|
34
|
+
|
35
|
+
# The provider of legends, a Legends::LegendProvider
|
36
|
+
# object.
|
37
|
+
attr_accessor :legend_provider
|
38
|
+
|
39
|
+
# Creates a CurveGenerator object.
|
40
|
+
def initialize
|
41
|
+
@legend_provider = Legends::LegendProvider.new
|
42
|
+
@style_factory = Styles::CurveStyleFactory.new
|
43
|
+
end
|
44
|
+
|
45
|
+
# Creates a Elements::TiogaElement representing the _dataset_
|
46
|
+
# and returns it.
|
47
|
+
#
|
48
|
+
# TODO:
|
49
|
+
# * coordinate transformations
|
50
|
+
# * other kinds of curves (pseudo-3D, surfaces, histograms...)
|
51
|
+
def curve_from_dataset(plot, dataset, options = {})
|
52
|
+
legend = @legend_provider.dataset_legend(dataset)
|
53
|
+
style = @style_factory.next(options)
|
54
|
+
style.legend ||= legend # The legend specified as option to
|
55
|
+
# the --plot command has precedence
|
56
|
+
# over the one specified by --legend.
|
57
|
+
|
58
|
+
# TODO: copy datasets here !
|
59
|
+
plot.style.transforms.transform_2d!(dataset)
|
60
|
+
curve = Graphics::Elements::Curve2D.new(dataset, style)
|
61
|
+
return curve
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
@@ -0,0 +1,108 @@
|
|
1
|
+
# legends.rb: handling of legends
|
2
|
+
# copyright (c) 2009 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/graphics/types'
|
15
|
+
require 'ctioga2/graphics/legends/items'
|
16
|
+
require 'ctioga2/graphics/legends/area'
|
17
|
+
require 'ctioga2/graphics/legends/storage'
|
18
|
+
require 'ctioga2/graphics/legends/provider'
|
19
|
+
|
20
|
+
module CTioga2
|
21
|
+
|
22
|
+
Version::register_svn_info('$Revision: 68 $', '$Date: 2009-05-31 00:02:56 +0200 (Sun, 31 May 2009) $')
|
23
|
+
|
24
|
+
module Graphics
|
25
|
+
|
26
|
+
# Now, various commands pertaining to legends
|
27
|
+
|
28
|
+
LegendGroup = CmdGroup.new('legends', "Legends", <<EOD, 1)
|
29
|
+
Commands to specify legends and tweak their look.
|
30
|
+
EOD
|
31
|
+
|
32
|
+
NextLegendCommand =
|
33
|
+
Cmd.new("legend",'-l',"--legend",
|
34
|
+
[ CmdArg.new('text') ]) do |plotmaker, legend|
|
35
|
+
plotmaker.curve_generator.legend_provider.current_legend = legend
|
36
|
+
end
|
37
|
+
|
38
|
+
NextLegendCommand.describe("Sets the legend for the next dataset",
|
39
|
+
<<EOH, LegendGroup)
|
40
|
+
Sets the legend for the next dataset. Overridden by the legend= option
|
41
|
+
to the plot command.
|
42
|
+
EOH
|
43
|
+
|
44
|
+
LegendLineCommand =
|
45
|
+
Cmd.new("legend-line",nil,"--legend-line",
|
46
|
+
[ CmdArg.new('text') ],
|
47
|
+
Styles::FullTextStyleOptions) do |plotmaker, legend, opts|
|
48
|
+
l = Legends::LegendLine.new(legend, opts)
|
49
|
+
plotmaker.root_object.current_plot.add_legend_item(l)
|
50
|
+
end
|
51
|
+
|
52
|
+
LegendLineCommand.describe("Adds a pure text line to the legend",
|
53
|
+
<<EOH, LegendGroup)
|
54
|
+
Adds a line of text unrelated to any curve to the legend.
|
55
|
+
EOH
|
56
|
+
|
57
|
+
LegendInsideCommand =
|
58
|
+
Cmd.new("legend-inside", nil, "--legend-inside",
|
59
|
+
[ CmdArg.new('aligned-point')]) do |plotmaker, point|
|
60
|
+
l = Legends::LegendArea.new(:inside)
|
61
|
+
l.legend_position = point
|
62
|
+
plotmaker.root_object.current_plot.legend_area = l
|
63
|
+
end
|
64
|
+
|
65
|
+
LegendInsideCommand.describe("Draw legends inside the current plot",
|
66
|
+
<<EOH, LegendGroup)
|
67
|
+
When this option is in effect, all legends for the current plot (and
|
68
|
+
possibly subplots) are drawn inside the current plot, at the specified
|
69
|
+
position.
|
70
|
+
EOH
|
71
|
+
|
72
|
+
AutoLegendCommand =
|
73
|
+
Cmd.new("auto-legend",nil,"--auto-legend",
|
74
|
+
[ CmdArg.new('boolean') ]) do |plotmaker, value|
|
75
|
+
plotmaker.curve_generator.legend_provider.auto_legend = value
|
76
|
+
end
|
77
|
+
|
78
|
+
AutoLegendCommand.describe("Automatically give legends to datasets",
|
79
|
+
<<EOH, LegendGroup)
|
80
|
+
When this option is in effect (off by default), all datasets get a legend,
|
81
|
+
their 'dataset name', unless another legend is manually specified.
|
82
|
+
EOH
|
83
|
+
|
84
|
+
LegendStyleOptions = {
|
85
|
+
'dy' => CmdArg.new('dimension'),
|
86
|
+
'scale' => CmdArg.new('float'),
|
87
|
+
'text_scale' => CmdArg.new('float'),
|
88
|
+
}
|
89
|
+
|
90
|
+
|
91
|
+
LegendStyleCommand =
|
92
|
+
Cmd.new("legend-style",nil,"--legend-style",
|
93
|
+
[], LegendStyleOptions) do |plotmaker, options|
|
94
|
+
plotmaker.root_object.current_legend_area.
|
95
|
+
legend_style.set_from_hash(options)
|
96
|
+
end
|
97
|
+
|
98
|
+
LegendStyleCommand.describe("Set the style of the legends",
|
99
|
+
<<EOH, LegendGroup)
|
100
|
+
Sets the various aspects of the style of the legends throught
|
101
|
+
its options:
|
102
|
+
* dy: the spacing between consecutive lines
|
103
|
+
* scale: the overall scale of the legends
|
104
|
+
* text_scale: the scale of the text (and the markers) inside the legends
|
105
|
+
EOH
|
106
|
+
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,199 @@
|
|
1
|
+
# storage.rb: an object holding legends
|
2
|
+
# copyright (c) 2009 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
|
+
module CTioga2
|
18
|
+
|
19
|
+
Version::register_svn_info('$Revision: 80 $', '$Date: 2009-06-09 23:56:44 +0200 (Tue, 09 Jun 2009) $')
|
20
|
+
|
21
|
+
module Graphics
|
22
|
+
|
23
|
+
# This module holds all the classes dealing with legends
|
24
|
+
module Legends
|
25
|
+
|
26
|
+
# This class holds a series of legends for curves.
|
27
|
+
#
|
28
|
+
# TODO:
|
29
|
+
#
|
30
|
+
# * a legend can be plotted either inside a plot or outside the
|
31
|
+
# root object
|
32
|
+
#
|
33
|
+
# * in case it is plotted outside the root object, the user should
|
34
|
+
# be able to choose whether it should be counted in the
|
35
|
+
# real-size or not.
|
36
|
+
#
|
37
|
+
# * legends should provide all the kind of things that were in the
|
38
|
+
# first ctioga, such as background, frames, and so on...
|
39
|
+
#
|
40
|
+
# * legends could be organized as columns (especially at the
|
41
|
+
# bottom of the graph).
|
42
|
+
#
|
43
|
+
# * whenever a --legend-inside is specified, we create a private
|
44
|
+
# @legend_area for the current Elements::Container, with the
|
45
|
+
# given position.
|
46
|
+
#
|
47
|
+
# TODO: make a subclass for a top-level area ????
|
48
|
+
class LegendArea
|
49
|
+
|
50
|
+
# The style of the LegendStorage, a Styles::LegendStorageStyle
|
51
|
+
# object (of course)
|
52
|
+
attr_accessor :legend_style
|
53
|
+
|
54
|
+
# The type of the legend. Can be :left, :right, :top, :bottom
|
55
|
+
# or :inside
|
56
|
+
attr_accessor :legend_type
|
57
|
+
|
58
|
+
# The position of the LegendArea. Only significant when the
|
59
|
+
# type is :inside. A Types::AlignedPoint instance.
|
60
|
+
attr_accessor :legend_position
|
61
|
+
|
62
|
+
def initialize(type = :right)
|
63
|
+
@legend_style = Styles::LegendStorageStyle.new
|
64
|
+
@legend_type = type
|
65
|
+
@legend_position = Types::AlignedPoint.new(0.5,0.5,:frame)
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
# Draws the legend of the given container and all its
|
70
|
+
# subobjects. It assumes that the frames have been set
|
71
|
+
# according to the return value of #partition_frame
|
72
|
+
#
|
73
|
+
# TODO:
|
74
|
+
#
|
75
|
+
# * customization of the x and y of origin (y should match the
|
76
|
+
# top of the corresponding graph, if applicable)
|
77
|
+
#
|
78
|
+
# * add padding on the external side of the legend, if
|
79
|
+
# applicable ?
|
80
|
+
#
|
81
|
+
def display_legend(t, container)
|
82
|
+
items = container.legend_storage.harvest_contents
|
83
|
+
t.context do
|
84
|
+
t.rescale(@legend_style.scale)
|
85
|
+
t.rescale_text(@legend_style.text_scale)
|
86
|
+
|
87
|
+
# We make figure coordinates frame coordinates
|
88
|
+
t.set_bounds([0, 1, 1, 0])
|
89
|
+
# TODO: customize this !
|
90
|
+
x, y = initial_xy(t, container)
|
91
|
+
for item in items
|
92
|
+
# TODO: transform the 0.0 for x into a negative
|
93
|
+
# user-specifiable stuff.
|
94
|
+
item.draw(t, @legend_style, x , y)
|
95
|
+
y -= @legend_style.dy.to_figure(t,:y)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# Returns the total size of the legend as a
|
101
|
+
# [ width, height ]
|
102
|
+
# array in figure coordinates.
|
103
|
+
def size(t, container)
|
104
|
+
items = container.legend_storage.harvest_contents
|
105
|
+
width, height = 0,0
|
106
|
+
for item in items
|
107
|
+
w,h = item.size(t, @legend_style)
|
108
|
+
if w > width
|
109
|
+
width = w
|
110
|
+
end
|
111
|
+
# Hmmm... this is plain wrong...
|
112
|
+
# height += h
|
113
|
+
height += @legend_style.dy.to_figure(t,:y) *
|
114
|
+
@legend_style.scale * @legend_style.text_scale
|
115
|
+
end
|
116
|
+
return [ width, height ]
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
# Returns an enlarged page size that can accomodate for both
|
121
|
+
# the text and the legend.
|
122
|
+
def enlarged_page_size(t, container, width, height)
|
123
|
+
w, h = size(t, container)
|
124
|
+
case @legend_type
|
125
|
+
when :left, :right
|
126
|
+
return [width + t.convert_figure_to_output_dx(w)/10,
|
127
|
+
height]
|
128
|
+
when :top, :bottom
|
129
|
+
return [width, height + t.convert_figure_to_output_dy(h)/10]
|
130
|
+
when :inside
|
131
|
+
return [width, height]
|
132
|
+
end
|
133
|
+
raise "Unknown type: #{@legend_type}"
|
134
|
+
end
|
135
|
+
|
136
|
+
|
137
|
+
# Partitions the frame in two: the plot frame and the legend
|
138
|
+
# frame, according to various parameters:
|
139
|
+
# * the #type of the LegendArea
|
140
|
+
# * the #size of the legend.
|
141
|
+
#
|
142
|
+
# It returns two arrays:
|
143
|
+
#
|
144
|
+
# [ plot_margins, legend_margins]
|
145
|
+
#
|
146
|
+
# These arrays can be used as arguments for subframe_margins
|
147
|
+
# or respectively the graph and the legends part of the plot.
|
148
|
+
#
|
149
|
+
# This function will *eventually* also work in the case of a
|
150
|
+
# #legend_type :inside?
|
151
|
+
def partition_frame(t, container)
|
152
|
+
w,h = size(t, container)
|
153
|
+
case @legend_type
|
154
|
+
when :right
|
155
|
+
w = t.convert_figure_to_frame_dx(w)
|
156
|
+
return [ [0, w, 0, 0], [1 - w, 0, 0, 0]]
|
157
|
+
when :left
|
158
|
+
w = t.convert_figure_to_frame_dx(w)
|
159
|
+
return [ [w, 0, 0, 0], [0, 1 - w, 0, 0]]
|
160
|
+
when :inside
|
161
|
+
return [
|
162
|
+
[0, 0, 0, 0],
|
163
|
+
@legend_position.to_frame_margins(t, w, h)
|
164
|
+
]
|
165
|
+
else
|
166
|
+
raise "Unimplemented yet..."
|
167
|
+
end
|
168
|
+
|
169
|
+
end
|
170
|
+
|
171
|
+
protected
|
172
|
+
|
173
|
+
# Returns the X and Y values for the top left of the legend
|
174
|
+
# inside the legend frame. Depends on a lot of things,
|
175
|
+
# including the type of the legend.
|
176
|
+
def initial_xy(t, container)
|
177
|
+
case @legend_type
|
178
|
+
when :right
|
179
|
+
l,r,t,b = container.subframe.to_frame_margins(t)
|
180
|
+
# Here, we take profit from the fact that frame
|
181
|
+
# coordinates are also figure coordinates within the
|
182
|
+
# legend.
|
183
|
+
|
184
|
+
# TODO: that won't work in the case of labels on the
|
185
|
+
# right-hand-side.
|
186
|
+
return [- l/2, 1.0 - t]
|
187
|
+
when :inside
|
188
|
+
return [0.0, 1.0]
|
189
|
+
else
|
190
|
+
raise "Unimplemented yet..."
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|
199
|
+
|
@@ -0,0 +1,183 @@
|
|
1
|
+
# items.rb: individual legend items
|
2
|
+
# copyright (c) 2008,2009 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, but
|
10
|
+
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
12
|
+
# General Public License for more details (in the COPYING file).
|
13
|
+
|
14
|
+
require 'ctioga2/utils'
|
15
|
+
require 'ctioga2/log'
|
16
|
+
|
17
|
+
require 'ctioga2/graphics/styles'
|
18
|
+
|
19
|
+
module CTioga2
|
20
|
+
|
21
|
+
Version::register_svn_info('$Revision: 55 $', '$Date: 2009-05-27 00:01:34 +0200 (Wed, 27 May 2009) $')
|
22
|
+
|
23
|
+
module Graphics
|
24
|
+
|
25
|
+
module Legends
|
26
|
+
|
27
|
+
# All items that can be displayed in a legend derive from this
|
28
|
+
# one.
|
29
|
+
class LegendItem
|
30
|
+
|
31
|
+
# This class-wide variable is used to number text
|
32
|
+
# in a unique fashion
|
33
|
+
@@legend_item_numbering = 0
|
34
|
+
|
35
|
+
# Initializes the LegendItem. Children *must* call super to
|
36
|
+
# make sure the numbering is dealt with properly.
|
37
|
+
def initialize
|
38
|
+
@legend_number = @@legend_item_numbering
|
39
|
+
@@legend_item_numbering += 1
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns the (width, height) in figure coordinates of the
|
43
|
+
# legend element with the given Styles::LegendStyle and
|
44
|
+
# FigureMaker reference objects.
|
45
|
+
#
|
46
|
+
# The returned values can be inaccurate to some extent.
|
47
|
+
def size(t, legend_style)
|
48
|
+
return [0, 0]
|
49
|
+
end
|
50
|
+
|
51
|
+
# Draws the legend at the given top left position (_x_,_y_) in
|
52
|
+
# figure coordinates.
|
53
|
+
def draw(t, legend_style, x, y)
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
protected
|
58
|
+
|
59
|
+
# The internal name for the legend - one we can use in a
|
60
|
+
# get_text_size query.
|
61
|
+
def legend_name
|
62
|
+
return "legend-#{@legend_number}"
|
63
|
+
end
|
64
|
+
|
65
|
+
# Returns the _y_ value for the baseline of the text in terms
|
66
|
+
# of figure coordinates.
|
67
|
+
def get_baseline_y(t, legend_style, y)
|
68
|
+
return y - Types::Dimension.new(:dy,1.0,:y).to_figure(t)
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
# A class representing the style of a single legend line
|
75
|
+
# (unrelated to a curve)
|
76
|
+
class LegendLine < LegendItem
|
77
|
+
|
78
|
+
# The text of the line
|
79
|
+
attr_accessor :text
|
80
|
+
|
81
|
+
# The style of the text, a Styles.FullTextStyle object.
|
82
|
+
attr_accessor :style
|
83
|
+
|
84
|
+
def initialize(text = "", style = {})
|
85
|
+
super()
|
86
|
+
@text = text
|
87
|
+
@style = Styles::FullTextStyle.from_hash(style)
|
88
|
+
@style.justification ||= Tioga::FigureConstants::LEFT_JUSTIFIED
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
# Draw one single text line.
|
93
|
+
def draw(t, legend_style, x, y)
|
94
|
+
y = get_baseline_y(t, legend_style, y)
|
95
|
+
@style.draw_text(t, @text, x, y, legend_name)
|
96
|
+
end
|
97
|
+
|
98
|
+
# Computes the size of the line. Height should always be
|
99
|
+
# accurate, but width can be 0 sometimes...
|
100
|
+
def size(t, legend_style)
|
101
|
+
height = legend_style.dy.to_figure(t)
|
102
|
+
|
103
|
+
width = 0.0
|
104
|
+
|
105
|
+
info = t.get_text_size(legend_name)
|
106
|
+
|
107
|
+
if info.key? 'width'
|
108
|
+
width += t.convert_output_to_figure_dx(10*info['width'])
|
109
|
+
end
|
110
|
+
|
111
|
+
return [ width, height ]
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
# The legend of a curve object, or rather, the legend
|
117
|
+
# corresponding to a given
|
118
|
+
#
|
119
|
+
# TODO: finish to adapt: use FullTextStyle to draw the objects.
|
120
|
+
class CurveLegend < LegendItem
|
121
|
+
|
122
|
+
include CTioga2::Log
|
123
|
+
|
124
|
+
attr_accessor :curve_style
|
125
|
+
|
126
|
+
def initialize(style)
|
127
|
+
super()
|
128
|
+
@curve_style = style
|
129
|
+
end
|
130
|
+
|
131
|
+
# Draw one single text line
|
132
|
+
#
|
133
|
+
# TODO: adapt here !
|
134
|
+
#
|
135
|
+
# TODO: _x_ and _y_ are not taken into account the way they should be.
|
136
|
+
def draw(t, legend_style, x, y)
|
137
|
+
y = get_baseline_y(t, legend_style, y)
|
138
|
+
t.context do
|
139
|
+
# Position specification for the legend pictogram
|
140
|
+
margin_specs = { 'left' => x,
|
141
|
+
'right' => 1 - x - legend_style.picto_width.to_figure(t),
|
142
|
+
'bottom' => y,
|
143
|
+
'top' => 1 - y - legend_style.picto_height.to_figure(t)
|
144
|
+
}
|
145
|
+
debug "Legend margins for '#{@curve_style.legend}' : #{margin_specs.inspect}"
|
146
|
+
t.subfigure(margin_specs) do
|
147
|
+
# We make the markers slightly smaller than the text
|
148
|
+
# around.
|
149
|
+
t.rescale_text(0.8)
|
150
|
+
@curve_style.draw_legend_pictogram(t)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
t.show_text('x' => x +
|
154
|
+
legend_style.picto_width.to_figure(t) +
|
155
|
+
legend_style.picto_to_text.to_figure(t),
|
156
|
+
'y' => y, 'text' => @curve_style.legend,
|
157
|
+
'measure' => legend_name,
|
158
|
+
'justification' => Tioga::FigureConstants::LEFT_JUSTIFIED)
|
159
|
+
end
|
160
|
+
|
161
|
+
# Computes the size of the line. Height should always
|
162
|
+
# be accurate, but width can be 0 sometimes...
|
163
|
+
def size(t, legend_style)
|
164
|
+
height = legend_style.dy.to_figure(t)
|
165
|
+
|
166
|
+
width = legend_style.picto_width.to_figure(t) +
|
167
|
+
legend_style.picto_to_text.to_figure(t)
|
168
|
+
|
169
|
+
info = t.get_text_size(legend_name)
|
170
|
+
|
171
|
+
if info.key? 'width'
|
172
|
+
width += t.convert_output_to_figure_dx(10*info['width'])
|
173
|
+
end
|
174
|
+
|
175
|
+
return [ width, height ]
|
176
|
+
end
|
177
|
+
|
178
|
+
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
end
|
183
|
+
end
|