AnyLogic
Expand
Font size

Shape replication

AnyLogic supports shape replication — a very easy and convenient way to create a number of same shapes. When you need multiple identical shapes, you do not have to create each one manually. Just draw the shape once and specify how many copies to created.

You define the replication factor of the shape in the Replication edit box in the Advanced section of the properties of the shape. This value determines how many copies of the shape will be created when the model runs. You can:

  • enter a simple integer (for example, 5) to create a fixed number of copies, or
  • specify an expression that evaluates to an integer at runtime (for example, the value of a modifiable control or a parameter).

If you leave this field empty, only one shape will be created, and no replication will occur.

Consider the following example model. It shows how a railroad and a train can be animated using only one replicated rectangle and one replicated group of three lines.

Demo model: Shape Replication Open the model page in AnyLogic Cloud. There you can run the model or download it (by clicking Model source files). Demo model: Shape ReplicationOpen the model in your AnyLogic desktop installation.

In this model, check the properties of the rectangle shape:

  • In the Advanced section, the Replication property is set to 8, meaning that a total of 8 rectangle shapes will be created.
  • In the Appearance section, the Fill color is a dynamic property that is calculated using a ternary operator: index == 7 ? black : yellow.
    The shape with index = 7 will be colored black to represent the train engine, while the remaining shapes will be colored yellow to represent the train cars.
  • In the Position and size section, the X property is also dynamic. Its value is calculated using the following formula: 5*time() + index*75.
    The time() function is a built-in time function of AnyLogic that returns the amount of model time that has elapsed since the model was started (in model time units). Because the engine renders the value of this property continuously, it allows the rectangles to move along the X axis during runtime, effectively simulating a moving train.

Each replicated shape has access to a built-in variable called index, which reflects the zero-based position of the shape within the replicated set. In our example, it is used to set the fill color dynamically, distinguishing the last rectangle (the locomotive) from the rest of the train, and offset the position of each rectangle along the X axis so that the shapes do not overlap and appear in a sequence.

The index variable can be used in any dynamic property of the replicated shape, such as position, size, color, text, visibility, or even custom logic. It is evaluated separately for each replicated instance, allowing finer control over their appearance and behavior.

Replicated groups

In addition to individual shapes, you can also replicate entire groups of shapes. A replicated group creates multiple independent copies of the entire group and all of its contents. Each replicated group has access to the built-in index variable, just like individual replicated shapes. However, this variable can only be used in the own properties of the group, and not in the properties of shapes within the group.

In the same Shape Replication demo model above, a group consisting of three line shapes is replicated to simulate train tracks. The X property of the group is defined dynamically, using the expression: index * 10. At runtime, each copy of the group is shifted along the X axis by 10 units relative to the previous copy. Since all groups contain the same set of line shapes, this creates the visual effect of continuous rails extending along the track.

While replicated groups visually appear as multiple independent copies, the elements within the group, such as shapes or controls, are not actually duplicated. Instead, they are shared among all group instances.
As a result, modifying an inner element (for example, changing its color or text) from within the code or control logic will affect that element across all replicated groups. This allows for more memory-efficient rendering of replicated visuals, but can lead to unexpected behavior if you assume that each group instance has unique inner elements.

Replicated controls

In addition to presentation shapes, you can replicate controls and charts. This is useful when you need to create an array of similar UI elements: for example, to control multiple elements at runtime. Replicating controls can save you time and make your model more scalable.

Consider the following model:

Demo model: Replicated Button Open the model page in AnyLogic Cloud. There you can run the model or download it (by clicking Model source files). Demo model: Replicated ButtonOpen the model in your AnyLogic desktop installation.

Each replicated shape is represented in code as an object of the ReplicatedShape class. You can access it as a member of an agent. You can access individual elements using the get(index) function, and call functions defined in the corresponding shape class (see the AnyLogic class reference for more information).

In the demo model, there is a replicated button that is used to change the fill color of a replicated shape. In this model, the number of buttons and shapes is dynamically controlled by a slider:

roundRectangle.get(index).setFillColor(blueViolet);

Since both the button and the shape use the same index, the logic between them remains synchronized.

Iterating through replicated shapes

Assume you have a replicated Rectangle element in your model, called replicatedRectangle, and you want to highlight every second shape in a different color. Try adding the following code to your model: for example, in the action of a Button:

for (int i = 0; i < replicatedRectangle.size(); i++) {
if (i % 2 == 0)
  replicatedRectangle.get(i).setFillColor(blue);
else
  replicatedRectangle.get(i).setFillColor(grey);
}

This will highlight the even-numbered rectangles in grey and the odd-numbered ones in blue.

Alternatively, you can use a for-each loop:

int i = 0;
for (ShapeRectangle r : replicatedRectangle) {
  r.setFillColor(i % 2 == 0 ? blue : grey);
  i++;
}

This approach makes it easy to apply patterns or visualize data dynamically using replicated shapes: for example, for simple timelines, resource indicators, or status blocks.

How can we improve this article?