OnGraphClick

New to Analytica 6.0

OnGraphClick

The OnGraphClick attribute holds an expression that is evaluated when an end-user clicks the mouse on the variable's result graph. Information about where the click occurred is passed to your expression through several local variables that are set before the expression is evaluated. Before you can enter an OnGraphClick expression, you'll need to make the attribute visible in the Attributes dialog.

Return value: Your expression needs to return true if you want the normal processing of the mouse click to continue. It should return false if you want to suspend the normal processing. If you suspend processing of the click, then data point balloons won't show, key items won't toggle, and zooming by dragging a rubber band rectangle won't work (unless you hold the shift key while dragging).

You should keep in mind that User-defined functions can be used in the attribute. Hence, if you implement your logic in a UDF, you can very easily reuse it across multiple graphs. You can even put it in a library to share across different models. More advanced Analytica programmers may write the code that implements complex on-click behaviors, and provide these in the form of UDFs in libraries for other Analytica modelers, who only have to worry about placing the appropriate call to the UDF in the OnGraphClick attribute (similar to the way functions are used in the OnGraphDraw attribute).

Some plausible uses of OnGraphClick

  • Set input variables in your model based on what a user clicks on. This can be a way to visually select a given case to focus on.
  • Add a data point to a collection of data points based on where a user clicks.
  • Customize the text in the data point hover balloons.
  • Suppress one (or both) of the two hover balloons when a user clicks on a line segment, filled area, data point, or bar.
  • Add interactivity to a customized "graph" type implemented in Analytica and drawn in OnGraphDraw. Based on where a user clicks, it would change variables within your model that determine the appearance of the graph.

Special local variables

Several local variables are set so that your expression can figure out what was clicked on. The set of locals that are meaningful depends on which part of the graph the user clicked.

  • where: Indicates which part of the graph was clicked on. Possible values are: "plotArea", "point" (on a single point or bar in the plot area), "segment" (on a line segment or filled area), "key", "axisTitle", "axisLabels" and "background".
  • click_x and click_y: The pixel coordinates of the mouse click relative to the top-left corner.
  • dim: An index used when specifying a data coordinate. The elements are handles of the indexes that are present in the graph (a subset of all the indexes, depending on what's clicked on).
  • endPt: An index used when specifying the coordinates of both ends of a data segment. It has the index values [1,2].
  • coord: The coordinate (by IndexValues) of the data point that was clicked on, or null in the click was not on a datum on segment. When a single data point is clicked on, this is a one-dimensional array indexed by dim. The cell corresponding to the index in dim contains the value of the index. When a line segment is clicked on, this is a 2-dimensional array, the .endPt dimension has values [1,2] give the coordinates of each end point. When dat is not clicked on, it is null.
  • coordPos: Same as coord except that the array cells contain the 1-based index positions instead of index labels.
  • balloonText: Contains the text that will be displayed in a datum balloon (when the click is on a data point). You can modify this to change the text that appears in the balloon.
  • isInRole: This is a 1-D boolean array indexed by GraphingRole that indicates whether the click was within the scope of the given role. For example, if you click on the x-axis, or within the plot area, then you are within the scope of the 'X axis' role. If you click on a symbol/color key, then you are within the scope of the 'Color' role.
  • info: This is the same as for OnGraphDraw, a 1-D array indexed by OnGraphDrawItem. All of the values in the local variables above are also available in info, which can be more convenient when encapsulating re-usable click logic in a UDF.
  • roles: This is the same as for OnGraphDraw, a 2-D array indexed by GraphingRole and GraphFillerInfo, although it also contains the value of the role filler where you clicked in the slice [ GraphFillerInfo='ClickCoord' ].
  • invalidateGraph: In some cases, OnGraphClick makes changes to other variables or parts of the model, but Analytica can't detect that these changes impact the graph image. This usually involves annotations from OnGraphDraw and changes that leave the computed values correct. When you know the graph image needs to be redrawn, you can set this to true to force the image to be redrawn to reflect any state changes your OnGraphClick made.

The information in coord and coordPos is redundant, but both are included since it is sometimes more convenient to use one or the other. If an index might have duplicates (which should be avoided in general), then only coordPos uniquely identifies the coordinate.

Clicking on a data point or bar

You can test for the case where the user clicks on a single datum (data point or bar) using

If where="point" Then.

The locals coord and coordPos are 1-D arrays, indexed by dim, and provide the index coordinates of the data point. The element values in dim are handles to the indexes. The local coord holds the IndexValue, as seen in this example:

OnGraphClickCoord.png

The local coordPos has the same structure but contains the 1-based position along each index. The following example tests whether the clicked data point determines the value of an index named Technology, and if so, it sets a variable in the model named Selected_tech to the index value:

If where="point" And @[dim=Handle(Technology)] Then
Selected_tech := coord[dim=Handle(Technology)]

Depending on how a graph is pivoted, the Technology index value might not be determined by the data point. An example would be when Technology is a slicer set to Total.

The x- and y-axes of a graph can depict either an index or a value. In the simplest and most common graphs, the x-axis is and index and the y-axis is a value (the main result value). In this case, the data point would determine the value of the x-axis index, but the value for the y-axis would not be present in the coord or coordPos arrays, since it isn't an index. In an XY plot, both axes are usually value dimensions, so the axes values would not be in coord, just the common index position would be there. When an axis depicts a value, rather than an index, you can access the data point's value along that axis using:

roles[ GraphingRole='Y axis', GraphFillerInfo='ClickCoord' ]

See also Clicking in the plot area below.

The local balloonText contains the text that will be displayed in the data balloon and in this case will be scalar text, and you can change the text (but it must remain scalar text). If you set balloonText to Null or "", then the balloon won't appear.

Clicking on a segment or filled area

You can test for the case where the user clicks on a line segment (between points) or in a filled area in a filled area line chart, using

If where="segment" Then …

The locals coord and coordPos are 2-dimensional, indexed by endPt and dim, where index endPt := [1,2]. So coord[.endPt=1] contains the coordinates of the end point of the segment closest to the mouse click, and coord[.endPt=2] contains the coordinates of the segment end point furthest from the click. The two endpoint coordinates will differ only on the common index. The local balloonText is a 1-D array indexed by the same endPt index and contains two text values. You can modify either or both, or set one to null if you want only a single balloon to display. For example, this shows only one data point balloon (the closest one) when you click on a line segment instead of the dual balloons:

If where="segment" Then
balloonText := If endPt=1 Then balloonText Else Null

Clicking in the plot area

The plot area is the rectangle bounded by and contained within the horizontal and vertical axes.

You can test for this case (but where the click isn't on a data point, line segment, bar of filled area) using

If where="plotArea" Then ….

In this case, the locals coord and coordPos are both 1-D arrays indexed by dim, but have only the slicer coordinates, if any. Slicers set to Total are not included. When there are no slicer indexes, they have zero-length.

The x & y coordinates of the click (in the units shown on the axis) are available using

Local x:=roles[ GraphingRole='X axis', GraphFillerInfo='ClickCoord' ];
Local y:=roles[ GraphingRole='Y axis', GraphFillerInfo='ClickCoord' ];

These coordinates are also available in this fashion when you click on a data point or line segment inside the plot area. But they are only available when the click is inside the plot area.

Clicking in a key

This case occurs if you click in the bounding rectangle of a key. A graph can have multiple keys at one time (e.g., a color key, symbol key and symbol size key). A single key may also combine multiple roles when the same dimension is mapped to multiple graphing roles.

You can test for this case using If where="key" Then ….

The isInRole local is a 1-D array indexed by GraphingRole containing True (i.e., 1) when the key that was clicked on depicts the given role. So, for example, you can test whether the user clicked in the Color key using:

If isInRole[ GraphingRole='Color'] Then

or you can get a list of the key types, such as ["Color","Symbol"], using Subset(isInRole). Information about the graphing dimension that is depicted in the key is available by looking in the roles array for any one the depicted roles (all entries in roles that are depicted in this key will have the same information).

The following obtains the key item that was clicked on, if any (a user can click in the key rectangle without clicking on a key item):

Local keyRole := roles[ GraphingRole = SubIndex(isInRole, GraphingRole, True) ];
Local keyItem := keyRole[ GraphFillerInfo = 'ClickCoord' ];

When an index is assigned to the key, dim will have a single item, a handle to that index. If in addition, the user clicks on a key item, the label for that item appears in coord and the position of that item in the index appears in coordPos. If the click was not on a key item, or if the key depicts a value instead of an index, then the single item in <coord>coord is null and the single item in coordPos is 0. So this gives a second way to obtain the key item that is clicked on in the case where the key depicts an index.

If you return false, the key visibility will not toggle.

Clicking on an axis title

You can test for a click on the x-axis title using:

If where="axisTitle" And isInRole[ GraphingRole='X axis' ] Then

You can test whether the click was on the y-axis title using:

If where="axisTitle" and isInRole[ GraphingRole='Y axis' ] Then

The locals dim, coord and coordPos are null.

Clicking in the axis label area

You can detect a click on an X-axis label, and obtain the label value clicked on, using:

If where="axisLabel" And isInRole[ GraphingRole='X axis' ] Then (
Local label := roles[ GraphingRole='X axis', GraphFillerInfo='ClickCoord' ];
)

The locals dim, coord and coordPos are null.

Clicking on the background

The background is any area outside of the plot area rectangle, outside of any key, and outside of the axis title or label areas.

You can test for this case using If where="background" Then ….

The locals dim, coord and coordPos are null.

Changing data balloon text

When you click on a data point or bar, a balloon pops up describing the coordinates of the point. When you click on a line segment of filled area, two balloons are shown, describing the two bounding data points. Your OnGraphClick code runs before the balloon is shown to the user, and your code can alter the text that appears. If you set the text to Null or "", the balloon will not show. Also, if your OnGraphClick returns False or zero, the balloon(s) will not show.

When you click on a single data point, the local balloonText contains a text string. You can assign a new text string to the variable to change the text that appears.

When you click on a line segment or filled area, the local balloonText is an array indexed by endPt which contains two text values. The first one, balloonText[.endPt=1], contains the text for the data point closest to the mouse click. If you didn't like both balloons appearing, you could suppress the second one as follows:

If where="segment" Then
balloonText := If endPt=2 then Null else balloonText

Side-effects

Your expression will generally be useful due to side-effects, such as:

  • Setting a user input, thus allowing the user to select a value by clicking on the graph
  • Writing something to a file (again, what is written can be selected by what is clicked)
  • Providing additional information in a message box.
  • Adding a point to an array with the coordinates where a user clicks.


Some other possibilities that are not currently possible (or at least not easily), listed here as enhancement ideas:

  • Changing the graph pivot, thus "zooming" into a particular dimension.

See Also

Comments


You are not allowed to post comments.