www.gusucode.com > mbcguitools 工具箱 matlab 源码程序 > mbcguitools/xregDisplayDataPatch.m

    function xregDisplayDataPatch(axes, string, point, usePatch)
%XREGDISPLAYDATAPATCH Display a data tooltip
%
%  XREGDISPLAYDATAPATCH(AXES, STRING, POINT)
%  XREGDISPLAYDATAPATCH(AXES, STRING)
%  
%  This helper function displays a data patch on button down with the text
%  in STRING at the point POINT. If POINT is not supplied it is taken as the
%  current point in AXES. 
%
%  XREGDISPLAYDATAPATCH(AXES, STRING, POINT, USEPATCH)
%  XREGDISPLAYDATAPATCH(AXES, STRING, [], USEPATCH)
%
%  The boolean USEPATCH can be used to explicitly specify if a patch should
%  be used as background for the text. If USEPATCH=false then the
%  background for the text is set via the text object. If USEPATCH=true or
%  is not specified then a patch is placed behind the text.

%  Copyright 2000-2014 The MathWorks, Inc. and Ford Global Technologies, Inc.

% Ensure that axes is a handle

% Do we want to use a patch for the background,
if nargin < 4,
    % If we're not told whether we should use a patcb or not, then we use
    % one.
    usePatch = true;
end

% Have we got a point
if nargin < 3 || isempty( point ),
    point = get(axes, 'CurrentPoint');
    point = 2*point(1,:) - point(2,:);
elseif numel( point ) < 3,
    % If we are given a "point" with only two elements then we assume we're
    % looking at a 2D plot and hence we can probably get away with z=3 as
    % the third entry.
    point = [point(:).', 3];
end

% Get the current settings on the axes
oldModes = get(axes, {'XLimMode' 'YLimMode' 'Layer'});
oldUnits = get(axes, 'Units');
% Set the axes properties
set(axes, 'XLimMode', 'manual', 'YLimMode', 'manual', 'Layer', 'bottom');
% Define some common unit to work in
commonUnit = 'point';

% Create a patch to use as the background
if usePatch 
    hPatch = patch('FaceColor',[1 1 0.8],...
        'Parent',axes,...
        'EdgeColor','k',...
        'Tag','xregDataPatch',...
        'Clipping','off');
end

% Ccreate the text to find out its extent and hence if it fits in the figure
hText = text(point(1), point(2), point(3),string,...
    'Parent',axes,...
    'Units','data',...
    'FontName','Lucida Console',...
    'Clipping','off',...
    'HorizontalAlignment','left',...
    'VerticalAlignment','bottom',...
    'Interpreter','none', ...
    'BackgroundColor', [1, 1, 0.8], ...
    'EdgeColor', 'k' );

% Everything in same units (commonUnit) to see if it all fits on
set([axes hText],'Units',commonUnit);
% Get the size of the axes
axPos = get(axes, 'Position');
axW = axPos(3);
axH = axPos(4);

% Define our offset from the clicked point
offset = 5;
% Sort out text size (a bit!) (Max Font Size is 10 point)
% set(hText, 'FontSize', max(6, min([10 axH/size(string, 1) 1.7*axW/size(string, 2)])));

% Lets move the text a little right and up so we can see the point on which
% we clicked (by 5 points)
textPos = get(hText, 'Position');
textPos(1:2) = textPos(1:2) + offset;
set(hText, 'Position', textPos);

% Now find how much space the text takes up
ext = get(hText, 'Extent');
% Does the text go off the end of the axes (to the right)?
if (ext(1) + ext(3)) > axW 
    % Will it go off the left if we right align?
    if (ext(1) - ext(3)) < 0
        textPos(1) = 0;
    else
        % Chage the horizontal alignment and modify the offset
        textPos(1) = textPos(1) - 2*offset;
        set(hText, 'HorizontalAlignment', 'right');
    end
end
% Does it go off the top
if (ext(2) + ext(4)) > axH
    % Does it go off the bottom
    if (ext(2) - ext(4)) < 0
        textPos(2) = 0;
    else
        textPos(2) = textPos(2) - 2*offset;
        set(hText, 'VerticalAlignment', 'top');
    end
end
set(hText, 'Position', textPos);

% Revert to original axes units
set(axes, 'Units', oldUnits);
set(hText, 'Units', 'data');

if usePatch,
    % Get the text extent to set the patch size around the text
    ext = get(hText, 'Extent');
    set( hPatch, ...
        'XData', [ext(1) ext(1)        ext(1)+ext(3) ext(1)+ext(3)],...
        'YData', [ext(2) ext(2)+ext(4) ext(2)+ext(4) ext(2)],...
        'ZData', repmat( point( 3 ), [1, 4] ) );    
    
    handles = [hPatch, hText];
else
    handles = hText;
end
bm = xregGui.ButtonUpManager(ancestor(axes, 'figure'));
bm.getNextEvent({@i_killPatch, axes, handles, oldModes});
set( handles, 'Visible', 'on' );

%----------------------------------------------------------------------
%  SUBFUNCTION i_killPatch
%----------------------------------------------------------------------
function i_killPatch(~, ~, axes, handles, oldModes)

% Remove text and patch
set(axes, {'XLimMode' 'YLimMode' 'Layer'}, oldModes);
delete(handles);