• • • 5.2
To make a button: To create a new button, enter edit mode, and drag from the button icon at the right end of the new object toolbar onto the diagram (or press Control+0).
OnClick attribute: The OnClick attribute holds an expression that gets evaluated when the button is pressed. You can view and edit the expression in the Attribute panel as above, or its Object window, like any user-editable attribute. The expression uses the same syntax as a Definition, but unlike a variable
Definition, it allows side-effects such as assignment to global variables or object attributes. Also unlike a variable
Definition, the result value is not stored or used. From the expression, you can call any of the functions that are available in Analytica. If variables are later renamed, the expression is automatically updated.
Note: In earlier releases of Analytica, the
Script attribute held the commands executed when the button is pressed. The
Script attribute can still be used (it is run after OnClick), and legacy models continue to work, but it has been superseded by the
OnClick attribute. Script uses a different syntax called typescript. With the introduction of
OnClick, there is no longer a need to learn another syntax since
OnClick uses the same expression syntax as
Assigning to global variables
Assigning a definition in OnClick or OnChange: A statement in a button or change event can assign to a nonlocal (global) variable, for example:
A := 100
This is not permitted in the definition of a variable, which only assigns to local variables declared within the definition of the variable, to prevent side effects — where evaluating one variable changes the value of another. See Assigning to a local value: v := e.
The right-hand side of the expression is evaluated before the assignment. Hence, an assignment of
A := B + 1
B, adds 1, and sets the
A to the result.
Assigning a value in a function
There is an important exception to the rule that you cannot assign to globals in a definition: You can assign to a global variable in a function that is called from a button event. It can be called directly or indirectly — that is, called from a function called from an
Script attribute, and so on recursively:
Variable A := 100
Variable B := 2
Definition: A := A + x
When you press button
Add_B_to_A, it calls function
IncrementA, which sets the definition of
A to the current value of
A + B, i.e.,
102. Like any assignment in a function, it assigns the value not the expression
A + B.
This kind of global assignment gives you the ability to create buttons and functions to make changes to a model, including such things as modifying existing model values and dependencies.
Save a computed value
One useful application of assigning to a global variable is to save the results of a long computation. Normally, the cached result of a computation is stored until you change any ancestor feeding into the computation, or until you Quit the session. By assigning the result to a global variable, you can save it so that it remains the same when you change an input, or even when you quit and later restart the model.
A common case where this is helpful is a model containing two parts: (1) A time-consuming statistical estimation, neural network, or optimization that learns a parameter set, and (2) a model that applies the learned parameters to classify new instances. After computing the parameters, you can save them into a set of global variables, and then save and close the model. When you restart the model, you can apply the learned parameters to many instances without having to waste time recomputing them.
Consider this example:
Variable Saved_A := 0
OnClick: Saved_A := A
When you click button
Save_A, it saves the value of
A into global
Saved_A retains this value if you change
A or any of its predecessors, or even if you quit the session, saving the model file, and later restart the model. Thus, you won’t have to wait to recompute
Saved_A. Of course, the value of
Saved_A does not update automatically if you change any of its predecessors, the way
A does. You need to click button
Save_A again to save a new value of
If the value of
A is an array with nonlocal indexes, the definition of
Saved_A is an edit table, using those indexes. Any subsequent change to those indexes affect, and possibly invalidate the table. If you want to make sure this doesn’t happen, you might want to save copies of the indexes, and transform the table to use the saved indexes.
Assign to an attribute
You can assign to any user-editable attribute of a (nonlocal) variable or other object, subject to the same restrictions as assigning a value — i.e., you can do it only in a function called from
OnChange, directly or indirectly. You cannot assign to an attribute in the definition of a variable. The syntax is:
<attrib> OF <object> := <text>
<attrib> is the name of an editable attribute, including Title, Units, Description, Definition, Check, Domain, and Author;
<object> is the identifier of a user-defined, nonlocal object, variable, function, module, etc.; and
<text> is a text value. For example:
Variable Gray := 0
OnClick: Title of Gray := 'Earl '& (Title of Gray)
When you click button
Change_title, it calls function
Retitle applying it to variable
Gray, prefixing the old title of
Earl to become
Earl Gray. It does this again each time you press the button.
If the text is an array, it flattens the array into a single text value before the assignment — probably not what you want. So, it is best only to assign atomic text values.
If you want to assign a new definition as text (rather than assigning the value of an expression), you can assign to the definition thus:
Definition OF X := 'Y^2
You can use this method to assign new values to various internal attributes, such as NodeLocation, NodeColor, NodeSize, and NodeFont, letting you change the way nodes appear on a diagram. Consult the Analytica Wiki for more details on attributes.
Invalidate a result
When a variable pulls data from an external source, or when a variable makes use of random numbers, invalidating a previously computed result for that variable forces the data to be refreshed the next time it is accessed. To invalidate the result of variable
in your OnClick expression.