[r1]: / XYChartExample.project  Maximize  Restore  History

Download this file

789 lines (678 with data), 2.0 MB

enum
-------------------------------------------------------------------------------
Overlap
-------------------------------------------------------------------------------


PROGRAM Overlap

VAR_INPUT
    xyChart: VisuStructXYChart;
    AxisX: VisuStructXYChartAxis;
    AxisY1: VisuStructXYChartAxis;
    Curve: VisuStructXYChartCurve;
    DataX: ARRAY [..] OF ;
    DataY: ARRAY [..] OF ;
    iCurveHeapSize: INT;
    iNumCurve: INT;
    xStart: BOOL;
    sText: string;
    rOffset: REAL;
    xShowTrace: BOOL;
    xNotVisMsg: BOOL;
    xChangeZoom: BOOL;
END_VAR

VAR
    xFirst: BOOL;
    xDoIt: BOOL;
    ePendingCmd: ENUM_CMD_PENDING;
    rTrigStart: R_TRIG;
    fTrigTimer: F_TRIG;
    rTrigZoom: R_TRIG;
    iCalc: INT;
    iLoop: INT;
    ix: INT;
    timer: TP;
    sampleTime: TIME;
    xTimerEnd: BOOL;
    rXValue: REAL;
    rYValue: REAL;
    udiCycleCounter: UDINT;
    udiCycleWait: UDINT;
    tDelay: TON;
    xDelay: BOOL;
    xDelayEnd: BOOL;
    iActualZoom: INT;
END_VAR
(**********************************************************************************************
   The scope of this application is to show how to use XYChart element in overlapping mode.
   It simply generates a curve and when the curve arrives at a certain point,
   it informs the element to push it in the heap.
   The next curve is generated with an offset on X and Y, to have the possibility to see the 
   difference with the previous one.
   When we reach the maximum number of curves to display, we will clean all and start again
***********************************************************************************************)


//------------------------------------------------------------------
// Initial settings
IF xFirst THEN
   Curve.iCurveHeapSize := iCurveHeapSize;                  // We will maintain 4 curves in the heap
   Curve.eOverlap := VisuEnumXYChartCvOverlapType.OVERLAP;  // We will work in overlapping mode 
   Curve.diIndexMin := 1;                                   // We set the initial indexes to use
   Curve.diIndexMax := 1;
   iNumCurve := Curve.iCurveHeapSize;                       // We will display as many curves as the heap size
   xNotVisMsg := TRUE;
END_IF

//------------------------------------------------------------------
// We change the text of the button
IF xStart THEN
   sText := 'Stop drawing';
ELSE   
   sText := 'Start drawing';
END_IF   

//------------------------------------------------------------------
// We enable/disable the tracking of the curve drawing using level lines
xDoIt := FALSE;
IF xShowTrace THEN
   xDoIt := TRUE;
END_IF   
AxisX.aLevelLine[1].xEnable  := xDoIt;
AxisY1.aLevelLine[1].xEnable := xDoIt;

//------------------------------------------------------------------
// Detect the zoom cahnging 
rTrigZoom(CLK:=xChangeZoom, Q=>xDoIt);
IF xDoIt THEN
   xChangeZoom := xDoIt := FALSE;
   IF iActualZoom = 0 THEN
      iActualZoom := 1;
      AxisX.rMin := -5;
      AxisX.rMax := 20;
      AxisY1.rMin := 0;
      AxisY1.rMax := 10;
   ELSE   
      iActualZoom := 0;
      AxisX.rMin := -2;
      AxisX.rMax := 15;
      AxisY1.rMin := -1;
      AxisY1.rMax := 5;
	END_IF
END_IF   
 
//------------------------------------------------------------------
// We start the curve drawing 
rTrigStart(CLK:=xStart, Q=>xDoIt);
IF xDoIt THEN
   xDoIt := FALSE;
   // We clean up the arrays
   FOR ix := 1 TO 200 BY 1 DO
       DataX[ix] := 0.0;
       DataY[ix] := 0.0;
   END_FOR
   iCalc := 1;          // The initial calculation point of our curve
   iLoop := 0;          // No loop right now
   rOffset := 0.0;      // No curve offset right now
   
   // If we did a "start" and next a "stop", we can have some curves in the heap.
   // In this way we will remove them
   Curve.eCurveHeapCmd := VisuEnumXYChartCvHeapCmd.CLEAN;
   udiCycleCounter := VisuSync.udiCycleCounter;  // Save cycle counter 
   ePendingCmd := ENUM_CMD_PENDING.CLEAN;
   udiCycleWait := 10;                 // How many cycle to wait the command ending  
   xNotVisMsg := TRUE;
END_IF

//------------------------------------------------------------------
// Timer for data generation 
timer(IN:=xStart, PT:=sampleTime, Q=>xTimerEnd) ;
IF xTimerEnd = FALSE THEN
   timer(IN:=xTimerEnd, PT:=sampleTime, Q=>xTimerEnd) ;
END_IF ;
	
// Timer clock detection
fTrigTimer(CLK:=xTimerEnd, Q=>xDoIt) ;
IF xDoIt THEN
   xDoIt := FALSE;
   IF (ePendingCmd = ENUM_CMD_PENDING.NO_CMD) AND NOT xDelay THEN   // only if we don't have pending command
      
      // When arrive the tick of the clock
      // we do the curve calculation
      IF iCalc <= 126 THEN                            // If we are in the calculation limit
         FctGetXYValues(iCalc-1, rXValue, rYValue);   // Get new values  
         DataX[iCalc] := rXValue + rOffset;           // Store the value in the arrays
         DataY[iCalc] := rYValue + rOffset;
         Curve.diIndexMax := iCalc;                   // The last valid value in the array 
         iCalc := iCalc+1;                      
      ELSE                       // We have finish to calculate the curve
         xDelay := TRUE;         // Enable delay time to finish the display curve
		END_IF
      AxisX.aLevelLine[1].rValue  := DataX[Curve.diIndexMax];      // Update the position for curve tracking
      AxisY1.aLevelLine[1].rValue := DataY[Curve.diIndexMax];
   END_IF
END_IF

//------------------------------------------------------------------
// Test the delay time to finish the display curve 
tDelay(IN:=xDelay, PT:=T#2S, Q=>xDelayEnd);
IF xDelay THEN
   IF xDelayEnd THEN
      xDelay := FALSE;
      
      // We have finish to calculate the curve
      iCalc := 1;                            // Reset the calculation value
      iLoop := iLoop+1;                      // We are facing a new loop
      IF iLoop < iNumCurve THEN              // I've room again, update the curve !
         Curve.eCurveHeapCmd := VisuEnumXYChartCvHeapCmd.UPDATE;     // We update the curve
         ePendingCmd := ENUM_CMD_PENDING.UPDATE;  // Update pending
      ELSE                                   // Heap full
         iLoop := 0 ;                        // We will start with a neww loop
         Curve.eCurveHeapCmd := VisuEnumXYChartCvHeapCmd.CLEAN;     // We clean the heap   
         ePendingCmd := ENUM_CMD_PENDING.CLEAN;   // Clean 
         udiCycleWait := 50;                 // How many cycle to wait the command ending, to have time to see the last curve, before clean all 
         xNotVisMsg := FALSE;
      END_IF    
	END_IF
   udiCycleCounter := VisuSync.udiCycleCounter;  // save cycle counter 
END_IF

//------------------------------------------------------------------
// If there's a clean command pending, we wait some cycles
// to have the possibility to see the last curve
IF ePendingCmd = ENUM_CMD_PENDING.CLEAN THEN
   IF (ABS(VisuSync.udiCycleCounter - udiCycleCounter) > udiCycleWait) AND (Curve.eCurveHeapCmd = VisuEnumXYChartCvHeapCmd.NO) THEN
      iLoop := 0 ;                        // We will start with a neww loop
      rOffset := 0.0;                     // No curve offset
      ePendingCmd := ENUM_CMD_PENDING.NO_CMD;      
      xNotVisMsg := TRUE;
   END_IF
END_IF

//----------------------------------------------------------------------------------------
// If there's an update command pending, we simply wait the end of the command
IF ePendingCmd = ENUM_CMD_PENDING.UPDATE THEN
   IF Curve.eCurveHeapCmd = VisuEnumXYChartCvHeapCmd.NO THEN
      iCalc := 1;                         // Reset the calculation value
      rOffset := rOffset + 0.3;           // Next curve will have an offset
      Curve.diIndexMax := iCalc;          // Reset to init curve
      ePendingCmd := ENUM_CMD_PENDING.NO_CMD;      
      xNotVisMsg := TRUE;
   END_IF
END_IF

xFirst := FALSE;



VAR_INPUT
    iValue: INT;
    rXValue: REFERENCE TO REAL;
    rYValue: REFERENCE TO REAL;
END_VAR

VAR
    rValue: REAL;
END_VAR
// X = t − 2 sin t
// Y = 2 − 2 cos t

rValue  := INT_TO_REAL(iValue);
rValue  := rValue/10.0;
rXValue := rValue - 2.0*SIN(rValue);
rYValue := 2.0 - 2.0*COS(rValue);






-------------------------------------------------------------------------------
VisuSync
-------------------------------------------------------------------------------


PROGRAM VisuSync

VAR_INPUT
    udiCycleCounter: UDINT;
END_VAR
udiCycleCounter := udiCycleCounter +1;

VAR
    ix: INT;
END_VAR
// Clean up the arrays
FOR ix := 1 TO 100 BY 1 DO
    Prog.DataX1[ix]  := 0.0 ;
    Prog.DataY1[ix]  := 0.0 ;
END_FOR
   
// Set deualt data   
Prog.DataX1[1] := -10.0 ;
Prog.DataX1[2] := 20.0 ;
Prog.DataX1[3] := 30.0 ;
Prog.DataX1[4] := 40.0 ;
Prog.DataX1[5] := 50.0 ;  
Prog.DataX1[6] := 60.0 ;  
Prog.DataX1[7] := 70.0 ;  
Prog.DataX1[8] := 80.0 ;  
Prog.DataX1[9] := 90.0 ;  
Prog.DataX1[10] := 100.0 ;  

Prog.DataY1[1] := 10.0 ;
Prog.DataY1[2] := 20.0 ;
Prog.DataY1[3] := 10.0 ;
Prog.DataY1[4] := 30.0 ;
Prog.DataY1[5] := 10.0 ;
Prog.DataY1[6] := 40.0 ;
Prog.DataY1[7] := 10.0 ;
Prog.DataY1[8] := 50.0 ;
Prog.DataY1[9] := 10.0 ;
Prog.DataY1[10] := 60.0 ;




-------------------------------------------------------------------------------
Prog
-------------------------------------------------------------------------------


PROGRAM Prog

VAR_INPUT
    xyChart: VisuStructXYChart;
    AxisX: VisuStructXYChartAxis;
    AxisY1: VisuStructXYChartAxis;
    Curve1: VisuStructXYChartCurve;
    DataX1: ARRAY [..] OF ;
    DataY1: ARRAY [..] OF ;
    iCurve1ProgType: INT;
    xProgCurve1: BOOL;
    xProgOff: BOOL;
    xProgSave: BOOL;
    xProgUndoS: BOOL;
    xProgUndo: BOOL;
    xSetOrigCurve: BOOL;
    sProgClient: string;
    xProgMode: BOOL;
    xChangePending: BOOL;
    udiCycleCounter: UDINT;
END_VAR

VAR
    xInitDone: BOOL;
    SVxyChart: VisuStructXYChart;
    SVAxisX: VisuStructXYChartAxis;
    SVAxisY1: VisuStructXYChartAxis;
    SVCurve1: VisuStructXYChartCurve;
    xDoIt: BOOL;
    xDelayProgCurve1: BOOL;
    xDelayProgOff: BOOL;
    xDelayProgSave: BOOL;
    rTrigProgCurve1: R_TRIG;
    rTrigProgOff: R_TRIG;
    rTrigOrig: R_TRIG;
    rTrigUndoS: R_TRIG;
    rTrigUndo: R_TRIG;
    rTrigSave: R_TRIG;
END_VAR
(**********************************************************************************************
   The scope of this application is to show how to use XYChart element in programming mode.
   It simply shows a predefine curve that the user can modify or completely make from scratch.
***********************************************************************************************)


//------------------------------------------------------------------
// During the first entry we do some initial activities
IF NOT xInitDone THEN
   IF ABS(VisuSync.udiCycleCounter - udiCycleCounter) > 2 THEN    // Valid when "Visu" is running
      // We save the initial element configuration for further uses
      SVxyChart := xyChart;
      SVAxisX   := AxisX;
      SVAxisY1  := AxisY1;
      SVCurve1  := Curve1;

      // We limit the use of the array
      Curve1.diIndexMin := 1 ;        
      Curve1.diIndexMax := 10 ;
      
      FctSetDefaultDataCurve();  // Set default data for curves   
      
      xInitDone := TRUE;         // done
   ELSE
      RETURN ;                   // We will do nothing if we don't' have the correct data          
	END_IF
END_IF


//------------------------------------------------------------------
// We start the programming on curve 
rTrigProgCurve1(CLK:=xProgCurve1, Q=>xDoIt);
IF xDoIt THEN
   xProgCurve1 := FALSE;
   rTrigProgCurve1(CLK:=xProgCurve1, Q=>xDoIt);
   IF xyChart.xProgMode = FALSE THEN                              // If it's not already in programming mode
      xyChart.wsFocus := SVCurve1.wsCvName;                       // We need to inform the element, what's the curve that has the focus 
      IF iCurve1ProgType = 0 THEN
         xyChart.eProg := VisuEnumXYChartProgType.MODIFY;         // We inform the element to enter in programming mode for exixting curve modification
      ELSE   
         xyChart.eProg := VisuEnumXYChartProgType.NEW_CURVE;      // We inform the element to enter in programming mode for a new curve modify
      END_IF
      udiCycleCounter  := VisuSync.udiCycleCounter;               // We save the actual cycle counter 
      xDelayProgCurve1 := TRUE;
   END_IF
END_IF

// We wait some cycles before to act in programming mode,
// to give to the element the time to activate the programming mode
IF xDelayProgCurve1 THEN
   IF xyChart.xProgMode THEN                                            // Command has been executed
      xDelayProgCurve1       := FALSE;
      Curve1.ePointStyle     := VisuEnumXYChartPointStyle.DOT;          // We set the visualization of the line using also dot  
      xyChart.eFocusDisplay  := VisuEnumXYChartFocusType.FOC_REV_COL;   // We show the axis that has the focus, with reverse colors on numbers
      xyChart.diCursorColorM := VisuElemXYChart.COLOR.Red;              // We change the color of the cursor
	ELSE
      IF ABS(VisuSync.udiCycleCounter - udiCycleCounter) > 100 THEN
         xDelayProgCurve1 := FALSE;                                     // Something went wrong 
      END_IF
   END_IF
END_IF


//------------------------------------------------------------------
// We stop the programming
rTrigProgOff(CLK:=xProgOff, Q=>xDoIt);
IF xDoIt THEN
   xProgOff := FALSE;
   rTrigProgOff(CLK:=xProgOff, Q=>xDoIt);
   xyChart.eProg   := VisuEnumXYChartProgType.NO;    // We inform the element to stop the programming mode for a new curve modify 
   udiCycleCounter := VisuSync.udiCycleCounter;      // We save the actual cycle counter 
   xDelayProgOff   := TRUE;
END_IF

// We wait some cycles before to exit from programming mode,
// to give to the element the time to update the visualization
IF xDelayProgOff THEN
   IF NOT xyChart.xProgMode THEN                                  // Command has been executed
      xDelayProgOff          := FALSE;
      Curve1.ePointStyle     := SVCurve1.ePointStyle;             // We change it to the original one
      xyChart.wsFocus        := SVCurve1.wsCvName;                // We set the focus as default on curve1 
      xyChart.eFocusDisplay  := SVxyChart.eFocusDisplay;          // We change it to the original one
      xyChart.diCursorColorM := SVxyChart.diCursorColorM;         // We change it to the original one    
	ELSE
      IF ABS(VisuSync.udiCycleCounter - udiCycleCounter) > 100 THEN
         xDelayProgOff := FALSE;                                  // Something went wrong 
      END_IF
   END_IF
END_IF


//------------------------------------------------------------------
// We save the curve 
rTrigSave(CLK:=xProgSave, Q=>xDoIt);
IF xDoIt THEN
   xProgSave := FALSE;
   rTrigSave(CLK:=xProgSave, Q=>xDoIt);
   xyChart.eCommand := VisuEnumXYChartCommands.PRG_SAVE;          // We inform the element to save the curvestop the programming mode for a new curve modify
   udiCycleCounter := VisuSync.udiCycleCounter;                   // We save the actual cycle counter 
   xDelayProgSave := TRUE;
END_IF

// We wait some cycles,
// to give to the element the time to save all the data
IF xDelayProgSave THEN
   IF xyChart.eCommand = VisuEnumXYChartCommands.NO THEN   // Command has been executed
      xDelayProgSave := FALSE;
      xProgOff := TRUE;                                    // We will do the same operations like programming off 
	ELSE
      IF ABS(VisuSync.udiCycleCounter - udiCycleCounter) > 100 THEN
         xDelayProgSave := FALSE;                          // Something went wrong 
      END_IF
   END_IF
END_IF


//------------------------------------------------------------------
// Undo single point 
rTrigUndoS(CLK:=xProgUndoS, Q=>xDoIt);
IF xDoIt THEN
   xProgUndoS := FALSE;
   rTrigUndoS(CLK:=xProgUndoS, Q=>xDoIt);
   xyChart.eCommand := VisuEnumXYChartCommands.PRG_UNDO;
END_IF


//------------------------------------------------------------------
// Undo all 
rTrigUndo(CLK:=xProgUndo, Q=>xDoIt);
IF xDoIt THEN
   xProgUndo := FALSE;
   rTrigUndo(CLK:=xProgUndo, Q=>xDoIt);
   xyChart.eCommand := VisuEnumXYChartCommands.PRG_UNDO_ALL;
END_IF


//------------------------------------------------------------------
// Set original curve 
rTrigOrig(CLK:=xSetOrigCurve, Q=>xDoIt);
IF xDoIt THEN
   xSetOrigCurve := FALSE;
   rTrigOrig(CLK:=xSetOrigCurve, Q=>xDoIt);

   // We set all the data as the original   
   xyChart := SVxyChart;
   AxisX   := SVAxisX;
   AxisY1  := SVAxisY1;
   Curve1  := SVCurve1;

   // We limit the use of the array
   Curve1.diIndexMin := 1 ;        
   Curve1.diIndexMax := 10 ;
   
   FctSetDefaultDataCurve();  // Set default data for curves   
END_IF


//------------------------------------------------------------------
// On line situation 
sProgClient := VisuElemXYChart.VisuFctGetClientName(xyChart.eClientProg);     // On which client programming is active
xProgMode := xyChart.xProgMode;                                               // Element is in programming mode
xChangePending := xyChart.xChangePending;                                     // Change is pending

-------------------------------------------------------------------------------
VisuSync
-------------------------------------------------------------------------------

                   Counter that runs in parallel with the "Visu" cycle


PROGRAM VisuSync

VAR_INPUT
    udiCycleCounter: UDINT;
END_VAR
udiCycleCounter := udiCycleCounter +1;
-------------------------------------------------------------------------------
PLC_PRG
-------------------------------------------------------------------------------


PROGRAM PLC_PRG

VAR_INPUT
    rSaveXMin: REAL;
    rSaveXMax: REAL;
    rSaveY1Min: REAL;
    rSaveY1Max: REAL;
    rSaveY2Min: REAL;
    rSaveY2Max: REAL;
    rMinAxisX: REAL;
    rMaxAxisX: REAL;
    rMinAxisY1: REAL;
    rMaxAxisY1: REAL;
    rMinAxisY2: REAL;
    rMaxAxisY2: REAL;
    AxisX: VisuStructXYChartAxis;
    AxisY1: VisuStructXYChartAxis;
    AxisY2: VisuStructXYChartAxis;
END_VAR

VAR
    xDoIt: BOOL;
    xCursorOff: BOOL;
    rTrigCurs: R_TRIG;
    strCursor: string;
    xZoom: BOOL;
    rTrigZoom: R_TRIG;
    strZoom: string;
    xZoomRst: BOOL;
    rTrigZoomRst: R_TRIG;
    xZoomUndo: BOOL;
    rTrigZoomUndo: R_TRIG;
    xPan: BOOL;
    rTrigPan: R_TRIG;
    strPan: string;
    xPanRst: BOOL;
    rTrigPanRst: R_TRIG;
    xCfg0: BOOL;
    rTrigCfg0: R_TRIG;
    xCfg1: BOOL;
    rTrigCfg1: R_TRIG;
    xCfg2: BOOL;
    rTrigCfg2: R_TRIG;
    xRevAxes: BOOL;
    rTrigRevAxes: R_TRIG;
    DataX1: ARRAY [..] OF ;
    DataY1: ARRAY [..] OF ;
    DataX2: ARRAY [..] OF ;
    DataY2: ARRAY [..] OF ;
    xyChart: VisuStructXYChart;
    Curve1: VisuStructXYChartCurve;
    Curve2: VisuStructXYChartCurve;
    xZoomEnableExt: BOOL;
    xZoomHomeExt: BOOL;
    xZoomUndoExt: BOOL;
    xZoomedExt: BOOL;
    strZoomExt: string;
    xPanEnableExt: BOOL;
    strPanExt: string;
    xPanHomeExt: BOOL;
    xPannedExt: BOOL;
    rValue: REAL;
    xFirst: BOOL;
END_VAR
(**********************************************************************************************
   The scope of this application is to show how to use zooming and panning in XYChart element.
***********************************************************************************************)

//------------------------------------------------------------------
// Initial settings
IF xFirst THEN
   DataX1[1] := 10.0 ;
   DataX1[2] := 20.0 ;
   DataX1[3] := 30.0 ;
   DataX1[4] := 40.0 ;
   DataX1[5] := 50.0 ;  
   DataX1[6] := 60.0 ;  
   DataX1[7] := 70.0 ;  
   DataX1[8] := 80.0 ;  
   DataX1[9] := 90.0 ;  
   DataX1[10] := 100.0 ;  
   
   DataY1[1] := 10.0 ;
   DataY1[2] := 20.0 ;
   DataY1[3] := 10.0 ;
   DataY1[4] := 30.0 ;
   DataY1[5] := 10.0 ;
   DataY1[6] := 40.0 ;
   DataY1[7] := 10.0 ;
   DataY1[8] := 50.0 ;
   DataY1[9] := 10.0 ;
   DataY1[10] := 60.0 ;
   
   DataX2[1] := 25.0 ;
   DataX2[2] := 30.0 ;
   DataX2[3] := 35.0 ;
   DataX2[4] := 40.0 ;
   DataX2[5] := 45.0 ;  
   DataX2[6] := 65.0 ;  
   DataX2[7] := 70.0 ;  
   DataX2[8] := 75.0 ;  
   DataX2[9] := 80.0 ;  
   DataX2[10] := 85.0 ;  
   
   DataY2[1] := 15.0 ;
   DataY2[2] := 8.0 ;
   DataY2[3] := 45.0 ;
   DataY2[4] := 25.0 ;
   DataY2[5] := 50.0 ;
   DataY2[6] := 15.0 ;
   DataY2[7] := 8.0 ;
   DataY2[8] := 45.0 ;
   DataY2[9] := 25.0 ;
   DataY2[10] := 50.0 ;
END_IF

// Switch on/off cursor
rTrigCurs(CLK:=xCursorOff, Q=>xDoIt);
IF xDoIt THEN
   IF xyChart.eCursor = VisuEnumXYChartCursorVisible.NOVIS THEN
      xyChart.eCursor := VisuEnumXYChartCursorVisible.VISIBLE_MAIN;
      strCursor := 'Curs OFF';
   ELSE   
      xyChart.eCursor := VisuEnumXYChartCursorVisible.NOVIS;
      strCursor := 'Curs ON';
	END_IF
END_IF

// Zoom start/stop using element structure 
rTrigZoom(CLK:=xZoom, Q=>xDoIt);
IF xDoIt THEN
   IF (xyChart.eActivity = VisuEnumXYChartActivityType.NO) OR (xyChart.eActivity = VisuEnumXYChartActivityType.PAN)  THEN 
      xyChart.eActivity := VisuEnumXYChartActivityType.ZOOM;
   ELSE   
      xyChart.eActivity := VisuEnumXYChartActivityType.NO;
	END_IF
END_IF

// Reset zoom
rTrigZoomRst(CLK:=xZoomRst, Q=>xDoIt);
IF xDoIt THEN
   xyChart.eCommand := VisuEnumXYChartCommands.ZOOM_HOME;
END_IF

// Undo zoom
rTrigZoomUndo(CLK:=xZoomUndo, Q=>xDoIt);
IF xDoIt THEN
   xyChart.eCommand := VisuEnumXYChartCommands.ZOOM_UNDO;
END_IF


// Pan start/stop using element structure 
rTrigPan(CLK:=xPan, Q=>xDoIt);
IF xDoIt THEN
   IF (xyChart.eActivity = VisuEnumXYChartActivityType.NO) OR (xyChart.eActivity = VisuEnumXYChartActivityType.ZOOM)  THEN 
      xyChart.eActivity := VisuEnumXYChartActivityType.PAN;
   ELSE   
      xyChart.eActivity := VisuEnumXYChartActivityType.NO;
	END_IF
END_IF

// Reset panning
rTrigPanRst(CLK:=xPanRst, Q=>xDoIt);
IF xDoIt THEN
   xyChart.eCommand := VisuEnumXYChartCommands.PAN_HOME;
END_IF



// Set default axes configuration
rTrigCfg0(CLK:=xCfg0, Q=>xDoIt);
IF xDoIt THEN
   AxisX.rMin  := rMinAxisX  := rSaveXMin;
   AxisX.rMax  := rMaxAxisX  := rSaveXMax;
   AxisY1.rMin := rMinAxisY1 := rSaveY1Min;
   AxisY1.rMax := rMaxAxisY1 := rSaveY1Max;
   AxisY2.rMin := rMinAxisY2 := rSaveY2Min;
   AxisY2.rMax := rMaxAxisY2 := rSaveY2Max;
END_IF

// Set axes configuration #1
rTrigCfg1(CLK:=xCfg1, Q=>xDoIt);
IF xDoIt THEN
   AxisX.rMin  := rMinAxisX  := -100;
   AxisX.rMax  := rMaxAxisX  := 200;
   AxisY1.rMin := rMinAxisY1 := 0;
   AxisY1.rMax := rMaxAxisY1 := 120;
   AxisY2.rMin := rMinAxisY2 := 0;
   AxisY2.rMax := rMaxAxisY2 := 180;
END_IF

// Set axes configuration #2
rTrigCfg2(CLK:=xCfg2, Q=>xDoIt);
IF xDoIt THEN
   AxisX.rMin  := rMinAxisX  := 20;
   AxisX.rMax  := rMaxAxisX  := 80;
   AxisY1.rMin := rMinAxisY1 := -100;
   AxisY1.rMax := rMaxAxisY1 := 200;
   AxisY2.rMin := rMinAxisY2 := -100;
   AxisY2.rMax := rMaxAxisY2 := 200;
END_IF

// Reverse axes
rTrigRevAxes(CLK:=xRevAxes, Q=>xDoIt);
IF xDoIt THEN
   rValue := AxisX.rMin;
   AxisX.rMin := AxisX.rMax;
   AxisX.rMax := rValue;
   
   rValue := AxisY1.rMin;
   AxisY1.rMin := AxisY1.rMax;
   AxisY1.rMax := rValue;
   
   rValue := AxisY2.rMin;
   AxisY2.rMin := AxisY2.rMax;
   AxisY2.rMax := rValue;

   rValue := rMinAxisX;
   rMinAxisX := rMaxAxisX;
   rMaxAxisX := rValue;

   rValue := rMinAxisY1;
   rMinAxisY1 := rMaxAxisY1;
   rMaxAxisY1 := rValue;
   
   rValue := rMinAxisY2;
   rMinAxisY2 := rMaxAxisY2;
   rMaxAxisY2 := rValue;
END_IF

// Display setting
IF xyChart.eActivity = VisuEnumXYChartActivityType.PAN THEN
   strPan := 'Pan OUT';
   strZoom := 'Zoom IN';
END_IF
IF xyChart.eActivity = VisuEnumXYChartActivityType.ZOOM THEN
   strZoom := 'Zoom OUT';
   strPan := 'Pan IN';
END_IF
IF xyChart.eActivity = VisuEnumXYChartActivityType.NO THEN
   strPan := 'Pan IN';
   strZoom := 'Zoom IN';
END_IF

IF xZoomEnableExt THEN 
   strZoomExt := 'Zoom OUT';
ELSE   
   strZoomExt := 'Zoom IN';
END_IF

IF xPanEnableExt THEN 
   strPanExt := 'Pan OUT';
ELSE   
   strPanExt := 'Pan IN';
END_IF


xFirst := FALSE;

-------------------------------------------------------------------------------
VISU_INIT
-------------------------------------------------------------------------------


PROGRAM VISU_INIT

VAR
    xFirst: BOOL;
END_VAR
IF xFirst THEN
   PLC_PRG.rMinAxisX  := PLC_PRG.AxisX.rMin;
   PLC_PRG.rMaxAxisX  := PLC_PRG.AxisX.rMax;
   PLC_PRG.rMinAxisY1 := PLC_PRG.AxisY1.rMin;
   PLC_PRG.rMaxAxisY1 := PLC_PRG.AxisY1.rMax;
   PLC_PRG.rMinAxisY2 := PLC_PRG.AxisY2.rMin;
   PLC_PRG.rMaxAxisY2 := PLC_PRG.AxisY2.rMax;
   
   PLC_PRG.rSaveXMin  := PLC_PRG.rMinAxisX;
   PLC_PRG.rSaveXMax  := PLC_PRG.rMaxAxisX;
   PLC_PRG.rSaveY1Min := PLC_PRG.AxisY1.rMin;
   PLC_PRG.rSaveY1Max := PLC_PRG.AxisY1.rMax;
   PLC_PRG.rSaveY2Min := PLC_PRG.AxisY2.rMin;
   PLC_PRG.rSaveY2Max := PLC_PRG.AxisY2.rMax;
END_IF
xFirst := FALSE;