* Bug #13579 fixed - bar displayed useless warnings.
[scilab.git] / scilab / modules / graphics / macros / bar.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 // This file must be used under the terms of the CeCILL.
5 // This source file is licensed as described in the file COPYING, which
6 // you should have received as part of this distribution.  The terms
7 // are also available at
8 // http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
9
10
11 function  bar(varargin)
12     // bar(x,y,width,style,color)
13     // This function  ...
14     //
15     // Input :
16     // x : a real scalar or a vector
17     // y : a real sclar, or a vector
18     // width : a double, the bar width, it's the percentage (0<width<1) of the width max of one bar which is wanted (default: width=0.8)
19     // style : a string 'grouped' or 'stacked' (default: style='grouped')
20
21     if size(varargin)<1 | size(varargin)>5  then
22         error(msprintf(gettext("%s: Wrong number of input argument(s): %d to %d expected.\n"), "bar", 1, 5));
23     end
24
25     styletab=["grouped","stacked"]
26     COLORBOOL=%f
27     STYLE="grouped"
28
29     //Check RHS argument
30     ListArg = varargin;
31
32     //detect and set the current axes now:
33     if type(ListArg(1)) == 9
34         hdle = ListArg(1);
35         if (hdle.type == "Axes")
36             sca(ListArg(1));
37             ListArg(1) = null(); // remove this parameter from the list
38         else
39             warning(msprintf(gettext("%s: Wrong type for input argument #%d: Axes handle expected.\n"),"bar",1));
40             return;
41         end
42     end
43
44     if size(ListArg) == 4 then
45         COLOR=ListArg(4);
46         if type(COLOR) <> 10 then
47             error(msprintf(gettext("%s: Wrong type for input arguments #%d: A string expected.\n"),"bar",4));
48         end
49     end
50     if size(ListArg) == 5 then
51         STYLE=ListArg(5);
52         if type(STYLE) <> 10 then
53             error(msprintf(gettext("%s: Wrong type for input arguments #%d: A string expected.\n"),"bar",5));
54         end
55     end
56     nv = size(ListArg)
57
58     T=[];
59
60     // Number of inputs arguments < 6
61     if  size(ListArg)>5 then
62         error(msprintf(gettext("%s: Wrong number of input arguments: %d to %d expected.\n"),"bar",1,5));
63     end
64
65     for k=1:nv
66         T(k) = type(ListArg(k))
67     end
68
69     argdb=find(T==1)
70     argstr=find(T==10)
71
72     if size(argdb,"*")<> argdb($) then
73         error(msprintf(gettext("%s: Wrong type for input arguments: Matrix expected for %s, %s and %s.\n"),"bar", "x", "y", "width"));
74     end
75
76     if size(argstr,"*") <> nv-argdb($) then
77         error(msprintf(gettext("%s: Wrong type for input arguments: String expected for %s and %s.\n"),"bar", "color", "style"));
78     end
79
80     //set the double argument : x,y,width
81     // bar(y,...)
82     if size(argdb,"*")==1
83         Y=ListArg(1)
84         WIDTH=0.8
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             // bar(x,y,...)
94             if size(ListArg(1),"*")==1 then
95                 WIDTH=0.8
96                 X=ListArg(1)
97                 Y=ListArg(2)
98             else
99                 //bar(y,width,...)
100                 WIDTH=ListArg(2)
101                 Y=ListArg(1)
102                 if or(size(Y)==1) then
103                     Y=Y(:)
104                 end
105                 X=1:size(Y,1)
106             end
107         else
108             // bar(x,y,...)
109             X=ListArg(1)
110             Y=ListArg(2)
111             if or(size(X)==1) then
112                 if size(X,"*")<>1 then // X is a vector
113                     if or(size(Y)==1) then // Y is a vector
114                         Y=Y(:)
115                     end
116                     if size(X,"*")<>size(Y,1) // Y is a matrix
117                         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));
118                     end
119                 elseif size(Y,1)>1 then
120                     error(msprintf(gettext("%s: Wrong size for input argument #%d: A scalar or a column vector expected.\n"),"bar",2));
121                 end
122             else
123                 error(msprintf(gettext("%s: Wrong type for input argument #%d: A scalar or a vector expected.\n"),"bar",1));
124             end
125             WIDTH=0.8
126         end
127     end
128
129     // bar(x,y,width,...)
130     if size(argdb,"*")==3
131         X=ListArg(1)
132         Y=ListArg(2)
133         WIDTH=ListArg(3)
134         if size(WIDTH,"*")<>1 then
135             error(msprintf(gettext("%s: Wrong type for input argument #%d: A scalar expected.\n"),"bar",3));
136         elseif or(size(X)==1) then
137             if size(X,"*")<>1 then // X is a vector
138                 if or(size(Y)==1) then // Y is a vector
139                     Y=Y(:)
140                 end
141                 if size(X,"*")<>size(Y,1)
142                     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))
143                 end
144             elseif size(Y,1)>1 then
145                 error(msprintf(gettext("%s: Wrong size for input arguments #%d: A scalar or a column vector expected.\n"),"bar",2));
146             end
147         else
148             error(msprintf(gettext("%s: Wrong type for input argument #%d: A scalar or a vector expected.\n"),"bar",1));
149         end
150     end
151     X=X(:)
152
153     // set the string argument
154     for i=1:size(argstr,"*")
155         // bar(...,style)
156         if or(ListArg(argstr(i))==styletab) then
157             STYLE=ListArg(argstr(i))
158         else
159             COLOR=ListArg(argstr(i))
160             COLORBOOL=%t
161         end
162     end
163
164     // drawlater
165     curFig = gcf();
166     immediate_drawing = curFig.immediate_drawing;
167
168     wmode = warning("query");
169     warning("off"); // See bug #13579 (some bar() calling sequences will lead to a plot() warning)
170     if COLORBOOL
171         plot(X,Y,COLOR); // plot manages immediate_drawing property itself to avoid flickering
172     else
173         plot(X,Y); // plot manages immediate_drawing property itself to avoid flickering
174     end
175     warning(wmode);
176
177     curFig.immediate_drawing = "off";
178
179     bar_number=size(Y,2)
180     if size(X,"*")>1 then
181         Xtemp=gsort(X,"r","i")
182         inter=Xtemp(2)-Xtemp(1)
183         for i=2:size(Xtemp,"*")-1
184             inter=min(Xtemp(i+1)-Xtemp(i),inter)
185         end
186         if bar_number>1
187             inter=inter*0.9
188         end
189     else
190         Xtemp=X
191         inter=1
192     end
193
194     wmax=inter/bar_number
195
196     y_shift=zeros(size(X,"*"),1)
197
198     bar_number= bar_number
199
200     e=gce()
201     a=gca()
202
203     a.sub_ticks(1) = 0; // bar (barh => a.sub_ticks(2) = 0;)
204
205     for i=bar_number:-1:1
206
207         ei = e.children(i);
208
209         // Perform x_shift
210         if modulo(bar_number,2)==0 then
211             x_shift=(-i+bar_number/2)*wmax+wmax/2
212         elseif modulo(bar_number,2)==1 then
213             x_shift=(-i+1+floor(bar_number/2))*wmax
214         end
215
216         // Perform y_shift
217         if i==bar_number then
218             y_shift=zeros(size(X,"*"),1)
219         else
220             y_shift=Y(:,bar_number-i)+y_shift
221         end
222
223         // Udate the axes data bounds
224         if STYLE=="grouped"
225             xmin=min(a.data_bounds(1,1),min(X)+x_shift-0.4*wmax)
226             ymin=min(a.data_bounds(1,2),0,min(y_shift+Y(:,bar_number-i+1)))
227             xmax=max(a.data_bounds(2,1),max(X)+x_shift+0.4*wmax)
228             ymax=max(a.data_bounds(2,2),0)
229             ei.x_shift=x_shift*ones(size(X,"*"),1)
230         else
231             wmax=inter
232             xmin=min(a.data_bounds(1,1),min(X)-0.4*wmax)
233             ymin=min(a.data_bounds(1,2),min(y_shift+Y(:,bar_number-i+1)))
234             xmax=max(a.data_bounds(2,1),max(X)+0.4*wmax)
235             ymax=max(a.data_bounds(2,2),max(y_shift+Y(:,bar_number-i+1)))
236             ei.y_shift=y_shift
237         end
238         a.data_bounds=[xmin ymin; xmax ymax]
239
240         a.x_ticks=tlist("ticks",Xtemp,string(Xtemp))
241
242         w=WIDTH*wmax
243
244         ei.bar_width=w
245         ei.background=ei.foreground
246         ei.polyline_style=6; // bar type
247         ei.background=ei.foreground
248         ei.foreground = -1; // black by default
249         ei.line_mode="off";
250     end
251
252     // drawnow
253     curFig.immediate_drawing = immediate_drawing;
254
255 endfunction