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,58 @@
|
|
|
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
|
+
module CTioga2
|
|
18
|
+
|
|
19
|
+
Version::register_svn_info('$Revision: 2 $', '$Date: 2009-04-25 14:03:30 +0200 (Sat, 25 Apr 2009) $')
|
|
20
|
+
|
|
21
|
+
module Graphics
|
|
22
|
+
|
|
23
|
+
module Legends
|
|
24
|
+
|
|
25
|
+
# This class is in charge of providing a legend for the given
|
|
26
|
+
# dataset. Most of its job is simply to collect --legend
|
|
27
|
+
# arguments from the command-line.
|
|
28
|
+
class LegendProvider
|
|
29
|
+
|
|
30
|
+
# The legend to be used for the next curve, if applicable
|
|
31
|
+
attr_accessor :current_legend
|
|
32
|
+
|
|
33
|
+
# Whether we automatically give a name to curves or not.
|
|
34
|
+
attr_accessor :auto_legend
|
|
35
|
+
|
|
36
|
+
def initialize
|
|
37
|
+
@current_legend = nil
|
|
38
|
+
@auto_legend = false
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Returns a legend suitable for the next curve.
|
|
42
|
+
def dataset_legend(dataset)
|
|
43
|
+
if @current_legend
|
|
44
|
+
l = @current_legend
|
|
45
|
+
@current_legend = nil
|
|
46
|
+
return l
|
|
47
|
+
elsif @auto_legend
|
|
48
|
+
return dataset.name
|
|
49
|
+
else
|
|
50
|
+
return nil
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
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: 53 $', '$Date: 2009-05-20 01:05:32 +0200 (Wed, 20 May 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
|
+
class LegendStorage
|
|
28
|
+
|
|
29
|
+
# An array of LegendItem objects, in the order in which they
|
|
30
|
+
# should get displayed.
|
|
31
|
+
attr_accessor :contents
|
|
32
|
+
|
|
33
|
+
def initialize
|
|
34
|
+
@contents = []
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Adds a LegendItem or a Container to the LegendStorage
|
|
38
|
+
# object.
|
|
39
|
+
def add_item(item)
|
|
40
|
+
@contents << item
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Returns a flat array of LegendItem that belong to the same
|
|
44
|
+
# LegendArea as the object in which the LegendStorage was
|
|
45
|
+
# created.
|
|
46
|
+
def harvest_contents
|
|
47
|
+
retval = []
|
|
48
|
+
for el in @contents
|
|
49
|
+
if el.is_a? LegendItem
|
|
50
|
+
retval << el
|
|
51
|
+
elsif el.is_a? Elements::Container and
|
|
52
|
+
(not el.legend_area)
|
|
53
|
+
retval.concat(el.legend_storage.harvest_contents)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
return retval
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
end
|
|
65
|
+
|
|
@@ -0,0 +1,209 @@
|
|
|
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/elements'
|
|
18
|
+
require 'ctioga2/graphics/legends'
|
|
19
|
+
|
|
20
|
+
require 'ctioga2/graphics/subplot-commands'
|
|
21
|
+
|
|
22
|
+
module CTioga2
|
|
23
|
+
|
|
24
|
+
Version::register_svn_info('$Revision: 88 $', '$Date: 2009-06-17 00:10:31 +0200 (Wed, 17 Jun 2009) $')
|
|
25
|
+
|
|
26
|
+
# This module contains all graphical elements of CTioga2
|
|
27
|
+
module Graphics
|
|
28
|
+
|
|
29
|
+
# The root object of the plot. The PlotMaker has one object like
|
|
30
|
+
# that. It is the real object drawing the plot.
|
|
31
|
+
class RootObject
|
|
32
|
+
|
|
33
|
+
# The current Elements::Container of the object.
|
|
34
|
+
attr_accessor :current_container
|
|
35
|
+
|
|
36
|
+
# The top-level Legends::LegendArea. This one gets necessarily
|
|
37
|
+
# displayed on one of the sides of the graph.
|
|
38
|
+
attr_accessor :legend_area
|
|
39
|
+
|
|
40
|
+
# Whether top-level legends are part of the "real size" of the
|
|
41
|
+
# graph or outside the graph (easier to align anything)
|
|
42
|
+
attr_accessor :count_legend_in_page
|
|
43
|
+
|
|
44
|
+
# The page size of the graph, a [width,height] array.
|
|
45
|
+
attr_accessor :page_size
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def initialize
|
|
49
|
+
@current_container = nil
|
|
50
|
+
|
|
51
|
+
@container_stack = []
|
|
52
|
+
|
|
53
|
+
@legend_area = Legends::LegendArea.new
|
|
54
|
+
|
|
55
|
+
@count_legend_in_page = false
|
|
56
|
+
# @count_legend_in_page = true
|
|
57
|
+
|
|
58
|
+
# Page size:
|
|
59
|
+
set_page_size("12cmx12cm") # Same as old ctioga
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Returns the current Elements::Container, or create an
|
|
63
|
+
# Elements::Subplot if there isn't.
|
|
64
|
+
#
|
|
65
|
+
# This function should be used by all functions that add
|
|
66
|
+
# Elements::TiogaElement to plots (or modify plot's data, such
|
|
67
|
+
# as title, axes...).
|
|
68
|
+
def current_plot
|
|
69
|
+
if @current_container
|
|
70
|
+
return @current_container
|
|
71
|
+
else
|
|
72
|
+
subplot = Elements::Subplot.new(nil, self, nil)
|
|
73
|
+
enter_subobject(subplot)
|
|
74
|
+
return subplot
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Enters into a new Elements::Container, _new_object_.
|
|
79
|
+
def enter_subobject(new_object)
|
|
80
|
+
if @current_container
|
|
81
|
+
@current_container.add_element(new_object)
|
|
82
|
+
end
|
|
83
|
+
@current_container = new_object
|
|
84
|
+
@container_stack << @current_container
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Leaves a subobject.
|
|
88
|
+
def leave_subobject
|
|
89
|
+
if @container_stack.size == 1
|
|
90
|
+
raise "Trying to leave top-level object"
|
|
91
|
+
end
|
|
92
|
+
if @container_stack.pop != @current_container
|
|
93
|
+
raise "We have a serious problem here"
|
|
94
|
+
end
|
|
95
|
+
@current_container = @container_stack.last
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# The only top-level container of the graph.
|
|
99
|
+
def top_level_container
|
|
100
|
+
return @container_stack.first
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Sets the page of the object, from a pure text object, such as
|
|
104
|
+
# "12cmx12cm"
|
|
105
|
+
def set_page_size(size)
|
|
106
|
+
@page_size = size.split(/\s*x\s*/).collect {|s|
|
|
107
|
+
Tioga::Utils::tex_dimension_to_bp(s)
|
|
108
|
+
}
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
# Sets up the page width and other parameters for the given
|
|
113
|
+
# FigureMaker object. Must be within a figure object, so that
|
|
114
|
+
# potential modifications to the page size due to text objects
|
|
115
|
+
# (legends) can be taken into account.
|
|
116
|
+
def setup_page(t)
|
|
117
|
+
if @count_legend_in_page or ! draw_top_level_legend?
|
|
118
|
+
effective_size = @page_size
|
|
119
|
+
else
|
|
120
|
+
effective_size = @legend_area.
|
|
121
|
+
enlarged_page_size(t, top_level_container, *@page_size)
|
|
122
|
+
end
|
|
123
|
+
t.page_setup(*effective_size)
|
|
124
|
+
t.set_frame_sides(0,1,1,0)
|
|
125
|
+
|
|
126
|
+
# Setting label and title scale to 1
|
|
127
|
+
t.title_scale = 1
|
|
128
|
+
t.xlabel_scale = 1
|
|
129
|
+
t.ylabel_scale = 1
|
|
130
|
+
# TODO: I think this is mostly useless. Check.
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Creates a subplot of the current plot. If @current_container
|
|
134
|
+
# is null, create it as a Elements::Container: this will make it
|
|
135
|
+
# *easy* to create complex graphs (no need to disable axes and
|
|
136
|
+
# other kinds of stuff on the main plot).
|
|
137
|
+
#
|
|
138
|
+
# For the sake of convenience, returns the newly created
|
|
139
|
+
# Elements::Subplot
|
|
140
|
+
def subplot()
|
|
141
|
+
if ! @current_container
|
|
142
|
+
enter_subobject(Elements::Container.new(nil, self))
|
|
143
|
+
end
|
|
144
|
+
subplot = Elements::Subplot.new(@current_container, self, nil)
|
|
145
|
+
enter_subobject(subplot)
|
|
146
|
+
return subplot
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# Returns true if not a single drawable object has been pushed
|
|
150
|
+
# unto the RootObject yet.
|
|
151
|
+
def empty?
|
|
152
|
+
return @current_container.nil?
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# Draws this object onto an appropriate FigureMaker object.
|
|
156
|
+
def draw_root_object(t)
|
|
157
|
+
setup_page(t)
|
|
158
|
+
if top_level_container
|
|
159
|
+
|
|
160
|
+
plot_margins, legend_margins =
|
|
161
|
+
if draw_top_level_legend?
|
|
162
|
+
@legend_area.partition_frame(t, top_level_container)
|
|
163
|
+
else
|
|
164
|
+
[[0, 0, 0, 0], nil]
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
t.context do
|
|
168
|
+
t.set_subframe(plot_margins)
|
|
169
|
+
top_level_container.do(t)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# Draw the legend only when applicable.
|
|
173
|
+
if legend_margins
|
|
174
|
+
t.context do
|
|
175
|
+
t.set_subframe(legend_margins)
|
|
176
|
+
@legend_area.display_legend(t, top_level_container)
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
else
|
|
180
|
+
raise "The root object should not be drawn empty ?"
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# Whether we are drawing a top-level legend
|
|
185
|
+
def draw_top_level_legend?
|
|
186
|
+
return (! top_level_container.legend_area) &&
|
|
187
|
+
( top_level_container.legend_storage.harvest_contents.size > 0)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# Returns the legend_area in charge of the current container.
|
|
191
|
+
def current_legend_area
|
|
192
|
+
area = nil
|
|
193
|
+
for el in @container_stack
|
|
194
|
+
if el.respond_to?(:legend_area) and el.legend_area
|
|
195
|
+
area = el.legend_area
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
if ! area
|
|
199
|
+
area = @legend_area
|
|
200
|
+
end
|
|
201
|
+
return area
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
end
|
|
209
|
+
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# styles.rb: all style objects
|
|
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/styles/base'
|
|
15
|
+
|
|
16
|
+
require 'ctioga2/graphics/styles/drawable'
|
|
17
|
+
require 'ctioga2/graphics/styles/texts'
|
|
18
|
+
require 'ctioga2/graphics/styles/carrays'
|
|
19
|
+
require 'ctioga2/graphics/styles/curve'
|
|
20
|
+
|
|
21
|
+
require 'ctioga2/graphics/styles/sets'
|
|
22
|
+
|
|
23
|
+
require 'ctioga2/graphics/styles/axes'
|
|
24
|
+
require 'ctioga2/graphics/styles/background'
|
|
25
|
+
require 'ctioga2/graphics/styles/plot'
|
|
26
|
+
|
|
27
|
+
require 'ctioga2/graphics/styles/legend'
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
require 'ctioga2/graphics/styles/factory'
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
# axes.rb: the style of one axis or edge
|
|
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: 94 $', '$Date: 2009-06-25 23:37:13 +0200 (Thu, 25 Jun 2009) $')
|
|
21
|
+
|
|
22
|
+
module Graphics
|
|
23
|
+
|
|
24
|
+
module Styles
|
|
25
|
+
|
|
26
|
+
# The style of an axis or an egde of the plot. Unlike tioga,
|
|
27
|
+
# ctioga2 does not make any difference.
|
|
28
|
+
class AxisStyle < BasicStyle
|
|
29
|
+
include Tioga::FigureConstants
|
|
30
|
+
|
|
31
|
+
# The type of the edge/axis. Any of the Tioga constants:
|
|
32
|
+
# AXIS_HIDDEN, AXIS_LINE_ONLY, AXIS_WITH_MAJOR_TICKS_ONLY,
|
|
33
|
+
# AXIS_WITH_TICKS_ONLY,
|
|
34
|
+
# AXIS_WITH_MAJOR_TICKS_AND_NUMERIC_LABELS, and
|
|
35
|
+
# AXIS_WITH_TICKS_AND_NUMERIC_LABELS.
|
|
36
|
+
attr_accessor :decoration
|
|
37
|
+
|
|
38
|
+
# The position of the axis. Can be one of :left, :right, :top,
|
|
39
|
+
# :bottom, :at_y_origin or :at_x_origin.
|
|
40
|
+
attr_accessor :location
|
|
41
|
+
|
|
42
|
+
# Offset of the axis with respect to its normal position. It
|
|
43
|
+
# is counted *away* from the graph. It is either a
|
|
44
|
+
# Types::Dimension object or _nil_.
|
|
45
|
+
attr_accessor :offset
|
|
46
|
+
|
|
47
|
+
# The background lines for the given axis. _nil_ for nothing,
|
|
48
|
+
# or a StrokeStyle object if we want to draw something.
|
|
49
|
+
attr_accessor :background_lines
|
|
50
|
+
|
|
51
|
+
# The style of the tick labels
|
|
52
|
+
attr_accessor :tick_label_style
|
|
53
|
+
|
|
54
|
+
# The label of the axis, if there is one
|
|
55
|
+
attr_accessor :axis_label
|
|
56
|
+
|
|
57
|
+
# Whether the axis should be log scale or not
|
|
58
|
+
attr_accessor :log
|
|
59
|
+
|
|
60
|
+
# Transform: a Types::Bijection object specifying a coordinate
|
|
61
|
+
# transformation for the axis.
|
|
62
|
+
attr_accessor :transform
|
|
63
|
+
|
|
64
|
+
# The color of the stroke for the lines of the axis
|
|
65
|
+
attr_accessor :stroke_color
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
# Creates a new AxisStyle object at the given location with
|
|
69
|
+
# the given style.
|
|
70
|
+
def initialize(location = nil, decoration = nil, label = nil)
|
|
71
|
+
@location = location
|
|
72
|
+
@decoration = decoration
|
|
73
|
+
|
|
74
|
+
@tick_label_style = FullTextStyle.new
|
|
75
|
+
@axis_label = TextLabel.new(label)
|
|
76
|
+
@log = false
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Draws the axis within the current plot. Boundaries are the
|
|
80
|
+
# current plot boundaries. Also draw the #axis_label, if there
|
|
81
|
+
# is one.
|
|
82
|
+
#
|
|
83
|
+
# TODO:
|
|
84
|
+
# * the offset mechanism, to place the axis away from the place
|
|
85
|
+
# where it should be...
|
|
86
|
+
# * non-linear axes (or linear, for that matter, but with
|
|
87
|
+
# a transformation)
|
|
88
|
+
def draw_axis(t)
|
|
89
|
+
spec = get_axis_specification(t)
|
|
90
|
+
# Add tick label style:
|
|
91
|
+
spec.merge!(@tick_label_style.to_hash)
|
|
92
|
+
if @stroke_color
|
|
93
|
+
spec['stroke_color'] = @stroke_color
|
|
94
|
+
end
|
|
95
|
+
t.show_axis(spec)
|
|
96
|
+
@axis_label.loc = LocationToTiogaLocation[@location]
|
|
97
|
+
default = vertical? ? 'ylabel' : 'xlabel'
|
|
98
|
+
@axis_label.draw(t, default)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Draw the axis background lines:
|
|
102
|
+
def draw_background_lines(t)
|
|
103
|
+
if @background_lines
|
|
104
|
+
# First, getting major ticks location from tioga
|
|
105
|
+
info = t.axis_information(get_axis_specification(t))
|
|
106
|
+
|
|
107
|
+
if info['vertical']
|
|
108
|
+
x0 = t.bounds_left
|
|
109
|
+
x1 = t.bounds_right
|
|
110
|
+
else
|
|
111
|
+
y0 = t.bounds_bottom
|
|
112
|
+
y1 = t.bounds_top
|
|
113
|
+
end
|
|
114
|
+
t.context do
|
|
115
|
+
@background_lines.set_stroke_style(t)
|
|
116
|
+
values = info['major_ticks'] || info['major']
|
|
117
|
+
for val in values
|
|
118
|
+
if info['vertical']
|
|
119
|
+
t.stroke_line(x0, val, x1, val)
|
|
120
|
+
else
|
|
121
|
+
t.stroke_line(val, y0, val, y1)
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Returns the AxisStyle object corresponding to the named axis
|
|
129
|
+
# in the current plot.
|
|
130
|
+
def self.current_axis_style(plotmaker, spec)
|
|
131
|
+
return PlotStyle.current_plot_style(plotmaker).
|
|
132
|
+
get_axis_style(spec)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Returns the extension of the axis (including tick labels and
|
|
136
|
+
# labels if applicable) perpendicular to itself, in units of
|
|
137
|
+
# text height (at scale = current text scale when drawing
|
|
138
|
+
# axes).
|
|
139
|
+
#
|
|
140
|
+
# _style_ is a PlotStyle object containing the style
|
|
141
|
+
# information for the target plot.
|
|
142
|
+
#
|
|
143
|
+
# TODO: handle offset axes when that is implemented.
|
|
144
|
+
def extension(t, style = nil)
|
|
145
|
+
ticks_shift, ticks_scale = *get_ticks_parameters(t)
|
|
146
|
+
default = vertical? ? 'ylabel' : 'xlabel'
|
|
147
|
+
le = @axis_label.label_extension(t, default, @location)
|
|
148
|
+
|
|
149
|
+
case @decoration
|
|
150
|
+
when AXIS_WITH_MAJOR_TICKS_AND_NUMERIC_LABELS,
|
|
151
|
+
AXIS_WITH_TICKS_AND_NUMERIC_LABELS
|
|
152
|
+
te = ticks_shift * ticks_scale
|
|
153
|
+
else
|
|
154
|
+
te = 0
|
|
155
|
+
end
|
|
156
|
+
return Dobjects::Dvector[le,te].max *
|
|
157
|
+
(style ? style.text_scale || 1 : 1)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
protected
|
|
161
|
+
|
|
162
|
+
# Whether the axis is vertical or not
|
|
163
|
+
def vertical?
|
|
164
|
+
return LocationVertical[@location]
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# Returns: _ticks_shift_, _ticks_scale_ for the axis.
|
|
168
|
+
#
|
|
169
|
+
# TODO: try something clever with the angles ?
|
|
170
|
+
def get_ticks_parameters(t)
|
|
171
|
+
i = t.axis_information({'location' =>
|
|
172
|
+
LocationToTiogaLocation[@location]})
|
|
173
|
+
retval = []
|
|
174
|
+
retval << (@tick_label_style.shift || i['shift'])
|
|
175
|
+
retval << (@tick_label_style.scale || i['scale'])
|
|
176
|
+
|
|
177
|
+
retval[0] += 1
|
|
178
|
+
return retval
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
# Returns an argument suitable for use for
|
|
182
|
+
# FigureMaker#show_axis or FigureMaker#axis_information.
|
|
183
|
+
#
|
|
184
|
+
# For the log axis scale to work, tioga revision 543 is
|
|
185
|
+
# absolutely necessary. It won't fail, though, without it.
|
|
186
|
+
def get_axis_specification(t)
|
|
187
|
+
if @transform
|
|
188
|
+
retval = compute_coordinate_transforms(t)
|
|
189
|
+
else
|
|
190
|
+
retval = {}
|
|
191
|
+
end
|
|
192
|
+
if @offset
|
|
193
|
+
raise YetUnimplemented, "This has not been implemented yet"
|
|
194
|
+
else
|
|
195
|
+
retval.
|
|
196
|
+
update({'location' =>
|
|
197
|
+
LocationToTiogaLocation[@location],
|
|
198
|
+
'type' => @decoration, 'log' => @log})
|
|
199
|
+
return retval
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# Setup coordinate transformations
|
|
204
|
+
def compute_coordinate_transforms(t)
|
|
205
|
+
return unless @transform
|
|
206
|
+
# We'll proceed by steps...
|
|
207
|
+
i = t.axis_information({'location' =>
|
|
208
|
+
LocationToTiogaLocation[@location]})
|
|
209
|
+
t.context do
|
|
210
|
+
if i['vertical']
|
|
211
|
+
top,b = @transform.convert_to([t.bounds_top, t.bounds_bottom])
|
|
212
|
+
l,r = t.bounds_left, t.bounds_right
|
|
213
|
+
else
|
|
214
|
+
top,b = t.bounds_top, t.bounds_bottom
|
|
215
|
+
l,r = @transform.convert_to([t.bounds_left, t.bounds_right])
|
|
216
|
+
end
|
|
217
|
+
t.set_bounds([l,r,top,b])
|
|
218
|
+
i = t.axis_information({'location' =>
|
|
219
|
+
LocationToTiogaLocation[@location]})
|
|
220
|
+
# Now, we have the location of everything we need.
|
|
221
|
+
end
|
|
222
|
+
# In the following, the || are because of a fix in Tioga
|
|
223
|
+
# r545
|
|
224
|
+
return { 'labels' => i['labels'],
|
|
225
|
+
'major_ticks' => @transform.
|
|
226
|
+
convert_from(i['major_ticks'] || i['major']),
|
|
227
|
+
'minor_ticks' => @transform.
|
|
228
|
+
convert_from(i['minor_ticks'] || i['minor'] )
|
|
229
|
+
}
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
PartialAxisStyle = {
|
|
237
|
+
'transform' => CmdArg.new('bijection'),
|
|
238
|
+
'stroke_color' => CmdArg.new('color')
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
FullAxisStyle = PartialAxisStyle.dup
|
|
242
|
+
FullAxisStyle['decoration'] = CmdArg.new('axis-decoration')
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
end
|