This week, guest author Justin Rawlings continues his series on improving AnyLogic animation. First, he will show us how to use Java animation layers and always keep visible what the user wants to see. Then, he applies this to the cool AnyLogic connections tool for visualizing agent links better. Next week, he will tie it all together, stay tuned :-)

Dynamically 'Bring To Front' presentation shapes

Why Do i care?

Consider that you want to edit the Person agent such that each time it is clicked, it shows a line chart of Number of Friends over time. Easy enough to do, however when testing it during an active model run the following appears:

The presentations for other Person agents are overlapping this one, how annoying!

The presentations for other Person agents are overlapping this one, how annoying!

How do i fix it?

What we really need is to "Bring To Front" a Person presentation whenever it is clicked. We can do so with the following function:

public void bringToFront(){
 // Get the shape that displays this agent
ShapeEmbeddedObjectPresentation shape = getOwnerShape();
// And the group it belongs to
ShapeGroup group = shape.getGroup();
// Remove it
group.remove( shape );
// Add back in (at the top of the Z-order stack)
group.add( shape );
}

Since AnyLogic stores all different Shapes of a presentation in a single group, their vertical layer order is dictated by their position in that group. The above function simply makes sure that any agent you bringToFront() is drawn on top of everything else.

Running again using bringToFront() when a Person is clicked:

Nice. No explicit reference to 'Main' necessary - this function will find the agents presentation no matter where it is and place it on the top of that group.

Nice. No explicit reference to 'Main' necessary - this function will find the agents presentation no matter where it is and place it on the top of that group.

Dynamically adjust LinkToAgent rendering

Agent links are one of the biggest hidden gems in AnyLogic. I could (and probably will) write an entire article dedicated to all of the great features of this simple object.

Why do I care?

Consider that you want to display the links between each Person and its friends. We have a linktoAgentCollection called toFriends defined so simply clicking the 'Draw Line connecting agents' checkbox will tell AnyLogic to drawn these links for us - great!

Let's try it out...

Not so great.

The ability to draw LinkToAgent is very useful - it saves you having to manage your own collection of ShapeLine and is one of the easiest ways to add some visual diagnostics to your model. However we need a bit more control in order to make it a useful tool for a large simulation.

How do I fix it?

The problem here is that showing the active links of every single Person at results in a jumbled mess on the canvas. We really only want to render these link when a Person is clicked.
Fortunately, each LinkToAgent and LinkToAgentCollection provide a method getLinkToAgentMyAnimationSettings. Using this method gives us some handy functions for controlling how the link in question is rendered:

  • setLineWidth(double width)
  • setLineStyle(LineStyle style)
  • setLineColor(Color color)
  • setVisible(boolean visible)

For most agents and link types in large models I suggest not rendering the links by default, simply turning them on and off when an agent is clicked.

In our example this means unchecking the 'draw connections' box, and adding the following line to to 'onHighlight' logic:

toFriends.getLinkToAgentMyAnimationSettings().setVisible(true)

emembering to stop rendering when the the agent has been 'unhighlighted'

toFriends.getLinkToAgentMyAnimationSettings().setVisible(false)
Much better.

Much better.

Consider using LinkToAgent next time you need to render a line between agents, and play around with getLinkToAgentMyAnimationSettings() to adjust the style as desired. Styling agent links to reflect the internal state of an Agent is a great way of providing information on the top level without the use of text.

Comment

English
German