barh(1,[1 2 3]): Undefined variable Xtemp => FIXED
[scilab.git] / scilab / modules / graphics / macros / barh.sci
1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C) 2005 - INRIA - Farid Belahcene
3 // Copyright (C) 2012 - Michael Baudin
4 // Copyright (C) 2012 - 2016 - Scilab Enterprises
5 //
6 // This file is hereby licensed under the terms of the GNU GPL v2.0,
7 // pursuant to article 5.3.4 of the CeCILL v.2.1.
8 // This file was originally licensed under the terms of the CeCILL v2.1,
9 // and continues to be available under such terms.
10 // For more information, see the COPYING file which you should have received
11 // along with this program.
12
13
14 function  barh(varargin)
15
16     // barh(x,y,width,style,color)
17     // Input :
18     // x : a scalar or a vector of reals
19     // y : a scalar, a vector or a matrix of reals
20     // width : a double, the bar width, it's the percentage (0<width<1) of the max width of one bar which is wanted (default: width=0.8)
21     // style : a string, 'grouped' or 'stacked' (default: style='grouped')
22
23     if and(size(varargin)<>[1:5]) then
24         error(msprintf(gettext("%s: Wrong number of input argument(s): %d to %d expected.\n"), "barh", 1, 5));
25     end
26
27     styletab=["grouped","stacked"]
28     COLORBOOL=%f
29
30     // Default values
31     STYLE="grouped"
32     WIDTH=0.8
33     COLORBOOL=%f
34
35     // Check RHS arguments
36     ListArg = varargin;
37
38     // Detect and set the current axes now:
39     if type(ListArg(1)) == 9
40         hdle = ListArg(1);
41         if (hdle.type == "Axes")
42             sca(ListArg(1));
43             ListArg(1) = null(); // remove this parameter from the list
44         else
45             warning(msprintf(gettext("%s: Wrong type for input argument #%d: Axes handle expected.\n"),"barh",1));
46             return;
47         end
48     end
49     if size(ListArg) == 4 then
50         COLOR=ListArg(4);
51         if type(COLOR) <> 10 then
52             error(msprintf(gettext("%s: Wrong type for input argument #%d: string expected.\n"),"barh",4));
53         end
54     end
55     if size(ListArg) == 5 then
56         STYLE=ListArg(5);
57         if type(STYLE) <> 10 then
58             error(msprintf(gettext("%s: Wrong type for input argument #%d: string expected.\n"),"barh",5));
59         end
60     end
61
62     nv = size(ListArg)
63
64     T=[];
65
66     for k=1:nv
67         T(k) = type(ListArg(k))
68     end
69
70     argdb=find(T==1)
71     argstr=find(T==10)
72
73     if size(argdb,"*")<> argdb($) then
74         error(msprintf(gettext("%s: Wrong type for input arguments: Matrix expected for %s, %s and %s.\n"),"barh", "x", "y", "width"));
75     end
76
77     if size(argstr,"*") <> nv-argdb($) then
78         error(msprintf(gettext("%s: Wrong type for input arguments: String expected for %s and %s.\n"),"barh", "color", "style"));
79     end
80
81     // Set the double argument : x,y,width
82     // barh(y,...)
83     if size(argdb,"*")==1
84         Y=ListArg(1)
85         if or(size(Y)==1) then
86             Y=Y(:)
87         end
88         X=1:size(Y,1)
89     end
90
91     if size(argdb,"*")==2
92         if size(ListArg(2),"*")==1 then
93             // barh(x,y,...)
94             if size(ListArg(1),"*")==1 then
95                 X=ListArg(1)
96                 Y=ListArg(2)
97             else
98                 //barh(y,width,...)
99                 WIDTH=ListArg(2)
100                 Y=ListArg(1)
101                 if or(size(Y)==1) then
102                     Y=Y(:)
103                 end
104                 X=1:size(Y,1)
105             end
106         else
107             // barh(x,y,...)
108             X=ListArg(1)
109             Y=ListArg(2)
110             if or(size(X)==1) then
111                 if size(X,"*")<>1 then // X is a vector
112                     if or(size(Y)==1) then // Y is a vector
113                         Y=Y(:)
114                     end
115                     if size(X,"*")<>size(Y,1)
116                         error(msprintf(gettext("%s: Wrong size for input arguments #%d and #%d: The number of rows of argument #%d must be equal to the size of argument #%d.\n"),"bar",1, 2, 2, 1));
117                     end
118                 elseif size(Y,1)>1 then
119                     error(msprintf(gettext("%s: Wrong size for input arguments #%d: A scalar or a column vector expected.\n"),"bar",2));
120                 end
121             else
122                 error(msprintf(gettext("%s: Wrong type for input argument #%d: A scalar or a vector expected.\n"),"barh",1));
123             end
124         end
125     end
126
127     // barh(x,y,width,...)
128     if size(argdb,"*")==3
129         X=ListArg(1)
130         Y=ListArg(2)
131         WIDTH=ListArg(3)
132         if size(WIDTH,"*")<>1 then
133             error(msprintf(gettext("%s: Wrong type for input argument #%d: A scalar expected.\n"),"barh",3));
134         elseif or(size(X)==1) then
135             if size(X,"*")<>1 then // X is a vector
136                 if or(size(Y)==1) then // Y is a vector
137                     Y=Y(:)
138                 end
139                 if size(X,"*")<>size(Y,1)
140                     error(msprintf(gettext("%s: Wrong size for input arguments #%d and #%d: The number of rows of argument #%d must be equal to the size of argument #%d.\n"),"bar",1, 2, 2, 1));
141                 end
142             elseif size(Y,1)>1 then
143                 error(msprintf(gettext("%s: Wrong size for input arguments #%d: A scalar or a column vector expected.\n"),"bar",2));
144             end
145         else
146             error(msprintf(gettext("%s: Wrong type for input argument #%d: A scalar or a vector expected.\n"),"barh",1));
147         end
148     end
149
150     X=X(:)
151
152     // Set the string argument
153     for i=1:size(argstr,"*")
154         // barh(...,style)
155         if or(ListArg(argstr(i))==styletab) then
156             STYLE=ListArg(argstr(i))
157         else
158             COLOR=ListArg(argstr(i))
159             COLORBOOL=%t
160         end
161     end
162
163     // Verify if there are data bounds which are defined before creation the horizontal bars creation, in order to merge the data bounds
164     a=gca()
165     if size(a.children)<>0 then
166         gca_children_empty=%t
167         a_data_bounds=a.data_bounds
168     else
169         gca_children_empty=%f
170     end
171
172     //drawlater
173     curFig = gcf();
174     immediate_drawing = curFig.immediate_drawing;
175
176     if COLORBOOL
177         plot(X,Y,COLOR); // plot manages immediate_drawing property itself to avoid flickering
178     else
179         plot(X,Y); // plot manages immediate_drawing property itself to avoid flickering
180     end
181
182     curFig.immediate_drawing = "off";
183
184     barh_number=size(Y,2)
185
186     if size(X,"*")>1 then
187         Xtemp=gsort(X,"r","i")
188         inter=Xtemp(2)-Xtemp(1)
189         for i=2:size(Xtemp,"*")-1
190             inter=min(Xtemp(i+1)-Xtemp(i),inter)
191         end
192         if barh_number>1
193             inter=inter*0.9
194         end
195     else
196         Xtemp=X
197         inter=1
198     end
199
200     wmax=inter/barh_number
201     y_shift=zeros(size(X,"*"),1)
202     bar_number= size(Y,2)
203     e=gce()
204     a=gca()
205     a.sub_ticks(2) = 0
206
207     for i=bar_number:-1:1
208
209         ei = e.children(i)
210
211         // Perform x_shift
212         if modulo(bar_number,2)==0 then
213             x_shift=(-i+bar_number/2)*wmax+0.4*wmax
214         elseif modulo(bar_number,2)==1 then
215             x_shift=(-i+1+floor(bar_number/2))*wmax
216         end
217
218         // Perform y_shift
219         if i==bar_number then
220             y_shift=zeros(size(X,"*"),1)
221         else
222             y_shift=Y(:,bar_number-i)+y_shift
223         end
224
225         // Update axes data bounds
226         // case 'grouped'
227         if STYLE=="grouped"
228             if i <> bar_number then
229                 ymin=min(a.data_bounds(1,1),min(Y(:,bar_number-i+1)),0)
230                 xmin=min(a.data_bounds(1,2),min(X)+x_shift-0.4*wmax)
231                 ymax=max(a.data_bounds(2,1),max(Y(:,bar_number-i+1)),0)
232                 xmax=max(a.data_bounds(2,2),max(X)+x_shift+0.4*wmax)
233             else
234                 if ~gca_children_empty
235                     ymin=min(min(Y(:,bar_number-i+1)),0)
236                     xmin=min(X)+x_shift-0.4*wmax
237                     ymax=max(max(Y(:,bar_number-i+1)),0)
238                     xmax=max(X)+x_shift+0.4*wmax
239                 else
240                     ymin=min(a_data_bounds(1,1),min(Y(:,bar_number-i+1)),0)
241                     xmin=min(a_data_bounds(1,2),min(X)+x_shift-0.4*wmax)
242                     ymax=max(a_data_bounds(2,1),max(Y(:,bar_number-i+1)),0)
243                     xmax=max(a_data_bounds(2,2),max(X)+x_shift+0.4*wmax)
244                 end
245             end
246             a.data_bounds=[ymin xmin;ymax xmax]
247             ei.x_shift=x_shift*ones(size(X,"*"),1)
248         else  // case 'stacked'
249             wmax=inter
250             if i <> bar_number then
251                 ymin=min(a.data_bounds(1,1),min(Y(:,bar_number-i+1)+y_shift))
252                 xmin=min(a.data_bounds(1,2),0,min(X-0.4*wmax))
253                 ymax=max(a.data_bounds(2,1),max(Y(:,bar_number-i+1)+y_shift))
254                 xmax=max(a.data_bounds(2,2),0,max(X+0.4*wmax))
255             else
256                 if ~gca_children_empty
257                     ymin=min(Y(:,bar_number-i+1)+y_shift)
258                     xmin=min(0,min(X-0.4*wmax))
259                     ymax=max(Y(:,bar_number-i+1)+y_shift)
260                     xmax=max(0,max(X+0.4*wmax))
261                 else
262                     ymin=min(a_data_bounds(1,1),min(Y(:,bar_number-i+1)+y_shift))
263                     xmin=min(a_data_bounds(1,2),0,min(X-0.4*wmax))
264                     ymax=max(a_data_bounds(2,1),max(Y(:,bar_number-i+1)+y_shift))
265                     xmax=max(a_data_bounds(2,2),0,max(X+0.4*wmax))
266                 end
267             end
268             a.data_bounds=[ymin xmin; ymax xmax]
269             ei.y_shift=y_shift
270         end
271
272         a.y_ticks=tlist("ticks",Xtemp,string(Xtemp))
273         w=WIDTH*wmax
274         ei.bar_width=w
275         ei.background=ei.foreground
276         ei.polyline_style=7; // bar type
277         ei.background=ei.foreground
278         ei.foreground = -1; // black by default
279         ei.line_mode="off";
280     end
281
282     //drawnow
283     curFig.immediate_drawing = immediate_drawing;
284
285 endfunction