在 OGDF 中设置节点边界框​​大小

Posted

技术标签:

【中文标题】在 OGDF 中设置节点边界框​​大小【英文标题】:Setting node bounding box size in OGDF 【发布时间】:2021-02-27 14:26:40 【问题描述】:

我正在尝试使用 OGDF 库和 Sugiyama 布局在 Qt 中布局和可视化代码流图。我使用的版本是 v2020.02,在撰写本文时应该是最新的。

我的问题: 创建节点时,我将它们设置为各种大小,但在调用 SugiyamaLayout 算法后,所有节点大小都重置为 20x20(大概是默认值?)。 如果我改用另一种算法(例如PlanarizationLayout),问题就会消失,节点大小会保持其分配的值。 我尝试了不同的配置,例如排名、crossMins 和布局,但节点大小不受这些影响。

最小可重现示例:

//Create graph and attributes
graph_ = new Graph();
GA_ = new GraphAttributes(*graph_, GraphAttributes::nodeGraphics | GraphAttributes::nodeType |
 GraphAttributes::nodeLabel | GraphAttributes::nodeStyle | GraphAttributes::edgeGraphics | 
 GraphAttributes::edgeType | GraphAttributes::edgeArrow);

//Create node and set size
node n = graph_->newNode();
GA_->width(n) = 80; //Or any other dimensions
GA_->height(n) = 40;
//Other nodes and edges omitted

//Create layout
SugiyamaLayout slayout;
slayout.setRanking(new OptimalRanking());
slayout.setCrossMin(new MedianHeuristic());
OptimalHierarchyLayout* ohl = new OptimalHierarchyLayout;
ohl->layerDistance(30.0);
ohl->nodeDistance(25.0);
ohl->weightBalancing(0.8);
slayout.setLayout(ohl);
slayout.call(*GA_);

//Retrieve new node position and size
double x = GA_->x(n);
double y = GA_->y(n);
double w = GA_->width(n);  //This always retrieves w*h of 20x20,
double h = GA_->height(n); //no matter what node dimensions were initially set

//Draw graph, etc. (omitted)

【问题讨论】:

【参考方案1】:

经过更多研究,OGDF 邮件列表为我提供了答案。

这种行为确实是由HierarchyLayoutModule.h 中的一个错误引起的,其中没有保留正确的边界框大小。

可以在here 找到相应的 Github 问题,并将在下一个版本中修复。 同时,可以通过将\include\ogdf\layered\HierarchyLayoutModule.h中的HierarchyLayoutModule::call方法替换为这段代码sn-p来修复:

/**
 * \brief Computes a hierarchy layout of \p levels in \p GA
 * @param levels is the input hierarchy.
 * @param GA is assigned the hierarchy layout.
 */
void call(const HierarchyLevelsBase &levels, GraphAttributes &GA) 
    GraphAttributes AGC(levels.hierarchy());
    // Copy over relevant nodeGraphics attributes that may be used by doCall or need to be preserved
    // edgeGraphics' bend points need to be cleared and aren't copied over
    if (GA.has(GraphAttributes::nodeGraphics)) 
        const GraphCopy &GC = dynamic_cast<const GraphCopy&>(AGC.constGraph());
        for (node vOrig: GA.constGraph().nodes)
        
            node v = GC.copy(vOrig);
            if (v != nullptr) 
                AGC.height(v) = GA.height(vOrig);
                AGC.width(v) = GA.width(vOrig);
                AGC.shape(v) = GA.shape(vOrig);
            
        
    
    doCall(levels,AGC);
    AGC.transferToOriginal(GA);

【讨论】:

以上是关于在 OGDF 中设置节点边界框​​大小的主要内容,如果未能解决你的问题,请参考以下文章

Android 中设置EditText输入框提示文本hint的字体大小

cocos2d中设置精灵的边界框

如何在html网页中设置文本框为必填?

在MFC怎么中设置窗口大小和位置?

如何在 RDLC 的文本框中设置上标

在kivy中设置全局字体大小