Doxygen
Loading...
Searching...
No Matches
DotNode Class Reference

A node in a dot graph. More...

#include <src/dotnode.h>

+ Collaboration diagram for DotNode:

Public Types

enum class  LabelStyle { Plain , List , Table }
 
enum  TruncState { Unknown , Truncated , Untruncated }
 

Public Member Functions

 DotNode (DotGraph *graph, const QCString &lab, const QCString &tip, const QCString &url, bool rootNode=FALSE, const ClassDef *cd=nullptr)
 
void addChild (DotNode *n, EdgeInfo::Colors edgeColor=EdgeInfo::Purple, EdgeInfo::Styles edgeStyle=EdgeInfo::Solid, const QCString &edgeLab=QCString(), const QCString &edgeURL=QCString(), int edgeLabCol=-1)
 
void addParent (DotNode *n)
 
void deleteNode (DotNodeRefVector &deletedList)
 
void removeChild (DotNode *n)
 
void removeParent (DotNode *n)
 
int findParent (DotNode *n)
 
void write (TextStream &t, GraphType gt, GraphOutputFormat f, bool topDown, bool toChildren, bool backArrows)
 
void writeXML (TextStream &t, bool isClassGraph) const
 
void writeDocbook (TextStream &t, bool isClassGraph) const
 
void writeDEF (TextStream &t) const
 
void writeLabel (TextStream &t, GraphType gt) const
 
void writeUrl (TextStream &t) const
 
void writeBox (TextStream &t, GraphType gt, GraphOutputFormat f, bool hasNonReachableChildren) const
 
void writeArrow (TextStream &t, GraphType gt, GraphOutputFormat f, const DotNode *cn, const EdgeInfo *ei, bool topDown, bool pointBack=TRUE) const
 
QCString label () const
 
int number () const
 
bool isVisible () const
 
TruncState isTruncated () const
 
int distance () const
 
int subgraphId () const
 
bool isRenumbered () const
 
bool hasDocumentation () const
 
bool isWritten () const
 
void clearWriteFlag ()
 
void renumberNodes (int &number)
 
void markRenumbered ()
 
DotNodemarkHasDocumentation ()
 
void setSubgraphId (int id)
 
void colorConnectedNodes (int curColor)
 
void setDistance (int distance)
 
void markAsVisible (bool b=TRUE)
 
DotNodemarkAsTruncated (bool b=TRUE)
 
const DotNodeRefVectorchildren () const
 
const DotNodeRefVectorparents () const
 
const EdgeInfoVectoredgeInfo () const
 
DotNodesetNodeId (int number)
 

Static Public Member Functions

static void deleteNodes (DotNode *node)
 
static QCString convertLabel (const QCString &, LabelStyle=LabelStyle::Plain)
 

Static Public Attributes

static constexpr auto placeholderUrl = "-"
 

Private Attributes

DotGraphm_graph
 
int m_number
 
QCString m_label
 label text
 
QCString m_tooltip
 node's tooltip
 
QCString m_url
 url of the node (format: remote$local)
 
DotNodeRefVector m_parents
 list of parent nodes (incoming arrows)
 
DotNodeRefVector m_children
 list of child nodes (outgoing arrows)
 
EdgeInfoVector m_edgeInfo
 edge info for each child
 
bool m_deleted = false
 used to mark a node as deleted
 
bool m_written = false
 used to mark a node as written
 
bool m_hasDoc = false
 used to mark a node as documented
 
bool m_isRoot
 indicates if this is a root node
 
const ClassDefm_classDef
 class representing this node (can be 0)
 
bool m_visible = false
 is the node visible in the output
 
TruncState m_truncated = Unknown
 does the node have non-visible children/parents
 
int m_distance = 1000
 shortest path to the root node
 
bool m_renumbered = false
 indicates if the node has been renumbered (to prevent endless loops)
 
int m_subgraphId = -1
 

Detailed Description

A node in a dot graph.

Definition at line 67 of file dotnode.h.

Member Enumeration Documentation

◆ LabelStyle

enum class DotNode::LabelStyle
strong
Enumerator
Plain 
List 
Table 

Definition at line 70 of file dotnode.h.

70{ Plain, List, Table };

◆ TruncState

Enumerator
Unknown 
Truncated 
Untruncated 

Definition at line 77 of file dotnode.h.

@ Truncated
Definition dotnode.h:77
@ Untruncated
Definition dotnode.h:77
@ Unknown
Definition dotnode.h:77

Constructor & Destructor Documentation

◆ DotNode()

DotNode::DotNode ( DotGraph * graph,
const QCString & lab,
const QCString & tip,
const QCString & url,
bool rootNode = FALSE,
const ClassDef * cd = nullptr )

Definition at line 327 of file dotnode.cpp.

329 : m_graph(graph)
330 , m_number(graph->getNextNodeNumber())
331 , m_label(lab)
332 , m_tooltip(tip)
333 , m_url(url)
334 , m_isRoot(isRoot)
335 , m_classDef(cd)
336{
337}
int getNextNodeNumber()
returns the node number.
Definition dotgraph.h:45
int m_number
Definition dotnode.h:130
QCString m_tooltip
node's tooltip
Definition dotnode.h:132
bool m_isRoot
indicates if this is a root node
Definition dotnode.h:140
QCString m_label
label text
Definition dotnode.h:131
const ClassDef * m_classDef
class representing this node (can be 0)
Definition dotnode.h:141
DotGraph * m_graph
Definition dotnode.h:129
QCString m_url
url of the node (format: remote$local)
Definition dotnode.h:133

References m_classDef, m_graph, m_isRoot, m_label, m_number, m_tooltip, and m_url.

Referenced by addChild(), addParent(), deleteNodes(), findParent(), markAsTruncated(), markHasDocumentation(), removeChild(), removeParent(), setNodeId(), and writeArrow().

Member Function Documentation

◆ addChild()

void DotNode::addChild ( DotNode * n,
EdgeInfo::Colors edgeColor = EdgeInfo::Purple,
EdgeInfo::Styles edgeStyle = EdgeInfo::Solid,
const QCString & edgeLab = QCString(),
const QCString & edgeURL = QCString(),
int edgeLabCol = -1 )

Definition at line 339 of file dotnode.cpp.

346{
347 m_children.push_back(n);
348 m_edgeInfo.emplace_back(
349 edgeColor,
350 edgeStyle,
351 edgeLab,
352 edgeURL,
353 edgeLabCol==-1 ? edgeColor : edgeLabCol);
354}
EdgeInfoVector m_edgeInfo
edge info for each child
Definition dotnode.h:136
DotNodeRefVector m_children
list of child nodes (outgoing arrows)
Definition dotnode.h:135

References DotNode(), m_children, and m_edgeInfo.

Referenced by DotClassGraph::addClass(), DotGfxHierarchyTable::addHierarchy(), DotCallGraph::buildGraph(), and DotInclDepGraph::buildGraph().

◆ addParent()

void DotNode::addParent ( DotNode * n)

Definition at line 356 of file dotnode.cpp.

357{
358 m_parents.push_back(n);
359}
DotNodeRefVector m_parents
list of parent nodes (incoming arrows)
Definition dotnode.h:134

References DotNode(), and m_parents.

Referenced by DotClassGraph::addClass(), DotCallGraph::buildGraph(), and DotInclDepGraph::buildGraph().

◆ children()

◆ clearWriteFlag()

void DotNode::clearWriteFlag ( )

Definition at line 888 of file dotnode.cpp.

889{
891 for (const auto &pn : m_parents) if (pn->isWritten()) pn->clearWriteFlag();
892 for (const auto &cn : m_children) if (cn->isWritten()) cn->clearWriteFlag();
893}
bool m_written
used to mark a node as written
Definition dotnode.h:138
#define FALSE
Definition qcstring.h:34

References FALSE, m_children, m_parents, and m_written.

Referenced by DotGraph::computeGraph().

◆ colorConnectedNodes()

void DotNode::colorConnectedNodes ( int curColor)

Definition at line 895 of file dotnode.cpp.

896{
897 for (const auto &cn : m_children)
898 {
899 if (cn->subgraphId()==-1) // uncolored child node
900 {
901 cn->setSubgraphId(curColor);
902 cn->markAsVisible();
903 cn->colorConnectedNodes(curColor);
904 //printf("coloring node %s (%p): %d\n",qPrint(cn->label()),cn,cn->subgraphId());
905 }
906 }
907
908 for (const auto &pn : m_parents)
909 {
910 if (pn->subgraphId()==-1) // uncolored parent node
911 {
912 pn->setSubgraphId(curColor);
913 pn->markAsVisible();
914 pn->colorConnectedNodes(curColor);
915 //printf("coloring node %s (%p): %d\n",qPrint(pn->label()),pn,pn->subgraphId());
916 }
917 }
918}

References m_children, and m_parents.

◆ convertLabel()

QCString DotNode::convertLabel ( const QCString & l,
LabelStyle style = LabelStyle::Plain )
static

Definition at line 196 of file dotnode.cpp.

197{
198 QCString bBefore("\\_/<({[: =-+@%#~?$"); // break before character set
199 QCString bAfter(">]),:;|"); // break after character set
200 QCString p(l);
201 if (p.isEmpty()) return QCString();
202 QCString result;
203 char pc=0;
204 uint32_t idx = 0;
205 int charsLeft=static_cast<int>(p.length());
206 int sinceLast=0;
207 int foldLen = Config_getInt(DOT_WRAP_THRESHOLD); // ideal text length
208 QCString br;
209 QCString br1;
210 if (style==LabelStyle::Table)
211 {
212 result += "<<TABLE CELLBORDER=\"0\" BORDER=\"0\"><TR><TD VALIGN=\"top\" ALIGN=\"LEFT\" CELLPADDING=\"1\" CELLSPACING=\"0\">";
213 }
214 if (style==LabelStyle::List)
215 {
216 br = "<BR ALIGN=\"LEFT\"/>";
217 }
218 else if (style==LabelStyle::Table)
219 {
220 br1 = "</TD></TR>\n<TR><TD VALIGN=\"top\" ALIGN=\"LEFT\" CELLPADDING=\"1\" CELLSPACING=\"0\">";
221 br = br1 + "&nbsp;&nbsp;";
222 }
223 else // style==LabelStyle::Plain
224 {
225 br = "\\l";
226 }
227 while (idx < p.length())
228 {
229 char c = p[idx++];
230 char cs[2] = { c, 0 };
231 const char *replacement = cs;
232 if (style!=LabelStyle::Plain)
233 {
234 switch(c)
235 {
236 case '\\': replacement="\\\\"; break;
237 case '\n': replacement="\\n"; break;
238 case '<': replacement="&lt;"; break;
239 case '>': replacement="&gt;"; break;
240 case '"': replacement="&quot;"; break;
241 case '\'': replacement="&apos;"; break;
242 case '&': replacement="&amp;"; break;
243 }
244 }
245 else // style==LabelStyle::Plain
246 {
247 switch(c)
248 {
249 case '\\': replacement="\\\\"; break;
250 case '\n': replacement="\\n"; break;
251 case '<': replacement="\\<"; break;
252 case '>': replacement="\\>"; break;
253 case '"': replacement="\\\""; break;
254 case '|': replacement="\\|"; break;
255 case '{': replacement="\\{"; break;
256 case '}': replacement="\\}"; break;
257 }
258 }
259 // Some heuristics to insert newlines to prevent too long
260 // boxes and at the same time prevent ugly breaks
261 if (c=='\n')
262 {
263 if (style==LabelStyle::Table)
264 {
265 result+=br1;
266 }
267 else
268 {
269 result+=replacement;
270 }
271 foldLen = (3*foldLen+sinceLast+2)/4;
272 sinceLast=1;
273 }
274 else if ((pc!=':' || c!=':') && charsLeft>foldLen/3 && sinceLast>foldLen && bBefore.contains(c))
275 {
276 result+=br;
277 result+=replacement;
278 foldLen = (foldLen+sinceLast+1)/2;
279 sinceLast=1;
280 }
281 else if (charsLeft>1+foldLen/4 && sinceLast>foldLen+foldLen/3 &&
282 !isupper(c) && isupper(p[idx]))
283 {
284 result+=replacement;
285 result+=br;
286 foldLen = (foldLen+sinceLast+1)/2;
287 sinceLast=0;
288 }
289 else if (charsLeft>foldLen/3 && sinceLast>foldLen && bAfter.contains(c) && (c!=':' || p[idx]!=':'))
290 {
291 result+=replacement;
292 result+=br;
293 foldLen = (foldLen+sinceLast+1)/2;
294 sinceLast=0;
295 }
296 else
297 {
298 result+=replacement;
299 sinceLast++;
300 }
301 charsLeft--;
302 pc=c;
303 }
304 if (style==LabelStyle::List)
305 {
306 result = result.stripWhiteSpace();
307 }
308 if (style==LabelStyle::Table)
309 {
310 result += "</TD></TR>\n</TABLE>>";
311 }
312 return result;
313}
QCString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition qcstring.h:245
#define Config_getInt(name)
Definition config.h:34

References Config_getInt, QCString::contains(), QCString::isEmpty(), QCString::length(), List, Plain, QCString::stripWhiteSpace(), and Table.

Referenced by drawClusterOpening(), drawDirectory(), DotGroupCollaboration::Edge::write(), writeArrow(), writeBoxMemberList(), and writeLabel().

◆ deleteNode()

void DotNode::deleteNode ( DotNodeRefVector & deletedList)

Definition at line 373 of file dotnode.cpp.

374{
375 if (m_deleted) return; // avoid recursive loops in case the graph has cycles
377 // delete all parent nodes of this node
378 for (const auto &pn : m_parents)
379 {
380 pn->deleteNode(deletedList);
381 }
382 // delete all child nodes of this node
383 for (const auto &cn : m_children)
384 {
385 cn->deleteNode(deletedList);
386 }
387 // add this node to the list of deleted nodes.
388 deletedList.push_back(this);
389}
bool m_deleted
used to mark a node as deleted
Definition dotnode.h:137
#define TRUE
Definition qcstring.h:37

References m_children, m_deleted, m_parents, and TRUE.

Referenced by deleteNodes().

◆ deleteNodes()

void DotNode::deleteNodes ( DotNode * node)
static

helper function that deletes all nodes in a connected graph, given one of the graph's nodes

Definition at line 405 of file dotnode.cpp.

406{
407 DotNodeRefVector deletedNodes;
408 node->deleteNode(deletedNodes); // collect nodes to be deleted.
409 for (const auto &dotNode : deletedNodes)
410 {
411 delete dotNode;
412 }
413}
void deleteNode(DotNodeRefVector &deletedList)
Definition dotnode.cpp:373
std::vector< DotNode * > DotNodeRefVector
Definition dotnode.h:63

References deleteNode(), and DotNode().

Referenced by DotCallGraph::~DotCallGraph(), DotClassGraph::~DotClassGraph(), and DotInclDepGraph::~DotInclDepGraph().

◆ distance()

int DotNode::distance ( ) const
inline

Definition at line 107 of file dotnode.h.

107{ return m_distance; }
int m_distance
shortest path to the root node
Definition dotnode.h:144

References m_distance.

Referenced by DotCallGraph::determineVisibleNodes(), DotClassGraph::determineVisibleNodes(), DotInclDepGraph::determineVisibleNodes(), and setDistance().

◆ edgeInfo()

const EdgeInfoVector & DotNode::edgeInfo ( ) const
inline

Definition at line 125 of file dotnode.h.

125{ return m_edgeInfo; }

References m_edgeInfo.

Referenced by writeDEF(), writeDocbook(), and writeXML().

◆ findParent()

int DotNode::findParent ( DotNode * n)
inline

Definition at line 396 of file dotnode.cpp.

397{
398 auto it = std::find(m_parents.begin(),m_parents.end(),n);
399 return it!=m_parents.end() ? static_cast<int>(it-m_parents.begin()) : -1;
400}

References DotNode(), and m_parents.

◆ hasDocumentation()

bool DotNode::hasDocumentation ( ) const
inline

Definition at line 110 of file dotnode.h.

110{ return m_hasDoc; }
bool m_hasDoc
used to mark a node as documented
Definition dotnode.h:139

References m_hasDoc.

◆ isRenumbered()

bool DotNode::isRenumbered ( ) const
inline

Definition at line 109 of file dotnode.h.

109{ return m_renumbered; }
bool m_renumbered
indicates if the node has been renumbered (to prevent endless loops)
Definition dotnode.h:145

References m_renumbered.

Referenced by renumberNodes().

◆ isTruncated()

TruncState DotNode::isTruncated ( ) const
inline

Definition at line 106 of file dotnode.h.

106{ return m_truncated; }
TruncState m_truncated
does the node have non-visible children/parents
Definition dotnode.h:143

References m_truncated.

Referenced by DotCallGraph::determineTruncatedNodes(), DotClassGraph::determineTruncatedNodes(), and DotInclDepGraph::determineTruncatedNodes().

◆ isVisible()

◆ isWritten()

bool DotNode::isWritten ( ) const
inline

Definition at line 111 of file dotnode.h.

111{ return m_written; }

References m_written.

◆ label()

QCString DotNode::label ( ) const
inline

Definition at line 103 of file dotnode.h.

103{ return m_label; }

References m_label.

Referenced by DotClassGraph::determineVisibleNodes().

◆ markAsTruncated()

DotNode & DotNode::markAsTruncated ( bool b = TRUE)
inline

◆ markAsVisible()

◆ markHasDocumentation()

DotNode & DotNode::markHasDocumentation ( )
inline

Definition at line 116 of file dotnode.h.

116{ m_hasDoc = true; return *this;}

References DotNode(), and m_hasDoc.

◆ markRenumbered()

void DotNode::markRenumbered ( )
inline

Definition at line 115 of file dotnode.h.

115{ m_renumbered = true; }

References m_renumbered.

Referenced by renumberNodes().

◆ number()

int DotNode::number ( ) const
inline

Definition at line 104 of file dotnode.h.

104{ return m_number; }

References m_number.

Referenced by renumberNodes(), setNodeId(), and writeArrow().

◆ parents()

const DotNodeRefVector & DotNode::parents ( ) const
inline

◆ removeChild()

void DotNode::removeChild ( DotNode * n)

Definition at line 361 of file dotnode.cpp.

362{
363 auto it = std::find(m_children.begin(),m_children.end(),n);
364 if (it!=m_children.end()) m_children.erase(it);
365}

References DotNode(), and m_children.

◆ removeParent()

void DotNode::removeParent ( DotNode * n)

Definition at line 367 of file dotnode.cpp.

368{
369 auto it = std::find(m_parents.begin(),m_parents.end(),n);
370 if (it!=m_parents.end()) m_parents.erase(it);
371}

References DotNode(), and m_parents.

◆ renumberNodes()

void DotNode::renumberNodes ( int & number)

Definition at line 922 of file dotnode.cpp.

923{
924 if (!isRenumbered())
925 {
926#if DEBUG_RENUMBERING
927 static int level = 0;
928 printf("%3d: ",subgraphId());
929 for (int i = 0; i < level; i++) printf(" ");
930 printf("> %s old = %d new = %d\n",qPrint(m_label),m_number,number);
931 level++;
932#endif
933 m_number = number++;
935 for (const auto &cn : m_children)
936 {
937 cn->renumberNodes(number);
938 }
939 for (const auto &pn : m_parents)
940 {
941 pn->renumberNodes(number);
942 }
943#if DEBUG_RENUMBERING
944 level--;
945 printf("%3d: ",subgraphId());
946 for (int i = 0; i < level; i++) printf(" ");
947 printf("< %s assigned = %d\n",qPrint(m_label),m_number);
948#endif
949 }
950}
void markRenumbered()
Definition dotnode.h:115
int number() const
Definition dotnode.h:104
bool isRenumbered() const
Definition dotnode.h:109
int subgraphId() const
Definition dotnode.h:108
const char * qPrint(const char *s)
Definition qcstring.h:672

References isRenumbered(), m_children, m_label, m_number, m_parents, markRenumbered(), number(), qPrint(), and subgraphId().

◆ setDistance()

void DotNode::setDistance ( int distance)

Definition at line 391 of file dotnode.cpp.

392{
394}
int distance() const
Definition dotnode.h:107

References distance(), and m_distance.

Referenced by DotClassGraph::addClass(), DotCallGraph::buildGraph(), and DotInclDepGraph::buildGraph().

◆ setNodeId()

DotNode & DotNode::setNodeId ( int number)
inline

Definition at line 126 of file dotnode.h.

126{ m_number=number; return *this; }

References DotNode(), m_number, and number().

◆ setSubgraphId()

void DotNode::setSubgraphId ( int id)
inline

Definition at line 117 of file dotnode.h.

117{ m_subgraphId = id; }
int m_subgraphId
Definition dotnode.h:146

References m_subgraphId.

◆ subgraphId()

int DotNode::subgraphId ( ) const
inline

Definition at line 108 of file dotnode.h.

108{ return m_subgraphId; }

References m_subgraphId.

Referenced by renumberNodes().

◆ write()

void DotNode::write ( TextStream & t,
GraphType gt,
GraphOutputFormat f,
bool topDown,
bool toChildren,
bool backArrows )

Definition at line 655 of file dotnode.cpp.

661{
662 //printf("DotNode::write(%d) name=%s this=%p written=%d visible=%d\n",m_distance,qPrint(m_label),this,m_written,m_visible);
663 if (m_written) return; // node already written to the output
664 if (!m_visible) return; // node is not visible
665 writeBox(t,gt,format,m_truncated==Truncated);
667 if (toChildren)
668 {
669 auto it = m_edgeInfo.begin();
670 for (const auto &cn : m_children)
671 {
672 if (cn->isVisible())
673 {
674 //printf("write arrow %s%s%s\n",qPrint(label()),backArrows?"<-":"->",qPrint(cn->label()));
675 writeArrow(t,gt,format,cn,&(*it),topDown,backArrows);
676 }
677 cn->write(t,gt,format,topDown,toChildren,backArrows);
678 ++it;
679 }
680 }
681 else // render parents
682 {
683 for (const auto &pn : m_parents)
684 {
685 if (pn->isVisible())
686 {
687 const auto &children = pn->children();
688 auto child_it = std::find(children.begin(),children.end(),this);
689 size_t index = child_it - children.begin();
690 //printf("write arrow %s%s%s\n",qPrint(label()),backArrows?"<-":"->",qPrint(pn->label()));
691 writeArrow(t,
692 gt,
693 format,
694 pn,
695 &pn->edgeInfo()[index],
696 FALSE,
697 backArrows
698 );
699 }
700 pn->write(t,gt,format,TRUE,FALSE,backArrows);
701 }
702 }
703 //printf("end DotNode::write(%d) name=%s\n",distance,qPrint(m_label));
704}
void writeBox(TextStream &t, GraphType gt, GraphOutputFormat f, bool hasNonReachableChildren) const
Definition dotnode.cpp:540
const DotNodeRefVector & children() const
Definition dotnode.h:123
void writeArrow(TextStream &t, GraphType gt, GraphOutputFormat f, const DotNode *cn, const EdgeInfo *ei, bool topDown, bool pointBack=TRUE) const
Definition dotnode.cpp:604

References children(), FALSE, m_children, m_edgeInfo, m_parents, m_truncated, m_visible, m_written, TRUE, Truncated, writeArrow(), and writeBox().

Referenced by DotGraph::computeGraph().

◆ writeArrow()

void DotNode::writeArrow ( TextStream & t,
GraphType gt,
GraphOutputFormat f,
const DotNode * cn,
const EdgeInfo * ei,
bool topDown,
bool pointBack = TRUE ) const

Definition at line 604 of file dotnode.cpp.

611{
612 t << " Node";
613 if (topDown)
614 t << cn->number();
615 else
616 t << m_number;
617 t << " -> Node";
618 if (topDown)
619 t << m_number;
620 else
621 t << cn->number();
622 t << " [";
623
624 const EdgeProperties *eProps = Config_getBool(UML_LOOK) ? &umlEdgeProps : &normalEdgeProps;
625 QCString aStyle = eProps->arrowStyleMap[ei->color()];
626 bool umlUseArrow = aStyle=="odiamond";
627
628 t << "id=\"edge" << m_graph->getNextEdgeNumber() <<
629 "_Node" << QCString().sprintf("%06d",m_number) <<
630 "_Node" << QCString().sprintf("%06d",cn->number()) << "\",";
631 if (pointBack && !umlUseArrow) t << "dir=\"back\",";
632 t << "color=\"" << eProps->edgeColorMap[ei->color()] << "\",";
633 t << "style=\"" << eProps->edgeStyleMap[ei->style()] << "\"";
634 t << ",tooltip=\" \""; // space in tooltip is required otherwise still something like 'Node0 -> Node1' is used
635 if (!ei->label().isEmpty())
636 {
637 t << ",label=" << convertLabel(ei->label(),LabelStyle::Table) << " ,fontcolor=\"grey\" ";
638 }
639 if (Config_getBool(UML_LOOK) &&
640 eProps->arrowStyleMap[ei->color()] &&
642 )
643 {
644 bool rev = pointBack;
645 if (umlUseArrow) rev=!rev; // UML use relates has arrow on the start side
646 if (rev)
647 t << ",arrowtail=\"" << eProps->arrowStyleMap[ei->color()] << "\"";
648 else
649 t << ",arrowhead=\"" << eProps->arrowStyleMap[ei->color()] << "\"";
650 }
651
652 t << "];\n";
653}
static QCString convertLabel(const QCString &, LabelStyle=LabelStyle::Plain)
Definition dotnode.cpp:196
int style() const
Definition dotnode.h:40
int color() const
Definition dotnode.h:39
QCString label() const
Definition dotnode.h:41
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:150
#define Config_getBool(name)
Definition config.h:33
@ Collaboration
Definition dotgraph.h:31
@ Inheritance
Definition dotgraph.h:31
static EdgeProperties normalEdgeProps
Definition dotnode.cpp:89
static EdgeProperties umlEdgeProps
Definition dotnode.cpp:94
const char *const * arrowStyleMap
Definition dotnode.cpp:30
const char *const * edgeStyleMap
Definition dotnode.cpp:31
const char *const * edgeColorMap
Definition dotnode.cpp:29

References EdgeProperties::arrowStyleMap, Collaboration, EdgeInfo::color(), Config_getBool, convertLabel(), DotNode(), EdgeProperties::edgeColorMap, EdgeProperties::edgeStyleMap, Inheritance, QCString::isEmpty(), EdgeInfo::label(), m_graph, m_number, normalEdgeProps, number(), QCString::sprintf(), EdgeInfo::style(), Table, and umlEdgeProps.

Referenced by DotGraph::computeGraph(), and write().

◆ writeBox()

void DotNode::writeBox ( TextStream & t,
GraphType gt,
GraphOutputFormat f,
bool hasNonReachableChildren ) const

Definition at line 540 of file dotnode.cpp.

544{
545 const char *labCol = nullptr;
546 const char *fillCol = "white";
547 if (m_classDef)
548 {
549 if (m_classDef->hasDocumentation() && hasNonReachableChildren)
550 {
551 labCol = "red";
552 fillCol = "#FFF0F0";
553 }
554 else if (m_classDef->hasDocumentation() && !hasNonReachableChildren)
555 {
556 labCol = "gray40";
557 }
558 else if (!m_classDef->hasDocumentation() && hasNonReachableChildren)
559 {
560 labCol = "orangered";
561 }
562 else // (!m_classDef->hasDocumentation() && !hasNonReachableChildren)
563 {
564 labCol = "grey75";
565 if (m_classDef->templateMaster() && m_classDef->isImplicitTemplateInstance() && m_classDef->templateMaster()->hasDocumentation())
566 {
567 labCol = "gray40";
568 }
569 }
570 }
571 else
572 {
573 labCol = m_url.isEmpty() ? "grey60" : // non link
574 (hasNonReachableChildren ? "red" : "grey40");
575 fillCol = m_url.isEmpty() ? "#E0E0E0" :
576 (hasNonReachableChildren ? "#FFF0F0" : "white");
577 }
578 t << " Node" << m_number << " [";
579 t << "id=\"Node" << QCString().sprintf("%06d",m_number) << "\",";
580 writeLabel(t,gt);
581 t << ",height=0.2,width=0.4";
582 if (m_isRoot)
583 {
584 t << ",color=\"gray40\", fillcolor=\"grey60\", style=\"filled\", fontcolor=\"black\"";
585 }
586 else
587 {
588 t << ",color=\"" << labCol << "\"";
589 t << ", fillcolor=\"" << fillCol << "\"";
590 t << ", style=\"filled\"";
591 writeUrl(t);
592 }
593 if (!m_tooltip.isEmpty())
594 {
595 t << ",tooltip=\"" << escapeTooltip(m_tooltip) << "\"";
596 }
597 else
598 {
599 t << ",tooltip=\" \""; // space in tooltip is required otherwise still something like 'Node0' is used
600 }
601 t << "];\n";
602}
void writeUrl(TextStream &t) const
Definition dotnode.cpp:515
void writeLabel(TextStream &t, GraphType gt) const
Definition dotnode.cpp:415
QCString escapeTooltip(const QCString &tooltip)
Definition dotnode.cpp:99

References escapeTooltip(), m_classDef, m_isRoot, m_number, m_tooltip, m_url, QCString::sprintf(), writeLabel(), and writeUrl().

Referenced by write().

◆ writeDEF()

void DotNode::writeDEF ( TextStream & t) const

Definition at line 831 of file dotnode.cpp.

832{
833 const char* nodePrefix = " node-";
834
835 t << " node = {\n";
836 t << nodePrefix << "id = " << m_number << ";\n";
837 t << nodePrefix << "label = '" << m_label << "';\n";
838
839 if (!m_url.isEmpty())
840 {
841 QCString url(m_url);
842 int dollarPos = url.find('$');
843 if (dollarPos!=-1)
844 {
845 t << nodePrefix << "link = {\n" << " "
846 << nodePrefix << "link-id = '" << url.mid(dollarPos+1) << "';\n";
847 if (dollarPos>0)
848 {
849 t << " " << nodePrefix << "link-external = '"
850 << url.left(dollarPos) << "';\n";
851 }
852 t << " };\n";
853 }
854 }
855 auto it = m_edgeInfo.begin();
856 for (const auto &childNode : m_children)
857 {
858 const EdgeInfo &edgeInfo = *it;
859 t << " node-child = {\n";
860 t << " child-id = '" << childNode->number() << "';\n";
861 t << " relation = ";
862
863 switch (edgeInfo.color())
864 {
865 case EdgeInfo::Blue: t << "public-inheritance"; break;
866 case EdgeInfo::Green: t << "protected-inheritance"; break;
867 case EdgeInfo::Red: t << "private-inheritance"; break;
868 case EdgeInfo::Purple: t << "usage"; break;
869 case EdgeInfo::Orange: t << "template-instance"; break;
870 case EdgeInfo::Orange2: t << "type-constraint"; break;
871 case EdgeInfo::Grey: ASSERT(0); break;
872 }
873 t << ";\n";
874
875 if (!edgeInfo.label().isEmpty())
876 {
877 t << " edgelabel = <<_EnD_oF_dEf_TeXt_\n"
878 << edgeInfo.label() << "\n"
879 << "_EnD_oF_dEf_TeXt_;\n";
880 }
881 t << " }; /* node-child */\n";
882 ++it;
883 }
884 t << " }; /* node */\n";
885}
const EdgeInfoVector & edgeInfo() const
Definition dotnode.h:125
@ Green
Definition dotnode.h:35
@ Purple
Definition dotnode.h:35
@ Orange2
Definition dotnode.h:35
@ Orange
Definition dotnode.h:35
#define ASSERT(x)
Definition qcstring.h:39

References ASSERT, EdgeInfo::Blue, edgeInfo(), QCString::find(), EdgeInfo::Green, EdgeInfo::Grey, QCString::left(), m_children, m_edgeInfo, m_label, m_number, m_url, QCString::mid(), EdgeInfo::Orange, EdgeInfo::Orange2, EdgeInfo::Purple, and EdgeInfo::Red.

◆ writeDocbook()

void DotNode::writeDocbook ( TextStream & t,
bool isClassGraph ) const

Definition at line 768 of file dotnode.cpp.

769{
770 t << " <node id=\"" << m_number << "\">\n";
771 t << " <label>" << convertToXML(m_label) << "</label>\n";
772 if (!m_url.isEmpty())
773 {
774 QCString url(m_url);
775 int dollarPos = url.find('$');
776 if (dollarPos!=-1)
777 {
778 t << " <link refid=\"" << convertToXML(url.mid(dollarPos+1)) << "\"";
779 if (dollarPos>0)
780 {
781 t << " external=\"" << convertToXML(url.left(dollarPos)) << "\"";
782 }
783 t << "/>\n";
784 }
785 }
786 auto it = m_edgeInfo.begin();
787 for (const auto &childNode : m_children)
788 {
789 const EdgeInfo &edgeInfo = *it;
790 t << " <childnode refid=\"" << childNode->number() << "\" relation=\"";
791 if (isClassGraph)
792 {
793 switch(edgeInfo.color())
794 {
795 case EdgeInfo::Blue: t << "public-inheritance"; break;
796 case EdgeInfo::Green: t << "protected-inheritance"; break;
797 case EdgeInfo::Red: t << "private-inheritance"; break;
798 case EdgeInfo::Purple: t << "usage"; break;
799 case EdgeInfo::Orange: t << "template-instance"; break;
800 case EdgeInfo::Orange2: t << "type-constraint"; break;
801 case EdgeInfo::Grey: ASSERT(0); break;
802 }
803 }
804 else // include graph
805 {
806 t << "include";
807 }
808 t << "\">\n";
809 if (!edgeInfo.label().isEmpty())
810 {
811 int p=0;
812 int ni=0;
813 while ((ni=edgeInfo.label().find('\n',p))!=-1)
814 {
815 t << " <edgelabel>"
816 << convertToXML(edgeInfo.label().mid(p,ni-p))
817 << "</edgelabel>\n";
818 p=ni+1;
819 }
820 t << " <edgelabel>"
821 << convertToXML(edgeInfo.label().right(edgeInfo.label().length()-p))
822 << "</edgelabel>\n";
823 }
824 t << " </childnode>\n";
825 ++it;
826 }
827 t << " </node>\n";
828}
QCString convertToXML(const QCString &s, bool keepEntities)
Definition util.cpp:4412

References ASSERT, EdgeInfo::Blue, convertToXML(), edgeInfo(), QCString::find(), EdgeInfo::Green, EdgeInfo::Grey, QCString::left(), m_children, m_edgeInfo, m_label, m_number, m_url, QCString::mid(), EdgeInfo::Orange, EdgeInfo::Orange2, EdgeInfo::Purple, and EdgeInfo::Red.

◆ writeLabel()

void DotNode::writeLabel ( TextStream & t,
GraphType gt ) const

Definition at line 415 of file dotnode.cpp.

416{
418 {
419 // Set shape to the plain type.
420 // the UML properties and methods are rendered using dot' HTML like table format
421 t << "shape=plain,label=";
422 // add names shown as relations to a set, so we don't show
423 // them as attributes as well
424 StringUnorderedSet arrowNames;
425 // for each edge
426 for (const auto &ei : m_edgeInfo)
427 {
428 if (!ei.label().isEmpty()) // labels joined by \n
429 {
430 int i=0;
431 int p=0;
432 QCString lab;
433 while ((i=ei.label().find('\n',p))!=-1)
434 {
435 lab = stripProtectionPrefix(ei.label().mid(p,i-p));
436 arrowNames.insert(lab.str());
437 p=i+1;
438 }
439 lab = stripProtectionPrefix(ei.label().right(ei.label().length()-p));
440 arrowNames.insert(lab.str());
441 }
442 }
443
444 constexpr auto hr_start = "<TR><TD COLSPAN=\"2\" CELLPADDING=\"1\" CELLSPACING=\"0\">";
445 constexpr auto hr_end = "</TD></TR>\n";
446 constexpr auto sep = "<HR/>\n";
447 constexpr auto empty_line = "<TR><TD COLSPAN=\"2\" CELLPADDING=\"1\" CELLSPACING=\"0\">&nbsp;</TD></TR>\n";
448 //printf("DotNode::writeBox for %s\n",qPrint(m_classDef->name()));
449 t << "<<TABLE CELLBORDER=\"0\" BORDER=\"1\">";
450 t << hr_start << convertLabel(m_label,LabelStyle::List) << hr_end;
451 auto dotUmlDetails = Config_getEnum(DOT_UML_DETAILS);
452 if (dotUmlDetails!=DOT_UML_DETAILS_t::NONE)
453 {
454 bool lineWritten = false;
455 t << sep;
456 writeBoxMemberList(t,'+',m_classDef->getMemberList(MemberListType::PubAttribs()),m_classDef,lineWritten,FALSE,&arrowNames);
457 writeBoxMemberList(t,'+',m_classDef->getMemberList(MemberListType::PubStaticAttribs()),m_classDef,lineWritten,TRUE,&arrowNames);
458 writeBoxMemberList(t,'+',m_classDef->getMemberList(MemberListType::Properties()),m_classDef,lineWritten,FALSE,&arrowNames);
459 writeBoxMemberList(t,'~',m_classDef->getMemberList(MemberListType::PacAttribs()),m_classDef,lineWritten,FALSE,&arrowNames);
460 writeBoxMemberList(t,'~',m_classDef->getMemberList(MemberListType::PacStaticAttribs()),m_classDef,lineWritten,TRUE,&arrowNames);
461 writeBoxMemberList(t,'#',m_classDef->getMemberList(MemberListType::ProAttribs()),m_classDef,lineWritten,FALSE,&arrowNames);
462 writeBoxMemberList(t,'#',m_classDef->getMemberList(MemberListType::ProStaticAttribs()),m_classDef,lineWritten,TRUE,&arrowNames);
463 if (Config_getBool(EXTRACT_PRIVATE))
464 {
465 writeBoxMemberList(t,'-',m_classDef->getMemberList(MemberListType::PriAttribs()),m_classDef,lineWritten,FALSE,&arrowNames);
466 writeBoxMemberList(t,'-',m_classDef->getMemberList(MemberListType::PriStaticAttribs()),m_classDef,lineWritten,TRUE,&arrowNames);
467 }
468 if (!lineWritten) t << empty_line;
469 t << sep;
470 lineWritten = false;
471 writeBoxMemberList(t,'+',m_classDef->getMemberList(MemberListType::PubMethods()),m_classDef,lineWritten);
472 writeBoxMemberList(t,'+',m_classDef->getMemberList(MemberListType::PubStaticMethods()),m_classDef,lineWritten,TRUE);
473 writeBoxMemberList(t,'+',m_classDef->getMemberList(MemberListType::PubSlots()),m_classDef,lineWritten);
474 writeBoxMemberList(t,'~',m_classDef->getMemberList(MemberListType::PacMethods()),m_classDef,lineWritten);
475 writeBoxMemberList(t,'~',m_classDef->getMemberList(MemberListType::PacStaticMethods()),m_classDef,lineWritten,TRUE);
476 writeBoxMemberList(t,'#',m_classDef->getMemberList(MemberListType::ProMethods()),m_classDef,lineWritten);
477 writeBoxMemberList(t,'#',m_classDef->getMemberList(MemberListType::ProStaticMethods()),m_classDef,lineWritten,TRUE);
478 writeBoxMemberList(t,'#',m_classDef->getMemberList(MemberListType::ProSlots()),m_classDef,lineWritten);
479 if (Config_getBool(EXTRACT_PRIVATE))
480 {
481 writeBoxMemberList(t,'-',m_classDef->getMemberList(MemberListType::PriMethods()),m_classDef,lineWritten);
482 writeBoxMemberList(t,'-',m_classDef->getMemberList(MemberListType::PriStaticMethods()),m_classDef,lineWritten,TRUE);
483 writeBoxMemberList(t,'-',m_classDef->getMemberList(MemberListType::PriSlots()),m_classDef,lineWritten);
484 }
485 if (m_classDef->getLanguage()!=SrcLangExt::Fortran)
486 {
487 for (const auto &mg : m_classDef->getMemberGroups())
488 {
489 if (!mg->members().empty())
490 {
491 writeBoxMemberList(t,'*',&mg->members(),m_classDef,lineWritten,FALSE,&arrowNames);
492 }
493 }
494 }
495 if (!lineWritten) t << empty_line;
496 }
497 t << "</TABLE>>\n";
498 }
499 else if (Config_getString(DOT_NODE_ATTR).contains("shape=plain"))
500 {
501 t << "label=";
502 if (m_isRoot)
503 t << "<<b>" << convertToXML(m_label) << "</b>>";
504 else if (m_truncated == Truncated)
505 t << "<<i>" << convertToXML(m_label) << "</i>>";
506 else
507 t << '"' << convertLabel(m_label,LabelStyle::Plain) << '"';
508 }
509 else // standard look
510 {
511 t << "label=" << '"' << convertLabel(m_label,LabelStyle::Plain) << '"';
512 }
513}
const std::string & str() const
Definition qcstring.h:537
#define Config_getString(name)
Definition config.h:32
#define Config_getEnum(name)
Definition config.h:35
std::unordered_set< std::string > StringUnorderedSet
Definition containers.h:29
static QCString stripProtectionPrefix(const QCString &s)
Definition dotnode.cpp:315
static void writeBoxMemberList(TextStream &t, char prot, const MemberList *ml, const ClassDef *scope, bool &lineWritten, bool isStatic=FALSE, const StringUnorderedSet *skipNames=nullptr)
Definition dotnode.cpp:117
@ Fortran
Definition types.h:53

References Collaboration, Config_getBool, Config_getEnum, Config_getString, convertLabel(), convertToXML(), FALSE, Fortran, Inheritance, List, m_classDef, m_edgeInfo, m_isRoot, m_label, m_truncated, Plain, QCString::str(), stripProtectionPrefix(), TRUE, Truncated, and writeBoxMemberList().

Referenced by writeBox().

◆ writeUrl()

void DotNode::writeUrl ( TextStream & t) const

Definition at line 515 of file dotnode.cpp.

516{
517 if (m_url.isEmpty() || m_url == DotNode::placeholderUrl) return;
518 int tagPos = m_url.findRev('$');
519 t << ",URL=\"";
520 QCString noTagURL = m_url;
521 if (tagPos!=-1)
522 {
523 t << m_url.left(tagPos);
524 noTagURL = m_url.mid(tagPos);
525 }
526 int anchorPos = noTagURL.findRev('#');
527 if (anchorPos==-1)
528 {
530 t << noTagURL << "\"";
531 }
532 else // insert extensiom before anchor
533 {
534 QCString fn = noTagURL.left(anchorPos);
536 t << fn << noTagURL.right(noTagURL.length() - anchorPos) << "\"";
537 }
538}
static constexpr auto placeholderUrl
Definition dotnode.h:71
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition qcstring.h:153
QCString right(size_t len) const
Definition qcstring.h:219
int findRev(char c, int index=-1, bool cs=TRUE) const
Definition qcstring.cpp:91
QCString left(size_t len) const
Definition qcstring.h:214
void addHtmlExtensionIfMissing(QCString &fName)
Definition util.cpp:5399

References addHtmlExtensionIfMissing(), QCString::findRev(), QCString::left(), QCString::length(), m_url, placeholderUrl, and QCString::right().

Referenced by writeBox().

◆ writeXML()

void DotNode::writeXML ( TextStream & t,
bool isClassGraph ) const

Definition at line 706 of file dotnode.cpp.

707{
708 t << " <node id=\"" << m_number << "\">\n";
709 t << " <label>" << convertToXML(m_label) << "</label>\n";
710 if (!m_url.isEmpty())
711 {
712 QCString url(m_url);
713 int dollarPos = url.find('$');
714 if (dollarPos!=-1)
715 {
716 t << " <link refid=\"" << convertToXML(url.mid(dollarPos+1)) << "\"";
717 if (dollarPos>0)
718 {
719 t << " external=\"" << convertToXML(url.left(dollarPos)) << "\"";
720 }
721 t << "/>\n";
722 }
723 }
724 auto it = m_edgeInfo.begin();
725 for (const auto &childNode : m_children)
726 {
727 const EdgeInfo &edgeInfo = *it;
728 t << " <childnode refid=\"" << childNode->number() << "\" relation=\"";
729 if (isClassGraph)
730 {
731 switch(edgeInfo.color())
732 {
733 case EdgeInfo::Blue: t << "public-inheritance"; break;
734 case EdgeInfo::Green: t << "protected-inheritance"; break;
735 case EdgeInfo::Red: t << "private-inheritance"; break;
736 case EdgeInfo::Purple: t << "usage"; break;
737 case EdgeInfo::Orange: t << "template-instance"; break;
738 case EdgeInfo::Orange2: t << "type-constraint"; break;
739 case EdgeInfo::Grey: ASSERT(0); break;
740 }
741 }
742 else // include graph
743 {
744 t << "include";
745 }
746 t << "\">\n";
747 if (!edgeInfo.label().isEmpty())
748 {
749 int p=0;
750 int ni=0;
751 while ((ni=edgeInfo.label().find('\n',p))!=-1)
752 {
753 t << " <edgelabel>"
754 << convertToXML(edgeInfo.label().mid(p,ni-p))
755 << "</edgelabel>\n";
756 p=ni+1;
757 }
758 t << " <edgelabel>"
759 << convertToXML(edgeInfo.label().right(edgeInfo.label().length()-p))
760 << "</edgelabel>\n";
761 }
762 t << " </childnode>\n";
763 ++it;
764 }
765 t << " </node>\n";
766}

References ASSERT, EdgeInfo::Blue, convertToXML(), edgeInfo(), QCString::find(), EdgeInfo::Green, EdgeInfo::Grey, QCString::left(), m_children, m_edgeInfo, m_label, m_number, m_url, QCString::mid(), EdgeInfo::Orange, EdgeInfo::Orange2, EdgeInfo::Purple, and EdgeInfo::Red.

Member Data Documentation

◆ m_children

DotNodeRefVector DotNode::m_children
private

list of child nodes (outgoing arrows)

Definition at line 135 of file dotnode.h.

Referenced by addChild(), children(), clearWriteFlag(), colorConnectedNodes(), deleteNode(), removeChild(), renumberNodes(), write(), writeDEF(), writeDocbook(), and writeXML().

◆ m_classDef

const ClassDef* DotNode::m_classDef
private

class representing this node (can be 0)

Definition at line 141 of file dotnode.h.

Referenced by DotNode(), writeBox(), and writeLabel().

◆ m_deleted

bool DotNode::m_deleted = false
private

used to mark a node as deleted

Definition at line 137 of file dotnode.h.

Referenced by deleteNode().

◆ m_distance

int DotNode::m_distance = 1000
private

shortest path to the root node

Definition at line 144 of file dotnode.h.

Referenced by distance(), and setDistance().

◆ m_edgeInfo

EdgeInfoVector DotNode::m_edgeInfo
private

edge info for each child

Definition at line 136 of file dotnode.h.

Referenced by addChild(), edgeInfo(), write(), writeDEF(), writeDocbook(), writeLabel(), and writeXML().

◆ m_graph

DotGraph* DotNode::m_graph
private

Definition at line 129 of file dotnode.h.

Referenced by DotNode(), and writeArrow().

◆ m_hasDoc

bool DotNode::m_hasDoc = false
private

used to mark a node as documented

Definition at line 139 of file dotnode.h.

Referenced by hasDocumentation(), and markHasDocumentation().

◆ m_isRoot

bool DotNode::m_isRoot
private

indicates if this is a root node

Definition at line 140 of file dotnode.h.

Referenced by DotNode(), writeBox(), and writeLabel().

◆ m_label

QCString DotNode::m_label
private

label text

Definition at line 131 of file dotnode.h.

Referenced by DotNode(), label(), renumberNodes(), writeDEF(), writeDocbook(), writeLabel(), and writeXML().

◆ m_number

int DotNode::m_number
private

◆ m_parents

DotNodeRefVector DotNode::m_parents
private

list of parent nodes (incoming arrows)

Definition at line 134 of file dotnode.h.

Referenced by addParent(), clearWriteFlag(), colorConnectedNodes(), deleteNode(), findParent(), parents(), removeParent(), renumberNodes(), and write().

◆ m_renumbered

bool DotNode::m_renumbered = false
private

indicates if the node has been renumbered (to prevent endless loops)

Definition at line 145 of file dotnode.h.

Referenced by isRenumbered(), and markRenumbered().

◆ m_subgraphId

int DotNode::m_subgraphId = -1
private

Definition at line 146 of file dotnode.h.

Referenced by setSubgraphId(), and subgraphId().

◆ m_tooltip

QCString DotNode::m_tooltip
private

node's tooltip

Definition at line 132 of file dotnode.h.

Referenced by DotNode(), and writeBox().

◆ m_truncated

TruncState DotNode::m_truncated = Unknown
private

does the node have non-visible children/parents

Definition at line 143 of file dotnode.h.

Referenced by isTruncated(), markAsTruncated(), write(), and writeLabel().

◆ m_url

QCString DotNode::m_url
private

url of the node (format: remote$local)

Definition at line 133 of file dotnode.h.

Referenced by DotNode(), writeBox(), writeDEF(), writeDocbook(), writeUrl(), and writeXML().

◆ m_visible

bool DotNode::m_visible = false
private

is the node visible in the output

Definition at line 142 of file dotnode.h.

Referenced by isVisible(), markAsVisible(), and write().

◆ m_written

bool DotNode::m_written = false
private

used to mark a node as written

Definition at line 138 of file dotnode.h.

Referenced by clearWriteFlag(), isWritten(), and write().

◆ placeholderUrl

auto DotNode::placeholderUrl = "-"
staticconstexpr

Definition at line 71 of file dotnode.h.

Referenced by DotLegendGraph::computeTheGraph(), and writeUrl().


The documentation for this class was generated from the following files: