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);