QChart Documentation by Michael Zito (c) 2003-2004
Appendix A: QChart

QChart Component

=============================================================================================
                           QChart:  A Charting Class for Rapid-Q
                          Copyright (c) 2003-2004  Michael J. Zito
                              Released under the LPGL License
=============================================================================================

QChart provides a rich set of 2-D charting routines for Rapid-Q programmers.
It generates histograms, bar charts, XY-scatter plots, line graphs, pie charts
and box plots.  Each charting routine will calculate an appropriate scale and plot
the data contained in the .Data or .XYData property of the object.  The user may
optionally specify the scaling as well as fonts, grids or other properties
(see code and HTML documentation). Once the data is formatted graphs can be called
with a few lines of simple code.

----> To create an instance and call QChart:

                $INCLUDE "QChart.inc"
                CREATE YourInstanceName AS QChart
                  Parent = QForm, QTabControl or QPanel
                  Set any other desired properties of a QCanvas
                END CREATE
                WITH YourInstanceName
                   .Initialize
                   .ChartType = ctXXXX
                   .ChartStyle = csXXXX
              ---->Change Any Desired Properties (See code or HTML Documentation)
              ---->REDIM .Data array property (See below)
              ---->Load Data Into .LabelList, .LegendList and .Data Array
                   .DrawChart (Overlay T or F)
                END WITH

NOTE: There is little error checking in this class.  It is up to the user
      to insure that the data is formatted properly before calling each routine.

LegendList and LabelList are implemented as QStringLists.
     *Use the .AddItems Method of each property to add text to the lists.
     *LegendList contains legend text and usually refers to the Cols (i.e. Series)
     *LabelList contains text used to label the X Axis and usually refers to Rows
      (i.e. Categories).  LabelList items are NOT USED by XY Charts

The .Data property is a 2 dimensional array of DOUBLE which must be REDIMd by the user
    prior to filling the grid with data.  The first dim is Cols and the second is Rows.
    Each Col represents a series to be plotted.  The Rows represent the data values
    within each series. Use the .Data property for all charts EXCEPT XY Charts.

XY Charts have their own data array.
    The .XYData property is a 3 dimensional array of DOUBLE. The first dim is Cols
    and the second is Rows. The third dim is ALWAYS 2. Each Col represents a series
    to be plotted. The Rows represent the number of XY data pairs within each
    series. The third dimension refers to the X and Y data values for each
    point to be plotted: 1 = X and 2 = Y values

----> To REDIM the .Data or .XYData array property:

You MUST set the .Cols and .Rows properties before calling QChart.  These values are used
throughout the QChart class as loop counters. Set .Cols to number of series to be plotted
and set .Rows to number of values in each series. REDIM the array using .Cols and .Rows.

NOTE:  To REDIM you MUST EXPLICITLY REFERENCE your QChart instance by name (even inside a
       WITH block) or RapidQ will not find and REDIM the array.  (A RapidQuirk?!?)
          WITH YourInstanceName
            .Cols = 2                                     <-- Num series
            .Rows = 2                                     <-- Num values in each series
            REDIM YourInstanceName.Data(.Cols, .Rows)     <-- for all EXCEPT XY Charts
            REDIM YourInstanceName.XYData(.Cols, .Rows, 2)<-- for XY Charts
          END WITH

   ----> Sample Data Formats (given the DIMs above):

              XY Charts                                All Other Charts
         =====================                         ================
         Series  NumPts Values                          Series  Values
         (Col)   (Row)  (dim 3)                         (Col)   (Row)
           1       1      1 <-- X                         1     val 11
           1       1      2 <-- Y                         1     val 12
           1       2      1                               2     val 21
           1       2      2                               2     val 22
           2       1      1
           2       1      2
           2       2      1
           2       2      2

   Box Plots         HiLo Plots        Pie Charts      BarLine Plots
  (5 rows only)     (3 rows only)     (1 Col only)     (2 Cols only)
================  =================  ==============   ===============           
 Row  1 = Max      Row   1 = Hi        Col     Row     Col 1    Col 2 
      2 = Q3             2 = Close    =====   =====    =====    =====       
      3 = Median         3 = Lo         1       1       Bar      Line 
      4 = Q1                            1       2       Data     Data       
      5 = Min                           1       n               

See QChartEx.rqb for more examples of setting up and calling each chart type.
See QChart.inc for named CONSTs used for ChartType, ChartStyle, HatchStyle and LineStyle

QChart Properties (Inherited from QCanvas)
FieldTypeR/WDefaultSupport





AlignINTEGERRWalNoneW
ClientHeightINTEGERRW
W
ClientWidthINTEGERRW
W
ColorINTEGERRW
WXG
CopyModeINTEGERRWcmBlacknessW
CursorINTEGERRWcrDefaultW
EnabledINTEGERRWTrueWXG
FontQFONTW
W
HeightINTEGERRW
WXG
HintSTRINGRW
W
LeftINTEGERRW0WXG
ParentQFORM/QPANEL/QTABCONTROLW
WXG
Pixel2D ARRAY of INTEGERRW
WXG
PopupMenuQPOPUPMENUW
W
ShowHintINTEGERRWFalseW
TagINTEGERRW
WXG
TopINTEGERRW0WXG
WidthINTEGERRW
WXG
VisibleINTEGERRWTrueWXG


QChart Specific Properties
FieldTypeDescriptionRWDefault





AxisBorder
BYTE
Draws border around plot
RW
True
ChartBorder
BYTEDraws border around entire chart RWTrue
Colors()
ARRAY of LONG
Array of predefined colors
RW
bgColor
LONG
Chart background color
RW
fgColor
LONGChart foreground colorRW
PlotAreaColor
LONGColor of plot area
RW
GridColor
LONGColor of gridlines
RW
BW
BYTEPlots in Black and White
RWFalse
GreyScale
BYTEPlots in GreyScaleRWFalse
DoLegend
BYTEDraw a legend to right of chart
RWTrue
MarkerSize
SINGLE
Size of markers for XY and Line charts
RW3
Viewport
INTEGER
Specifies Viewport width for Real Time Graphs
RW100
ChartType
INTEGER
Sets type of Chart to plot
RWctXY

ctBar, ctLine, ctXY, ctPie, ctHiLo, ctBox, ctBarLine, ctReal

ChartStyle
INTEGERSets style of Chart Type to plot
RWcsPoints

Bar           Line and XY      Pie        HiLo
==================================================
csBar          csPoints     csPisPct    csAntenna
csHisto        csLines      csPieVal    csHiLoBox
csStacked      csBoth
csPctStacked

Missing
DOUBLE
Value used to represent missing data
RW-9.999E-45
Data
2D ARRAY of DOUBLE
Data used in plotting all Charts EXCEPT XY
RW

Series   Values
(Col)    (Row)
  1      val 11
  1      val 12
  2      val 21
  2      val 22

XYData
3D ARRAY of DOUBLEData used to plot XY Charts ONLY
RW

Series  NumPts Values
(Col)   (Row)  (dim 3)
  1       1       1 <-- X
  1       1       2 <-- Y
  1       2       1
  1       2       2
  2       1       1
  2       1       2
  2       2       1
  2       2       2
Cols
INTEGER
Number of series to plot
RW1
Rows
INTEGER
Number of data values in each series
RW1

To REDIM the .Data or .XYData array property:

You MUST set the .Cols and .Rows properties before calling QChart. These values are used throughout the QChart class as loop counters. Set .Cols to number of series to be plotted and set .Rows to number of values in each series. REDIM the array using .Cols and .Rows.

NOTE:  To REDIM you MUST EXPLICITLY REFERENCE your QChart instance by name (even inside a WITH block) or RapidQ will not find and REDIM the array.  (A RapidQuirk?!?)

WITH YourInstanceName
  .Cols = 2                                    <-- Num series
  .Rows = 2                                    <-- Num values
   REDIM YourInstanceName.XYData(.Cols, .Rows, 2) <-- XY Only
   REDIM YourInstanceName.Data(.Cols, .Rows)   <-- All Others
END WITH
MainFont
QFONT
Font used to draw the Main Title
RWTimes
MainTitle.Text
STRING

RW""
SubFont
QFONTFont used to draw the Sub TitleRWTimes
SubTitle.Text
STRING
RW""
LegendFont
QFONTFont used to draw the LegendRWTimes
LegendList
QSTRINGLISTLegend text items; usually one for each series
RW""

Use the .AddItems Method to add text to the lists.
LegendList contains legend text and usually refers to the Cols
(i.e. Series)
AxisFont
QFONTFont used to draw the Axis LabelsRWTimes
LabelList
QSTRINGLISTAxis label text items; usually one for each categoryRW""

Use the .AddItems Method to add text to the lists.
LabelList contains text used to label the X Axis and usually refers to Rows (i.e. Categories).  LabelList items are NOT USED by XY Charts
XTitle.Text
STRING
RW""
YTitle.Text
STRING
RW""
XAxis / YAxis
UDTs (Elements Below)
There is 1 UDT for the XAxis and 1 for the YAxis
RW
   .AutoScale
BYTE
QChart scales the axes
RWTrue
   .Color
LONG
Color of axis line
RW
   .Div
INTEGER
Number of divisions on the axis
RW10
   .DrawZero
BYTEDraw a zero line if data spans origin
RWTrue
   .ZeroColor
LONG
Color of Zero line
RW
   .Grid
BYTEDraw gridlines for the axis
RWTrue
   .Labeled
BYTELabel the axis at tic intervals
RWTrue
   .LogScale
BYTETRUE = Log Scale, FALSE = Linear Scale
RWFalse
   .Min
DOUBLE
Data Minimum.  Must be set if AutoScale = FALSE
RW
   .Max
DOUBLE
Data Maximum.  Must be set if AutoScale = FALSERW
   .Tics
BYTEDraw tic marks on the axis
RWTrue
   .MnrTics
BYTEDraw minor tic marks on the axisRWTrue
Series()
UDT ARRAY (Elements Below)
Contains format inforamtion for each series plotted
RW
   .AutoColor
BYTE
Cycle through 18 available colors
RWTrue
   .AutoMark
BYTECycle through 8 available marker stylesRWTrue
   .Color
LONG
Color used in plotting the series
RW
   .HatchStyle
LONGHatch style used in plotting the seriesRWhsSolid
   .LineStyle
LONGLine style used in plotting the seriesRWlsSolid
   .LineWidth
LONGLineWidth used in plotting the seriesRW1
   .Marker
BYTE
Marker style used in plotting the seriesRWmsFilledCircle

QChart Methods
MethodTypeDescriptionParams




Initialize
SUB
Sets all values to default
0
ClearAll
SUB
Clears drawing buffer and paints blank canvas
0
PaintChart
SUBDraws Chart on Canvas. Assign this method to your OnPaint event0
DrawChart
SUB (Overlay%)Draws the currently defined chart to screen
1
RedrawChart
SUB
Redraws chart at new size.  Call from Resize event
0
CopyToClipboard
SUB (Wid%, Hgt%)Copies at specified width and height
2
SaveChart
SUB (SaveAs%)SaveAs = 0:No dialog if previously saved; 1:Always shows dialog
1
PrintChart
SUB (Prn%, Orient%, Margin%, Copies%, Color%)Uses CopyRect method to print chart.  May not work with all printers
5


QChart Events (Inherited from QCanvas)
EventTypeOccurs when...ParamsSupport





OnClickVOIDUser clicked on canvas0WXG
OnMouseDownSUB (Button%, X%, Y%, Shift%)Mouse button held down4WXG
OnMouseMoveSUB (X%, Y%, Shift%)Mouse moves3WXG
OnMouseUpSUB (Button%, X%, Y%, Shift%)Mouse button is released4WXG
OnPaintVOIDReceives WM_PAINT message0WXG


QChart Example

$OPTIMIZE ON
$TYPECHECK ON
$INCLUDE "QChart.inc" '<--- change path to point to file on your system 

'----- Form Event SUB Declarations  
Declare Sub btnOnClick (SENDER As QBUTTON)
Declare Sub frmMainResize (SENDER As QFORM)
Declare Sub frmMainClose (SENDER As QFORM)

'----- Define the main form  
Create frmMain As QFORM
  Center
  Width = 640
  Height = 480
  Caption = "QChart Example"
  OnResize = frmMainResize
  OnClose = frmMainClose
    Create drwBar1 As QBUTTON
      Caption = "Bar Graph"
      OnClick = btnOnClick
    End Create
    Create btnPie As QBUTTON
      Caption = "Pie Chart"
      Top = 25
      OnClick = btnOnClick
    End Create
    Create drwXYboth As QBUTTON
      Caption = "XY Both"
      Top = 50
      OnClick = btnOnClick
    End Create
    Create drwBox As QBUTTON
      Caption = "Box Plot"
      Top = 75
      OnClick = btnOnClick
    End Create
    Create drwHiLo1 As QBUTTON
      Caption = "HLC Style 1"
      Top = 100
      OnClick = btnOnClick
    End Create
    Create Graph As QCHART                        	'Create a copy of the new object  
      Align = 4                                   	'alRight  
      Width = frmMain.ClientWidth - btnPie.Width
      Height = frmMain.ClientHeight
      OnPaint = Graph.PaintChart                        'This line REQUIRED to process Repaints  
    End Create'Graph  
End Create'frmMain  

Graph.ClearAll
frmMain.Showmodal

Sub btnOnClick (SENDER As QBUTTON)

  Dim i  As Integer                                     'Loop counters...  
  Dim j  As Integer
  Dim k  As Single                                      'A Scratch Variable  

  Select Case Sender.Caption
    Case "Bar Graph"
      With Graph
        .Initialize                                     'Set defaults  
        .ChartType = ctBar                              'Bar Chart  
        .ChartStyle = csBar                             'Grouped Bars  
        .MainTitle.Text = "Bar Graph Example 1"         'change desired options  
        .SubTitle.Text = "Standard Bar Graph"
        .XTitle.Text = "X Axis"
        .YTitle.Text = "Y Axis"
        .Cols = 6                                       '<- Set Num Series  
        .Rows = 3                                       '<- Set Num Groups  
        REDIM Graph.Data(.Cols,.Rows)                   '<- REDIM the Data Array  
        k = 75                                           
        Randomize
        For j = 1 To .Rows                              'Do this outside data loop  
          .LabelList.AddItems "Treatment " + Str$(j)    'to avoid duplication of entries  
        Next j
        For i = 1 To .Cols        'Load the data 
   	  .LegendList.AddItems "Grp " + Str$(i)
          For j = 1 To .Rows
             .Data(i,j) = Rnd * k
          Next j
        Next i
        .DrawChart (FALSE)                              'Draw it!  
      End With

    Case "Pie Chart"  
      With Graph                                        
        .Initialize                                     'Always call this first  
        .ChartType = ctPie
        .ChartStyle = csPiePct                          'Show % at wedges (csPieVal shows Values)  
        .AxisFont.Size = 12
        .LegendFont.Size = 12
        .MainTitle.Text = "Pie Chart" 
        .SubTitle.Text = "Click Again For New Data"
        .Cols = 1                                       'Only 1 col for pie data  
        .Rows = 6                                       'Set Num data points  
        REDIM Graph.Data(.Cols,.Rows)                   'Redim the Data Array  
        k = 100                                         'Load the data  
        Randomize
        For i = 1 To .Rows
          .Series(i).AutoColor = FALSE
          .Series(i).Color = .Colors(i + 12)
          .LegendList.AddItems "Group " + Str$(i)
          .Data(1,i) = Rnd * k ' * i            
        Next 
        .DrawChart(FALSE)                               'Always call this last  
      End With

    Case "XY Both"
      With Graph
        .Initialize                                     'Set defaults  
        .ChartType = ctXY                               'XY Scatter Chart  
        .ChartStyle = csBoth                            'Lines and Points  
        .MainTitle.Text = "Scatter Plot With Lines"     'change desired options  
        .SubTitle.Text = "Double Width Lines"
        .XTitle.Text = "X Axis"
        .YTitle.Text = "Y Axis"
        .MarkerSize = .MarkerSize * 1.5
        .Cols = 3                                       'Number of series                                 
        .Rows = 11                                      'Number of data points per series  
        REDIM Graph.XYData(.Cols,.Rows,2)               'Redim XYData.  Note 3rd dim always 2  
        k = 132                                         'Load the data  
        Randomize
        For i = 1 To .Cols
          .LegendList.AddItems "Group " + Str$(i)          
          .Series(i).LineWidth = 2
          For j = 1 To .Rows
            .XYData(i,j,1) = Str$(j)                    'X Values (3rd dim 1)  
            .XYData(i,j,2) = Str$(Rnd * k)              'Y Values (3rd dim 2)  
          Next j
        Next i
        .DrawChart (FALSE)                              'Draw it!  
      End With

    Case "Box Plot"
      With Graph
        .Initialize                                     'Set defaults  
        .ChartType = ctBox                              'Box and Whisker Plot  
        .MainTitle.Text = "Box and Whisker Plot"        'change desired options  
        .XTitle.Text = "X Axis"
        .YTitle.Text = "Y Axis"
        .XAxis.Grid = FALSE
        .DoLegend = FALSE
        .Cols = 6                                       'Number of series  
        .Rows = 5                                       'Always 5 for Box Plots  
        REDIM Graph.Data(.Cols,.Rows)                   'Redim the data array  
        k = 20                                          'Load the data  
        Randomize
        For i = 1 To .Cols                              'for each col  
          .Series(i).AutoColor = FALSE
          .Series(i).Color = .Colors(2)
          .LabelList.AddItems "Group " + Str$(i)
          .Data(i , 1) = Str$(Rnd * k + 100)            'Max Values  
          .Data(i , 2) = Str$(Rnd * k + 75)             'Q3 Values  
          .Data(i , 3) = Str$(Rnd * k + 50)             'Q2 Values  
          .Data(i , 4) = Str$(Rnd * k + 25)             'Q1 Values  
          .Data(i , 5) = Str$(Rnd * k)                  'Min Values            
        Next i
        .DrawChart (FALSE)                              'Draw it!  
      End With

    Case "HLC Style 1"
      With Graph
        .Initialize                                     'Set defaults  
        .ChartType = ctHiLo                             'Hi-Lo-Close Plot  
        .ChartStyle = csAntenna
        .MainTitle.Text = "Hi-Lo-Close Plot"            'change desired options  
        .SubTitle.Text = "Antenna Style"
        .XTitle.Text = "X Axis"
        .YTitle.Text = "Y Axis"
        .XAxis.Grid = FALSE
        .Cols = 12                                      'Number of series  
        .Rows = 3                                       'Always 3 for HiLo charts  
        REDIM Graph.Data(.Cols,.Rows)                   'Redim the data array  
        k = 10                                          'Load the data  
        Randomize
        For i = 1 To .Cols                              'for each col  
          .LabelList.AddItems "Group " + Str$(i)          
          .Data(i , 1) = Rnd * k + 100                  'Hi Value  
          .Data(i , 2) = Rnd * k + 75                   'Close Value  
          .Data(i , 3) = Rnd * k + 50                   'Lo Value  
        Next i
        .DrawChart (FALSE)                              'Draw it!  
      End With
  End Select
End Sub
'-------------------------------------------------------------------------------------------  
Sub frmMainResize (SENDER As QFORM)
  With Graph
    .Width = frmMain.ClientWidth - btnPie.Width       'Calculate new sizes  
    .Height = frmMain.ClientHeight
    .RedrawChart                                       'Redraw the QChart Object  
  End With
End Sub
'-------------------------------------------------------------------------------------------  
Sub frmMainClose (SENDER As QFORM)
  Application.Terminate
End Sub
'-------------------------------------------------------------------------------------------