ctioga 1.11.1

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.
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
+