Important: Please read the Qt Code of Conduct -

[Solved] How to QML Graph layout ?

  • Hello,

    Let's talk "graph visualization" :
    I've a list of "Nodes" (QQuikItem derived) that must be spread and organized within a squared area.
    An external graph layout engine computes the position of each node.
    The list of nodes with the computed positions are stored in a model using a QQmlListProperty<Node>

    Now, I'd like a way to position the nodes in a qml view using this model.
    I couldn't find a way, couldn't find the right view or the right way to use the right view...

    Please tell me I'm wrong!


  • Did you already consider "Canvas": + "Context2D": There are some (incompletely documented, unfortunately) examples "here":
    Your goal seems to be reachable using Canvas solution. Even though Canvas targets JavaScript "compatibility", nothing's enforced.

  • Thank you for the answer,
    My post wasn't clear enough: I also want interactions with objects of the graph: selection at least.

    So, if you encompass all nodes in a single canvas, I guess you can only interact with one object (the canvas/graph) and you cannot access and interact with each node. Or am i wrong?
    If you draw each node with a canvas, then each canvas is an item, and it brings us back to the initial issue, that i rewrite another way: how to dynamically create a list of prepositioned items passed to a view using those convenient qml models?

  • I see. In this case it might get cumbersome to customize QtQuick elements to your preference, and drawing each item in a separate canvas will hurt performance.

    Perhaps you should take a closer look at the "graph scene of QtQuick 5": There is a fine example "here":
    Any type of interaction can be theoretically implemented, as the underlying element you will use in this approach is "QQuickItem": with a couple of virtual MouseEvent functions.

  • For now, my concerns focuses more on dynamic creation than rendering or performance.

    What can be done :
    In a Qml List View, the delegate has a width and height set to zero (w and h are defined by the root item of the delegate component, no matter what the size of children is).
    => All elements of the list are superposed <=> share the same origin
    => The nodes themselves are children of the root items and can be given an individual position

    That way, you can use a model to dynamically create a list of nodes. And having a control on individual positions.

  • Short example

    import QtQuick 2.0

    Rectangle {
    width: 300
    height: 200
    color : "#ddf"

    ListView {
        anchors.fill: parent
        interactive: false
        model : ListModel { // nodes
            ListElement { nx:50; ny:100; }   // node position is (nx, ny)
            ListElement { nx:150; ny:50; }
            ListElement { nx:250; ny:100; }
            ListElement { nx:150; ny:150; }
        delegate : Item { 
            x:0; y:0; 
            width:0; height:0 // here is the "trick"
            Rectangle { x: nx; y:ny; width:10; height:10; radius: 5; border.color: "#113"
                MouseArea { anchors.fill: parent; parent; }



Log in to reply