Click here to see how it looks (100K gif).
Or get the whole code here.
program Normal; uses {$IFDEF WIN32} Forms, {$ENDIF} {$IFDEF LINUX} {Note the pre-pending of "Q" to Forms for Clx:} QForms, {$ENDIF} Normal1 in 'Normal1.pas' {MainForm}; {Ensure that your resource files' extension really is ".res" and not ".RES".} {$R *.res} begin Application.Initialize; Application.Title := 'Normal for Linux'; Application.CreateForm(TMainForm, MainForm); Application.Run; end.
unit Normal1; {$I Chemware.inc} interface uses SysUtils, Classes, TypInfo, // units common to Delphi and Kylix {$IFDEF WIN32} // Windows units Windows, Messages, Graphics, Controls, Forms, Dialogs, ImgList, Menus, Grids, ExtCtrls, StdCtrls, Buttons, ComCtrls, ToolWin, {$ENDIF} {$IFDEF LINUX} // Kylix equivalents that link to Qt {Note the pre-pending of "Q" for many Clx units:} Qt, Types, // you rarely need to pull in Qt directly QGraphics, QControls, QForms, QDialogs, QImgList, QMenus, QGrids, QExtCtrls, QStdCtrls, QButtons, QComCtrls, {$ENDIF} {our own cross-platform units. Be very very careful about case sensitivity !} Plot, Plotdefs, Plotmenu, Plotimagelist, Data, Plottoolbar, Nedit; type TMainForm = class(TForm) Panel1: TPanel; StringGrid1: TStringGrid; MinNEdit: TNEdit; Label1: TLabel; Label2: TLabel; MaxNEdit: TNEdit; Label3: TLabel; StepSizeNEdit: TNEdit; Label4: TLabel; MeanNEdit: TNEdit; Label5: TLabel; StdDevNEdit: TNEdit; GoBitBtn: TBitBtn; GoCrazyBitBtn: TBitBtn; CrazyTimer: TTimer; ClearAllBitBtn: TBitBtn; NoisyBitBtn: TBitBtn; TraceBitBtn: TBitBtn; TypeBitBtn: TBitBtn; StatusBar1: TStatusBar; procedure ClearAllBitBtnClick(Sender: TObject); procedure GoBitBtnClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure PlotMenu1ExitMenuItemClick(Sender: TObject); procedure NoisyBitBtnClick(Sender: TObject); procedure GoCrazyBitBtnClick(Sender: TObject); procedure CrazyTimerTimer(Sender: TObject); procedure MyPlotFileOpen(Sender: TObject; TheFile: String); procedure TraceBitBtnClick(Sender: TObject); procedure TypeBitBtnClick(Sender: TObject); private MyPlot: TPlot; MyPlotMenu: TPlotMenu; MyPlotImageList: TPlotImageList; MyPlotToolBar: TPlotToolBar; Revolutions, StartWidth, StartHeight: Integer; Angle, AngleInc: Single; public { Public declarations } end; var MainForm: TMainForm; implementation {Note the lower case "dfm":} {$R *.dfm} const RADIUS = 50.0; procedure TMainForm.FormCreate(Sender: TObject); begin Height := 516; Width := 712; MyPlotImageList := TPlotImageList.Create(Self); MyPlot := TPlot.Create(Self); MyPlot.Parent := Self; MyPlot.Align := alClient; MyPlot.Images := MyPlotImageList; MyPlot.PlotType := ptXY; MyPlot.NoSeries := 2; MyPlot.MakeDummyData(20); MyPlotMenu := TPlotMenu.Create(Self); MyPlotMenu.Images := MyPlotImageList; MyPlotMenu.Plot := MyPlot; MyPlotMenu.SetUpOnClicks; MyPlotToolBar := TPlotToolBar.Create(Self); MyPlotToolBar.Parent := Self; MyPlotToolBar.Images := MyPlotImageList; MyPlotToolBar.Plot := MyPlot; StringGrid1.Cells[0, 0] := 'Test:'; StringGrid1.Cells[0, 1] := 'Score:'; StringGrid1.ColWidths[0] := 60; {$IFDEF WIN32} Self.Caption := 'TPlot demo for Delphi'; {$ENDIF} {$IFDEF LINUX} Self.Caption := 'TPlot demo for Kylix'; {$ENDIF} end; procedure TMainForm.ClearAllBitBtnClick(Sender: TObject); var i: Integer; begin MyPlot.SeriesList.ClearSeries; for i := 1 to StringGrid1.ColCount-1 do begin StringGrid1.Cells[i, 0] := ''; StringGrid1.Cells[i, 1] := ''; end; end; procedure TMainForm.GoBitBtnClick(Sender: TObject); var X, Y: Single; Mean: Single; StdDev: Single; Min: Single; Max: Single; StepSize: Single; {$IFDEF MSWINDOWS} FStartTime: Int64; {TLargeInteger;} FFinishTime: Int64; FFrequency: Int64; {$ENDIF} {$IFDEF LINUX} FStartTime: TDateTime; FFinishTime: TDateTime; {$ENDIF} ElapsedTime: Double; begin MyPlot.NoSeries := 1; MyPlot.Series[0].DelData; Screen.Cursor := crHourGlass; {$IFDEF MSWINDOWS} QueryPerformanceFrequency(FFrequency); {counts per second} {get the starting time:} QueryPerformanceCounter(FStartTime); { LARGE_INTEGER} {$ENDIF} {$IFDEF LINUX} FStartTime := Time; {$ENDIF} Mean := MeanNEdit.AsReal; StdDev := StdDevNEdit.AsReal; Min := MinNEdit.AsReal; Max := MaxNEdit.AsReal; StepSize := StepSizeNEdit.AsReal; {Set the axes:} MyPlot.XAxis.Max := Max; MyPlot.XAxis.Min := Min; MyPlot.YAxis.Min := 0; MyPlot.XAxis.Intercept := 0; X := Min; while (X <= Max) do begin Y := Exp(-Sqr((X-Mean)/(2*StdDev))) / Sqrt(2*Pi*StdDev); {Don't fire any events, and don't adjust axes:} MyPlot[0].AddPoint(X, Y, FALSE, FALSE); X := X + StepSize; end; MyPlot[0].Visible := TRUE; MyPlot.YAxis.Max := MyPlot.Series[0].YMax; {get the finishing time:} {$IFDEF MSWINDOWS} QueryPerformanceCounter(FFinishTime); { LARGE_INTEGER} {take difference and convert to ms:} ElapsedTime := 1000 * (FFinishTime - FStartTime) / FFrequency; {$ENDIF} {$IFDEF LINUX} FFinishTime := Time; ElapsedTime := 1000 * (FFinishTime - FStartTime); {$ENDIF} StatusBar1.SimpleText := Format('Drawing %d points takes %g ms', [MyPlot[0].NoPts, ElapsedTime]); Screen.Cursor := crDefault; end; procedure TMainForm.PlotMenu1ExitMenuItemClick(Sender: TObject); begin Close; end; procedure TMainForm.NoisyBitBtnClick(Sender: TObject); begin MyPlot.MakeDummyData(100); end; procedure TMainForm.GoCrazyBitBtnClick(Sender: TObject); begin if (CrazyTimer.Enabled) then begin CrazyTimer.Enabled := FALSE; GoCrazyBitBtn.Caption := 'Go Crazy'; TraceBitBtn.Enabled := TRUE; end else begin Revolutions := 0; StartWidth := Width; StartHeight := Height; Angle := 0; AngleInc := 4 * Pi / 180; GoCrazyBitBtn.Caption := 'Enough !'; CrazyTimer.Enabled := TRUE; TraceBitBtn.Enabled := FALSE; end; end; procedure TMainForm.CrazyTimerTimer(Sender: TObject); begin if (MyPlot.PlotType >= pt3DContour) then begin MyPlot.ZAngle := MyPlot.ZAngle + 1; end else begin Width := StartWidth + Round(RADIUS * Sin(Angle)); Height := StartHeight + Round(RADIUS * Cos(Angle)); Angle := Angle + AngleInc; Inc(Revolutions); StatusBar1.SimpleText := IntToStr(Revolutions); end; end; procedure TMainForm.MyPlotFileOpen(Sender: TObject; TheFile: String); var TheTitle: String; begin TheTitle := ExtractFileName(Application.ExeName); TheTitle := Copy(TheTitle, 1, Length(TheTitle)-4); TheTitle := TheTitle + ' - ' + ExtractFileName(TheFile); Application.Title := TheTitle; MainForm.Caption := TheTitle; end; procedure TMainForm.TraceBitBtnClick(Sender: TObject); begin MyPlot.Trace; end; procedure TMainForm.TypeBitBtnClick(Sender: TObject); var ThePlotType: Integer; TheXStringData: TStringList; begin ThePlotType := Ord(MyPlot.PlotType); ThePlotType := (ThePlotType+1) mod (Ord(High(TPlotType))+1); MyPlot.SeriesList.ClearSeries; MyPlot.PlotType := TPlotType(ThePlotType); MyPlot.Title.Caption := 'TPlot - ' + #10 + Copy(TypInfo.GetEnumName(TypeInfo(TPlotType), ThePlotType), 3, 99); case MyPlot.PlotType of ptXY: begin MyPlot.MakeDummyData(100); MyPlot.Border.Left := 70; MyPlot.Border.BottomGap := 80; end; ptError: begin MyPlot.MakeDummyData(20); MyPlot.Series[0].Symbol := syCircle; end; ptMultiple: begin MyPlot.NoSeries := 4; MyPlot.Multiplicity := 4; MyPlot.MakeDummyData(20); MyPlot.Series[0].Pen.Width := 0; MyPlot.Series[1].Pen.Width := 0; MyPlot.Series[2].Pen.Width := 0; MyPlot.Series[3].Pen.Width := 0; MyPlot.Series[0].Name := 'High'; MyPlot.Series[1].Name := 'Low'; MyPlot.Series[2].Name := 'Open'; MyPlot.Series[3].Name := 'Close'; MyPlot.Series[0].Symbol := syLeftDash; MyPlot.Series[1].Symbol := syRightDash; MyPlot.MultiJoin := '2,3'; end; ptBubble: begin MyPlot.MakeDummyData(20); end; ptColumn, ptStack, ptNormStack: MyPlot.MakeDummyData(10); ptPie: begin MyPlot.MakeDummyData(10); TheXStringData := TStringList.Create; TheXStringData.Add('Alpha'); TheXStringData.Add('Bravo'); TheXStringData.Add('Charlie'); TheXStringData.Add('Delta'); TheXStringData.Add('Echo'); TheXStringData.Add('Foxtrot'); TheXStringData.Add('Golf'); TheXStringData.Add('Hotel'); TheXStringData.Add('India'); TheXStringData.Add('Juliet'); TheXStringData.Add('Kilo'); MyPlot.Series[0].XStringData := TheXStringData; MyPlot.Series[1].XStringData := TheXStringData; TheXStringData.Free; end; ptPolar: begin MyPlot.XAxis.Min := -10; MyPlot.XAxis.Max := 10; MyPlot.YAxis.Min := -10; MyPlot.YAxis.Max := 10; MyPlot.MakeDummyData(20); MyPlot.XAxis.Intercept := 0; MyPlot.YAxis.Intercept := 0; end; ptContour, pt3DContour, pt3DWire, pt3DColumn: begin if (MyPlot.PlotType > ptContour) then begin MyPlot.Border.Left := 120; MyPlot.Border.BottomGap := 130; end; MyPlot.XAxis.Min := 0; MyPlot.XAxis.Max := 10; MyPlot.YAxis.Min := 0; MyPlot.YAxis.Max := 10; MyPlot.NoSeries := 10; MyPlot.MakeDummyData(20); end; else ; end; end; end.