All pastes #197486 Raw Edit

Anonymous

public text v1 · immutable
·published 2006-10-11 10:30 UTC
rendered paste body
/*
Qanava - Graph drawing library for QT
Copyright (C) 2006 Benoit AUTHEMAN

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

//-----------------------------------------------------------------------------
// This file is a part of the Qanava software.
//
// \file	laLayout.h
// \author	Benoit Autheman (benoit@libqanava.org)
// \date	2004 May 22
//-----------------------------------------------------------------------------


#ifndef laLayout_h
#define laLayout_h


// Qanava headers
#include "../utl/utlProgress.h"
#include "./laGraph.h"
#include "./laGrid.h"


// STD headers
#include <vector>


// QT headers
#include <QRectF>


//-----------------------------------------------------------------------------
namespace qan { // ::qan
	namespace la { // ::qan::la

	//! Abstract interface defining a graph layout algorithm (placement of node in space).
	/*!
		\nosubgrouping
	*/
	class	Layout
	{
	public:
	
		/*! \name Layout Constructor/Destructor *///---------------------------
		//@{
		//! Layout constructor.
		Layout( ) { }

		//! Layout virtual destructor.
		virtual ~Layout( ) { }

	private:

		Layout( const Layout& l );
		//@}
		//---------------------------------------------------------------------



		/*! \name Layout Generation Management *///----------------------------
		//@{
	public:

		//! Layout nodes from a given graph using r as a clipping rect, and update grid.
		virtual void	layout( la::Graph& graph, la::Grid& grid, 
								QRectF r, utl::Progress& progress, int step = -1 ) = 0;

	protected:

		//! Reset all nodes positions.
		static void		resetNodesPositions( la::Graph& graph );
		//@}
		//---------------------------------------------------------------------
	};



	//! Randomly layout an undirected graph.
	/*!
		\nosubgrouping
	*/
	class Random : public Layout
	{
		/*! \name Random Constructor/Destructor *///---------------------------
		//@{
	public:

		//! Random constructor.
		Random( ) : Layout( ) { }
		//@}
		//---------------------------------------------------------------------



		/*! \name Random Layout Generation Management *///---------------------
		//@{
	public:

		//! .
		virtual	void	layout( la::Graph& graph, la::Grid& grid, 
								QRectF r, utl::Progress& progress, int step = -1 );
		//@}
		//---------------------------------------------------------------------
	};


	//! Layout a graph as concentric circles of nodes.
	/*!
		\nosubgrouping
	*/
	class Concentric : public Layout
	{
		/*! \name Concentric Constructor/Destructor *///-----------------------
		//@{
	public:

		//! Concentric constructor.
		Concentric( double azimutDelta = 45., double circleInterval = 50. ) : 
			Layout( ), _azimutDelta( azimutDelta ), _circleInterval( circleInterval ) { }

	private:

		double	_azimutDelta;

		double	_circleInterval;
		//@}
		//---------------------------------------------------------------------



		/*! \name Concentric Layout Management *///----------------------------
		//@{
	public:

		//! .
		virtual void	layout( la::Graph& graph, la::Grid& grid, 
								QRectF r, utl::Progress& progress, int step = -1 );
		//@}
		//---------------------------------------------------------------------
	};


	//! Layout nodes in a (logarithm) colimacon.
	/*!
		\nosubgrouping
	*/
	class Colimacon : public Layout
	{
		/*! \name Colimacon Constructor/Destructor *///------------------------
		//@{
	public:

		//! Colimacon constructor.
		Colimacon( double azimutDelta = 15., double circleInterval = 10. ) :
			Layout( ), _azimutDelta( azimutDelta ), _circleInterval( circleInterval ) { }

	private:

		double	_azimutDelta;

		double	_circleInterval;
		//@}
		//---------------------------------------------------------------------



		/*! \name Colimacon Layout Management *///-----------------------------
		//@{
	public:

		//! .
		virtual void	layout( la::Graph& graph, la::Grid& grid, 
								QRectF r, utl::Progress& progress, int step = -1 );
		//@}
		//---------------------------------------------------------------------
	};


	//! Layout an undirected graph as a directed top-down tree.
	/*!
		\nosubgrouping
	*/
	class DirectedTree : public Layout
	{
		/*! \name DirectedTree Constructor/Destructor *///---------------------
		//@{
	public:

		//! Define layout orientation.
		enum Orientation
		{
			//! .
			NONE		= 0,

			//! .
			HORIZONTAL	= 1,

			//! .
			VERTICAL	= 2
		};
		
		//! DirectedTree constructor with orientation initialization.
		/*! \param spacing spacing between node on x and y (ex: 120, 70 with VERTICAL).	*/ 
		DirectedTree( const VectorF& spacing, Orientation orientation ) :
			Layout( ), _origin( 2 ), _spacing( spacing ), _orientation( orientation ), _stopRecursion( false ) { _origin( 0 ) = 0.f; _origin( 1 ) = 0.f; }

		//! DirectedTree constructor with origin and orientation initialization.
		/*! \param spacing spacing between node on x and y (ex: 120, 70 with VERTICAL).	*/ 
		DirectedTree( const VectorF& origin, const VectorF& spacing, Orientation orientation ) : 
			Layout( ), _origin( origin ), _spacing( spacing ), _orientation( orientation ), _stopRecursion( false ) { }

	private:

		VectorF		_origin;
		//@}
		//---------------------------------------------------------------------



		/*! \name Hierarchy Layout Generation Management *///------------------
		//@{
	public:

		//! Layout a graph as a hierarchy tree.
		virtual void	layout( la::Graph& graph, la::Grid& grid, 
								QRectF r, utl::Progress& progress, int step = -1 );

	protected:

		//! Layout a node hierarchy as a hierarchy tree.
		void			layout( la::Node& node, VectorF& bbox, int depth, utl::Progress& progress );

		//! Invert the x/y coordinates to set the desired orientation.
		static void		transpose( la::Graph& graph );

		//! Spacing on x and y between tree nodes.
		VectorF			_spacing;

		//! Generated tree orientation.
		Orientation		_orientation;

		//! Container for already laid out nodes.
		la::Node::Set	_marked;

	private:

		//! Get the 'x' horizontal spacing according to the current orientation.
		float			getXSpacing( ) const { return ( _orientation == HORIZONTAL ? _spacing( 1 ) : _spacing( 0 ) ); }

		//! Get the 'y' vertical spacing according to the current orientation.
		float			getYSpacing( ) const{ return ( _orientation == HORIZONTAL ? _spacing( 0 ) : _spacing( 1 ) ); }

		//! Get the 'x' horizontal origin according to the current orientation.
		float			getXOrigin( ) const { return ( _orientation == HORIZONTAL ? _origin( 1 ) : _origin( 0 ) ); }

		//! Get the 'y' vertical origin according to the current orientation.
		float			getYOrigin( ) const { return ( _orientation == HORIZONTAL ? _origin( 0 ) : _origin( 1 ) ); }

		//! Force the tree layout algorithm to stop recursion.
		void			stopRecursion( ) { _stopRecursion = true; }

		//! Return the value of the stop recursion flag.
		bool			getStopRecusrion( ) const  { return _stopRecursion; }

		//! Indicate that the algorithm execution is canceled and that the layout algorithm recusrion must stop.
		bool			_stopRecursion;
		//@}
		//---------------------------------------------------------------------
	};



	//! Layout an undirected graph using a spring force algorithm.
	/*!
		\nosubgrouping
	*/
	class UndirectedGraph : public Layout
	{
		/*! \name UndirectedGraph Constructor/Destructor *///------------------
		//@{
	public:

		//! UndirectedGraph constructor.
		UndirectedGraph( ) : Layout( ), _center( "" ) { }
		//@}
		//---------------------------------------------------------------------



		/*! \name Force Layout Generation Management *///----------------------
		//@{
	public:

		//! Layout 'graph' using a spring force algorithm.
		virtual void	layout( la::Graph& graph, la::Grid& grid, 
								QRectF r, utl::Progress& progress, int step = -1 );

		static void		add( VectorF& a, const VectorF& b );

		static void		scale( VectorF& p, float scale );

		static VectorF	vector( VectorF a, VectorF b );

		static float	length( const VectorF& v );

		static float	length2( const VectorF& v );

	private:

		VectorF	computeRepulseForce( la::Node& node, la::Node::Set& adjacentNodes, la::Node::Set& nodes, la::Graph& graph );

		VectorF	computeSpringForce( la::Node& node, la::Node::Set& adjacentNodes, la::Graph& graph );

		la::Node		_center;

	protected:

		static	void	computeBoundingBox( std::vector< VectorF >& positions, VectorF& min, VectorF& max );
		//@}
		//---------------------------------------------------------------------
	};
	} // ::qan::la
} // ::qan
//-----------------------------------------------------------------------------


#endif // laLayout_h