ctioga2 0.0
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.
- 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,351 @@
|
|
|
1
|
+
# factory.rb: an object in charge of generating the style for Curves
|
|
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
|
+
# This module contains all the classes used by ctioga
|
|
18
|
+
module CTioga2
|
|
19
|
+
|
|
20
|
+
Version::register_svn_info('$Revision: 59 $', '$Date: 2009-05-28 23:15:50 +0200 (Thu, 28 May 2009) $')
|
|
21
|
+
|
|
22
|
+
module Graphics
|
|
23
|
+
|
|
24
|
+
module Styles
|
|
25
|
+
|
|
26
|
+
# This object is in charge of the generation of the CurveStyle
|
|
27
|
+
# object for the next curve to be drawn.
|
|
28
|
+
class CurveStyleFactory
|
|
29
|
+
|
|
30
|
+
include Log
|
|
31
|
+
|
|
32
|
+
# A private class that defines a parameter for the Factory
|
|
33
|
+
class CurveStyleFactoryParameter
|
|
34
|
+
|
|
35
|
+
# The code-like name of the parameter
|
|
36
|
+
attr_accessor :name
|
|
37
|
+
|
|
38
|
+
# The Commands::CommandType of the parameter
|
|
39
|
+
attr_accessor :type
|
|
40
|
+
|
|
41
|
+
# The pre-defined sets available to use with that
|
|
42
|
+
# parameter. It is a hash.
|
|
43
|
+
attr_accessor :sets
|
|
44
|
+
|
|
45
|
+
# The description of the parameter.
|
|
46
|
+
attr_accessor :description
|
|
47
|
+
|
|
48
|
+
# The short option for setting the parameter directly from
|
|
49
|
+
# the command-line.
|
|
50
|
+
attr_accessor :short_option
|
|
51
|
+
|
|
52
|
+
# The MetaBuilder::Type object that can convert a String to
|
|
53
|
+
# an Array suitable for use with CircularArray.
|
|
54
|
+
attr_accessor :sets_type
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
# Creates a new CurveStyleFactoryParameter object.
|
|
58
|
+
def initialize(name, type, sets, description,
|
|
59
|
+
short_option = nil)
|
|
60
|
+
@name = name
|
|
61
|
+
@type = Commands::CommandType.get_type(type)
|
|
62
|
+
@sets = sets
|
|
63
|
+
@description = description
|
|
64
|
+
@short_option = short_option
|
|
65
|
+
|
|
66
|
+
# TODO: it is not very satisfying to mix CommandTypes and
|
|
67
|
+
# MetaBuilder::Type on the same level.
|
|
68
|
+
if @sets
|
|
69
|
+
@sets_type =
|
|
70
|
+
MetaBuilder::Type.get_type({
|
|
71
|
+
:type => :set,
|
|
72
|
+
:subtype => @type.type,
|
|
73
|
+
:shortcuts => @sets
|
|
74
|
+
})
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Returns a suitable default set for the given object.
|
|
79
|
+
def default_set
|
|
80
|
+
return nil unless @sets
|
|
81
|
+
if @sets.key? 'default'
|
|
82
|
+
return @sets['default']
|
|
83
|
+
else
|
|
84
|
+
@sets.each do |k,v|
|
|
85
|
+
return v
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Switch some parameter back to automatic
|
|
93
|
+
AutoRE = /auto/i
|
|
94
|
+
|
|
95
|
+
# Sets some parameter to _false_.
|
|
96
|
+
DisableRE = /no(ne)?|off/i
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
# Creates a new parameter for the style factory.
|
|
101
|
+
def self.define_parameter(target, name, type, sets, description,
|
|
102
|
+
short_option = nil)
|
|
103
|
+
# We define two new types:
|
|
104
|
+
# - first, the color-or-auto type:
|
|
105
|
+
base_type = Commands::CommandType.get_type(type)
|
|
106
|
+
|
|
107
|
+
if ! Commands::Interpreter.type("#{base_type.name}-or-auto")
|
|
108
|
+
mb_type = base_type.type.dup
|
|
109
|
+
mb_type.re_shortcuts = (mb_type.re_shortcuts ?
|
|
110
|
+
mb_type.re_shortcuts.dup : {})
|
|
111
|
+
|
|
112
|
+
mb_type.re_shortcuts[AutoRE] = 'auto'
|
|
113
|
+
mb_type.re_shortcuts[DisableRE] = false
|
|
114
|
+
|
|
115
|
+
# Now, register a type for the type or automatic.
|
|
116
|
+
CmdType.new("#{base_type.name}-or-auto", mb_type,
|
|
117
|
+
"Same thing as type #{base_type.name}, or 'auto'")
|
|
118
|
+
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
if sets and ! Commands::Interpreter.type("#{base_type.name}-set")
|
|
122
|
+
# Now, register a type for the type or automatic.
|
|
123
|
+
CmdType.new("#{base_type.name}-set",{
|
|
124
|
+
:type => :set,
|
|
125
|
+
:subtype => base_type.type,
|
|
126
|
+
:shortcuts => sets
|
|
127
|
+
} ,
|
|
128
|
+
"Sets of #{base_type.name}")
|
|
129
|
+
end
|
|
130
|
+
param =
|
|
131
|
+
CurveStyleFactoryParameter.new(name, type, sets,
|
|
132
|
+
description, short_option)
|
|
133
|
+
@parameters ||= {}
|
|
134
|
+
@parameters[target] = param
|
|
135
|
+
|
|
136
|
+
@name_to_target ||= {}
|
|
137
|
+
@name_to_target[name] = target
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Returns the Hash containing the class parameters.
|
|
141
|
+
def self.parameters
|
|
142
|
+
return @parameters || {}
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
# Returns the Hash containing the class parameters.
|
|
147
|
+
def self.name_to_target
|
|
148
|
+
return @name_to_target
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# The CmdGroup for stylistic information about
|
|
152
|
+
# curves.
|
|
153
|
+
CurveStyleGroup =
|
|
154
|
+
CmdGroup.new('curve-style', "Curve styles",
|
|
155
|
+
"Set stylistic details about curves", 1)
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
# Creates two commands for each parameter of the object:
|
|
159
|
+
# * a command to set the override
|
|
160
|
+
# * a command to choose the sets.
|
|
161
|
+
def self.create_commands
|
|
162
|
+
parameters.each do |target, param|
|
|
163
|
+
override_cmd =
|
|
164
|
+
Cmd.new("#{param.name}",
|
|
165
|
+
param.short_option,
|
|
166
|
+
"--#{param.name}",
|
|
167
|
+
[
|
|
168
|
+
CmdArg.new("#{param.type.name}-or-auto")
|
|
169
|
+
], {},
|
|
170
|
+
"Sets the #{param.description} for subsequent curves",
|
|
171
|
+
"Sets the #{param.description} for subsequent curves, until cancelled with 'auto' as argument.", CurveStyleGroup) do |plotmaker, value|
|
|
172
|
+
plotmaker.curve_generator.style_factory.
|
|
173
|
+
set_parameter_override(target, value)
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
if param.sets
|
|
177
|
+
set_cmd =
|
|
178
|
+
Cmd.new("#{param.name}-set",
|
|
179
|
+
nil,
|
|
180
|
+
"--#{param.name}-set",
|
|
181
|
+
[
|
|
182
|
+
CmdArg.new("#{param.type.name}-set")
|
|
183
|
+
], {},
|
|
184
|
+
"Chooses a set for the #{param.description} of subsequent curves",
|
|
185
|
+
"Chooses a set for the #{param.description} of subsequent curves",
|
|
186
|
+
CurveStyleGroup) do |plotmaker, value|
|
|
187
|
+
plotmaker.curve_generator.style_factory.
|
|
188
|
+
set_parameter_set(target, value)
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# This function returns a hash suitable for use with the plot
|
|
195
|
+
# command as optional arguments, that will end up as the
|
|
196
|
+
# _one_time_ hash in #next.
|
|
197
|
+
def self.plot_optional_arguments
|
|
198
|
+
args = {}
|
|
199
|
+
for option_name, param in @parameters
|
|
200
|
+
args[param.name] =
|
|
201
|
+
CmdArg.new(param.type)
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
# Here, we add the support for a /legend= option
|
|
205
|
+
args['legend'] = CmdArg.new('text')
|
|
206
|
+
@name_to_target['legend'] = 'legend'
|
|
207
|
+
|
|
208
|
+
return args
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
# A hash containing values that override default ones derived
|
|
213
|
+
# from the CircularArray objects.
|
|
214
|
+
attr_accessor :override_parameters
|
|
215
|
+
|
|
216
|
+
# A hash of CircularArray objects.
|
|
217
|
+
attr_accessor :parameter_carrays
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
# Creates a new CurveStyleFactory.
|
|
221
|
+
def initialize
|
|
222
|
+
# Overrides as in the first ctioga
|
|
223
|
+
@override_parameters = {
|
|
224
|
+
'line_style' => LineStyles::Solid,
|
|
225
|
+
'marker_marker' => false,
|
|
226
|
+
'marker_scale' => 0.5
|
|
227
|
+
}
|
|
228
|
+
@parameters_carrays = {}
|
|
229
|
+
for target, param in self.class.parameters
|
|
230
|
+
set = param.default_set
|
|
231
|
+
if set
|
|
232
|
+
@parameters_carrays[target] = CircularArray.new(set)
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
# Gets the style for the next curve. The _one_time_ hash
|
|
238
|
+
# contains values 'parameter name' (name, and not target) =>
|
|
239
|
+
# value that are used for this time only.
|
|
240
|
+
def next(one_time = {})
|
|
241
|
+
base = {}
|
|
242
|
+
for target, array in @parameters_carrays
|
|
243
|
+
base[target] = array.next
|
|
244
|
+
end
|
|
245
|
+
base.merge!(@override_parameters)
|
|
246
|
+
base.merge!(hash_name_to_target(one_time))
|
|
247
|
+
# TODO: here, resolve 'links', such as :->color ?
|
|
248
|
+
return CurveStyle.from_hash(base)
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
# Sets the override for the given parameter. This corresponds
|
|
254
|
+
# to fixing manually the corresponding element until the
|
|
255
|
+
# override is removed, by a call with a _value_ that matches
|
|
256
|
+
# AutoRE.
|
|
257
|
+
#
|
|
258
|
+
# The _value_ should ideally be a String that is further
|
|
259
|
+
# converted to the appropriate type. Non-string objects will
|
|
260
|
+
# be left untouched.
|
|
261
|
+
def set_parameter_override(target, value)
|
|
262
|
+
param = get_parameter(target)
|
|
263
|
+
# Perform automatic type conversion only on strings.
|
|
264
|
+
if value.is_a? String
|
|
265
|
+
if value =~ AutoRE
|
|
266
|
+
@override_parameters.delete(target)
|
|
267
|
+
return
|
|
268
|
+
end
|
|
269
|
+
if value =~ DisableRE
|
|
270
|
+
value = false
|
|
271
|
+
else
|
|
272
|
+
value = param.type.string_to_type(value)
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
@override_parameters[target] = value
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
# Sets the CircularArray set corresponding to the named
|
|
280
|
+
def set_parameter_set(target, value)
|
|
281
|
+
param = get_parameter(target)
|
|
282
|
+
# Perform automatic type conversion only on strings.
|
|
283
|
+
if value.is_a? String
|
|
284
|
+
value = param.sets_type.string_to_type(value)
|
|
285
|
+
end
|
|
286
|
+
@parameters_carrays[target].set = value
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
# Now, the parameters:
|
|
290
|
+
define_parameter 'line_color', 'color', 'color',
|
|
291
|
+
Sets::ColorSets, "color", "-c"
|
|
292
|
+
|
|
293
|
+
define_parameter 'line_width', 'line-width', 'float',
|
|
294
|
+
Sets::LineWidthSets, "line width", nil
|
|
295
|
+
|
|
296
|
+
define_parameter 'line_style', 'line-style', 'line-style',
|
|
297
|
+
Sets::LineStyleSets, "line style", nil
|
|
298
|
+
|
|
299
|
+
define_parameter 'marker_marker', 'marker', 'marker',
|
|
300
|
+
Sets::MarkerSets, "marker", '-m'
|
|
301
|
+
|
|
302
|
+
define_parameter 'marker_color', 'marker-color', 'color',
|
|
303
|
+
Sets::ColorSets, "marker color", nil
|
|
304
|
+
|
|
305
|
+
define_parameter 'marker_scale', 'marker-scale', 'float',
|
|
306
|
+
Sets::LineWidthSets, "marker scale", nil
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
# And finally, we register all necessary commands...
|
|
310
|
+
create_commands
|
|
311
|
+
|
|
312
|
+
# A constant suitable for use as the optional arguments of the
|
|
313
|
+
# plot command.
|
|
314
|
+
PlotCommandOptions = plot_optional_arguments
|
|
315
|
+
|
|
316
|
+
protected
|
|
317
|
+
|
|
318
|
+
# Returns the CurveFactoryParameterType object corresponding
|
|
319
|
+
# to the named parameter.
|
|
320
|
+
def get_parameter(target)
|
|
321
|
+
if ! parameters.key? target
|
|
322
|
+
raise "Unkown parameter: #{target}"
|
|
323
|
+
else
|
|
324
|
+
return parameters[target]
|
|
325
|
+
end
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
# Returns the class parameters hash
|
|
329
|
+
def parameters
|
|
330
|
+
return self.class.parameters
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
# Converts the one-time parameters, which is a hash whose keys
|
|
334
|
+
# are the names of the parameters to targets.
|
|
335
|
+
def hash_name_to_target(h)
|
|
336
|
+
retval = {}
|
|
337
|
+
convert = self.class.name_to_target
|
|
338
|
+
for k,v in h
|
|
339
|
+
if convert.key? k
|
|
340
|
+
retval[convert[k]] = v
|
|
341
|
+
else
|
|
342
|
+
warn "Unkown key for hash_name_to_target: #{k}"
|
|
343
|
+
end
|
|
344
|
+
end
|
|
345
|
+
return retval
|
|
346
|
+
end
|
|
347
|
+
end
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
end
|
|
351
|
+
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# legend.rb: style 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/utils'
|
|
15
|
+
require 'ctioga2/log'
|
|
16
|
+
|
|
17
|
+
# This module contains all the classes used by ctioga
|
|
18
|
+
module CTioga2
|
|
19
|
+
|
|
20
|
+
Version::register_svn_info('$Revision: 55 $', '$Date: 2009-05-27 00:01:34 +0200 (Wed, 27 May 2009) $')
|
|
21
|
+
|
|
22
|
+
module Graphics
|
|
23
|
+
|
|
24
|
+
module Styles
|
|
25
|
+
|
|
26
|
+
# Style of a given Legends::LegendStorage object.
|
|
27
|
+
class LegendStorageStyle < BasicStyle
|
|
28
|
+
|
|
29
|
+
# The distance between two lines, a Types::Dimension object.
|
|
30
|
+
attr_accessor :dy
|
|
31
|
+
|
|
32
|
+
# The width of the legend pictogram, a Types::Dimension object.
|
|
33
|
+
attr_accessor :picto_width
|
|
34
|
+
|
|
35
|
+
# The height of the legend pictogram, a Types::Dimension object.
|
|
36
|
+
attr_accessor :picto_height
|
|
37
|
+
|
|
38
|
+
# The distance between the legend pictogram and the text
|
|
39
|
+
attr_accessor :picto_to_text
|
|
40
|
+
|
|
41
|
+
# The scale of the legend
|
|
42
|
+
attr_accessor :scale
|
|
43
|
+
|
|
44
|
+
# The scale of the legend text -- relative to the overall
|
|
45
|
+
# scale.
|
|
46
|
+
attr_accessor :text_scale
|
|
47
|
+
|
|
48
|
+
def initialize
|
|
49
|
+
@dy = Types::Dimension.new(:dy, 1.6, :y)
|
|
50
|
+
|
|
51
|
+
@picto_width = Types::Dimension.new(:dy, 1.6, :x)
|
|
52
|
+
@picto_height = Types::Dimension.new(:dy, 0.6, :y)
|
|
53
|
+
|
|
54
|
+
@picto_to_text = Types::Dimension.new(:dy, 0.3, :x)
|
|
55
|
+
|
|
56
|
+
@scale = 0.8
|
|
57
|
+
@text_scale = 0.82
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
# plot.rb: the style of a plot object.
|
|
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
|
+
# This module contains all the classes used by ctioga
|
|
20
|
+
module CTioga2
|
|
21
|
+
|
|
22
|
+
Version::register_svn_info('$Revision: 94 $', '$Date: 2009-06-25 23:37:13 +0200 (Thu, 25 Jun 2009) $')
|
|
23
|
+
|
|
24
|
+
module Graphics
|
|
25
|
+
|
|
26
|
+
module Styles
|
|
27
|
+
|
|
28
|
+
# The style of a Elements::Subplot object.
|
|
29
|
+
#
|
|
30
|
+
# TODO: it should hold
|
|
31
|
+
# * labels
|
|
32
|
+
# * axes and edges (in a *clean* way !)
|
|
33
|
+
# * ticks
|
|
34
|
+
# * background (uniform fill + watermark if applicable + possibly
|
|
35
|
+
# a picture .?)
|
|
36
|
+
class PlotStyle
|
|
37
|
+
|
|
38
|
+
include Tioga::FigureConstants
|
|
39
|
+
|
|
40
|
+
# The various sides of the plot. A hash location -> AxisStyle.
|
|
41
|
+
attr_accessor :axes
|
|
42
|
+
|
|
43
|
+
# The default location of the X axis (well, mainly, the X label)
|
|
44
|
+
attr_accessor :xaxis_location
|
|
45
|
+
|
|
46
|
+
# The default location of the Y axis (well, mainly, the Y label)
|
|
47
|
+
attr_accessor :yaxis_location
|
|
48
|
+
|
|
49
|
+
# The title of the plot
|
|
50
|
+
attr_accessor :title
|
|
51
|
+
|
|
52
|
+
# A margin to be left around the data points
|
|
53
|
+
attr_accessor :plot_margin
|
|
54
|
+
|
|
55
|
+
# Coordinate tranforms
|
|
56
|
+
attr_accessor :transforms
|
|
57
|
+
|
|
58
|
+
# Style of the background of the plot
|
|
59
|
+
attr_accessor :background
|
|
60
|
+
|
|
61
|
+
# Scale of the lines of the plot. The plot is wrapped in a
|
|
62
|
+
# t.rescale_lines call.
|
|
63
|
+
attr_accessor :lines_scale
|
|
64
|
+
|
|
65
|
+
# Scale of the text of the plot. The plot is wrapped in a
|
|
66
|
+
# t.rescale_text call.
|
|
67
|
+
attr_accessor :text_scale
|
|
68
|
+
|
|
69
|
+
# A padding around the box when automatic spacing is in auto
|
|
70
|
+
# mode. A Dimension.
|
|
71
|
+
attr_accessor :padding
|
|
72
|
+
|
|
73
|
+
def initialize
|
|
74
|
+
# Default style for the plots.
|
|
75
|
+
@axes = {}
|
|
76
|
+
@axes[:left] = AxisStyle.new(:left,
|
|
77
|
+
AXIS_WITH_TICKS_AND_NUMERIC_LABELS,
|
|
78
|
+
'$y$')
|
|
79
|
+
@axes[:bottom] = AxisStyle.new(:bottom,
|
|
80
|
+
AXIS_WITH_TICKS_AND_NUMERIC_LABELS,
|
|
81
|
+
'$x$')
|
|
82
|
+
|
|
83
|
+
@axes[:right] = AxisStyle.new(:right, AXIS_WITH_TICKS_ONLY)
|
|
84
|
+
@axes[:top] = AxisStyle.new(:top, AXIS_WITH_TICKS_ONLY)
|
|
85
|
+
|
|
86
|
+
@xaxis_location = :bottom
|
|
87
|
+
@yaxis_location = :left
|
|
88
|
+
|
|
89
|
+
@title = TextLabel.new
|
|
90
|
+
@title.loc = :top
|
|
91
|
+
|
|
92
|
+
@plot_margin = nil
|
|
93
|
+
|
|
94
|
+
@transforms = CoordinateTransforms.new
|
|
95
|
+
|
|
96
|
+
@background = BackgroundStyle.new
|
|
97
|
+
|
|
98
|
+
# A padding of 4bp ? Why ?? Why not ?
|
|
99
|
+
@padding = Types::Dimension.new(:bp, 4)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Whether to use log scale for the given axis.
|
|
103
|
+
#
|
|
104
|
+
# Now the question is: how should that affect user-defined
|
|
105
|
+
# axes ? It should not.
|
|
106
|
+
def set_log_scale(which, val)
|
|
107
|
+
case which
|
|
108
|
+
when :x
|
|
109
|
+
@axes[:top].log = val
|
|
110
|
+
@axes[:bottom].log = val
|
|
111
|
+
@transforms.x_log = val
|
|
112
|
+
when :y
|
|
113
|
+
@axes[:left].log = val
|
|
114
|
+
@axes[:right].log = val
|
|
115
|
+
@transforms.y_log = val
|
|
116
|
+
else
|
|
117
|
+
raise "Unknown axis: #{which.inspect}"
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Returns the AxisStyle corresponding to the named
|
|
122
|
+
# axis. _name_ can be:
|
|
123
|
+
# * one of the named elements of axes (ie, by default: top,
|
|
124
|
+
# left, right, bottom). All names are stripped from spaces
|
|
125
|
+
# around, and downcased (see #clean_axis_name).
|
|
126
|
+
# * x(axis)?/y(axis)?, which returns the default object for the
|
|
127
|
+
# given location
|
|
128
|
+
def get_axis_style(name)
|
|
129
|
+
if name =~ /^\s*([xy])(?:axis)?\s*$/i
|
|
130
|
+
return @axes[self.send("#{$1.downcase}axis_location")]
|
|
131
|
+
else
|
|
132
|
+
style = @axes[clean_axis_name(name)]
|
|
133
|
+
if ! style
|
|
134
|
+
raise "Unkown named axis: '#{name}'"
|
|
135
|
+
else
|
|
136
|
+
return style
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Returns a BaseTextStyle or similar for the given
|
|
142
|
+
# location. The location is of the form:
|
|
143
|
+
# axis_name(_(ticks?|label))
|
|
144
|
+
# or
|
|
145
|
+
# title
|
|
146
|
+
#
|
|
147
|
+
# If neither label nor ticks is specified in the first form,
|
|
148
|
+
# ticks are implied.
|
|
149
|
+
def get_label_style(location)
|
|
150
|
+
if location =~ /^\s*title\s*$/
|
|
151
|
+
return @title
|
|
152
|
+
end
|
|
153
|
+
location =~ /^\s*(.*?)(?:_(ticks?|label))?\s*$/i
|
|
154
|
+
which = $2
|
|
155
|
+
axis = get_axis_style($1)
|
|
156
|
+
if which =~ /label/
|
|
157
|
+
return axis.axis_label
|
|
158
|
+
else
|
|
159
|
+
return axis.tick_label_style
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Sets the style of the given label. Sets the text as well, if
|
|
164
|
+
# _text_ is not _nil_
|
|
165
|
+
def set_label_style(which, hash, text = nil)
|
|
166
|
+
style = get_label_style(which)
|
|
167
|
+
hash = hash.merge({'text' => text}) unless text.nil?
|
|
168
|
+
if hash.key?('text') and ! style.is_a?(TextLabel)
|
|
169
|
+
CTioga2::Log::warn("Text property of label #{which} was set, but this has no meaning: tick labels can't be set this way. Did you mean to use \"#{which}_label\"" + " instead ?")
|
|
170
|
+
end
|
|
171
|
+
style.set_from_hash(hash)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
# Draws all axes for the plot.
|
|
176
|
+
def draw_all_axes(t)
|
|
177
|
+
for which, axis in @axes
|
|
178
|
+
axis.draw_axis(t)
|
|
179
|
+
end
|
|
180
|
+
# We draw the title last
|
|
181
|
+
title.draw(t, 'title')
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# Draws all axes background lines for the plot.
|
|
185
|
+
def draw_all_background_lines(t)
|
|
186
|
+
for which, axis in @axes
|
|
187
|
+
axis.draw_background_lines(t)
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# Sets up the FigureMaker object for the plot. To be called
|
|
192
|
+
# just after the outermost context call for the concerned
|
|
193
|
+
# plot.
|
|
194
|
+
def setup_figure_maker(t)
|
|
195
|
+
if @lines_scale
|
|
196
|
+
t.rescale_lines(@lines_scale)
|
|
197
|
+
end
|
|
198
|
+
if @text_scale
|
|
199
|
+
t.rescale_text(@text_scale)
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
# Returns a deep copy of _self_, with all references stripped.
|
|
205
|
+
def deep_copy
|
|
206
|
+
return Marshal.load(Marshal.dump(self))
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# Returns the PlotStyle object of the current plot
|
|
210
|
+
def self.current_plot_style(plotmaker)
|
|
211
|
+
return plotmaker.root_object.current_plot.style
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
# Estimate the margins of the plot whose style this object
|
|
215
|
+
# controls. These margins are used when the plot margins are
|
|
216
|
+
# in automatic mode.
|
|
217
|
+
#
|
|
218
|
+
# Returns a Types::MarginsBox
|
|
219
|
+
def estimate_margins(t)
|
|
220
|
+
margins = [:left, :right, :top, :bottom].map do |side|
|
|
221
|
+
ext = @axes[side].extension(t,self)
|
|
222
|
+
if side == @title.loc
|
|
223
|
+
ext2 = @title.label_extension(t, 'title', side) *
|
|
224
|
+
(@text_scale || 1)
|
|
225
|
+
if ext < ext2
|
|
226
|
+
ext = ext2
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
Types::Dimension.new(:dy, ext)
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
# TODO: add the plot title !
|
|
233
|
+
box = Types::MarginsBox.new(*margins)
|
|
234
|
+
if @padding
|
|
235
|
+
for dim in box.margins
|
|
236
|
+
dim.replace_if_bigger(t, @padding)
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
return box
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
protected
|
|
243
|
+
|
|
244
|
+
# Takes a string and returns a Symbol suitable for use with
|
|
245
|
+
# the #axes hash (lower case without spaces).
|
|
246
|
+
def clean_axis_name(name)
|
|
247
|
+
if name.is_a?(::Symbol) # Argh ! Tioga redefined Symbol !
|
|
248
|
+
return name
|
|
249
|
+
end
|
|
250
|
+
name =~ /^\s*(.*?)\s*$/
|
|
251
|
+
return $1.downcase.to_sym
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
AxisGroup = CmdGroup.new('axes-labels',
|
|
257
|
+
"Axes and labels", "Axes and labels", 40)
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
AxisTypeCommands = []
|
|
262
|
+
[:left, :right, :top, :bottom].each do |loc|
|
|
263
|
+
AxisTypeCommands <<
|
|
264
|
+
Cmd.new("#{loc}",nil,"--#{loc}",
|
|
265
|
+
[
|
|
266
|
+
CmdArg.new('axis-decoration'),
|
|
267
|
+
], PartialAxisStyle) do |plotmaker, dec, opts|
|
|
268
|
+
style = AxisStyle.current_axis_style(plotmaker, loc)
|
|
269
|
+
style.decoration = dec
|
|
270
|
+
|
|
271
|
+
style.set_from_hash(opts)
|
|
272
|
+
end
|
|
273
|
+
AxisTypeCommands.last.
|
|
274
|
+
describe("Sets the type of the #{loc} axis",
|
|
275
|
+
<<"EOH", AxisGroup)
|
|
276
|
+
Sets the type of the #{loc} axis.
|
|
277
|
+
EOH
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
AxisStyleCommand =
|
|
281
|
+
Cmd.new("axis-style",nil,"--axis-style",
|
|
282
|
+
[
|
|
283
|
+
CmdArg.new('axis'),
|
|
284
|
+
], FullAxisStyle) do |plotmaker, which, opts|
|
|
285
|
+
style = AxisStyle.current_axis_style(plotmaker, which)
|
|
286
|
+
style.set_from_hash(opts)
|
|
287
|
+
end
|
|
288
|
+
AxisStyleCommand.
|
|
289
|
+
describe("Sets the style of the given axis",
|
|
290
|
+
<<"EOH", AxisGroup)
|
|
291
|
+
This command can be used to set various aspects of the style of the
|
|
292
|
+
given axis, through its various options:
|
|
293
|
+
* decoration
|
|
294
|
+
EOH
|
|
295
|
+
|
|
296
|
+
BackgroundLinesCommands =
|
|
297
|
+
Cmd.new('background-lines', nil, '--background-lines',
|
|
298
|
+
[
|
|
299
|
+
CmdArg.new('axis'),
|
|
300
|
+
CmdArg.new('color-or-false')
|
|
301
|
+
],{
|
|
302
|
+
'style' => CmdArg.new('line-style'),
|
|
303
|
+
'width' => CmdArg.new('float')
|
|
304
|
+
}) do |plotmaker, which, color, options|
|
|
305
|
+
axis = AxisStyle.current_axis_style(plotmaker, which)
|
|
306
|
+
if color
|
|
307
|
+
style = {'color' => color}
|
|
308
|
+
style.merge!(options)
|
|
309
|
+
if axis.background_lines
|
|
310
|
+
axis.background_lines.set_from_hash(style)
|
|
311
|
+
else
|
|
312
|
+
axis.background_lines = StrokeStyle.from_hash(style)
|
|
313
|
+
end
|
|
314
|
+
else
|
|
315
|
+
axis.background_lines = false
|
|
316
|
+
end
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
BackgroundLinesCommands.
|
|
320
|
+
describe("Sets the color of the background lines",
|
|
321
|
+
<<"EOH", AxisGroup)
|
|
322
|
+
Sets the color of the background lines for the given axis.
|
|
323
|
+
EOH
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
XAxisLabelCommand =
|
|
327
|
+
Cmd.new('xlabel', '-x', '--xlabel', [ CmdArg.new('text') ],
|
|
328
|
+
FullTextStyleOptions) do |plotmaker, label, options|
|
|
329
|
+
PlotStyle.current_plot_style(plotmaker).
|
|
330
|
+
set_label_style('x_label', options, label)
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
XAxisLabelCommand.describe("Sets the X label of the plot",
|
|
334
|
+
<<"EOH", AxisGroup)
|
|
335
|
+
Sets the X label of the current plot.
|
|
336
|
+
EOH
|
|
337
|
+
|
|
338
|
+
NoXAxisLabelCommand =
|
|
339
|
+
Cmd.new('no-xlabel', nil, '--no-xlabel', []) do |plotmaker|
|
|
340
|
+
PlotStyle.current_plot_style(plotmaker).
|
|
341
|
+
set_label_style('x_label', {}, false)
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
NoXAxisLabelCommand.describe("Disables X label for the plot",
|
|
345
|
+
<<"EOH", AxisGroup)
|
|
346
|
+
Disables the X label for the current plot.
|
|
347
|
+
EOH
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
YAxisLabelCommand =
|
|
351
|
+
Cmd.new('ylabel', '-y', '--ylabel', [ CmdArg.new('text') ],
|
|
352
|
+
FullTextStyleOptions) do |plotmaker, label, options|
|
|
353
|
+
PlotStyle.current_plot_style(plotmaker).
|
|
354
|
+
set_label_style('y_label', options, label)
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
YAxisLabelCommand.describe("Sets the Y label of the plot",
|
|
358
|
+
<<"EOH", AxisGroup)
|
|
359
|
+
Sets the Y label of the current plot.
|
|
360
|
+
EOH
|
|
361
|
+
|
|
362
|
+
NoYAxisLabelCommand =
|
|
363
|
+
Cmd.new('no-ylabel', nil, '--no-ylabel', []) do |plotmaker|
|
|
364
|
+
PlotStyle.current_plot_style(plotmaker).
|
|
365
|
+
set_label_style('y_label', {}, false)
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
NoYAxisLabelCommand.describe("Disables Y label for the plot",
|
|
369
|
+
<<"EOH", AxisGroup)
|
|
370
|
+
Disables the Y label for the current plot.
|
|
371
|
+
EOH
|
|
372
|
+
|
|
373
|
+
TitleLabelCommand =
|
|
374
|
+
Cmd.new('title', '-t', '--title', [ CmdArg.new('text') ],
|
|
375
|
+
FullTextStyleOptions) do |plotmaker, label, options|
|
|
376
|
+
PlotStyle.current_plot_style(plotmaker).
|
|
377
|
+
set_label_style('title', options, label)
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
TitleLabelCommand.describe("Sets the title of the plot",
|
|
381
|
+
<<"EOH", AxisGroup)
|
|
382
|
+
Sets the title of the current plot.
|
|
383
|
+
EOH
|
|
384
|
+
|
|
385
|
+
LabelStyleCommand =
|
|
386
|
+
Cmd.new('label-style', nil, '--label-style',
|
|
387
|
+
[ CmdArg.new('label') ], # Here: change the label too...
|
|
388
|
+
FullTextLabelOptions) do |plotmaker, which, options|
|
|
389
|
+
PlotStyle.current_plot_style(plotmaker).
|
|
390
|
+
set_label_style(which, options)
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
LabelStyleCommand.describe("Sets the style of the given label",
|
|
394
|
+
<<"EOH", AxisGroup)
|
|
395
|
+
Sets the style of the given label (see the type {type: label} for more
|
|
396
|
+
information).
|
|
397
|
+
|
|
398
|
+
The option text permits to also set the text of the label (does not
|
|
399
|
+
work for ticks).
|
|
400
|
+
|
|
401
|
+
For tick labels, setting the color option also sets the color for the
|
|
402
|
+
lines of the corresponding axis. If you don't want that, you can
|
|
403
|
+
override the color using the /stroke_color option of
|
|
404
|
+
{command: axis-style}. This will only work with Tioga version 1.11 or
|
|
405
|
+
greater.
|
|
406
|
+
EOH
|
|
407
|
+
|
|
408
|
+
end
|
|
409
|
+
end
|
|
410
|
+
end
|