Curve Fit Chart

The Curve Fit Chart calculates and plots a least squares fit to a series of observed data points (X,Y). The functional form of the curve fit can be selected from a variety of supported equations. The Curve Fit chart is implemented in the OCCurveFitItem class. Several other classes (defined in curvefit.cpp) are used internally to perform the least squares fit calculations. A CX_GRAPH_XYSCATTERG_EX graph plots the data. Linear or logarithmic scaling can be applied to the X and Y axes independently. Optionally, the fit information (equation with computed coefficients and correlation coefficient) are displayed in an SRGraphTitleResizeable component.

Internally, the Curve Fit chart maintains four groups of data. The first two groups store the raw (or input) X and Y data, which are plotted as blue dots. The third and fourth groups store points generated to describe the equation of the fit, which is plotted as a red line.

The input data is passed to OCCurveFitItem::SetData(int nSize, double* pInX, double pInY) as two arrays of doubles. Alternatively, OCCurveFitItem will create its own buffers if both pInX and pInY are NULL. In that case, OCCurveFitItem allocates and deallocates its own buffers, but the buffers must be initialized -- by calling SetValue() -- before the curve fit is generated or the chart is drawn.

Using the Curve Fit Chart

To set up a Curve Fit chart:

1. Create an OCCurveFitItem object somewhere.

2. Create two data buffers (optional).

3. Initialize the data buffers with your X and Y data.

4. Call SetData((int nSize, double* pInX, double pInY) to provide the data to the OCCurveFitItem instance.

5. Call SetXRange(double dMinX, double dMaxX) to restrict the range of X data used to compute the fit (optional).

6. Call SetupComponent() to create the display and optional title for the internal SRGraph member.

7. Call SetFitType(int nType) to specify form of the desired curve. The supported types are listed in the Table 21.

8. Finally, call ProcessData() to perform the computation.

9. In your OnDraw() function call the DrawComponentList() function of OCCurveFitItem's internal SRGraph object to display the chart.

FIT_NONE | 0 | |

FIT_1ST_ORDER_POLY | 1 | y = a0 + a1*x |

FIT_2ND_ORDER_POLY | 2 | y = a0 + a1*x + a2*x^2 |

FIT_3RD_ORDER_POLY | 3 | y = a0 + a1*x + a2*x^2 + a3*x^3a |

FIT_4TH_ORDER_POLY | 4 | y = a0 + a1*x + a2*x^2 + ... + a4*x^4 |

FIT_5TH_ORDER_POLY | 5 | y = a0 + a1*x + a2*x^2 + ... + a5*x^5 |

FIT_6TH_ORDER_POLY | 6 | y = a0 + a1*x + a2*x^2 + ... + a6*x^6 |

FIT_7TH_ORDER_POLY | 7 | y = a0 + a1*x + a2*x^2 + ... + a7*x^7 |

FIT_8TH_ORDER_POLY | 8 | y = a0 + a1*x + a2*x^2 + ... + a8*x^8 |

FIT_9TH_ORDER_POLY | 9 | y = a0 + a1*x + a2*x^2 + ... + a9*x^9 |

FIT_EXPONENTIAL | 10 | y = a0*e^(a1*x) |

FIT_LOGRITHMIC | 11 | y = a0*ln(a1*x) |

FIT_POWER | 12 | y = a0*10^(a1*x) |

FIT_INVERSE | 13 | y = a0 + a1*x^(-1) |

FIT_INVERSE_SQUARE | 14 | y = a0 + a1*x^(-2) |

FIT_SINE | 15 | y = a0*sin(a1*x+a2) + a3 |

Here is an example:

// Create an OCCurveFitItem object somewhere in the app

OCCurveFitItem m_CurveFitChart;

// Set up the Curve Fit chart

void CCurveFitChartView::OnInitialUpdate()

{

m_CurveFitChart.SetupComponents();

int nPoints = InitTestData(); // app specific

m_CurveFitChart.SetFitType(3); // Third order polynomial

m_CurveFitChart.SetData(nPoints, dXData, dYData);

m_CurveFitChart.SetXRange(-5., 5.); // optional

m_CurveFitChart.ProcessData();

}

int CCurveFitChartView::InitTestData()

{

double x0 = -10.0;

double x1 = 10.0;

int nCount = 50;

double dx = (x1 - x0) / (double)(nCount-1);

for(int i = 0; i<nCount; i++)

{

// Random double (-1 to 1)

double rpct = ((double)rand() / (double)RAND_MAX) * 2 - 1;

double noise = 20 * rpct;

dXData[i] = x0;

dYData[i] =(3*x0*x0) + (2*x0) + 1 + noise;

x0 += dx;

}

return nCount;

}

// Draw the chart

void CCurveFitChartView::OnDraw(CDC* pDC)

{

m_CurveFitChart.GetGraph()->DrawComponentList(pDC, this);

}

Figure 137 – Sample Curve Fit chart

The CurveFitChart sample application distributed with Objective Chart (in <installdir>\Samples\Chart\Utility Toolkit) is a full implementation of the Curve Fit chart. The view class contains the OCCurveFitItem object and displays the chart. The view also supports several user interface enhancements.

Select Chart | Update to cycle through a series of data sets and appropriate curve fits.

Select a different fit type using the Chart | Change Fit Type command.

Other commands under the Chart menu let you choose logarithmic scaling for the X and Y axes and enable/disable the display of fit info in a title component in the chart.

The title component can be repositioned by right-clicking and dragging with the mouse.

The range bars on the X axis can be dragged to limit the range of data values used in calculating the fit.

Left-click and drag a blue raw data object. When you release the mouse button, the curve fit will be updated for the new data. The curve fit points (red) can not be dragged.

The view supports zooming, printing, print preview, and more.

NOTE >> The sine fit may not give good results unless a whole number of periods are observed. In the sample, you can adjust the position of the range bars to yield a good fit.