comparison src/graphics.cc @ 7862:8f3459a90bf3

Redesign axis limit computation handling (using hidden limit properties in child objects)
author Michael Goffioul <michael.goffioul@gmail.com>
date Sun, 23 Mar 2008 16:45:45 +0100
parents 67edbcb19665
children 56f781f38f0b
comparison
equal deleted inserted replaced
7861:7397a0026ca8 7862:8f3459a90bf3
1506 } 1506 }
1507 1507
1508 void 1508 void
1509 base_properties::update_axis_limits (const std::string& axis_type) const 1509 base_properties::update_axis_limits (const std::string& axis_type) const
1510 { 1510 {
1511 graphics_handle h = (get_type () == "axes") ? __myhandle__ : get_parent (); 1511 graphics_object obj = gh_manager::get_object (__myhandle__);
1512 1512
1513 graphics_object obj = gh_manager::get_object (h); 1513 if (obj)
1514
1515 if (obj.isa ("axes"))
1516 obj.update_axis_limits (axis_type); 1514 obj.update_axis_limits (axis_type);
1517 } 1515 }
1518 1516
1519 void 1517 void
1520 base_properties::delete_children (void) 1518 base_properties::delete_children (void)
1638 1636
1639 return available_backends["gnuplot"]; 1637 return available_backends["gnuplot"];
1640 } 1638 }
1641 1639
1642 std::map<std::string, graphics_backend> graphics_backend::available_backends; 1640 std::map<std::string, graphics_backend> graphics_backend::available_backends;
1641
1642 // ---------------------------------------------------------------------
1643
1644 void
1645 base_graphics_object::update_axis_limits (const std::string& axis_type)
1646 {
1647 if (valid_object ())
1648 {
1649 graphics_object parent_obj = gh_manager::get_object (get_parent ());
1650
1651 if (parent_obj)
1652 parent_obj.update_axis_limits (axis_type);
1653 }
1654 else
1655 error ("base_graphics_object::update_axis_limits: invalid graphics object");
1656 }
1643 1657
1644 // --------------------------------------------------------------------- 1658 // ---------------------------------------------------------------------
1645 1659
1646 #include "graphics-props.cc" 1660 #include "graphics-props.cc"
1647 1661
2556 } 2570 }
2557 2571
2558 return retval; 2572 return retval;
2559 } 2573 }
2560 2574
2575 // FIXME: Remove
2561 // FIXME: Maybe this should go into array_property class? 2576 // FIXME: Maybe this should go into array_property class?
2577 /*
2562 static void 2578 static void
2563 check_limit_vals (double& min_val, double& max_val, double& min_pos, 2579 check_limit_vals (double& min_val, double& max_val, double& min_pos,
2564 const array_property& data) 2580 const array_property& data)
2565 { 2581 {
2566 double val = data.min_val (); 2582 double val = data.min_val ();
2570 if (! (xisinf (val) || xisnan (val)) && val > max_val) 2586 if (! (xisinf (val) || xisnan (val)) && val > max_val)
2571 max_val = val; 2587 max_val = val;
2572 val = data.min_pos (); 2588 val = data.min_pos ();
2573 if (! (xisinf (val) || xisnan (val)) && val > 0 && val < min_pos) 2589 if (! (xisinf (val) || xisnan (val)) && val > 0 && val < min_pos)
2574 min_pos = val; 2590 min_pos = val;
2591 }
2592 */
2593
2594 static void
2595 check_limit_vals (double& min_val, double& max_val, double& min_pos,
2596 const octave_value& data)
2597 {
2598 if (data.is_matrix_type ())
2599 {
2600 Matrix m = data.matrix_value ();
2601
2602 if (! error_state && m.numel () == 3)
2603 {
2604 double val;
2605
2606 val = m(0);
2607 if (! (xisinf (val) || xisnan (val)) && val < min_val)
2608 min_val = val;
2609
2610 val = m(1);
2611 if (! (xisinf (val) || xisnan (val)) && val > max_val)
2612 max_val = val;
2613
2614 val = m(2);
2615 if (! (xisinf (val) || xisnan (val)) && val > 0 && val < min_pos)
2616 min_pos = val;
2617 }
2618 }
2575 } 2619 }
2576 2620
2577 // magform(x) Returns (a, b), where x = a * 10^b, a >= 1., and b is 2621 // magform(x) Returns (a, b), where x = a * 10^b, a >= 1., and b is
2578 // integral. 2622 // integral.
2579 2623
2764 2808
2765 2809
2766 ticks = tmp_ticks; 2810 ticks = tmp_ticks;
2767 } 2811 }
2768 2812
2813 static void
2814 get_children_limits (double& min_val, double& max_val, double& min_pos,
2815 const Matrix& kids, char limit_type)
2816 {
2817 octave_idx_type n = kids.numel ();
2818
2819 switch (limit_type)
2820 {
2821 case 'x':
2822 for (octave_idx_type i = 0; i < n; i++)
2823 {
2824 graphics_object obj = gh_manager::get_object (kids(i));
2825
2826 if (obj.is_xliminclude ())
2827 {
2828 octave_value lim = obj.get_xlim ();
2829
2830 check_limit_vals (min_val, max_val, min_pos, lim);
2831 }
2832 }
2833 break;
2834
2835 case 'y':
2836 for (octave_idx_type i = 0; i < n; i++)
2837 {
2838 graphics_object obj = gh_manager::get_object (kids(i));
2839
2840 if (obj.is_yliminclude ())
2841 {
2842 octave_value lim = obj.get_ylim ();
2843
2844 check_limit_vals (min_val, max_val, min_pos, lim);
2845 }
2846 }
2847 break;
2848
2849 case 'z':
2850 for (octave_idx_type i = 0; i < n; i++)
2851 {
2852 graphics_object obj = gh_manager::get_object (kids(i));
2853
2854 if (obj.is_zliminclude ())
2855 {
2856 octave_value lim = obj.get_zlim ();
2857
2858 check_limit_vals (min_val, max_val, min_pos, lim);
2859 }
2860 }
2861 break;
2862
2863 case 'c':
2864 for (octave_idx_type i = 0; i < n; i++)
2865 {
2866 graphics_object obj = gh_manager::get_object (kids(i));
2867
2868 if (obj.is_climinclude ())
2869 {
2870 octave_value lim = obj.get_clim ();
2871
2872 check_limit_vals (min_val, max_val, min_pos, lim);
2873 }
2874 }
2875 break;
2876
2877 case 'a':
2878 for (octave_idx_type i = 0; i < n; i++)
2879 {
2880 graphics_object obj = gh_manager::get_object (kids(i));
2881
2882 if (obj.is_aliminclude ())
2883 {
2884 octave_value lim = obj.get_alim ();
2885
2886 check_limit_vals (min_val, max_val, min_pos, lim);
2887 }
2888 }
2889 break;
2890
2891 default:
2892 break;
2893 }
2894 }
2895
2769 static bool updating_axis_limits = false; 2896 static bool updating_axis_limits = false;
2770 2897
2771 void 2898 void
2772 axes::update_axis_limits (const std::string& axis_type) 2899 axes::update_axis_limits (const std::string& axis_type)
2773 { 2900 {
2786 2913
2787 Matrix limits; 2914 Matrix limits;
2788 2915
2789 if (axis_type == "xdata" || axis_type == "xscale" 2916 if (axis_type == "xdata" || axis_type == "xscale"
2790 || axis_type == "xldata" || axis_type == "xudata" 2917 || axis_type == "xldata" || axis_type == "xudata"
2791 || axis_type == "xlimmode") 2918 || axis_type == "xlimmode" || axis_type == "xliminclude"
2919 || axis_type == "xlim")
2792 { 2920 {
2793 if (xproperties.xlimmode_is ("auto")) 2921 if (xproperties.xlimmode_is ("auto"))
2794 { 2922 {
2795 for (octave_idx_type i = 0; i < n; i++) 2923 get_children_limits (min_val, max_val, min_pos, kids, 'x');
2796 { 2924
2797 graphics_object obj = gh_manager::get_object (kids(i));
2798
2799 if (obj.isa ("line") || obj.isa ("image")
2800 || obj.isa ("patch") || obj.isa ("surface"))
2801 {
2802 array_property xdata = obj.get_xdata_property ();
2803
2804 check_limit_vals (min_val, max_val, min_pos, xdata);
2805
2806 if (obj.isa ("line"))
2807 {
2808 array_property xldata = obj.get_xldata_property ();
2809 array_property xudata = obj.get_xudata_property ();
2810
2811 check_limit_vals (min_val, max_val, min_pos, xldata);
2812 check_limit_vals (min_val, max_val, min_pos, xudata);
2813 }
2814 }
2815 }
2816
2817 limits = xproperties.get_axis_limits (min_val, max_val, min_pos, 2925 limits = xproperties.get_axis_limits (min_val, max_val, min_pos,
2818 xproperties.xscale_is ("log")); 2926 xproperties.xscale_is ("log"));
2819 2927
2820 update_type = 'x'; 2928 update_type = 'x';
2821 } 2929 }
2822 } 2930 }
2823 else if (axis_type == "ydata" || axis_type == "yscale" 2931 else if (axis_type == "ydata" || axis_type == "yscale"
2824 || axis_type == "ldata" || axis_type == "udata" 2932 || axis_type == "ldata" || axis_type == "udata"
2825 || axis_type == "ylimmode") 2933 || axis_type == "ylimmode" || axis_type == "yliminclude"
2934 || axis_type == "ylim")
2826 { 2935 {
2827 if (xproperties.ylimmode_is ("auto")) 2936 if (xproperties.ylimmode_is ("auto"))
2828 { 2937 {
2829 for (octave_idx_type i = 0; i < n; i++) 2938 get_children_limits (min_val, max_val, min_pos, kids, 'y');
2830 {
2831 graphics_object obj = gh_manager::get_object (kids(i));
2832
2833 if (obj.isa ("line") || obj.isa ("image")
2834 || obj.isa ("patch") || obj.isa ("surface"))
2835 {
2836 array_property ydata = obj.get_ydata_property ();
2837
2838 check_limit_vals (min_val, max_val, min_pos, ydata);
2839
2840 if (obj.isa ("line"))
2841 {
2842 array_property ldata = obj.get_ldata_property ();
2843 array_property udata = obj.get_udata_property ();
2844
2845 check_limit_vals (min_val, max_val, min_pos, ldata);
2846 check_limit_vals (min_val, max_val, min_pos, udata);
2847 }
2848 }
2849 }
2850 2939
2851 limits = xproperties.get_axis_limits (min_val, max_val, min_pos, 2940 limits = xproperties.get_axis_limits (min_val, max_val, min_pos,
2852 xproperties.yscale_is ("log")); 2941 xproperties.yscale_is ("log"));
2853 2942
2854 update_type = 'y'; 2943 update_type = 'y';
2855 } 2944 }
2856 } 2945 }
2857 else if (axis_type == "zdata" || axis_type == "zscale" 2946 else if (axis_type == "zdata" || axis_type == "zscale"
2858 || axis_type == "zlimmode") 2947 || axis_type == "zlimmode" || axis_type == "zliminclude"
2948 || axis_type == "zlim")
2859 { 2949 {
2860 if (xproperties.zlimmode_is ("auto")) 2950 if (xproperties.zlimmode_is ("auto"))
2861 { 2951 {
2862 for (octave_idx_type i = 0; i < n; i++) 2952 get_children_limits (min_val, max_val, min_pos, kids, 'z');
2863 {
2864 graphics_object obj = gh_manager::get_object (kids(i));
2865
2866 if (obj.isa ("line") || obj.isa ("patch") || obj.isa ("surface"))
2867 {
2868 array_property zdata = obj.get_zdata_property ();
2869
2870 check_limit_vals (min_val, max_val, min_pos, zdata);
2871 }
2872 }
2873 2953
2874 limits = xproperties.get_axis_limits (min_val, max_val, min_pos, 2954 limits = xproperties.get_axis_limits (min_val, max_val, min_pos,
2875 xproperties.zscale_is ("log")); 2955 xproperties.zscale_is ("log"));
2876 2956
2877 update_type = 'z'; 2957 update_type = 'z';
2878 } 2958 }
2879 } 2959 }
2880 else if (axis_type == "cdata" || axis_type == "climmode") 2960 else if (axis_type == "cdata" || axis_type == "climmode"
2961 || axis_type == "cdatamapping" || axis_type == "climinclude"
2962 || axis_type == "clim")
2881 { 2963 {
2882 if (xproperties.climmode_is ("auto")) 2964 if (xproperties.climmode_is ("auto"))
2883 { 2965 {
2884 for (octave_idx_type i = 0; i < n; i++) 2966 get_children_limits (min_val, max_val, min_pos, kids, 'c');
2967
2968 if (min_val > max_val)
2885 { 2969 {
2886 graphics_object obj = gh_manager::get_object (kids(i)); 2970 min_val = min_pos = 0;
2887 2971 max_val = 1;
2888 if (obj.isa ("image") || obj.isa ("patch") || obj.isa ("surface"))
2889 {
2890 array_property cdata = obj.get_cdata_property ();
2891
2892 check_limit_vals (min_val, max_val, min_pos, cdata);
2893 }
2894 } 2972 }
2895 2973 else if (min_val == max_val)
2896 if (min_val == max_val)
2897 max_val = min_val + 1; 2974 max_val = min_val + 1;
2898 2975
2899 limits.resize (1, 2); 2976 limits.resize (1, 2);
2900 2977
2901 limits(0) = min_val; 2978 limits(0) = min_val;
2902 limits(1) = max_val; 2979 limits(1) = max_val;
2903 2980
2904 update_type = 'c'; 2981 update_type = 'c';
2982 }
2983
2984 }
2985 else if (axis_type == "alphadata" || axis_type == "alimmode"
2986 || axis_type == "alphadatamapping" || axis_type == "aliminclude"
2987 || axis_type == "alim")
2988 {
2989 if (xproperties.alimmode_is ("auto"))
2990 {
2991 get_children_limits (min_val, max_val, min_pos, kids, 'a');
2992
2993 if (min_val > max_val)
2994 {
2995 min_val = min_pos = 0;
2996 max_val = 1;
2997 }
2998 else if (min_val == max_val)
2999 max_val = min_val + 1;
3000
3001 limits.resize (1, 2);
3002
3003 limits(0) = min_val;
3004 limits(1) = max_val;
3005
3006 update_type = 'a';
2905 } 3007 }
2906 3008
2907 } 3009 }
2908 3010
2909 unwind_protect_bool (updating_axis_limits); 3011 unwind_protect_bool (updating_axis_limits);
2930 break; 3032 break;
2931 3033
2932 case 'c': 3034 case 'c':
2933 xproperties.set_clim (limits); 3035 xproperties.set_clim (limits);
2934 xproperties.set_climmode ("auto"); 3036 xproperties.set_climmode ("auto");
3037 break;
3038
3039 case 'a':
3040 xproperties.set_alim (limits);
3041 xproperties.set_alimmode ("auto");
2935 break; 3042 break;
2936 3043
2937 default: 3044 default:
2938 break; 3045 break;
2939 } 3046 }
2990 unzoom (); 3097 unzoom ();
2991 } 3098 }
2992 3099
2993 // --------------------------------------------------------------------- 3100 // ---------------------------------------------------------------------
2994 3101
2995 // Note: "line" code is entirely auto-generated 3102 Matrix
3103 line::properties::compute_xlim (void) const
3104 {
3105 Matrix m (1, 3);
3106
3107 m(0) = xmin (xdata.min_val (), xmin (xldata.min_val (), xudata.min_val ()));
3108 m(1) = xmax (xdata.max_val (), xmax (xldata.max_val (), xudata.max_val ()));
3109 m(2) = xmin (xdata.min_pos (), xmin (xldata.min_pos (), xudata.min_pos ()));
3110
3111 return m;
3112 }
3113
3114 Matrix
3115 line::properties::compute_ylim (void) const
3116 {
3117 Matrix m (1, 3);
3118
3119 m(0) = xmin (ydata.min_val (), xmin (ldata.min_val (), udata.min_val ()));
3120 m(1) = xmax (ydata.max_val (), xmax (ldata.max_val (), udata.max_val ()));
3121 m(2) = xmin (ydata.min_pos (), xmin (ldata.min_pos (), udata.min_pos ()));
3122
3123 return m;
3124 }
2996 3125
2997 // --------------------------------------------------------------------- 3126 // ---------------------------------------------------------------------
2998 3127
2999 // Note: "text" code is entirely auto-generated 3128 // Note: "text" code is entirely auto-generated
3000 3129