unit PixelDownS;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  Basic2, StdCtrls, ExtCtrls, TeeProcs, TeEngine, Chart,
  MtxVec, Math387, MtxVecEdit, Series, ComCtrls, Buttons;

type
  TDownS = class(TBasicForm2)
    Chart1: TChart;
    Chart2: TChart;
    Series1: TFastLineSeries;
    Series2: TFastLineSeries;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    TrackBar1: TTrackBar;
    Label5: TLabel;
    Label6: TLabel;
    Button1: TBitBtn;
    procedure FormResize(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure TrackBar1Change(Sender: TObject);
  private
    TestVec : TVec;
    NumPoints : Integer;
    procedure FillRandomPoints;
    procedure bthHelpClick(Sender: TObject);
    { Private declarations }
  public
    { Public declarations }
  end;

var
  DownS: TDownS;

implementation
{$R *.DFM}

Uses MtxVecTee;


const PIXELDEHELP = 10820;

procedure TDownS.bthHelpClick(Sender: TObject);
begin
     Application.HelpContext(PIXELDEHELP);
end;

procedure TDownS.FillRandomPoints;
var tmp: TSample;
    i  : Integer;
begin
  TestVec.Size(NumPoints);
  tmp := Random(1000);
  for i := 0 to TestVec.Length -1 do
  begin
       tmp := tmp + random(1000)-500;
       TestVec.Values[i] := tmp;
  end;
end;

procedure TDownS.FormResize(Sender: TObject);
begin
  Chart1.Height := Panel3.Height div 2;
end;

procedure TDownS.FormCreate(Sender: TObject);
begin
  inherited;
  With RichEdit1.Lines do
  begin
    Add('The PixelDownSample method can be used to speed '
      + 'up the drawing of huge amounts of data (>> 2000 '
      + 'samples). The routine will reduce the number of '
      + 'points in vectors Y and X in such a way that there '
      + 'will be no visual difference between the original '
      + 'and downsampled data. That however will no longer be '
      + 'true, if you will zoom-in on the data.');
    Add('The performance gain can be as big as 20x depending '
      + 'on the charting tool that you use. You can easily '
      + 'draw data series from vectors with length of over 100000 '
      + 'samples in real time. Try changing the "Number of points" '
      + 'and compare the visual appearance of both charts.');
  end;

  TestVec := TVec.Create;
  TrackBar1Change(TrackBar1);
  with TButton(Self.Owner.FindComponent('btnHelp')) do
  begin
       OnClick := bthHelpClick;
       Enabled := true;
  end;
end;

procedure TDownS.FormDestroy(Sender: TObject);
begin
  TestVec.Destroy;
  TButton(Self.Owner.FindComponent('btnHelp')).OnClick := nil;
  inherited;
end;

procedure TDownS.Button1Click(Sender: TObject);
begin
  FillRandomPoints;
  { "regular" plotting }
  Screen.Cursor := crHourGlass;
  TimeCheck := GetTickCount;
  with Chart1.BottomAxis do
  begin
       Automatic := false;
       SetMinMax(0,TestVec.Length);
  end;
  Series1.Clear;
  DrawValues(TestVec,Series1,0,1.0,False);
  TimeElapsed := GetTickCount - TimeCheck;
  Label3.Caption := IntToStr(TimeElapsed)+' ms';

  { "optimized" plotting }
  TimeCheck := GetTickCount;
  with Chart2.BottomAxis do
  begin
       Automatic := false;
       SetMinMax(0,TestVec.Length-1);
  end;
  Series2.Clear;
  DrawValues(TestVec,Series2,0,1.0,True);
  TimeElapsed := GetTickCount - TimeCheck;
  Label4.Caption := IntToStr(TimeElapsed)+' ms';
  Screen.Cursor := crDefault;
end;

procedure TDownS.TrackBar1Change(Sender: TObject);
begin
  NumPoints := TTrackBar(Sender).Position;
  Label6.Caption := IntToStr(NumPoints);
end;

initialization
   RegisterClass(TDownS);

end.
