36using DirDefMap = std::map<std::string,const DirDef *>;
63typedef std::vector< std::pair< std::unique_ptr<DirRelation>,
bool> >
DirRelations;
71 assert(depthIndex>=0 && depthIndex<=
Config_getInt(DIR_GRAPH_MAX_DEPTH));
72 float fraction =
static_cast<float>(depthIndex)/
static_cast<float>(
Config_getInt(DIR_GRAPH_MAX_DEPTH));
73 const char hex[] =
"0123456789abcdef";
75 int luma = 0xef-
static_cast<int>(fraction*
static_cast<float>(range));
78 pow(luma/255.0,gamma/100.0),&r,&g,&b);
79 int red =
static_cast<int>(r*255.0);
80 int green =
static_cast<int>(g*255.0);
81 int blue =
static_cast<int>(b*255.0);
82 assert(red>=0 && red<=255);
83 assert(green>=0 && green<=255);
84 assert(blue>=0 && blue<=255);
87 colStr[1]=hex[red>>4];
88 colStr[2]=hex[red&0xf];
89 colStr[3]=hex[green>>4];
90 colStr[4]=hex[green&0xf];
91 colStr[5]=hex[blue>>4];
92 colStr[6]=hex[blue&0xf];
123 std::string style =
"filled";
145 "URL=\"" << url <<
"\","
158 DirDefMap &directoriesInGraph,
int startLevel)
193 outputStream <<
"\", "
219 for (
const auto &usedDirectory : srcDir->
usedDirs())
221 const auto &dstDir = usedDirectory->dir();
222 if (!dstDir->isParentOf(srcDir) && (isLeaf || usedDirectory->hasDirectSrcDeps()))
225 relationName.
sprintf(
"dir_%06d_%06d", srcDir->
dirIndex(), dstDir->dirIndex());
226 bool directRelation = isLeaf ? usedDirectory->hasDirectDstDeps() : usedDirectory->hasDirectDeps();
227 dependencies.emplace_back(
228 std::make_unique<DirRelation>(relationName, srcDir, usedDirectory.get()),
236 int startLevel,
DirDefMap &directoriesInGraph,
const bool isTreeRoot)
241 drawDirectory(t, directory, directoryProperty, directoriesInGraph,startLevel);
249 drawDirectory(t, directory, directoryProperty, directoriesInGraph,startLevel);
257 drawClusterOpening(t, directory, directoryProperty, directoriesInGraph,
false, startLevel);
262 for (
const auto &subDirectory : directory->
subDirs())
264 drawTree(dependencies, t, subDirectory, startLevel, directoriesInGraph,
false);
295 std::vector<const DirDef *> usedDirsNotDrawn, usedDirsDrawn;
296 for (
const auto& usedDir : dd->
usedDirs())
298 usedDirsNotDrawn.push_back(usedDir->dir());
301 auto moveDrawnDirs = [&usedDirsDrawn,&usedDirsNotDrawn](
const std::vector<const DirDef *>::iterator &newEnd)
306 std::move(newEnd, std::end(usedDirsNotDrawn), std::back_inserter(usedDirsDrawn));
307 usedDirsNotDrawn.erase(newEnd, usedDirsNotDrawn.end());
316 makeOrphaned(
parent->parent()!=
nullptr);
321 const auto &newEnd = std::stable_partition(usedDirsNotDrawn.begin(), usedDirsNotDrawn.end(),
322 [&](
const DirDef *
const usedDir)
324 if (dd!=usedDir && dd->parent()==usedDir->parent())
326 const DotDirProperty usedDirProperty = DotDirPropertyBuilder().makeTruncated(usedDir->hasSubdirs());
327 drawDirectory(t, usedDir, usedDirProperty, dirsInGraph, parent->level());
332 moveDrawnDirs(newEnd);
338 drawTree(dependencies, t, dd, dd->level(), dirsInGraph,
true);
347 const auto &newEnd = std::stable_partition(usedDirsNotDrawn.begin(), usedDirsNotDrawn.end(),
348 [&](
const DirDef *
const usedDir)
350 const DirDef *dir=dd;
353 if (dir!=usedDir && dir->parent()==usedDir->parent())
355 const DotDirProperty usedDirProperty = DotDirPropertyBuilder().
356 makeOrphaned(usedDir->parent()!=nullptr).
357 makeTruncated(usedDir->hasSubdirs()).
359 drawDirectory(t, usedDir, usedDirProperty, dirsInGraph, dir->level());
366 moveDrawnDirs(newEnd);
371 for (
const auto &relationPair : dependencies)
373 const auto &relation = relationPair.first;
374 const bool directRelation = relationPair.second;
375 const auto &udir = relation->destination();
376 const auto &usedDir = udir->dir();
377 const bool destIsSibling = std::find(std::begin(usedDirsDrawn), std::end(usedDirsDrawn), usedDir) != std::end(usedDirsDrawn);
378 const bool destIsDrawn = dirsInGraph.find(usedDir->getOutputFileBase().str())!=dirsInGraph.end();
379 const bool atMaxDepth =
isAtMaxDepth(usedDir, dd->level());
381 if (destIsSibling || (destIsDrawn && (directRelation || atMaxDepth)))
383 const auto &relationName = relation->getOutputFileBase();
384 const auto &dir = relation->source();
386 std::make_unique<DirRelation>(
387 relationName,dir,udir));
388 size_t nrefs = udir->filePairs().size();
390 << usedDir->getOutputFileBase();
391 t <<
" [headlabel=\"" << nrefs <<
"\", labeldistance=1.5";
396 t <<
" headhref=\"" << fn <<
"\"";
397 t <<
" href=\"" << fn <<
"\"";
399 t <<
" color=\"steelblue1\" fontcolor=\"steelblue1\"];\n";
424 md5stream <<
" compound=true\n";
442 int graphId,
bool linkRelations)
449 return DotGraph::writeGraph(out, graphFormat, textFormat, path, fileName, relPath, generateImageMap, graphId);
static void hsl2rgb(double h, double s, double l, double *pRed, double *pGreen, double *pBlue)
A String class for use with Doxygen wrapping std::string and adding some additional functionality off...
DString & sprintf(const char *format,...)
const std::string & str() const
virtual DString briefDescriptionAsTooltip() const =0
virtual DString displayName(bool includeScope=true) const =0
virtual DString getOutputFileBase() const =0
A model of a directory symbol.
virtual int level() const =0
virtual const DString shortName() const =0
virtual int dirIndex() const =0
virtual DirDef * parent() const =0
virtual bool depGraphIsTrivial() const =0
virtual const DirList & subDirs() const =0
virtual const UsedDirLinkedMap & usedDirs() const =0
virtual bool hasSubdirs() const =0
DString getOutputFileBase() const
DString getImgAltText() const override
DString writeGraph(TextStream &out, GraphOutputFormat gf, EmbeddedOutputFormat ef, const DString &path, const DString &fileName, const DString &relPath, bool writeImageMap=true, int graphId=-1, bool linkRelations=true)
void computeTheGraph() override
DString getBaseName() const override
DotDirDeps(const DirDef *dir)
DString getMapLabel() const override
Builder helper to create instances of the DotDirProperty struct.
DotDirPropertyBuilder & makeOriginal(bool b=true)
DotDirProperty m_property
DotDirPropertyBuilder & makePeripheral(bool b=true)
DotDirPropertyBuilder & makeOrphaned(bool b=true)
DotDirPropertyBuilder & makeIncomplete(bool b=true)
DotDirPropertyBuilder & makeTruncated(bool b=true)
static void writeGraphFooter(TextStream &t)
bool m_doNotAddImageToIndex
DString writeGraph(TextStream &t, GraphOutputFormat gf, EmbeddedOutputFormat ef, const DString &path, const DString &fileName, const DString &relPath, bool writeImageMap=true, int graphId=-1)
static void writeGraphHeader(TextStream &t, const DString &title=DString())
static DString convertLabel(const DString &, LabelStyle=LabelStyle::Plain)
static DirRelationLinkedMap dirRelations
T * add(const char *k, Args &&... args)
Text streaming class that buffers data.
std::string str() const
Return the contents of the buffer as a std::string object.
#define Config_getInt(name)
#define Config_getString(name)
constexpr DocNodeVariant * parent(DocNodeVariant *n)
returns the parent node of a given node n or nullptr if the node has no parent.
std::vector< std::pair< std::unique_ptr< DirRelation >, bool > > DirRelations
Elements consist of (1) directory relation and (2) whether it is pointing only to inherited dependees...
static TextStream & common_attributes(TextStream &t, const DirDef *const dir, const DotDirProperty &prop)
static bool isAtMaxDepth(const DirDef *const directory, const int startLevel)
Checks, if the directory is a the maximum drawn directory level.
static void drawClusterClosing(TextStream &t)
static void addDependencies(DirRelations &dependencies, const DirDef *const srcDir, bool isLeaf)
Assembles a list of the directory relations and whether or not they result from "inheritance".
static std::string getDirectoryBorderStyle(const DotDirProperty &property)
Returns a DOT node style according to the directory properties.
static void drawDirectory(TextStream &t, const DirDef *const directory, const DotDirProperty &property, DirDefMap &directoriesInGraph, int startLevel)
Puts DOT code for drawing directory to stream and adds it to the list.
static void drawClusterOpening(TextStream &outputStream, const DirDef *const directory, const DotDirProperty &directoryProperty, DirDefMap &directoriesInGraph, const bool isAncestor, int startLevel)
Writes DOT code for opening a cluster subgraph to stream.
std::map< std::string, const DirDef * > DirDefMap
static void drawTree(DirRelations &dependencies, TextStream &t, const DirDef *const directory, int startLevel, DirDefMap &directoriesInGraph, const bool isTreeRoot)
Recursively draws directory tree.
void writeDotDirDepGraph(TextStream &t, const DirDef *dd, bool linkRelations)
Write DOT code for directory dependency graph.
static DString getDirectoryBackgroundColor(int depthIndex)
Returns a DOT color name according to the directory depth.
static const char * getDirectoryBorderColor(const DotDirProperty &property)
Returns a DOT color name according to the directory properties.
DString escapeTooltip(const DString &tooltip)
Properties are used to format the directories in the graph distinctively.
bool isTruncated
true has successors, none is drawn
bool isOrphaned
true if parent is not drawn
bool isOriginal
true if is the directory for which the graph is drawn
bool isPeripheral
true if no successor of parent of original directory
bool isIncomplete
true if not all successors of a cluster are drawn
void addHtmlExtensionIfMissing(DString &fName)
DString convertToXML(const DString &s, bool keepEntities, const bool citeEntry)
DString escapeCharsInString(const DString &name, bool allowDots, bool allowUnderscore)
A bunch of utility functions.