mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-27 12:00:29 +02:00
Merged revision(s) 65376 #4160d7c7ef, 65379 #becaac9c5d, 65384-65385 #9d7566217a-#9d7566217a, 65389 #9f896e3f00, 65391 #7bf4f7da41, 65393-65394 #5ef5288afe-#5ef5288afe, 65420-65423 #b75cbf6965-#b75cbf6965, 65425 #2bf2902c91, 65427 #f549172f40, 65431 #51044e806b, 65440 #0ec2f041e7, 65453 #4553a2eafb from trunk:
TAChart: Update xml help. ........ TAChart: Decode system colors in text elements. ........ TAChart: Add method GetAxisRange to determine the range of an axis covered by all series assigned to it. ........ TAChart: Use real axis limits in ChartEditor demo. ........ TAChart: Rename TChart.GetAxisRange to .GetAllSeriesAxisLimits (more precise). ........ TAChart/ChartEditor demo: Check that axis maximum is always greater than the minimum. ........ TAChart/ChartEditor demo: Fix bug in handling of axis.Inverted. ........ TAChart: Update xml doc. ........ TAChart/ChartEditor demo: Fix update of axis grid visibility. ........ TAChart/ChartEditor demo: Fix axis lines not being updated. ........ TAChart: Always draw axis arrows with solid pen. ........ TAChart: Fix usage of axistransformations in ChartLiveView having ExtentY = lveAuto. ........ TAChart: Fix initialization error in TChartLiveView when ExtentY is lveAuto. ........ TAChart: Fix axis scaling of TChartLiveView with coincident axis limits and ExtentY = lveAuto. ........ TAChart/ChartEditor demo: add forgotten lfm file. ........ TAChart/ChartLiveView: Fix autoscaling when multiple axes are used. Add new ExtentY mode, lveMultiAxisRange ........ TAChart/TChartLiveView: Add some comments. Add xml documentation. ........ git-svn-id: branches/fixes_2_2@65460 -
This commit is contained in:
parent
3ed9efb552
commit
2c461bda95
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -5404,6 +5404,7 @@ components/tachart/fpdoc/descr.lst svneol=native#text/plain
|
||||
components/tachart/fpdoc/input.lst svneol=native#text/plain
|
||||
components/tachart/fpdoc/tachartaxis.xml svneol=native#text/plain
|
||||
components/tachart/fpdoc/tachartaxisutils.xml svneol=native#text/xml
|
||||
components/tachart/fpdoc/tachartliveview.xml svneol=native#text/xml
|
||||
components/tachart/fpdoc/tachartutils.xml svneol=native#text/plain
|
||||
components/tachart/fpdoc/tacustomseries.xml svneol=native#text/plain
|
||||
components/tachart/fpdoc/tacustomsource.xml svneol=native#text/xml
|
||||
@ -5415,6 +5416,7 @@ components/tachart/fpdoc/talegend.xml svneol=native#text/plain
|
||||
components/tachart/fpdoc/tamath.xml svneol=native#text/xml
|
||||
components/tachart/fpdoc/taseries.xml svneol=native#text/plain
|
||||
components/tachart/fpdoc/tasources.xml svneol=native#text/plain
|
||||
components/tachart/fpdoc/tatools.xml svneol=native#text/xml
|
||||
components/tachart/fpdoc/tatypes.xml svneol=native#text/plain
|
||||
components/tachart/fpvectorial/tachartfpvectorial.lpk svneol=native#text/plain
|
||||
components/tachart/fpvectorial/tachartfpvectorial.pas svneol=native#text/pascal
|
||||
|
@ -11,7 +11,7 @@ object ChartAxisEditor: TChartAxisEditor
|
||||
OnCreate = FormCreate
|
||||
OnShow = FormShow
|
||||
Position = poScreenCenter
|
||||
LCLVersion = '2.1.0.0'
|
||||
LCLVersion = '2.3.0.0'
|
||||
object ButtonPanel: TButtonPanel
|
||||
Left = 6
|
||||
Height = 34
|
||||
|
@ -179,8 +179,17 @@ begin
|
||||
end;
|
||||
|
||||
procedure TChartAxisEditor.OKButtonClick(Sender: TObject);
|
||||
var
|
||||
msg: String;
|
||||
C: TWinControl;
|
||||
begin
|
||||
FOKClicked := true;
|
||||
if not FAxisFrame.Validate(msg, C) then
|
||||
begin
|
||||
C.SetFocus;
|
||||
MessageDlg(msg, mtError, [mbOK], 0);
|
||||
ModalResult := mrNone;
|
||||
end else
|
||||
FOKClicked := true;
|
||||
end;
|
||||
|
||||
procedure TChartAxisEditor.Prepare(Axis: TChartAxis;
|
||||
|
@ -40,23 +40,24 @@ object ChartAxisFrame: TChartAxisFrame
|
||||
Height = 446
|
||||
Top = 25
|
||||
Width = 646
|
||||
ActivePage = pgLabels
|
||||
ActivePage = pgGrid
|
||||
Align = alClient
|
||||
TabIndex = 1
|
||||
TabIndex = 2
|
||||
TabOrder = 1
|
||||
OnChanging = PageControlChanging
|
||||
object pgTitle: TTabSheet
|
||||
Caption = 'Title'
|
||||
ClientHeight = 378
|
||||
ClientHeight = 418
|
||||
ClientWidth = 638
|
||||
object TitleMemoPanel: TPanel
|
||||
Left = 8
|
||||
Height = 151
|
||||
Height = 191
|
||||
Top = 8
|
||||
Width = 622
|
||||
Align = alClient
|
||||
BorderSpacing.Around = 8
|
||||
BevelOuter = bvNone
|
||||
ClientHeight = 151
|
||||
ClientHeight = 191
|
||||
ClientWidth = 622
|
||||
TabOrder = 0
|
||||
object lblTitle: TLabel
|
||||
@ -68,7 +69,6 @@ object ChartAxisFrame: TChartAxisFrame
|
||||
Width = 21
|
||||
BorderSpacing.Top = 2
|
||||
Caption = 'Text'
|
||||
ParentColor = False
|
||||
end
|
||||
object mmoTitle: TMemo
|
||||
AnchorSideLeft.Control = lblTitle
|
||||
@ -79,7 +79,7 @@ object ChartAxisFrame: TChartAxisFrame
|
||||
AnchorSideBottom.Control = TitleMemoPanel
|
||||
AnchorSideBottom.Side = asrBottom
|
||||
Left = 0
|
||||
Height = 130
|
||||
Height = 170
|
||||
Top = 21
|
||||
Width = 622
|
||||
Anchors = [akTop, akLeft, akRight, akBottom]
|
||||
@ -109,7 +109,7 @@ object ChartAxisFrame: TChartAxisFrame
|
||||
object TitleParamsPanel: TPanel
|
||||
Left = 8
|
||||
Height = 203
|
||||
Top = 167
|
||||
Top = 207
|
||||
Width = 622
|
||||
Align = alBottom
|
||||
BorderSpacing.Around = 8
|
||||
@ -199,7 +199,6 @@ object ChartAxisFrame: TChartAxisFrame
|
||||
Width = 45
|
||||
Caption = 'Distance'
|
||||
FocusControl = seTitleDistance
|
||||
ParentColor = False
|
||||
end
|
||||
object seTitleDistance: TSpinEdit
|
||||
AnchorSideLeft.Control = lblTitleDistance
|
||||
@ -248,7 +247,6 @@ object ChartAxisFrame: TChartAxisFrame
|
||||
BorderSpacing.Left = 16
|
||||
BorderSpacing.Top = 6
|
||||
Caption = 'Automatic'
|
||||
ParentColor = False
|
||||
end
|
||||
object cbAutoMax: TCheckBox
|
||||
AnchorSideLeft.Control = lblAutomatic
|
||||
@ -427,7 +425,6 @@ object ChartAxisFrame: TChartAxisFrame
|
||||
Top = 31
|
||||
Width = 38
|
||||
Caption = 'Format'
|
||||
ParentColor = False
|
||||
end
|
||||
object seLabelDistance: TSpinEdit
|
||||
AnchorSideLeft.Control = edLabelFormat
|
||||
@ -453,7 +450,6 @@ object ChartAxisFrame: TChartAxisFrame
|
||||
Width = 45
|
||||
Caption = 'Distance'
|
||||
FocusControl = seLabelDistance
|
||||
ParentColor = False
|
||||
end
|
||||
end
|
||||
object Bevel2: TBevel
|
||||
@ -524,7 +520,6 @@ object ChartAxisFrame: TChartAxisFrame
|
||||
Width = 67
|
||||
BorderSpacing.Left = 16
|
||||
Caption = 'Outer length'
|
||||
ParentColor = False
|
||||
end
|
||||
object lblTickInnerLength: TLabel
|
||||
AnchorSideLeft.Control = lblTickLength
|
||||
@ -535,7 +530,6 @@ object ChartAxisFrame: TChartAxisFrame
|
||||
Top = 37
|
||||
Width = 64
|
||||
Caption = 'Inner length'
|
||||
ParentColor = False
|
||||
end
|
||||
object cbTickColor: TColorButton
|
||||
AnchorSideTop.Side = asrCenter
|
||||
@ -555,8 +549,8 @@ object ChartAxisFrame: TChartAxisFrame
|
||||
end
|
||||
object pgGrid: TTabSheet
|
||||
Caption = 'Grid'
|
||||
ClientHeight = 378
|
||||
ClientWidth = 513
|
||||
ClientHeight = 418
|
||||
ClientWidth = 638
|
||||
object gbGrid: TGroupBox
|
||||
AnchorSideLeft.Control = pgGrid
|
||||
AnchorSideTop.Control = pgGrid
|
||||
@ -584,14 +578,15 @@ object ChartAxisFrame: TChartAxisFrame
|
||||
BorderSpacing.Right = 16
|
||||
BorderSpacing.Bottom = 8
|
||||
Caption = 'Visible'
|
||||
OnChange = cbGridVisibleChange
|
||||
TabOrder = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
object pgLine: TTabSheet
|
||||
Caption = 'Line'
|
||||
ClientHeight = 378
|
||||
ClientWidth = 513
|
||||
ClientHeight = 418
|
||||
ClientWidth = 638
|
||||
object gbFrame: TGroupBox
|
||||
AnchorSideLeft.Control = pgLine
|
||||
AnchorSideTop.Control = pgLine
|
||||
@ -599,19 +594,19 @@ object ChartAxisFrame: TChartAxisFrame
|
||||
Left = 8
|
||||
Height = 119
|
||||
Top = 8
|
||||
Width = 275
|
||||
Width = 400
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
BorderSpacing.Left = 8
|
||||
BorderSpacing.Top = 8
|
||||
Caption = 'gbFrame'
|
||||
ClientHeight = 99
|
||||
ClientWidth = 271
|
||||
ClientWidth = 396
|
||||
TabOrder = 0
|
||||
object cbFrameVisible: TCheckBox
|
||||
Left = 16
|
||||
Height = 19
|
||||
Top = 8
|
||||
Width = 239
|
||||
Width = 364
|
||||
Align = alTop
|
||||
BorderSpacing.Left = 16
|
||||
BorderSpacing.Top = 8
|
||||
@ -631,18 +626,18 @@ object ChartAxisFrame: TChartAxisFrame
|
||||
Left = 8
|
||||
Height = 137
|
||||
Top = 143
|
||||
Width = 275
|
||||
Width = 400
|
||||
Anchors = [akTop, akLeft, akRight]
|
||||
BorderSpacing.Top = 16
|
||||
Caption = 'gbAxisLine'
|
||||
ClientHeight = 117
|
||||
ClientWidth = 271
|
||||
ClientWidth = 396
|
||||
TabOrder = 1
|
||||
object cbAxisLineVisible: TCheckBox
|
||||
Left = 16
|
||||
Height = 19
|
||||
Top = 8
|
||||
Width = 239
|
||||
Width = 364
|
||||
Align = alTop
|
||||
BorderSpacing.Left = 16
|
||||
BorderSpacing.Top = 8
|
||||
@ -659,7 +654,7 @@ object ChartAxisFrame: TChartAxisFrame
|
||||
AnchorSideTop.Control = gbFrame
|
||||
AnchorSideRight.Control = pgLine
|
||||
AnchorSideRight.Side = asrBottom
|
||||
Left = 307
|
||||
Left = 432
|
||||
Height = 156
|
||||
Top = 8
|
||||
Width = 200
|
||||
@ -693,7 +688,6 @@ object ChartAxisFrame: TChartAxisFrame
|
||||
Top = 39
|
||||
Width = 61
|
||||
Caption = 'Base length'
|
||||
ParentColor = False
|
||||
end
|
||||
object lblArrowLength: TLabel
|
||||
AnchorSideLeft.Control = cbArrowVisible
|
||||
@ -704,7 +698,6 @@ object ChartAxisFrame: TChartAxisFrame
|
||||
Top = 70
|
||||
Width = 37
|
||||
Caption = 'Length'
|
||||
ParentColor = False
|
||||
end
|
||||
object lblArrowWidth: TLabel
|
||||
AnchorSideLeft.Control = cbArrowVisible
|
||||
@ -715,7 +708,6 @@ object ChartAxisFrame: TChartAxisFrame
|
||||
Top = 101
|
||||
Width = 32
|
||||
Caption = 'Width'
|
||||
ParentColor = False
|
||||
end
|
||||
object seArrowBaseLength: TSpinEdit
|
||||
AnchorSideLeft.Control = lblArrowBaseLength
|
||||
|
@ -76,6 +76,7 @@ type
|
||||
procedure cbAutoMinChange(Sender: TObject);
|
||||
procedure cbAxisLineVisibleChange(Sender: TObject);
|
||||
procedure cbFrameVisibleChange(Sender: TObject);
|
||||
procedure cbGridVisibleChange(Sender: TObject);
|
||||
procedure cbInvertedChange(Sender: TObject);
|
||||
procedure cbLabelsVisibleChange(Sender: TObject);
|
||||
procedure cbShowChange(Sender: TObject);
|
||||
@ -83,6 +84,7 @@ type
|
||||
procedure cbTitleVisibleChange(Sender: TObject);
|
||||
procedure edLabelFormatEditingDone(Sender: TObject);
|
||||
procedure mmoTitleChange(Sender: TObject);
|
||||
procedure PageControlChanging(Sender: TObject; var AllowChange: Boolean);
|
||||
procedure rgTitleAlignmentClick(Sender: TObject);
|
||||
procedure seArrowBaseLengthChange(Sender: TObject);
|
||||
procedure seArrowLengthChange(Sender: TObject);
|
||||
@ -95,6 +97,7 @@ type
|
||||
procedure seTitleDistanceChange(Sender: TObject);
|
||||
private
|
||||
FAxis: TChartAxis;
|
||||
FAxisMin, FAxisMax: Double;
|
||||
FTitleFontFrame: TChartFontFrame;
|
||||
FTitleShapeBrushPenMarginsFrame: TChartShapeBrushPenMarginsFrame;
|
||||
FLabelFontFrame: TChartFontFrame;
|
||||
@ -119,9 +122,12 @@ type
|
||||
procedure CalculatePreferredSize(var PreferredWidth, PreferredHeight: integer;
|
||||
{%H-}WithThemeSpace: Boolean); override;
|
||||
function GetChart: TChart;
|
||||
function GetRealAxisMax: Double;
|
||||
function GetRealAxisMin: Double;
|
||||
public
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
procedure Prepare(Axis: TChartAxis);
|
||||
function Validate(out AMsg: String; out AControl: TWinControl): Boolean;
|
||||
property Page: TChartAxisEditorPage read GetPage write SetPage;
|
||||
end;
|
||||
|
||||
@ -266,7 +272,7 @@ end;
|
||||
|
||||
procedure TChartAxisFrame.cbAxisLineVisibleChange(Sender: TObject);
|
||||
begin
|
||||
FAxis.Grid.Visible := cbGridVisible.Checked;
|
||||
FAxis.AxisPen.Visible := cbAxisLineVisible.Checked;
|
||||
end;
|
||||
|
||||
procedure TChartAxisFrame.cbFrameVisibleChange(Sender: TObject);
|
||||
@ -274,9 +280,14 @@ begin
|
||||
GetChart.Frame.Visible := cbFrameVisible.Checked;
|
||||
end;
|
||||
|
||||
procedure TChartAxisFrame.cbGridVisibleChange(Sender: TObject);
|
||||
begin
|
||||
FAxis.Grid.Visible := cbGridVisible.Checked;
|
||||
end;
|
||||
|
||||
procedure TChartAxisFrame.cbInvertedChange(Sender: TObject);
|
||||
begin
|
||||
FAxis.Inverted := not FAxis.Inverted;
|
||||
FAxis.Inverted := cbInverted.Checked;
|
||||
end;
|
||||
|
||||
procedure TChartAxisFrame.cbLabelsVisibleChange(Sender: TObject);
|
||||
@ -336,6 +347,22 @@ begin
|
||||
Result := TChartAxisEditorPage(PageControl.ActivePageIndex);
|
||||
end;
|
||||
|
||||
function TChartAxisFrame.GetRealAxisMax: Double;
|
||||
begin
|
||||
if cbAutoMax.Checked then
|
||||
Result := FAxisMax
|
||||
else
|
||||
Result := seMaximum.Value;
|
||||
end;
|
||||
|
||||
function TChartAxisFrame.GetRealAxisMin: Double;
|
||||
begin
|
||||
if cbAutoMin.Checked then
|
||||
Result := FAxisMin
|
||||
else
|
||||
Result := seMinimum.Value;
|
||||
end;
|
||||
|
||||
procedure TChartAxisFrame.LabelChangedHandler(Sender: TObject);
|
||||
begin
|
||||
GetChart.Invalidate;
|
||||
@ -356,6 +383,20 @@ begin
|
||||
FAxis.Title.Caption := mmoTitle.Lines.Text;
|
||||
end;
|
||||
|
||||
procedure TChartAxisFrame.PageControlChanging(Sender: TObject;
|
||||
var AllowChange: Boolean);
|
||||
var
|
||||
msg: String;
|
||||
C: TWinControl;
|
||||
begin
|
||||
if not Validate(msg, C) then
|
||||
begin
|
||||
C.SetFocus;
|
||||
MessageDlg(msg, mtError, [mbOK], 0);
|
||||
AllowChange := false;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TChartAxisFrame.Prepare(Axis: TChartAxis);
|
||||
begin
|
||||
FAxis := Axis;
|
||||
@ -379,8 +420,9 @@ begin
|
||||
end;
|
||||
|
||||
// Page "Labels"
|
||||
seMaximum.Value := Axis.Range.Max;
|
||||
seMinimum.Value := Axis.Range.Min;
|
||||
GetChart.GetAllSeriesAxisLimits(Axis, FAxisMin, FAxisMax);
|
||||
seMaximum.Value := IfThen(Axis.Range.UseMax, Axis.Range.Max, FAxisMax);
|
||||
seMinimum.Value := IfThen(Axis.Range.UseMin, Axis.Range.Min, FAxisMin);
|
||||
cbAutoMax.Checked := not Axis.Range.UseMax;
|
||||
cbAutoMin.Checked := not Axis.Range.UseMin;
|
||||
cbInverted.Checked := Axis.Inverted;
|
||||
@ -491,6 +533,23 @@ begin
|
||||
FAxis.Title.Shape := AShape;
|
||||
end;
|
||||
|
||||
function TChartAxisFrame.Validate(out AMsg: String; out AControl: TWinControl): Boolean;
|
||||
begin
|
||||
Result := false;
|
||||
if GetRealAxisMin >= GetRealAxisMax then
|
||||
begin
|
||||
AMsg := 'The axis minimum must be smaller than the axis maximum.';
|
||||
if seMaximum.Visible then
|
||||
AControl := seMaximum
|
||||
else if seMinimum.Visible then
|
||||
AControl := seMinimum
|
||||
else
|
||||
AControl := cbAutoMax;
|
||||
exit;
|
||||
end;
|
||||
Result := true;
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
|
||||
|
@ -10,7 +10,7 @@ object ChartEditorForm: TChartEditorForm
|
||||
OnCloseQuery = FormCloseQuery
|
||||
OnCreate = FormCreate
|
||||
OnDestroy = FormDestroy
|
||||
LCLVersion = '2.1.0.0'
|
||||
LCLVersion = '2.3.0.0'
|
||||
object ButtonPanel: TButtonPanel
|
||||
Left = 6
|
||||
Height = 34
|
||||
@ -41,6 +41,7 @@ object ChartEditorForm: TChartEditorForm
|
||||
Constraints.MinWidth = 120
|
||||
Images = ChartImagesDM.ChartImages
|
||||
TabOrder = 1
|
||||
OnChanging = TreeChanging
|
||||
OnDeletion = TreeDeletion
|
||||
OnSelectionChanged = TreeSelectionChanged
|
||||
end
|
||||
@ -110,7 +111,6 @@ object ChartEditorForm: TChartEditorForm
|
||||
Font.Color = clWindow
|
||||
Font.Height = -16
|
||||
Font.Style = [fsBold]
|
||||
ParentColor = False
|
||||
ParentFont = False
|
||||
end
|
||||
object Image1: TImage
|
||||
|
@ -29,6 +29,8 @@ type
|
||||
procedure FormCreate(Sender: TObject);
|
||||
procedure FormDestroy(Sender: TObject);
|
||||
procedure OKButtonClick(Sender: TObject);
|
||||
procedure TreeChanging(Sender: TObject; Node: TTreeNode;
|
||||
var AllowChange: Boolean);
|
||||
procedure TreeDeletion(Sender: TObject; Node: TTreeNode);
|
||||
procedure TreeSelectionChanged(Sender: TObject);
|
||||
private
|
||||
@ -57,6 +59,7 @@ type
|
||||
procedure SaveChartToStream;
|
||||
procedure SelectNode(ANode: TTreeNode);
|
||||
procedure RestoreChartFromStream;
|
||||
function Validate(ANode: TTreeNode; out AMsg: String; out AControl: TWinControl): boolean;
|
||||
public
|
||||
procedure SelectAxis(AxisIndex: Integer; APage: TChartAxisEditorPage);
|
||||
procedure SelectFooter;
|
||||
@ -210,8 +213,17 @@ begin
|
||||
end;
|
||||
|
||||
procedure TChartEditorForm.ApplyButtonClick(Sender: TObject);
|
||||
var
|
||||
msg: String;
|
||||
C: TWinControl;
|
||||
begin
|
||||
RestoreChartFromStream;
|
||||
if not Validate(Tree.Selected, msg, C) then
|
||||
begin
|
||||
C.SetFocus;
|
||||
MessageDlg(msg, mtError, [mbOK], 0);
|
||||
ModalResult := mrNone;
|
||||
end else
|
||||
RestoreChartFromStream;
|
||||
end;
|
||||
|
||||
procedure TChartEditorForm.FormActivate(Sender: TObject);
|
||||
@ -338,8 +350,31 @@ begin
|
||||
end;
|
||||
|
||||
procedure TChartEditorForm.OKButtonClick(Sender: TObject);
|
||||
var
|
||||
msg: String;
|
||||
C: TWinControl;
|
||||
begin
|
||||
FOKClicked := true;
|
||||
if not Validate(Tree.selected, msg, C) then
|
||||
begin
|
||||
C.SetFocus;
|
||||
MessageDlg(msg, mtError, [mbOK], 0);
|
||||
ModalResult := mrNone;
|
||||
end else
|
||||
FOKClicked := true;
|
||||
end;
|
||||
|
||||
procedure TChartEditorForm.TreeChanging(Sender: TObject; Node: TTreeNode;
|
||||
var AllowChange: Boolean);
|
||||
var
|
||||
msg: String;
|
||||
C: TWinControl;
|
||||
begin
|
||||
if not Validate(Tree.Selected, msg, C) then
|
||||
begin
|
||||
C.SetFocus;
|
||||
MessageDlg(msg, mtError, [mbOk], 0);
|
||||
AllowChange := false;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TChartEditorForm.PopulateAxes(AChart: TChart);
|
||||
@ -559,5 +594,19 @@ begin
|
||||
ChartImagesDM.ChartImages.GetBitmap(Tree.Selected.ImageIndex, Image1.Picture.Bitmap);
|
||||
end;
|
||||
|
||||
function TChartEditorForm.Validate(ANode: TTreeNode; out AMsg: String;
|
||||
out AControl: TWinControl): Boolean;
|
||||
begin
|
||||
if ANode = nil then
|
||||
exit(true);
|
||||
|
||||
if TObject(ANode.Data) is TChartAxisFrame then
|
||||
begin
|
||||
Result := TChartAxisFrame(ANode.Data).Validate(AMsg, AControl);
|
||||
if not Result then exit;
|
||||
end;
|
||||
Result := true;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
@ -198,6 +198,7 @@
|
||||
</CodeGeneration>
|
||||
<Linking>
|
||||
<Debugging>
|
||||
<DebugInfoType Value="dsDwarf2Set"/>
|
||||
<TrashVariables Value="True"/>
|
||||
</Debugging>
|
||||
<Options>
|
||||
|
19
components/tachart/fpdoc/tachartliveview.xml
Normal file
19
components/tachart/fpdoc/tachartliveview.xml
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<fpdoc-descriptions><package name="TAChartLazarusPkg"><module name="TAChartLiveView"><element name="TChartLiveView"><short><var>TChartLiveView</var> is a component optimized for displaying a long array of incoming data in a viewport with only the most recent data while older data are flowing to the left out of the vewport.</short><descr>The viewport is updated whenever the full extent of the associated chart changes. However, when property <var>Active</var> is set to <var>false</var> the viewport is fixed -- this is a setting which allows the user to review older data, or change the extent while still new data are coming at the same time.
|
||||
</descr>
|
||||
</element><element name="TChartLiveView.Chart"><short>Chart on which the LiveView operates</short>
|
||||
</element><element name="TChartLiveView.ViewportSize"><short>Width of the visible viewport on the x axis, in graph units</short><descr>If set to 0, the width of the current <var>LogicalExtent</var> is used instead.
|
||||
</descr>
|
||||
</element><element name="TChartLiveView.Active"><short>Allows to turn the scrolling controlled by the component ON and OFF.</short>
|
||||
</element><element name="TChartLiveView.ExtentY"><short>Mode determining how the vertical y axis is displayed in the scrolling viewport</short>
|
||||
<descr><p><var>lveAuto</var>: adjusts the height to the visible data range automatically. This works also when the chart contains several y axes.
|
||||
</p><p><var>lveFull</var>: freezes the height to the full extent of the chart.</p><p><var>lveLogical</var>: freezes the height to the logical extent of the chart.</p><p><var>lveMultiAxisRange</var> tries to use a predefined <var>Range</var> of the y axes in case of a multi-axis chart. Use the <var>Range.Min</var>, <var>Range.Max</var>, <var>Range.UseMin</var> and <var>Range.UseMax</var> properties to set up the axis range. Note that the range is extended automatically when a series attached to this axis contains out-of-range y values. When no range is specified (i.e., <var>axis.Range.UseMin=false</var> and <var>axis.Range.UseMax=false</var>) the behaviour is similar to <var>lveAuto</var>.</p>
|
||||
</descr>
|
||||
</element><element name="TChartLiveView.Create"><short>Constructor of the <var>TChartLiveView</var>
|
||||
</short>
|
||||
</element><element name="TChartLiveView.Destroy"><short>Destructor of the <var>TChartLiveView</var>
|
||||
</short>
|
||||
</element>
|
||||
</module>
|
||||
</package>
|
||||
</fpdoc-descriptions>
|
@ -7,7 +7,7 @@
|
||||
</element>
|
||||
<element name="TChartGetMarkEvent"/>
|
||||
<element name="TChartSeries.Count">
|
||||
<short>Return number of points in the series.</short>
|
||||
<short>Returns the number of points in the series.</short>
|
||||
</element>
|
||||
<element name="TChartSeries.Add">
|
||||
<short>Add new point to the right of the series.</short>
|
||||
@ -32,7 +32,7 @@
|
||||
<element name="TChartSeries.ListSource">
|
||||
<errors><link id="TASources.EEditableSourceRequired">EEditableSourceRequired</link>
|
||||
</errors>
|
||||
<short>Verify that the data source is editable and return it.</short>
|
||||
<short>Verifies that the data source is editable and returns it (or <var>nil</var> if the source is not a <var>TListChartSource</var>)</short>
|
||||
</element>
|
||||
<element name="TChartSeries.Clear">
|
||||
<short>Remove all points from the series.</short>
|
||||
@ -40,12 +40,10 @@
|
||||
</descr>
|
||||
</element>
|
||||
<element name="TChartSeries.Delete">
|
||||
<errors>
|
||||
<link id="TASources.EEditableSourceRequired">EEditableSourceRequired</link>
|
||||
<errors><link id="TASources.EEditableSourceRequired">EEditableSourceRequired</link>
|
||||
</errors>
|
||||
<short>Remove point by index.</short>
|
||||
<descr>
|
||||
<p>Requires <link id="TChartSeries.ListSource">editable data source</link>.</p>
|
||||
<short>Removes a data point by index.</short>
|
||||
<descr><p>Requires <link id="TChartSeries.ListSource">editable data source</link>.</p>
|
||||
</descr>
|
||||
</element>
|
||||
<element name="TChartSeries.SetXValue"/>
|
||||
@ -55,6 +53,8 @@
|
||||
</element>
|
||||
<element name="TChartSeries.Marks">
|
||||
<short>Mark parameters.</short>
|
||||
<descr>Marks are the text labels drawn for each data point.
|
||||
</descr>
|
||||
</element>
|
||||
<element name="TChartSeries.OnGetMark">
|
||||
<short>Called before the drawing of each mark.</short>
|
||||
@ -81,7 +81,7 @@ from a <link id="TACustomSource.TCustomChartSource"><var>chart source</var>
|
||||
<short>Return the label for the point number <var>AIndex</var> formatted as per <var>Marks</var> property</short>
|
||||
</element>
|
||||
<element name="TChartSeries.Extent">
|
||||
<short>Return the bounding rectangle for all points in the serie.</short>
|
||||
<short>Returns the bounding rectangle for all points in the serie.</short>
|
||||
<seealso><link id="TASources.TCustomChartSource.Extent">TCustomChartSource.Extent</link>
|
||||
</seealso>
|
||||
</element>
|
||||
@ -192,6 +192,20 @@ per data points than specified by <link id="TChartSeriesGetXYCountNeeded"><var>G
|
||||
By default, i.e. <var>DepthBrightnessDelta=0</var>, the series sides have the same color as the series itself.
|
||||
</descr>
|
||||
</element>
|
||||
<element name="TChartSeries.FindYRange"><short>Finds the y maximum and minimum of the series data having an x between AXMin and AXMax</short>
|
||||
</element><element name="TChartSeries.IsEmpty"><short>Returns true when the series contains no data.</short>
|
||||
</element><element name="TChartSeries.LastValueIndex"><short>Returns the index of the last data point.</short>
|
||||
</element><element name="TChartSeries.MaxXValue"><short>Returns the largest x value</short>
|
||||
</element><element name="TChartSeries.MinXValue"><short>Returns the smallest x value</short>
|
||||
</element><element name="TChartSeries.MaxYValue"><short>Returns the largest y value</short>
|
||||
</element><element name="TChartSeries.MinYValue"><short>Returns the smallest y value</short>
|
||||
</element><element name="TChartSeries.XValue"><short>Returns the x value of the data point with the given index</short>
|
||||
</element><element name="TChartSeries.YValue"><short>Returns the y value of the data point with the given index</short>
|
||||
</element><element name="TChartSeries.XValues"><short>If a source provides data points with multiple x values, the x value with the index <var>AXIndex</var> is returned for the data point at index <var>AIndex</var>
|
||||
</short>
|
||||
</element><element name="TChartSeries.YValues"><short>If a source provides data points with multiple y values, the y value with the index <var>AYIndex</var> is returned for the data point at index <var>AIndex</var>
|
||||
</short>
|
||||
</element>
|
||||
</module>
|
||||
</package>
|
||||
</fpdoc-descriptions>
|
||||
|
@ -268,10 +268,7 @@ For example, <link id="TASeries.TPieSeries">pie series</link> displays a separat
|
||||
</element>
|
||||
<element name="TChart.YImageToGraph">
|
||||
<short>Converts the Y coordinate of a point from image units to graph units.</short>
|
||||
<seealso>
|
||||
<link id="TChart.YGraphToImage"/>
|
||||
<link id="TChart.XImageToGraph"/>
|
||||
<link id="TChart.ImageToGraph"/>
|
||||
<seealso><link id="TChart.YGraphToImage"/><link id="TChart.XImageToGraph"/><link id="TChart.ImageToGraph"/>
|
||||
</seealso>
|
||||
</element>
|
||||
<element name="TChart.CurrentExtent">
|
||||
@ -316,7 +313,9 @@ chart margin and the space reserved for series marks.
|
||||
</element>
|
||||
<element name="Register" skip="1"/>
|
||||
<element name="RegisterSeriesClass" skip="1"/>
|
||||
<element name="TChart.EraseBackground" skip="1"/>
|
||||
<element name="TChart.EraseBackground" skip="1"><short>This overridden background painting method does nothing because the background will be painted over anyway.</short><descr>The inherited behaviour is ignored.
|
||||
</descr>
|
||||
</element>
|
||||
<element name="TChart.GetChildren" skip="1"/>
|
||||
<element name="TChart.Paint" skip="1"/>
|
||||
<element name="TChart.SetChildOrder" skip="1"/>
|
||||
@ -326,10 +325,10 @@ chart margin and the space reserved for series marks.
|
||||
</element>
|
||||
<element name="TChart.PaintOnCanvas.Draw"/>
|
||||
<element name="TChart.Draw">
|
||||
<short>Draws the chart usung the given drawing back-end</short>
|
||||
<short>Draws the chart using the given drawing back-end</short>
|
||||
<descr>This method draws the chart by means of the given drawing back-end,
|
||||
<var>Drawer</var>. Unlike
|
||||
<var>PaintOnCanvas</var> the chart can be drawn on non-canvas devices, such as a svg file.
|
||||
<var>PaintOnCanvas</var> the chart can be drawn on non-canvas devices, such as a svg file or OpenGL context.
|
||||
</descr>
|
||||
<seealso><link id=""/>
|
||||
</seealso>
|
||||
@ -659,6 +658,15 @@ as a replacement.
|
||||
</descr>
|
||||
</element><element name="TChart.Proportional"><short><var>Proportional</var>, when set to <var>true</var>, applies the same scaling factor to the x and y axis.</short>
|
||||
</element>
|
||||
<element name="TChart.ScalingValid"><short>Indicates whether the scaling parameters for the conversion between graph and image coordinates have valid values.</short>
|
||||
</element><element name="TChart.ActiveToolIndex"><short>Returns the index of the currently active chart tool in the toolset attached to the chart.</short>
|
||||
</element>
|
||||
<element name="TChart.MouseDown"><short>The inherited handler for MouseDown events is overridden to dispatch the event to the ChartToolset assigned to the chart.</short>
|
||||
</element><element name="TChart.MouseMove"><short>The inherited handler for MouseMove events is overridden to dispatch the event to the ChartToolset assigned to the chart.</short>
|
||||
</element><element name="TChart.MouseUp"><short>The inherited handler for MouseUp events is overridden to dispatch the event to the ChartToolset assigned to the chart.</short>
|
||||
</element>
|
||||
<element name="TChart.GetAllSeriesAxisLimits"><short>Determines the data range covered by all series assigned to the specified axis. Minimum and maximum are returned in axis units.</short>
|
||||
</element>
|
||||
</module>
|
||||
</package>
|
||||
</fpdoc-descriptions>
|
||||
|
8
components/tachart/fpdoc/tatools.xml
Normal file
8
components/tachart/fpdoc/tatools.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<fpdoc-descriptions><package name="TAChartLazarusPkg"><module name="TATools"><element name="TZoomDragTool"><short>Tool for zooming while dragging the mouse over the area to be magnified</short>
|
||||
</element><element name="TZoomDragTool.EscapeCancels"/><element name="TChartTool.EscapeCancels"><short>Cancels the current operation of the chart tool by pressing the ESC key</short><descr>When the property <var>EscapeCancels</var> is true the current operation of the currently active chart tool, e.g. dragging the mouse for zooming, can be aborted by pressing the ESC key.
|
||||
</descr>
|
||||
</element>
|
||||
</module>
|
||||
</package>
|
||||
</fpdoc-descriptions>
|
@ -1,3 +1,24 @@
|
||||
{
|
||||
/***************************************************************************
|
||||
TAChartLiveView.pas
|
||||
-------------------
|
||||
|
||||
TChartLiveView is a component optimized for displaying a long array of incoming
|
||||
data in a viewport with only the most recent data while older data are flowing
|
||||
to the left out of the viewport.
|
||||
|
||||
It was created based on the following forum discussions:
|
||||
- https://forum.lazarus.freepascal.org/index.php/topic,15037.html
|
||||
- https://forum.lazarus.freepascal.org/index.php/topic,50759.0.html
|
||||
- https://forum.lazarus.freepascal.org/index.php/topic,55266.html
|
||||
|
||||
See the file COPYING.modifiedLGPL.txt, included in this distribution,
|
||||
for details about the license.
|
||||
*****************************************************************************
|
||||
|
||||
Author: Werner Pamler
|
||||
}
|
||||
|
||||
unit TAChartLiveView;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
@ -8,21 +29,33 @@ uses
|
||||
Classes, SysUtils, TAGraph, TAChartUtils;
|
||||
|
||||
type
|
||||
TChartLiveViewExtentY = (lveAuto, lveFull, lveLogical);
|
||||
TChartLiveViewExtentY = (lveAuto, lveFull, lveLogical, lveMultiAxisRange);
|
||||
|
||||
{ TChartLiveView }
|
||||
|
||||
TChartLiveView = class(TComponent)
|
||||
private
|
||||
type
|
||||
TLVAxisRange = record
|
||||
Min, Max: double;
|
||||
UseMin, UseMax: Boolean;
|
||||
end;
|
||||
private
|
||||
FActive: Boolean;
|
||||
FChart: TChart;
|
||||
FExtentY: TChartLiveViewExtentY;
|
||||
FListener: TListener;
|
||||
FViewportSize: Double;
|
||||
FAxisRanges: Array of TLVAxisRange;
|
||||
procedure FullExtentChanged(Sender: TObject);
|
||||
procedure SetActive(const AValue: Boolean);
|
||||
procedure SetChart(const AValue: TChart);
|
||||
procedure SetExtentY(const AValue: TChartLiveViewExtentY);
|
||||
procedure SetViewportSize(const AValue: Double);
|
||||
procedure UpdateViewport;
|
||||
protected
|
||||
procedure RestoreAxisRanges;
|
||||
procedure StoreAxisRanges;
|
||||
public
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
@ -39,7 +72,7 @@ procedure Register;
|
||||
implementation
|
||||
|
||||
uses
|
||||
Math, TACustomSeries;
|
||||
Math, TAChartAxis, TAChartAxisUtils, TACustomSeries;
|
||||
|
||||
constructor TChartLiveView.Create(AOwner: TComponent);
|
||||
begin
|
||||
@ -53,6 +86,8 @@ begin
|
||||
inherited;
|
||||
end;
|
||||
|
||||
{ A new data point has been added to the chart so that the full extent changes.
|
||||
As a consequence the viewport of the live view must be updated. }
|
||||
procedure TChartLiveView.FullExtentChanged(Sender: TObject);
|
||||
begin
|
||||
if (not FActive) or (FChart = nil) then
|
||||
@ -60,14 +95,46 @@ begin
|
||||
UpdateViewport;
|
||||
end;
|
||||
|
||||
procedure TChartLiveView.RestoreAxisRanges;
|
||||
var
|
||||
i: Integer;
|
||||
ax: TChartAxis;
|
||||
begin
|
||||
if FChart = nil then
|
||||
exit;
|
||||
|
||||
for i := 0 to FChart.AxisList.Count-1 do
|
||||
begin
|
||||
ax := FChart.AxisList[i];
|
||||
ax.Range.Max := FAxisRanges[i].Max;
|
||||
ax.Range.Min := FAxisRanges[i].Min;
|
||||
ax.Range.UseMax := FAxisRanges[i].UseMax;
|
||||
ax.Range.UseMin := FAxisRanges[i].UseMin;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ Activates the live view mode. Because the Range of the y axes can be changed
|
||||
their current Range is stored before activating, and restored after
|
||||
deactivating the mode. }
|
||||
procedure TChartLiveView.SetActive(const AValue: Boolean);
|
||||
begin
|
||||
if FActive = AValue then exit;
|
||||
|
||||
FActive := AValue;
|
||||
if FChart <> nil then
|
||||
begin
|
||||
if FActive then
|
||||
StoreAxisRanges
|
||||
else
|
||||
RestoreAxisRanges;
|
||||
end;
|
||||
|
||||
FullExtentChanged(nil);
|
||||
end;
|
||||
|
||||
{ Attaches the chart on which the liveview operates. Installs a "listener"
|
||||
object so that the liveview can be notified of a change in the chart's full
|
||||
extent when a new data point has been added (method FullExtentChanged). }
|
||||
procedure TChartLiveView.SetChart(const AValue: TChart);
|
||||
begin
|
||||
if FChart = AValue then exit;
|
||||
@ -77,6 +144,7 @@ begin
|
||||
FChart := AValue;
|
||||
if FChart <> nil then
|
||||
FChart.FullExtentBroadcaster.Subscribe(FListener);
|
||||
StoreAxisRanges;
|
||||
FullExtentChanged(Self);
|
||||
end;
|
||||
|
||||
@ -84,30 +152,54 @@ procedure TChartLiveview.SetExtentY(const AValue: TChartLiveViewExtentY);
|
||||
begin
|
||||
if FExtentY = AValue then exit;
|
||||
FExtentY := AValue;
|
||||
RestoreAxisRanges;
|
||||
FullExtentChanged(nil);
|
||||
end;
|
||||
|
||||
procedure TChartLiveView.SetViewportSize(const AValue: Double);
|
||||
begin
|
||||
if FViewportSize = AValue then exit;
|
||||
|
||||
FViewportSize := AValue;
|
||||
FullExtentChanged(nil);
|
||||
end;
|
||||
|
||||
procedure TChartLiveView.StoreAxisRanges;
|
||||
var
|
||||
i: Integer;
|
||||
ax: TChartAxis;
|
||||
begin
|
||||
SetLength(FAxisRanges, FChart.AxisList.Count);
|
||||
for i := 0 to FChart.AxisList.Count-1 do
|
||||
begin
|
||||
ax := FChart.AxisList[i];
|
||||
FAxisRanges[i].Max := ax.Range.Max;
|
||||
FAxisRanges[i].Min := ax.Range.Min;
|
||||
FAxisRanges[i].UseMax := ax.Range.UseMax;
|
||||
FAxisRanges[i].UseMin := ax.Range.UseMin;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ "Workhorse" method of the component. It calculates the logical extent and
|
||||
the axis ranges needed to display only the recent data values in the
|
||||
given viewport. }
|
||||
procedure TChartLiveView.UpdateViewport;
|
||||
var
|
||||
fext, lext: TDoubleRect;
|
||||
fext, lext: TDoubleRect; // "full extent", "logical extent" variables
|
||||
w: double;
|
||||
i: Integer;
|
||||
i, j: Integer;
|
||||
ymin, ymax: Double;
|
||||
ygmin, ygmax: Double;
|
||||
ser: TChartSeries;
|
||||
ax: TChartAxis;
|
||||
begin
|
||||
if not FChart.ScalingValid then
|
||||
exit;
|
||||
|
||||
if Length(FAxisRanges) = 0 then
|
||||
StoreAxisRanges;
|
||||
|
||||
fext := FChart.GetFullExtent();
|
||||
lext := FChart.LogicalExtent;
|
||||
w := lext.b.x - lext.a.x;
|
||||
if FViewportSize = 0 then
|
||||
w := lext.b.x - lext.a.x
|
||||
else
|
||||
@ -119,19 +211,6 @@ begin
|
||||
lext.b.x := lext.a.x + w;
|
||||
end;
|
||||
case FExtentY of
|
||||
lveAuto:
|
||||
begin
|
||||
ymin := Infinity;
|
||||
ymax := -Infinity;
|
||||
for i := 0 to FChart.SeriesCount-1 do
|
||||
if FChart.Series[i] is TChartSeries then
|
||||
TChartSeries(FChart.Series[i]).FindYRange(lext.a.x, lext.b.x, ymin, ymax);
|
||||
if (ymin <> Infinity) and (ymax <> -Infinity) then
|
||||
begin
|
||||
lext.a.y := ymin;
|
||||
lext.b.y := ymax;
|
||||
end;
|
||||
end;
|
||||
lveFull:
|
||||
begin
|
||||
lext.a.y := fext.a.y;
|
||||
@ -139,6 +218,57 @@ begin
|
||||
end;
|
||||
lveLogical:
|
||||
;
|
||||
lveAuto,
|
||||
lveMultiAxisRange:
|
||||
begin
|
||||
lext.a.y := Infinity;
|
||||
lext.b.y := -Infinity;
|
||||
for i := 0 to FChart.AxisList.Count-1 do
|
||||
begin
|
||||
ax := FChart.AxisList[i];
|
||||
// we only support scrolling along x, i.e. ax must be a y axis.
|
||||
if not (ax.Alignment in [calLeft, calRight]) then
|
||||
Continue;
|
||||
ymin := Infinity;
|
||||
ymax := -Infinity;
|
||||
for j := 0 to FChart.SeriesCount-1 do
|
||||
if FChart.Series[j] is TChartSeries then
|
||||
begin
|
||||
ser := TChartSeries(FChart.Series[j]);
|
||||
if (not ser.Active) or (ser.GetAxisY <> ax) or ser.IsRotated then
|
||||
continue;
|
||||
ser.FindYRange(lext.a.x, lext.b.x, ymin, ymax);
|
||||
end;
|
||||
if (ymin = Infinity) then
|
||||
begin
|
||||
ymin := -1;
|
||||
ymax := +1;
|
||||
end else
|
||||
if (ymin = ymax) then
|
||||
begin
|
||||
if ymin = 0 then
|
||||
begin
|
||||
ymin := -1;
|
||||
ymax := +1;
|
||||
end else
|
||||
begin
|
||||
ymin := abs(ymin) * 0.9;
|
||||
ymax := abs(ymax) * 1.1;
|
||||
end;
|
||||
end;
|
||||
ax.Range.Min := ymin;
|
||||
ax.Range.Max := ymax;
|
||||
if (FExtentY = lveMultiAxisRange) then
|
||||
begin
|
||||
if FAxisRanges[i].UseMin then ax.Range.Min := FAxisRanges[i].Min;
|
||||
if FAxisRanges[i].UseMax then ax.Range.Max := FAxisRanges[i].Max;
|
||||
end;
|
||||
ax.Range.UseMin := true;
|
||||
ax.Range.UseMax := true;
|
||||
lext.a.y := Min(lext.a.y, ax.GetTransform.AxisToGraph(ymin));
|
||||
lext.b.y := Max(lext.b.y, ax.GetTransform.AxisToGraph(ymax));
|
||||
end; // for i
|
||||
end;
|
||||
end;
|
||||
FChart.LogicalExtent := lext;
|
||||
end;
|
||||
|
@ -441,13 +441,17 @@ function TCustomChartSeries.GetAxisBounds(AAxis: TChartAxis;
|
||||
out AMin, AMax: Double): Boolean;
|
||||
var
|
||||
ex: TDoubleRect;
|
||||
axIndexX, axIndexY: Integer;
|
||||
begin
|
||||
if (AAxis.Index = AxisIndexX) or (AAxis.Index = AxisIndexY) then begin
|
||||
axIndexX := GetAxisX.Index;
|
||||
axIndexY := GetAxisY.Index;
|
||||
|
||||
if (AAxis.Index = axIndexX) or (AAxis.Index = axIndexY) then begin
|
||||
ex := EmptyExtent;
|
||||
GetBounds(ex);
|
||||
with ex do begin
|
||||
UpdateBoundsByAxisRange(FChart.AxisList, AxisIndexX, a.X, b.X);
|
||||
UpdateBoundsByAxisRange(FChart.AxisList, AxisIndexY, a.Y, b.Y);
|
||||
UpdateBoundsByAxisRange(FChart.AxisList, axIndexX, a.X, b.X);
|
||||
UpdateBoundsByAxisRange(FChart.AxisList, axIndexY, a.Y, b.Y);
|
||||
if IsRotated then begin
|
||||
Exchange(a.X, a.Y);
|
||||
Exchange(b.X, b.Y);
|
||||
|
@ -352,6 +352,7 @@ type
|
||||
procedure Draw(ADrawer: IChartDrawer; const ARect: TRect);
|
||||
procedure DrawLegendOn(ACanvas: TCanvas; var ARect: TRect);
|
||||
procedure EnableRedrawing;
|
||||
procedure GetAllSeriesAxisLimits(AAxis: TChartAxis; out AMin, AMax: Double);
|
||||
function GetFullExtent: TDoubleRect;
|
||||
function GetLegendItems(AIncludeHidden: Boolean = false): TChartLegendItems;
|
||||
procedure Notify(ACommand: Integer; AParam1, AParam2: Pointer; var AData); override;
|
||||
@ -1140,6 +1141,15 @@ begin
|
||||
AClass := nil;
|
||||
end;
|
||||
|
||||
procedure TChart.GetAllSeriesAxisLimits(AAxis: TChartAxis; out AMin, AMax: Double);
|
||||
var
|
||||
interval: TDoubleInterval;
|
||||
begin
|
||||
interval := GetAxisBounds(AAxis);
|
||||
AMin := interval.FStart;
|
||||
AMax := interval.FEnd;
|
||||
end;
|
||||
|
||||
function TChart.GetAxisBounds(AAxis: TChartAxis): TDoubleInterval;
|
||||
var
|
||||
s: TBasicChartSeries;
|
||||
|
@ -365,7 +365,8 @@ begin
|
||||
ADrawer.ClippingStop;
|
||||
|
||||
DrawLink(ADrawer, ADataPoint, ALabelCenter);
|
||||
ADrawer.Brush := GetLabelBrush;
|
||||
with GetLabelBrush do
|
||||
ADrawer.SetBrushParams(Style, ColorToRGB(Color));
|
||||
if IsMarginRequired then begin
|
||||
if GetFrame.Visible then
|
||||
ADrawer.Pen := GetFrame
|
||||
|
@ -751,6 +751,7 @@ begin
|
||||
diag := -ADrawer.Scale(Round(Sqrt(Sqr(Length) + Sqr(Width))));
|
||||
pt1 := AEndPos + RotatePointX(diag, AAngle - da)*sgn;
|
||||
pt2 := AEndPos + RotatePointX(diag, AAngle + da)*sgn;
|
||||
ADrawer.SetPenParams(psSolid, FPColorToTColor(APen.FPColor), APen.Width);
|
||||
if BaseLength > 0 then begin
|
||||
ptBase := AEndPos + RotatePointX(-ADrawer.Scale(BaseLength), AAngle)*sgn;
|
||||
ADrawer.SetBrushParams(bsSolid, FPColorToChartColor(APen.FPColor));
|
||||
|
Loading…
Reference in New Issue
Block a user