Mercurial > hg > camir-aes2014
diff toolboxes/graph_visualisation/graphViz4Matlab/layouts/Gvizlayout.m @ 0:e9a9cd732c1e tip
first hg version after svn
author | wolffd |
---|---|
date | Tue, 10 Feb 2015 15:05:51 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/toolboxes/graph_visualisation/graphViz4Matlab/layouts/Gvizlayout.m Tue Feb 10 15:05:51 2015 +0000 @@ -0,0 +1,142 @@ +classdef Gvizlayout < Abstractlayout +% Use the graphVIZ package to determine the optimal layout for a graph. +% +% Matthew Dunham +% University of British Columbia +% http://www.cs.ubc.ca/~mdunham/ + properties + xmin; % The left most point on the graph axis in data units + xmax; % The right most point on the graph axis in data units + ymin; % The bottom most point on the graph axis in data units + ymax; % The top most point on the graph axis in data units + adjMatrix; % The adjacency matrix + maxNodeSize; % The maximum diameter of a node in data units + image; % An image for the button that will lanuch this layout + name; % A unique name for instances of this class. + shortDescription; % A short descriptions used in tooltips. + nodeSize; % The calculated node size, call dolayout() before accessing + centers; % The calculated node centers in an n-by-2 matrix + end + + properties(GetAccess = 'protected', SetAccess = 'protected') + layoutFile = 'layout.dot'; + adjFile = 'adjmat.dot'; + end + + methods + + function obj = Gvizlayout(name) + % constructor + if(nargin < 1) + obj.name = 'Gvizlayout'; + else + obj.name = name; + end + load glicons; + obj.image = icons.energy; + obj.shortDescription = 'Minimum Energy Layout (GraphViz)'; + end + + function available = isavailable(obj) + % Make sure graphViz is available. + available = Gvizlayout.queryGviz('neato'); + if(not(available)) + fprintf('Please install or upgrade graphViz\n'); + end + end + + + end + + + methods(Access = 'protected') + + function calcLayout(obj) + % Have graphViz calculate the layout + obj.writeDOTfile(); + obj.callGraphViz(); + obj.readLayout(); + obj.cleanup(); + end + + function writeDOTfile(obj) + % Write the adjacency matrix into a dot file that graphViz can + % understand. + fid = fopen('adjmat.dot','w'); + fprintf(fid,'digraph G {\ncenter = 1;\nsize="10,10";\n'); + n = size(obj.adjMatrix,1); + for i=1:n, fprintf(fid,'%d;\n',i); end + edgetxt = ' -> '; + for i=1:n + for j=1:n + if(obj.adjMatrix(i,j)) + fprintf(fid,'%d%s%d;\n',i,edgetxt,j); + end + end + end + fprintf(fid,'}'); + fclose(fid); + end + + function callGraphViz(obj) + % Call GraphViz to determine an optimal layout. Write this layout in + % layout.dot for later parsing. + err = system(['neato -Tdot -Gmaxiter=5000 -Gstart=7 -o ',obj.layoutFile,' ',obj.adjFile]); + if(err),error('Sorry, unknown GraphViz failure, try another layout'); end + end + + function readLayout(obj) + % Parse the layout.dot file for the graphViz node locations and + % dimensions. + fid = fopen(obj.layoutFile,'r'); + text = textscan(fid,'%s','delimiter','\n'); + fclose(fid); + text = text{:}; + [start,dims] = strtok(text{cellfun(@(x)~isempty(x),strfind(text,'graph [bb="'))},'"'); + dims = textscan(strtok(dims,'"'),'%n','delimiter',','); + dims = dims{:}'; + text(cellfun(@(x)~isempty(x),strfind(text,' -> ')))=[]; % delete edge info, we don't need it + text(cellfun(@(x)isempty(x),strfind(text,'pos')))=[]; % keep only positions + [start,remaining] = strtok(text,'"'); + [locations,remaining] = strtok(remaining,'"'); + locations = cellfun(@(str)textscan(str,'%n','delimiter',','),locations,'UniformOutput',false); + locations = [locations{:}]; + locations = [locations{:}]'; + obj.scaleLocations(locations,dims); + end + + function scaleLocations(obj,locations,graphVizDims) + % Scale the graphViz node locations to the smartgraph dimensions and + % set the node size. + dims = graphVizDims; loc = locations; + loc(:,1) = (loc(:,1)-dims(1)) ./ (dims(3)-dims(1))*(obj.xmax - obj.xmin) + obj.xmin; + loc(:,2) = (loc(:,2)-dims(2)) ./ (dims(4)-dims(2))*(obj.ymax - obj.ymin) + obj.ymin; + obj.centers = loc; + + a = min(abs(loc(:,1) - obj.xmin)); + b = min(abs(loc(:,1) - obj.xmax)); + c = min(abs(loc(:,2) - obj.ymin)); + d = min(abs(loc(:,2) - obj.ymax)); + obj.nodeSize = min(2*min([a,b,c,d]),obj.maxNodeSize); + + end + + function cleanup(obj) + % delete the temporary files. + delete(obj.adjFile); + delete(obj.layoutFile); + end + + end + + methods(Access = 'protected',Static = true) + + function available = queryGviz(name) + err = system([name,' -V']); + available = ~err; + end + + end + + +end % end of graphVIZlayout class \ No newline at end of file