diff --git a/.gitattributes b/.gitattributes
index 105da21ee0..e78fb72d11 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -2213,6 +2213,7 @@ components/tachart/tamultiseries.pas svneol=native#text/pascal
components/tachart/taseries.pas svneol=native#text/plain
components/tachart/taserieseditor.pas svneol=native#text/plain
components/tachart/tasources.pas svneol=native#text/pascal
+components/tachart/tastyles.pas svneol=native#text/pascal
components/tachart/tasubcomponentseditor.lfm svneol=native#text/plain
components/tachart/tasubcomponentseditor.pas svneol=native#text/pascal
components/tachart/tatools.pas svneol=native#text/pascal
diff --git a/components/tachart/tachartlazaruspkg.lpk b/components/tachart/tachartlazaruspkg.lpk
index 4643175751..147c44081c 100644
--- a/components/tachart/tachartlazaruspkg.lpk
+++ b/components/tachart/tachartlazaruspkg.lpk
@@ -25,7 +25,7 @@
for details about the copyright.
"/>
-
+
@@ -92,6 +92,11 @@
+
+
+
+
+
diff --git a/components/tachart/tachartlazaruspkg.pas b/components/tachart/tachartlazaruspkg.pas
index d8a38a4a8c..395f70d3f9 100644
--- a/components/tachart/tachartlazaruspkg.pas
+++ b/components/tachart/tachartlazaruspkg.pas
@@ -9,7 +9,7 @@ interface
uses
TAChartAxis, TAChartUtils, TACustomSeries, TADbSource, TAGraph, TASeries,
TASeriesEditor, TASources, TASubcomponentsEditor, TATools,
- TATransformations, TATypes, TADrawUtils, TAMultiSeries, TALegend,
+ TATransformations, TATypes, TADrawUtils, TAMultiSeries, TALegend, TAStyles,
LazarusPackageIntf;
implementation
@@ -22,6 +22,7 @@ begin
RegisterUnit('TASources', @TASources.Register);
RegisterUnit('TATools', @TATools.Register);
RegisterUnit('TATransformations', @TATransformations.Register);
+ RegisterUnit('TAStyles', @TAStyles.Register);
end;
initialization
diff --git a/components/tachart/tacustomseries.pas b/components/tachart/tacustomseries.pas
index a08badbae7..ce0a6d128d 100644
--- a/components/tachart/tacustomseries.pas
+++ b/components/tachart/tacustomseries.pas
@@ -24,7 +24,7 @@ interface
uses
Classes, Graphics, SysUtils,
- TAChartAxis, TAChartUtils, TAGraph, TASources, TATypes;
+ TAChartAxis, TAChartUtils, TAGraph, TASources, TAStyles, TATypes;
const
DEF_AXIS_INDEX = -1;
@@ -88,12 +88,15 @@ type
FMarks: TChartMarks;
FOnGetMark: TChartGetMarkEvent;
FSource: TCustomChartSource;
+ FStyles: TChartStyles;
+ FStylesListener: TListener;
function GetSource: TCustomChartSource;
function IsSourceStored: boolean;
procedure SetMarks(const AValue: TChartMarks);
procedure SetOnGetMark(const AValue: TChartGetMarkEvent);
procedure SetSource(AValue: TCustomChartSource);
+ procedure SetStyles(AValue: TChartStyles);
protected
procedure AfterAdd; override;
procedure AfterDraw; override;
@@ -107,6 +110,8 @@ type
function GetXMaxVal: Integer;
procedure VisitSources(
AVisitor: TChartOnSourceVisitor; AAxis: TChartAxis; var AData); override;
+ protected
+ property Styles: TChartStyles read FStyles write SetStyles;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
@@ -411,6 +416,7 @@ begin
FBuiltinSource.Name := BUILTIN_SOURCE_NAME;
FBuiltinSource.Broadcaster.Subscribe(FListener);
FMarks := TChartMarks.Create(FChart);
+ FStylesListener := TListener.Create(@FStyles, @StyleChanged);
end;
procedure TChartSeries.Delete(AIndex: Integer);
@@ -423,6 +429,7 @@ begin
FreeAndNil(FListener);
FreeAndNil(FBuiltinSource);
FreeAndNil(FMarks);
+ FreeAndNil(FStylesListener);
inherited;
end;
@@ -586,6 +593,16 @@ begin
UpdateParentChart;
end;
+procedure TChartSeries.SetStyles(AValue: TChartStyles);
+begin
+ if FStyles = AValue then exit;
+ if FStylesListener.IsListening then
+ Styles.Broadcaster.Unsubscribe(FStylesListener);
+ FStyles := AValue;
+ Styles.Broadcaster.Subscribe(FStylesListener);
+ UpdateParentChart;
+end;
+
procedure TChartSeries.SetXValue(AIndex: Integer; AValue: Double); inline;
begin
ListSource.SetXValue(AIndex, AValue);
diff --git a/components/tachart/tastyles.pas b/components/tachart/tastyles.pas
new file mode 100644
index 0000000000..4a0732a49d
--- /dev/null
+++ b/components/tachart/tastyles.pas
@@ -0,0 +1,226 @@
+{
+
+ *****************************************************************************
+ * *
+ * 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 TAStyles;
+
+{$H+}
+
+interface
+
+uses
+ Classes, Graphics, SysUtils, TAChartUtils;
+
+type
+ { TChartStyle }
+
+ TChartStyle = class(TCollectionItem)
+ private
+ FBrush: TBrush;
+ FPen: TPen;
+ FRepeatCount: Cardinal;
+ procedure SetBrush(const AValue: TBrush);
+ procedure SetPen(const AValue: TPen);
+ procedure SetRepeatCount(AValue: Cardinal);
+ procedure StyleChanged(ASender: TObject);
+ protected
+ function GetDisplayName: string; override;
+ public
+ constructor Create(ACollection: TCollection); override;
+ destructor Destroy; override;
+ public
+ procedure Assign(Source: TPersistent); override;
+ procedure Apply(ACanvas: TCanvas);
+ published
+ property Brush: TBrush read FBrush write SetBrush;
+ property Pen: TPen read FPen write SetPen;
+ property RepeatCount: Cardinal
+ read FRepeatCount write SetRepeatCount default 1;
+ end;
+
+ TChartStyles = class;
+
+ { TChartStyleList }
+
+ TChartStyleList = class(TCollection)
+ private
+ FOwner: TChartStyles;
+ function GetStyle(AIndex: Integer): TChartStyle;
+ protected
+ function GetOwner: TPersistent; override;
+ procedure Changed;
+ public
+ constructor Create(AOwner: TChartStyles);
+ property Style[AIndex: Integer]: TChartStyle read GetStyle; default;
+ end;
+
+ { TChartStyles }
+
+ TChartStyles = class(TComponent)
+ private
+ FBroadcaster: TBroadcaster;
+ FStyles: TChartStyleList;
+ procedure SetStyles(const AValue: TChartStyleList);
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ public
+ procedure Apply(ACanvas: TCanvas; AIndex: Cardinal);
+ property Broadcaster: TBroadcaster read FBroadcaster;
+ published
+ property Styles: TChartStyleList read FStyles write SetStyles;
+ end;
+
+ procedure Register;
+
+implementation
+
+procedure Register;
+begin
+ RegisterComponents(CHART_COMPONENT_IDE_PAGE, [TChartStyles]);
+end;
+
+{ TChartStyle }
+
+procedure TChartStyle.Apply(ACanvas: TCanvas);
+begin
+ ACanvas.Brush := Brush;
+ ACanvas.Pen := Pen;
+end;
+
+procedure TChartStyle.Assign(Source: TPersistent);
+begin
+ if Source is TChartStyle then
+ with Source as TChartStyle do begin
+ Self.Brush := Brush;
+ Self.Pen := Pen;
+ end;
+ inherited Assign(Source);
+end;
+
+constructor TChartStyle.Create(ACollection: TCollection);
+begin
+ inherited Create(ACollection);
+ FBrush := TBrush.Create;
+ FBrush.OnChange := @StyleChanged;
+ FPen := TPen.Create;
+ FPen.OnChange := @StyleChanged;
+ FRepeatCount := 1;
+end;
+
+destructor TChartStyle.Destroy;
+begin
+ FreeAndNil(FBrush);
+ FreeAndNil(FPen);
+ inherited Destroy;
+end;
+
+function TChartStyle.GetDisplayName: string;
+begin
+ Result := inherited GetDisplayName;
+end;
+
+procedure TChartStyle.SetBrush(const AValue: TBrush);
+begin
+ if FBrush = AValue then exit;
+ FBrush := AValue;
+end;
+
+procedure TChartStyle.SetPen(const AValue: TPen);
+begin
+ if FPen = AValue then exit;
+ FPen := AValue;
+end;
+
+procedure TChartStyle.SetRepeatCount(AValue: Cardinal);
+begin
+ if FRepeatCount = AValue then exit;
+ FRepeatCount := AValue;
+ StyleChanged(Self);
+end;
+
+procedure TChartStyle.StyleChanged(ASender: TObject);
+begin
+ Unused(ASender);
+ TChartStyleList(Collection).Changed;
+end;
+
+{ TChartStyleList }
+
+procedure TChartStyleList.Changed;
+begin
+ TChartStyles(Owner).Broadcaster.Broadcast(Self);
+end;
+
+constructor TChartStyleList.Create(AOwner: TChartStyles);
+begin
+ inherited Create(TChartStyle);
+ FOwner := AOwner;
+end;
+
+function TChartStyleList.GetOwner: TPersistent;
+begin
+ Result := FOwner;
+end;
+
+function TChartStyleList.GetStyle(AIndex: Integer): TChartStyle;
+begin
+ Result := Items[AIndex] as TChartStyle;
+end;
+
+{ TChartStyles }
+
+procedure TChartStyles.Apply(ACanvas: TCanvas; AIndex: Cardinal);
+var
+ totalRepeatCount: Cardinal = 0;
+ i: Integer;
+begin
+ for i := 0 to Styles.Count - 1 do
+ totalRepeatCount += Styles[i].RepeatCount;
+ if totalRepeatCount = 0 then exit;
+ AIndex := AIndex mod totalRepeatCount;
+ totalRepeatCount := 0;
+ for i := 0 to Styles.Count - 1 do begin
+ totalRepeatCount += Styles[i].RepeatCount;
+ if AIndex < totalRepeatCount then begin
+ Styles[i].Apply(ACanvas);
+ break;
+ end;
+ end;
+end;
+
+constructor TChartStyles.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FBroadcaster := TBroadcaster.Create;
+ FStyles := TChartStyleList.Create(Self);
+end;
+
+destructor TChartStyles.Destroy;
+begin
+ FreeAndNil(FBroadcaster);
+ FreeAndNil(FStyles);
+ inherited Destroy;
+end;
+
+procedure TChartStyles.SetStyles(const AValue: TChartStyleList);
+begin
+ if FStyles = AValue then exit;
+ FStyles := AValue;
+ Broadcaster.Broadcast(Self);
+end;
+
+end.
+