TAChart: Extract TAFuncSeries unit

git-svn-id: trunk@27724 -
This commit is contained in:
ask 2010-10-17 02:15:13 +00:00
parent 7575f7e21e
commit 32c7dba3c0
11 changed files with 227 additions and 203 deletions

1
.gitattributes vendored
View File

@ -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

View File

@ -1,8 +1,8 @@
<?xml version="1.0"?>
<CONFIG>
<ProjectOptions>
<Version Value="9"/>
<PathDelim Value="\"/>
<Version Value="8"/>
<General>
<Flags>
<SaveClosedFiles Value="False"/>
@ -10,12 +10,11 @@
</Flags>
<SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/>
<TargetFileExt Value=".exe"/>
<Title Value="TAChart axis demo"/>
<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>

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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

View File

@ -5,7 +5,8 @@ unit main;
interface
uses
Classes, StdCtrls, Forms, Graphics, TAGraph, TASeries, TASources;
Classes, StdCtrls, Forms, Graphics, TAFuncSeries, TAGraph, TASeries,
TASources;
type

View File

@ -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"/>

View File

@ -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

View File

@ -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.

View File

@ -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}