2 Qanava - Graph drawing library for QT
3 Copyright (C) 2006 Benoit AUTHEMAN
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 //-----------------------------------------------------------------------------
21 // This file is a part of the Qanava software.
24 // \author Benoit Autheman (benoit@libqanava.org)
25 // \date 2004 December 05
26 //-----------------------------------------------------------------------------
34 #include "./qanLayout.h"
35 #include "./qanGrid.h"
38 //-----------------------------------------------------------------------------
39 namespace qan
{ // ::qan
41 //! Layout a graph in space taking into account group membership (clusters) and respecting a chronological order.
44 <img src="./images/qan-timetree_shot.png" alt="Qanava timetree sample">
48 class TimeTree
: public Layout
52 //! Sort nodes on the basis of their date (older first).
55 bool operator()( const Node
* n1
, const Node
* n2
) const;
58 //! STL set sorting node by date.
59 typedef std::multiset
< Node
*, NodeDateComp
> NodeSet
;
61 //! Manager of NodeSet objects.
62 typedef std::list
< NodeSet
* > NodeSetManager
;
66 //! Construct the grid for a cluster based time tree graph layout.
72 /*! \name TimeTree Grid Management *///----------------------------
77 GridBuilder( Grid
& grid
) : _grid( grid
) { }
81 //! Add _one_ grid element for a given cluster coordinates.
82 void buildClusterGrid( int cy
, int w
, int h
, int r
, int g
, int b
);
84 //! Add all horizontal time grid elements for the given (sorted) nodes.
85 void buildTimeGrid( NodeSet
& nodes
, int width
, int height
);
88 void buildTimeLabel( Node
& node
, int x
, int y
);
91 Grid
& getGrid( ) { return _grid
; }
98 //-----------------------------------------------------------------
103 //! Models a group of nodes in the same track (usually a group equals a cluster of nodes).
111 class GroupMedDateComp
114 bool operator()( const Group
* g1
, const Group
* g2
) const;
125 //! Add a group of nodes corresponding to a line of nodes for a given cluster.
126 /*! The node must be sorted by date ascending order. */
127 void addLine( Node::List
* lineNodes
) { _lines
.push_back( lineNodes
); }
129 //! Get the number of lines in this group.
130 int getLineCount( ) const { return _lines
.size( ); }
132 //! Get the ith line in this group.
133 Node::List
* getLine( unsigned int line
);
135 //! Collect this group nodes to a given node list (list can be non emtpy).
136 void collectNodes( Node::List
& nodes
) const;
138 //! Affect a given style type to all of this group nodes.
139 void setNodesType( int type
);
141 //! Test if a group intersect with this group time interval.
142 bool intersect( const Group
& group
) const;
144 //! Get this group median date.
145 QDateTime
getMedianDate( ) const;
147 typedef std::list
< Group
* > Groups
;
149 typedef std::vector
< Node::List
* > Lines
;
151 //! STL multi set with median date group sorting.
152 typedef std::multiset
< Group
*, GroupMedDateComp
> GroupSet
;
156 //! Nodes in each lines must be stored in .
163 //! Models a line of related groups of nodes (the track form a line, but the group in the track can take ultiple single lines).
173 void addGroup( Group
* group
) { _groups
.push_back( group
); }
175 //! Test if a given track time duration interval is disjoint from this track own duration.
176 bool isDisjointOf( Track
& track
);
178 //! Merge a given track groups to this track.
179 void mergeTrack( Track
& track
);
181 typedef std::list
< Track
* > Tracks
;
183 int getLineCount( ) const;
185 float layout( float trackY
, float width
, GridBuilder
& gridBuilder
);
187 //! Collect groups in this track sorted by group's average date.
188 void collectGroups( Group::Groups
& groups
);
190 Group::Groups
& getGroups( ) { return _groups
; }
192 int getNodeCount( ) const;
198 Group::Groups _groups
;
202 //! Sort tracks on the basis of their node (spatial) density.
203 struct TrackDensityComp
205 bool operator()( const Track
* t1
, const Track
* t2
) const;
209 //! Model a series of tracks.
219 void addTrack( Track
* track
);
223 float layout( float width
, GridBuilder
& gridBuilder
);
225 //! Collect all tracks group to a group list in the left-right top to bottom order.
226 void collectGroups( Group::Groups
& groups
);
228 void sortByNodeDensity( );
232 Track::Tracks _tracks
;
236 /*! \name TimeTree Constructor/Destructor *///-------------------------
240 //! TimeTree constructor.
241 TimeTree( NodeSetManager
& nodeSetManager
) :
243 _nodeSetManager( nodeSetManager
) { }
253 NodeSetManager
& _nodeSetManager
;
255 //---------------------------------------------------------------------
259 /*! \name TimeTree Layout Generation Management *///-------------------
265 static float lineIntervalY
;
267 static float trackIntervalY
;
270 virtual void layout( Graph
& graph
, Grid
& grid
, int width
, int height
, QProgressDialog
* progress
= 0 );
274 //! Set nodes horizontal position, and return the resulting layout width.
275 float layoutNodesX( NodeSet
& nodes
);
278 Group
* buildGroup( NodeSet
& clusterNodes
);
280 //---------------------------------------------------------------------
283 //-----------------------------------------------------------------------------
286 #endif // laTimeTree_h