📄 panfcn.m
字号:
function varargout = panfcn(varargin)
%PANFCN Pan Function for Axes and Signal GUI
% Usage: call this function either as the buttondownfcn of the lines in
% an axes that you want to pan, or as the windowbuttondownfcn when you
% click inside an axes.
% Inputs are in param/value pairs
% 'Ax' axes to pan, default: gca
% 'Bounds' structure with .xlim and .ylim - panning will not
% ever leave these bounds. default: no bounds
% 'DirectFlag' 1 ==> drag in main axes, 0 ==> drag in panner. default = 1
% 'borderAxes' axes whose perimeter is one pixel outside of 'Axes' -
% if not defined, the 'Axes' will get erased if the erasemode
% of the lines is background.
% 'PannerPatch' handle to pannerpatch - if [], don't update.
% Defaults to [].
% 'DynamicDrag' 1 ==> update lines on the fly (default),
% 0 ==> update panner patch only
% 'Data' structure array with fields
% .h vector of handles to lines
% .data matrix of data for the lines (in columns)
% .xdata if this is present, it must be the same size as .data, and
% the entire line will be transformed into the current limits;
% if not present, a linearly
% spaced xdata will be assumed, and during the dynamic pan, the
% xdata and ydata of the lines will be updated in such a way
% as to only display what is between the current xlimits
% defaults to all the lines in the axes
% 'Transform' function string - applied with feval before setting ydata
% defaults to ''
% 'Immediate' 1==>switch to border Axes immediately (default)
% 0==> " " " " on mouse motion only
% 'Invisible' vector of handles to hide and restore on exit
% 'UserHand' handle to object to use for userdata - defaults to Ax
% 'EraseMode' used for lines during panning, should be 'xor' or
% 'background', defaults to 'background'
% 'Pointer' used during drag - defaults to 'closedhand'
% 'InterimPointer' used prior to drag in case Immediate == 0; defaults
% to nothing (doesn't change). This is a string which is passed
% to setptr.
% OUTPUTS:
% returns 1 if limits changed, 0 else
% Copyright (c) 1988-98 by The MathWorks, Inc.
% $Revision: 1.17 $
% define default values:
ax = [];
bounds = [];
directflag = 1;
borderaxes = [];
pannerpatch = [];
panneraxes = []; % parent of pannerpatch
dynamicdrag = 1;
data = [];
transform = '';
immediate = 1;
invisible = [];
userhand = [];
erasemode = 'background';
pointer = 'closedhand';
interimpointer = '';
% parse parameters - could use some error checking
for i=1:2:length(varargin)
param = lower(varargin{i});
value = varargin{i+1};
eval([param ' = value;'])
end
% finish default value setting
if isempty(ax)
ax = gca;
end
fig = get(ax,'parent');
ptr = getptr(fig);
if ~isempty(interimpointer)
setptr(fig,interimpointer)
end
if isempty(userhand)
userhand = ax;
end
if ~isempty(pannerpatch)
panneraxes = get(pannerpatch,'parent');
end
% initialize "data" structure array from axes line objects here.
% This costly computation will be skipped if you pass in the "data"
% structure array yourself.
% This array has fields:
% .data - matrix
% .columns - index vector; indicates which columns of .data are
% actually displayed as lines
% .h - line handles - one per column of .data(:, data.columns)
% .xdata - either the same size as .data or empty if .Fs >0
% .Fs - scalar; -1 indicates xdata matrix contains x information,
% if >0, xdata is created evenly spaced
% .t0 - scalar; used with .Fs to compute xdata
if isempty(data)
h = findobj(ax,'type','line');
h = setdiff(h,invisible);
if isempty(h)
setptr(fig,ptr)
return
end
for i=1:length(h)
data(i).h = h(i);
data(i).data = get(h(i),'ydata');
data(i).data = data(i).data(:); % make into column
data(i).columns = 1;
data(i).xdata = get(h(i),'xdata');
data(i).xdata = data(i).xdata(:); % make into column
xdf=diff(data(i).xdata); % see if this line is evenly spaced
if length(xdf)>1 & all(xdf==xdf(1)) & xdf(1)~=0
data(i).t0 = data(i).xdata(1); data(i).Fs = 1./xdf(1);
else
data(i).t0 = 0; data(i).Fs = -1;
end
end
end
save_userhand_tag = get(userhand,'tag');
set(userhand,'tag','userhand')
% get current point of mouse click
if directflag
p = get(ax,'currentpoint');
else
p = get(panneraxes,'currentpoint');
end
p = p(1,1:2);
np = p;
if immediate
[oldptr,save_visible] = start_motion(fig,ax,borderaxes,...
data,erasemode,invisible,pointer);
end
xlim = get(ax,'xlim');
ylim = get(ax,'ylim');
% To get fast panning without axes redrawing, we never change
% the xlim and ylim of ax during the dragging. Instead, we
% set the xdata and ydata of the lines during dragging and
% set the xlim and ylim when we are done.
actual_xlim = xlim;
actual_ylim = ylim;
logscale = [strcmp(get(ax,'xscale'),'log') strcmp(get(ax,'yscale'),'log')];
save_callBacks = ...
installCallbacks(userhand,fig,...
{'windowbuttonmotionfcn', 'windowbuttonupfcn'},{'motion', 'up'});
done = 0;
moved = 0;
while ~done
event = waitForNextEvent(userhand);
switch event
case 'motion'
if ~moved,
if ~immediate
[oldptr,save_visible] = start_motion(fig,ax,borderaxes,...
data,erasemode,invisible,pointer);
end
moved = 1;
end
p = np;
[xlim,ylim,oxlim,oylim,np] = ...
draglims(directflag,ax,panneraxes,xlim,ylim,bounds,p,logscale);
if ~isequal([xlim ylim],[oxlim oylim])
if ~isempty(pannerpatch)
setpdata(pannerpatch,xlim,ylim)
end
if dynamicdrag
doDynamicDrag(xlim,ylim,actual_xlim,actual_ylim,....
data,transform)
end
end
case 'up'
done = 1;
end
end
if immediate | moved
p = np;
[xlim,ylim,oxlim,oylim,np] = ...
draglims(directflag,ax,panneraxes,xlim,ylim,bounds,p,logscale);
stop_motion(ax,borderaxes,data,invisible,save_visible)
if dynamicdrag & moved
% need to restore x and y data
for i=1:length(data)
if data(i).Fs > 0
xdata = data(i).t0 + (0:size(data(i).data,1)-1)/data(i).Fs;
else
xdata = data(i).xdata;
end
for j=1:length(data(i).columns)
y = data(i).data(:,data(i).columns(j));
if ~isempty(transform)
y = feval(transform,y);
end
set(data(i).h(j),'xdata',xdata,'ydata',y)
end
end
end
set(ax,'xlim',xlim,'ylim',ylim)
set(fig,oldptr{:})
end
set(fig,{'windowbuttonmotionfcn' 'windowbuttonupfcn'},save_callBacks)
set(userhand,'tag',save_userhand_tag)
if nargout>0
varargout{1} = moved;
end
set(fig,ptr{:})
return
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [oldptr,save_visible] = start_motion(fig,ax,borderaxes,...
data,erasemode,invisible,pointer)
oldptr = getptr(fig);
setptr(fig,pointer)
switchToBorderAxes(ax,borderaxes)
for i=1:length(data)
set(data(i).h,'erasemode',erasemode)
end
save_visible = get(invisible,{'visible'});
set(invisible,'visible','off')
function stop_motion(ax,borderaxes,data,invisible,save_visible)
for i=1:length(data)
set(data(i).h,'erasemode','normal')
end
set(invisible,{'visible'},save_visible)
switchToMainAxes(ax,borderaxes)
function [xlim,ylim,oxlim,oylim,np] = draglims(directflag,ax,...
panneraxes,xlim,ylim,bounds,p,logscale);
% This function takes the current point information and the old limits,
% and calculates the new xlims and ylims.
if directflag
np = get(ax,'currentpoint'); % new point
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -