8a55cf8410344d8e0386982bc60c8714afd53c91
[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         inter=1
197     end
198
199     wmax=inter/barh_number
200     y_shift=zeros(size(X,"*"),1)
201     bar_number= size(Y,2)
202     e=gce()
203     a=gca()
204     a.sub_ticks(2) = 0
205
206     for i=bar_number:-1:1
207
208         ei = e.children(i)
209
210         // Perform x_shift
211         if modulo(bar_number,2)==0 then
212             x_shift=(-i+bar_number/2)*wmax+0.4*wmax
213         elseif modulo(bar_number,2)==1 then
214             x_shift=(-i+1+floor(bar_number/2))*wmax
215         end
216
217         // Perform y_shift
218         if i==bar_number then
219             y_shift=zeros(size(X,"*"),1)
220         else
221             y_shift=Y(:,bar_number-i)+y_shift
222         end
223
224         // Update axes data bounds
225         // case 'grouped'
226         if STYLE=="grouped"
227             if i <> bar_number then
228                 ymin=min(a.data_bounds(1,1),min(Y(:,bar_number-i+1)),0)
229                 xmin=min(a.data_bounds(1,2),min(X)+x_shift-0.4*wmax)
230                 ymax=max(a.data_bounds(2,1),max(Y(:,bar_number-i+1)),0)
231                 xmax=max(a.data_bounds(2,2),max(X)+x_shift+0.4*wmax)
232             else
233                 if ~gca_children_empty
234                     ymin=min(min(Y(:,bar_number-i+1)),0)
235                     xmin=min(X)+x_shift-0.4*wmax
236                     ymax=max(max(Y(:,bar_number-i+1)),0)
237                     xmax=max(X)+x_shift+0.4*wmax
238                 else
239                     ymin=min(a_data_bounds(1,1),min(Y(:,bar_number-i+1)),0)
240                     xmin=min(a_data_bounds(1,2),min(X)+x_shift-0.4*wmax)
241                     ymax=max(a_data_bounds(2,1),max(Y(:,bar_number-i+1)),0)
242                     xmax=max(a_data_bounds(2,2),max(X)+x_shift+0.4*wmax)
243                 end
244             end
245             a.data_bounds=[ymin xmin;ymax xmax]
246             ei.x_shift=x_shift*ones(size(X,"*"),1)
247         else  // case 'stacked'
248             wmax=inter
249             if i <> bar_number then
250                 ymin=min(a.data_bounds(1,1),min(Y(:,bar_number-i+1)+y_shift))
251                 xmin=min(a.data_bounds(1,2),0,min(X-0.4*wmax))
252                 ymax=max(a.data_bounds(2,1),max(Y(:,bar_number-i+1)+y_shift))
253                 xmax=max(a.data_bounds(2,2),0,max(X+0.4*wmax))
254             else
255                 if ~gca_children_empty
256                     ymin=min(Y(:,bar_number-i+1)+y_shift)
257                     xmin=min(0,min(X-0.4*wmax))
258                     ymax=max(Y(:,bar_number-i+1)+y_shift)
259                     xmax=max(0,max(X+0.4*wmax))
260                 else
261                     ymin=min(a_data_bounds(1,1),min(Y(:,bar_number-i+1)+y_shift))
262                     xmin=min(a_data_bounds(1,2),0,min(X-0.4*wmax))
263                     ymax=max(a_data_bounds(2,1),max(Y(:,bar_number-i+1)+y_shift))
264                     xmax=max(a_data_bounds(2,2),0,max(X+0.4*wmax))
265                 end
266             end
267             a.data_bounds=[ymin xmin; ymax xmax]
268             ei.y_shift=y_shift
269         end
270
271         a.y_ticks=tlist("ticks",Xtemp,string(Xtemp))
272         w=WIDTH*wmax
273         ei.bar_width=w
274         ei.background=ei.foreground
275         ei.polyline_style=7; // bar type
276         ei.background=ei.foreground
277         ei.foreground = -1; // black by default
278         ei.line_mode="off";
279     end
280
281     //drawnow
282     curFig.immediate_drawing = immediate_drawing;
283
284 endfunction