ctioga 1.11.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. data/COPYING +340 -0
  2. data/ctioga/bin/ctable +28 -0
  3. data/ctioga/bin/ctioga +37 -0
  4. data/ctioga/doc/ctable.1 +156 -0
  5. data/ctioga/doc/ctioga.1 +2363 -0
  6. data/ctioga/examples/README +46 -0
  7. data/ctioga/examples/ctioga.gnuplot +4 -0
  8. data/ctioga/examples/ctioga_within_tioga.rb +53 -0
  9. data/ctioga/examples/ctiogarc.rb +24 -0
  10. data/ctioga/examples/include_1.rb +15 -0
  11. data/ctioga/examples/noise.dat +100 -0
  12. data/ctioga/examples/noise.rb +13 -0
  13. data/ctioga/examples/trig.csv +100 -0
  14. data/ctioga/examples/trig.dat +100 -0
  15. data/ctioga/examples/trig.rb +14 -0
  16. data/ctioga/examples/trigh.dat +100 -0
  17. data/ctioga/examples/trigh.rb +10 -0
  18. data/ctioga/examples/tutorial +763 -0
  19. data/ctioga/examples/tutorial.sh +269 -0
  20. data/ctioga/tests/README +14 -0
  21. data/ctioga/tests/axes.sh +40 -0
  22. data/ctioga/tests/basic.sh +11 -0
  23. data/ctioga/tests/draw.sh +24 -0
  24. data/ctioga/tests/histograms.sh +14 -0
  25. data/ctioga/tests/insets.sh +41 -0
  26. data/ctioga/tests/layouts.sh +29 -0
  27. data/ctioga/tests/legends.sh +113 -0
  28. data/ctioga/tests/styles.sh +43 -0
  29. data/ctioga/tests/test_style.sh +8 -0
  30. data/ctioga/tests/tests.sh +24 -0
  31. data/ctioga/tests/text_backend.sh +83 -0
  32. data/ctioga/tests/tioga_defaults.rb +18 -0
  33. data/lib/CTioga/axes.rb +904 -0
  34. data/lib/CTioga/backends.rb +88 -0
  35. data/lib/CTioga/boundaries.rb +224 -0
  36. data/lib/CTioga/ctable.rb +134 -0
  37. data/lib/CTioga/curve_style.rb +246 -0
  38. data/lib/CTioga/debug.rb +199 -0
  39. data/lib/CTioga/dimension.rb +133 -0
  40. data/lib/CTioga/elements.rb +17 -0
  41. data/lib/CTioga/elements/base.rb +84 -0
  42. data/lib/CTioga/elements/containers.rb +578 -0
  43. data/lib/CTioga/elements/curves.rb +368 -0
  44. data/lib/CTioga/elements/tioga_primitives.rb +440 -0
  45. data/lib/CTioga/layout.rb +595 -0
  46. data/lib/CTioga/legends.rb +29 -0
  47. data/lib/CTioga/legends/cmdline.rb +187 -0
  48. data/lib/CTioga/legends/item.rb +164 -0
  49. data/lib/CTioga/legends/style.rb +257 -0
  50. data/lib/CTioga/log.rb +73 -0
  51. data/lib/CTioga/movingarrays.rb +131 -0
  52. data/lib/CTioga/partition.rb +271 -0
  53. data/lib/CTioga/plot_style.rb +230 -0
  54. data/lib/CTioga/plotmaker.rb +1677 -0
  55. data/lib/CTioga/shortcuts.rb +69 -0
  56. data/lib/CTioga/structures.rb +82 -0
  57. data/lib/CTioga/styles.rb +140 -0
  58. data/lib/CTioga/themes.rb +581 -0
  59. data/lib/CTioga/themes/classical.rb +82 -0
  60. data/lib/CTioga/themes/demo.rb +63 -0
  61. data/lib/CTioga/themes/fits.rb +91 -0
  62. data/lib/CTioga/themes/mono.rb +33 -0
  63. data/lib/CTioga/tioga.rb +32 -0
  64. data/lib/CTioga/utils.rb +173 -0
  65. data/lib/MetaBuilder/Parameters/dates.rb +38 -0
  66. data/lib/MetaBuilder/Parameters/lists.rb +132 -0
  67. data/lib/MetaBuilder/Parameters/numbers.rb +69 -0
  68. data/lib/MetaBuilder/Parameters/strings.rb +86 -0
  69. data/lib/MetaBuilder/Parameters/styles.rb +75 -0
  70. data/lib/MetaBuilder/Qt4/Parameters/dates.rb +51 -0
  71. data/lib/MetaBuilder/Qt4/Parameters/numbers.rb +65 -0
  72. data/lib/MetaBuilder/Qt4/Parameters/strings.rb +106 -0
  73. data/lib/MetaBuilder/Qt4/parameter.rb +172 -0
  74. data/lib/MetaBuilder/Qt4/parameters.rb +9 -0
  75. data/lib/MetaBuilder/descriptions.rb +603 -0
  76. data/lib/MetaBuilder/factory.rb +101 -0
  77. data/lib/MetaBuilder/group.rb +57 -0
  78. data/lib/MetaBuilder/metabuilder.rb +10 -0
  79. data/lib/MetaBuilder/parameter.rb +374 -0
  80. data/lib/MetaBuilder/parameters.rb +11 -0
  81. data/lib/MetaBuilder/qt4.rb +8 -0
  82. data/lib/SciYAG/Backends/backend.rb +379 -0
  83. data/lib/SciYAG/Backends/binner.rb +168 -0
  84. data/lib/SciYAG/Backends/cache.rb +102 -0
  85. data/lib/SciYAG/Backends/dataset.rb +158 -0
  86. data/lib/SciYAG/Backends/descriptions.rb +469 -0
  87. data/lib/SciYAG/Backends/filters.rb +25 -0
  88. data/lib/SciYAG/Backends/filters/average.rb +134 -0
  89. data/lib/SciYAG/Backends/filters/cumulate.rb +37 -0
  90. data/lib/SciYAG/Backends/filters/filter.rb +70 -0
  91. data/lib/SciYAG/Backends/filters/norm.rb +39 -0
  92. data/lib/SciYAG/Backends/filters/smooth.rb +63 -0
  93. data/lib/SciYAG/Backends/filters/sort.rb +43 -0
  94. data/lib/SciYAG/Backends/filters/strip.rb +34 -0
  95. data/lib/SciYAG/Backends/filters/trim.rb +64 -0
  96. data/lib/SciYAG/Backends/gnuplot.rb +131 -0
  97. data/lib/SciYAG/Backends/math.rb +108 -0
  98. data/lib/SciYAG/Backends/mdb.rb +462 -0
  99. data/lib/SciYAG/Backends/multitext.rb +96 -0
  100. data/lib/SciYAG/Backends/source.rb +64 -0
  101. data/lib/SciYAG/Backends/text.rb +339 -0
  102. data/lib/SciYAG/backends.rb +16 -0
  103. metadata +191 -0
@@ -0,0 +1,113 @@
1
+ #!/bin/sh
2
+ # This file contains some 'visual tests' for ctioga to make sure that when
3
+ # I add some features to ctioga, I don't break everything existing.
4
+ # As such, it also stands as a 'feature list' for ctioga.
5
+
6
+ # Test for legends
7
+
8
+ . ./test_style.sh
9
+
10
+ ctioga -t 'Normal legends' 'sin(x)' 'cos(x)'
11
+
12
+ ctioga -t 'Normal legends + line' 'sin(x)' --legend-line \
13
+ 'One line between' 'cos(x)'
14
+
15
+ # Legends of the second axes must show where the first axes are
16
+ ctioga -t 'Legends and second axes' 'sin(x)' 'cos(x)' \
17
+ --y2 -l '$x^2$ (2nd)' 'x**2'
18
+
19
+ # Legends and insets
20
+ ctioga -N -t 'Legends and insets' -l '$x^2$' 'x**2' \
21
+ --inset .5,.5:.4 -l '$\sin x$' 'sin(x)' \
22
+ -l '$\cos x$' 'cos(x)'
23
+
24
+ # Legends and markers
25
+ ctioga -N -t 'Legends and markers' --marker auto \
26
+ -l '$x^2$' 'x**2' --line-style none \
27
+ -l 'No line' 'x**2 + 2*x + 1'
28
+
29
+ # Legends inside
30
+ ctioga -N -t 'Legends inside' \
31
+ --legend-inside 0.5,0.7:0.3 \
32
+ --marker auto \
33
+ -l '$x^2$' 'x**2' --line-style none \
34
+ -l 'No line' 'x**2 + 2*x + 1'
35
+
36
+ # A (bad) use case of --legend-dy
37
+ ctioga -N -t 'Crammed legends inside' \
38
+ --legend-inside 0.5,0.7:0.3 \
39
+ --marker auto --legend-dy 1.0 \
40
+ -l '$x^2$' 'x**2' --line-style none \
41
+ --legend-line \
42
+ 'One (crammed) line between' \
43
+ 'cos(x)' \
44
+ -l 'No line' 'x**2 + 2*x + 1'
45
+
46
+
47
+ # New position scheme
48
+ ctioga -N -t 'Top left in the middle' \
49
+ --legend-inside tl:0.5,0.5 \
50
+ --marker auto \
51
+ -l '$x^2$' 'x**2' --line-style none \
52
+ -l 'Intentionally long legend' 'x**2 + 2*x + 1'
53
+
54
+
55
+ ctioga -N -t 'Bottom right in the middle' \
56
+ --legend-inside br:0.5,0.5 \
57
+ --marker auto \
58
+ -l '$x^2$' 'x**2' --line-style none \
59
+ -l 'Intentionally long legend' 'x**2 + 2*x + 1'
60
+
61
+ ctioga -N -t 'Center in the middle' \
62
+ --legend-inside cc:0.5,0.5 \
63
+ --marker auto \
64
+ -l '$x^2$' 'x**2' --line-style none \
65
+ -l 'Intentionally long legend' 'x**2 + 2*x + 1'
66
+
67
+ ctioga -N -t 'Center in the middle, simpler spec' \
68
+ --legend-inside cc --marker auto \
69
+ -l '$x^2$' 'x**2' --line-style none \
70
+ -l 'Intentionally long legend' 'x**2 + 2*x + 1'
71
+
72
+ # Frames around legends...
73
+ ctioga -N -t 'Bottom right in the middle, framed (square)' \
74
+ --legend-inside br:0.5,0.5 \
75
+ --marker auto \
76
+ --legend-frame square \
77
+ -l '$x^2$' 'x**2' --line-style none \
78
+ -l 'Intentionally long legend' 'x**2 + 2*x + 1'
79
+
80
+ ctioga -N -t 'Bottom right in the middle, framed (round)' \
81
+ --legend-inside br:0.5,0.5 \
82
+ --marker auto \
83
+ --legend-frame round \
84
+ -l '$x^2$' 'x**2' --line-style none \
85
+ -l 'Intentionally long legend' 'x**2 + 2*x + 1'
86
+
87
+ # Colors...
88
+ ctioga -N -t 'Colored frames' \
89
+ --legend-inside cc:0.5,0.5 \
90
+ --legend-color Green --legend-background 0.9,1.0,0.9 \
91
+ --marker auto \
92
+ --legend-frame round \
93
+ -l '$x^2$' 'x**2' --line-style none \
94
+ -l 'Intentionally long legend' 'x**2 + 2*x + 1'
95
+
96
+ ctioga -N -t 'Transparent background' \
97
+ --legend-inside cc:0.5,0.5 --math-samples 1000 \
98
+ --legend-color Green --legend-background White \
99
+ --legend-transparency 0.4 \
100
+ --marker auto \
101
+ --legend-frame round \
102
+ -l '$\cos 2x$' 'cos(2*x)' \
103
+ -l '$\sin 2x$ (still decently long)' 'sin(2*x)'
104
+
105
+ ctioga -N -t 'Fancy frames' \
106
+ --legend-inside cc:0.5,0.5 --math-samples 100 \
107
+ --legend-line-width 0.7 \
108
+ --legend-line-style Dots \
109
+ --legend-background Cornsilk \
110
+ --marker auto \
111
+ --legend-frame round \
112
+ -l '$x^2$' 'x**2' --line-style none \
113
+ -l 'Intentionally long legend' 'x**2 + 2*x + 1'
@@ -0,0 +1,43 @@
1
+ #!/bin/sh
2
+ # This file contains some 'visual tests' for ctioga to make sure that when
3
+ # I add some features to ctioga, I don't break everything existing.
4
+ # As such, it also stands as a 'feature list' for ctioga.
5
+
6
+ . ./test_style.sh
7
+
8
+ # Then, we try various styles:
9
+ ctioga -N -t 'Transparency and fills' \
10
+ --fill y-axis --fill-transparency 0.6 'sin(x)' 'cos(x)'
11
+ ctioga -N -t 'Markers' \
12
+ --marker auto 'sin(x)**2' 'cos(x)**2'
13
+ ctioga -N -t 'Dot clouds' \
14
+ --marker auto --marker-scale 0.2 --line-style no 'x**2' '1 - x**2'
15
+
16
+ # Special sets
17
+ ctioga -N -t 'Unusual set specifications' \
18
+ --marker auto --color-set 'Red|Blue|Pink' \
19
+ --line-style-set Dashes 'x**2 + 10*0##9'
20
+
21
+ # Style manipulations
22
+ ctioga -N -t 'Reset override' \
23
+ --marker auto --marker-scale 0.2 --line-style no 'x**2' '1 - x**2' \
24
+ --reset-override '10 - x**2'
25
+ # And override manipulations
26
+ ctioga -N -t 'Override manipulations' \
27
+ --marker auto --marker-scale 0.2 --line-style no 'x**2' \
28
+ --save-override cloud --reset-override \
29
+ '1 - x**2' '10 - x**2' --use-override cloud 'x**2 - 10'
30
+
31
+ # Now testing background colors
32
+
33
+ ctioga -N -t 'Turquoise background' \
34
+ --background PaleTurquoise 'sin(x)**2' 'cos(x)**2'
35
+
36
+ ctioga -N -t 'Backgrounds with --grid' \
37
+ --grid column=2 \
38
+ --background PaleTurquoise 'sin(x)**2' 'cos(x)**2' \
39
+ --next 'tan(x)' --next --background Chiffon \
40
+ 'x**2' 'x**2 + 10'
41
+
42
+
43
+
@@ -0,0 +1,8 @@
1
+ # A small include file to setup environment variables
2
+ # Copyright 2008 by Vincent Fourmond.
3
+ # You can do whatever you want with this file.
4
+
5
+ export CTIOGA="--echo --xpdf --clean-all --math "
6
+ if [ "$DEBUG" ]; then
7
+ export CTIOGA="$CTIOGA --debug "
8
+ fi;
@@ -0,0 +1,24 @@
1
+ #!/bin/sh
2
+ # This file contains some 'visual tests' for ctioga to make sure that when
3
+ # I add some features to ctioga, I don't break everything existing.
4
+ # As such, it also stands as a 'feature list' for ctioga.
5
+
6
+ . ./test_style.sh
7
+
8
+ # First, some basic stuff
9
+ ctioga -t 'Basic curve' 'sin(x)'
10
+ ctioga -N -t 'Several styles' 'sin(x)' 'cos(x)' 'tan(x)'
11
+
12
+ # Then, we try various styles:
13
+ ctioga -N -t 'Transparency and fills' \
14
+ --fill y-axis --fill-transparency 0.6 'sin(x)' 'cos(x)'
15
+ ctioga -N -t 'Markers' \
16
+ --marker auto 'sin(x)**2' 'cos(x)**2'
17
+ ctioga -N -t 'Dot clouds' \
18
+ --marker auto --marker-scale 0.2 --line-style no 'x**2' '1 - x**2'
19
+
20
+ # Then, insets:
21
+
22
+ ctioga -N -t 'Inset (with title)' 'x**2' --inset .5,.5:.4 \
23
+ -t 'Title inset' 'cos(x)'
24
+
@@ -0,0 +1,83 @@
1
+ #!/bin/sh
2
+ # This file contains some 'visual tests' for ctioga to make sure that when
3
+ # I add some features to ctioga, I don't break everything existing.
4
+ # As such, it also stands as a 'feature list' for ctioga.
5
+
6
+ . ./test_style.sh
7
+
8
+ # We first create several data files using ctable
9
+
10
+ tmpfile=`mktemp -t "ctioga-test-XXXXXXX"`
11
+
12
+ echo "Generating temporary data file ${tmpfile}"
13
+
14
+ # Here: warning; density is quite high (500 points)
15
+ ruby -e 'include Math; srand(Time.now.to_f); 0.upto(500) do |i|
16
+ x = 3.1415 * (1- 2*rand)
17
+ puts "#{i}\t#{x}\t#{sin(x)}\t#{cos(x) + 0.1*rand}\t#{0.2*sin(x)}"
18
+ end
19
+ ' > $tmpfile
20
+
21
+ ctioga -N -t 'Raw data' --text --marker auto --line-style Dashes \
22
+ $tmpfile@2:3
23
+
24
+ ctioga -N -t 'Without lines' --text --marker auto --line-style No \
25
+ $tmpfile@2:3
26
+
27
+ ctioga -N -t '20\% error bars' --text --marker auto --line-style No \
28
+ $tmpfile@2:3:5
29
+
30
+ ctioga -N -t 'Noisy cosine' --text --marker auto --line-style No \
31
+ $tmpfile@2:4
32
+
33
+ # Two small exercises:
34
+ # * why did I draw the y = 1 line ?
35
+ # * compute the envelope of the obtained dot cloud ;-)...
36
+
37
+ ctioga -N -t 'Nearly one !' --text --marker auto --line-style No \
38
+ --draw 'line: -3.14,1 3.14,1 line_style=Dashes color=Gray' \
39
+ $tmpfile@'$2:$3**2 + $4**2'
40
+
41
+
42
+ # Now, demonstrating the --sort filter:
43
+
44
+ ctioga -N -t 'Sorted data' --text --sort --marker auto \
45
+ --line-style Dashes $tmpfile@2:3
46
+
47
+ ctioga -N -t 'Sorted data with error bars' --text --sort --marker auto \
48
+ --line-style Dashes $tmpfile@2:3:5
49
+
50
+ ctioga -N -t 'Cosine' --text --marker auto --line-style No \
51
+ --legend-inside 'tl' \
52
+ -l "Original" $tmpfile@2:4 \
53
+ --smooth 7 -l 'Smoothed before sorting' $tmpfile@2:4 \
54
+ --filter-clear --sort \
55
+ --smooth 7 -l 'Smoothed after sorting' $tmpfile@2:4
56
+
57
+ # rm -f $tmpfile
58
+
59
+ echo "Generating temporary (nearly) redundant data ${tmpfile}"
60
+
61
+ # Here: warning; density is quite high (500 points)
62
+ ruby -e 'include Math; srand(Time.now.to_f); 0.upto(50) do |i|
63
+ x = 3.1415 * (1- 2*rand)
64
+ 20.times { puts "#{x}\t#{sin(x) + (1.6*(rand - 0.5))**3}" }
65
+ end
66
+ puts "0\t0"
67
+ ' > $tmpfile
68
+
69
+ ctioga -N -t 'Redundant data' --text --marker auto --line-style Dashes \
70
+ $tmpfile
71
+
72
+ ctioga -N -t 'Sorted redundant data' --text --marker auto \
73
+ --sort --line-style Dashes \
74
+ $tmpfile
75
+
76
+ ctioga -N -t 'After averageing duplicates' --text --marker auto \
77
+ --line-style Dashes --avgdup $tmpfile
78
+
79
+ ctioga -N -t 'Computing standard deviation' --text --marker auto \
80
+ --sort --stddev \
81
+ --line-style Dashes --avgdup $tmpfile
82
+
83
+ rm -f $tmpfile
@@ -0,0 +1,18 @@
1
+ # tioga_defaults.rb: a small Ruby script displaying Tioga's default parameters
2
+ # Copyright 2008 by Vincent Fourmond
3
+ # You are free to do whatever you want with this file, provided you don't
4
+ # remove the copyright notice nor this notice
5
+
6
+ require 'Tioga/FigureMaker'
7
+
8
+ def display_value(t, element)
9
+ puts "#{element} -> #{t.send(element).inspect}"
10
+ end
11
+
12
+ t = Tioga::FigureMaker.new
13
+ display_value(t, 'legend_line_dy')
14
+ display_value(t, 'legend_line_x0')
15
+ display_value(t, 'legend_line_x1')
16
+ display_value(t, 'legend_text_dy')
17
+ display_value(t, 'legend_text_xstart')
18
+ display_value(t, 'legend_text_ystart')
@@ -0,0 +1,904 @@
1
+ # axes.rb: A module to deal with axes customization.
2
+ # Copyright (c) 2007, 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/utils'
15
+ require 'CTioga/layout'
16
+ require 'CTioga/log'
17
+ require 'CTioga/boundaries'
18
+ require 'CTioga/partition'
19
+
20
+ module CTioga
21
+
22
+ Version::register_svn_info('$Revision: 828 $', '$Date: 2008-08-07 11:29:21 +0200 (Thu, 07 Aug 2008) $')
23
+
24
+ # A module to be included by the main PlotMaker instance. It
25
+ # deals with various aspects of axes manipulations.
26
+ module Axes
27
+
28
+ LabelSpecification = {
29
+ /^x(label)?$/i => :xlabel,
30
+ /^y(label)?$/i => :ylabel,
31
+ /^t(itle)?$/i => :title,
32
+ /^xticks?$/i => :xticks,
33
+ /^yticks?$/i => :yticks,
34
+ }
35
+
36
+ AxisSpecification = {
37
+ /^x$/i => 'xaxis',
38
+ /^y?$/i => 'yaxis',
39
+ }
40
+
41
+ LabelSide = {
42
+ /bottom/i => Tioga::FigureConstants::BOTTOM,
43
+ /top/i => Tioga::FigureConstants::TOP,
44
+ /left/i => Tioga::FigureConstants::LEFT,
45
+ /right/i => Tioga::FigureConstants::RIGHT,
46
+ }
47
+
48
+ Alignment = {
49
+ /B/ => Tioga::FigureConstants::ALIGNED_AT_BASELINE,
50
+ /baseline/i => Tioga::FigureConstants::ALIGNED_AT_BASELINE,
51
+ /b/ => Tioga::FigureConstants::ALIGNED_AT_BOTTOM,
52
+ /bottom/i => Tioga::FigureConstants::ALIGNED_AT_BOTTOM,
53
+ /t(op)?/i => Tioga::FigureConstants::ALIGNED_AT_TOP,
54
+ }
55
+
56
+ Justification = {
57
+ /c(enter)?/i => Tioga::FigureConstants::CENTERED,
58
+ /l(eft)?/i => Tioga::FigureConstants::LEFT_JUSTIFIED,
59
+ /r(ight)?/i => Tioga::FigureConstants::RIGHT_JUSTIFIED,
60
+ }
61
+
62
+
63
+ # TODO: all the following attributes should go to PlotStyle!
64
+ # This would allow to remove the dirty ugly funcall hack for
65
+ # log values...
66
+
67
+ # Whether to have X or Y log axes
68
+ attr_accessor :x_log, :y_log
69
+ # Scaling of data axes
70
+ attr_accessor :x_factor, :y_factor
71
+ # Offsets
72
+ attr_accessor :x_offset, :y_offset
73
+ # Decimal separator
74
+ attr_accessor :decimal_separator
75
+
76
+ # Initializes variables pertaining to axes
77
+ def init_axes
78
+ # TODO: same as above
79
+ @x_log = false
80
+ @y_log = false
81
+ @x_factor = false
82
+ @y_factor = false
83
+ @x_offset = false
84
+ @y_offset = false
85
+ @decimal_separator = false
86
+ end
87
+
88
+ # Turns a String into a [ left, right, top, bottom ]
89
+ # edge visibility specification
90
+ def parse_edge_visibility(str)
91
+ # First and simplest : a series of v (for visible) and i
92
+ # (for invisible)
93
+ if str =~ /^\s*([vi]{4})\s*$/i
94
+ val = $1.split(//).map { |s| s =~ /v/i ? true : false }
95
+ return val
96
+ end
97
+ # By default, everything is visible
98
+ return [ true, true, true, true ]
99
+ end
100
+
101
+ # Runs a block safely with a label specification
102
+ def run_with_label(name)
103
+ w = Utils::interpret_arg(name, LabelSpecification) {false}
104
+ if w
105
+ yield current_object.plot_style.send(w)
106
+ elsif current_plot_style.edges.axes.key? name
107
+ yield current_plot_style.edges.axes[name].ticks
108
+ else
109
+ error "The label/axis specification #{w} was not understood, ignoring"
110
+ end
111
+ end
112
+
113
+ # Runs a block safely with an axis specification.
114
+ #
115
+ # This function relies on the fact that it is being used
116
+ # from within a PlotMaker instance !!
117
+ def run_with_axis(name)
118
+ w = Utils::interpret_arg(name, AxisSpecification) {name}
119
+ if current_plot_style.edges.axes.key? w
120
+ yield current_plot_style.edges.axes[w]
121
+ else
122
+ error "The axis specification #{w} was not understood, ignoring"
123
+ error "Valid axis specifications are " +
124
+ current_plot_style.edges.axes.keys.join(', ')
125
+ end
126
+ end
127
+
128
+ # Prepare the option parser for axes options
129
+ def axes_options(parser)
130
+
131
+ parser.separator "\nVarious axes manipulations:"
132
+ parser.on("--xfact FACT",
133
+ "Multiply all x values by FACT") do |f|
134
+ @x_factor = safe_float(f)
135
+ end
136
+ parser.on("--yfact FACT",
137
+ "Multiply all y values by FACT") do |f|
138
+ @y_factor = safe_float(f)
139
+ end
140
+ parser.on("--xoffset OFFSET",
141
+ "Add OFFSET to all X values (after multiplication)") do |f|
142
+ @x_offset = safe_float(f)
143
+ end
144
+ parser.on("--yoffset OFFSET",
145
+ "Add OFFSET to all X values (after multiplication)") do |f|
146
+ @y_offset = safe_float(f)
147
+ end
148
+
149
+ parser.on("--[no-]xlog",
150
+ "Uses logarithmic scale for X axis") do |v|
151
+ @x_log = v
152
+ add_elem_funcall(:xaxis_log_values=, v)
153
+ end
154
+ parser.on("--[no-]ylog",
155
+ "Uses logarithmic scale for Y axis") do |v|
156
+ @y_log = v
157
+ add_elem_funcall(:yaxis_log_values=, v)
158
+ end
159
+
160
+ parser.on("--reset-transformations",
161
+ "Reset axes transformations") do |v|
162
+ @y_log = false
163
+ @x_log = false
164
+ # TODO: remove that when this is move to PlotStyle:
165
+ # it should be setup automatically by the Container
166
+ # at the beginning of a plot...
167
+ add_elem_funcall(:xaxis_log_values=, false)
168
+ add_elem_funcall(:yaxis_log_values=, false)
169
+ @x_factor = nil
170
+ @y_factor = nil
171
+ @x_offset = nil
172
+ @y_offset = nil
173
+ end
174
+
175
+
176
+
177
+ parser.on("--comma",
178
+ "Uses a comma for the decimal separator") do
179
+ @decimal_separator = ','
180
+ end
181
+ parser.on("--decimal SEP",
182
+ "Uses SEP for the decimal separator") do |s|
183
+ @decimal_separator = s
184
+ end
185
+
186
+ parser.separator "\nLabels and titles"
187
+ parser.on("-x","--[no-]xlabel [LABEL]",
188
+ "Label of the x axis") do |l|
189
+ current_object.plot_style.xlabel.label = l
190
+ end
191
+ parser.on("-y","--[no-]ylabel [LABEL]",
192
+ "Label of the y axis") do |l|
193
+ current_object.plot_style.ylabel.label = l
194
+ end
195
+ parser.on('-t', "--[no-]title [TITLE]",
196
+ "Sets the title of the plot") do |l|
197
+ current_object.plot_style.title.label = l
198
+ end
199
+ parser.on("--side WHAT ALIGN",
200
+ "Sets the side for the WHAT label, ",
201
+ "where WHAT = x(label),y(label) or t(itle)") do |w|
202
+ run_with_label(w) do |label|
203
+ a = Utils::interpret_arg(@args.shift, LabelSide) {false}
204
+ label.side = a if a
205
+ end
206
+ end
207
+
208
+ parser.on("--lcolor WHAT COLOR",
209
+ "Sets the color for the WHAT label, ",
210
+ "where WHAT = x(label),y(label) or t(itle)") do |w|
211
+ run_with_label(w) do |label|
212
+ a = CTioga.get_tioga_color(@args.shift)
213
+ label.color = a if a
214
+ end
215
+ end
216
+
217
+ parser.on("--position WHAT WHERE",
218
+ "Sets the position for the WHAT label, ",
219
+ "where WHAT = x(label),y(label) or t(itle)",
220
+ "and WHERE a number between 0 and 1, 0.5 = centered") do |w|
221
+ run_with_label(w) do |label|
222
+ a = safe_float(@args.shift)
223
+ label.position = a if a
224
+ end
225
+ end
226
+
227
+ parser.on("--angle WHAT ANGLE",
228
+ "Sets the angle for the WHAT label, ",
229
+ "where WHAT = x(label),y(label) or t(itle).") do |w|
230
+ run_with_label(w) do |label|
231
+ a = safe_float(@args.shift)
232
+ label.angle = a if a
233
+ end
234
+ end
235
+
236
+ parser.on("--scale WHAT SCALE",
237
+ "Sets the scale for the WHAT label, ",
238
+ "where WHAT = x(label),y(label) or t(itle).") do |w|
239
+ run_with_label(w) do |label|
240
+ a = safe_float(@args.shift)
241
+ label.scale = a if a
242
+ end
243
+ end
244
+
245
+ parser.on("--shift WHAT SHIFT",
246
+ "Sets the shift for the WHAT label, ",
247
+ "where WHAT = x(label),y(label) or t(itle).",
248
+ "The shift is the distance of the label from the plot") do |w|
249
+ run_with_label(w) do |label|
250
+ a = safe_float(@args.shift)
251
+ label.shift = a if a
252
+ end
253
+ end
254
+
255
+ parser.on("--align WHAT ALIGN",
256
+ "Sets the 'vertical' alignment for the WHAT label, ",
257
+ "where WHAT = x(label),y(label) or t(itle).") do |w|
258
+ run_with_label(w) do |label|
259
+ a = Utils::interpret_arg(@args.shift, Alignment) {false}
260
+ label.alignment = a if a
261
+ end
262
+ end
263
+
264
+ parser.on("--just WHAT JUST",
265
+ "Sets the 'horizontal' alignment for the WHAT label, ",
266
+ "where WHAT = x(label),y(label) or t(itle).") do |w|
267
+ run_with_label(w) do |label|
268
+ a = Utils::interpret_arg(@args.shift, Justification) {false}
269
+ label.justification = a if a
270
+ end
271
+ end
272
+
273
+ parser.separator "\nEdges and axes look:"
274
+
275
+ parser.on("--edges-visibility SPEC",
276
+ "Chooses which edges of the current graph will be",
277
+ "visible. Will not act on edges that are also axes.") do |w|
278
+ current_object.plot_style.edges.edge_visibility =
279
+ parse_edge_visibility(w)
280
+ end
281
+
282
+ parser.on("--axis-pos AXIS POS",
283
+ "Sets the position of AXIS to POS") do |w|
284
+ run_with_axis(w) do |axis|
285
+ axis.loc = EdgesAndAxes.parse_axis_position(@args.shift)
286
+ end
287
+ end
288
+
289
+
290
+ parser.on("--xaxis STYLE",
291
+ "Sets the style of the X axis") do |w|
292
+ current_object.plot_style.set_axis_style(:x, w)
293
+ end
294
+
295
+ parser.on("--yaxis STYLE",
296
+ "Sets the style of the Y axis") do |w|
297
+ current_object.plot_style.set_axis_style(:y, w)
298
+ end
299
+
300
+ parser.on("--edge-style WHICH STYLE",
301
+ "Sets the style of the X axis") do |w|
302
+ current_object.plot_style.set_axis_style(w.to_sym,
303
+ @args.shift)
304
+ end
305
+
306
+ parser.on("--no-axes",
307
+ "No title, labels and axes") do
308
+ ps = current_plot_style
309
+ ps.set_axis_style(:x, "none")
310
+ ps.set_axis_style(:y, "none")
311
+ ps.xlabel.label = false
312
+ ps.ylabel.label = false
313
+ ps.title.label = false
314
+ end
315
+
316
+ parser.on("--lines-color AXIS COLOR",
317
+ "Sets the color for lines perpendicular to AXIS",
318
+ "'none' for no lines") do |w|
319
+ run_with_axis(w) do |axis|
320
+ color = @args.shift
321
+ if color =~ /no(ne)?/
322
+ color = false
323
+ else
324
+ color = CTioga.get_tioga_color(color)
325
+ end
326
+ axis.lines_color = color
327
+ end
328
+ end
329
+
330
+ parser.on("--new-axis NAME POSITION",
331
+ "Creates a new axis named NAME for this plot") do |name|
332
+ current_plot_style.edges.axes[name] =
333
+ EdgesAndAxes::Axis.new(@args.shift)
334
+ end
335
+
336
+ parser.on("--axis-function AXIS TO FROM",
337
+ "Sets AXIS to use a non-linear mapping represented",
338
+ "by 2 mathematical functions (of x): TO (to convert from",
339
+ "real to axis) and FROM that does the opposite") do |w|
340
+ run_with_axis(w) do |axis|
341
+ axis.real_to_axis = eval "proc { |x| #{@args.shift} }"
342
+ axis.axis_to_real = eval "proc { |x| #{@args.shift} }"
343
+ end
344
+ end
345
+
346
+
347
+
348
+ end
349
+
350
+ end
351
+
352
+ # A class that describes the various attributes of a label,
353
+ # either for the X or Y axis, or even the plot title.
354
+ class Label
355
+
356
+ include Log
357
+
358
+ # Include the figure constants, else it gets really painful...
359
+ include Tioga::FigureConstants
360
+
361
+ # The various attributes
362
+ Attributes = [:alignment, :angle, :color, :justification,
363
+ :position, :scale, :shift, :side, :visible]
364
+
365
+ attr_accessor *Attributes
366
+
367
+ # Which axis ?
368
+ attr_accessor :which
369
+
370
+ # The actual text to be displayed
371
+ attr_accessor :label
372
+
373
+ # Creates a label specification for the _which_ axis.
374
+ # _other_values_ is a hash that can be used to provide default
375
+ # values for the various Attributes.
376
+ #
377
+ # _which_ can be :xlabel, :ylabel or :title
378
+ def initialize(which, label = nil, other_values = {})
379
+ @which = which
380
+ @label = label
381
+ for key,val in other_values
382
+ self.send("#{key}=", val)
383
+ end
384
+ end
385
+
386
+ # Shows the given label on the figure _t_
387
+ def show(t)
388
+ # We don't do anything unless we have a label to display !
389
+ return unless @label
390
+ # We wrap the call in a context so we don't pollute subpictures
391
+ t.context do
392
+ for attr in Attributes
393
+ if instance_variables.include?("@#{attr}")
394
+ val = instance_variable_get("@#{attr}")
395
+ t.send("#{which}_#{attr}=", val)
396
+ end
397
+ end
398
+ t.send("show_#{which}", @label)
399
+ end
400
+ end
401
+
402
+ # Guesses the extension of the label on the side of the plot.
403
+ # The output is only garanteed when called with _t_ exactly in the
404
+ # context that will be used for the plot. An external _scale_ factor
405
+ # can be given in the case we have more information about the actual
406
+ # overall scale. Of course, just multiplying the result by it does
407
+ # give the same thing.
408
+ #
409
+ # The value returned is an array left,right, top, bottom
410
+ # containing only zeroes but for the place where the axis
411
+ # does extend.
412
+ def extension(t, scale = 1)
413
+ ret_val = [0,0,0,0]
414
+ if @label
415
+ ext = (@scale || tioga_value(t,:scale)) *
416
+ (1 + (@shift || tioga_value(t,:shift))) *
417
+ t.default_text_scale * t.default_font_size * scale
418
+ # Set to 0 if label doesn't extend.
419
+ ext = 0 if ext < 0
420
+ case (@side || tioga_value(t,:side))
421
+ when LEFT
422
+ ret_val[0] = ext
423
+ when BOTTOM
424
+ ret_val[3] = ext
425
+ when TOP
426
+ ret_val[2] = ext
427
+ when RIGHT
428
+ ret_val[1] = ext
429
+ end
430
+ end
431
+ debug "Axis #{self.inspect} extension #{ret_val.inspect}"
432
+ return ret_val
433
+ end
434
+
435
+
436
+ # Returns the value of the _what_ attribute
437
+ # corresponding to the value of which.
438
+ def tioga_value(t, what)
439
+ return t.send("#{@which}_#{what}")
440
+ end
441
+ end
442
+
443
+ # A tick label is basically the same thing as a label
444
+ class TickLabels < Label
445
+
446
+ # Extension currently does not work really well.
447
+ def extension(t)
448
+ return [0,0,0,0]
449
+ end
450
+
451
+ def show(t)
452
+ for attr in Attributes
453
+ if instance_variables.include?("@#{attr}")
454
+ val = instance_variable_get("@#{attr}")
455
+ t.send("#{which}_#{attr}=", val)
456
+ end
457
+ end
458
+ end
459
+
460
+ undef :color=
461
+ def color=(*a)
462
+ error "There is no attribute color for tick labels"
463
+ end
464
+
465
+
466
+ end
467
+
468
+ # A class that holds the information about how to plot the edges.
469
+ # And the size they potentially take.
470
+ #
471
+ # TODO: make sure the TickLabels and EdgesAndAxes
472
+ # talk to each other (for the #extension, essentially). They should be
473
+ # connected from the SubPlot class.
474
+ class EdgesAndAxes
475
+
476
+ # This function parses an axes position specification
477
+ # from the command-line.
478
+ def self.parse_axis_position(str)
479
+ case str
480
+ when /xori?g(in)?/i, /x=0/i
481
+ return Tioga::FigureConstants::AT_X_ORIGIN
482
+ when /yori?g(in)?/i, /y=0/i
483
+ return Tioga::FigureConstants::AT_Y_ORIGIN
484
+ when /l(eft)?/i
485
+ return Tioga::FigureConstants::LEFT
486
+ when /r(ight)?/i
487
+ return Tioga::FigureConstants::RIGHT
488
+ when /t(op)?/i
489
+ return Tioga::FigureConstants::TOP
490
+ when /b(ottom)?/i
491
+ return Tioga::FigureConstants::BOTTOM
492
+ else
493
+ raise "Unkown axis position: #{str}"
494
+ end
495
+ end
496
+
497
+ # A class that represents an axis.
498
+ class Axis
499
+
500
+ include Log
501
+
502
+ # Include the figure constants, else it gets really painful...
503
+ include Tioga::FigureConstants
504
+
505
+ # For an easy use of Boundaries:
506
+ include Utils
507
+
508
+
509
+ # The various attributes
510
+ Attributes = [:line_width, :loc, :log_values, :type,
511
+ :ticks_inside, :ticks_outside, :visible]
512
+
513
+ attr_accessor *Attributes
514
+
515
+ # Which axis ?
516
+ attr_accessor :which
517
+
518
+ # The corresponding TickLabels
519
+ attr_accessor :ticks
520
+
521
+ # The color of perpendicular lines, or false if no lines are
522
+ # to be drawn
523
+ attr_accessor :lines_color
524
+
525
+ # The line style of perpendicular lines
526
+ attr_accessor :lines_style
527
+
528
+ # The line width of perpendicular lines
529
+ attr_accessor :lines_width
530
+
531
+ # The coordinate conversions blocks
532
+ attr_accessor :real_to_axis, :axis_to_real
533
+
534
+ # _which_ can be :x or :y
535
+ def initialize(which, ticks = nil)
536
+ @which = which
537
+ case which
538
+ when :x
539
+ @loc = BOTTOM
540
+ when :y
541
+ @loc = LEFT
542
+ when String
543
+ # We have a named position, in which case a little
544
+ # more tweaking needs to be done.
545
+ if which =~ /(\w+)([+-].*)?/
546
+ # OK, $1 is the position, and $2 is a position shift
547
+ loc = EdgesAndAxes::parse_axis_position($1)
548
+ if $2
549
+ dim = Dimension.new($2)
550
+ else
551
+ dim = false
552
+ end
553
+ if dim
554
+ @loc = [loc, dim]
555
+ else
556
+ @loc = loc
557
+ end
558
+ end
559
+ end
560
+ @ticks = ticks || TickLabels.new(:none)
561
+
562
+ # Background lines.
563
+ @lines_color = false
564
+ @lines_style = Styles::Dashes
565
+ @lines_width = false
566
+ end
567
+
568
+ # Setup attributes for the axis.
569
+ def setup(t, container)
570
+ # We readjust the position of the axis if the X or Y origin is
571
+ # out of bounds
572
+ case @loc
573
+ when AT_X_ORIGIN
574
+ bounds = Boundaries.new(container.internal_get_boundaries)
575
+ case bounds.where_x?(0)
576
+ when :left
577
+ @loc = LEFT
578
+ when :right
579
+ @loc = RIGHT
580
+ end
581
+ when AT_Y_ORIGIN
582
+ bounds = Boundaries.new(container.internal_get_boundaries)
583
+ case bounds.where_y?(0)
584
+ when :top
585
+ @loc = TOP
586
+ when :bottom
587
+ @loc = BOTTOM
588
+ end
589
+ end
590
+ for attr in Attributes
591
+ if instance_variables.include?("@#{attr}")
592
+ # The visible attribute cannot be explicitly set to true.
593
+ next if attr == :visible && @visible
594
+ val = instance_variable_get("@#{attr}")
595
+ t.send("#{which}axis_#{attr}=", val)
596
+ end
597
+ end
598
+ end
599
+
600
+ # Returns the boundaries of the axis corresponding to the
601
+ # location of the axis
602
+ def axis_coordinate_boundaries(t, container)
603
+ loc = (@loc.is_a?(Array) ? @loc.first : @loc)
604
+ case loc
605
+ when TOP, BOTTOM, AT_Y_ORIGIN
606
+ return [t.bounds_left, t.bounds_right]
607
+ when LEFT, RIGHT, AT_X_ORIGIN
608
+ return [t.bounds_bottom, t.bounds_top]
609
+ end
610
+ end
611
+
612
+ # Prepares the major ticks/tick labels, in the case of a
613
+ # non-linear axis. These are returned as a
614
+ # [ [tick position], [tick values]]
615
+ #
616
+ # Returns nil if no tick changes are applicable
617
+ def prepare_major_ticks(t, container)
618
+ if @real_to_axis
619
+ # First, the naive version:
620
+
621
+ x1, x2 = axis_coordinate_boundaries(t, container)
622
+
623
+ y1 = @real_to_axis.call(x1)
624
+ y2 = @real_to_axis.call(x2)
625
+
626
+ # Now the y1, y2 segment is our mapping.
627
+ # We make sure y1 < y2:
628
+ if y1 > y2
629
+ y1, y2 = y2, y1
630
+ end
631
+
632
+ # We get information about what the axis would have been
633
+ loc = (@loc.is_a?(Array) ? @loc.first : @loc)
634
+ info = t.axis_information(loc)
635
+
636
+ # First: we divide relatively naively
637
+ number = info['major'].size
638
+
639
+ values = Utils::partition_nonlinear(@real_to_axis, @axis_to_real,
640
+ x1, x2, number + 1)
641
+
642
+ # Now, we have the positions (or nearly so), we need to
643
+ # convert that back to original
644
+
645
+ positions = values.map(&@axis_to_real)
646
+
647
+ return [positions, values]
648
+
649
+ else
650
+ return nil
651
+ end
652
+ end
653
+
654
+ # Gets the argument to give to FigureMaker#show_axis and
655
+ # FigureMaker#axis_information.
656
+ def axis_argument(t, container)
657
+ if @which == :x or @which == :y
658
+ return @loc
659
+ end
660
+ spec = {}
661
+ if @loc.is_a? Array
662
+ spec['location'] = @loc.first
663
+ else
664
+ spec['location'] = @loc
665
+ end
666
+
667
+ spec['type'] = @type if @type
668
+ if val = prepare_major_ticks(t, container)
669
+ spec['major_ticks'] = val[0]
670
+ spec['labels'] = val[1].map { |v| v.to_s }
671
+ end
672
+ return spec
673
+ end
674
+
675
+ # Draws the background lines associated with this axis, if
676
+ # applicable.
677
+ #
678
+ # This function requires Tioga SVN -r 482
679
+ def draw_lines(t, container)
680
+
681
+ return unless @lines_color
682
+ # First, getting major ticks location from tioga
683
+ info = t.axis_information(axis_argument(t, container))
684
+
685
+ if info['vertical']
686
+ x0 = t.bounds_left
687
+ x1 = t.bounds_right
688
+ else
689
+ y0 = t.bounds_bottom
690
+ y1 = t.bounds_top
691
+ end
692
+
693
+ t.context do
694
+ t.stroke_color = @lines_color
695
+ t.line_width = @lines_width || info['major_tick_width']
696
+ t.line_type = @lines_style
697
+ for val in info['major']
698
+ if info['vertical']
699
+ t.stroke_line(x0, val, x1, val)
700
+ else
701
+ t.stroke_line(val, y0, val, y1)
702
+ end
703
+ end
704
+ end
705
+ end
706
+
707
+ def label_shift(t)
708
+ shift = nil
709
+ if @ticks
710
+ shift = @ticks.shift
711
+ end
712
+ shift = t.send("#{@which}axis_numeric_label_shift") unless shift
713
+ return shift
714
+ end
715
+
716
+ def label_scale(t)
717
+ scale = nil
718
+ if @ticks
719
+ scale = @ticks.scale
720
+ end
721
+ scale = t.send("#{@which}axis_numeric_label_scale") unless scale
722
+ return scale
723
+ end
724
+
725
+ def extension(t, scale = 1)
726
+ ext = 0
727
+ f = [0,0,0,0]
728
+ # First, we estimate the size:
729
+ case @type
730
+ when AXIS_WITH_MAJOR_TICKS_AND_NUMERIC_LABELS,
731
+ AXIS_WITH_TICKS_AND_NUMERIC_LABELS
732
+ ext = (1 + (label_shift(t))) * label_scale(t) *
733
+ t.default_text_scale * t.default_font_size
734
+ else
735
+ ext = 0
736
+ end
737
+ loc_idx = Utils::location_index(@loc)
738
+ if loc_idx # That is, left,right, top, bottom
739
+ f[loc_idx] = ext
740
+ end
741
+ return f
742
+ end
743
+
744
+ # Manually shows the given element.
745
+ def show(t, container)
746
+ t.show_axis(axis_argument(t, container))
747
+ end
748
+
749
+ end
750
+
751
+ include Tioga::FigureConstants
752
+
753
+ include Log
754
+
755
+ Edges = [:left, :right, :top, :bottom]
756
+
757
+
758
+ # A hash containing the edge type for each edge.
759
+ attr_accessor :edge_specs
760
+
761
+ # A hash containing the default visibility for
762
+ # the edges.
763
+ attr_reader :edge_visibility
764
+
765
+ # The default values for the edges
766
+ Defaults = {
767
+ :left => AXIS_WITH_TICKS_AND_NUMERIC_LABELS,
768
+ :right => AXIS_WITH_TICKS_ONLY,
769
+ :top => AXIS_WITH_TICKS_ONLY,
770
+ :bottom => AXIS_WITH_TICKS_AND_NUMERIC_LABELS
771
+ }
772
+
773
+ # The main axes
774
+ attr_accessor :xaxis, :yaxis
775
+
776
+ # Named axes:
777
+ attr_accessor :axes
778
+
779
+
780
+ def initialize(xticks = nil, yticks = nil)
781
+ @edge_specs = Defaults.dup
782
+ @xaxis = Axis.new(:x, xticks)
783
+ @xaxis.type = AXIS_WITH_TICKS_AND_NUMERIC_LABELS
784
+ @yaxis = Axis.new(:y, yticks)
785
+ @yaxis.type = AXIS_WITH_TICKS_AND_NUMERIC_LABELS
786
+
787
+ # A handy shortcut
788
+ @axis = {:x => @xaxis, :y => @yaxis}
789
+
790
+ @edge_visibility = {}
791
+
792
+ @axes = {
793
+ 'xaxis' => @xaxis,
794
+ 'yaxis' => @yaxis,
795
+ }
796
+ end
797
+
798
+ def set_edges(value, *which)
799
+ which = Edges if which.empty?
800
+ for edge in which
801
+ @edge_specs[edge] = value
802
+ end
803
+ end
804
+
805
+ # Disable the given edges, or all if no arguments
806
+ def disable(*which)
807
+ set_edges(AXIS_HIDDEN, *which)
808
+ end
809
+
810
+ # Show only one line for the given edges.
811
+ def line_only(*which)
812
+ set_edges(AXIS_LINE_ONLY, *which)
813
+ end
814
+
815
+ # Returns either #xaxis or #yaxis depending on the value of
816
+ # which.
817
+ def axis(which)
818
+ return @axis[which]
819
+ end
820
+
821
+
822
+ # Sets up the edges for the given plot. Should probably be called
823
+ # just before the exit of the show_plot_with_legend block argument
824
+ def setup(t, container)
825
+ # Send axes informations.
826
+ @xaxis.setup(t, container)
827
+ @yaxis.setup(t, container)
828
+ for edge in Edges
829
+ t.send("#{edge}_edge_type=", @edge_specs[edge]) if
830
+ @edge_specs.key? edge
831
+ # Can only disable edges
832
+ if (@edge_visibility.key?(edge) && !@edge_visibility[edge])
833
+ t.send("#{edge}_edge_visible=", false)
834
+ end
835
+
836
+ end
837
+ end
838
+
839
+
840
+ # Sets the style for both the axis and the edges of the given
841
+ # side.
842
+ def set_axis_and_edges_style(axis, style)
843
+ case axis
844
+ when :x
845
+ @xaxis.type = style
846
+ set_edges(style, :top,:bottom)
847
+ when :y
848
+ @yaxis.type = style
849
+ set_edges(style, :left,:right)
850
+ else # for :left, :right, :top, :bottom
851
+ set_edges(style, axis)
852
+ end
853
+ end
854
+
855
+ # This does not take ticks into account yet. No need !
856
+ def extension(t, scale = 1)
857
+ f = [0,0,0,0]
858
+ Dimension.update_extensions(f, @xaxis.extension(t))
859
+ Dimension.update_extensions(f, @yaxis.extension(t))
860
+ debug "Edges and axis #{self.inspect} extension #{f.inspect}"
861
+ return f
862
+ end
863
+
864
+ # Choosing which edges are visible
865
+ def edge_visibility=(ar)
866
+ if ar.is_a?(Array) and ar.size == 4
867
+ 4.times do |i|
868
+ @edge_visibility[Edges[i]] = ar[i]
869
+ end
870
+ else
871
+ if ar
872
+ @edge_visibility = h.dup
873
+ end
874
+ end
875
+ end
876
+
877
+ # Sets the edge visibility for the given sides
878
+ def set_edges_visibility(which, what)
879
+ case which
880
+ when :y
881
+ @edge_visibility[:left] = @edge_visibility[:right] = what
882
+ when :x
883
+ @edge_visibility[:top] = @edge_visibility[:bottom] = what
884
+ end
885
+ end
886
+
887
+ # Called from PlotStyle#show_background to display
888
+ # axis lines.
889
+ def show_axis_lines(t, container)
890
+ for axis in @axes.keys.sort
891
+ @axes[axis].draw_lines(t, container)
892
+ end
893
+ end
894
+
895
+ # Draw all named non-standard axes
896
+ def show_additional_axes(t, container)
897
+ for name in @axes.keys - %w(xaxis yaxis)
898
+ @axes[name].show(t, container)
899
+ end
900
+ end
901
+
902
+ end
903
+ end
904
+