Graphing (Formerly AgentWidgets) - theRAPTLab/gsgo GitHub Wiki
See !92 !110 !113 !290
For this first pass, we are moving two properties from direct agent manipulation to Features:
- text
- meters
In addition, basic line graphs are supported.
One of the challenges of setting visual properties like text and meters is that they are sensitive to when they are updated. In most cases, they need to be frequently updated. This generally works fine during a simulation run, but during the SETUP phase, the lack of these updates can be confusing (see #166, where we were running into labels display the wrong or outdated values because of the lack of updates).
To address this, the Graphing feature handles updating the visual UI every cycle during both the PRERUN/SETUP phase and during the RUN phase.
text
textProp
There are two ways of using text:
Graphing has a featProp text
that you can set directly.
You can set the text
value directly as you did previously, e.g.:
useFeature Graphing
featProp Graphing text setTo 'Fish'
As before, stack operations also work:
every 1 runAtStart [[
// Show 'name: energyLevel'
exprPush {{ agent.name + ': ' + agent.getProp('energyLevel').value }}
featPropPop Graphing text
]]
Note though, that in this case, the name would only update once a second.
As a convenience, you can bind text to an agent property:
# BLUEPRINT Moth
addFeature Graphing
addProp energyLevel number 0
featProp Graphing textProp setTo energyLevel
Now, whenever energyLevel changes, the text will automatically change, and there is no need to add an additional loop handler.
This partially implements styling for character text.
Due to the complexity of implementing selection menu options for wizards, it is not possible at this time to use a selection menu to select alignment and justification values. Instead, you'll have to use a bitwise flags to combine settings.
The Graphing feature now has three feature properties:
textAlign
textJustfication
textColor
To set text alignment:
addFeature Graphing
featProp character.Graphing.text setTo "Fish Under The Seam"
featProp character.Graphing.textAlign setTo 18
featProp character.Graphing.textJustification setTo 1
featProp character.Graphing.textColor setToColor 16768256
Notes
- We use bitwise flags to set alignment and justification values to minimize the data footprint when sending visual data across the network.
- The ability to select an alignment/justification value via
setToOption
will be added in the future once we add support for defining and using built-in gvars options for features.
Alignments are set via bitwise flags that you can combine to determine the position. e.g. to set TOP
use 1
; e.g. to use TOP + CENTER
add CENTER: 16
to TOP: 1
or 17
. Use the table below for convenience.
featProp character.Graphing.textAlign setTo 18
Labels are set to appear just outside of the sprite bounding box so they don't cover the sprite. The exception is the MIDDLE + CENTER value which will appear in the middle of the sprite.
The default alignment is BOTTOM + CENTER.
TOP: 1
MIDDLE: 2 // vertical
BOTTOM: 4
LEFT: 8
CENTER: 16 // horizontal
RIGHT: 32
alignment values | ||
---|---|---|
TOP LEFT: 9 | TOP CENTER: 17 | TOP RIGHT: 33 |
MIDDLE LEFT: 10 | MIDDLE CENTER: 18 | MIDDLE RIGHT: 34 |
BOTTOM LEFT: 12 | BOTTOM CENTER: 20 | BOTTOM RIGHT: 36 |
Justification only works for multiline text.
featProp character.Graphing.textJustification setTo 1
The default justification is CENTER.
LEFT: 1
CENTER: 2
RIGHT: 4
Use the setToColor
method to enable the color picker.
Previously we applied a slightly transparent alpha to the text to soften the text, but the color picker does not allow alphas.
featProp character.Graphing.textColor setToColor 16768256
v has a featProp meter
that you can set directly.
You can set the meter
value directly as you did previously, e.g.:
AddFeature AgentWidgets
featProp Graphing setTo 0.5
As before, stack operations also work:
every 1 runAtStart [[
// Show 'name: energyLevel'
exprPush {{ agent.getProp('energyLevel').value / 100 }}
featPropPop AgentWidgets meter
]]
Note though, that in this case, the meter would only update once a second.
As a convenience, you can bind meter to an agent property:
addFeature AgentWidgets
featProp Moth.AgentWidgets.meterProp setTo energyLevel
Now, whenever energyLevel changes, the meter will automatically change, and there is no need to add an additional loop handler.
Currently you still need to set meter colors via regular periodic script updates. In the future we can add support for defining different color values via the AgentWidgets Feature.
Meters default to outside-left
position. If you need to place them elsewhere, use setMeterPosition
. This will set a different x offset for the meter. The meter position is bottom aligned with the sprite and is not currently settable.
featCall AgentWidgets setMeterPosition '<position>'
where <position>
is one of:
'outside-left'
'inside-left'
'middle'
'inside-right'
'outside-right'
NOTE: the quote is necessary.
featCall AgentWidgets setMeterPosition 'middle'
Currently Line Graphs are implemented essentially as time-based graphs that plot a single value over time.
Like Meters, you can bind a graph to an agent property. The graphs will then automatically update as the property changes.
Graphs will automatically scale themselves to show ALL the values, changing the Y axis minimum and maximum values automatically. The Y axis labels are automatically inserted. If you need a fixed scale on your graph, use graphMinY
and graphMaxY
-- see next entry.
featProp <blueprint>.AgentWidgets graphProp setTo <property>
where <property>
is an agent property.
To use:
addFeature AgentWidgets
featProp Moth.AgentWidgets graphProp setTo energyLevel
You can also bind a graph to a global property. It works pretty much like graphPop
. See the "Global Feature" for more information on how to set up a Global Property.
featProp <blueprint>.Graphing graphGlobalProp <property>
where <property>
is a global property. NOTE that you do not need to prefix the popertyname with global
, e.g. use totalEnergy
, not global.totalEnergy
.
graphMinX
,graphMaxX
,graphMinY
,graphMaxY
, and graphFrequency
affect for both graphProp
and graphGlobalProp
.
# BLUEPRINT Global
addProp totalEnergy number 0
# BLUEPRINT AlgaeGraph
addFeature Graphing
featProp Graphing graphGlobalProp setTo 'totalEnergy'
Graphs normally rescale themselves based on the range of input values they receive. If you need the graph to use a fixed scale, e.g. from 0 to 1000, set these minimum and maximum values. If graphMinY or graphMaxY are not set, the system will automatically fit the graph values onto the graph, calculating the bounds dynamically.
NOTE that if a value exceeds the graphMaxY
value, the line will still be plotted even if it extends beyond the top of the graph. To "clip" the graph, set the min and max on the property being graphed. e.g. if graphProp
is set to eneryLevel
, do a prop energyLevel setMax 100
to make sure any attempt to set energyLevel
above 100 will be clipped to 100.
NOTE the graphMinX
and graphMaxX
values have not been fully tested and may result in some odd behavior. X axis labels have not been implemented.
featProp <blueprint>.Graphing graphProp setTo <property>
where <property>
is an agent property.
To use:
addFeature Graphing
addProp energyLevel number 50
featProp Graphing graphProp setTo 'energyLevel'
featProp Graphing graphMinY setTo 0
featProp Graphing graphMaxY setTo 100
This will generate a graph with a maximum of 100, and a point starting at 50.
graphFrequency
is how often you want the value to be plotted, in number of frame steps between updates. will default to 30, or once a second, if it is not included.
We recommend using a frequency of no less than 30
-- this will plot a point once a second, since the simulation runs at 30 frames a second. More frequent updates can impact performance.
graphFrequency
is used for both graphProp
and graphGlobalProp
.
featProp <blueprint>.AgentWidgets graphFrequency setTo <frequency>
where <frequency>
is the number of frames to skip between each graph plot. Max is 1.
Use this agent property set a large size for the Meter or the Line Graph.
featProp AgentWidgets isLargeGraphic setTo true
showMessage
will display a message in a popup modal dialog window with an "OK" button.
If you send multiple messages before the user has clicked OK, each subsequent message will appear on a separate line in the dialog window.
NOTE: No formatting is allowed in the message. If you want separate lines, send a second message.
featCall AgentWidgets showMessage '<string>'
where <string>
is your message.
featCall AgentWidgets showMessage 'Hello World'
Graphing