TAChart: Initial implementation of polar series

git-svn-id: trunk@29102 -
This commit is contained in:
ask 2011-01-18 09:02:33 +00:00
parent 21453ac232
commit 2572b49221
2 changed files with 142 additions and 2 deletions

View File

@ -130,6 +130,7 @@ type
function GetGraphPointY(AIndex: Integer): Double; inline;
function GetSeriesColor: TColor; virtual;
function GetXMaxVal: Integer;
procedure SourceChanged(ASender: TObject); virtual;
procedure VisitSources(
AVisitor: TChartOnSourceVisitor; AAxis: TChartAxis; var AData); override;
protected
@ -495,7 +496,7 @@ const
begin
inherited Create(AOwner);
FListener := TListener.Create(@FSource, @StyleChanged);
FListener := TListener.Create(@FSource, @SourceChanged);
FBuiltinSource := TListChartSource.Create(Self);
FBuiltinSource.Name := BUILTIN_SOURCE_NAME;
FBuiltinSource.Broadcaster.Subscribe(FListener);
@ -697,6 +698,11 @@ begin
ListSource.SetYValue(AIndex, AValue);
end;
procedure TChartSeries.SourceChanged(ASender: TObject);
begin
StyleChanged(ASender);
end;
procedure TChartSeries.VisitSources(
AVisitor: TChartOnSourceVisitor; AAxis: TChartAxis; var AData);
begin

View File

@ -68,6 +68,40 @@ type
read FFixedRadius write SetFixedRadius default 0;
property RotateLabels: Boolean
read FRotateLabels write SetRotateLabels default false;
end;
TSinCos = record
FSin, FCos: Double;
end;
{ TPolarSeries }
TPolarSeries = class(TChartSeries)
private
FLinePen: TPen;
FOriginX: Double;
FOriginY: Double;
function IsOriginXStored: Boolean;
function IsOriginYStored: Boolean;
procedure SetLinePen(AValue: TPen);
procedure SetOriginX(AValue: Double);
procedure SetOriginY(AValue: Double);
private
FAngleCache: array of TSinCos;
function GraphPoint(AIndex: Integer): TDoublePoint;
procedure PrepareAngleCache;
protected
procedure SourceChanged(ASender: TObject); override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
public
procedure Draw(ACanvas: TCanvas); override;
function Extent: TDoubleRect; override;
published
property LinePen: TPen read FLinePen write SetLinePen;
property OriginX: Double read FOriginX write SetOriginX stored IsOriginXStored;
property OriginY: Double read FOriginY write SetOriginY stored IsOriginYStored;
property Source;
end;
@ -75,7 +109,7 @@ implementation
uses
Math,
TADrawUtils, TACustomSource;
TACustomSource, TADrawUtils, TAGraph;
{ TCustomPieSeries }
@ -312,5 +346,105 @@ begin
InflateRect(Result, MARGIN, MARGIN);
end;
{ TPolarSeries }
constructor TPolarSeries.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FLinePen := TPen.Create;
FLinePen.OnChange := @StyleChanged;
end;
destructor TPolarSeries.Destroy;
begin
FreeAndNil(FLinePen);
inherited;
end;
procedure TPolarSeries.Draw(ACanvas: TCanvas);
var
i: Integer;
pts: TPointArray;
begin
PrepareAngleCache;
SetLength(pts, Count);
for i := 0 to Count - 1 do
pts[i] := FChart.GraphToImage(GraphPoint(i));
ACanvas.Pen := LinePen;
ACanvas.Brush.Style := bsClear;
ACanvas.Polygon(pts);
end;
function TPolarSeries.Extent: TDoubleRect;
var
i: Integer;
begin
PrepareAngleCache;
Result := EmptyExtent;
for i := 0 to Count - 1 do
ExpandRect(Result, GraphPoint(i));
end;
function TPolarSeries.GraphPoint(AIndex: Integer): TDoublePoint;
begin
with Source[AIndex]^, FAngleCache[AIndex] do
Result := DoublePoint(Y * FCos + OriginX, Y * FSin + OriginY);
end;
function TPolarSeries.IsOriginXStored: Boolean;
begin
Result := OriginX <> 0;
end;
function TPolarSeries.IsOriginYStored: Boolean;
begin
Result := OriginY <> 0;
end;
procedure TPolarSeries.PrepareAngleCache;
var
i: Integer;
s, c: Extended;
begin
if Length(FAngleCache) = Count then exit;
SetLength(FAngleCache, Count);
for i := 0 to Count - 1 do begin
SinCos(Source[i]^.X, s, c);
FAngleCache[i].FSin := s;
FAngleCache[i].FCos := c;
end;
end;
procedure TPolarSeries.SetLinePen(AValue: TPen);
begin
if FLinePen = AValue then exit;
FLinePen := AValue;
end;
procedure TPolarSeries.SetOriginX(AValue: Double);
begin
if FOriginX = AValue then exit;
FOriginX := AValue;
UpdateParentChart;
end;
procedure TPolarSeries.SetOriginY(AValue: Double);
begin
if FOriginY = AValue then exit;
FOriginY := AValue;
UpdateParentChart;
end;
procedure TPolarSeries.SourceChanged(ASender: TObject);
begin
FAngleCache := nil;
inherited;
end;
initialization
RegisterSeriesClass(TPolarSeries, 'Polar series');
end.