unit MtxGridSeries_Demo;
{$I BdsppDefs.inc}
interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, Basic2, StdCtrls, ComCtrls, ExtCtrls, TeeProcs, TeEngine, Chart,
  MtxVec, MtxVecTee, MtxComCtrls, Sparse;

type
  TfrmMtxGridSeries = class(TBasicForm2)
    Chart1: TChart;
    Panel4: TPanel;
    CheckBox2: TCheckBox;
    Timer1: TTimer;
    Button2: TButton;
    RadioGroup1: TRadioGroup;
    CheckBox1: TCheckBox;
    Label1: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure CheckBox2Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure RadioGroup1Click(Sender: TObject);
    procedure Chart1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure Chart1GetAxisLabel(Sender: TChartAxis; Series: TChartSeries;
      ValueIndex: Integer; var LabelText: String);
  private
    { Private declarations }
    A: TMtx;
    v1,v2: TVec;
    SparseA: TSparseMtx;
    GridSeries : TMtxGridSeries;
  public
    { Public declarations }
  end;

var
  frmMtxGridSeries: TfrmMtxGridSeries;

implementation

Uses {$IFNDEF TEESTD}EditChar,{$ENDIF}MtxGridSerEdit; { <--- add grid series editor to uses clause }

{$R *.dfm}

procedure TfrmMtxGridSeries.FormCreate(Sender: TObject);
begin
  inherited;
  With RichEdit1.Lines, RichEdit1 do
  begin
    Clear;
    Add('New in MtxVec 1.5 : TMtxGridSeries which can be used '
      + 'with all TeeChart versions (v4 Standard, v4 PRO, v5). '
      + 'Using TMtxGridSeries you can visualize matrix values. '
      + 'Key properties/methods are:');
    Add('');
    Paragraph.FirstIndent := 10;
    Paragraph.Numbering := nsBullet;
    Add('property PaletteSteps : Defines the number of palette steps for legend');
    Add('property BottomColor, TopColor : Defines color for lowest and highest value.');
    Add('property PaletteStyle : Default value is palRange meaning palette '
      + 'colors will be calculated from BottomColor, TopColor and PaletteSteps '
      + 'properties.  If you want to define custom palette levels, set '
      + 'PaletteStyle to palCustom and then define level and it''s color by using '
      + 'AddPalette method.');
    Add('method AddPalette : adds new palette level (works only if PaletteStyle is palCustom).');
    Add('method CreateRangePalette : Recreates range palette values. Call this method if matrix '
      + 'maximum/minimum value changes.');
    Add('method ClearPalette : clears palette.'+#10+#13);

    Paragraph.FirstIndent := 0;
    Paragraph.Numbering := nsNone;
    Add('');
    Add('Some properties are accessible via the MtxGridSeries editor (click on "Edit Grid Series" button).');
  end;
  {$IFDEF TEESTD}
  Button2.Visible := False;
  Chart1.Legend.Visible := False;
  {$ELSE}
  Chart1.Legend.Visible := True;
  Button2.Visible := True;
  {$ENDIF}
  { setup grid series }
  With Chart1.LeftAxis do
  begin
    Title.Caption := 'Index';
    Increment := 1.0;
    RoundFirstLabel := False;
    LabelsOnAxis := True;
  end;
  With Chart1.LeftAxis do
  begin
    Title.Caption := 'Index';
    Increment := 1.0;
    RoundFirstLabel := False;
    LabelsOnAxis := True;
  end;
  GridSeries := TMtxGridSeries.Create(Chart1);
  GridSeries.ValueFormat := '0.00';
  GridSeries.BottomColor := clWhite;
  GridSeries.TopColor := clBlack;
  GridSeries.PaletteSteps := 10;
  GridSeries.HorizAxis := aTopAxis;
  GridSeries.ParentChart := Chart1;
  { now setup sparse matrix }
  SparseA := TSparseMtx.Create;
  A := TMtx.Create;
  v1 := TVec.Create;
  v2 := TVec.Create;
  { zero count is only estimated zero count if the value is to small.
    This will result in many memory reallocations by RandomSparse. }
  SparseA.Size(2000,2000,100000,False);
  SparseA.RandomSparse(v1,v2,False,1,100000);
  SparseA.PixelDownSample(A,500,TPixelDownSample(RadioGroup1.ItemIndex));
  DrawValues(A,GridSeries); { showing A }
end;

procedure TfrmMtxGridSeries.FormDestroy(Sender: TObject);
begin
  A.Destroy;
  v1.Destroy;
  v2.Destroy;
  SparseA.Destroy;
  inherited;
end;

procedure TfrmMtxGridSeries.CheckBox2Click(Sender: TObject);
begin
  Timer1.Enabled := CheckBox2.Checked;
  RadioGroup1.Enabled := Not Timer1.Enabled;
  Button2.Enabled := Not Timer1.Enabled;
  CheckBox1.Checked := Not CheckBox2.Checked;
end;

procedure TfrmMtxGridSeries.Timer1Timer(Sender: TObject);
begin
  SparseA.RandomSparse(v1,v2,False,1,100000);
  SparseA.PixelDownSample(A,500,TPixelDownSample(RadioGroup1.ItemIndex));
  GridSeries.CreateDefaultPalette; { range most likely changed, so ... }
  GridSeries.Repaint;
end;

procedure TfrmMtxGridSeries.Button2Click(Sender: TObject);
begin
  {$IFNDEF TEESTD}
  EditSeries(Self,GridSeries);
  {$ENDIF}
end;

procedure TfrmMtxGridSeries.RadioGroup1Click(Sender: TObject);
begin
  SparseA.PixelDownSample(A,500,TPixelDownSample(RadioGroup1.ItemIndex));
  GridSeries.CreateDefaultPalette;
  GridSeries.Repaint;
end;

procedure TfrmMtxGridSeries.Chart1MouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: Integer);
var index: Integer;
begin
  inherited;
  if CheckBox1.Checked then
  begin
    index := GridSeries.Clicked(X,Y);
    if index <> -1 then
      Label1.Caption := FormatFloat('0.00',GridSeries.Matrix.Values1D[index])
    else Label1.Caption := '';
  end;
end;

procedure TfrmMtxGridSeries.Chart1GetAxisLabel(Sender: TChartAxis;
  Series: TChartSeries; ValueIndex: Integer; var LabelText: String);
var tmp : Integer;
begin
  inherited;
  { invert axis labels}
  if (Sender = Chart1.LeftAxis) and (Assigned(GridSeries.Matrix)) then
  begin
    tmp := Round(StrToFloat(LabelText));
    tmp := GridSeries.Matrix.Rows - 1 - tmp;
    LabelText := IntToStr(tmp);
  end;
end;

initialization
  RegisterClass(TfrmMtxGridSeries);

end.
