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 14function 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 285endfunction 286