Mercurial > hg > octave-nkf
comparison scripts/plot/util/struct2hdl.m @ 17572:7bb76a22cde1
maint: Split scripts/plot directory into 4 pieces.
scripts/gui : user-interface functions
scripts/plot/appearance : functions controlling plot appearance
scripts/plot/draw : plotting functions which produce graphs
scripts/plot/util : low-level plotting functions and utilities.
* scripts/gui/guidata.m, scripts/gui/guihandles.m, scripts/gui/module.mk,
scripts/gui/private/__file_filter__.m,
scripts/gui/private/__fltk_file_filter__.m,
scripts/gui/private/__is_function__.m, scripts/gui/private/__uigetdir_fltk__.m,
scripts/gui/private/__uigetfile_fltk__.m,
scripts/gui/private/__uiobject_split_args__.m,
scripts/gui/private/__uiputfile_fltk__.m, scripts/gui/uicontextmenu.m,
scripts/gui/uicontrol.m, scripts/gui/uigetdir.m, scripts/gui/uigetfile.m,
scripts/gui/uimenu.m, scripts/gui/uipanel.m, scripts/gui/uipushtool.m,
scripts/gui/uiputfile.m, scripts/gui/uiresume.m, scripts/gui/uitoggletool.m,
scripts/gui/uitoolbar.m, scripts/gui/uiwait.m, scripts/gui/waitbar.m,
scripts/gui/waitforbuttonpress.m: Moved from scripts/plot to scripts/gui
* scripts/plot/appearance/__clabel__.m,
scripts/plot/appearance/__getlegenddata__.m, scripts/plot/appearance/axis.m,
scripts/plot/appearance/box.m, scripts/plot/appearance/caxis.m,
scripts/plot/appearance/clabel.m, scripts/plot/appearance/daspect.m,
scripts/plot/appearance/diffuse.m, scripts/plot/appearance/grid.m,
scripts/plot/appearance/gtext.m, scripts/plot/appearance/hidden.m,
scripts/plot/appearance/legend.m,
scripts/plot/appearance/orient.m, scripts/plot/appearance/pbaspect.m,
scripts/plot/appearance/private/__axis_label__.m,
scripts/plot/appearance/private/__axis_limits__.m,
scripts/plot/appearance/shading.m, scripts/plot/appearance/specular.m,
scripts/plot/appearance/text.m, scripts/plot/appearance/title.m,
scripts/plot/appearance/view.m, scripts/plot/appearance/whitebg.m,
scripts/plot/appearance/xlabel.m, scripts/plot/appearance/xlim.m,
scripts/plot/appearance/ylabel.m, scripts/plot/appearance/ylim.m,
scripts/plot/appearance/zlabel.m, scripts/plot/appearance/zlim.m:
Moved from scripts/plot to subdir appearance.
* scripts/plot/draw/area.m, scripts/plot/draw/bar.m, scripts/plot/draw/barh.m,
scripts/plot/draw/colorbar.m, scripts/plot/draw/comet.m,
scripts/plot/draw/comet3.m, scripts/plot/draw/compass.m,
scripts/plot/draw/contour.m, scripts/plot/draw/contour3.m,
scripts/plot/draw/contourc.m, scripts/plot/draw/contourf.m,
scripts/plot/draw/cylinder.m, scripts/plot/draw/ellipsoid.m,
scripts/plot/draw/errorbar.m, scripts/plot/draw/ezcontour.m,
scripts/plot/draw/ezcontourf.m, scripts/plot/draw/ezmesh.m,
scripts/plot/draw/ezmeshc.m, scripts/plot/draw/ezplot.m,
scripts/plot/draw/ezplot3.m, scripts/plot/draw/ezpolar.m,
scripts/plot/draw/ezsurf.m, scripts/plot/draw/ezsurfc.m,
scripts/plot/draw/feather.m, scripts/plot/draw/fill.m,
scripts/plot/draw/fplot.m, scripts/plot/draw/hist.m,
scripts/plot/draw/isocolors.m, scripts/plot/draw/isonormals.m,
scripts/plot/draw/isosurface.m, scripts/plot/draw/line.m,
scripts/plot/draw/loglog.m, scripts/plot/draw/loglogerr.m,
scripts/plot/draw/mesh.m, scripts/plot/draw/meshc.m, scripts/plot/draw/meshz.m,
scripts/plot/draw/pareto.m,
scripts/plot/draw/patch.m, scripts/plot/draw/pcolor.m,
scripts/plot/draw/peaks.m, scripts/plot/draw/pie.m, scripts/plot/draw/pie3.m,
scripts/plot/draw/plot.m, scripts/plot/draw/plot3.m,
scripts/plot/draw/plotmatrix.m, scripts/plot/draw/plotyy.m,
scripts/plot/draw/polar.m, scripts/plot/draw/private/__add_datasource__.m,
scripts/plot/draw/private/__bar__.m, scripts/plot/draw/private/__contour__.m,
scripts/plot/draw/private/__errcomm__.m,
scripts/plot/draw/private/__errplot__.m,
scripts/plot/draw/private/__ezplot__.m,
scripts/plot/draw/private/__interp_cube__.m,
scripts/plot/draw/private/__line__.m,
scripts/plot/draw/private/__marching_cube__.m,
scripts/plot/draw/private/__patch__.m, scripts/plot/draw/private/__pie__.m,
scripts/plot/draw/private/__plt__.m, scripts/plot/draw/private/__quiver__.m,
scripts/plot/draw/private/__scatter__.m, scripts/plot/draw/private/__stem__.m,
scripts/plot/draw/quiver.m, scripts/plot/draw/quiver3.m,
scripts/plot/draw/rectangle.m, scripts/plot/draw/ribbon.m,
scripts/plot/draw/rose.m, scripts/plot/draw/scatter.m,
scripts/plot/draw/scatter3.m, scripts/plot/draw/semilogx.m,
scripts/plot/draw/semilogxerr.m, scripts/plot/draw/semilogy.m,
scripts/plot/draw/semilogyerr.m, scripts/plot/draw/shrinkfaces.m,
scripts/plot/draw/slice.m, scripts/plot/draw/sombrero.m,
scripts/plot/draw/sphere.m, scripts/plot/draw/stairs.m,
scripts/plot/draw/stem.m, scripts/plot/draw/stem3.m,
scripts/plot/draw/stemleaf.m, scripts/plot/draw/surf.m,
scripts/plot/draw/surface.m, scripts/plot/draw/surfc.m,
scripts/plot/draw/surfl.m, scripts/plot/draw/surfnorm.m,
scripts/plot/draw/tetramesh.m, scripts/plot/draw/trimesh.m,
scripts/plot/draw/triplot.m, scripts/plot/draw/trisurf.m,
scripts/plot/draw/waterfall.m: Moved from plot/ to subdir draw.
* scripts/plot/util/__actual_axis_position__.m,
scripts/plot/util/__default_plot_options__.m,
scripts/plot/util/__gnuplot_drawnow__.m,
scripts/plot/util/__next_line_color__.m,
scripts/plot/util/__next_line_style__.m,
scripts/plot/util/__plt_get_axis_arg__.m, scripts/plot/util/__pltopt__.m,
scripts/plot/util/allchild.m, scripts/plot/util/ancestor.m,
scripts/plot/util/axes.m, scripts/plot/util/cla.m, scripts/plot/util/clf.m,
scripts/plot/util/close.m, scripts/plot/util/closereq.m,
scripts/plot/util/colstyle.m, scripts/plot/util/copyobj.m,
scripts/plot/util/figure.m, scripts/plot/util/findall.m,
scripts/plot/util/findfigs.m, scripts/plot/util/findobj.m,
scripts/plot/util/gca.m, scripts/plot/util/gcbf.m, scripts/plot/util/gcbo.m,
scripts/plot/util/gcf.m, scripts/plot/util/gco.m, scripts/plot/util/ginput.m,
scripts/plot/util/gnuplot_binary.in, scripts/plot/util/graphics_toolkit.m,
scripts/plot/util/hdl2struct.m, scripts/plot/util/hggroup.m,
scripts/plot/util/hold.m, scripts/plot/util/isaxes.m,
scripts/plot/util/isfigure.m, scripts/plot/util/ishghandle.m,
scripts/plot/util/ishold.m, scripts/plot/util/isprop.m,
scripts/plot/util/linkprop.m, scripts/plot/util/meshgrid.m,
scripts/plot/util/ndgrid.m,
scripts/plot/util/newplot.m, scripts/plot/util/print.m,
scripts/plot/util/printd.m, scripts/plot/util/private/__add_default_menu__.m,
scripts/plot/util/private/__fltk_ginput__.m,
scripts/plot/util/private/__fltk_print__.m,
scripts/plot/util/private/__ghostscript__.m,
scripts/plot/util/private/__gnuplot_get_var__.m,
scripts/plot/util/private/__gnuplot_ginput__.m,
scripts/plot/util/private/__gnuplot_has_feature__.m,
scripts/plot/util/private/__gnuplot_has_terminal__.m,
scripts/plot/util/private/__gnuplot_open_stream__.m,
scripts/plot/util/private/__gnuplot_print__.m,
scripts/plot/util/private/__gnuplot_version__.m,
scripts/plot/util/private/__go_draw_axes__.m,
scripts/plot/util/private/__go_draw_figure__.m,
scripts/plot/util/private/__print_parse_opts__.m,
scripts/plot/util/private/__tight_eps_bbox__.m, scripts/plot/util/refresh.m,
scripts/plot/util/refreshdata.m, scripts/plot/util/saveas.m,
scripts/plot/util/shg.m, scripts/plot/util/struct2hdl.m,
scripts/plot/util/subplot.m: Moved from plot to subdir util.
* etc/HACKING: Updated directory structure info.
* scripts/Makefile.am, scripts/plot/appearance/module.mk,
scripts/plot/draw/module.mk, scripts/plot/util/module.mk:
Added new directories to build system.
author | Rik <rik@octave.org> |
---|---|
date | Fri, 04 Oct 2013 17:09:08 -0700 |
parents | scripts/plot/struct2hdl.m@0b3cf264ec2f |
children | d63878346099 |
comparison
equal
deleted
inserted
replaced
17571:6e4ea5c8a4bb | 17572:7bb76a22cde1 |
---|---|
1 ## Copyright (C) 2012 pdiribarne | |
2 ## | |
3 ## This program is free software; you can redistribute it and/or modify | |
4 ## it under the terms of the GNU General Public License as published by | |
5 ## the Free Software Foundation; either version 3 of the License, or | |
6 ## (at your option) any later version. | |
7 ## | |
8 ## This program is distributed in the hope that it will be useful, | |
9 ## but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 ## GNU General Public License for more details. | |
12 ## | |
13 ## You should have received a copy of the GNU General Public License | |
14 ## along with Octave; see the file COPYING. If not, see | |
15 ## <http://www.gnu.org/licenses/>. | |
16 | |
17 ## -*- texinfo -*- | |
18 ## @deftypefn {Function File} {@var{h} =} struct2hdl (@var{s}) | |
19 ## @deftypefnx {Function File} {@var{h} =} struct2hdl (@var{s}, @var{p}) | |
20 ## @deftypefnx {Function File} {@var{h} =} struct2hdl (@var{s}, @var{p}, @var{hilev}) | |
21 ## Construct a graphics handle object @var{h} from the structure @var{s}. | |
22 ## | |
23 ## The structure must contain the fields @qcode{"handle"}, @qcode{"type"}, | |
24 ## @qcode{"children"}, @qcode{"properties"}, and @qcode{"special"}. If the | |
25 ## handle of an existing figure or axes is specified, @var{p}, the new object | |
26 ## will be created as a child of that object. If no parent handle is provided | |
27 ## then a new figure and the necessary children will be constructed using the | |
28 ## default values from the root figure. | |
29 ## | |
30 ## A third boolean argument @var{hilev} can be passed to specify whether | |
31 ## the function should preserve listeners/callbacks, e.g., for legends or | |
32 ## hggroups. The default is false. | |
33 ## @seealso{hdl2struct, findobj} | |
34 ## @end deftypefn | |
35 | |
36 ## Author: pdiribarne <pdiribarne@new-host.home> | |
37 ## Created: 2012-03-04 | |
38 | |
39 function [h, pout] = struct2hdl (s, p=[], hilev = false) | |
40 | |
41 fields = {"handle", "type", "children", "properties", "special"}; | |
42 partypes = {"root", "figure", "axes", "hggroup"}; | |
43 othertypes = {"line", "patch", "surface", "image", "text"}; | |
44 alltypes = [partypes othertypes]; | |
45 | |
46 if (nargin > 3 || ! isstruct (s)) | |
47 print_usage (); | |
48 elseif (! all (isfield (s, fields))) | |
49 print_usage (); | |
50 elseif (isscalar (p)) | |
51 if (! ishandle (p)) | |
52 error ("struct2hdl: P is not a handle to a graphic object"); | |
53 endif | |
54 if (any (strcmp (get (p).type, partypes))) | |
55 paridx = find (strcmp (get (p).type, alltypes)); | |
56 kididx = find (strcmp (s.type, alltypes)); | |
57 if (kididx <= paridx) | |
58 error ("struct2hdl: incompatible input handles"); | |
59 endif | |
60 else | |
61 error ("struct2hdl: %s object can't be parent object", get (p).type); | |
62 endif | |
63 hpar = p; | |
64 p = [NaN; hpar]; | |
65 ## create appropriate parent if needed | |
66 if (any (strcmp (s.type, othertypes))) | |
67 for ii = (paridx+1) : (numel (partypes)-1) | |
68 eval (["hpar = " partypes{ii} "(\"parent\", hpar);"]); | |
69 p = [p [NaN; hpar]]; | |
70 endfor | |
71 elseif (any (strcmp (s.type, {"hggroup", "axes"}))) | |
72 for ii = (paridx+1) : (kididx-1) | |
73 eval (["hpar = " partypes{ii} "(\"parent\", hpar);"]); | |
74 p = [p [NaN; hpar]]; | |
75 endfor | |
76 else | |
77 par = NaN; | |
78 endif | |
79 elseif (isempty (p)) | |
80 if (any (strcmp (s.type, othertypes))) | |
81 par = axes (); | |
82 elseif (any (strcmp (s.type, {"hggroup", "axes"}))) | |
83 par = figure (); | |
84 else | |
85 par = NaN; | |
86 endif | |
87 p = [NaN; par]; | |
88 endif | |
89 ## read parent (last column) in p and remove it if duplicate | |
90 par = p(2,end); | |
91 tst = find (p(2,:) == par); | |
92 if (numel (tst) > 1) | |
93 p = p(1:2, 1:(tst(end)-1)); | |
94 endif | |
95 | |
96 ## Place the "*mode" properties at the end to avoid having the updaters | |
97 ## change the mode to "manual" when the value is "auto". | |
98 names = fieldnames (s.properties); | |
99 n = strncmp (cellfun (@fliplr, names, "uniformoutput", false), "edom", 4); | |
100 n = (n | strcmp (names, "activepositionproperty")); | |
101 names = [names(!n); names(n)]; | |
102 if (strcmp (s.type, "axes")) | |
103 n_pos = find (strcmp (names, "position") | strcmp (names, "outerposition")); | |
104 if (strcmp (s.properties.activepositionproperty, "position")) | |
105 names{n_pos(1)} = "outerposition"; | |
106 names{n_pos(2)} = "position"; | |
107 else | |
108 names{n_pos(1)} = "position"; | |
109 names{n_pos(2)} = "outerposition"; | |
110 endif | |
111 endif | |
112 ## Reorder the properties with the mode properties coming last | |
113 s.properties = orderfields (s.properties, names); | |
114 | |
115 ## create object | |
116 if (strcmp (s.type, "root")) | |
117 h = 0; | |
118 s.properties = rmfield (s.properties, ... | |
119 {"callbackobject", "commandwindowsize", ... | |
120 "screendepth", "screenpixelsperinch", ... | |
121 "screensize"}); | |
122 elseif (strcmp (s.type, "figure")) | |
123 h = figure (); | |
124 elseif (strcmp (s.type, "axes")) | |
125 ## legends and colorbars are "transformed" in normal axes | |
126 ## if hilev is not requested | |
127 if (! hilev) | |
128 if (strcmp (s.properties.tag, "legend")) | |
129 s.properties.tag = ""; | |
130 s.properties.userdata = []; | |
131 par = gcf; | |
132 elseif (strcmp (s.properties.tag, "colorbar")) | |
133 s.properties.tag = ""; | |
134 s.properties.userdata = []; | |
135 par = gcf; | |
136 endif | |
137 endif | |
138 | |
139 [h, s] = createaxes (s, p, par); | |
140 elseif (strcmp (s.type, "line")) | |
141 h = createline (s, par); | |
142 elseif (strcmp (s.type, "patch")) | |
143 [h, s] = createpatch (s, par); | |
144 elseif (strcmp (s.type, "text")) | |
145 h = createtext (s, par); | |
146 elseif (strcmp (s.type, "image")) | |
147 h = createimage (s, par); | |
148 elseif (strcmp (s.type, "surface")) | |
149 h = createsurface (s, par); | |
150 elseif (strcmp (s.type, "hggroup")) | |
151 [h, s, p] = createhg (s, p, par, hilev); | |
152 else | |
153 error ("struct2hdl: %s objects are not implemented yet", s.type) | |
154 endif | |
155 | |
156 ## children | |
157 p = [p [s.handle; h]]; # [original; new] | |
158 kids = s.children; | |
159 nkids = length (kids); | |
160 ii = 0; | |
161 while (nkids) | |
162 ii++; | |
163 if (! any (ii == s.special)) | |
164 [h2, p] = struct2hdl (s.children(ii), [p [s.handle; h]], hilev); | |
165 endif | |
166 nkids--; | |
167 endwhile | |
168 | |
169 ## paste properties | |
170 setprops (s, h, p, hilev); | |
171 | |
172 pout = p; | |
173 | |
174 endfunction | |
175 | |
176 function [h, sout] = createaxes (s, p, par) | |
177 ## regular axes | |
178 if (strcmp (s.properties.tag, "")) | |
179 propval = {"position", s.properties.position}; | |
180 hid = {"autopos_tag", "looseinset"}; | |
181 for ii = 1:numel (hid) | |
182 prop = hid{ii}; | |
183 if (isfield (s.properties, prop)) | |
184 val = s.properties.(prop); | |
185 propval = [propval, prop, val]; | |
186 endif | |
187 endfor | |
188 h = axes (propval{:}, "parent", par); | |
189 | |
190 if (isfield (s.properties, "__plotyy_axes__")) | |
191 plty = s.properties.__plotyy_axes__; | |
192 addproperty ("__plotyy_axes__", h, "data"); | |
193 tmp = [p [s.handle; h]]; | |
194 tst = ismember (tmp(1:2:end), plty); | |
195 if (sum (tst) == numel (plty)) | |
196 for ii = 1:numel (plty) | |
197 plty(ii) = tmp(find (tmp == plty(ii)) + 1); | |
198 endfor | |
199 for ii = 1:numel (plty) | |
200 set (plty(ii), "__plotyy_axes__", plty); | |
201 endfor | |
202 endif | |
203 s.properties = rmfield (s.properties, "__plotyy_axes__"); | |
204 endif | |
205 | |
206 ## delete non-default and already set properties | |
207 fields = fieldnames (s.properties); | |
208 tst = cellfun (@(x) isprop (h, x), fields); | |
209 s.properties = rmfield (s.properties, fields(find (tst == 0))); | |
210 | |
211 elseif (strcmp (s.properties.tag, "legend")) | |
212 ## legends | |
213 oldax = s.properties.userdata.handle; | |
214 idx = find (p == oldax); | |
215 newax = p(idx+1); | |
216 strings = {}; | |
217 kids = s.children; | |
218 kids(s.special) = []; | |
219 oldh = unique (arrayfun (@(x) x.properties.userdata(end), kids)); | |
220 for ii = 1:length (oldh) | |
221 idx = find (p(1:2:end) == oldh(ii)) * 2; | |
222 if (! isempty (idx)) | |
223 newh(ii) = p(idx); | |
224 if (! strcmp (get (newh(ii), "type"), "hggroup")) | |
225 str = get (newh(ii), "displayname"); | |
226 strings = [strings str]; | |
227 else | |
228 str = get (get (newh(ii), "children")(1), "displayname"); | |
229 strings = [strings str]; | |
230 endif | |
231 else | |
232 error ("struct2hdl: didn't find a legend item"); | |
233 endif | |
234 endfor | |
235 location = s.properties.location; | |
236 orientation = s.properties.orientation; | |
237 textpos = s.properties.textposition; | |
238 box = s.properties.box; | |
239 | |
240 h = legend (newax, newh, strings, "location", location, ... | |
241 "orientation", orientation); | |
242 set (h, "textposition", textpos); # bug makes "textposition" | |
243 # redefine the legend | |
244 h = legend (newax, newh, strings, "location", location, ... | |
245 "orientation", orientation); | |
246 ## box | |
247 if (strcmp (box, "on")) | |
248 legend ("boxon"); | |
249 endif | |
250 | |
251 ## visibility | |
252 tst = arrayfun (@(x) strcmp (x.properties.visible, "on"), kids); | |
253 if (! any (tst)) | |
254 legend ("hide"); | |
255 endif | |
256 | |
257 ## remove all properties such as "textposition" that redefines | |
258 ## the entire legend. Also remove chidren | |
259 s.properties = rmfield (s.properties, ... | |
260 {"userdata", "xlabel",... | |
261 "ylabel", "zlabel", "location", ... | |
262 "title", "string","orientation", ... | |
263 "visible", "textposition"}); | |
264 | |
265 s.children = []; | |
266 | |
267 elseif (strcmp (s.properties.tag, "colorbar")) | |
268 ## colorbar | |
269 oldax = s.properties.axes; | |
270 if (! isempty (idx = find (oldax == p))) | |
271 ax = p(idx+1); | |
272 location = s.properties.location; | |
273 h = colorbar ("peer", ax, location); | |
274 s.properties = rmfield (s.properties, ... | |
275 {"userdata", "xlabel" ... | |
276 "ylabel", "zlabel", ... | |
277 "title", "axes"}); | |
278 s.children= []; | |
279 else | |
280 error ("hdl2struct: didn't find an object"); | |
281 endif | |
282 endif | |
283 sout = s; | |
284 endfunction | |
285 | |
286 function h = createline (s, par) | |
287 h = line ("parent", par); | |
288 addmissingprops (h, s.properties); | |
289 endfunction | |
290 | |
291 function [h, sout] = createpatch (s, par) | |
292 prp.faces = s.properties.faces; | |
293 prp.vertices = s.properties.vertices; | |
294 prp.facevertexcdata = s.properties.facevertexcdata; | |
295 h = patch (prp); | |
296 set (h, "parent", par); | |
297 s.properties = rmfield (s.properties, | |
298 {"faces", "vertices", "facevertexcdata"}); | |
299 addmissingprops (h, s.properties); | |
300 sout = s; | |
301 endfunction | |
302 | |
303 function h = createtext (s, par) | |
304 h = text ("parent", par); | |
305 addmissingprops (h, s.properties); | |
306 endfunction | |
307 | |
308 function h = createimage (s, par) | |
309 h = image (1, "parent", par); | |
310 addmissingprops (h, s.properties); | |
311 endfunction | |
312 | |
313 function h = createsurface (s, par) | |
314 h = surface ("parent", par); | |
315 addmissingprops (h, s.properties); | |
316 endfunction | |
317 | |
318 function [h, sout, pout] = createhg (s, p, par, hilev) | |
319 ## Here we infer from properties the type of hggroup we should build | |
320 ## an call corresponding high level functions | |
321 ## We manually set "hold on" to avoid next hggroup be deleted | |
322 ## the proper value of axes "nextplot" will finally be recovered | |
323 | |
324 hold on; | |
325 if (hilev) | |
326 [h, s, p] = createhg_hilev (s, p, par); | |
327 if (numel (s.children) != numel (get (h).children)) | |
328 warning (["struct2hdl: could not infer the hggroup type. ", ... | |
329 "Will build objects but listener/callback functions ", ... | |
330 "will be lost"]); | |
331 if (isfield (h, "bargroup")) | |
332 delete (get (h).bargroup); | |
333 else | |
334 delete (h); | |
335 endif | |
336 h = hggroup ("parent", par); | |
337 addmissingprops (h, s.properties); | |
338 s.special = []; | |
339 else | |
340 oldkids = s.children; | |
341 newkids = get (h).children; | |
342 nkids = numel (oldkids); | |
343 ii = 1; | |
344 while (nkids) | |
345 p = [p [oldkids(ii++).handle; newkids(nkids--)]]; | |
346 endwhile | |
347 endif | |
348 else | |
349 h = hggroup ("parent", par); | |
350 addmissingprops (h, s.properties); | |
351 s.special = []; | |
352 endif | |
353 sout = s; | |
354 pout = p; | |
355 endfunction | |
356 | |
357 function [h, sout, pout] = createhg_hilev (s, p, par) | |
358 fields = s.properties; | |
359 if (isfield (fields, "contourmatrix")) | |
360 ## contours | |
361 xdata = s.properties.xdata; | |
362 ydata = s.properties.ydata; | |
363 zdata = s.properties.zdata; | |
364 levellist = s.properties.levellist; | |
365 textlist = s.properties.textlist; | |
366 | |
367 ## contour creation | |
368 if (isempty (s.children(1).properties.zdata)) | |
369 if (strcmpi (s.properties.fill, "on")) | |
370 [cm2, h] = contourf (xdata, ydata, zdata, levellist); | |
371 else | |
372 [cm2, h] = contour (xdata, ydata, zdata, levellist); | |
373 endif | |
374 | |
375 ## labels | |
376 if (strcmpi (s.properties.showtext, "on")) | |
377 clabel (cm2, h, textlist); | |
378 endif | |
379 else | |
380 [cm2, h] = contour3 (xdata, ydata, zdata, levellist); | |
381 endif | |
382 | |
383 ## delete already set properties and children | |
384 s.properties = rmfield (s.properties, ... | |
385 {"xdata", "ydata", "zdata", ... | |
386 "contourmatrix", "levellist", ... | |
387 "fill", "labelspacing", ... | |
388 "levellistmode", "levelstep", ... | |
389 "levelstepmode", "textlist"... | |
390 "textlistmode" , "textstep", ... | |
391 "textstepmode", "zlevel", ... | |
392 "zlevelmode"}); | |
393 | |
394 elseif (isfield (fields, "udata") && isfield (fields, "vdata")) | |
395 ## quiver | |
396 xdata = s.properties.xdata; | |
397 ydata = s.properties.ydata; | |
398 | |
399 udata = s.properties.udata; | |
400 vdata = s.properties.vdata; | |
401 | |
402 h = quiver (xdata, ydata, udata, vdata); | |
403 | |
404 ## delete already set properties and children | |
405 s.properties = rmfield (s.properties, ... | |
406 {"xdata", "ydata", "zdata", ... | |
407 "xdatasource", "ydatasource", "zdatasource", ... | |
408 "udata", "vdata", "wdata", ... | |
409 "udatasource", "vdatasource", "wdatasource"}); | |
410 | |
411 elseif (isfield (fields, "format")) | |
412 ##errorbar | |
413 form = s.properties.format; | |
414 xdata = s.properties.xdata; | |
415 ydata = s.properties.ydata; | |
416 xldata = s.properties.xldata; | |
417 ldata = s.properties.ldata; | |
418 xudata = s.properties.xudata; | |
419 udata = s.properties.udata; | |
420 | |
421 switch (form) | |
422 case "xerr" | |
423 h = errorbar (xdata, ydata, xldata, xudata, ">"); | |
424 case "yerr" | |
425 h = errorbar (xdata, ydata, ldata, udata, "~"); | |
426 case "xyerr" | |
427 h = errorbar (xdata, ydata, xldata, xudata, ldata, udata, "~>"); | |
428 case "box" | |
429 h = errorbar (xdata, ydata, xldata, xudata, "#"); | |
430 case "boxy" | |
431 h = errorbar (xdata, ydata, ldata, udata, "#~"); | |
432 case "boxxy" | |
433 h = errorbar (xdata, ydata, xldata, xudata, ldata, udata, "#~>"); | |
434 otherwise | |
435 error ("struct2hdl: couldn't guess the errorbar format"); | |
436 endswitch | |
437 ## delete already set properties | |
438 s.properties = rmfield (s.properties, ... | |
439 {"xdata", "ydata", ... | |
440 "xldata", "ldata", ... | |
441 "xudata", "udata", ... | |
442 "xldatasource", "ldatasource", ... | |
443 "xudatasource", "udatasource", ... | |
444 "format"}); | |
445 | |
446 elseif (isfield (fields, "bargroup")) | |
447 ## bar plot | |
448 ## FIXME - here we don't have access to brothers so we first create all | |
449 ## the barseries of the bargroup (but the last), then retrieve information, | |
450 ## and rebuild the whole bargroup. | |
451 ## The duplicate are deleted after calling "setprops" | |
452 | |
453 bargroup = s.properties.bargroup; | |
454 oldh = s.handle; | |
455 | |
456 temp = ismember ([p(1:2:end) oldh], bargroup); | |
457 | |
458 tst = sum (temp) == length (bargroup); | |
459 | |
460 if (isscalar (bargroup) || !tst) | |
461 xdata = s.properties.xdata; | |
462 ydata = s.properties.ydata; | |
463 | |
464 h = bar (xdata, ydata); | |
465 | |
466 ## delete already set properties, | |
467 s.properties = rmfield (s.properties, ... | |
468 {"xdata", "ydata", ... | |
469 "xdatasource", "ydatasource", ... | |
470 "bargroup", ... | |
471 "barwidth", "baseline"}); | |
472 else | |
473 xdata = []; | |
474 ydata = []; | |
475 | |
476 ##build x/y matrix | |
477 nbar = length (bargroup); | |
478 tmp = struct ("handle", NaN, "type", "", "children", [], "special", []); | |
479 for ii = 1:(nbar - 1) | |
480 idx = find (p(1:2:end) == bargroup(ii)) * 2; | |
481 hdl = p (idx); | |
482 xdata = [xdata get(hdl).xdata]; | |
483 ydata = [ydata get(hdl).ydata]; | |
484 tmp.children(ii) = hdl2struct (hdl); | |
485 endfor | |
486 | |
487 xdata = [xdata s.properties.xdata]; | |
488 ydata = [ydata s.properties.ydata]; | |
489 width = s.properties.barwidth; | |
490 h = bar (ydata, width); | |
491 | |
492 ## replace previous handles in "match", copy props and delete redundant | |
493 for ii = 1:(nbar - 1) | |
494 props = tmp.children(ii).properties; | |
495 bl = props.baseline; | |
496 tmp.children(ii).properties = rmfield (props, {"baseline", "bargroup"}); | |
497 setprops (tmp.children(ii), h(ii), p, 1); | |
498 delete (tmp.children(ii).handle); | |
499 delete (bl); | |
500 idxpar = find (p == tmp.children(ii).handle); | |
501 p(idxpar) = h(ii); | |
502 idxkid = idxpar - 2; | |
503 p(idxkid) = get (h(ii), "children"); | |
504 endfor | |
505 p(2,((end-nbar+2):end)) = h(1:(end-1)); | |
506 h = h(end); | |
507 | |
508 ## delete already set properties , | |
509 s.properties = rmfield (s.properties, ... | |
510 {"xdata", "ydata", "bargroup"... | |
511 "barwidth", "baseline"}); | |
512 endif | |
513 elseif (isfield (fields, "baseline")) | |
514 ## stem plot | |
515 xdata = s.properties.xdata; | |
516 ydata = s.properties.ydata; | |
517 | |
518 h = stem (xdata, ydata); | |
519 | |
520 ## delete already set properties, | |
521 s.properties = rmfield (s.properties, ... | |
522 {"xdata", "ydata", ... | |
523 "xdatasource", "ydatasource", ... | |
524 "baseline"}); | |
525 elseif (isfield (fields, "basevalue")) | |
526 ## area plot | |
527 xdata = s.properties.xdata; | |
528 ydata = s.properties.ydata; | |
529 level = s.properties.basevalue; | |
530 | |
531 h = area (xdata, ydata, level); | |
532 | |
533 ## delete already set properties, | |
534 s.properties = rmfield (s.properties, ... | |
535 {"xdata", "ydata", ... | |
536 "xdatasource", "ydatasource"}); | |
537 else | |
538 warning ("struct2hdl: could not infer the hggroup type. Will build objects but listener/callback functions will be lost"); | |
539 h = hggroup ("parent", par); | |
540 addmissingprops (h, s.properties); | |
541 s.special = []; # children will be treated as normal children | |
542 endif | |
543 sout = s; | |
544 pout = p; | |
545 endfunction | |
546 | |
547 function setprops (s, h, p, hilev) | |
548 more off; | |
549 if (strcmpi (s.properties.tag, "")) | |
550 specs = s.children(s.special); | |
551 if (isempty (specs)) | |
552 hdls = []; | |
553 else | |
554 hdls = [specs.handle]; | |
555 endif | |
556 nh = length (hdls); | |
557 msg = ""; | |
558 if (! nh) | |
559 set (h, s.properties); | |
560 else | |
561 ## Specials are objects that where automatically constructed with | |
562 ## current object. Among them are "x(yz)labels", "title", high | |
563 ## level hggroup children | |
564 fields = fieldnames (s.properties); | |
565 vals = struct2cell (s.properties); | |
566 idx = find (cellfun (@(x) valcomp(x, hdls) , vals)); | |
567 s.properties = rmfield (s.properties, fields(idx)); | |
568 | |
569 ## set all properties but special handles | |
570 set (h, s.properties); | |
571 | |
572 ## find props with val == (one of special handles) | |
573 nf = length (idx); | |
574 fields = fields(idx); | |
575 vals = vals(idx); | |
576 while (nf) | |
577 field = fields{nf}; | |
578 idx = find (hdls == vals{nf}); | |
579 spec = specs(idx); | |
580 if (isprop (h, field)) | |
581 h2 = get (h , field); | |
582 set (h2, spec.properties); | |
583 endif | |
584 nf--; | |
585 endwhile | |
586 | |
587 ## If hggroup children were created by high level functions, | |
588 ## copy only usefull properties. | |
589 if (hilev) | |
590 if (strcmp (s.type, "hggroup")) | |
591 nold = numel (s.children); | |
592 nnew = numel (get (h).children); | |
593 | |
594 if (nold == nnew) | |
595 hnew = get (h).children; | |
596 ii = 1; | |
597 while (ii <= nnew) | |
598 try | |
599 set (hnew (ii), "displayname", ... | |
600 s.children(ii).properties.displayname); | |
601 catch | |
602 sprintf ("struct2hdl: couldn't set hggroup children #%d props.", ii); | |
603 end_try_catch | |
604 ii ++; | |
605 endwhile | |
606 | |
607 else | |
608 error ("struct2hdl: non-conformant number of children in hgggroup"); | |
609 endif | |
610 endif | |
611 endif | |
612 endif | |
613 | |
614 elseif (strcmpi (s.properties.tag, "legend") | |
615 || strcmpi (s.properties.tag, "colorbar")) | |
616 set (h, s.properties); | |
617 endif | |
618 | |
619 endfunction | |
620 | |
621 function out = valcomp (x, hdls) | |
622 if (isfloat (x) && isscalar (x)) | |
623 out = any (x == hdls); | |
624 else | |
625 out = 0; | |
626 endif | |
627 endfunction | |
628 | |
629 function addmissingprops (h, props) | |
630 hid = {"autopos_tag", "looseinset"}; | |
631 oldfields = fieldnames (props); | |
632 curfields = fieldnames (get (h)); | |
633 missing = ! ismember (oldfields, curfields); | |
634 idx = find (missing); | |
635 for ii = 1:length (idx) | |
636 prop = oldfields{idx(ii)}; | |
637 if (! any (strcmp (prop, hid))) | |
638 addproperty (prop, h, "any"); | |
639 endif | |
640 endfor | |
641 endfunction | |
642 | |
643 | |
644 ## FIXME: Need validation tests | |
645 |