|
Open Graph Drawing Framework |
v. 2023.09 (Elderberry)
|
|
|
Hierarchical layout
This example shows how to read a graph from a file and use a layout algorithm to retrieve a hierarchical visualization of it.
#include <iostream>
#include <string>
{
std::cerr << "Could not load unix-history.gml" << std::endl;
return 1;
}
return 0;
}
Step-by-step explanation
- What we see here for the first time is how to read a graph from a file. To achieve this we first have to enable all the attributes we want to be filled in using the information from the specified file. When calling ogdf::GraphIO::read() (again specifying the correct reader function for .gml files) any attribute enabled in
GA
will be parsed from the file – if present.
- We then set up the configuration for a hierarchical layout algorithm called ogdf::SugiyamaLayout. As can be seen the algorithm is highly modular. In this case we specify
- A ranking module that will determine the layering of the graph
- A module that handles the minimization of two-layer crossing
- The main module that computes the actual graph layout
- Although this is done by passing dynamically allocated configuration objects we don't have to worry about cleaning them up, as the layout class takes care of that. Also there is default values for all modules so you need not explicitly set all of them.
- Calling the layout algorithm on an ogdf::GraphAttribute object relies on node size information and will alter the xy-coordinates of the nodes but will leave the other attributes untouched, so the svg visualization that is output in the end will still use the information initially read from the .gml file.
Hierarchical layout with predefined layering
This example shows a slight modification of the previous one in that layering is not done by an optimization module but instead is specified in advance.
#include <iostream>
#include <string>
0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 9, 10, 10, 11, 12, 12,
13, 14, 14, 15, 16, 17, 18, 18, 19, 19, 20, 21, 22, 22,
22, 23, 23, 23, 23, 24, 25, 26, 27, 27, 27, 28, 29, 29,
29, 30, 30, 31, 31, 31, 32, 33, 33, 34, 34, 35, 35, 35,
35, 0, 1, 2, 3, 5, 6, 7, 8, 10, 11, 12, 14, 15, 16, 18,
19, 20, 21, 22, 23, 25, 27, 29, 30, 31, 32, 33, 34, 35, -1
};
{
std::cerr << "Could not load unix-history-time.gml" << std::endl;
return 1;
}
int i = 0;
return 0;
}
There is just one new concept we encounter here which is ogdf::NodeArray<T>, a templated class used for direct mapping from ogdf::node handles to any type T
. In this case it holds a rank value for each node which is later passed together with GA
to the layout algorithm. In this case the ranking optimization module has no effect. Note that we also disable the separate layout and arranging of connected components by the default packing module using ogdf::SugiyamaLayout::arrangeCCs().
Energy-based layout
This example shows yet another layout algorithm, ogdf::FMMMLayout (fast multipole multilevel layout), suited for very large graphs and based on potential-field and force computations.
#include <iostream>
#include <string>
{
std::cerr << "Could not load sierpinski_04.gml" << std::endl;
return 1;
}
GA.width(v) = GA.height(v) = 5.0;
return 0;
}
Step-by-step explanation
- An important thing to note here is that after loading the graph from a file we can access node width and height without explicitly enabling ogdf::GraphAttributes::nodeGraphics in
GA
. This is because ogdf::GraphAttributes::nodeGraphics and ogdf::GraphAttributes::edgeGraphics are enabled by default.
- ogdf::FMMMLayout can be configured in two ways: using high-level options (recommended) or low-level options (requires good knowledge of the algorithm). For this example we will use the few high-level options ogdf::FMMMLayout provides and thus set the respective flag to true before actually setting anything.
- We then set the unit edge length (a scaling factor if you will), enable initial replacing of nodes and choose one of the available options from ogdf::FMMMOptions::QualityVsSpeed to tune tradeoffs between speed and aesthetic of the resulting graph. The only remaining high-level option is ogdf::FMMMOptions::PageFormatType which defaults to a Square if not explicitly set. These high-level options will then be used to derive the low-level settings accordingly.
- After calling the algorithm on our read graph instance the same instance augmented by the node positions in the resulting graph layout is written back out to a .gml and a .svg file.
Orthogonal layout
This example shows how to layout a graph so that all edges propagate only parallel to the x- or y-axis meaning any edge bends have an angle of 90°. This is called an orthogonal drawing.
#include <iostream>
#include <string>
{
std::cerr << "Could not read ERDiagram.gml" << std::endl;
return 1;
}
{
GA.width(v) /= 2;
GA.height(v) /= 2;
}
return 0;
}
Step-by-step explanation
- Here, we use ogdf::PlanarizationLayout as our base layout algorithm, again configuring it to our needs by passing dynamically allocated module instances.
- The first module we specify is the ogdf::CrossingMinimizationModule for which we choose ogdf::SubgraphPlanarizer. It works in two core phases, the former will compute a planar subgraph while the latter then reinserts the remaining edges while trying to minimize the resulting crossings. We alter its default configuration by setting the number of randomized reruns for planar subgraph computation and making it consider all edges in the postprocessing step during edge reinsertion.
- The next submodule we configure is ogdf::EmbedderModule for which we use a default instance of ogdf::EmbedderMinDepthMaxFaceLayers.
- The final module supplied to
pl
is ogdf::LayoutPlanRepModule. We use ogdf::OrthoLayout to achieve the main feature we wanted to achieve from the beginning and configure the minimum allowed distance between edges and vertices (and their corners).
- As always, after calling the composed algorithm on the graph instance the result is once again written to out to .gml and .svg files.
Hypergraph layout
This example shows the interface for IO and layout of hypergraphs. There are only few algorithms for hypergraphs in the OGDF.
#include <string>
{
H.readBenchHypergraph(
"c17.bench");
return 0;
}
Step-by-step explanation
- While ogdf::Hypergraph is the direct analogon to ogdf::Graph, ogdf::HypergraphAttributesES is the analogon of ogdf::GraphAttributes for edge-standard representation.
- The input file is read via a dedicated hypergraph reader function ogdf::Hypergraph::readBenchHypergraph.
- The hypergraph attributes get initialized and the option ogdf::EdgeStandardType that governs the internal representation of hyperedges is set to a tree representation. Note that only ogdf::EdgeStandardType::star and ogdf::EdgeStandardType::tree will insert dummy nodes which might be useful (as in this example) to generate a representation of the hypergraph using the standard ogdf::Graph and ogdf::GraphAttributes interfaces.
- The base layout algorithm ogdf::HypergraphLayoutES that is then used has basically the same interface for modular configuring as the standard graph layout algorithms but on top of that it also has an option to choose between the general profiles ogdf::HypergraphLayoutES::Profile::Normal and ogdf::HypergraphLayoutES::Profile::ElectricCircuit.
- After calling the layout algorithm on our hypergraph instance we can access the ogdf::GraphAttributes component of
hlES
as the internal representation works on a wrapped instance of ogdf::GraphAttributes with some dummy nodes added anyways. This is especially useful for using the standard ogdf::GraphIO interface to output a reduced representation of the resulting hypergraph layout.
Multilevel layout mixer
This example shows the use of the modular multilevel mixer class that can be used to build energybased multilevel layouts. Since it is modular one can easily assemble different layouts by using different coarsening techniques (merger), placer and single level layouts. As this example is quite exhaustive explanation is provided in place as inline comments.
#include <iostream>
#include <string>
class InitialPlacer;
class MultilevelBuilder;
}
template<class T>
{
T *merger = new T();
merger->setFactor(2.0);
merger->setEdgeLengthAdjustment(0);
return merger;
}
{
return placer;
}
{
}
{
merger = getDoubleFactoredZeroAdjustedMerger<EdgeCoverMerger>();
}
{
merger = getDoubleFactoredZeroAdjustedMerger<LocalBiconnectedMerger>();
}
int main(
int argc,
const char *argv[])
{
if (argc != 2) {
std::cout << "Usage: " << argv[0] << " (0|1|2)" << std::endl;
return 255;
}
std::cerr << "Could not load Graph" << std::endl;
return 1;
}
ga.width(v) = ga.height(v) = 10.0;
}
switch (argv[1][0]) {
case 2:
break;
case 1:
break;
default:
break;
}
mlg.exportAttributes(ga);
return 0;
}
double separation() const override
Returns the minimum distance between edges and vertices.
void setScalingType(ScalingType type)
Sets a ScalingType wich sets the relative scale for the Graph.
The namespace for all OGDF objects.
Declaration of class VariablEmbeddingInserter.
Stores additional attributes of a graph (like layout information).
Declaration of class GraphAttributes which extends a Graph by additional attributes.
void setInitialPlacer(InitialPlacer *placement)
Sets the initial placer module to placement.
static InitialPlacer * getBarycenterPlacer()
The barycenter placer for multilevel layout.
Includes declaration of graph class.
@ All
Postproceesing with all edges.
static bool write(const Graph &G, const string &filename, WriterFunc writer=nullptr)
Writes graph G to a file with name filename and infers the format to use from the file's extension.
FMMMOptions::QualityVsSpeed qualityVersusSpeed() const
Returns the current setting of option qualityVersusSpeed.
void setLayoutModule(LayoutModule *layout)
The planarization approach for drawing graphs.
static const long edgeStyle
Corresponds to edge attributes strokeColor(edge), strokeType(edge), and strokeWidth(edge).
static const long nodeStyle
Corresponds to node attributes strokeColor(node), strokeType(node), strokeWidth(node),...
The optimal ranking algorithm.
MMM is a Multilevel Graph drawing Algorithm that can use different modules.
@ GorgeousAndEfficient
Best quality.
void setRandomize(bool b)
if true, layout algorithm will randomize the layout in the beginning
static bool writeGML(const Graph &G, std::ostream &os)
Writes graph G in GML format to output stream os.
static bool drawSVG(const GraphAttributes &A, std::ostream &os, const SVGSettings &settings)
Optimal edge insertion module.
void call(Graph &G, MultilevelGraph &MLG)
Declaration of class OrthoLayout which represents an orthogonal planar drawing algorithm.
@ RelativeToDesiredLength
Scales by a factor relative to the desired Edgelength m_desEdgeLength.
The fast multipole multilevel layout algorithm.
void setProfile(Profile pProfile)
Sets the layout profile.
Stores additional attributes of edge standard representation of a hypergraph.
The fast multipole embedder approach for force-directed layout.
Declaration of the PlanarSubgraphFast.
The PreprocessorLayout removes multi-edges and self-loops.
Definition of RemoveReinsertType (used for postprocessing in edge insertion algorithms).
virtual void call(HypergraphAttributes &HA) override
Computes a layout of hypergraph given by HA.
static void configureFastLayout(ScalingLayout *sl, MultilevelBuilder *&merger, InitialPlacer *&placer)
The solar merger for multilevel layout.
Declaration of class SubgraphPlanarizer.
static void configureNiceLayout(ScalingLayout *sl, MultilevelBuilder *&merger, InitialPlacer *&placer)
double layerDistance() const
Returns the minimal allowed y-distance between layers.
static bool readGML(Graph &G, std::istream &is)
Reads graph G in GML format from input stream is.
void setInserter(EdgeInsertionModule *pInserter)
Sets the module option for the edge insertion module.
Computation of a planar subgraph using PQ-trees.
virtual void call(GraphAttributes &GA) override
Calls the layout algorithm for graph GA.
void weightedPositionPriority(bool on)
void setRandomizePositions(bool on)
Defines whether the positions of the node are randomized before the secondary layout call.
Places nodes at the barycenter of his neighbors.
double cOverhang() const
Returns the option m_cOverhang, which specifies the minimal distance of incident edges to the corner ...
Declaration and a partial implementation of a Hypergraph class partly based on the original classes f...
double unitEdgeLength() const
Returns the current setting of option unitEdgeLength.
Base class for placer modules.
void setCrossMin(LayeredCrossMinModule *pCrossMin)
Sets the module option for the two-layer crossing minimization.
Preprocessor Layout simplifies Graphs for use in other Algorithms.
Declaration of optimal ranking algorithm for Sugiyama algorithm.
bool useHighLevelOptions() const
Returns the current setting of option useHighLevelOptions.
void setScaling(double min, double max)
Sets the minimum and the maximum scaling factor.
void setExtraScalingSteps(unsigned int steps)
Sets how often the scaling should be repeated.
double nodeDistance() const
Returns the minimal allowed x-distance between nodes on a layer.
void setPlanarLayouter(LayoutPlanRepModule *pPlanarLayouter)
Sets the module option for the planar layout algorithm.
internal::GraphObjectContainer< NodeElement > nodes
The container containing all node objects.
Declares ogdf::EmbedderMinDepthMaxFaceLayers.
virtual void call(GraphAttributes &GA) override
Calls the algorithm for graph GA and returns the layout information in GA.
@ RelativeToDrawing
Scales by a factor relative to the drawing.
Merges nodes with neighbour to get a Multilevel Graph.
static const long edgeType
Corresponds to edge attribute type(edge).
void setLayout(HierarchyLayoutModule *pLayout)
Sets the module option for the computation of the final layout.
void setPacker(CCLayoutPackModule *packer)
Decralation of GraphElement and GraphList classes.
Declaration of Fast Multipole Multilevel Method (FM^3).
static const long nodeTemplate
Corresponds to node attribute templateNode(node).
Declares class GraphIO which provides access to all graph read and write functionality.
double weightBalancing() const
Returns the weight for balancing successors below a node; 0.0 means no balancing.
Places Nodes with solar system rules.
void setEmbedder(EmbedderModule *pEmbedder)
Sets the module option for the graph embedding algorithm.
void setLayoutRepeats(int times=1)
Determines how many times the one-level layout will be called.
Splits and packs the components of a Graph.
A declaration of EdgeStandardRep class representing a graph representation of a hypergraph in the edg...
RegisteredArray for nodes, edges and adjEntries of a graph.
Declares HypergraphAttributes storing specific attributes related to hypergraph layout drawings.
Data type for general directed graphs (adjacency list representation).
void setLayoutModule(LayoutModule *layout)
Sets the secondary layout.
The Orthogonal layout algorithm for planar graphs.
Merges nodes with neighbour to get a Multilevel Graph.
static const long nodeLabel
Corresponds to node attribute label(node).
Base class for merger modules.
bool arrangeCCs() const
Returns the current setting of option arrangeCCs.
@ tree
for every hyperedge e a minimal subcubic tree connecting all hypernodes incident with e together is a...
Sugiyama's layout algorithm.
Declaration of class TileToRowsCCPacker.
MLG is the main data structure for ModularMultilevelMixer.
void setLayoutRepeats(unsigned int repeats)
Sets how often the LayoutModule should be applied.
bool newInitialPlacement() const
Returns the current setting of option newInitialPlacement.
static const long edgeGraphics
Corresponds to edge attribute bends(edge).
void setSecondaryLayout(LayoutModule *layout)
Sets a LayoutModule that should be applied after scaling.
Planar graph embedding that minimizes block-nesting depth and maximizes the external face and optimiz...
Declaration of Fast-Multipole-Embedder layout algorithm.
ScalingLayout scales and calls a secondary layout.
void setSubgraph(PlanarSubgraphModule< int > *pSubgraph)
Sets the module option for the computation of the planar subgraph.
void setRanking(RankingModule *pRanking)
Sets the module option for the node ranking (layer assignment).
static bool read(Graph &G, const string &filename, ReaderFunc reader=nullptr)
Reads graph G from a file with name filename and infers the used format from the file's extension.
void setNumIterations(uint32_t numIterations)
sets the maximum number of iterations
static void configureNoTwistLayout(ScalingLayout *sl, MultilevelBuilder *&merger, InitialPlacer *&placer)
Declaration of class PlanarizationLayout.
The planarization approach for crossing minimization.
Layout algorithms for hypergraph based on edge standard representations (clique / star / tree) - Hype...
void removeReinsert(RemoveReinsertType rrOption)
Sets the remove-reinsert postprocessing method.
Declaration and implementation of the optimal third phase of the Sugiyama algorithm.
Scales a graph layout and calls a secondary layout algorithm.
Modular multilevel graph layout.
The solar placer for multilevel layout.
void call(GraphAttributes &ga) override
Calls planarization layout for GraphAttributes ga.
static MultilevelBuilder * getDoubleFactoredZeroAdjustedMerger()
The tile-to-rows algorithm for packing drawings of connected components.
static const long nodeType
Corresponds to node attribute type(node).
void setCrossMin(CrossingMinimizationModule *pCrossMin)
Sets the module option for crossing minimization.
Class for the representation of nodes.
void setMultilevelBuilder(MultilevelBuilder *levelBuilder)
Sets the multilevel builder module to levelBuilder.
static const long nodeGraphics
Corresponds to node attributes x(node), y(node), width(node), height(node), and shape(node).
void runs(int nRuns)
Sets the number of randomized runs to nRuns.
Declaration of Sugiyama algorithm.
Merges nodes with solar system rules.
void setLevelLayoutModule(LayoutModule *levelLayout)
Sets the one-level layout module to levelLayout.
The LP-based hierarchy layout algorithm.
Declaration of Fast Multipole Multilevel Method (FM^3) options.