TAChart: Initial commit of new TPolygonSeries

git-svn-id: trunk@64244 -
This commit is contained in:
wp 2020-12-19 23:08:11 +00:00
parent fa5199045e
commit 48dfae77e3
17 changed files with 261 additions and 4 deletions

1
.gitattributes vendored
View File

@ -5432,6 +5432,7 @@ components/tachart/talegendpanel.pas svneol=native#text/pascal
components/tachart/tamath.pas svneol=native#text/pascal
components/tachart/tamultiseries.pas svneol=native#text/pascal
components/tachart/tanavigation.pas svneol=native#text/pascal
components/tachart/tapolygonseries.pas svneol=native#text/pascal
components/tachart/taradialseries.pas svneol=native#text/pascal
components/tachart/taseries.pas svneol=native#text/plain
components/tachart/tasources.pas svneol=native#text/pascal

View File

@ -10,7 +10,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: de\n"
"X-Generator: Poedit 2.2\n"
"X-Generator: Poedit 2.4.2\n"
"X-Poedit-SourceCharset: UTF-8\n"
#: tachartstrconsts.descolor
@ -422,6 +422,10 @@ msgstr "Punkt"
msgid "Polar series"
msgstr "Polar-Diagramm"
#: tachartstrconsts.rspolygonseries
msgid "Polygon series"
msgstr "Polygon-Diagramm"
#: tachartstrconsts.rspsclear
msgctxt "tachartstrconsts.rspsclear"
msgid "no line"
@ -548,4 +552,3 @@ msgstr "Fehler beim Umbenennen von Komponenten: %s"
#: tachartstrconsts.tastoolseditortitle
msgid "Edit tools"
msgstr "Werkzeuge bearbeiten"

View File

@ -410,6 +410,10 @@ msgstr ""
msgid "Polar series"
msgstr "Napakuvaaja"
#: tachartstrconsts.rspolygonseries
msgid "Polygon series"
msgstr ""
#: tachartstrconsts.rspsclear
msgctxt "tachartstrconsts.rspsclear"
msgid "no line"

View File

@ -420,6 +420,10 @@ msgstr "Point"
msgid "Polar series"
msgstr "Séries polaires"
#: tachartstrconsts.rspolygonseries
msgid "Polygon series"
msgstr ""
#: tachartstrconsts.rspsclear
msgctxt "tachartstrconsts.rspsclear"
msgid "no line"

View File

@ -420,6 +420,10 @@ msgstr "Pont"
msgid "Polar series"
msgstr "Polár"
#: tachartstrconsts.rspolygonseries
msgid "Polygon series"
msgstr ""
#: tachartstrconsts.rspsclear
msgctxt "tachartstrconsts.rspsclear"
msgid "no line"

View File

@ -421,6 +421,10 @@ msgstr "Taškas"
msgid "Polar series"
msgstr "Polinės sekos"
#: tachartstrconsts.rspolygonseries
msgid "Polygon series"
msgstr ""
#: tachartstrconsts.rspsclear
msgctxt "tachartstrconsts.rspsclear"
msgid "no line"

View File

@ -420,6 +420,10 @@ msgstr ""
msgid "Polar series"
msgstr ""
#: tachartstrconsts.rspolygonseries
msgid "Polygon series"
msgstr ""
#: tachartstrconsts.rspsclear
msgid "no line"
msgstr ""

View File

@ -410,6 +410,10 @@ msgstr ""
msgid "Polar series"
msgstr ""
#: tachartstrconsts.rspolygonseries
msgid "Polygon series"
msgstr ""
#: tachartstrconsts.rspsclear
msgctxt "tachartstrconsts.rspsclear"
msgid "no line"

View File

@ -420,6 +420,10 @@ msgstr "Ponto"
msgid "Polar series"
msgstr "Série Polar"
#: tachartstrconsts.rspolygonseries
msgid "Polygon series"
msgstr ""
#: tachartstrconsts.rspsclear
msgctxt "tachartstrconsts.rspsclear"
msgid "no line"

View File

@ -420,6 +420,10 @@ msgstr "Точка"
msgid "Polar series"
msgstr "Лепестковая диаграмма"
#: tachartstrconsts.rspolygonseries
msgid "Polygon series"
msgstr ""
#: tachartstrconsts.rspsclear
msgctxt "tachartstrconsts.rspsclear"
msgid "no line"

View File

@ -423,6 +423,10 @@ msgstr ""
msgid "Polar series"
msgstr "Polardiagram"
#: tachartstrconsts.rspolygonseries
msgid "Polygon series"
msgstr ""
#: tachartstrconsts.rspsclear
msgctxt "tachartstrconsts.rspsclear"
msgid "no line"

View File

@ -423,6 +423,10 @@ msgstr "Точка"
msgid "Polar series"
msgstr "Пелюсткова діаграма"
#: tachartstrconsts.rspolygonseries
msgid "Polygon series"
msgstr ""
#: tachartstrconsts.rspsclear
msgctxt "tachartstrconsts.rspsclear"
msgid "no line"

View File

@ -421,6 +421,10 @@ msgstr "点"
msgid "Polar series"
msgstr "极线系列(Polar)"
#: tachartstrconsts.rspolygonseries
msgid "Polygon series"
msgstr ""
#: tachartstrconsts.rspsclear
msgctxt "tachartstrconsts.rspsclear"
msgid "no line"

View File

@ -30,7 +30,7 @@
for details about the copyright.
"/>
<Version Major="1"/>
<Files Count="54">
<Files Count="55">
<Item1>
<Filename Value="tagraph.pas"/>
<HasRegisterProc Value="True"/>
@ -266,6 +266,10 @@
<Filename Value="tadatapointseditor.pas"/>
<UnitName Value="TADataPointsEditor"/>
</Item54>
<Item55>
<Filename Value="tapolygonseries.pas"/>
<UnitName Value="TAPolygonSeries"/>
</Item55>
</Files>
<CompatibilityMode Value="True"/>
<LazDoc Paths="$(LazarusDir)\components\tachart\fpdoc"/>

View File

@ -19,7 +19,7 @@ uses
TACustomFuncSeries, TAFitUtils, TAGUIConnector, TADiagram, TADiagramDrawing,
TADiagramLayout, TAChartStrConsts, TAChartCombos, TAHtml, TAFonts,
TAExpressionSeries, TAFitLib, TASourcePropEditors, TADataPointsEditor,
LazarusPackageIntf;
TAPolygonSeries, LazarusPackageIntf;
implementation

View File

@ -26,6 +26,7 @@ resourcestring
rsUserDrawnSeries = 'User-drawn series';
rsExpressionSeries = 'Math expression series';
rsExpressionColorMapSeries = 'Math expression color map series';
rsPolygonSeries = 'Polygon series';
// Series editor
sesSeriesEditorTitle = 'Edit series';

View File

@ -0,0 +1,204 @@
unit TAPolygonSeries;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Graphics,
TAChartUtils, TADrawUtils, TACustomSeries;
type
TPolygonSeries = class(TBasicPointSeries)
private
FBrush: TBrush;
FPen: TPen;
FPoints: array of TPoint;
FStart: array of Integer;
procedure SetBrush(AValue: TBrush);
procedure SetPen(AValue: TPen);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Draw(ADrawer: IChartDrawer); override;
function GetNearestPoint(const AParams: TNearestPointParams;
out AResults: TNearestPointResults): Boolean; override;
published
property Brush: TBrush read FBrush write SetBrush;
property Pen: TPen read FPen write SetPen;
property ToolTargets default [nptPoint, nptCustom];
// inherited
property AxisIndexX;
property AxisIndexY;
property Source;
end;
implementation
uses
TAChartStrConsts, TAGeometry, TAGraph;
constructor TPolygonSeries.Create(AOwner: TComponent);
begin
inherited;
ToolTargets := [nptPoint, nptCustom];
FPen := TPen.Create;
FPen.OnChange := @StyleChanged;
FBrush := TBrush.Create;
FBrush.OnChange := @StyleChanged;
end;
destructor TPolygonSeries.Destroy;
begin
FPoints := nil;
FStart := nil;
FPen.Free;
FBrush.Free;
inherited;
end;
procedure TPolygonSeries.Draw(ADrawer: IChartDrawer);
const
START_BLOCKSIZE = 100;
var
ext: TDoubleRect;
ap, apStart: TDoublePoint; // axis units
gp: TDoublePoint; // graph units
pt: TPoint; // image units
nSource, nPoints: Integer;
nStart: Integer;
newPolygon: Boolean;
i: Integer;
procedure SavePolygonStartIndex(AIndex: Integer);
begin
if nStart mod START_BLOCKSIZE = 0 then
SetLength(FStart, Length(FStart) + START_BLOCKSIZE);
FStart[nStart] := AIndex;
inc(nStart);
end;
begin
if IsEmpty or (not Active) then
exit;
// Do not draw anything if the series extent does not intersect CurrentExtent.
with Extent do begin
ext.a := AxisToGraph(a);
ext.b := AxisToGraph(b);
end;
NormalizeRect(ext);
if not RectIntersectsRect(ext, ParentChart.CurrentExtent) then
exit;
nSource := Source.Count;
SetLength(FPoints, nSource);
SetLength(FStart, START_BLOCKSIZE);
nStart := 0;
nPoints := 0;
newPolygon := true;
for i := 0 to nSource-1 do begin
// a new polygon begins with the current index --> store index in array FStart[].
if newPolygon then begin
SavePolygonStartIndex(nPoints);
// Since the polygon ends if the start point is met again we must store the start point.
apStart := Source.Item[i]^.Point;
end;
// Get polygon point in image coordinates
ap := Source.Item[i]^.Point;
if IsRotated then
gp := DoublePoint(AxisToGraphX(ap.Y), AxisToGraphY(ap.X))
else
gp := AxisToGraph(ap);
pt := ParentChart.GraphToImage(gp);
// Store image point in FPoints array
FPoints[nPoints] := pt;
inc(nPoints);
// Current point coincides with the polygon start point
// --> polygon is closed, set flag "newPolygon" to be processed in next iteration
if (ap = apStart) then
newPolygon := not newPolygon;
end;
if nPoints = 0 then
exit;
// Use length of FStart array as last array element for easier calculation
SavePolygonStartIndex(nPoints);
// Trim length of FStart array to occupied length
SetLength(FStart, nStart);
// Draw polygon(s)
ADrawer.SetBrush(FBrush);
ADrawer.SetPen(FPen);
for i := 0 to High(FStart)-1 do
ADrawer.Polygon(FPoints, FStart[i], FStart[i+1] - FStart[i]);
end;
{ Is overridden in order to detect tool events inside the polygon (nptCustom).
Otherwise only events on the perimenter would be detected. }
function TPolygonSeries.GetNearestPoint(const AParams: TNearestPointParams;
out AResults: TNearestPointResults): Boolean;
var
ext: TDoubleRect;
begin
Result := false;
AResults.FDist := sqr(AParams.FRadius) + 1;
AResults.FIndex := -1;
AResults.FXIndex := 0;
AResults.FYIndex := 0;
Result := inherited;
if Result or not ((nptCustom in AParams.FTargets) and (nptCustom in ToolTargets)) then
exit;
with Extent do begin
ext.a := AxisToGraph(a);
ext.b := AxisToGraph(b);
end;
NormalizeRect(ext);
// Do not do anything if the series extent does not intersect CurrentExtent.
if not RectIntersectsRect(ext, ParentChart.CurrentExtent) then
exit;
Result := IsPointInPolygon(AParams.FPoint, FPoints);
if Result then
begin
AResults.FDist := 0;
AResults.FIndex := 0;
AResults.FYIndex := 0;
AResults.FValue := ParentChart.ImageToGraph(AParams.FPoint);
AResults.FImg := AParams.FPoint;
end;
end;
procedure TPolygonSeries.SetBrush(AValue: TBrush);
begin
FBrush.Assign(AValue);
UpdateParentChart;
end;
procedure TPolygonSeries.SetPen(AValue: TPen);
begin
FPen.Assign(AValue);
UpdateParentChart;
end;
initialization
RegisterSeriesClass(TPolygonSeries, @rsPolygonSeries);
end.