diff --git a/applications/lazstats/source/LazStats.lpi b/applications/lazstats/source/LazStats.lpi
index 0ce9526b1..4361df52f 100644
--- a/applications/lazstats/source/LazStats.lpi
+++ b/applications/lazstats/source/LazStats.lpi
@@ -24,26 +24,32 @@
-
+
-
+
-
+
-
-
+
-
-
+
-
+
+
+
+
+
+
+
+
+
-
+
@@ -1386,6 +1392,13 @@
+
+
+
+
+
+
+
@@ -1418,7 +1431,7 @@
-
+
@@ -1443,6 +1456,9 @@
+
+
+
diff --git a/applications/lazstats/source/LazStats.lpr b/applications/lazstats/source/LazStats.lpr
index 14f2f0966..e0f496add 100644
--- a/applications/lazstats/source/LazStats.lpr
+++ b/applications/lazstats/source/LazStats.lpr
@@ -7,8 +7,8 @@ uses
cthreads,
{$ENDIF}{$ENDIF}
Interfaces, // this includes the LCL widgetset
- Forms, lhelpcontrolpkg,
- Globals, LicenseUnit, OptionsUnit, MainDM, MainUnit, utils;
+ Forms, tachartlazaruspkg, tachartprint, lhelpcontrolpkg,
+ Globals, LicenseUnit, OptionsUnit, MainDM, MainUnit, utils, chartunit;
{$R LazStats.res}
@@ -26,9 +26,8 @@ begin
else
Application.Terminate;
end;
-
- Application.CreateForm(TMainDataModule, MainDataModule);
- Application.CreateForm(TOS3MainFrm, OS3MainFrm);
+Application.CreateForm(TMainDataModule, MainDataModule);
+Application.CreateForm(TOS3MainFrm, OS3MainFrm);
Application.Run;
end.
diff --git a/applications/lazstats/source/forms/misc/chartunit.lfm b/applications/lazstats/source/forms/misc/chartunit.lfm
new file mode 100644
index 000000000..829f20d07
--- /dev/null
+++ b/applications/lazstats/source/forms/misc/chartunit.lfm
@@ -0,0 +1,131 @@
+object ChartForm: TChartForm
+ Left = 299
+ Height = 518
+ Top = 133
+ Width = 860
+ ActiveControl = CloseBtn
+ Caption = 'Plot window'
+ ClientHeight = 518
+ ClientWidth = 860
+ OnCreate = FormCreate
+ LCLVersion = '2.1.0.0'
+ object ButtonBevel: TBevel
+ Left = 0
+ Height = 8
+ Top = 468
+ Width = 860
+ Align = alBottom
+ Shape = bsBottomLine
+ end
+ object ButtonPanel: TPanel
+ Left = 8
+ Height = 26
+ Top = 484
+ Width = 844
+ Align = alBottom
+ AutoSize = True
+ BorderSpacing.Around = 8
+ BevelOuter = bvNone
+ ClientHeight = 26
+ ClientWidth = 844
+ TabOrder = 1
+ object PrintBtn: TButton
+ AnchorSideLeft.Control = ButtonPanel
+ AnchorSideLeft.Side = asrCenter
+ AnchorSideTop.Control = ButtonPanel
+ AnchorSideTop.Side = asrCenter
+ Left = 397
+ Height = 25
+ Top = 1
+ Width = 51
+ AutoSize = True
+ BorderSpacing.Left = 12
+ BorderSpacing.Right = 12
+ Caption = 'Print'
+ OnClick = PrintBtnClick
+ TabOrder = 1
+ end
+ object SaveBtn: TButton
+ AnchorSideTop.Control = ButtonPanel
+ AnchorSideTop.Side = asrCenter
+ AnchorSideRight.Control = PrintBtn
+ Left = 299
+ Height = 25
+ Top = 1
+ Width = 86
+ Anchors = [akTop, akRight]
+ AutoSize = True
+ Caption = 'Save Image'
+ OnClick = SaveBtnClick
+ TabOrder = 0
+ end
+ object CloseBtn: TButton
+ AnchorSideLeft.Control = PrintBtn
+ AnchorSideLeft.Side = asrBottom
+ AnchorSideTop.Control = ButtonPanel
+ AnchorSideTop.Side = asrCenter
+ AnchorSideRight.Side = asrBottom
+ Left = 460
+ Height = 25
+ Top = 1
+ Width = 55
+ AutoSize = True
+ Cancel = True
+ Caption = 'Close'
+ Default = True
+ ModalResult = 11
+ TabOrder = 2
+ end
+ end
+ object Chart: TChart
+ Left = 6
+ Height = 456
+ Top = 6
+ Width = 848
+ AxisList = <
+ item
+ Grid.Color = clSilver
+ Grid.Style = psSolid
+ Grid.Visible = False
+ Marks.LabelBrush.Style = bsClear
+ Minors = <>
+ Title.LabelFont.Orientation = 900
+ Title.LabelFont.Style = [fsBold]
+ Title.LabelBrush.Style = bsClear
+ end
+ item
+ Grid.Color = clSilver
+ Grid.Style = psSolid
+ Grid.Visible = False
+ Alignment = calBottom
+ Marks.LabelBrush.Style = bsClear
+ Minors = <>
+ Title.LabelFont.Style = [fsBold]
+ Title.LabelBrush.Style = bsClear
+ end>
+ BackColor = clWhite
+ Foot.Brush.Color = clBtnFace
+ Foot.Font.Color = clBlue
+ Margins.Left = 8
+ Margins.Top = 8
+ Margins.Right = 8
+ Margins.Bottom = 8
+ Title.Brush.Color = clBtnFace
+ Title.Font.Color = clBlue
+ Title.Font.Style = [fsBold]
+ Title.Text.Strings = (
+ 'TAChart'
+ )
+ Align = alClient
+ BorderSpacing.Around = 6
+ end
+ object SavePictureDialog: TSavePictureDialog
+ Filter = 'Graphic (*.png;*.bmp;*.jpeg;*.jpg;*.jpe;*.jfif;*.svg)|*.png;*.bmp;*.jpeg;*.jpg;*.jpe;*.jfif;*.svg|Portable Network Graphic (*.png)|*.png|Bitmaps (*.bmp)|*.bmp|Joint Picture Expert Group (*.jpeg;*.jpg;*.jpe;*.jfif)|*.jpeg;*.jpg;*.jpe;*.jfif|Scaleable Vector Graphic (*.svg)|*.svg|All Files (*.*)|*.*'
+ Left = 408
+ Top = 136
+ end
+ object PrintDialog: TPrintDialog
+ Left = 408
+ Top = 194
+ end
+end
diff --git a/applications/lazstats/source/forms/misc/chartunit.pas b/applications/lazstats/source/forms/misc/chartunit.pas
new file mode 100644
index 000000000..9edaaf965
--- /dev/null
+++ b/applications/lazstats/source/forms/misc/chartunit.pas
@@ -0,0 +1,243 @@
+unit ChartUnit;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, ExtCtrls,
+ StdCtrls, ExtDlgs, TAGraph, TACustomSeries, TASeries, PrintersDlgs,
+ Globals;
+
+type
+
+ TPlotType = (ptLines, ptSymbols, ptLinesAndSymbols, ptHorBars, ptVertBars,
+ ptArea);
+
+ { TChartForm }
+
+ TChartForm = class(TForm)
+ ButtonBevel: TBevel;
+ Chart: TChart;
+ CloseBtn: TButton;
+ ButtonPanel: TPanel;
+ PrintBtn: TButton;
+ PrintDialog: TPrintDialog;
+ SaveBtn: TButton;
+ SavePictureDialog: TSavePictureDialog;
+ procedure FormCreate(Sender: TObject);
+ procedure PrintBtnClick(Sender: TObject);
+ procedure SaveBtnClick(Sender: TObject);
+ private
+ procedure Constline(xy: Double; ADirection: TLineStyle;
+ AColor: TColor; ALineStyle: TPenStyle; ALegendTitle: String);
+
+ public
+ procedure Clear;
+
+ procedure GetXRange(out XMin, XMax: Double; Logical: Boolean = true);
+ procedure GetYRange(out YMin, YMax: Double; Logical: Boolean = true);
+
+ procedure HorLine(y: Double; AColor: TColor; ALineStyle: TPenStyle; ALegendTitle: String);
+ function PlotXY(AType: TPlotType; x, y: DblDyneVec; LegendTitle: string;
+ AColor: TColor; xTitles: StrDynevec = nil): TChartSeries;
+ procedure Vertline(x: Double; AColor: TColor; ALineStyle: TPenStyle; ALegendTitle: String);
+
+ procedure SetFooter(const ATitle: String);
+ procedure SetTitle(const ATitle: String);
+ procedure SetXTitle(const ATitle: String);
+ procedure SetYTitle(const ATitle: String);
+
+ end;
+
+var
+ ChartForm: TChartForm;
+
+implementation
+
+{$R *.lfm}
+
+uses
+ Math, Printers, //OSPrinters,
+ TAChartUtils, TATypes, TADrawerSVG, TAPrint;
+
+{ TChartForm }
+
+procedure TChartForm.Clear;
+begin
+ Chart.ClearSeries;
+ Chart.Title.Text.Clear;
+ Chart.Foot.Text.Clear;
+ Chart.BottomAxis.Title.Caption := '';
+ Chart.LeftAxis.Title.Caption := '';
+end;
+
+procedure TChartForm.FormCreate(Sender: TObject);
+begin
+ Clear;
+end;
+
+procedure TChartForm.PrintBtnClick(Sender: TObject);
+const
+ MARGIN = 10;
+var
+ R: TRect;
+ d: Integer;
+begin
+ if not PrintDialog.Execute then
+ exit;
+
+ Printer.BeginDoc;
+ try
+ R := Rect(0, 0, Printer.PageWidth, Printer.PageHeight div 2);
+
+ d := R.Right - R.Left;
+ R.Left += d div MARGIN;
+ R.Right -= d div MARGIN;
+
+ d := R.Bottom - R.Top;
+ R.Top += d div MARGIN;
+ R.Bottom -= d div MARGIN;
+
+ Chart.Draw(TPrinterDrawer.Create(Printer, true), R);
+ finally
+ Printer.EndDoc;
+ end;
+end;
+
+procedure TChartForm.GetXRange(out XMin, XMax: Double; Logical: Boolean = true);
+var
+ ext: TDoubleRect;
+begin
+ if Logical then
+ ext := Chart.LogicalExtent
+ else
+ ext := Chart.CurrentExtent;
+ XMin := ext.a.x;
+ XMax := ext.b.x;
+end;
+
+procedure TChartForm.GetYRange(out YMin, YMax: Double; Logical: Boolean = true);
+var
+ ext: TDoubleRect;
+begin
+ if Logical then
+ ext := Chart.LogicalExtent
+ else
+ ext := Chart.CurrentExtent;
+ YMin := ext.a.y;
+ YMax := ext.b.y;
+end;
+
+procedure TChartForm.HorLine(y: Double; AColor: TColor; ALineStyle: TPenStyle;
+ ALegendTitle: String);
+begin
+ ConstLine(y, lsHorizontal, AColor, ALineStyle, ALegendTitle);
+end;
+
+procedure TChartForm.VertLine(x: Double; AColor: TColor; ALineStyle: TPenStyle;
+ ALegendTitle: String);
+begin
+ ConstLine(x, lsVertical, AColor, ALineStyle, ALegendTitle);
+end;
+
+procedure TChartForm.Constline(xy: Double; ADirection: TLineStyle;
+ AColor: TColor; ALineStyle: TPenStyle; ALegendTitle: String);
+var
+ ser: TConstantLine;
+begin
+ ser := TConstantLine.Create(self);
+ ser.Position := xy;
+ ser.LineStyle := ADirection;
+ ser.Pen.Color := AColor;
+ ser.Pen.Style := ALineStyle;
+ ser.Title := ALegendTitle;
+ ser.Legend.Visible := ALegendTitle <> '';
+ Chart.AddSeries(ser);
+end;
+
+function TChartForm.PlotXY(AType: TPlotType; x, y: DblDyneVec;
+ LegendTitle: string; AColor: TColor; xTitles: StrDynevec = nil): TChartSeries;
+var
+ i, n: Integer;
+ s: String;
+begin
+ case AType of
+ ptLines, ptSymbols, ptLinesAndSymbols:
+ begin
+ Result := TLineSeries.Create(self);
+ TLineSeries(Result).ShowPoints := AType in [ptSymbols, ptLinesAndSymbols];
+ TLineSeries(Result).ShowLines := AType in [ptLines, ptLinesAndSymbols];
+ TLineSeries(Result).SeriesColor := AColor;
+ if AType in [ptSymbols, ptLinesAndSymbols] then
+ begin
+ TLineSeries(Result).Pointer.Brush.Color := AColor;
+ TLineSeries(Result).Pointer.Style := psCircle;
+ end;
+ end;
+ ptHorBars, ptVertBars:
+ Result := TBarSeries.Create(self);
+ ptArea:
+ Result := TAreaSeries.Create(self);
+ else
+ raise Exception.Create('Unknown plot type.');
+ end;
+
+ n := Min(Length(x), Length(y));
+ for i := 0 to n-1 do
+ begin
+ if (xTitles <> nil) and (i <= Length(xTitles)) then
+ s := xTitles[i]
+ else
+ s := '';
+ Result.AddXY(x[i], y[i], s);
+ end;
+
+ Result.Title := LegendTitle;
+ Chart.AddSeries(Result);
+ Chart.Legend.Visible := Chart.SeriesCount > 0;
+ Chart.Prepare;
+end;
+
+procedure TChartForm.SaveBtnClick(Sender: TObject);
+var
+ ext: String;
+begin
+ if SavePictureDialog.Execute then
+ begin
+ ext := Lowercase(ExtractFileExt(SavePictureDialog.FileName));
+ case ext of
+ '.bmp': Chart.SaveToFile(TBitmap, SavePictureDialog.Filename);
+ '.png': Chart.SaveToFile(TPortableNetworkGraphic, SavePictureDialog.FileName);
+ '.jpg', '.jpeg', '.jpe', '.jfif': Chart.SaveToFile(TJpegImage, SavePictureDialog.FileName);
+ '.svg': Chart.SaveToSVGFile(SavePictureDialog.FileName);
+ end;
+ end;
+end;
+
+procedure TChartForm.SetFooter(const ATitle: String);
+begin
+ Chart.Foot.Text.Text := ATitle;
+ Chart.Foot.Visible := ATitle <> '';
+end;
+
+procedure TChartForm.SetTitle(const ATitle: String);
+begin
+ Chart.Title.Text.Text := ATitle;
+ Chart.Title.Visible := ATitle <> '';
+end;
+
+procedure TChartForm.SetXTitle(const ATitle: String);
+begin
+ Chart.BottomAxis.Title.Caption := ATitle;
+ Chart.BottomAxis.Title.Visible := ATitle <> '';
+end;
+
+procedure TChartForm.SetYTitle(const ATitle: String);
+begin
+ Chart.LeftAxis.Title.Caption := ATitle;
+ Chart.LeftAxis.Title.Visible := ATitle <> '';
+end;
+
+end.
+