Home > vbmeg > functions > gui > select_xrange.m

select_xrange

PURPOSE ^

select_xrange( key, varargin )

SYNOPSIS ^

function varargout = select_xrange(key, varargin)

DESCRIPTION ^

 select_xrange( key, varargin )

  2次元グラフのx軸の範囲をマウスドラッグで指定するための
  コールバックルーチンです

 key :  'init'  'delete'  'get'  'clear'  'SetBoxColor'
        'SetReturnVariable'  'SetButtonUpFcn'  'SetInitialRange'

   select_xrange( 'init', <axes handle>
       [ , 'BoxColor', <color> ]
       [ , 'ReturnVariable', <variable name> ]
       [ , 'ButtonUpFcn', <function string> ]
       [ , 'InitialRange', <range> ] )
     <axes handle> で指定されるグラフを選択対象に設定します。オプ
     ションとして、'BoxColor', 'BoxStyle',
     'ReturnVariable', 'ButtonUpFcn', 'InitialRange' を設定できま
     す。それぞれのオプションの詳細は下記を参照してください。

   select_xrange( 'delete', <axes handle> )
     <axes handle> で指定されるグラフを選択対象から除外します。

   select_xrange( 'get', <axes handle> )
     <axes handle> で指定されるグラフをにおける現在の選択範囲を返
     します。出力形式は [ 下界値, 上界値 ] です。

   select_xrange( 'clear', <axes handle> )
     <axes handle> で指定されるグラフの選択範囲を消去します。
   
   select_xrange( 'SetBoxColor', <axes handle>, <color> );
     <axes handle> で指定されるグラフにおける選択範囲を示すBOXの色
     を設定します。<color>はMatlabのColorSpecに準拠します。デフォ
     ルト値は [ 1.0, 0.6, 0.6 ] です。

   select_xrange( 'SetReturnVariable', <axes_handle>, <variable name> );
     <axes handle> で指定されるグラフにおける選択範囲を出力するた
     めのグローバル変数名を設定します。<variable name> は変数名を
     示す文字列になります。デフォルトは空行列です。

   select_xrange( 'SetButtonUpFcn', <axes_handle>, <command> );
     <axes handle> で指定されるグラフにおけるドラッグ終了時に実行
     するコマンドを設定します。ここで、選択した範囲を利用するには、
     xrange という変数名を用いて下さい。例えば、
       >> select_xrange( 'SetButtonUpFcn', 'func( xrange, var )' );
     などにより、選択範囲が関数funcの引数として渡されます。デフォ
     ルトは空行列です。

   select_xrange( 'SetInitialRange', <range> );
     <axes handle> で指定されるグラフにおける選択範囲の初期値を設
     定します。これを用いることにより、マウスドラッグ以外での範囲
     指定が可能です。<range>は2要素のベクトルで、それぞれx軸範囲の
     上界値と下界値を示します。マウスドラッグでは、表示グラフより
     大きい範囲指定はできませんが、ここでは可能です。デフォルトは
     空行列です。


 [ 簡単な使い方の説明 ]

   まず、選択対象となるグラフの axes handle を設定します。

   >> select_xrange( 'set', <axes handle> );

   これにより、対象グラフをマウスでドラッグすると
   選択されたx軸範囲が四角形で囲まれます。
   選択範囲にアクセスするには、

   >> select_xrange( 'get', <axes handle> );

   としてください。


 Copyright (C) 2011, ATR All Rights Reserved.
 License : New BSD License(see VBMEG_LICENSE.txt)

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function varargout = select_xrange(key, varargin)
0002 % select_xrange( key, varargin )
0003 %
0004 %  2次元グラフのx軸の範囲をマウスドラッグで指定するための
0005 %  コールバックルーチンです
0006 %
0007 % key :  'init'  'delete'  'get'  'clear'  'SetBoxColor'
0008 %        'SetReturnVariable'  'SetButtonUpFcn'  'SetInitialRange'
0009 %
0010 %   select_xrange( 'init', <axes handle>
0011 %       [ , 'BoxColor', <color> ]
0012 %       [ , 'ReturnVariable', <variable name> ]
0013 %       [ , 'ButtonUpFcn', <function string> ]
0014 %       [ , 'InitialRange', <range> ] )
0015 %     <axes handle> で指定されるグラフを選択対象に設定します。オプ
0016 %     ションとして、'BoxColor', 'BoxStyle',
0017 %     'ReturnVariable', 'ButtonUpFcn', 'InitialRange' を設定できま
0018 %     す。それぞれのオプションの詳細は下記を参照してください。
0019 %
0020 %   select_xrange( 'delete', <axes handle> )
0021 %     <axes handle> で指定されるグラフを選択対象から除外します。
0022 %
0023 %   select_xrange( 'get', <axes handle> )
0024 %     <axes handle> で指定されるグラフをにおける現在の選択範囲を返
0025 %     します。出力形式は [ 下界値, 上界値 ] です。
0026 %
0027 %   select_xrange( 'clear', <axes handle> )
0028 %     <axes handle> で指定されるグラフの選択範囲を消去します。
0029 %
0030 %   select_xrange( 'SetBoxColor', <axes handle>, <color> );
0031 %     <axes handle> で指定されるグラフにおける選択範囲を示すBOXの色
0032 %     を設定します。<color>はMatlabのColorSpecに準拠します。デフォ
0033 %     ルト値は [ 1.0, 0.6, 0.6 ] です。
0034 %
0035 %   select_xrange( 'SetReturnVariable', <axes_handle>, <variable name> );
0036 %     <axes handle> で指定されるグラフにおける選択範囲を出力するた
0037 %     めのグローバル変数名を設定します。<variable name> は変数名を
0038 %     示す文字列になります。デフォルトは空行列です。
0039 %
0040 %   select_xrange( 'SetButtonUpFcn', <axes_handle>, <command> );
0041 %     <axes handle> で指定されるグラフにおけるドラッグ終了時に実行
0042 %     するコマンドを設定します。ここで、選択した範囲を利用するには、
0043 %     xrange という変数名を用いて下さい。例えば、
0044 %       >> select_xrange( 'SetButtonUpFcn', 'func( xrange, var )' );
0045 %     などにより、選択範囲が関数funcの引数として渡されます。デフォ
0046 %     ルトは空行列です。
0047 %
0048 %   select_xrange( 'SetInitialRange', <range> );
0049 %     <axes handle> で指定されるグラフにおける選択範囲の初期値を設
0050 %     定します。これを用いることにより、マウスドラッグ以外での範囲
0051 %     指定が可能です。<range>は2要素のベクトルで、それぞれx軸範囲の
0052 %     上界値と下界値を示します。マウスドラッグでは、表示グラフより
0053 %     大きい範囲指定はできませんが、ここでは可能です。デフォルトは
0054 %     空行列です。
0055 %
0056 %
0057 % [ 簡単な使い方の説明 ]
0058 %
0059 %   まず、選択対象となるグラフの axes handle を設定します。
0060 %
0061 %   >> select_xrange( 'set', <axes handle> );
0062 %
0063 %   これにより、対象グラフをマウスでドラッグすると
0064 %   選択されたx軸範囲が四角形で囲まれます。
0065 %   選択範囲にアクセスするには、
0066 %
0067 %   >> select_xrange( 'get', <axes handle> );
0068 %
0069 %   としてください。
0070 %
0071 %
0072 % Copyright (C) 2011, ATR All Rights Reserved.
0073 % License : New BSD License(see VBMEG_LICENSE.txt)
0074 
0075 
0076 
0077 
0078 switch key
0079 
0080  % -----------------------------------------------------------------
0081  %  key : init
0082  % -----------------------------------------------------------------
0083  case 'init'  % axes を select_xrange の対象として設定
0084 
0085   % axes handle 取得
0086   h = varargin{1};
0087   if ~ishandle(h) | ~strcmp( get(h,'Type'), 'axes' )
0088     disp( 'error in select_xrange: invalid axes handle' );
0089     return;
0090   end
0091 
0092   % 引数チェック(不完全)  %%%
0093   if mod( size(varargin,2), 2 ) ~= 1
0094     disp( 'invalid arguments for select_xrange( ''set'', ... )' );
0095     return;
0096   end 
0097   i = 2;
0098   while i < size(varargin,2)
0099     switch varargin{i}
0100      case 'BoxColor'
0101       boxcolor = varargin{i+1};
0102      case 'ReturnVariable'
0103       retvar = varargin{i+1};
0104      case 'ButtonUpFcn'
0105       upfcn = varargin{i+1};
0106      case 'InitialRange'
0107       xrange = varargin{i+1};
0108      otherwise
0109       disp( 'invalid arguments for select_xrange( ''set'', ... )' );
0110       return;
0111     end
0112     i = i + 2;
0113   end
0114   % ---- 引数チェック終了
0115   
0116   % オプションのデフォルト設定
0117   if ~exist('boxcolor'); boxcolor = [0.6,0.6,0.6]; end
0118   if ~exist('retvar'); retvar = []; end
0119   if ~exist('upfcn'); upfcn = []; end
0120   if ~exist('xrange'); xrange = []; end
0121   
0122   % axes に マウスボタンを押したときのコールバックを設定
0123   set( h, 'ButtonDownFcn',...
0124       [ 'select_xrange(''down'',''' retvar ''',''' upfcn ''');' ] );
0125 
0126   % 既存の範囲選択BOXがあれば削除
0127   boxhandle = findobj( gca, 'Tag', 'SelX_BOX' );
0128   if ~isempty( boxhandle );
0129     delete( boxhandle );
0130   end
0131   
0132   boxhandle = findobj( gca, 'Tag', 'SelXY_BOX' );
0133   if ~isempty( boxhandle );
0134     delete( boxhandle );
0135   end
0136   
0137   % 新規に範囲選択BOXを作成
0138   ylim = get( h, 'YLim' );
0139   if isempty(xrange)
0140     xlim = get( h, 'XLim' );
0141     xinf = xlim(1);
0142     xsup = xlim(2);
0143   else
0144     xinf = xrange(1);
0145     xsup = xrange(2);
0146   end
0147   if vb_matlab_version('<', '8.4.0')
0148       boxhandle = ...
0149           patch( [ xinf, xsup, xsup, xinf ],...
0150              [ ylim(1), ylim(1), ylim(2), ylim(2) ], ...
0151              boxcolor, 'HitTest', 'off', 'Visible', 'off',...
0152              'EraseMode', 'xor', 'Tag', 'SelX_BOX' );
0153   else
0154       boxhandle = ...
0155           patch( [ xinf, xsup, xsup, xinf ],...
0156              [ ylim(1), ylim(1), ylim(2), ylim(2) ], ...
0157              boxcolor, 'HitTest', 'off', 'Visible', 'off',...
0158              'Tag', 'SelX_BOX' );
0159       boxhandle.FaceAlpha = 0.5;
0160   end
0161   if ~isempty(xrange)
0162     set( boxhandle, 'Visible', 'on' );
0163   end
0164   % -----
0165 
0166 
0167 
0168  % -----------------------------------------------------------------
0169  %  key : delete
0170  % -----------------------------------------------------------------
0171  case 'delete'  % axes を select_xrange の対象から削除
0172   
0173   % axes handle 取得
0174   h = varargin{1};
0175   if ~ishandle(h) | ~strcmp( get(h,'Type'), 'axes' )
0176     disp( 'error in select_xrange: invalid axes handle' );
0177     return;
0178   end
0179 
0180   % 範囲選択BOXがあれば削除 (BOXは'init'時に必ず作成される)
0181   boxhandle = findobj( gca, 'Tag', 'SelX_BOX' );
0182   if ~isempty( boxhandle );
0183     delete( boxhandle );
0184     set( h, 'ButtonDownFcn', [] );
0185   end
0186   
0187   boxhandle = findobj( gca, 'Tag', 'SelXY_BOX' );
0188   if ~isempty( boxhandle );
0189     delete( boxhandle );
0190     set( h, 'ButtonDownFcn', [] );
0191   end
0192 
0193 
0194 
0195  % -----------------------------------------------------------------
0196  %  key : down
0197  % -----------------------------------------------------------------
0198  case 'down' % マウスボタンが押されたとき (Boxの描画,
0199              % WindowButtonMotionFcn, WindowButtonUpFcn の設定)
0200 
0201   % 引数 : retvar --- 出力用グローバル変数,
0202   %        upfcn --- マウスボタンを離したときのコマンド
0203   retvar = varargin{1};
0204   upfcn = varargin{2};
0205 
0206   % 有効なのは左クリックのみ
0207   if strcmp( get( gcf, 'SelectionType' ), 'normal' ) == 0
0208     return;
0209   end
0210   
0211   % BOXの再描画
0212   acpt = get( gca, 'CurrentPoint' );  
0213   xlim = get( gca, 'XLim' );
0214   ylim = get( gca, 'YLim' );
0215   xini = max( xlim(1), acpt(1) ); % 範囲選択は
0216   xini = min( xlim(2), xini );    % グラフのaxis内のみ
0217   boxhandle = findobj( gca, 'Tag', 'SelX_BOX' ); % BOXのハンドルを取得
0218   set( boxhandle, 'XData', [ xini, xini, xini, xini ],...
0219           'Visible', 'on' );
0220   
0221   % マウスを動かしたときとボタンを離したときのコールバックを設定
0222   set( gcf, 'WindowButtonMotionFcn', 'select_xrange(''move'')' );
0223   if isempty( retvar )
0224     set( gcf, 'WindowButtonUpFcn',...
0225           [ 'select_xrange(''up'',''' upfcn ''');' ] );
0226   else
0227     set( gcf, 'WindowButtonUpFcn',...
0228           [ retvar ' = select_xrange(''up'',''' upfcn ''');' ] );
0229   end
0230   
0231  
0232 
0233  % -----------------------------------------------------------------
0234  %  key : move
0235  % -----------------------------------------------------------------
0236  case 'move' % マウスを動かしたとき
0237 
0238   % BOXの再描画
0239   acpt = get( gca, 'CurrentPoint' );
0240   xlim = get( gca, 'XLim' );
0241   xcur = max( xlim(1), acpt(1) ); % 範囲選択は
0242   xcur = min( xlim(2), xcur );    % グラフのaxis内のみ
0243   boxhandle = findobj( gca, 'Tag', 'SelX_BOX' ); % BOXのハンドルを取得
0244   temp = get( boxhandle, 'XData' );
0245   xini = temp(1);
0246   set( boxhandle, 'XData', [ xini, xcur, xcur, xini ] );
0247     
0248 
0249 
0250  % -----------------------------------------------------------------
0251  %  key : up
0252  % -----------------------------------------------------------------
0253  case 'up' % マウスボタンを離したとき
0254 
0255   % 引数 : upfcn --- マウスボタンを離したときのコマンド
0256   upfcn = varargin{1};
0257   
0258   % マウスを動かしたときとマウスボタンを離したときのコールバックの解除
0259   set( gcf, 'WindowButtonMotionFcn', [] );
0260   set( gcf, 'WindowButtonUpFcn', [] );
0261   
0262   % BOXの再描画
0263   acpt = get( gca, 'CurrentPoint' );
0264   xlim = get( gca, 'XLim' );
0265   xcur = max( xlim(1), acpt(1) );
0266   xcur = min( xlim(2), xcur );
0267   boxhandle = findobj( gca, 'Tag', 'SelX_BOX' );
0268   temp = get( boxhandle, 'XData' );
0269   xini = temp(1);
0270   set( boxhandle, 'XData', [ xini, xcur, xcur, xini ] );
0271   
0272   % 選択範囲
0273   xrange = sort( [ xini, xcur ] );
0274   
0275   % ユーザ指定関数呼び出し
0276   if ~isempty( upfcn )
0277     eval( upfcn );
0278   end
0279   
0280   % 返値として出力
0281   varargout{1} = xrange;
0282   
0283 
0284  
0285  % -----------------------------------------------------------------
0286  %  key : get
0287  % -----------------------------------------------------------------
0288  case 'get' % 指定範囲の取得
0289   
0290   % axes handle 取得
0291   h = varargin{1};
0292   if ~ishandle(h) | ~strcmp( get(h,'Type'), 'axes' )
0293     disp( 'error in select_xrange: invalid axes handle' );
0294     varargout{1} = [];
0295     return;
0296   end
0297   
0298   % BOXのハンドルを取得 → あれば出力
0299   boxhandle = findobj( h, 'Tag', 'SelX_BOX' );
0300   if ~isempty(boxhandle) &...
0301      strcmp( get( boxhandle, 'Visible' ), 'on' ) == 1;
0302     xdat = get( boxhandle, 'XData' );
0303     xrange = sort( [ xdat(1), xdat(2) ] );
0304     varargout{1} = xrange;
0305   else
0306     varargout{1} = [];
0307   end
0308   
0309 
0310 
0311  % -----------------------------------------------------------------
0312  %  key : clear
0313  % -----------------------------------------------------------------
0314  case 'clear'  % BOXの消去
0315   
0316   % axes handle 取得
0317   h = varargin{1};
0318   if ~ishandle(h) | ~strcmp( get(h,'Type'), 'axes' )
0319     disp( 'error in select_xrange: invalid axes handle' );
0320     return;
0321   end
0322 
0323   % BOXのハンドルを取得 → あれば非可視化
0324   boxhandle = findobj( h, 'Tag', 'SelX_BOX' );
0325   if ~isempty(boxhandle)
0326     xlim = get( h, 'XLim' );
0327     set( boxhandle, 'Visible', 'off' );
0328   end
0329 
0330 
0331 
0332  % -----------------------------------------------------------------
0333  %  key : SetBoxColor
0334  % -----------------------------------------------------------------
0335  case 'SetBoxColor'  % 範囲選択BOXの色を設定 (不完全) %%%
0336   
0337   % axes handle 取得
0338   h = varargin{1};
0339   if ~ishandle(h) | ~strcmp( get(h,'Type'), 'axes' )
0340     disp( 'error in select_xrange: invalid axes handle' );
0341     return;
0342   end
0343   
0344   % 引数 : 設定する色 (チェック必要)
0345   boxcolor = varargin{2};
0346 
0347   % BOXのハンドルを取得 → あれば色の変更(不完全) %%%
0348   boxhandle = findobj( h, 'Tag', 'SelX_BOX' );
0349   if ~isempty(boxhandle)
0350     set( boxhandle, 'FaceVertexCData', boxcolor );
0351   end
0352   
0353 
0354 
0355  % -----------------------------------------------------------------
0356  %  key : SetReturnVariable
0357  % -----------------------------------------------------------------
0358  case 'SetReturnVariable' % ボタンを離したときに選択範囲を出力する
0359                           % ためのグローバル変数の設定
0360 
0361   % axes handle 取得
0362   h = varargin{1};
0363   if ~ishandle(h) | ~strcmp( get(h,'Type'), 'axes' )
0364     disp( 'error in select_xrange: invalid axes handle' );
0365     return;
0366   end
0367 
0368   % 引数 : 設定する変数 (チェック必要?不可能か?) %%%
0369   retvar = varargin{2};
0370 
0371   % axes ButtonDownFcn コールバックの書き直し
0372   bdf = get( h, 'ButtonDownFcn' );
0373   i = findstr( bdf, 'select_xrange' );
0374   if ~isempty( i )
0375     c = findstr( bdf, ',' );
0376     set( h, 'ButtonDownFcn',...
0377         [ bdf(1:c(1)+1), retvar, bdf(c(2)-1:size(bdf,2)) ] );
0378   end
0379   
0380   
0381 
0382  % -----------------------------------------------------------------
0383  %  key : SetButtonUpFcn
0384  % -----------------------------------------------------------------
0385  case 'SetButtonUpFcn'  % ボタンを離したときに実行されるコマンドの設定
0386 
0387   % axes handle 取得
0388   h = varargin{1};
0389   if ~ishandle(h) | ~strcmp( get(h,'Type'), 'axes' )
0390     disp( 'error in select_xrange: invalid axes handle' );
0391     return;
0392   end
0393 
0394   % 引数 : 設定するコマンド (チェック必要?不可能か?) %%%
0395   upfcn = varargin{2};
0396   
0397   % axes ButtonDownFcn コールバックの書き直し
0398   bdf = get( h, 'ButtonDownFcn' );
0399   i = findstr( bdf, 'select_xrange' );
0400   if ~isempty( i )
0401     c = findstr( bdf, ',' );
0402     set( h, 'ButtonDownFcn',...
0403         [ bdf(1:c(2)+1), upfcn, ''');' ] );
0404   end
0405 
0406 
0407  % -----------------------------------------------------------------
0408  %  key : SetInitialRange
0409  % -----------------------------------------------------------------
0410  case 'SetInitialRange'  % マウスドラッグ前の選択範囲を設定
0411   
0412   % axes handle 取得
0413   h = varargin{1};
0414   if ~ishandle(h) | ~strcmp( get(h,'Type'), 'axes' )
0415     disp( 'error in select_xrange: invalid axes handle' );
0416     return;
0417   end
0418   
0419   % 引数 : 設定する範囲 (チェック必要) %%%
0420   xrange = varargin{2};
0421   
0422   % BOXのハンドル取得 → あれば再描画&可視化
0423   boxhandle = findobj( h, 'Tag', 'SelX_BOX' );
0424   if ~isempty(boxhandle)
0425     set( boxhandle, 'XData', [xrange(1),xrange(2),xrange(2),xrange(1)],...
0426             'Visible', 'on');
0427   end
0428 
0429 
0430   
0431  % -----------------------------------------------------------------
0432  %  key : その他 (エラー)
0433  % -----------------------------------------------------------------
0434  otherwise
0435   disp( 'Invalid key for select_xrange()' );
0436 
0437 
0438   
0439 end % switch key
0440

Generated on Mon 22-May-2023 06:53:56 by m2html © 2005