To prevent spam users, you can only post on this forum after registration, which is by invitation. If you want to post on the forum, please send me a mail (h DOT m DOT w DOT verbeek AT tue DOT nl) and I'll send you an invitation in return for an account.

Update petrinet visualization with ProMJGraph Visualizer

Hey all,

I am currently developing a plugin to integrate the Performance Spectrum Visualization (Vadim Denisov) with alignments and petrinets.
The plugin is an interactive visualizer containing a PromJGraphPanel for the petrinet.
I chose this because it allows the selection of places and transitions which is very important for my functionality.
From all the (layout cache) update listening and GraphChangeEvents, I assumed that this visualizer can also handle changing the underlying petrinet.

I at least know how to change the ViewAttributeMap to color the places but I also need remove (or hide) and re-add elements. This is where my problem is.
When I simply change the petrinet and completely re-visualize it (so re-create the panel which is not elegant..), all new (also re-added) elements bunch up in the upper left corner, even when I copy the full AttributeMaps.
I guess this is because of the underlying graph layout connection.

Is there a better way to do this?

Another related thing is how to "catch" keystrokes and right clicks on the panel.
I tried adding a KeyListener to the graph panel but it seemed that no event came through. The same for a MouseListener for right clicks. Even a FocusListener never got any events, even though I interacted with the petrinet on the panel.
I would like to add a right click menu on places and transitions and also to add keyboard shortcuts for easier use.

Can I somehow do this with the existing plugins/functionality?

Thank you in advance.

Regards,
Daniel

Answers

  • hverbeekhverbeek Posts: 427
    Hi Daniel,

    The visualizer uses JGraph in the back, which (in principle) allows for editing. However, the visualizer was never build with editing capabilities in mind, and may in fact even make it hard for you to use it as an editor.

    Next to that, ProM does not handle updates to Petri nets in the workspace too well. Basically, if you have somethign in the workspace, your should not update it. When starting an editor on a Petri net, first deep-clone the Petri net, allow the user to edit the deep-clone, and if you want to push it back into the workspace, push a deep-clone of the deep-clone into the workspace. This prevents the user from updating a Petri net in the workspace.

    Yes, I guess the GraphLayoutConnection plays a role here. If a Petri net is visualized for the first time, it is checked whether such a connection already exists. If not, such a connection is created, which includes a JGraph layout for the Petri net. If you want ProM to redo the layout, use "layoutConnection.setLayedOut(false);" first (where layoutConnection is the proper instance of the GraphLayoutConnection).

    Also, when adding/removing nodes and such to/from the graph, make sure the grapElementAdded/graphElementRemoved methods are called.

    Perhaps the following code snippet helps for the listeners (copied from the Fuzzy Miner):
    		jgraph = graphPanel.getGraph();
    jgraph.setEditable(false);
    System.out.println("[FuzzyModelPanel] Set editable to false");
    jgraph.addMouseListener(new MouseListener() {
    public void mouseClicked(MouseEvent e) {
    if (e.getClickCount() >= 2) { //double-click the node
    synchronized (jgraph.getProMGraph()) {
    // Check for selection.
    // If the cell that is being clicked is part of the selection,
    // we use the current selection.
    // otherwise, we use a new selection
    Object cell = jgraph.getFirstCellForLocation(e.getX(), e.getY());
    Collection<DirectedGraphElement> sel;
    if (cell == null) {
    // Nothing selected
    jgraph.clearSelection();
    sel = new ArrayList<DirectedGraphElement>(0);
    } else if (jgraph.getSelectionModel().isCellSelected(cell)) {
    // the current selection contains cell
    // use that selection
    sel = graphPanel.getSelectedElements();
    showDetailGraphOfNode(cell);
    } else {
    // the current selection does not contain cell.
    // reset the selection to [cell]
    sel = new ArrayList<DirectedGraphElement>(1);
    sel.add(graphPanel.getElementForLocation(e.getX(), e.getY()));
    jgraph.setSelectionCell(cell);
    }
    }
    }
    }

    public void mouseEntered(MouseEvent e) {

    }

    public void mouseReleased(MouseEvent e) {

    }

    public void mousePressed(MouseEvent e) {

    }

    public void mouseExited(MouseEvent e) {

    }
    });


    In this snippet, jgraph is an instance of ProMJGraph, and graphPanel is an instance of ProMJGraphPanel. The typical way to create graphPanel would be:
    			graphPanel = ProMJGraphVisualizer.instance().visualizeGraph(context, graph);

    where graph is to graph (Petri net) to visualize.

    I hope this helps you a bit, but you're in deep water here. As said, Prom was never build to be used as an editor.

    Kind regards,
    Eric.



  • dantudantu Posts: 4
    Hello Eric,

    thank you very much for your in depth reply.

    I already use a cloned petrinet and the created transition/place maps to keep object identity when working with the alignment.

    It's disappointing to hear that the visualizer was not really made with editing capabilities in mind but maybe I can work around it a bit by manually resetting the layout connection as you suggested.

    However, I can't really find those grapElementAdded/Removed methods on the ProMJGraph.
    The only thing I found is graphChanged(GraphModelEvent e) where the GraphModelEvent seems very low level. Even an implementation like GraphModelEdit seems difficult to use with just knowledge of the petrinet.

    Ok, so I have to add the listeners to the graph itself and not the panel..

    Another thing I found is "ExpandableSubnet" when looking through the methods of a petrinet (addGroup()). Could this possibly be used to make a selection into a group and thus collapsible in the view?
    I just need the visual "effect" of hiding subnets of the net to make it less complex.
    It would even be enough if I could set some Attribute in the ViewSpecificAttributeMap to make them invisible but I have not found such a thing.

    Best regards,
    Daniel



  • hverbeekhverbeek Posts: 427
    Hello Daniel,

    The graphElementAdded/graphElementRemoved operate on the Petri net, not on the ProMJGraph. If you add/remove a node to/from a Petri net using addPlace etc., these methods will already be called.

    You can create kind of hierarchy using ExpandableSubnets, and show/hide the contents of such a subnet. When hidden, the subnets shows as an empty node. When shown, the contents are shown inside of this node. You can use it to group, but I would only do so for nodes that should be positioned close to another in the first place. If that's the case, then this just may work.

    As an alternative, you can make nodes very small, but the arcs would still be shown, and the layout would still be affected.

    Cheers,
    Eric.
  • dantudantu Posts: 4
    Hello Eric,

    I basically only want to simplify/hide block structures, so that sounds promising.
    I'll look into it, thanks!

    Best regards,
    Daniel

  • dantudantu Posts: 4
    Unknown column 'DateAccepted' in 'field list'
    The error occurred on or near: /var/www/win/promforum/library/database/class.database.php

    418: $this->closeConnection();

    419: continue;

    420: }

    421:

    422: trigger_error($message, E_USER_ERROR);

    423: }

    424:

    425: }

    426:

    Backtrace:

    /var/www/win/promforum/library/database/class.database.phpPHP::Gdn_ErrorHandler();

    [/var/www/win/promforum/library/database/class.database.php:422] PHP::trigger_error();

    [/var/www/win/promforum/library/database/class.sqldriver.php:1663] Gdn_Database->query();

    [/var/www/win/promforum/library/database/class.sqldriver.php:1618] Gdn_SQLDriver->query();

    [/var/www/win/promforum/plugins/QnA/class.qna.plugin.php:557] Gdn_SQLDriver->put();

    [/var/www/win/promforum/plugins/QnA/class.qna.plugin.php:557] QnAPlugin->DiscussionController_QnA_Create();

    [/var/www/win/promforum/library/core/class.dispatcher.php:316] PHP::call_user_func_array();

    [/var/www/win/promforum/index.php:40] Gdn_Dispatcher->dispatch();

    Variables in local scope:

    [Sql] 'update GDN_Comment `Comment`
    set QnA = :QnA,
    DateAccepted = :DateAccepted,
    AcceptedUserID = :AcceptedUserID
    where CommentID = :CommentID'

    [InputParameters] array (
    ':QnA' => 'Accepted',
    ':DateAccepted' => '2019-06-07 09:21:47',
    ':AcceptedUserID' => '3945',
    ':CommentID' => '3263',
    )

    [Options] array (
    'Type' => 'update',
    'Slave' => NULL,
    'ReturnType' => NULL,
    )

    [ReturnType] NULL

    [tries] 2

    [try] 0

    [PDO] array (
    )

    [PDOStatement] false

    [ex] array (
    )

    [message] 'Unknown column \'DateAccepted\' in \'field list\''

    [code] 1054

    [state] '42S22'
    By the way, I just got this error when clicking "yes" for "Did this answer the question?"



Sign In or Register to comment.