andreas

Overlay a characteristic curve in an XY Plot

Blog Post created by andreas Employee on Jul 5, 2010

Overlay a characteristic curve in an XY Plot

Some time ago I got a request to display a characteristic curve on an XY plot. A characteristic curve is an idealized graphical representation of two dependent (physical) measurements. An example of this is the current–voltage characteristic of a diode.

 

In this particular case the request was a best practice curve to appear on an XY plot along with the normal PI data. This had to be done for a wind turbine and should show 'wind speed' versus 'power generated' as PI data and as an idealized wind speed to power relationship.

 

As you know all data in PI archives are stored as time series, so I thought I am out of luck. Overlaying a simple graphic would work, but what happens when the user zooms in? In this little example we will use VBA to overlay an XY plot with dynamic PI data and an XY plot with static data, keeping them overlaid while you zoom and change the time range.

 

XYPic01.jpg

 

Talking to my “relational” colleague Frank caused him to come up with the characteristic curve stored in an access database, just a column for pressure and temperature as an example:

Line

Pressure

Temperature

0

1

5

10

10

17

15

20

20

20

25

22

30

23

35

27

40

30

45

32

50

35

55

45

60

65

65

75

70

85

75

85

80

80

85

75

90

72

95

70

100

70

And use that as a data source for an XY plot. For convenience we create a System Data source in Control Panel>All Control Panel Items>Administrative Tools>Data Sources (ODBC):

 

XYPic02.jpg

 

After this we can simply use it in PI ProcessBook to create a new ODBC Dataset:

 

XYPic03.jpg XYPic04.jpg XYPic05.jpg

 

And we can build a XY plot from this:

 

XYPic06.jpg XYPic07.jpg

 

Next to this plot we are going to create an XY plot with SINUSOID and SINUSOIDU:

 

XYPic08.jpg XYPic09.jpg

 

That was easy. Now we could set the background of our SINUSOID XY Plot to none and carefully move it above the characteristic curve – but this would only be slightly better than a simple bitmap in the background of the trend. So here is how vCampus comes in – let us automate the movement of the trends!

 

We assume, that we have renamed the left XY plot to XYPlotChar (for the left one, the ODBC Data) and the right one to XYPlotReal (for the right one, the PI Data)

 

First we add two command buttons to the display. For demonstrational purposes we want to overlay and separate the two trends:

 

XYPic10.jpg

Now let’s take a look at the code:

    1. First make sure that we do define all variables:

' Define all variables

Option Explicit

 

    1. As there is no VB color code for none, define one:

' We do not have a standard color code for none

Const vbNone = -1

 

    1. Limit the amount of code, so going for one SUB needs a switch:

' Switch between overlay and separate

Const myOverlay = 0

Const mySeparate = 1

Dim myButton As Boolean

 

    1. The myButton is necessary later, so let us initialize it properly:

' Initialization

Private Sub Display_Open()

   myButton = False

End Sub

 

    1. The worker routine is called MyFormat, here it is called from the overlay button …

' The Overlay button

Private Sub btnOverlay_Click()

   Call MyFormat(myOverlay)

End Sub

 

    1. … here it is called from the separate button (the myButton should make sure that the TimeRangeChange event does not interfere with us here) …

' The Separate button

Private Sub btnSeparate_Click()

   myButton = True

   Call MyFormat(mySeparate)

   myButton = False

End Sub

 

    1. … and finally from the zoom event!

' The ZOOM event

Private Sub XYPlotReal_Zoom()

   Call MyFormat(myOverlay)

End Sub

 

    1. Add the TimeRangeChange event handler to support the revert button, but make sure nothing happens if the seperate button is hit:

' The TimeRangeChange event

Private Sub XYPlotReal_TimeRangeChange(ByVal StartTime As String, ByVal EndTime As String)

    If myButton = False Then

       Call MyFormat(myOverlay)

    End If

End Sub

 

    1. Here is the code for MyFormat:

' My formatting routine:

'    opt: myOverlay to overlay the XY Plots

'         mySeparate to separate the XY Plots

Private Sub MyFormat(opt As Integer)


    ' First the position.

    If opt = mySeparate Then

       ' Separate:

        XYPlotChar.Height = 700

        XYPlotReal.Height = 700

        XYPlotChar.Width = 1000

        XYPlotReal.Width = 1000

        XYPlotChar.Left = -14950

        XYPlotReal.Left = -13900

        XYPlotChar.Top = 14950

        XYPlotReal.Top = 14950

    Else

        ' Overlayed:

        XYPlotChar.Height = XYPlotReal.Height

        XYPlotChar.Width = XYPlotReal.Width

        XYPlotChar.Left = XYPlotReal.Left

        XYPlotChar.Top = XYPlotReal.Top

    End If


    ' Now let us define the XY definition ...

    Dim myXYCharDefinition As XYDefinition

    Dim myXYRealDefinition As XYDefinition


    ' ... and get it.

    Set myXYCharDefinition = XYPlotChar.GetDefinition

    Set myXYRealDefinition = XYPlotReal.GetDefinition


    ' We need to loop through the tags, so get an integer

    Dim myTag As Integer


    ' Set the Definition.

    If opt = mySeparate Then

        ' For the separate plots.


        For myTag = 1 To 2

           ' Adjust the formating of the scale ...

           myXYRealDefinition.Tags.Item(myTag).ScaleFormat = _

                 myXYCharDefinition.Tags.Item(myTag).ScaleFormat

           ' ... and set the charactersitic curve ...

           myXYCharDefinition.Tags.Item(myTag).SetScaleConfiguration _

                 False, _

                 pbScaleAutorange, _

                 0, _

                 pbScaleAutorange, _

                 1

           ' ... and the data identically to AutoRange.

           myXYRealDefinition.Tags.Item(myTag).SetScaleConfiguration _

                 False, _

                 pbScaleAutorange, _

                 0, _

                 pbScaleAutorange, _

                 1

        Next myTag

        myXYCharDefinition.XYTitle = "Characteristic Curve"


        ' Apply the definition

        XYPlotChar.SetDefinition myXYCharDefinition

        XYPlotReal.SetDefinition myXYRealDefinition

    Else

        ' For the overlay plots.


        For myTag = 1 To 2

           ' We have to keep the scales in sync,

           ' so we need to remember them somewhere.

           Dim myMin As Double

           Dim myMax As Double

           Dim MaxScale As pbMinMaxEnum

           Dim MinScale As pbMinMaxEnum

           ' Get the type ...

           MaxScale = myXYRealDefinition.Tags.Item(myTag).Max

           MinScale = myXYRealDefinition.Tags.Item(myTag).Min

           ' ... and set the variables accordingly for the maximum ...

           Select Case MaxScale

              Case pbScaleAutorange

                 myMax = myXYRealDefinition.Tags.Item(myTag).AutorangeMax

              Case pbScaleAbsolute

                 myMax = myXYRealDefinition.Tags.Item(myTag).AbsoluteMax

              Case pbScaleDatabase

                 MsgBox "ERROR!"

           End Select

           ' ... and the minimum.


           Select Case MinScale

              Case pbScaleAutorange

                 myMin = myXYRealDefinition.Tags.Item(myTag).AutorangeMin

              Case pbScaleAbsolute

                 myMin = myXYRealDefinition.Tags.Item(myTag).AbsoluteMin

              Case pbScaleDatabase

                 MsgBox "ERROR!"

           End Select

           ' Now set the values ...

           myXYCharDefinition.Tags.Item(myTag).SetScaleConfiguration _

               False, _

               pbScaleAbsolute, _

               myMin, _

               pbScaleAbsolute, _

               myMax

       Next myTag

        myXYCharDefinition.XYTitle = ""


       ' ... and apply them

        XYPlotChar.SetDefinition myXYCharDefinition

    End If

  

    'After we adjusted the scales, now let us take a look at the formatting.

    Dim myXYCharFormatAs XYFormat

    Dim myXYRealFormatAs XYFormat

 

    'Get the format

    Set myXYCharFormat = XYPlotChar.GetFormat

    Set myXYRealFormat = XYPlotReal.GetFormat

 

    ' The characteristic curve

    With myXYCharFormat

        .DisplayScaleInside = True

        .ShowCoefficient = False

        .ShowDescription = False

        .ShowEngUnits = False

        .ShowGrids = myXYRealFormat.ShowGrids

        .ShowLinearCorrelation = myXYRealFormat.ShowLinearCorrelation

        .ShowTagName = False

        .ShowValue = False

        .ShowTitle = myXYRealFormat.ShowTitle

        If opt = mySeparate Then

           .Elements.Item(pbXYPen1).Color = vbBlue

        Else

           .Elements.Item(pbXYPen1).Color = vbRed

        End If

    End With

    XYPlotChar.SetFormat myXYCharFormat

 

    ' The real plot

    Set myXYRealFormat = XYPlotReal.GetFormat

    With myXYRealFormat

        .DisplayScaleInside = True

        .ShowCoefficient = False

        .ShowDescription = False

        .ShowEngUnits = False

        .ShowTagName = False

        .ShowValue = False

        .Elements.Item(pbXYPen1).Color = vbBlue

    End With

    XYPlotReal.SetFormat myXYRealFormat

  

    ' Just a white background ...

    XYPlotChar.BackgroundColor = vbWhite

    If opt = mySeparate Then

        XYPlotReal.BackgroundColor = vbWhite

    Else

        XYPlotReal.BackgroundColor = vbNone

    End If

  

End Sub

Now we have a characteristic curve from an ODBC data source ...

 

XYPic11.jpg

 

... that properly reacts on zoom and time range change!

 

XYPic12.jpg

 

Files MS Access Database & PDI are attached to this post

Attachments

Outcomes