From 32c7dba3c037a799d1baedf31fbe4b807ae82974 Mon Sep 17 00:00:00 2001 From: ask Date: Sun, 17 Oct 2010 02:15:13 +0000 Subject: [PATCH] TAChart: Extract TAFuncSeries unit git-svn-id: trunk@27724 - --- .gitattributes | 1 + components/tachart/demo/axis/axisdemo.lpi | 7 +- components/tachart/demo/axis/main.lfm | 15 -- components/tachart/demo/axis/main.pas | 4 +- components/tachart/demo/func/funcdemo.lpi | 10 +- components/tachart/demo/func/main.lfm | 12 +- components/tachart/demo/func/main.pas | 3 +- components/tachart/tachartlazaruspkg.lpk | 6 +- components/tachart/tachartlazaruspkg.pas | 2 +- components/tachart/tafuncseries.pas | 204 ++++++++++++++++++++++ components/tachart/taseries.pas | 166 ------------------ 11 files changed, 227 insertions(+), 203 deletions(-) create mode 100644 components/tachart/tafuncseries.pas diff --git a/.gitattributes b/.gitattributes index fb48410800..161a8d5e4c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2283,6 +2283,7 @@ components/tachart/tachartutils.pas svneol=native#text/plain components/tachart/tacustomseries.pas svneol=native#text/plain components/tachart/tadbsource.pas svneol=native#text/pascal components/tachart/tadrawutils.pas svneol=native#text/pascal +components/tachart/tafuncseries.pas svneol=native#text/pascal components/tachart/tagraph.lrs svneol=native#text/pascal components/tachart/tagraph.pas svneol=native#text/plain components/tachart/talegend.pas svneol=native#text/plain diff --git a/components/tachart/demo/axis/axisdemo.lpi b/components/tachart/demo/axis/axisdemo.lpi index d333c09ca7..45dced8e89 100644 --- a/components/tachart/demo/axis/axisdemo.lpi +++ b/components/tachart/demo/axis/axisdemo.lpi @@ -1,8 +1,8 @@ + - @@ -10,12 +10,11 @@ - <ResourceType Value="res"/> </General> <VersionInfo> - <StringTable Comments="" CompanyName="" FileDescription="" FileVersion="0.0.0.0" InternalName="" LegalCopyright="" LegalTrademarks="" OriginalFilename="" ProductName="" ProductVersion=""/> + <StringTable ProductVersion=""/> </VersionInfo> <PublishOptions> <Version Value="2"/> @@ -57,7 +56,7 @@ <Version Value="9"/> <PathDelim Value="\"/> <SearchPaths> - <IncludeFiles Value="$(ProjOutDir)\"/> + <IncludeFiles Value="$(ProjOutDir)"/> <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> </SearchPaths> <Parsing> diff --git a/components/tachart/demo/axis/main.lfm b/components/tachart/demo/axis/main.lfm index 7793d1fcf5..732a102bcd 100644 --- a/components/tachart/demo/axis/main.lfm +++ b/components/tachart/demo/axis/main.lfm @@ -37,8 +37,6 @@ object Form1: TForm1 Title.LabelFont.Orientation = 900 Title.Visible = True Title.Caption = 'Summer temperature, °C' - Title.Font.Color = clRed - Title.Font.Orientation = 900 Transformations = catTAuto end item @@ -57,8 +55,6 @@ object Form1: TForm1 Title.LabelFont.Orientation = 900 Title.Visible = True Title.Caption = 'Winter temperature, °F' - Title.Font.Color = clBlue - Title.Font.Orientation = 900 Transformations = catT end> Foot.Brush.Color = clBtnFace @@ -75,21 +71,18 @@ object Form1: TForm1 AxisIndexY = 0 LinePen.Color = clRed LinePen.Width = 2 - SeriesColor = clRed Source = rcsTSummer end object ChartTWinterLine: TLineSeries AxisIndexY = 2 LinePen.Color = clBlue LinePen.Width = 2 - SeriesColor = clBlue Source = rcsTWinter end object ChartTWinterBar: TBarSeries AxisIndexY = 2 BarBrush.Color = clBlue BarBrush.Style = bsDiagCross - SeriesColor = clBlue Source = rcsTWinter end end @@ -127,7 +120,6 @@ object Form1: TForm1 Title.LabelFont.Orientation = 900 Title.Visible = True Title.Caption = 'Left' - Title.Font.Orientation = 900 Transformations = catLog end item @@ -142,7 +134,6 @@ object Form1: TForm1 Title.LabelFont.Orientation = 900 Title.Visible = True Title.Caption = 'Right 1' - Title.Font.Orientation = 900 end item Alignment = calTop @@ -162,7 +153,6 @@ object Form1: TForm1 AxisIndexY = 0 LineType = ltNone Pointer.Brush.Color = clMaroon - SeriesColor = clBlack ShowPoints = True end object cfsLog: TFuncSeries @@ -215,7 +205,6 @@ object Form1: TForm1 Marks.Source = lcsMarks Marks.Style = smsCustom Title.LabelFont.Orientation = 900 - Title.Font.Orientation = 900 end item Alignment = calBottom @@ -242,7 +231,6 @@ object Form1: TForm1 BarBrush.Color = clGreen BarPen.Color = clLime BarPen.Width = 2 - SeriesColor = clGreen Source = lcsMarks end end @@ -262,7 +250,6 @@ object Form1: TForm1 Group = 2 TickLength = 0 Title.LabelFont.Orientation = 900 - Title.Font.Orientation = 900 end item Alignment = calBottom @@ -290,7 +277,6 @@ object Form1: TForm1 AxisList = < item Title.LabelFont.Orientation = 900 - Title.Font.Orientation = 900 end item Alignment = calBottom @@ -312,7 +298,6 @@ object Form1: TForm1 Align = alClient ParentColor = False object ChartDateTimeLineSeries1: TLineSeries - SeriesColor = clBlack Source = rcsDates end end diff --git a/components/tachart/demo/axis/main.pas b/components/tachart/demo/axis/main.pas index 89b7eb8c4b..02749c07e0 100644 --- a/components/tachart/demo/axis/main.pas +++ b/components/tachart/demo/axis/main.pas @@ -5,8 +5,8 @@ unit Main; interface uses - ComCtrls, ExtCtrls, Forms, StdCtrls, TAGraph, TASeries, TASources, - TATools, TATransformations; + ComCtrls, ExtCtrls, Forms, StdCtrls, TAFuncSeries, TAGraph, TASeries, + TASources, TATools, TATransformations; type diff --git a/components/tachart/demo/func/funcdemo.lpi b/components/tachart/demo/func/funcdemo.lpi index 9fc1173018..258770cf80 100644 --- a/components/tachart/demo/func/funcdemo.lpi +++ b/components/tachart/demo/func/funcdemo.lpi @@ -1,21 +1,23 @@ <?xml version="1.0"?> <CONFIG> <ProjectOptions> + <Version Value="9"/> <PathDelim Value="\"/> - <Version Value="8"/> <General> <Flags> <LRSInOutputDirectory Value="False"/> </Flags> <SessionStorage Value="InProjectDir"/> <MainUnit Value="0"/> - <TargetFileExt Value=".exe"/> <Title Value="TAChart function series demo"/> <ResourceType Value="res"/> </General> <VersionInfo> - <StringTable Comments="" CompanyName="" FileDescription="" FileVersion="0.0.0.0" InternalName="" LegalCopyright="" LegalTrademarks="" OriginalFilename="" ProductName="" ProductVersion=""/> + <StringTable ProductVersion=""/> </VersionInfo> + <BuildModes Count="1"> + <Item1 Name="default" Default="True"/> + </BuildModes> <PublishOptions> <Version Value="2"/> <IgnoreBinaries Value="False"/> @@ -56,7 +58,7 @@ <Version Value="9"/> <PathDelim Value="\"/> <SearchPaths> - <IncludeFiles Value="$(ProjOutDir)\"/> + <IncludeFiles Value="$(ProjOutDir)"/> <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> </SearchPaths> <Parsing> diff --git a/components/tachart/demo/func/main.lfm b/components/tachart/demo/func/main.lfm index c5963a2268..16a0b4c80c 100644 --- a/components/tachart/demo/func/main.lfm +++ b/components/tachart/demo/func/main.lfm @@ -15,15 +15,10 @@ object Form1: TForm1 Width = 461 AxisList = < item - Alignment = calLeft - Title.Font.Orientation = 900 - Transformation.Offset = 0 - Transformation.Scale = 1 + Title.LabelFont.Orientation = 900 end item Alignment = calBottom - Transformation.Offset = 0 - Transformation.Scale = 1 end> ExpandPercentage = 10 Extent.YMin = -6 @@ -52,20 +47,19 @@ object Form1: TForm1 Title = '1 / Sin(x)' end object Chart1XAxis: TConstantLine + Legend.Visible = False Position = 0 SeriesColor = clBlack - ShowInLegend = False end object Chart1YAxis: TConstantLine + Legend.Visible = False LineStyle = lsVertical Position = 0 SeriesColor = clBlack - ShowInLegend = False end object Chart1BarSeries1: TBarSeries Title = 'Cos(x)' BarBrush.Color = clMoneyGreen - SeriesColor = clMoneyGreen Source = UserDefinedChartSource1 end object Chart1UserDrawnSeries1: TUserDrawnSeries diff --git a/components/tachart/demo/func/main.pas b/components/tachart/demo/func/main.pas index 92e88e6ae1..bcda912fb1 100644 --- a/components/tachart/demo/func/main.pas +++ b/components/tachart/demo/func/main.pas @@ -5,7 +5,8 @@ unit main; interface uses - Classes, StdCtrls, Forms, Graphics, TAGraph, TASeries, TASources; + Classes, StdCtrls, Forms, Graphics, TAFuncSeries, TAGraph, TASeries, + TASources; type diff --git a/components/tachart/tachartlazaruspkg.lpk b/components/tachart/tachartlazaruspkg.lpk index 147c44081c..b6678b2ff8 100644 --- a/components/tachart/tachartlazaruspkg.lpk +++ b/components/tachart/tachartlazaruspkg.lpk @@ -25,7 +25,7 @@ for details about the copyright. "/> <Version Major="1"/> - <Files Count="16"> + <Files Count="17"> <Item1> <Filename Value="tachartaxis.pas"/> <UnitName Value="TAChartAxis"/> @@ -97,6 +97,10 @@ <HasRegisterProc Value="True"/> <UnitName Value="TAStyles"/> </Item16> + <Item17> + <Filename Value="tafuncseries.pas"/> + <UnitName Value="TAFuncSeries"/> + </Item17> </Files> <LazDoc Paths="$(LazarusDir)\components\tachart\fpdoc\"/> <Type Value="RunAndDesignTime"/> diff --git a/components/tachart/tachartlazaruspkg.pas b/components/tachart/tachartlazaruspkg.pas index 395f70d3f9..d1aa0b3d0c 100644 --- a/components/tachart/tachartlazaruspkg.pas +++ b/components/tachart/tachartlazaruspkg.pas @@ -10,7 +10,7 @@ uses TAChartAxis, TAChartUtils, TACustomSeries, TADbSource, TAGraph, TASeries, TASeriesEditor, TASources, TASubcomponentsEditor, TATools, TATransformations, TATypes, TADrawUtils, TAMultiSeries, TALegend, TAStyles, - LazarusPackageIntf; + TAFuncSeries, LazarusPackageIntf; implementation diff --git a/components/tachart/tafuncseries.pas b/components/tachart/tafuncseries.pas new file mode 100644 index 0000000000..765a4c7e01 --- /dev/null +++ b/components/tachart/tafuncseries.pas @@ -0,0 +1,204 @@ +{ + + Function series for TAChart. + + ***************************************************************************** + * * + * See the file COPYING.modifiedLGPL.txt, included in this distribution, * + * for details about the copyright. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * * + ***************************************************************************** + + Authors: Alexander Klenin + +} +unit TAFuncSeries; + +{$H+} + +interface + +uses + Classes, Graphics, + TAChartUtils, TACustomSeries, TALegend, TATypes; + +type + TFuncCalculateEvent = procedure (const AX: Double; out AY: Double) of object; + + TFuncSeriesStep = 1..MaxInt; + + { TFuncSeries } + + TFuncSeries = class(TCustomChartSeries) + private + FDomainExclusions: TIntervalList; + FExtent: TChartExtent; + FOnCalculate: TFuncCalculateEvent; + FPen: TChartPen; + FStep: TFuncSeriesStep; + + procedure SetExtent(const AValue: TChartExtent); + procedure SetOnCalculate(const AValue: TFuncCalculateEvent); + procedure SetPen(const AValue: TChartPen); + procedure SetStep(AValue: TFuncSeriesStep); + protected + procedure GetBounds(var ABounds: TDoubleRect); override; + procedure GetLegendItems(AItems: TChartLegendItems); override; + + public + constructor Create(AOwner: TComponent); override; + destructor Destroy; override; + + procedure Draw(ACanvas: TCanvas); override; + function IsEmpty: Boolean; override; + public + property DomainExclusions: TIntervalList read FDomainExclusions; + published + property Active default true; + property AxisIndexY; + property Extent: TChartExtent read FExtent write SetExtent; + property OnCalculate: TFuncCalculateEvent read FOnCalculate write SetOnCalculate; + property Pen: TChartPen read FPen write SetPen; + property ShowInLegend; + property Step: TFuncSeriesStep read FStep write SetStep default 2; + property Title; + property ZPosition; + end; + +implementation + +uses + Math, SysUtils, TAGraph; + +{ TFuncSeries } + +constructor TFuncSeries.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + FExtent := TChartExtent.Create(FChart); + FDomainExclusions := TIntervalList.Create; + FDomainExclusions.OnChange := @StyleChanged; + FPen := TChartPen.Create; + FPen.OnChange := @StyleChanged; + FStep := 2; +end; + +destructor TFuncSeries.Destroy; +begin + FreeAndNil(FExtent); + FreeAndNil(FDomainExclusions); + FreeAndNil(FPen); + inherited; +end; + +procedure TFuncSeries.Draw(ACanvas: TCanvas); +var + ygMin, ygMax: Double; + + function CalcY(AXg: Double): Integer; + var + yg: Double; + begin + OnCalculate(AXg, yg); + Result := FChart.YGraphToImage(EnsureRange(AxisToGraphY(yg), ygMin, ygMax)); + end; + +var + x, xmax, hint: Integer; + xg, xg1: Double; +begin + if not Assigned(OnCalculate) then exit; + + x := FChart.ClipRect.Left; + if Extent.UseXMin then + x := Max(FChart.XGraphToImage(Extent.XMin), x); + xmax := FChart.ClipRect.Right; + if Extent.UseXMax then + xmax := Min(FChart.XGraphToImage(Extent.XMax), xmax); + + ygMin := FChart.CurrentExtent.a.Y; + if Extent.UseYMin and (ygMin < Extent.YMin) then + ygMin := Extent.YMin; + ygMax := FChart.CurrentExtent.b.Y; + if Extent.UseYMax and (ygMax < Extent.YMax) then + ygMax := Extent.YMax; + ExpandRange(ygMin, ygMax, 1); + + hint := 0; + xg := FChart.XImageToGraph(x); + if DomainExclusions.Intersect(xg, xg, hint) then + x := FChart.XGraphToImage(xg); + ACanvas.MoveTo(x, CalcY(xg)); + + ACanvas.Pen.Assign(Pen); + while x < xmax do begin + Inc(x, FStep); + xg1 := FChart.XImageToGraph(x); + if DomainExclusions.Intersect(xg, xg1, hint) then begin + ACanvas.LineTo(FChart.XGraphToImage(xg), CalcY(xg)); + x := FChart.XGraphToImage(xg1); + ACanvas.MoveTo(x, CalcY(xg1)); + end + else + ACanvas.LineTo(x, CalcY(xg1)); + xg := xg1; + end; +end; + +procedure TFuncSeries.GetBounds(var ABounds: TDoubleRect); +begin + with Extent do begin + if UseXMin then ABounds.a.X := XMin; + if UseYMin then ABounds.a.Y := YMin; + if UseXMax then ABounds.b.X := XMax; + if UseYMax then ABounds.b.Y := YMax; + end; +end; + +procedure TFuncSeries.GetLegendItems(AItems: TChartLegendItems); +begin + AItems.Add(TLegendItemLine.Create(Pen, Title)); +end; + +function TFuncSeries.IsEmpty: Boolean; +begin + Result := not Assigned(OnCalculate); +end; + +procedure TFuncSeries.SetExtent(const AValue: TChartExtent); +begin + if FExtent = AValue then exit; + FExtent.Assign(AValue); + UpdateParentChart; +end; + +procedure TFuncSeries.SetOnCalculate(const AValue: TFuncCalculateEvent); +begin + if TMethod(FOnCalculate) = TMethod(AValue) then exit; + FOnCalculate := AValue; + UpdateParentChart; +end; + +procedure TFuncSeries.SetPen(const AValue: TChartPen); +begin + if FPen = AValue then exit; + FPen.Assign(AValue); + UpdateParentChart; +end; + +procedure TFuncSeries.SetStep(AValue: TFuncSeriesStep); +begin + if FStep = AValue then exit; + FStep := AValue; + UpdateParentChart; +end; + +initialization + RegisterSeriesClass(TFuncSeries, 'Function series'); + +end. + diff --git a/components/tachart/taseries.pas b/components/tachart/taseries.pas index 0fb9864ad4..c1da2cd693 100644 --- a/components/tachart/taseries.pas +++ b/components/tachart/taseries.pas @@ -267,48 +267,6 @@ type // Use TConstantLine instead. TLine = class(TConstantLine) end deprecated; - TFuncCalculateEvent = procedure (const AX: Double; out AY: Double) of object; - - TFuncSeriesStep = 1..MaxInt; - - { TFuncSeries } - - TFuncSeries = class(TCustomChartSeries) - private - FDomainExclusions: TIntervalList; - FExtent: TChartExtent; - FOnCalculate: TFuncCalculateEvent; - FPen: TChartPen; - FStep: TFuncSeriesStep; - - procedure SetExtent(const AValue: TChartExtent); - procedure SetOnCalculate(const AValue: TFuncCalculateEvent); - procedure SetPen(const AValue: TChartPen); - procedure SetStep(AValue: TFuncSeriesStep); - protected - procedure GetBounds(var ABounds: TDoubleRect); override; - procedure GetLegendItems(AItems: TChartLegendItems); override; - - public - constructor Create(AOwner: TComponent); override; - destructor Destroy; override; - - procedure Draw(ACanvas: TCanvas); override; - function IsEmpty: Boolean; override; - public - property DomainExclusions: TIntervalList read FDomainExclusions; - published - property Active default true; - property AxisIndexY; - property Extent: TChartExtent read FExtent write SetExtent; - property OnCalculate: TFuncCalculateEvent read FOnCalculate write SetOnCalculate; - property Pen: TChartPen read FPen write SetPen; - property ShowInLegend; - property Step: TFuncSeriesStep read FStep write SetStep default 2; - property Title; - property ZPosition; - end; - TSeriesDrawEvent = procedure (ACanvas: TCanvas; const ARect: TRect) of object; TSeriesGetBoundsEvent = procedure (var ABounds: TDoubleRect) of object; @@ -1231,129 +1189,6 @@ begin UpdateParentChart; end; -{ TFuncSeries } - -constructor TFuncSeries.Create(AOwner: TComponent); -begin - inherited Create(AOwner); - FExtent := TChartExtent.Create(FChart); - FDomainExclusions := TIntervalList.Create; - FDomainExclusions.OnChange := @StyleChanged; - FPen := TChartPen.Create; - FPen.OnChange := @StyleChanged; - FStep := 2; -end; - -destructor TFuncSeries.Destroy; -begin - FreeAndNil(FExtent); - FreeAndNil(FDomainExclusions); - FreeAndNil(FPen); - inherited; -end; - -procedure TFuncSeries.Draw(ACanvas: TCanvas); -var - ygMin, ygMax: Double; - - function CalcY(AXg: Double): Integer; - var - yg: Double; - begin - OnCalculate(AXg, yg); - Result := FChart.YGraphToImage(EnsureRange(AxisToGraphY(yg), ygMin, ygMax)); - end; - -var - x, xmax, hint: Integer; - xg, xg1: Double; -begin - if not Assigned(OnCalculate) then exit; - - x := FChart.ClipRect.Left; - if Extent.UseXMin then - x := Max(FChart.XGraphToImage(Extent.XMin), x); - xmax := FChart.ClipRect.Right; - if Extent.UseXMax then - xmax := Min(FChart.XGraphToImage(Extent.XMax), xmax); - - ygMin := FChart.CurrentExtent.a.Y; - if Extent.UseYMin and (ygMin < Extent.YMin) then - ygMin := Extent.YMin; - ygMax := FChart.CurrentExtent.b.Y; - if Extent.UseYMax and (ygMax < Extent.YMax) then - ygMax := Extent.YMax; - ExpandRange(ygMin, ygMax, 1); - - hint := 0; - xg := FChart.XImageToGraph(x); - if DomainExclusions.Intersect(xg, xg, hint) then - x := FChart.XGraphToImage(xg); - ACanvas.MoveTo(x, CalcY(xg)); - - ACanvas.Pen.Assign(Pen); - while x < xmax do begin - Inc(x, FStep); - xg1 := FChart.XImageToGraph(x); - if DomainExclusions.Intersect(xg, xg1, hint) then begin - ACanvas.LineTo(FChart.XGraphToImage(xg), CalcY(xg)); - x := FChart.XGraphToImage(xg1); - ACanvas.MoveTo(x, CalcY(xg1)); - end - else - ACanvas.LineTo(x, CalcY(xg1)); - xg := xg1; - end; -end; - -procedure TFuncSeries.GetBounds(var ABounds: TDoubleRect); -begin - with Extent do begin - if UseXMin then ABounds.a.X := XMin; - if UseYMin then ABounds.a.Y := YMin; - if UseXMax then ABounds.b.X := XMax; - if UseYMax then ABounds.b.Y := YMax; - end; -end; - -procedure TFuncSeries.GetLegendItems(AItems: TChartLegendItems); -begin - AItems.Add(TLegendItemLine.Create(Pen, Title)); -end; - -function TFuncSeries.IsEmpty: Boolean; -begin - Result := not Assigned(OnCalculate); -end; - -procedure TFuncSeries.SetExtent(const AValue: TChartExtent); -begin - if FExtent = AValue then exit; - FExtent.Assign(AValue); - UpdateParentChart; -end; - -procedure TFuncSeries.SetOnCalculate(const AValue: TFuncCalculateEvent); -begin - if TMethod(FOnCalculate) = TMethod(AValue) then exit; - FOnCalculate := AValue; - UpdateParentChart; -end; - -procedure TFuncSeries.SetPen(const AValue: TChartPen); -begin - if FPen = AValue then exit; - FPen.Assign(AValue); - UpdateParentChart; -end; - -procedure TFuncSeries.SetStep(AValue: TFuncSeriesStep); -begin - if FStep = AValue then exit; - FStep := AValue; - UpdateParentChart; -end; - { TUserDrawnSeries } procedure TUserDrawnSeries.Draw(ACanvas: TCanvas); @@ -1407,7 +1242,6 @@ initialization RegisterSeriesClass(TAreaSeries, 'Area series'); RegisterSeriesClass(TBarSeries, 'Bar series'); RegisterSeriesClass(TPieSeries, 'Pie series'); - RegisterSeriesClass(TFuncSeries, 'Function series'); RegisterSeriesClass(TUserDrawnSeries, 'User-drawn series'); RegisterSeriesClass(TConstantLine, 'Constant line'); {$WARNINGS OFF}RegisterSeriesClass(TLine, '');{$WARNINGS ON}