Skip to content

Commit

Permalink
#228 Draft queue based BFS. Strat naive layout implementation. WIP.
Browse files Browse the repository at this point in the history
Signed-off-by: cneben <[email protected]>
  • Loading branch information
cneben committed Aug 13, 2024
1 parent 1549900 commit 1593eb3
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 8 deletions.
2 changes: 2 additions & 0 deletions samples/layouts/layouts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,15 @@

// QuickQanava headers
#include <QuickQanava.h>
#include "./qanOrgTreeLayout.h"

//-----------------------------------------------------------------------------
int main( int argc, char** argv )
{
QGuiApplication app(argc, argv);
QQuickStyle::setStyle("Material");
QQmlApplicationEngine* engine = new QQmlApplicationEngine();
qmlRegisterType<qan::OrgTreeLayout>("QuickQanava", 2, 0, "OrgTreeLayout");
engine->addPluginPath(QStringLiteral("../../src")); // Necessary only for development when plugin is not installed to QTDIR/qml
QuickQanava::initialize(engine);
engine->load(QUrl("qrc:/layouts.qml"));
Expand Down
25 changes: 19 additions & 6 deletions samples/layouts/layouts.qml
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,29 @@ ApplicationWindow {
parent: graphView
id: graph
Component.onCompleted: {
var n1 = graph.insertNode()
n1.label = "Hello World"; n1.item.x=15; n1.item.y= 25
let n1 = graph.insertNode()
n1.label = "n1"; n1.item.x=15; n1.item.y= 25
n1.item.ratio = 0.4
var n2 = graph.insertNode()
n2.label = "Node 2"; n2.item.x=15; n2.item.y= 125

var e = graph.insertEdge(n1, n2);
let n11 = graph.insertNode()
n11.label = "n11"; n11.item.x=15; n11.item.y= 125
let n12 = graph.insertNode()
n12.label = "n12"; n12.item.x=125; n12.item.y= 125


let n121 = graph.insertNode()
n121.label = "n121"; n121.item.x=125; n121.item.y= 225

graph.insertEdge(n1, n12);
graph.insertEdge(n1, n11);
graph.insertEdge(n12, n121);

orgTreeLayout.layout(n1);
}
Qan.OrgTreeLayout {
id: orgTreeLayout
}
} // Qan.Graph

Menu { // Context menu demonstration
id: contextMenu
MenuItem {
Expand Down
49 changes: 48 additions & 1 deletion samples/layouts/qanOrgTreeLayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
//-----------------------------------------------------------------------------

// Std headers
#include <memory>
#include <queue>
#include <unordered_set>

// Qt headers
#include <QQmlProperty>
Expand Down Expand Up @@ -65,8 +66,54 @@ void OrgTreeLayout::layout(qan::Node& root) noexcept
// 2. Layout the tree bottom up
// 3. Shift the tree to align root to it's original position.

const auto collectBFS = [](qan::Node* root) -> std::vector<std::vector<qan::Node*>> {
std::vector<std::vector<qan::Node*>> r;
if (root == nullptr)
return r;

// <-- hand tuned ChatGPT code
std::queue<std::pair<Node*, int>> nodeLevelqueue;
std::unordered_set<Node*> visited;

nodeLevelqueue.push({root, 0});
visited.insert(root);

while (!nodeLevelqueue.empty()) {
auto [current, level] = nodeLevelqueue.front();
nodeLevelqueue.pop();

if (r.size() <= level)
r.resize(level + 1); // Resize() initialize new items
r[level].push_back(current);
for (auto child : current->get_out_nodes()) { // Enqueue unvisited children with their level
if (visited.find(child) == visited.end()) {
nodeLevelqueue.push({child, level + 1});
visited.insert(child);
}
}
}
// <-- ChatGPT code
return r;
};

// 1. BFS
const auto levels = collectBFS(&root);

// Debug
int l = 0;
for (const auto& level: levels) {
std::cerr << l++ << ": ";
for (const auto node: level)
std::cerr << node->getLabel().toStdString() << "\t";
std::cerr << std::endl;
}
}

void OrgTreeLayout::layout(qan::Node* root) noexcept
{
qWarning() << "qan::OrgTreeLayout::layout(): root=" << root;
if (root != nullptr)
layout(*root);
}
//-----------------------------------------------------------------------------

Expand Down
5 changes: 4 additions & 1 deletion samples/layouts/qanOrgTreeLayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,10 @@ class OrgTreeLayout : public QObject
* running this algorithm on a non tree subgraph might lead to inifinite recursions or
* invalid layouts.
*/
Q_INVOKABLE virtual void layout(qan::Node& root) noexcept;
void layout(qan::Node& root) noexcept;

//! QML invokable version of layout().
Q_INVOKABLE void layout(qan::Node* root) noexcept;
//@}
//-------------------------------------------------------------------------
};
Expand Down

0 comments on commit 1593eb3

Please sign in to comment.