Repository for import to local machine

Dependencies:   DMBasicGUI DMSupport

GuiLibGraph.h

Committer:
jmitc91516
Date:
2017-07-31
Revision:
8:26e49e6955bd
Parent:
1:a5258871b33d

File content as of revision 8:26e49e6955bd:

#ifndef GUILIBGRAPH_H
#define GUILIBGRAPH_H

#include "GuiLib.h"
#include "GuiDisplay.h"

#include "USBHostGC.h"

#include "GCStateAndFaultCodes.h" // This also contains the #define'd symbol USE_VERSION_102


typedef enum enumTimeUnit { MINUTES, SECONDS } TimeUnit;

typedef struct structFloatingDataPoint { float X; float Y; } FloatingDataPoint;
    
/*
    A class to implement an array of graph coordinate values, for use with an easyGUI graph
    (and with the GuiLibGraph class below, each instance of which encapsulates an easyGUI graph).
    Note that, while an easyGUI graph requires its coordinates to be integers, 
    we use floating point values in this class, for accuracy (the GC stores time values in 'units'
    of 0.1 minute). We convert these values to integers only when we pass them to an actual graph.
*/
class GuiLibGraphDataSet
{
public:
    GuiLibGraphDataSet();
    ~GuiLibGraphDataSet();
    
    void ClearData(void);
    
    bool AddDataPoint(float X, float Y);
    bool GetDataPoint(int dataPointIndex, float *X, float *Y);
    
    GuiLib_GraphDataPoint* GetGraphDataPointCopy(TimeUnit timeUnit, GuiConst_INT16U *countOfCopiedPoints);
    GuiLib_GraphDataPoint* GetGraphDataPointCopyInTenthsOfMinutes(float yAxisScaleFactor, GuiConst_INT16U *countOfCopiedPoints);
    GuiConst_INT16U GetDataSize(void) { return graphDataSetActualLength; }
    
    float GetYCoordAtXCoord(float X);

    void MakePartialCopy(float startXCoord, float endXCoord, GuiLibGraphDataSet* copyDestination);
    void MakeInterpolatedPartialCopy(float startXCoord, float endXCoord, float xInterval, GuiLibGraphDataSet* copyDestination);
    void MakeInterpolatedPartialCopyWithFinalPoint(float startXCoord, float endXCoord, float xInterval, GuiLibGraphDataSet* copyDestination);
    
    int SetupFromColumnTemperatureRampValues(USBDeviceConnected* usbDevice, USBHostGC* usbHostGC);
    int SetupFromPressureRampValues(USBDeviceConnected* usbDevice, USBHostGC* usbHostGC, GuiLibGraphDataSet* columnMethodDataSet);
    int SetupInjectorTemperatureProfileToMatchColumnMethod(USBDeviceConnected* usbDevice, USBHostGC* usbHostGC, GuiLibGraphDataSet* columnMethodDataSet);
    int SetupFromPTVTemperatureRampValues(USBDeviceConnected* usbDevice, USBHostGC* usbHostGC);
    int SetupGasPressureProfileWithTimingsFromColumnMethod(USBDeviceConnected* usbDevice, USBHostGC* usbHostGC, GuiLibGraphDataSet* columnMethodDataSet);
    
    float GetTotalMethodTime(void);
    int GetPointCount(void) { return graphDataSetActualLength; }
    float GetNonRoundedTotalMethodTime(void) { return nonRoundedTotalMethodTime; }

    void GetXAxisRange(GuiConst_INT32S *xMin, GuiConst_INT32S *xMax, TimeUnit timeUnit);
    void GetXAxisRangeInTenthsOfMinutes(GuiConst_INT32S *xMin, GuiConst_INT32S *xMax);
    void GetYAxisRange(GuiConst_INT32S *yMin, GuiConst_INT32S *yMax);

    void GetXAxisRange(GuiConst_INT32S *xMin, GuiConst_INT32S *xMax, GuiConst_INT32S tickSize, TimeUnit timeUnit);
    void GetXAxisRangeInTenthsOfMinutes(GuiConst_INT32S *xMin, GuiConst_INT32S *xMax, GuiConst_INT32S tickSize);
    void GetYAxisRange(GuiConst_INT32S *yMin, GuiConst_INT32S *yMax, GuiConst_INT32S tickSize);
    
    void DrawUsingGuiLibVLine(GuiConst_INT16S xLeft, GuiConst_INT16S yBottom, double xScaleFactor, double yScaleFactor, GuiConst_INTCOLOR firstColour, GuiConst_INTCOLOR secondColour, double xColourBoundary);
    void DrawUsingGuiLibVLine(void); // Use the values previously passed to the version with parameters

    static void ConvertFloatingDataPointToGuiLibGraphDataPoint(GuiLib_GraphDataPoint* graphDataPoint, FloatingDataPoint floatingDataPoint, TimeUnit timeUnit);
    
private:
    enum SizeIncrement { SIZE_INCREMENT = 10 }; // i.e. we allocate enough memory for this number of points each time we extend the array

    FloatingDataPoint* theGraphDataSet; // pointer to the actual data
    
    int graphDataSetActualLength; // The number of points to which we have actually assigned values
    int graphDataSetSizeInIncrements; // The number of points allowed for in the memory allocated to the array, as a count of SIZE_INCREMENT 'quanta' - 
                                      // i.e. the actual number of points currently available is (graphDataSetSizeInIncrements * SIZE_INCREMENT).
                                      // This *must* always be >= graphDataSetActualLength
                                      
    float nonRoundedTotalMethodTime; // The value returned by 'GetTotalMethodTime' is affected by the fact that X coordinates (i.e. time values)
                                     // are rounded to integer values (usually in minutes), because easyGUI graphs use integer coordinate values. 
                                     // This variable contains the non-rounded, accurate, total method time (effectively in units of 0.1 minute, 
                                     // as used by the GC itself).
                                     // *** This variable will be set only if the 'SetupFromColumnTemperatureRampValues', 'SetupFromPressureRampValues'  ***
                                     // *** 'SetupGasPressureProfileWithTimingsFromColumnMethod', 'SetupInjectorTemperatureProfileToMatchColumnMethod'   ***
                                     // *** or 'SetupFromPTVTemperatureRampValues' methods have been called on this dataset. Otherwise it will be zero.  ***
    
    bool ExtendDataSetArray(void);

    float GetComponentTemperature(char *cmd, USBDeviceConnected* usbDevice, USBHostGC* usbHostGC);
    float GetColumnTemperature(USBDeviceConnected* usbDevice, USBHostGC* usbHostGC);
    float GetInjectorTemperature(USBDeviceConnected* usbDevice, USBHostGC* usbHostGC);
    
    float GetTimeValue(char *cmd, USBDeviceConnected* usbDevice, USBHostGC* usbHostGC);
    float GetInitialHoldTime(USBDeviceConnected* usbDevice, USBHostGC* usbHostGC);
    float GetPTVInitialTime(USBDeviceConnected* usbDevice, USBHostGC* usbHostGC);

    float GetInitialPressure(USBDeviceConnected* usbDevice, USBHostGC* usbHostGC);
        
    float GetRampValue(char *cmd, int rampIndex, USBDeviceConnected* usbDevice, USBHostGC* usbHostGC);
    
    float GetTemperatureRampRate(int rampIndex, USBDeviceConnected* usbDevice, USBHostGC* usbHostGC);
    float GetRampUpperTemperature(int rampIndex, USBDeviceConnected* usbDevice, USBHostGC* usbHostGC);

    float GetRampUpperTime(int rampIndex, USBDeviceConnected* usbDevice, USBHostGC* usbHostGC);

    float GetPressureRampRate(int rampIndex, USBDeviceConnected* usbDevice, USBHostGC* usbHostGC);
    float GetRampUpperPressure(int rampIndex, USBDeviceConnected* usbDevice, USBHostGC* usbHostGC);
    
    float GetPTVTemperatureRampRate(int rampIndex, USBDeviceConnected* usbDevice, USBHostGC* usbHostGC);
    float GetPTVRampUpperTemperature(int rampIndex, USBDeviceConnected* usbDevice, USBHostGC* usbHostGC);

    float GetPTVRampUpperTime(int rampIndex, USBDeviceConnected* usbDevice, USBHostGC* usbHostGC);

    void RoundAxisRangeByTickSize(GuiConst_INT32S *axisMin, GuiConst_INT32S *axisMax, GuiConst_INT32S rawAxisMin, GuiConst_INT32S rawAxisMax, GuiConst_INT32S axisTickSize);

    struct structDrawUsingGuiLibVLineParameters {
        bool isSet;
        GuiConst_INT16S xLeft;
        GuiConst_INT16S yBottom;
        double xScaleFactor;
        double yScaleFactor;
        GuiConst_INTCOLOR firstColour;
        GuiConst_INTCOLOR secondColour;
        double xColourBoundary;   
    } DrawUsingGuiLibVLineParameters;    

    void DrawUsingGuiLibVLine(GuiConst_INT16S xLeft, GuiConst_INT16S yBottom, double xScaleFactor, double yScaleFactor, 
                              GuiConst_INTCOLOR firstColour, GuiConst_INTCOLOR secondColour, double xColourBoundary, bool recordParameters);
};

/*
    A class to implement an easyGUI graph, so that the caller does not need to know (for example) 
    which easyGUI 'GuiLib_Graph_xxx' functions to call, or how to use them. These functions 
    will be called only from inside this class. 
    
    This should keep the caller's code simpler and easier to understand - all the complications
    will be 'encapsulated' in this class.
    
    The graph index must be defined when an object of this class is instantiated. 
    This must correspond with its index number in easyGUI.
    *****************************************************
*/
class GuiLibGraph
{
public:
    GuiLibGraph(GuiConst_INT8U graphIndex);
    ~GuiLibGraph();
    
    GuiConst_INT8U DrawAxes(void);
    GuiConst_INT8U DrawDataSet(GuiConst_INT8U dataSetIndex);
    GuiConst_INT8U DrawDataPoint(GuiConst_INT8U dataSetIndex, GuiConst_INT16U dataPointIndex);
    GuiConst_INT8U HideDataSet(GuiConst_INT8U dataSetIndex);
    GuiConst_INT8U ShowDataSet(GuiConst_INT8U dataSetIndex);
    
    void DrawXAxisLabels(GuiConst_INT32S minValue, GuiConst_INT32S maxValue, GuiConst_INT32S tickSize, 
                         GuiConst_INT16S graphX, GuiConst_INT16S graphY, GuiConst_INT16S graphW);
    void DrawXAxisLabels(void); // Use the values previously passed to the version with parameters
    
    void DrawYAxisLabels(GuiConst_INT32S minValue, GuiConst_INT32S maxValue, GuiConst_INT32S tickSize, 
                         GuiConst_INT16S graphX, GuiConst_INT16S graphY, GuiConst_INT16S graphH);
    void DrawYAxisLabels(void); // Use the values previously passed to the version with parameters
    
    GuiConst_INT8U SetXAxisRange(GuiConst_INT32S minValue, GuiConst_INT32S maxValue);
    GuiConst_INT8U SetYAxisRange(GuiConst_INT32S minValue, GuiConst_INT32S maxValue);
    
    GuiConst_INT8U SetDataForGraphDataSet(GuiConst_INT8U dataSetIndex, GuiLibGraphDataSet* dataSet, TimeUnit timeUnit);
    GuiConst_INT8U SetDataForGraphDataSetInTenthsOfMinutes(GuiConst_INT8U dataSetIndex, float yAxisScaleFactor, GuiLibGraphDataSet* dataSet);
    GuiConst_INT8U SetSinglePointForGraphDataSet(GuiConst_INT8U dataSetIndex, GuiConst_INT32S X, GuiConst_INT32S Y);

    GuiConst_INT8U Redraw(void);
    
    void SetXAxisUnits(TimeUnit newXAxisUnits);
    TimeUnit GetXAxisUnits(void);

private:
    GuiConst_INT8U GuiLib_GraphIndex;
    
    TimeUnit xAxisUnits;
    
    enum { MINUTES_XAXIS_INDEX = 0, SECONDS_XAXIS_INDEX = 1 }; // There are two X axes set up for each graph in easyGUI. These are their indices
    enum { YAXIS_INDEX = 0 }; // For completeness - we currently do not intend to have multiple Y axes
    
    // We keep a pointer to the dataset data for each dataset index, up to 10.
    // This is the data added to the easyGUI graph object at that index.
    // Currently, we do not allow indices outside the range 0-9 - we just ignore them
    enum { DATASET_INDEX_COUNT = 10 };
    GuiLib_GraphDataPoint *dataSetDataPtr[DATASET_INDEX_COUNT];
    
    struct structXAxisLabelData {
        bool isSet;
        GuiConst_INT32S minValue;
        GuiConst_INT32S maxValue; 
        GuiConst_INT32S tickSize; 
        GuiConst_INT16S graphX; 
        GuiConst_INT16S graphY; 
        GuiConst_INT16S graphW;       
    } xAxisLabelData;    
    
    struct structYAxisLabelData {
        bool isSet;
        GuiConst_INT32S minValue;
        GuiConst_INT32S maxValue; 
        GuiConst_INT32S tickSize; 
        GuiConst_INT16S graphX; 
        GuiConst_INT16S graphY; 
        GuiConst_INT16S graphH;       
    } yAxisLabelData;    
    
    void DrawXAxisLabels(GuiConst_INT32S minValue, GuiConst_INT32S maxValue, GuiConst_INT32S tickSize, 
                         GuiConst_INT16S graphX, GuiConst_INT16S graphY, GuiConst_INT16S graphW, bool recordParameters);
    
    void DrawYAxisLabels(GuiConst_INT32S minValue, GuiConst_INT32S maxValue, GuiConst_INT32S tickSize, 
                         GuiConst_INT16S graphX, GuiConst_INT16S graphY, GuiConst_INT16S graphH, bool recordParameters);
};

#endif // GUILIBGRAPH_H