Page 1 of 1

Specific Spline X value required at Y Maximum

Posted: Wed Feb 18, 2009 5:38 am
by 10052502
Hi Steema,

I have just purchased the latest VCL Pro version and have implemented a Spline function which works perfectly. My next requirement is to get a specific X value from the Y Maximum of the spline. Is this possible and if so how do I achieve this ?

Thanks,
Steve West

Posted: Wed Feb 18, 2009 11:05 am
by yeray
Hi Steve,

Here is how you could search for your function maximum:

Code: Select all

procedure TForm1.Button1Click(Sender: TObject);
var maxY: double;
maxYIndex, i: integer;
begin
  maxY := Series2.MaxYValue;

  for i:=0 to Series2.Count-1 do
  begin
    if (Series2.YValue[i] = maxY) then
    begin
      maxYIndex := i;
      break;
    end;
  end;

  caption := 'maxY: ' + floattostr(maxY) + '  maxYIndex: ' + inttostr(maxYIndex) + '  X: ' + floattostr(Series2.XValue[maxYIndex]);
end;

Posted: Wed Feb 18, 2009 11:46 am
by 10052502
Yeray,

Thanks for the reply. I should have included a little more information on how I use the spline function. I have tried the method shown in your reply but I have had no luck as the TSmoothingFunction gives me no data in my series. Here is what I have so far.......

unit testofspline ;

// procedure declarations here

var

SplineFunction : TSmoothingFunction ;
SplineSeries : Array[1..10] of TLineSeries ;
MDRPointSeries : Array[1..10] of TPointSeries ;
XatYPeak,YPeak : Real ;

procedure TTestofSplineForm.CalculateandDrawSpline(LabNoIndex) ;
var
i : integer ;
begin
MDRPointSeries[LabNoIndex] := TPointSeries.Create(Self) ;
SplineFunction := TSmoothingFunction.Create(self) ;
SplineFunction.Interpolate := true ;
SplineFunction.Factor := 8 ;

SplineSeries[LabNoIndex] := TLineSeries.Create(Self) ;
SplineSeries[LabNoIndex].SetFunction(Splinefunction) ;

MDRPointSeries.AddXY(5.5,1.85,'',clTeal) ;
MDRPointSeries.AddXY(6.5,1.90,'',clTeal) ;
MDRPointSeries.AddXY(7.5,1.95,'',clTeal) ;
MDRPointSeries.AddXY(8.5,1.91,'',clTeal) ;

SplineSeries[LabNoIndex].DataSource := MDRPointSeries[LabnoIndex] ;
SplineSeries[LabnoIndex].checkDataSource ;

YPeak := SplineSeries[LabNoIndex].MaxYValue ;
for i := 0 to SplineSeries[LabNoIndex].Count-1 do
begin
if SplineSeries[LabNoIndex].YValues = YPeak then
XatYPeak := SplineSeries[LabNoIndex].XValue ;
end;
end;


Using this code above I end up with nothing that is accessible as points in my SplineSeries which is odd because the line is drawn perfectly on the graph. What am I doing wrong ?

Posted: Wed Feb 18, 2009 11:49 am
by 10052502
The lines shown as

MDRPointSeries.AddXY(5.5,1.85,'',clTeal) ;
MDRPointSeries.AddXY(6.5,1.90,'',clTeal) ;
MDRPointSeries.AddXY(7.5,1.95,'',clTeal) ;
MDRPointSeries.AddXY(8.5,1.91,'',clTeal) ;


should read

MDRPointSeries[LabNoIndex].AddXY(5.5,1.85,'',clTeal) ;
MDRPointSeries[LabNoIndex].AddXY(6.5,1.90,'',clTeal) ;
MDRPointSeries[LabNoIndex].AddXY(7.5,1.95,'',clTeal) ;
MDRPointSeries[LabNoIndex].AddXY(8.5,1.91,'',clTeal) ;

sorry about that was hashing code from my main project into a unit.

Regards,
Steve

Posted: Wed Feb 18, 2009 2:18 pm
by narcis
Hi Steve,

Could you please send us a simple example project we can run "as-is" to reproduce the problem here ?

You can either post your files at news://www.steema.net/steema.public.attachments newsgroup or at our upload page.

Thanks in advance.

Posted: Wed Feb 18, 2009 10:19 pm
by 10052502
Hi NarcĂ­s,

I have uploaded an app as requested. Very basic but does do what I have tried to explain in this post so far. The file I have uploaded is called TestofSplineExampleApp.zip

Cheers,
Steve

Posted: Wed Feb 18, 2009 10:19 pm
by 10052502
I should mention I uploaded via the upload page.

Thanks,
Steve

Posted: Thu Feb 19, 2009 11:38 am
by yeray
Hi Steve,

Simply changing the order of some calls, your code works fine for me:

Code: Select all

procedure TForm1.CalculateandDrawSpline(LabNoIndex : integer) ;
var
i : integer ;
begin
  ebYPeak.Text := '' ;
  ebXatYPeak.Text := '' ;
  ebSeriesPointCount.Text := '' ;
  ebPointSeriesPointCount.Text := '' ;

  MDRPointSeries[LabNoIndex] := TPointSeries.Create(Self) ;
  SplineFunction := TSmoothingFunction.Create(self) ;

  SplineSeries[LabNoIndex] := TLineSeries.Create(Self) ;
  SplineSeries[LabNoIndex].SetFunction(Splinefunction) ;

  Chart1.AddSeries(MDRPointSeries[LabNoindex]) ;
  Chart1.AddSeries(SplineSeries[LabNoindex]) ;

  SplineFunction.Interpolate := true ;
  SplineFunction.Factor := 8 ;

  MDRPointSeries[LabNoIndex].AddXY(5.5,1.85,'',clTeal) ;
  MDRPointSeries[LabNoIndex].AddXY(6.5,1.90,'',clTeal) ;
  MDRPointSeries[LabNoIndex].AddXY(7.5,1.95,'',clTeal) ;
  MDRPointSeries[LabNoIndex].AddXY(8.5,1.91,'',clTeal) ;

  SplineSeries[LabNoIndex].DataSource := MDRPointSeries[LabnoIndex] ;
  SplineSeries[LabnoIndex].checkDataSource ;

  YPeak := SplineSeries[LabNoIndex].MaxYValue ;
  for i := 0 to SplineSeries[LabNoIndex].Count-1 do
  begin
    if SplineSeries[LabNoIndex].YValues[i] = YPeak then
    XatYPeak := SplineSeries[LabNoIndex].XValue[i] ;
  end;
  ebSeriesPointCount.Text := inttostr(SplineSeries[LabNoIndex].Count) ;
  ebYPeak.Text := FloattoStrF(YPeak,ffFixed,6,3) ;
  ebXatYPeak.Text := FloattoStrF(XatYPeak,ffFixed,4,1) ;
  ebPointSeriesPointCount.Text := inttostr(MDRPointSeries[LabNoIndex].Count) ;
end;

Posted: Thu Feb 19, 2009 11:53 am
by 10052502
Yeray,

Thanks for that. Perfect. Works fine now.
One thing though, I have used Delphi since Delphi 1 and your standard components as part of Delphi since I can't remember but I have never put my AddSeries before I have processed the points into the actual series. Is this standard practice ? I am sure I read examples over the years showing the AddSeries as almost the last thing to do. Doesn't matter a great deal but I am glad it works. I appreciate the speedy replies from the Steema team.

Kind Regards,
Steve

Posted: Thu Feb 19, 2009 3:53 pm
by yeray
Hi Steve,

Well, as you know, when you add a series in design time, the series is created and added to the chart immediately. Then, it's more logic doing one thing just after the other also at runtime but, anyway, I'm glad to see that those examples worked at you end. :)