Mercurial > octave-nkf
comparison src/graphics.cc @ 11175:c0a95a5c6d25
Address the speed of plotting large hggroup groups and in particular
contours (bug #31305). Changes to address this include
- Use __go_patch__ in __contour__ rather than patch so that
the cost of setting up the callback functions is avoided.
The contourgroup callback handles the updating of properties.
- Add children_property class to store children in a list so
that adding and deleting children is a low cost operation.
- Create a new version of update_axis_limits code that doesn't
force the recalculation of all of the objects children.
Patch also allows unclosed patch contours with the FLTK backend.
author | David Bateman <dbateman@free.fr> |
---|---|
date | Tue, 02 Nov 2010 00:47:31 +0100 |
parents | 36442102c340 |
children | 5fa7667f90e5 |
comparison
equal
deleted
inserted
replaced
11174:2114867f2a50 | 11175:c0a95a5c6d25 |
---|---|
686 | 686 |
687 for (octave_idx_type i = 0; i < n; i++) | 687 for (octave_idx_type i = 0; i < n; i++) |
688 { | 688 { |
689 double e = double (data[i]); | 689 double e = double (data[i]); |
690 | 690 |
691 if (! (xisinf (e) || xisnan (e))) | 691 // Don't need to test for NaN here as NaN>x and NaN<x is always false |
692 if (! xisinf (e)) | |
692 { | 693 { |
693 if (e < emin) | 694 if (e < emin) |
694 emin = e; | 695 emin = e; |
695 | 696 |
696 if (e > emax) | 697 if (e > emax) |
1204 get_name ().c_str ()); | 1205 get_name ().c_str ()); |
1205 | 1206 |
1206 return false; | 1207 return false; |
1207 } | 1208 } |
1208 | 1209 |
1210 Matrix | |
1211 children_property::do_get_children (bool return_hidden) const | |
1212 { | |
1213 Matrix retval (children_list.size (), 1); | |
1214 octave_idx_type k = 0; | |
1215 | |
1216 graphics_object go = gh_manager::get_object (0); | |
1217 | |
1218 root_figure::properties& props = | |
1219 dynamic_cast<root_figure::properties&> (go.get_properties ()); | |
1220 | |
1221 if (! props.is_showhiddenhandles ()) | |
1222 { | |
1223 for (const_children_list_iterator p = children_list.begin (); | |
1224 p != children_list.end (); p++) | |
1225 { | |
1226 graphics_handle kid = *p; | |
1227 | |
1228 if (gh_manager::is_handle_visible (kid)) | |
1229 { | |
1230 if (! return_hidden) | |
1231 retval(k++) = *p; | |
1232 } | |
1233 else if (return_hidden) | |
1234 retval(k++) = *p; | |
1235 } | |
1236 | |
1237 retval.resize (k, 1); | |
1238 } | |
1239 else | |
1240 { | |
1241 for (const_children_list_iterator p = children_list.begin (); | |
1242 p != children_list.end (); p++) | |
1243 retval(k++) = *p; | |
1244 } | |
1245 | |
1246 return retval; | |
1247 } | |
1248 | |
1249 void | |
1250 children_property::do_delete_children (bool clear) | |
1251 { | |
1252 for (children_list_iterator p = children_list.begin (); | |
1253 p != children_list.end (); p++) | |
1254 { | |
1255 graphics_object go = gh_manager::get_object (*p); | |
1256 | |
1257 if (go.valid_object ()) | |
1258 gh_manager::free (*p); | |
1259 | |
1260 } | |
1261 | |
1262 if (clear) | |
1263 children_list.clear (); | |
1264 } | |
1265 | |
1209 bool | 1266 bool |
1210 callback_property::validate (const octave_value& v) const | 1267 callback_property::validate (const octave_value& v) const |
1211 { | 1268 { |
1212 // case 1: function handle | 1269 // case 1: function handle |
1213 // case 2: cell array with first element being a function handle | 1270 // case 2: cell array with first element being a function handle |
1881 graphics_object obj = gh_manager::get_object (h); | 1938 graphics_object obj = gh_manager::get_object (h); |
1882 obj.set (args); | 1939 obj.set (args); |
1883 } | 1940 } |
1884 } | 1941 } |
1885 | 1942 |
1886 | |
1887 static octave_value | 1943 static octave_value |
1888 xget (const graphics_handle& h, const caseless_str& name) | 1944 xget (const graphics_handle& h, const caseless_str& name) |
1889 { | 1945 { |
1890 graphics_object obj = gh_manager::get_object (h); | 1946 graphics_object obj = gh_manager::get_object (h); |
1891 return obj.get (name); | 1947 return obj.get (name); |
1950 | 2006 |
1951 static void | 2007 static void |
1952 adopt (const graphics_handle& p, const graphics_handle& h) | 2008 adopt (const graphics_handle& p, const graphics_handle& h) |
1953 { | 2009 { |
1954 graphics_object parent_obj = gh_manager::get_object (p); | 2010 graphics_object parent_obj = gh_manager::get_object (p); |
1955 | |
1956 parent_obj.adopt (h); | 2011 parent_obj.adopt (h); |
1957 } | 2012 } |
1958 | 2013 |
1959 static bool | 2014 static bool |
1960 is_handle (const graphics_handle& h) | 2015 is_handle (const graphics_handle& h) |
2145 else | 2200 else |
2146 return it->second; | 2201 return it->second; |
2147 } | 2202 } |
2148 | 2203 |
2149 void | 2204 void |
2150 base_properties::remove_child (const graphics_handle& h) | |
2151 { | |
2152 octave_idx_type k = -1; | |
2153 octave_idx_type n = children.numel (); | |
2154 for (octave_idx_type i = 0; i < n; i++) | |
2155 { | |
2156 if (h.value () == children(i)) | |
2157 { | |
2158 k = i; | |
2159 break; | |
2160 } | |
2161 } | |
2162 | |
2163 if (k >= 0) | |
2164 { | |
2165 Matrix new_kids (n-1, 1); | |
2166 octave_idx_type j = 0; | |
2167 for (octave_idx_type i = 0; i < n; i++) | |
2168 { | |
2169 if (i != k) | |
2170 new_kids(j++) = children(i); | |
2171 } | |
2172 children = new_kids; | |
2173 mark_modified (); | |
2174 } | |
2175 } | |
2176 | |
2177 void | |
2178 base_properties::set_parent (const octave_value& val) | 2205 base_properties::set_parent (const octave_value& val) |
2179 { | 2206 { |
2180 double tmp = val.double_value (); | 2207 double tmp = val.double_value (); |
2181 | 2208 |
2182 graphics_handle new_parent = octave_NaN; | 2209 graphics_handle new_parent = octave_NaN; |
2198 else | 2225 else |
2199 error ("set: invalid graphics handle (= %g) for parent", tmp); | 2226 error ("set: invalid graphics handle (= %g) for parent", tmp); |
2200 } | 2227 } |
2201 else | 2228 else |
2202 error ("set: expecting parent to be a graphics handle"); | 2229 error ("set: expecting parent to be a graphics handle"); |
2203 } | |
2204 | |
2205 void | |
2206 base_properties::set_children (const octave_value& val) | |
2207 { | |
2208 const Matrix new_kids = val.matrix_value (); | |
2209 | |
2210 octave_idx_type nel = new_kids.numel (); | |
2211 | |
2212 const Matrix new_kids_column = new_kids.reshape (dim_vector (nel, 1)); | |
2213 | |
2214 bool ok = true; | |
2215 | |
2216 if (! error_state) | |
2217 { | |
2218 const Matrix visible_kids = get_children (); | |
2219 | |
2220 if (visible_kids.numel () == new_kids.numel ()) | |
2221 { | |
2222 Matrix t1 = visible_kids.sort (); | |
2223 Matrix t2 = new_kids_column.sort (); | |
2224 | |
2225 if (t1 != t2) | |
2226 ok = false; | |
2227 } | |
2228 else | |
2229 ok = false; | |
2230 | |
2231 if (! ok) | |
2232 error ("set: new children must be a permutation of existing children"); | |
2233 } | |
2234 else | |
2235 { | |
2236 ok = false; | |
2237 error ("set: expecting children to be array of graphics handles"); | |
2238 } | |
2239 | |
2240 if (ok) | |
2241 children = new_kids_column.stack (get_hidden_children ()); | |
2242 } | 2230 } |
2243 | 2231 |
2244 void | 2232 void |
2245 base_properties::mark_modified (void) | 2233 base_properties::mark_modified (void) |
2246 { | 2234 { |
2267 if (obj) | 2255 if (obj) |
2268 obj.update_axis_limits (axis_type); | 2256 obj.update_axis_limits (axis_type); |
2269 } | 2257 } |
2270 | 2258 |
2271 void | 2259 void |
2272 base_properties::delete_children (void) | 2260 base_properties::update_axis_limits (const std::string& axis_type, |
2273 { | 2261 const graphics_handle& h) const |
2274 octave_idx_type n = children.numel (); | 2262 { |
2275 | 2263 graphics_object obj = gh_manager::get_object (__myhandle__); |
2276 // A callback function might have already deleted the child, | 2264 |
2277 // so check before deleting | 2265 if (obj) |
2278 for (octave_idx_type i = 0; i < n; i++) | 2266 obj.update_axis_limits (axis_type, h); |
2279 { | |
2280 graphics_object go = gh_manager::get_object (children(i)); | |
2281 | |
2282 if (go.valid_object ()) | |
2283 gh_manager::free (children(i)); | |
2284 } | |
2285 } | 2267 } |
2286 | 2268 |
2287 graphics_backend | 2269 graphics_backend |
2288 base_properties::get_backend (void) const | 2270 base_properties::get_backend (void) const |
2289 { | 2271 { |
2468 else | 2450 else |
2469 error ("base_graphics_object::update_axis_limits: invalid graphics object"); | 2451 error ("base_graphics_object::update_axis_limits: invalid graphics object"); |
2470 } | 2452 } |
2471 | 2453 |
2472 void | 2454 void |
2455 base_graphics_object::update_axis_limits (const std::string& axis_type, | |
2456 const graphics_handle& h) | |
2457 { | |
2458 if (valid_object ()) | |
2459 { | |
2460 graphics_object parent_obj = gh_manager::get_object (get_parent ()); | |
2461 | |
2462 if (parent_obj) | |
2463 parent_obj.update_axis_limits (axis_type, h); | |
2464 } | |
2465 else | |
2466 error ("base_graphics_object::update_axis_limits: invalid graphics object"); | |
2467 } | |
2468 | |
2469 void | |
2473 base_graphics_object::remove_all_listeners (void) | 2470 base_graphics_object::remove_all_listeners (void) |
2474 { | 2471 { |
2475 octave_map m = get (true).map_value (); | 2472 octave_map m = get (true).map_value (); |
2476 | 2473 |
2477 for (octave_map::const_iterator pa = m.begin (); pa != m.end (); pa++) | 2474 for (octave_map::const_iterator pa = m.begin (); pa != m.end (); pa++) |
2726 | 2723 |
2727 if (gh == currentaxes.handle_value ()) | 2724 if (gh == currentaxes.handle_value ()) |
2728 { | 2725 { |
2729 graphics_handle new_currentaxes; | 2726 graphics_handle new_currentaxes; |
2730 | 2727 |
2731 for (octave_idx_type i = 0; i < children.numel (); i++) | 2728 Matrix kids = get_children (); |
2732 { | 2729 |
2733 graphics_handle kid = children(i); | 2730 for (octave_idx_type i = 0; i < kids.numel (); i++) |
2731 { | |
2732 graphics_handle kid = kids(i); | |
2734 | 2733 |
2735 graphics_object go = gh_manager::get_object (kid); | 2734 graphics_object go = gh_manager::get_object (kid); |
2736 | 2735 |
2737 if (go.isa ("axes")) | 2736 if (go.isa ("axes")) |
2738 { | 2737 { |
3416 position = default_axes_position (); | 3415 position = default_axes_position (); |
3417 | 3416 |
3418 activepositionproperty = "outerposition"; | 3417 activepositionproperty = "outerposition"; |
3419 } | 3418 } |
3420 | 3419 |
3421 delete_children (); | 3420 delete_children (true); |
3422 | |
3423 children = Matrix (); | |
3424 | 3421 |
3425 xlabel = gh_manager::make_graphics_handle ("text", __myhandle__, false); | 3422 xlabel = gh_manager::make_graphics_handle ("text", __myhandle__, false); |
3426 ylabel = gh_manager::make_graphics_handle ("text", __myhandle__, false); | 3423 ylabel = gh_manager::make_graphics_handle ("text", __myhandle__, false); |
3427 zlabel = gh_manager::make_graphics_handle ("text", __myhandle__, false); | 3424 zlabel = gh_manager::make_graphics_handle ("text", __myhandle__, false); |
3428 title = gh_manager::make_graphics_handle ("text", __myhandle__, false); | 3425 title = gh_manager::make_graphics_handle ("text", __myhandle__, false); |
3500 delete_text_child (zlabel); | 3497 delete_text_child (zlabel); |
3501 else if (title.handle_value ().ok () && h == title.handle_value ()) | 3498 else if (title.handle_value ().ok () && h == title.handle_value ()) |
3502 delete_text_child (title); | 3499 delete_text_child (title); |
3503 else | 3500 else |
3504 base_properties::remove_child (h); | 3501 base_properties::remove_child (h); |
3505 } | |
3506 | |
3507 Matrix | |
3508 base_properties::get_children_internal (bool return_hidden) const | |
3509 { | |
3510 Matrix retval = children; | |
3511 | |
3512 graphics_object go = gh_manager::get_object (0); | |
3513 | |
3514 root_figure::properties& props = | |
3515 dynamic_cast<root_figure::properties&> (go.get_properties ()); | |
3516 | |
3517 if (! props.is_showhiddenhandles ()) | |
3518 { | |
3519 octave_idx_type k = 0; | |
3520 | |
3521 for (octave_idx_type i = 0; i < children.numel (); i++) | |
3522 { | |
3523 graphics_handle kid = children (i); | |
3524 | |
3525 if (gh_manager::is_handle_visible (kid)) | |
3526 { | |
3527 if (! return_hidden) | |
3528 retval(k++) = children(i); | |
3529 } | |
3530 else | |
3531 { | |
3532 if (return_hidden) | |
3533 retval(k++) = children(i); | |
3534 } | |
3535 } | |
3536 | |
3537 retval.resize (k, 1); | |
3538 } | |
3539 | |
3540 return retval; | |
3541 } | |
3542 | |
3543 Matrix | |
3544 base_properties::get_children (void) const | |
3545 { | |
3546 return get_children_internal (false); | |
3547 } | |
3548 | |
3549 Matrix | |
3550 base_properties::get_hidden_children (void) const | |
3551 { | |
3552 return get_children_internal (true); | |
3553 } | 3502 } |
3554 | 3503 |
3555 inline Matrix | 3504 inline Matrix |
3556 xform_matrix (void) | 3505 xform_matrix (void) |
3557 { | 3506 { |
4551 break; | 4500 break; |
4552 } | 4501 } |
4553 } | 4502 } |
4554 | 4503 |
4555 static bool updating_axis_limits = false; | 4504 static bool updating_axis_limits = false; |
4505 | |
4506 void | |
4507 axes::update_axis_limits (const std::string& axis_type, | |
4508 const graphics_handle& h) | |
4509 { | |
4510 if (updating_axis_limits) | |
4511 return; | |
4512 | |
4513 Matrix kids = Matrix (1, 1, h.value ()); | |
4514 | |
4515 double min_val = octave_Inf; | |
4516 double max_val = -octave_Inf; | |
4517 double min_pos = octave_Inf; | |
4518 | |
4519 char update_type = 0; | |
4520 | |
4521 Matrix limits; | |
4522 double val; | |
4523 | |
4524 #define FIX_LIMITS \ | |
4525 if (limits.numel() == 3) \ | |
4526 { \ | |
4527 val = limits(0); \ | |
4528 if (! (xisinf (val) || xisnan (val))) \ | |
4529 min_val = val; \ | |
4530 val = limits(1); \ | |
4531 if (! (xisinf (val) || xisnan (val))) \ | |
4532 max_val = val; \ | |
4533 val = limits(2); \ | |
4534 if (! (xisinf (val) || xisnan (val))) \ | |
4535 min_pos = val; \ | |
4536 } \ | |
4537 else \ | |
4538 { \ | |
4539 limits.resize(3, 1); \ | |
4540 limits(0) = min_val; \ | |
4541 limits(1) = max_val; \ | |
4542 limits(2) = min_pos; \ | |
4543 } | |
4544 | |
4545 if (axis_type == "xdata" || axis_type == "xscale" | |
4546 || axis_type == "xlimmode" || axis_type == "xliminclude" | |
4547 || axis_type == "xlim") | |
4548 { | |
4549 if (xproperties.xlimmode_is ("auto")) | |
4550 { | |
4551 limits = xproperties.get_xlim ().matrix_value (); | |
4552 FIX_LIMITS ; | |
4553 | |
4554 get_children_limits (min_val, max_val, min_pos, kids, 'x'); | |
4555 | |
4556 limits = xproperties.get_axis_limits (min_val, max_val, min_pos, | |
4557 xproperties.xscale_is ("log")); | |
4558 | |
4559 update_type = 'x'; | |
4560 } | |
4561 } | |
4562 else if (axis_type == "ydata" || axis_type == "yscale" | |
4563 || axis_type == "ylimmode" || axis_type == "yliminclude" | |
4564 || axis_type == "ylim") | |
4565 { | |
4566 if (xproperties.ylimmode_is ("auto")) | |
4567 { | |
4568 limits = xproperties.get_ylim ().matrix_value (); | |
4569 FIX_LIMITS ; | |
4570 | |
4571 get_children_limits (min_val, max_val, min_pos, kids, 'y'); | |
4572 | |
4573 limits = xproperties.get_axis_limits (min_val, max_val, min_pos, | |
4574 xproperties.yscale_is ("log")); | |
4575 | |
4576 update_type = 'y'; | |
4577 } | |
4578 } | |
4579 else if (axis_type == "zdata" || axis_type == "zscale" | |
4580 || axis_type == "zlimmode" || axis_type == "zliminclude" | |
4581 || axis_type == "zlim") | |
4582 { | |
4583 if (xproperties.zlimmode_is ("auto")) | |
4584 { | |
4585 limits = xproperties.get_zlim ().matrix_value (); | |
4586 FIX_LIMITS ; | |
4587 | |
4588 get_children_limits (min_val, max_val, min_pos, kids, 'z'); | |
4589 | |
4590 limits = xproperties.get_axis_limits (min_val, max_val, min_pos, | |
4591 xproperties.zscale_is ("log")); | |
4592 | |
4593 update_type = 'z'; | |
4594 } | |
4595 } | |
4596 else if (axis_type == "cdata" || axis_type == "climmode" | |
4597 || axis_type == "cdatamapping" || axis_type == "climinclude" | |
4598 || axis_type == "clim") | |
4599 { | |
4600 if (xproperties.climmode_is ("auto")) | |
4601 { | |
4602 limits = xproperties.get_clim ().matrix_value (); | |
4603 FIX_LIMITS ; | |
4604 | |
4605 get_children_limits (min_val, max_val, min_pos, kids, 'c'); | |
4606 | |
4607 if (min_val > max_val) | |
4608 { | |
4609 min_val = min_pos = 0; | |
4610 max_val = 1; | |
4611 } | |
4612 else if (min_val == max_val) | |
4613 max_val = min_val + 1; | |
4614 | |
4615 limits.resize (1, 2); | |
4616 | |
4617 limits(0) = min_val; | |
4618 limits(1) = max_val; | |
4619 | |
4620 update_type = 'c'; | |
4621 } | |
4622 | |
4623 } | |
4624 else if (axis_type == "alphadata" || axis_type == "alimmode" | |
4625 || axis_type == "alphadatamapping" || axis_type == "aliminclude" | |
4626 || axis_type == "alim") | |
4627 { | |
4628 if (xproperties.alimmode_is ("auto")) | |
4629 { | |
4630 limits = xproperties.get_alim ().matrix_value (); | |
4631 FIX_LIMITS ; | |
4632 | |
4633 get_children_limits (min_val, max_val, min_pos, kids, 'a'); | |
4634 | |
4635 if (min_val > max_val) | |
4636 { | |
4637 min_val = min_pos = 0; | |
4638 max_val = 1; | |
4639 } | |
4640 else if (min_val == max_val) | |
4641 max_val = min_val + 1; | |
4642 | |
4643 limits.resize (1, 2); | |
4644 | |
4645 limits(0) = min_val; | |
4646 limits(1) = max_val; | |
4647 | |
4648 update_type = 'a'; | |
4649 } | |
4650 | |
4651 } | |
4652 | |
4653 #undef FIX_LIMITS | |
4654 | |
4655 unwind_protect frame; | |
4656 frame.protect_var (updating_axis_limits); | |
4657 | |
4658 updating_axis_limits = true; | |
4659 | |
4660 switch (update_type) | |
4661 { | |
4662 case 'x': | |
4663 xproperties.set_xlim (limits); | |
4664 xproperties.set_xlimmode ("auto"); | |
4665 xproperties.update_xlim (); | |
4666 break; | |
4667 | |
4668 case 'y': | |
4669 xproperties.set_ylim (limits); | |
4670 xproperties.set_ylimmode ("auto"); | |
4671 xproperties.update_ylim (); | |
4672 break; | |
4673 | |
4674 case 'z': | |
4675 xproperties.set_zlim (limits); | |
4676 xproperties.set_zlimmode ("auto"); | |
4677 xproperties.update_zlim (); | |
4678 break; | |
4679 | |
4680 case 'c': | |
4681 xproperties.set_clim (limits); | |
4682 xproperties.set_climmode ("auto"); | |
4683 break; | |
4684 | |
4685 case 'a': | |
4686 xproperties.set_alim (limits); | |
4687 xproperties.set_alimmode ("auto"); | |
4688 break; | |
4689 | |
4690 default: | |
4691 break; | |
4692 } | |
4693 | |
4694 xproperties.update_transform (); | |
4695 | |
4696 } | |
4556 | 4697 |
4557 void | 4698 void |
4558 axes::update_axis_limits (const std::string& axis_type) | 4699 axes::update_axis_limits (const std::string& axis_type) |
4559 { | 4700 { |
4560 if (updating_axis_limits || updating_aspectratios) | 4701 if (updating_axis_limits || updating_aspectratios) |
5067 } | 5208 } |
5068 } | 5209 } |
5069 | 5210 |
5070 // --------------------------------------------------------------------- | 5211 // --------------------------------------------------------------------- |
5071 | 5212 |
5072 void | 5213 void |
5073 hggroup::update_axis_limits (const std::string& axis_type) | 5214 hggroup::properties::update_limits (void) const |
5074 { | 5215 { |
5075 Matrix kids = xproperties.get_children (); | 5216 graphics_object obj = gh_manager::get_object (__myhandle__); |
5076 | 5217 |
5218 if (obj) | |
5219 { | |
5220 obj.update_axis_limits ("xlim"); | |
5221 obj.update_axis_limits ("ylim"); | |
5222 obj.update_axis_limits ("zlim"); | |
5223 obj.update_axis_limits ("clim"); | |
5224 obj.update_axis_limits ("alim"); | |
5225 } | |
5226 } | |
5227 | |
5228 void | |
5229 hggroup::properties::update_limits (const graphics_handle& h) const | |
5230 { | |
5231 graphics_object obj = gh_manager::get_object (__myhandle__); | |
5232 | |
5233 if (obj) | |
5234 { | |
5235 obj.update_axis_limits ("xlim", h); | |
5236 obj.update_axis_limits ("ylim", h); | |
5237 obj.update_axis_limits ("zlim", h); | |
5238 obj.update_axis_limits ("clim", h); | |
5239 obj.update_axis_limits ("alim", h); | |
5240 } | |
5241 } | |
5242 | |
5243 static bool updating_hggroup_limits = false; | |
5244 | |
5245 void | |
5246 hggroup::update_axis_limits (const std::string& axis_type, | |
5247 const graphics_handle& h) | |
5248 { | |
5249 if (updating_hggroup_limits) | |
5250 return; | |
5251 | |
5252 Matrix kids = Matrix (1, 1, h.value ()); | |
5253 | |
5077 double min_val = octave_Inf; | 5254 double min_val = octave_Inf; |
5078 double max_val = -octave_Inf; | 5255 double max_val = -octave_Inf; |
5079 double min_pos = octave_Inf; | 5256 double min_pos = octave_Inf; |
5080 | 5257 |
5258 Matrix limits; | |
5259 double val; | |
5260 | |
5081 char update_type = 0; | 5261 char update_type = 0; |
5082 | 5262 |
5083 if (axis_type == "xlim" || axis_type == "xliminclude") | 5263 if (axis_type == "xlim" || axis_type == "xliminclude") |
5084 { | 5264 { |
5265 limits = xproperties.get_xlim ().matrix_value (); | |
5266 update_type = 'x'; | |
5267 } | |
5268 else if (axis_type == "ylim" || axis_type == "yliminclude") | |
5269 { | |
5270 limits = xproperties.get_ylim ().matrix_value (); | |
5271 update_type = 'y'; | |
5272 } | |
5273 else if (axis_type == "zlim" || axis_type == "zliminclude") | |
5274 { | |
5275 limits = xproperties.get_zlim ().matrix_value (); | |
5276 update_type = 'z'; | |
5277 } | |
5278 else if (axis_type == "clim" || axis_type == "climinclude") | |
5279 { | |
5280 limits = xproperties.get_clim ().matrix_value (); | |
5281 update_type = 'c'; | |
5282 } | |
5283 else if (axis_type == "alim" || axis_type == "aliminclude") | |
5284 { | |
5285 limits = xproperties.get_alim ().matrix_value (); | |
5286 update_type = 'a'; | |
5287 } | |
5288 | |
5289 if (limits.numel() == 3) | |
5290 { | |
5291 val = limits(0); | |
5292 if (! (xisinf (val) || xisnan (val))) | |
5293 min_val = val; | |
5294 val = limits(1); | |
5295 if (! (xisinf (val) || xisnan (val))) | |
5296 max_val = val; | |
5297 val = limits(2); | |
5298 if (! (xisinf (val) || xisnan (val))) | |
5299 min_pos = val; | |
5300 } | |
5301 else | |
5302 { | |
5303 limits.resize(3,1); | |
5304 limits(0) = min_val; | |
5305 limits(1) = max_val; | |
5306 limits(2) = min_pos; | |
5307 } | |
5308 | |
5309 get_children_limits (min_val, max_val, min_pos, kids, update_type); | |
5310 | |
5311 unwind_protect frame; | |
5312 frame.protect_var (updating_hggroup_limits); | |
5313 | |
5314 updating_hggroup_limits = true; | |
5315 | |
5316 if (limits(0) != min_val || limits(1) != max_val || limits(2) != min_pos) | |
5317 { | |
5318 limits(0) = min_val; | |
5319 limits(1) = max_val; | |
5320 limits(2) = min_pos; | |
5321 | |
5322 switch (update_type) | |
5323 { | |
5324 case 'x': | |
5325 xproperties.set_xlim (limits); | |
5326 break; | |
5327 | |
5328 case 'y': | |
5329 xproperties.set_ylim (limits); | |
5330 break; | |
5331 | |
5332 case 'z': | |
5333 xproperties.set_zlim (limits); | |
5334 break; | |
5335 | |
5336 case 'c': | |
5337 xproperties.set_clim (limits); | |
5338 break; | |
5339 | |
5340 case 'a': | |
5341 xproperties.set_alim (limits); | |
5342 break; | |
5343 | |
5344 default: | |
5345 break; | |
5346 } | |
5347 | |
5348 base_graphics_object::update_axis_limits (axis_type, h); | |
5349 } | |
5350 } | |
5351 | |
5352 void | |
5353 hggroup::update_axis_limits (const std::string& axis_type) | |
5354 { | |
5355 if (updating_hggroup_limits) | |
5356 return; | |
5357 | |
5358 Matrix kids = xproperties.get_children (); | |
5359 | |
5360 double min_val = octave_Inf; | |
5361 double max_val = -octave_Inf; | |
5362 double min_pos = octave_Inf; | |
5363 | |
5364 char update_type = 0; | |
5365 | |
5366 if (axis_type == "xlim" || axis_type == "xliminclude") | |
5367 { | |
5085 get_children_limits (min_val, max_val, min_pos, kids, 'x'); | 5368 get_children_limits (min_val, max_val, min_pos, kids, 'x'); |
5086 | 5369 |
5087 update_type = 'x'; | 5370 update_type = 'x'; |
5088 } | 5371 } |
5089 else if (axis_type == "ylim" || axis_type == "yliminclude") | 5372 else if (axis_type == "ylim" || axis_type == "yliminclude") |
5090 { | 5373 { |
5091 get_children_limits (min_val, max_val, min_pos, kids, 'y'); | 5374 get_children_limits (min_val, max_val, min_pos, kids, 'y'); |
5101 else if (axis_type == "clim" || axis_type == "climinclude") | 5384 else if (axis_type == "clim" || axis_type == "climinclude") |
5102 { | 5385 { |
5103 get_children_limits (min_val, max_val, min_pos, kids, 'c'); | 5386 get_children_limits (min_val, max_val, min_pos, kids, 'c'); |
5104 | 5387 |
5105 update_type = 'c'; | 5388 update_type = 'c'; |
5106 | |
5107 } | 5389 } |
5108 else if (axis_type == "alim" || axis_type == "aliminclude") | 5390 else if (axis_type == "alim" || axis_type == "aliminclude") |
5109 { | 5391 { |
5110 get_children_limits (min_val, max_val, min_pos, kids, 'a'); | 5392 get_children_limits (min_val, max_val, min_pos, kids, 'a'); |
5111 | 5393 |
5112 update_type = 'a'; | 5394 update_type = 'a'; |
5113 } | 5395 } |
5396 | |
5397 unwind_protect frame; | |
5398 frame.protect_var (updating_hggroup_limits); | |
5399 | |
5400 updating_hggroup_limits = true; | |
5114 | 5401 |
5115 Matrix limits (1, 3, 0.0); | 5402 Matrix limits (1, 3, 0.0); |
5116 | 5403 |
5117 limits(0) = min_val; | 5404 limits(0) = min_val; |
5118 limits(1) = max_val; | 5405 limits(1) = max_val; |