/*
* $Revision: 2585 $
*
* last checkin:
* $Author: klein $
* $Date: 2012-07-12 03:46:50 +0200 (Do, 12. Jul 2012) $
***************************************************************/
/** \file
* \brief Declaration of class GraphAttributes which extends a Graph
* by additional attributes.
*
* \author Carsten Gutwenger
* Karsten Klein
* Joachim Kupke
* Sebastian Leipert
*
* \par License:
* This file is part of the Open Graph Drawing Framework (OGDF).
*
* \par
* Copyright (C)
* See README.txt in the root directory of the OGDF installation for details.
*
* \par
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* Version 2 or 3 as published by the Free Software Foundation;
* see the file LICENSE.txt included in the packaging of this file
* for details.
*
* \par
* This program 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 General Public License for more details.
*
* \par
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the Free
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
* \see http://www.gnu.org/copyleft/gpl.html
***************************************************************/
#ifdef _MSC_VER
#pragma once
#endif
#ifndef OGDF_ATTRIBUTED_GRAPH_H
#define OGDF_ATTRIBUTED_GRAPH_H
#include "NodeArray.h"
#include "EdgeArray.h"
#include "String.h"
#include "geometry.h"
namespace ogdf {
//---------------------------------------------------------
// GraphAttributes
// graph topology + graphical attributes
//---------------------------------------------------------
//! Stores additional attributes of a graph (like layout information).
/**
* It is frequently necessary to associate additional attributes with a graph.
* The class GraphAttributes provides various such attributes and is the
* central place were such attributes are stored.
*
* Attributes are simply stored in node or edge arrays; for memory consumption
* reasons, only a subset of these arrays is in fact initialized for the graph;
* non-initialized arrays require only a few bytes of extra memory.
*
* Which arrays are initialized is specified by a bit vector; each bit in this
* bit vector corresponds to one or more attributes. E.g., \a #nodeGraphics
* corresponds to the attributes \a #m_x, \a #m_y, \a #m_width, and \a #m_height;
* whereas \a #edgeDoubleWeight only corresponds to the attribute \a #m_doubleWeight.
*
* Attributes can be initialized by the constructor GraphAttributes(const Graph &,long)
* or the function initAttributes(); attributes can also be deinitialized by
* calling destroyAttributes().
*/
class OGDF_EXPORT GraphAttributes {
public:
//! Types for edge arrows.
enum EdgeArrow {
none, //!< no edge arrows
last, //!< edge arrow at target node of the edge
first, //!< edge arrow at source node of the edge
both, //!< edge arrow at target and source node of the edge
undefined
};
//! Types for line styles.
/**
* The line styles are preliminary the same as in QT.
*/
enum EdgeStyle {
esNoPen = 0, //!< no line
esSolid = 1, //!< solid line
esDash = 2, //!< dashed line
esDot = 3, //!< dotted line
esDashdot = 4, //!< line style "dash dot dash dot ..."
esDashdotdot = 5
//!< line style "dash dot dot dash dot dot ..."
};
//! Converts integer \a i to edge style.
static EdgeStyle intToStyle(int i) {
switch (i) {
case 0:
return esNoPen;
case 1:
return esSolid;
case 2:
return esDash;
case 3:
return esDot;
case 4:
return esDashdot;
case 5:
return esDashdotdot;
default:
return esNoPen;
}
}
//! Types for object brush patterns.
/**
* The brush patterns are currently the same as the GDE project.
*/
enum BrushPattern {
bpNone = 0,
bpSolid = 1,
bpDense1 = 2,
bpDense2 = 3,
bpDense3 = 4,
bpDense4 = 5,
bpDense5 = 6,
bpDense6 = 7,
bpDense7 = 8,
bpHorizontal = 9,
bpVertical = 10,
bpCross = 11,
BackwardDiagonal = 12,
ForwardDiagonal = 13,
DiagonalCross = 14
};
//! Converts integer \a i to brush pattern.
static BrushPattern intToPattern(int i) {
switch (i) {
case 0:
return bpNone;
break;
case 1:
return bpSolid;
break;
case 2:
return bpDense1;
break;
case 3:
return bpDense2;
break;
case 4:
return bpDense3;
break;
case 5:
return bpDense4;
break;
case 6:
return bpDense5;
break;
case 7:
return bpDense6;
break;
case 8:
return bpDense7;
break;
case 9:
return bpHorizontal;
break;
case 10:
return bpVertical;
break;
case 11:
return bpCross;
break;
case 12:
return BackwardDiagonal;
break;
case 13:
return ForwardDiagonal;
break;
case 14:
return DiagonalCross;
break;
default:
return bpNone;
break;
}
}
//! Specifies scaling of images.
enum ImageStyle {
FreeScale = 0, FixScale = 1
};
//! Specifies image alignment.
enum ImageAlignment {
TopLeft = 0, TopCenter, TopRight, CenterLeft, Center, CenterRight, BottomLeft, BottomCenter, BottomRight
};
//! Helper function mapping int values to image styles
static ImageStyle intToImageStyle(int i) {
switch (i) {
case 0:
return FreeScale;
break;
case 1:
return FixScale;
break;
default:
return FreeScale;
}//switch
}//intToStyle
//! Helper function mapping int values to image alignment
static ImageAlignment intToImageAlignment(int i) {
switch (i) {
case 0:
return TopLeft;
break;
case 1:
return TopCenter;
break;
case 2:
return TopRight;
break;
case 3:
return CenterLeft;
break;
case 4:
return Center;
break;
case 5:
return CenterRight;
break;
case 6:
return BottomLeft;
break;
case 7:
return BottomCenter;
break;
case 8:
return BottomRight;
break;
default:
return TopLeft;
}//switch
}//intToAlignment
protected:
/**
* Writes string \a str into a GML file such that line length limits
* are respected and characters '\', '"' are correctly escaped.
*/
void writeLongString(ostream &os, const String &str) const;
/* Methods for OGML serialization */
//! Static helper method for mapping edge styles to ogml.
static const char * edgeStyleToOGML(const GraphAttributes::EdgeStyle & edgeStyle);
//! Static helper method for mapping image alignments to ogml.
static const char * imageAlignmentToOGML(const GraphAttributes::ImageAlignment &imgAlign);
//! Static helper method for mapping image style to ogml.
static const char * imageStyleToOGML(const GraphAttributes::ImageStyle &imgStyle);
//! Static helper method for mapping brush patterns styles to ogml.
static const char * brushPatternToOGML(const GraphAttributes::BrushPattern & brushPattern);
//static void generateIndent(char ** indent, const int & indentSize);
//! Static helper method for exchanging X(HT)ML-tag specific chars.
String formatLabel(const String & labelText);
/* End methods for OGML serialization */
const Graph *m_pGraph; //!< associated graph
bool m_directed; //!< whether or not the graph is directed
// graphical representation of nodes
NodeArray m_x; //!< x-coordinate of a node
NodeArray m_y; //!< y-coordinate pf a node
NodeArray m_width; //!< width of a node's bounding box
NodeArray m_height; //!< height of a nodes's bounding box
NodeArray m_nodeLabel; //!< label of a node
NodeArray m_nodeColor; //!< color of a node
NodeArray m_nodeLine; //!< line color of a node
NodeArray m_nodeShape; //!< shape of a node
NodeArray m_nodeLineWidth; //!< line width of a node
NodeArray m_nodePattern; //!< brush pattern of a node
NodeArray m_nodeStyle; //!< line style of a node
NodeArray m_nodeTemplate; //!< name of template of a node
// images
NodeArray m_imageUri;
NodeArray m_imageStyle;
NodeArray m_imageAlign;
NodeArray m_imageDrawLine;
NodeArray m_imageWidth;
NodeArray m_imageHeight;
// other node attributes
NodeArray m_nodeId; //!< user ID of a node
NodeArray m_level; //!< level of a node
NodeArray m_nodeIntWeight; //!< (integer) weight of a node
NodeArray m_vType; // type (vertex, dummy, generalizationMerger)
// graphical representation of edges
EdgeArray m_bends; //!< list of bend points of an edge
EdgeArray m_edgeLabel; //!< label of an edge
EdgeArray m_edgeArrow; //!< arrow type of an edge
EdgeArray m_edgeStyle; //!< line style of an edge
EdgeArray m_edgeColor; //!< line color of an edge
EdgeArray m_edgeWidth; //!< line width of an edge
EdgeArray m_eType; //!< type of an edge (association or generalization)
// other edge attributes
EdgeArray m_intWeight; //!< (integer) weight of an edge
EdgeArray m_doubleWeight; //!< (real number) weight of an edge
EdgeArray m_subGraph; //!< is element of subgraphs given by bitvector
long m_attributes; //!< bit vector of currently used attributes
public:
//! Bits for specifying attributes.
enum {
nodeGraphics = 0x00001, //!< node attributes m_x, m_y, m_width, m_height, m_nodeShape
edgeGraphics = 0x00002, //!< edge attribute m_bends
nodeLevel = 0x00004, //!< node attribute m_level
edgeIntWeight = 0x00008, //!< edge attribute m_intWeight
edgeDoubleWeight = 0x00010, //!< edge attribute m_doubleWeight
edgeLabel = 0x00020, //!< edge attribute m_edgeLabel
nodeLabel = 0x00040, //!< node attribute m_nodeLabel
edgeType = 0x00080, //!< edge attribute m_eType
nodeType = 0x00100, //!< node attribute m_vType
nodeColor = 0x00200, //!< node attribute m_nodeColor, m_nodeLine
nodeId = 0x00400, //!< node attribute m_nodeId
edgeArrow = 0x00800, //!< edge attribute m_edgeArrow
edgeColor = 0x01000, //!< edge attribute m_edgeColor
edgeStyle = 0x02000, //!< edge attribute m_edgeStyle, m_edgeWidth
nodeStyle = 0x04000, //!< node attributes m_nodePattern, m_nodeStyle, m_nodeLineWidth;
//!< experimental: m_imageUri, m_imageStyle, m_imageAlign,
//!< m_imageDrawLine, m_imageWidth, m_imageHeight
nodeTemplate = 0x08000, //!< node attribute m_nodeTemplate
edgeSubGraph = 0x10000, //!< edge attribute m_subGraph
nodeWeight = 0x20000
//!< node attribute m_nodeIntWeight
};
//! Bits for specifying node shapes.
enum {
oval = 0x8001, rectangle = 0x8002
};
//! Constructs graph attributes for no associated graph (default constructor).
/**
* The associated graph can be set later with the init() function.
*/
GraphAttributes();
//! Constructs graph attributes associated with the graph \a G.
/**
* @param G is the associated graph.
* @param initAttributes specifies the set of attributes that can be accessed.
*/
GraphAttributes(const Graph &G, long initAttributes = nodeGraphics | edgeGraphics);
virtual ~GraphAttributes() {
}
//! Initializes the graph attributes for graph \a G.
/**
* @param G is the new associated graph.
* @param initAttr specifies the set of attributes that can be accessed.
*
* \warning All attributes that were allocated before are destroyed by this function!
* If you wish to extend the set of allocated attributes, use initAttributes().
*/
virtual void init(const Graph &G, long initAttr);
//! Returns currently accessible attributes.
long attributes() const {
return m_attributes;
}
//! Initializes attributes in \a attr for usage.
void initAttributes(long attr);
//! Destroys attributes in attr.
void destroyAttributes(long attr);
//! Returns a reference to the associated graph
const Graph& constGraph() const {
return *m_pGraph;
}
//! Returns if the graph is directed.
bool directed() {
return m_directed;
}
//! Sets if the graph is directed to \a directed.
void directed(bool directed) {
m_directed = directed;
}
//! Returns the template name of node \a v.
const String &templateNode(node v) const {
return m_nodeTemplate[v];
}
//! Returns the template name of node \a v.
String &templateNode(node v) {
return m_nodeTemplate[v];
}
//! Returns the x-coordinate of node \a v.
const double &x(node v) const {
return m_x[v];
}
//! Returns the x-coordinate of node \a v.
double &x(node v) {
return m_x[v];
}
//! Returns the y-coordinate of node \a v.
const double &y(node v) const {
return m_y[v];
}
//! Returns the y-coordinate of node \a v.
double &y(node v) {
return m_y[v];
}
//! Returns a reference to the NodeArray \a m_width.
const NodeArray &width() const {
return m_width;
}
//! Returns a refeence to the NodeArray \a m_width.
NodeArray &width() {
return m_width;
}
//! Returns the width of the bounding box of node \a v.
const double &width(node v) const {
return m_width[v];
}
//! Returns the width of the bounding box of node \a v.
double &width(node v) {
return m_width[v];
}
//! Returns a reference to the NodeArray \a m_height.
const NodeArray &height() const {
return m_height;
}
//! Returns a refeence to the NodeArray \a m_height.
NodeArray &height() {
return m_height;
}
//! Returns the height of the bounding box of node \a v.
const double &height(node v) const {
return m_height[v];
}
//! Returns the height of the bounding box of node \a v.
double &height(node v) {
return m_height[v];
}
//! Returns the level of node \a v.
const int &level(node v) const {
return m_level[v];
}
//! Returns the level of node \a v.
int &level(node v) {
return m_level[v];
}
//! Returns the weight of node \a v.
const int &weight(node v) const {
return m_nodeIntWeight[v];
}
//! Returns the weight of node \a v.
int &weight(node v) {
return m_nodeIntWeight[v];
}
//! Returns the brush pattern of node \a v.
const BrushPattern &nodePattern(node v) const {
return m_nodePattern[v];
}
//! Returns the brush pattern of node \a v.
BrushPattern &nodePattern(node v) {
return m_nodePattern[v];
}
//! Returns the line style of node \ v.
const EdgeStyle &styleNode(node v) const {
return m_nodeStyle[v];
}
//! Returns the line style of node \ v.
EdgeStyle &styleNode(node v) {
return m_nodeStyle[v];
}
//! Returns the line width of node \a v.
const double &lineWidthNode(node v) const {
return m_nodeLineWidth[v];
}
//! Returns the line width of node \a v.
double &lineWidthNode(node v) {
return m_nodeLineWidth[v];
}
//! Returns the line color of node \a v.
const String &nodeLine(node v) const {
return m_nodeLine[v];
}
//! Returns the line color of node \a v.
String &nodeLine(node v) {
return m_nodeLine[v];
}
//! Returns the list of bend points of edge \a e.
const DPolyline &bends(edge e) const {
return m_bends[e];
}
//! Returns the list of bend points of edge \a e.
DPolyline &bends(edge e) {
return m_bends[e];
}
//! Returns the (integer) weight of edge \a e.
const int &intWeight(edge e) const {
return m_intWeight[e];
}
//! Returns the (integer) weight of edge \a e.
int &intWeight(edge e) {
return m_intWeight[e];
}
//! Returns the (real number) weight of edge \a e.
const double &doubleWeight(edge e) const {
return m_doubleWeight[e];
}
//! Returns the (real number) weight of edge \a e.
double &doubleWeight(edge e) {
return m_doubleWeight[e];
}
//! Returns the line width of edge \a e.
const double &edgeWidth(edge e) const {
return m_edgeWidth[e];
}
//! Returns the line width of edge \a e.
double &edgeWidth(edge e) {
return m_edgeWidth[e];
}
//! Returns the color of node \a v.
const String &colorNode(node v) const {
return m_nodeColor[v];
}
//! Returns the color of node \a v.
String &colorNode(node v) {
return m_nodeColor[v];
}
//! Returns the shape type of node \a v.
int shapeNode(node v) const {
return m_nodeShape[v];
}
//! Returns the shape type of node \a v.
int &shapeNode(node v) {
return m_nodeShape[v];
}
//! Returns the label of node \ v.
const String &labelNode(node v) const {
return m_nodeLabel[v];
}
//! Returns the label of node \ v.
String &labelNode(node v) {
return m_nodeLabel[v];
}
//! Returns the label of edge \a e.
const String &labelEdge(edge e) const {
return m_edgeLabel[e];
}
//! Returns the label of edge \a e.
String &labelEdge(edge e) {
return m_edgeLabel[e];
}
//! Returns the type of edge \a e.
Graph::EdgeType type(edge e) const {
return m_eType.valid() ? m_eType[e] : Graph::association;
}
//! Returns the type of edge \a e.
Graph::EdgeType &type(edge e) {
return m_eType[e];
}
//! Returns the type of node \a v.
Graph::NodeType type(node v) const {
return m_vType.valid() ? m_vType[v] : Graph::vertex;
}
//! Returns the type of node \a v.
Graph::NodeType &type(node v) {
return m_vType[v];
}
//! Returns the user ID of node \a v.
const int &idNode(node v) const {
return m_nodeId[v];
}
//! Returns the user ID of node \a v.
int &idNode(node v) {
return m_nodeId[v];
}
//! Returns the arrow type of edge \a e.
const EdgeArrow &arrowEdge(edge e) const {
return m_edgeArrow[e];
}
//! Returns the arrow type of edge \a e.
EdgeArrow &arrowEdge(edge e) {
return m_edgeArrow[e];
}
//! Returns the line style of an edge \a e.
const EdgeStyle &styleEdge(edge e) const {
return m_edgeStyle[e];
}
//! Returns the line style of an edge \a e.
EdgeStyle &styleEdge(edge e) {
return m_edgeStyle[e];
}
//! Returns the color of node \a v.
const String &colorEdge(edge e) const {
return m_edgeColor[e];
}
//! Returns the color of node \a v.
String &colorEdge(edge e) {
return m_edgeColor[e];
}
// Images:
//! Returns image uri of node v.
const String &imageUriNode(node v) const {
return m_imageUri[v];
}
//! Returns image uri of node v.
String &imageUriNode(node v) {
return m_imageUri[v];
}
//! Returns image style of node v.
const ImageStyle &imageStyleNode(node v) const {
return m_imageStyle[v];
}
//! Returns image style of node v.
ImageStyle &imageStyleNode(node v) {
return m_imageStyle[v];
}
// Returns image alignment of node v.
const ImageAlignment &imageAlignmentNode(node v) const {
return m_imageAlign[v];
}
// Returns image alignment of node v.
ImageAlignment &imageAlignmentNode(node v) {
return m_imageAlign[v];
}
//! Returns bool value drawLine of node v.
const bool &imageDrawLineNode(node v) const {
return m_imageDrawLine[v];
}
//! Returns bool value drawLine of node v.
bool &imageDrawLineNode(node v) {
return m_imageDrawLine[v];
}
//! Returns image width of node v.
const double &imageWidthNode(node v) const {
return m_imageWidth[v];
}
//! Returns image width of node v.
double &imageWidthNode(node v) {
return m_imageWidth[v];
}
// Returns image height of node v.
const double &imageHeightNode(node v) const {
return m_imageHeight[v];
}
// Returns image height of node v.
double &imageHeightNode(node v) {
return m_imageHeight[v];
}
//! Returns the edgesubgraph value of an edge \a e.
const unsigned int &subGraphBits(edge e) const {
return m_subGraph[e];
}
//! Returns the edgesubgraph value of an edge \a e.
unsigned int &subGraphBits(edge e) {
return m_subGraph[e];
}
//! Checks whether edge \a e belongs to basic graph \a n.
bool inSubGraph(edge e, int n) const {
OGDF_ASSERT( n>=0 && n<32 );
return (m_subGraph[e] & (1 << n)) != 0;
}
//! Addes edge \a e to basic graph \a n.
void addSubGraph(edge e, int n) {
OGDF_ASSERT( n>=0 && n<32 );
m_subGraph[e] |= (1 << n);
}
//! Removes edge \a e from basic graph \a n.
void removeSubGraph(edge e, int n) {
OGDF_ASSERT( n>=0 && n<32 );
m_subGraph[e] &= ~(1 << n);
}
//! Returns the bounding box of the graph.
const DRect boundingBox() const;
/**
* We hide the internal representation of semantic node types from
* the user to be able to change this later (semantic node type member array).
* We are not allowed to set association classes manually, only by calling
* createAssociationClass().
*/
bool isAssociationClass(node v) const {
return (type(v) == Graph::associationClass);
}
/**
* According to the \a mode switch add either the node center points to
* the bends or the anchor point on the node boundary
* - \a mode = 0: only add node center
* - \a mode = 1: compute intersection with the line segment to the center
* and the boundary of the rectangular node
* - \a mode = 2: compute intersection with the first/last line segment
* and the boundary of the rectangular node
*/
void addNodeCenter2Bends(int mode = 1);
void clearAllBends();
//! Returns a list of all inheritance hierarchies in the graph.
/**
* Inheritance hierarchies are identified by edges with type Graph::generalization.
*
* @param list is a list of all hierarchies; each hierarchie is itself a list
* of all nodes in this hierarchy.
*
* \return Returns the number of generalization hierarchies.
*/
int hierarchyList(List*> &list) const;
//! Returns a list of all inheritance hierarchies in the graph.
/**
* Inheritance hierarchies are identified by edges with type Graph::generalization.
*
* @param list is a list of all hierarchies; each hierarchie is itself a list
* of all edges in this hierarchy.
*
* \return Returns the number of generalization hierarchies.
*/
int hierarchyList(List*> &list) const;
//! Sets the width of all nodes to \a w.
void setAllWidth(double w);
//! Sets the height of all nodes to \a h.
void setAllHeight(double h);
//! Reads the graph from a GML file \a fileName.
bool readGML(Graph &G, const String &fileName);
//! Reads the graph from a GML input stream \a is.
bool readGML(Graph &G, istream &is);
//! Writes the graph with its attributes in GML format to file \a fileName.
void writeGML(const String &fileName) const;
//! Writes the graph with its attributes in GML format to output stream \a os.
void writeGML(ostream &os) const;
//! Writes the graph with its attributes in SVG format to file \a fileName.
/**
* @param fileName filename of the SVG
* @param fontSize size of node label (default = 3)
* @param fontColor color of node label (default = #000000)
*/
void writeSVG(const String &fileName, int fontSize = 3, const String &fontColor = "#000000") const;
//! Writes the graph with its attributes in SVG format to output stream \a os.
/**
* @param os output stream for SVG
* @param fontSize size of node label
* @param fontColor color of node label
*/
void writeSVG(ostream &os, int fontSize, const String &fontColor) const;
//! Reads the graph and attributes from the XML file \a fileName.
bool readXML(Graph &G, const String &fileName);
//! Reads the graph and attributes from the XML input stream \a is.
bool readXML(Graph &G, istream &is);
//! Writes the graph to the XML file \a fileName.
void writeXML(const String &fileName, const char* delimiter = "", const char* offset = "") const;
//! Writes the graph to XML output stream \a os.
virtual void writeXML(ostream &os, const char* delimiter = "", const char* offset = "") const;
//! Reads a graph in Rudy format from file \a fileName.
bool readRudy(Graph &G, const String &fileName);
//! Reads a graph in Rudy format from input stream \a is.
bool readRudy(Graph &G, istream &is);
//! Writes the graph in Rudy format to file \a fileName.
void writeRudy(const String &fileName) const;
//! Writes the graph in Rudy format to output stream \a os.
void writeRudy(ostream &os) const;
//! Removes unnecessary bend points in orthogonal segements.
/**
* Processes all edges and removes unnecessary bend points in the bend point list
* of the edge, i.e., bend points such that the preceding and succeeding bend point
* form a horizontal or vertical segement containing this bend point. This function
* is useful to remove redundant bend points in an orthogonal layout.
*/
void removeUnnecessaryBendsHV();
};
} // end namespace ogdf
#endif