Please ensure Javascript is enabled for purposes of website accessibility
Powered by Zoomin Software. For more details please contactZoomin

Edge HMI

Display text- and image-based trend annotations in a trend control

Display text- and image-based trend annotations in a trend control

  • Last UpdatedOct 29, 2026
  • 10 minute read

Use trend annotations to display additional text and images in a trend control during project run time. The annotations' content and settings are stored in the same database that stores the historical data.

Note: This feature is not supported in projects that are configured to run on the Embedded target platform. For more information, see About target platforms, product types, and target systems.

When you configure the data source for a Trend Control object, you can connect to an external database that stores the historical data that you want to display. The historical data might be generated by a Trend worksheet in the same project, or they might be provided by some other source, but in either case, they are typically stored in a single database table with one field (column) for each trend point.

A database can have many tables, however, so you can create another table to store your trend annotations. The table can be named anything (for example, TrendNotes), but it must have the following fields (columns):

Field

Description

Type

The type of annotation:

  • 0 = Image

  • 1 = Text

AnnotationID

The annotation ID for the specific trend point with which the annotation should be associated. Multiple annotations can be associated with the same point.

Associating an annotation with a point ensures that the annotation will be displayed correctly in the trend control. If the trend control is configured to display multiple sections, the annotations associated with each point will be displayed in that point's section. Also, if a point is hidden or removed from the trend control during run time, its associated annotations will also be hidden or removed.

The annotation ID for a point can be configured in that point's options. For more information, see Options. If no annotation ID has been configured for a point, you can associate annotations with the point's tag/field instead.

AnnotationContent

The content of the annotation:

  • If the value in the Type field is 0, the value in this field should be the name of the image file (for example, image.jpg). The file should be located Web sub-folder of your project folder (for example, <project name>/Web/image.jpg), on the computer that hosts your project runtime server.

  • If the value in the Type field is 1, the value in this field should be a plain text comment.

X1

The left border of the annotation box, specified in the same units as the trend control's X axis. If the X axis is set to Date/Time, the value in this field should be an appropriate time stamp (for example, 10/10/2009 10:00:00). For more information, see Axes dialog.

X2

The right border of the annotation box, specified in the same units as the trend control's X axis. If the X axis is set to Date/Time, the value in this field should be an appropriate time stamp (for example, 10/10/2009 10:00:00). For more information, see Axes dialog.

Y1

The top border of the annotation box, specified in the same units as the trend control's Y axis. For more information, see Axes dialog.

Y2

The bottom border of the annotation box, specified in the same units as the trend control's Y axis. For more information, see Axes dialog.

Z

The Z-index of the annotation box, which determines whether it is drawn in front of or behind other annotation boxes. The greater the Z-index, the more "forward" the annotation box will be.

Note: If the value of Z is negative, the annotation box will be drawn behind the trend control.

ImageFitMode

How the image should fit in the annotation box:

  • 0 = Use the specified image as a fill pattern.

  • 1 = Scale the specified image to fit the annotation box.

  • 2 = Resize the annotation box to fit the specified image. The bottom-left corner defined by X1 and Y2 remains fixed, while the top and right borders defined by X2 and Y1 are moved as needed.

    The value in this field is significant only if the value in the Type field is 0.

TextBaseWidth

The width of the text label (in pixels). If this value is not the same as the width of the annotation box (which is X2 minus X1), the text label will be scaled horizontally to fit.

The value in this field is significant only if the value in the Type field is 1.

TextBaseHeight

The height of the text label (in pixels). If this value is not the same as the height of the annotation box (which is Y1 minus Y2), the text label will be scaled vertically to fit.

The value in this field is significant only if the value in the Type field is 1.

Font

The font settings, in the following format:

size:color:alignment

size is the font size in points. The default font size is the same as the size specified for the Y-axis labels.

color is the font color, specified as an RGB code (for example, 0,128,128). For more information about RGB codes, see Color Interface. The default font color is the same as the color specified for the Y-axis labels.

alignment is the alignment of the text within the text label:

  • 0 = Top-left (default)

  • 1 = Top-center

  • 2 = Top-right

  • 3 = Middle-left

  • 4 = Middle-center

  • 5 = Middle-right

  • 6 = Bottom-left

  • 7 = Bottom-center

  • 8 = Bottom-right

    Note: The font style cannot be specified separately. It will be the same as the style specified for the Y-axis labels.

The value in this field is significant only if the value in the Type field is 1.

With the table's fields (columns) configured like this, each record (row) in the table can store the content and settings for an single annotation. Then, in the trend control's Data Source settings, in the Ann. Source box, type the name of this table (for example, TrendNotes). For more information, see Data Sources.

With everything properly configured, the project runtime server will get the data stored in this table and use them to display your annotations in the trend control during project run time. For example, given a record (row) with the following values:

Field (Column)

Value

Type

1

AnnotationID

SimulSin

AnnotationContent

This is an example of a text annotation.

X1

01/29/2015 10:23:36

X2

01/29/2015 10:24:45

Y1

81

Y2

62

Z

1

ImageFitMode

0

TextBaseWidth

381

TextBaseHeight

87

Font

11:0,0,0:4

…the annotation will be displayed in the trend control like this:l

Example of text-based trend animation

Please note that the red lines and captions in the example above are included only to highlight the borders (X1, X2, Y1, Y2) of the annotation box. They would not actually be displayed like this during project run time.

Add and edit annotations during project run time

Note: The following tips and code examples are for demonstration purposes only, and they are taken from the sample project named "Trend Annotation ID" that is available for download from our website (www.indusoft.com). If you want to add these features to your project, we recommend that you download and explore the sample project first, so that you can understand how all of the different parts of the project work together. Keep in mind that you will probably need to modify the code in order to have it work properly in your own project. In particular, make sure the database connection string specifies the correct provider, source, and credentials for your external database — the sample project uses a Microsoft Access database file (dbDemo.mdb) that is located in the project folder.

Your project's connection to an external database allows both reading and writing, so in addition to getting annotations from the database and then displaying them in the trend control, you can also add, edit, and even delete annotations during project run time.

In order to do so, however, you must make sure that the annotations table actually exists in the database. If you try to get annotations from a table that does not exist, it will not cause serious problems — the annotations simply will not be displayed. But if you try to add annotations to a table that does not exist, that information might be permanently lost.

You can use VBScript in your project to verify that the annotations table exists or create it if it does not. First, in the Procedures folder in the Project Explorer, define the following three procedures:

Function VerifyTableExists()

Dim Conn, TablesSchema, foundTable

On Error Resume Next

foundTable = 0

Set Conn = CreateObject ("ADODB.Connection")

' Open the connection to the database

Conn.Open $ConnectionString

' Open the database schema to query the list of tables. Extract the list in a Recordset object

Set TablesSchema = Conn.OpenSchema (20)

' Loop through the list and print the table names

Do While Not TablesSchema.EOF

If UCase(TablesSchema ("TABLE_Type")) = "TABLE" Then

If UCase(TablesSchema ("TABLE_NAME")) = "TRENDNOTES" Then

foundTable = 1

Exit Do

End If

End If

TablesSchema.MoveNext

Loop

'Create TrendNotes Table

If foundTable = 0 Then Call CreateTrendNotesTable()

' Close and destroy the recordset and connection objects

TablesSchema.Close

Conn.Close

Set TablesSchema = Nothing

Set Conn = Nothing

End Function

Function CreateTrendNotesTable()

Dim sql

On Error Resume Next

sql = "CREATE TABLE TrendNotes "_

& " ( ID Integer Not Null CONSTRAINT RestrictCamp PRIMARY KEY, "_

& " Type Integer Not Null, "_

& " AnnotationID Text(50) Not Null, "_

& " AnnotationContent Text(50) Not Null, "_

& " X1 datetime Not Null, "_

& " Y1 Integer Not Null, "_

& " X2 datetime Not Null, "_

& " Y2 Integer Not Null, "_

& " Z Integer Not Null, "_

& " ImageFitMode Integer, "_

& " TextBaseWidth Integer, "_

& " TextBaseHeight Integer, "_

& " Font Integer Not Null "_

& " ); "

$DBExecute("DB", sql)

End Function

Function AddComment(X,Y,FontSize,Comment)

Dim X1, X2, Y1, Y2, sql, numCur,numRows, uDate, uTime, uSec

On Error Resume Next

'The comment is written based on the upper left coordinate (X1, Y2).

Y1 = -1000000

Y2 = Y

X1 = X

X2 = DateAdd("d", 1, X1)

'Gets the next ID

sql = "SELECT * FROM TrendNotes"

numCur = $DBCursorOpenSQL("DB", sql)

numRows = $DBCursorRowCount(numCur)

If numRows<1 Then

numRows = 1

Else

numRows = numRows+1

End If

$DBCursorClose(numCur)

'Saves to DB and insert comment

$DBExecute("DB", "Insert into TrendNotes (ID,AnnotationID,X1,Y1,X2,Y2,Z,Type,AnnotationContent,ImageFitMode,[Font],TextBaseHeight,TextBaseWidth) Values (" & numRows & ",'Pens','" & X1 & "'," & Y1 & ", '" & X2 & "'," & Y2 & ",1,1,'" & Comment & "',0,'" & FontSize & "',0,0)")

End Function

For more information, see VBScript Global Procedures.

The first procedure opens a connection to the database and then searches it for the annotations table (for example, TrendNotes). If it does not find the table, it calls the second procedure, which subsequently creates a new table with the necessary fields (columns). The third procedure adds a new record (row) to the annotations table, according to the user's input (that is, cursor position, font size, comment text); it is called by the Add Comment screen, which is described later in this section.

Once you have defined these procedures, update your project's Startup Script to call the first procedure when the project is run:

$ConnectionString="Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & $GetAppPath() & "dbDemo.mdb"

Call VerifyTableExists()

For more information, see VBScript Startup Script.

Now you can create the project screens that will actually be used to add and edit annotations during project run time. (Please note that this example only shows how to handle text-based annotations. Image-based annotations could be handled in a similar manner, but they would require additional steps describing how to save and load image files, and those are beyond the scope of this example.) First, in the main screen that displays the trend control, insert buttons for Add Comment and Edit Comments.

Insert buttons for Add Comment and Edit Comment

Configure the Add Comment button to get the current position of of the cursor in the trend control and then open a pop-up screen that can be used to add a comment at that position. To do this, add the following VBScript to the button's On Up event:

$demoTrend.NotesY = $yCursorValue

$demoTrend.NotesX = $StrGetElement($xCursorValue,".",1)

$Open("AddComment")

Similarly, configure the Edit Comments button to open another pop-up screen that can be used to edit or delete existing comments in the annotations table:

$Open("EditComment")

For more information, see Command animation.

Tip: In most cases, you should add code like this to a button's On Up event and not its On Down event. The On Down event is immediately triggered when the user clicks or taps the button, even if they do so accidentally or they change their mind in mid-click. In contrast, the On Up event is triggered only when the button is fully released, which gives the user an opportunity to slide the cursor off the button and thereby abort the command.

Lay out the Add comment screen

Lay out the Edit Comment screen

In the Add Comment screen, configure the Comment and Font Size boxes to capture the user's input, and then configure the Apply button to call the AddComment procedure that you defined earlier:

Call AddComment($demoTrend.NotesX,$demoTrend.NotesY,$demoTrend.NotesFontSize,$demoTrend.NotesText)

$demoTrend.TrendReload = $Toggle($demoTrend.TrendReload)

$Close("AddComment")

In the Edit Comment screen, configure a Grid object to display the contents of the annotations table. As long as input is enabled for the grid, whatever the user types in the cells of the grid will actually be saved in the database. For more information, see Grid object.

Finally, configure the Delete button to delete any comment(s) that the user has selected in the grid:

Dim ret, i, sql, numCur, numRows

ret = MsgBox("Are you sure you want to delete this comment?",4)

If ret = 6 Then

sql = "SELECT * FROM TrendNotes"

numCur = $DBCursorOpenSQL("DB",sql)

numRows = $DBCursorRowCount(numCur)

$DBExecute("DB","DELETE FROM TrendNotes WHERE ID=" & $SelText)

For i = $SelText+1 To numRows

sql = "UPDATE TrendNotes SET ID=" & i-1 &" WHERE ID=" & i & ""

$DBExecute("DB",sql)

Next

End If

$demoTrend.TrendReload = $Toggle($demoTrend.TrendReload)

Any and all changes that the user makes to the annotations table during project run time should be immediately displayed in the associated trend control, as long as the values saved in the table are valid.