From 488a25bd427fbf8443b5b4b13bf79ff5e818649b Mon Sep 17 00:00:00 2001 From: darius Date: Thu, 11 Dec 2008 18:57:43 +0000 Subject: [PATCH] 1) Created new unit TAChartUtils, moved some support code into it. 2) Heavily refactored code of CalculateIntervals and TAGraph.DrawAxis procedures -- removed lots of duplicated code, simplifed logic, extracted local procedures etc. 3) Introduced TPenBrushFontRecall helper class. 4) Added 'Axis titles' checkbox to the demo program. Patch by Alexander Klenin Resolves: http://bugs.freepascal.org/view.php?id=12758 git-svn-id: trunk@17799 - --- components/tachart/demo/demo.lpi | 7 +- components/tachart/demo/unit1.lfm | 273 +------- components/tachart/demo/unit1.lrs | 229 ++---- components/tachart/demo/unit1.pas | 24 +- components/tachart/tachartlazaruspkg.lpk | 4 + components/tachart/tachartlazaruspkg.pas | 6 +- components/tachart/tagraph.pas | 856 ++++++++--------------- components/tachart/taseries.pas | 27 +- 8 files changed, 449 insertions(+), 977 deletions(-) diff --git a/components/tachart/demo/demo.lpi b/components/tachart/demo/demo.lpi index 3db88b739c..b54cabde83 100644 --- a/components/tachart/demo/demo.lpi +++ b/components/tachart/demo/demo.lpi @@ -32,7 +32,7 @@ - + @@ -46,6 +46,11 @@ + + + + + diff --git a/components/tachart/demo/unit1.lfm b/components/tachart/demo/unit1.lfm index b253f5d7f7..1ef8dab0c5 100644 --- a/components/tachart/demo/unit1.lfm +++ b/components/tachart/demo/unit1.lfm @@ -1,82 +1,50 @@ object Form1: TForm1 - Left = 470 + Left = 341 Height = 499 - Top = 248 + Top = 225 Width = 585 - HelpContext = 0 - ActiveControl = Panel1 Caption = 'Form1' - ChildSizing.LeftRightSpacing = 0 - ChildSizing.TopBottomSpacing = 0 - ChildSizing.HorizontalSpacing = 0 - ChildSizing.VerticalSpacing = 0 - ChildSizing.ControlsPerLine = 0 ClientHeight = 499 ClientWidth = 585 - Font.Height = 0 - Font.Style = [] Position = poScreenCenter LCLVersion = '0.9.27' object Chart1: TChart - Left = 0 Height = 408 - Top = 0 Width = 585 - HelpContext = 0 - XGraphMin = 0 - YGraphMin = 0 - XGraphMax = 0 - YGraphMax = 0 - MirrorX = False - ShowVerticalReticule = False - ShowReticule = False - Legend.Visible = False Legend.Alignment = laRight Legend.Font.Height = -11 Legend.Font.Name = 'MS Sans Serif' - Legend.Font.Style = [] Legend.Frame.Cosmetic = True - Legend.Frame.Visible = False Title.Visible = True Title.Brush.Color = clBtnFace Title.Font.Color = clBlue Title.Font.Height = -11 Title.Font.Name = 'MS Sans Serif' - Title.Font.Style = [] Title.Frame.Cosmetic = True - Title.Frame.Visible = False Title.Alignment = taCenter Title.Text.Strings = ( 'Centered Chart Title' ) - Foot.Visible = False Foot.Brush.Color = clBtnFace Foot.Font.Color = clRed Foot.Font.Height = -13 Foot.Font.Name = 'MS Sans Serif' Foot.Font.Style = [fsBold] Foot.Frame.Cosmetic = True - Foot.Frame.Visible = False - Foot.Alignment = taLeftJustify Foot.Text.Strings = ( 'This a LeftAligned Footer' ) LeftAxis.Visible = True - LeftAxis.Inverted = False LeftAxis.Title.Angle = 90 LeftAxis.Title.Font.Height = -11 LeftAxis.Title.Font.Name = 'MS Sans Serif' - LeftAxis.Title.Font.Style = [] LeftAxis.Grid.Color = clGray LeftAxis.Grid.Cosmetic = True LeftAxis.Grid.Style = psDot LeftAxis.Grid.Visible = True BottomAxis.Visible = True - BottomAxis.Inverted = False - BottomAxis.Title.Angle = 0 BottomAxis.Title.Font.Height = -11 BottomAxis.Title.Font.Name = 'MS Sans Serif' - BottomAxis.Title.Font.Style = [] BottomAxis.Grid.Color = clGray BottomAxis.Grid.Cosmetic = True BottomAxis.Grid.Style = psDot @@ -89,72 +57,34 @@ object Form1: TForm1 ParentColor = False end object Panel1: TPanel - Left = 0 Height = 91 Top = 408 Width = 585 - HelpContext = 0 Align = alBottom - BorderSpacing.Left = 0 - BorderSpacing.Top = 0 - BorderSpacing.Right = 0 - BorderSpacing.Bottom = 0 - BorderSpacing.Around = 0 - BorderSpacing.CellAlignHorizontal = ccaFill - BorderSpacing.CellAlignVertical = ccaFill - ChildSizing.LeftRightSpacing = 0 - ChildSizing.TopBottomSpacing = 0 - ChildSizing.HorizontalSpacing = 0 - ChildSizing.VerticalSpacing = 0 - ChildSizing.ControlsPerLine = 0 ClientHeight = 91 ClientWidth = 585 TabOrder = 0 object lblAdd: TLabel Left = 13 - Height = 18 + Height = 14 Top = 10 - Width = 30 - HelpContext = 0 - BorderSpacing.Left = 0 - BorderSpacing.Top = 0 - BorderSpacing.Right = 0 - BorderSpacing.Bottom = 0 - BorderSpacing.Around = 0 - BorderSpacing.CellAlignHorizontal = ccaFill - BorderSpacing.CellAlignVertical = ccaFill + Width = 24 Caption = 'Add:' ParentColor = False end - object lblAdd1: TLabel + object lblClear: TLabel Left = 13 - Height = 18 + Height = 14 Top = 40 - Width = 38 - HelpContext = 0 - BorderSpacing.Left = 0 - BorderSpacing.Top = 0 - BorderSpacing.Right = 0 - BorderSpacing.Bottom = 0 - BorderSpacing.Around = 0 - BorderSpacing.CellAlignHorizontal = ccaFill - BorderSpacing.CellAlignVertical = ccaFill + Width = 30 Caption = 'Clear:' ParentColor = False end - object Label1: TLabel + object lblAddCount: TLabel Left = 288 - Height = 18 + Height = 14 Top = 16 - Width = 78 - HelpContext = 0 - BorderSpacing.Left = 0 - BorderSpacing.Top = 0 - BorderSpacing.Right = 0 - BorderSpacing.Bottom = 0 - BorderSpacing.Around = 0 - BorderSpacing.CellAlignHorizontal = ccaFill - BorderSpacing.CellAlignVertical = ccaFill + Width = 58 Caption = 'Multiple add' ParentColor = False end @@ -163,15 +93,7 @@ object Form1: TForm1 Height = 24 Top = 8 Width = 52 - HelpContext = 0 - BorderSpacing.Left = 0 - BorderSpacing.Top = 0 - BorderSpacing.Right = 0 - BorderSpacing.Bottom = 0 - BorderSpacing.Around = 0 BorderSpacing.InnerBorder = 4 - BorderSpacing.CellAlignHorizontal = ccaFill - BorderSpacing.CellAlignVertical = ccaFill Caption = 'Pie' OnClick = btnAddPieClick TabOrder = 0 @@ -181,15 +103,7 @@ object Form1: TForm1 Height = 24 Top = 8 Width = 52 - HelpContext = 0 - BorderSpacing.Left = 0 - BorderSpacing.Top = 0 - BorderSpacing.Right = 0 - BorderSpacing.Bottom = 0 - BorderSpacing.Around = 0 BorderSpacing.InnerBorder = 4 - BorderSpacing.CellAlignHorizontal = ccaFill - BorderSpacing.CellAlignVertical = ccaFill Caption = 'Line' OnClick = btnAddLineClick TabOrder = 1 @@ -199,15 +113,7 @@ object Form1: TForm1 Height = 24 Top = 8 Width = 52 - HelpContext = 0 - BorderSpacing.Left = 0 - BorderSpacing.Top = 0 - BorderSpacing.Right = 0 - BorderSpacing.Bottom = 0 - BorderSpacing.Around = 0 BorderSpacing.InnerBorder = 4 - BorderSpacing.CellAlignHorizontal = ccaFill - BorderSpacing.CellAlignVertical = ccaFill Caption = 'Area' OnClick = btnAddAreaClick TabOrder = 2 @@ -217,150 +123,77 @@ object Form1: TForm1 Height = 24 Top = 8 Width = 52 - HelpContext = 0 - BorderSpacing.Left = 0 - BorderSpacing.Top = 0 - BorderSpacing.Right = 0 - BorderSpacing.Bottom = 0 - BorderSpacing.Around = 0 BorderSpacing.InnerBorder = 4 - BorderSpacing.CellAlignHorizontal = ccaFill - BorderSpacing.CellAlignVertical = ccaFill Caption = 'Bar' OnClick = btnAddBarClick TabOrder = 3 end object cbLegend: TCheckBox Left = 384 - Height = 22 + Height = 19 Top = 8 - Width = 71 - HelpContext = 0 - BorderSpacing.Left = 0 - BorderSpacing.Top = 0 - BorderSpacing.Right = 0 - BorderSpacing.Bottom = 0 - BorderSpacing.Around = 0 - BorderSpacing.CellAlignHorizontal = ccaFill - BorderSpacing.CellAlignVertical = ccaFill + Width = 61 Caption = 'Legend' OnChange = cbLegendChange - State = cbUnchecked TabOrder = 4 - UseOnChange = False end object cbBottomAxis: TCheckBox Left = 384 - Height = 22 + Height = 19 Top = 24 - Width = 102 - HelpContext = 0 - BorderSpacing.Left = 0 - BorderSpacing.Top = 0 - BorderSpacing.Right = 0 - BorderSpacing.Bottom = 0 - BorderSpacing.Around = 0 - BorderSpacing.CellAlignHorizontal = ccaFill - BorderSpacing.CellAlignVertical = ccaFill + Width = 83 Caption = 'Bottom Axis' Checked = True OnChange = cbBottomAxisChange State = cbChecked TabOrder = 5 - UseOnChange = False end object cbLeftAxis: TCheckBox Left = 384 - Height = 22 + Height = 19 Top = 40 - Width = 78 - HelpContext = 0 - BorderSpacing.Left = 0 - BorderSpacing.Top = 0 - BorderSpacing.Right = 0 - BorderSpacing.Bottom = 0 - BorderSpacing.Around = 0 - BorderSpacing.CellAlignHorizontal = ccaFill - BorderSpacing.CellAlignVertical = ccaFill + Width = 68 Caption = 'Left Axis' Checked = True OnChange = cbLeftAxisChange State = cbChecked TabOrder = 6 - UseOnChange = False end object cbTitle: TCheckBox Left = 496 - Height = 22 + Height = 19 Top = 8 - Width = 50 - HelpContext = 0 - BorderSpacing.Left = 0 - BorderSpacing.Top = 0 - BorderSpacing.Right = 0 - BorderSpacing.Bottom = 0 - BorderSpacing.Around = 0 - BorderSpacing.CellAlignHorizontal = ccaFill - BorderSpacing.CellAlignVertical = ccaFill + Width = 46 Caption = 'Title' Checked = True OnChange = cbTitleChange State = cbChecked TabOrder = 7 - UseOnChange = False end object cbFooter: TCheckBox Left = 496 - Height = 22 + Height = 19 Top = 24 - Width = 65 - HelpContext = 0 - BorderSpacing.Left = 0 - BorderSpacing.Top = 0 - BorderSpacing.Right = 0 - BorderSpacing.Bottom = 0 - BorderSpacing.Around = 0 - BorderSpacing.CellAlignHorizontal = ccaFill - BorderSpacing.CellAlignVertical = ccaFill + Width = 58 Caption = 'Footer' OnChange = cbFooterChange - State = cbUnchecked TabOrder = 8 - UseOnChange = False end object cbInverted: TCheckBox Left = 496 - Height = 22 + Height = 19 Top = 40 - Width = 76 - HelpContext = 0 - BorderSpacing.Left = 0 - BorderSpacing.Top = 0 - BorderSpacing.Right = 0 - BorderSpacing.Bottom = 0 - BorderSpacing.Around = 0 - BorderSpacing.CellAlignHorizontal = ccaFill - BorderSpacing.CellAlignVertical = ccaFill + Width = 68 Caption = 'Inverted' OnChange = cbInvertedChange - State = cbUnchecked TabOrder = 9 - UseOnChange = False end object btnClearBar: TButton Left = 160 Height = 24 Top = 38 Width = 52 - HelpContext = 0 - BorderSpacing.Left = 0 - BorderSpacing.Top = 0 - BorderSpacing.Right = 0 - BorderSpacing.Bottom = 0 - BorderSpacing.Around = 0 BorderSpacing.InnerBorder = 4 - BorderSpacing.CellAlignHorizontal = ccaFill - BorderSpacing.CellAlignVertical = ccaFill Caption = 'Bar' OnClick = btnClearBarClick TabOrder = 10 @@ -370,15 +203,7 @@ object Form1: TForm1 Height = 24 Top = 38 Width = 52 - HelpContext = 0 - BorderSpacing.Left = 0 - BorderSpacing.Top = 0 - BorderSpacing.Right = 0 - BorderSpacing.Bottom = 0 - BorderSpacing.Around = 0 BorderSpacing.InnerBorder = 4 - BorderSpacing.CellAlignHorizontal = ccaFill - BorderSpacing.CellAlignVertical = ccaFill Caption = 'Area' OnClick = btnClearAreaClick TabOrder = 11 @@ -388,15 +213,7 @@ object Form1: TForm1 Height = 24 Top = 38 Width = 52 - HelpContext = 0 - BorderSpacing.Left = 0 - BorderSpacing.Top = 0 - BorderSpacing.Right = 0 - BorderSpacing.Bottom = 0 - BorderSpacing.Around = 0 BorderSpacing.InnerBorder = 4 - BorderSpacing.CellAlignHorizontal = ccaFill - BorderSpacing.CellAlignVertical = ccaFill Caption = 'Line' OnClick = btnClearLineClick TabOrder = 12 @@ -406,15 +223,7 @@ object Form1: TForm1 Height = 24 Top = 38 Width = 52 - HelpContext = 0 - BorderSpacing.Left = 0 - BorderSpacing.Top = 0 - BorderSpacing.Right = 0 - BorderSpacing.Bottom = 0 - BorderSpacing.Around = 0 BorderSpacing.InnerBorder = 4 - BorderSpacing.CellAlignHorizontal = ccaFill - BorderSpacing.CellAlignVertical = ccaFill Caption = 'Pie' OnClick = btnClearPieClick TabOrder = 13 @@ -424,41 +233,33 @@ object Form1: TForm1 Height = 21 Top = 41 Width = 90 - HelpContext = 0 - BorderSpacing.Left = 0 - BorderSpacing.Top = 0 - BorderSpacing.Right = 0 - BorderSpacing.Bottom = 0 - BorderSpacing.Around = 0 - BorderSpacing.CellAlignHorizontal = ccaFill - BorderSpacing.CellAlignVertical = ccaFill MaxValue = 1000000 MinValue = 1 TabOrder = 14 Value = 1 end - object ShowGridCheckBox: TCheckBox + object edShowGridCheckBox: TCheckBox AnchorSideLeft.Control = cbLeftAxis AnchorSideTop.Control = cbLeftAxis AnchorSideTop.Side = asrBottom - Left = -360 - Height = 23 - Top = 56 - Width = 90 - HelpContext = 0 - BorderSpacing.Left = 0 - BorderSpacing.Top = 0 - BorderSpacing.Right = 0 - BorderSpacing.Bottom = 0 - BorderSpacing.Around = 0 - BorderSpacing.CellAlignHorizontal = ccaFill - BorderSpacing.CellAlignVertical = ccaFill + Left = 384 + Height = 19 + Top = 59 + Width = 76 Caption = 'Show grid ' Checked = True - OnChange = ShowGridCheckBoxChange + OnChange = edShowGridCheckBoxChange State = cbChecked TabOrder = 15 - UseOnChange = False + end + object cbShowAxisTitles: TCheckBox + Left = 496 + Height = 19 + Top = 59 + Width = 72 + Caption = 'Axis titles' + OnChange = cbShowAxisTitlesChange + TabOrder = 16 end end end diff --git a/components/tachart/demo/unit1.lrs b/components/tachart/demo/unit1.lrs index 049ddd071d..a92f5c78fa 100644 --- a/components/tachart/demo/unit1.lrs +++ b/components/tachart/demo/unit1.lrs @@ -1,159 +1,74 @@ -{ This is an automatically generated lazarus resource file } - LazarusResources.Add('TForm1','FORMDATA',[ - 'TPF0'#6'TForm1'#5'Form1'#4'Left'#3#214#1#6'Height'#3#243#1#3'Top'#3#248#0#5 - +'Width'#3'I'#2#11'HelpContext'#2#0#13'ActiveControl'#7#6'Panel1'#7'Caption'#6 - +#5'Form1'#28'ChildSizing.LeftRightSpacing'#2#0#28'ChildSizing.TopBottomSpaci' - +'ng'#2#0#29'ChildSizing.HorizontalSpacing'#2#0#27'ChildSizing.VerticalSpacin' - +'g'#2#0#27'ChildSizing.ControlsPerLine'#2#0#12'ClientHeight'#3#243#1#11'Clie' - +'ntWidth'#3'I'#2#11'Font.Height'#2#0#10'Font.Style'#11#0#8'Position'#7#14'po' - +'ScreenCenter'#10'LCLVersion'#6#6'0.9.27'#0#6'TChart'#6'Chart1'#4'Left'#2#0#6 - +'Height'#3#152#1#3'Top'#2#0#5'Width'#3'I'#2#11'HelpContext'#2#0#9'XGraphMin' - +#5#0#0#0#0#0#0#0#0#0#0#9'YGraphMin'#5#0#0#0#0#0#0#0#0#0#0#9'XGraphMax'#5#0#0 - +#0#0#0#0#0#0#0#0#9'YGraphMax'#5#0#0#0#0#0#0#0#0#0#0#7'MirrorX'#8#20'ShowVert' - +'icalReticule'#8#12'ShowReticule'#8#14'Legend.Visible'#8#16'Legend.Alignment' - +#7#7'laRight'#18'Legend.Font.Height'#2#245#16'Legend.Font.Name'#6#13'MS Sans' - +' Serif'#17'Legend.Font.Style'#11#0#21'Legend.Frame.Cosmetic'#9#20'Legend.Fr' - +'ame.Visible'#8#13'Title.Visible'#9#17'Title.Brush.Color'#7#9'clBtnFace'#16 - +'Title.Font.Color'#7#6'clBlue'#17'Title.Font.Height'#2#245#15'Title.Font.Nam' - +'e'#6#13'MS Sans Serif'#16'Title.Font.Style'#11#0#20'Title.Frame.Cosmetic'#9 - +#19'Title.Frame.Visible'#8#15'Title.Alignment'#7#8'taCenter'#18'Title.Text.S' - +'trings'#1#6#20'Centered Chart Title'#0#12'Foot.Visible'#8#16'Foot.Brush.Col' - +'or'#7#9'clBtnFace'#15'Foot.Font.Color'#7#5'clRed'#16'Foot.Font.Height'#2#243 - +#14'Foot.Font.Name'#6#13'MS Sans Serif'#15'Foot.Font.Style'#11#6'fsBold'#0#19 - +'Foot.Frame.Cosmetic'#9#18'Foot.Frame.Visible'#8#14'Foot.Alignment'#7#13'taL' - +'eftJustify'#17'Foot.Text.Strings'#1#6#25'This a LeftAligned Footer'#0#16'Le' - +'ftAxis.Visible'#9#17'LeftAxis.Inverted'#8#20'LeftAxis.Title.Angle'#2'Z'#26 - +'LeftAxis.Title.Font.Height'#2#245#24'LeftAxis.Title.Font.Name'#6#13'MS Sans' - +' Serif'#25'LeftAxis.Title.Font.Style'#11#0#19'LeftAxis.Grid.Color'#7#6'clGr' - +'ay'#22'LeftAxis.Grid.Cosmetic'#9#19'LeftAxis.Grid.Style'#7#5'psDot'#21'Left' - +'Axis.Grid.Visible'#9#18'BottomAxis.Visible'#9#19'BottomAxis.Inverted'#8#22 - +'BottomAxis.Title.Angle'#2#0#28'BottomAxis.Title.Font.Height'#2#245#26'Botto' - +'mAxis.Title.Font.Name'#6#13'MS Sans Serif'#27'BottomAxis.Title.Font.Style' - +#11#0#21'BottomAxis.Grid.Color'#7#6'clGray'#24'BottomAxis.Grid.Cosmetic'#9#21 - +'BottomAxis.Grid.Style'#7#5'psDot'#23'BottomAxis.Grid.Visible'#9#14'Frame.Co' - +'smetic'#9#13'Frame.Visible'#9#9'BackColor'#7#9'clBtnFace'#5'Align'#7#8'alCl' - +'ient'#5'Color'#7#9'clBtnFace'#11'ParentColor'#8#0#0#6'TPanel'#6'Panel1'#4'L' - +'eft'#2#0#6'Height'#2'['#3'Top'#3#152#1#5'Width'#3'I'#2#11'HelpContext'#2#0#5 - +'Align'#7#8'alBottom'#18'BorderSpacing.Left'#2#0#17'BorderSpacing.Top'#2#0#19 - +'BorderSpacing.Right'#2#0#20'BorderSpacing.Bottom'#2#0#20'BorderSpacing.Arou' - +'nd'#2#0'!BorderSpacing.CellAlignHorizontal'#7#7'ccaFill'#31'BorderSpacing.C' - +'ellAlignVertical'#7#7'ccaFill'#28'ChildSizing.LeftRightSpacing'#2#0#28'Chil' - +'dSizing.TopBottomSpacing'#2#0#29'ChildSizing.HorizontalSpacing'#2#0#27'Chil' - +'dSizing.VerticalSpacing'#2#0#27'ChildSizing.ControlsPerLine'#2#0#12'ClientH' - +'eight'#2'['#11'ClientWidth'#3'I'#2#8'TabOrder'#2#0#0#6'TLabel'#6'lblAdd'#4 - +'Left'#2#13#6'Height'#2#18#3'Top'#2#10#5'Width'#2#30#11'HelpContext'#2#0#18 - +'BorderSpacing.Left'#2#0#17'BorderSpacing.Top'#2#0#19'BorderSpacing.Right'#2 - +#0#20'BorderSpacing.Bottom'#2#0#20'BorderSpacing.Around'#2#0'!BorderSpacing.' - +'CellAlignHorizontal'#7#7'ccaFill'#31'BorderSpacing.CellAlignVertical'#7#7'c' - +'caFill'#7'Caption'#6#4'Add:'#11'ParentColor'#8#0#0#6'TLabel'#7'lblAdd1'#4'L' - +'eft'#2#13#6'Height'#2#18#3'Top'#2'('#5'Width'#2'&'#11'HelpContext'#2#0#18'B' - +'orderSpacing.Left'#2#0#17'BorderSpacing.Top'#2#0#19'BorderSpacing.Right'#2#0 - +#20'BorderSpacing.Bottom'#2#0#20'BorderSpacing.Around'#2#0'!BorderSpacing.Ce' - +'llAlignHorizontal'#7#7'ccaFill'#31'BorderSpacing.CellAlignVertical'#7#7'cca' - +'Fill'#7'Caption'#6#6'Clear:'#11'ParentColor'#8#0#0#6'TLabel'#6'Label1'#4'Le' - +'ft'#3' '#1#6'Height'#2#18#3'Top'#2#16#5'Width'#2'N'#11'HelpContext'#2#0#18 - +'BorderSpacing.Left'#2#0#17'BorderSpacing.Top'#2#0#19'BorderSpacing.Right'#2 - +#0#20'BorderSpacing.Bottom'#2#0#20'BorderSpacing.Around'#2#0'!BorderSpacing.' - +'CellAlignHorizontal'#7#7'ccaFill'#31'BorderSpacing.CellAlignVertical'#7#7'c' - +'caFill'#7'Caption'#6#12'Multiple add'#11'ParentColor'#8#0#0#7'TButton'#9'bt' - +'nAddPie'#4'Left'#2'0'#6'Height'#2#24#3'Top'#2#8#5'Width'#2'4'#11'HelpContex' - +'t'#2#0#18'BorderSpacing.Left'#2#0#17'BorderSpacing.Top'#2#0#19'BorderSpacin' - +'g.Right'#2#0#20'BorderSpacing.Bottom'#2#0#20'BorderSpacing.Around'#2#0#25'B' - +'orderSpacing.InnerBorder'#2#4'!BorderSpacing.CellAlignHorizontal'#7#7'ccaFi' - +'ll'#31'BorderSpacing.CellAlignVertical'#7#7'ccaFill'#7'Caption'#6#3'Pie'#7 - +'OnClick'#7#14'btnAddPieClick'#8'TabOrder'#2#0#0#0#7'TButton'#10'btnAddLine' - +#4'Left'#3#216#0#6'Height'#2#24#3'Top'#2#8#5'Width'#2'4'#11'HelpContext'#2#0 - +#18'BorderSpacing.Left'#2#0#17'BorderSpacing.Top'#2#0#19'BorderSpacing.Right' - ,#2#0#20'BorderSpacing.Bottom'#2#0#20'BorderSpacing.Around'#2#0#25'BorderSpac' - +'ing.InnerBorder'#2#4'!BorderSpacing.CellAlignHorizontal'#7#7'ccaFill'#31'Bo' - +'rderSpacing.CellAlignVertical'#7#7'ccaFill'#7'Caption'#6#4'Line'#7'OnClick' - +#7#15'btnAddLineClick'#8'TabOrder'#2#1#0#0#7'TButton'#10'btnAddArea'#4'Left' - +#2'h'#6'Height'#2#24#3'Top'#2#8#5'Width'#2'4'#11'HelpContext'#2#0#18'BorderS' - +'pacing.Left'#2#0#17'BorderSpacing.Top'#2#0#19'BorderSpacing.Right'#2#0#20'B' - +'orderSpacing.Bottom'#2#0#20'BorderSpacing.Around'#2#0#25'BorderSpacing.Inne' - +'rBorder'#2#4'!BorderSpacing.CellAlignHorizontal'#7#7'ccaFill'#31'BorderSpac' - +'ing.CellAlignVertical'#7#7'ccaFill'#7'Caption'#6#4'Area'#7'OnClick'#7#15'bt' - +'nAddAreaClick'#8'TabOrder'#2#2#0#0#7'TButton'#9'btnAddBar'#4'Left'#3#160#0#6 - +'Height'#2#24#3'Top'#2#8#5'Width'#2'4'#11'HelpContext'#2#0#18'BorderSpacing.' - +'Left'#2#0#17'BorderSpacing.Top'#2#0#19'BorderSpacing.Right'#2#0#20'BorderSp' - +'acing.Bottom'#2#0#20'BorderSpacing.Around'#2#0#25'BorderSpacing.InnerBorder' - +#2#4'!BorderSpacing.CellAlignHorizontal'#7#7'ccaFill'#31'BorderSpacing.CellA' - +'lignVertical'#7#7'ccaFill'#7'Caption'#6#3'Bar'#7'OnClick'#7#14'btnAddBarCli' - +'ck'#8'TabOrder'#2#3#0#0#9'TCheckBox'#8'cbLegend'#4'Left'#3#128#1#6'Height'#2 - +#22#3'Top'#2#8#5'Width'#2'G'#11'HelpContext'#2#0#18'BorderSpacing.Left'#2#0 - +#17'BorderSpacing.Top'#2#0#19'BorderSpacing.Right'#2#0#20'BorderSpacing.Bott' - +'om'#2#0#20'BorderSpacing.Around'#2#0'!BorderSpacing.CellAlignHorizontal'#7#7 - +'ccaFill'#31'BorderSpacing.CellAlignVertical'#7#7'ccaFill'#7'Caption'#6#6'Le' - +'gend'#8'OnChange'#7#14'cbLegendChange'#5'State'#7#11'cbUnchecked'#8'TabOrde' - +'r'#2#4#11'UseOnChange'#8#0#0#9'TCheckBox'#12'cbBottomAxis'#4'Left'#3#128#1#6 - +'Height'#2#22#3'Top'#2#24#5'Width'#2'f'#11'HelpContext'#2#0#18'BorderSpacing' - +'.Left'#2#0#17'BorderSpacing.Top'#2#0#19'BorderSpacing.Right'#2#0#20'BorderS' - +'pacing.Bottom'#2#0#20'BorderSpacing.Around'#2#0'!BorderSpacing.CellAlignHor' - +'izontal'#7#7'ccaFill'#31'BorderSpacing.CellAlignVertical'#7#7'ccaFill'#7'Ca' - +'ption'#6#11'Bottom Axis'#7'Checked'#9#8'OnChange'#7#18'cbBottomAxisChange'#5 - +'State'#7#9'cbChecked'#8'TabOrder'#2#5#11'UseOnChange'#8#0#0#9'TCheckBox'#10 - +'cbLeftAxis'#4'Left'#3#128#1#6'Height'#2#22#3'Top'#2'('#5'Width'#2'N'#11'Hel' - +'pContext'#2#0#18'BorderSpacing.Left'#2#0#17'BorderSpacing.Top'#2#0#19'Borde' - +'rSpacing.Right'#2#0#20'BorderSpacing.Bottom'#2#0#20'BorderSpacing.Around'#2 - +#0'!BorderSpacing.CellAlignHorizontal'#7#7'ccaFill'#31'BorderSpacing.CellAli' - +'gnVertical'#7#7'ccaFill'#7'Caption'#6#9'Left Axis'#7'Checked'#9#8'OnChange' - +#7#16'cbLeftAxisChange'#5'State'#7#9'cbChecked'#8'TabOrder'#2#6#11'UseOnChan' - +'ge'#8#0#0#9'TCheckBox'#7'cbTitle'#4'Left'#3#240#1#6'Height'#2#22#3'Top'#2#8 - +#5'Width'#2'2'#11'HelpContext'#2#0#18'BorderSpacing.Left'#2#0#17'BorderSpaci' - +'ng.Top'#2#0#19'BorderSpacing.Right'#2#0#20'BorderSpacing.Bottom'#2#0#20'Bor' - +'derSpacing.Around'#2#0'!BorderSpacing.CellAlignHorizontal'#7#7'ccaFill'#31 - +'BorderSpacing.CellAlignVertical'#7#7'ccaFill'#7'Caption'#6#5'Title'#7'Check' - +'ed'#9#8'OnChange'#7#13'cbTitleChange'#5'State'#7#9'cbChecked'#8'TabOrder'#2 - +#7#11'UseOnChange'#8#0#0#9'TCheckBox'#8'cbFooter'#4'Left'#3#240#1#6'Height'#2 - +#22#3'Top'#2#24#5'Width'#2'A'#11'HelpContext'#2#0#18'BorderSpacing.Left'#2#0 - +#17'BorderSpacing.Top'#2#0#19'BorderSpacing.Right'#2#0#20'BorderSpacing.Bott' - +'om'#2#0#20'BorderSpacing.Around'#2#0'!BorderSpacing.CellAlignHorizontal'#7#7 - +'ccaFill'#31'BorderSpacing.CellAlignVertical'#7#7'ccaFill'#7'Caption'#6#6'Fo' - +'oter'#8'OnChange'#7#14'cbFooterChange'#5'State'#7#11'cbUnchecked'#8'TabOrde' - +'r'#2#8#11'UseOnChange'#8#0#0#9'TCheckBox'#10'cbInverted'#4'Left'#3#240#1#6 - +'Height'#2#22#3'Top'#2'('#5'Width'#2'L'#11'HelpContext'#2#0#18'BorderSpacing' - +'.Left'#2#0#17'BorderSpacing.Top'#2#0#19'BorderSpacing.Right'#2#0#20'BorderS' - +'pacing.Bottom'#2#0#20'BorderSpacing.Around'#2#0'!BorderSpacing.CellAlignHor' - +'izontal'#7#7'ccaFill'#31'BorderSpacing.CellAlignVertical'#7#7'ccaFill'#7'Ca' - +'ption'#6#8'Inverted'#8'OnChange'#7#16'cbInvertedChange'#5'State'#7#11'cbUnc' - +'hecked'#8'TabOrder'#2#9#11'UseOnChange'#8#0#0#7'TButton'#11'btnClearBar'#4 - +'Left'#3#160#0#6'Height'#2#24#3'Top'#2'&'#5'Width'#2'4'#11'HelpContext'#2#0 - +#18'BorderSpacing.Left'#2#0#17'BorderSpacing.Top'#2#0#19'BorderSpacing.Right' - +#2#0#20'BorderSpacing.Bottom'#2#0#20'BorderSpacing.Around'#2#0#25'BorderSpac' - +'ing.InnerBorder'#2#4'!BorderSpacing.CellAlignHorizontal'#7#7'ccaFill'#31'Bo' - +'rderSpacing.CellAlignVertical'#7#7'ccaFill'#7'Caption'#6#3'Bar'#7'OnClick'#7 - +#16'btnClearBarClick'#8'TabOrder'#2#10#0#0#7'TButton'#12'btnClearArea'#4'Lef' - +'t'#2'h'#6'Height'#2#24#3'Top'#2'&'#5'Width'#2'4'#11'HelpContext'#2#0#18'Bor' - +'derSpacing.Left'#2#0#17'BorderSpacing.Top'#2#0#19'BorderSpacing.Right'#2#0 - +#20'BorderSpacing.Bottom'#2#0#20'BorderSpacing.Around'#2#0#25'BorderSpacing.' - +'InnerBorder'#2#4'!BorderSpacing.CellAlignHorizontal'#7#7'ccaFill'#31'Border' - +'Spacing.CellAlignVertical'#7#7'ccaFill'#7'Caption'#6#4'Area'#7'OnClick'#7#17 - ,'btnClearAreaClick'#8'TabOrder'#2#11#0#0#7'TButton'#12'btnClearLine'#4'Left' - +#3#216#0#6'Height'#2#24#3'Top'#2'&'#5'Width'#2'4'#11'HelpContext'#2#0#18'Bor' - +'derSpacing.Left'#2#0#17'BorderSpacing.Top'#2#0#19'BorderSpacing.Right'#2#0 - +#20'BorderSpacing.Bottom'#2#0#20'BorderSpacing.Around'#2#0#25'BorderSpacing.' - +'InnerBorder'#2#4'!BorderSpacing.CellAlignHorizontal'#7#7'ccaFill'#31'Border' - +'Spacing.CellAlignVertical'#7#7'ccaFill'#7'Caption'#6#4'Line'#7'OnClick'#7#17 - +'btnClearLineClick'#8'TabOrder'#2#12#0#0#7'TButton'#11'btnClearPie'#4'Left'#2 - +'0'#6'Height'#2#24#3'Top'#2'&'#5'Width'#2'4'#11'HelpContext'#2#0#18'BorderSp' - +'acing.Left'#2#0#17'BorderSpacing.Top'#2#0#19'BorderSpacing.Right'#2#0#20'Bo' - +'rderSpacing.Bottom'#2#0#20'BorderSpacing.Around'#2#0#25'BorderSpacing.Inner' - +'Border'#2#4'!BorderSpacing.CellAlignHorizontal'#7#7'ccaFill'#31'BorderSpaci' - +'ng.CellAlignVertical'#7#7'ccaFill'#7'Caption'#6#3'Pie'#7'OnClick'#7#16'btnC' - +'learPieClick'#8'TabOrder'#2#13#0#0#9'TSpinEdit'#10'edAddCount'#4'Left'#3' ' - +#1#6'Height'#2#21#3'Top'#2')'#5'Width'#2'Z'#11'HelpContext'#2#0#18'BorderSpa' - +'cing.Left'#2#0#17'BorderSpacing.Top'#2#0#19'BorderSpacing.Right'#2#0#20'Bor' - +'derSpacing.Bottom'#2#0#20'BorderSpacing.Around'#2#0'!BorderSpacing.CellAlig' - +'nHorizontal'#7#7'ccaFill'#31'BorderSpacing.CellAlignVertical'#7#7'ccaFill'#8 - +'MaxValue'#4'@B'#15#0#8'MinValue'#2#1#8'TabOrder'#2#14#5'Value'#2#1#0#0#9'TC' - +'heckBox'#16'ShowGridCheckBox'#22'AnchorSideLeft.Control'#7#10'cbLeftAxis'#21 - +'AnchorSideTop.Control'#7#10'cbLeftAxis'#18'AnchorSideTop.Side'#7#9'asrBotto' - +'m'#4'Left'#3#152#254#6'Height'#2#23#3'Top'#2'8'#5'Width'#2'Z'#11'HelpContex' - +'t'#2#0#18'BorderSpacing.Left'#2#0#17'BorderSpacing.Top'#2#0#19'BorderSpacin' - +'g.Right'#2#0#20'BorderSpacing.Bottom'#2#0#20'BorderSpacing.Around'#2#0'!Bor' - +'derSpacing.CellAlignHorizontal'#7#7'ccaFill'#31'BorderSpacing.CellAlignVert' - +'ical'#7#7'ccaFill'#7'Caption'#6#10'Show grid '#7'Checked'#9#8'OnChange'#7#22 - +'ShowGridCheckBoxChange'#5'State'#7#9'cbChecked'#8'TabOrder'#2#15#11'UseOnCh' - +'ange'#8#0#0#0#0 + 'TPF0'#6'TForm1'#5'Form1'#4'Left'#3'U'#1#6'Height'#3#243#1#3'Top'#3#225#0#5'W' + +'idth'#3'I'#2#7'Caption'#6#5'Form1'#12'ClientHeight'#3#243#1#11'ClientWidth' + +#3'I'#2#8'Position'#7#14'poScreenCenter'#10'LCLVersion'#6#6'0.9.27'#0#6'TCha' + +'rt'#6'Chart1'#6'Height'#3#152#1#5'Width'#3'I'#2#16'Legend.Alignment'#7#7'la' + +'Right'#18'Legend.Font.Height'#2#245#16'Legend.Font.Name'#6#13'MS Sans Serif' + +#21'Legend.Frame.Cosmetic'#9#13'Title.Visible'#9#17'Title.Brush.Color'#7#9'c' + +'lBtnFace'#16'Title.Font.Color'#7#6'clBlue'#17'Title.Font.Height'#2#245#15'T' + +'itle.Font.Name'#6#13'MS Sans Serif'#20'Title.Frame.Cosmetic'#9#15'Title.Ali' + +'gnment'#7#8'taCenter'#18'Title.Text.Strings'#1#6#20'Centered Chart Title'#0 + +#16'Foot.Brush.Color'#7#9'clBtnFace'#15'Foot.Font.Color'#7#5'clRed'#16'Foot.' + +'Font.Height'#2#243#14'Foot.Font.Name'#6#13'MS Sans Serif'#15'Foot.Font.Styl' + +'e'#11#6'fsBold'#0#19'Foot.Frame.Cosmetic'#9#17'Foot.Text.Strings'#1#6#25'Th' + +'is a LeftAligned Footer'#0#16'LeftAxis.Visible'#9#20'LeftAxis.Title.Angle'#2 + +'Z'#26'LeftAxis.Title.Font.Height'#2#245#24'LeftAxis.Title.Font.Name'#6#13'M' + +'S Sans Serif'#19'LeftAxis.Grid.Color'#7#6'clGray'#22'LeftAxis.Grid.Cosmetic' + +#9#19'LeftAxis.Grid.Style'#7#5'psDot'#21'LeftAxis.Grid.Visible'#9#18'BottomA' + +'xis.Visible'#9#28'BottomAxis.Title.Font.Height'#2#245#26'BottomAxis.Title.F' + +'ont.Name'#6#13'MS Sans Serif'#21'BottomAxis.Grid.Color'#7#6'clGray'#24'Bott' + +'omAxis.Grid.Cosmetic'#9#21'BottomAxis.Grid.Style'#7#5'psDot'#23'BottomAxis.' + +'Grid.Visible'#9#14'Frame.Cosmetic'#9#13'Frame.Visible'#9#9'BackColor'#7#9'c' + +'lBtnFace'#5'Align'#7#8'alClient'#5'Color'#7#9'clBtnFace'#11'ParentColor'#8#0 + +#0#6'TPanel'#6'Panel1'#6'Height'#2'['#3'Top'#3#152#1#5'Width'#3'I'#2#5'Align' + +#7#8'alBottom'#12'ClientHeight'#2'['#11'ClientWidth'#3'I'#2#8'TabOrder'#2#0#0 + +#6'TLabel'#6'lblAdd'#4'Left'#2#13#6'Height'#2#14#3'Top'#2#10#5'Width'#2#24#7 + +'Caption'#6#4'Add:'#11'ParentColor'#8#0#0#6'TLabel'#8'lblClear'#4'Left'#2#13 + +#6'Height'#2#14#3'Top'#2'('#5'Width'#2#30#7'Caption'#6#6'Clear:'#11'ParentCo' + +'lor'#8#0#0#6'TLabel'#11'lblAddCount'#4'Left'#3' '#1#6'Height'#2#14#3'Top'#2 + +#16#5'Width'#2':'#7'Caption'#6#12'Multiple add'#11'ParentColor'#8#0#0#7'TBut' + +'ton'#9'btnAddPie'#4'Left'#2'0'#6'Height'#2#24#3'Top'#2#8#5'Width'#2'4'#25'B' + +'orderSpacing.InnerBorder'#2#4#7'Caption'#6#3'Pie'#7'OnClick'#7#14'btnAddPie' + +'Click'#8'TabOrder'#2#0#0#0#7'TButton'#10'btnAddLine'#4'Left'#3#216#0#6'Heig' + +'ht'#2#24#3'Top'#2#8#5'Width'#2'4'#25'BorderSpacing.InnerBorder'#2#4#7'Capti' + +'on'#6#4'Line'#7'OnClick'#7#15'btnAddLineClick'#8'TabOrder'#2#1#0#0#7'TButto' + +'n'#10'btnAddArea'#4'Left'#2'h'#6'Height'#2#24#3'Top'#2#8#5'Width'#2'4'#25'B' + +'orderSpacing.InnerBorder'#2#4#7'Caption'#6#4'Area'#7'OnClick'#7#15'btnAddAr' + +'eaClick'#8'TabOrder'#2#2#0#0#7'TButton'#9'btnAddBar'#4'Left'#3#160#0#6'Heig' + +'ht'#2#24#3'Top'#2#8#5'Width'#2'4'#25'BorderSpacing.InnerBorder'#2#4#7'Capti' + +'on'#6#3'Bar'#7'OnClick'#7#14'btnAddBarClick'#8'TabOrder'#2#3#0#0#9'TCheckBo' + +'x'#8'cbLegend'#4'Left'#3#128#1#6'Height'#2#19#3'Top'#2#8#5'Width'#2'='#7'Ca' + +'ption'#6#6'Legend'#8'OnChange'#7#14'cbLegendChange'#8'TabOrder'#2#4#0#0#9'T' + +'CheckBox'#12'cbBottomAxis'#4'Left'#3#128#1#6'Height'#2#19#3'Top'#2#24#5'Wid' + +'th'#2'S'#7'Caption'#6#11'Bottom Axis'#7'Checked'#9#8'OnChange'#7#18'cbBotto' + +'mAxisChange'#5'State'#7#9'cbChecked'#8'TabOrder'#2#5#0#0#9'TCheckBox'#10'cb' + +'LeftAxis'#4'Left'#3#128#1#6'Height'#2#19#3'Top'#2'('#5'Width'#2'D'#7'Captio' + +'n'#6#9'Left Axis'#7'Checked'#9#8'OnChange'#7#16'cbLeftAxisChange'#5'State'#7 + +#9'cbChecked'#8'TabOrder'#2#6#0#0#9'TCheckBox'#7'cbTitle'#4'Left'#3#240#1#6 + +'Height'#2#19#3'Top'#2#8#5'Width'#2'.'#7'Caption'#6#5'Title'#7'Checked'#9#8 + +'OnChange'#7#13'cbTitleChange'#5'State'#7#9'cbChecked'#8'TabOrder'#2#7#0#0#9 + +'TCheckBox'#8'cbFooter'#4'Left'#3#240#1#6'Height'#2#19#3'Top'#2#24#5'Width'#2 + +':'#7'Caption'#6#6'Footer'#8'OnChange'#7#14'cbFooterChange'#8'TabOrder'#2#8#0 + +#0#9'TCheckBox'#10'cbInverted'#4'Left'#3#240#1#6'Height'#2#19#3'Top'#2'('#5 + +'Width'#2'D'#7'Caption'#6#8'Inverted'#8'OnChange'#7#16'cbInvertedChange'#8'T' + +'abOrder'#2#9#0#0#7'TButton'#11'btnClearBar'#4'Left'#3#160#0#6'Height'#2#24#3 + +'Top'#2'&'#5'Width'#2'4'#25'BorderSpacing.InnerBorder'#2#4#7'Caption'#6#3'Ba' + +'r'#7'OnClick'#7#16'btnClearBarClick'#8'TabOrder'#2#10#0#0#7'TButton'#12'btn' + +'ClearArea'#4'Left'#2'h'#6'Height'#2#24#3'Top'#2'&'#5'Width'#2'4'#25'BorderS' + +'pacing.InnerBorder'#2#4#7'Caption'#6#4'Area'#7'OnClick'#7#17'btnClearAreaCl' + +'ick'#8'TabOrder'#2#11#0#0#7'TButton'#12'btnClearLine'#4'Left'#3#216#0#6'Hei' + +'ght'#2#24#3'Top'#2'&'#5'Width'#2'4'#25'BorderSpacing.InnerBorder'#2#4#7'Cap' + +'tion'#6#4'Line'#7'OnClick'#7#17'btnClearLineClick'#8'TabOrder'#2#12#0#0#7'T' + +'Button'#11'btnClearPie'#4'Left'#2'0'#6'Height'#2#24#3'Top'#2'&'#5'Width'#2 + +'4'#25'BorderSpacing.InnerBorder'#2#4#7'Caption'#6#3'Pie'#7'OnClick'#7#16'bt' + +'nClearPieClick'#8'TabOrder'#2#13#0#0#9'TSpinEdit'#10'edAddCount'#4'Left'#3 + +' '#1#6'Height'#2#21#3'Top'#2')'#5'Width'#2'Z'#8'MaxValue'#4'@B'#15#0#8'MinV' + ,'alue'#2#1#8'TabOrder'#2#14#5'Value'#2#1#0#0#9'TCheckBox'#18'edShowGridCheck' + +'Box'#22'AnchorSideLeft.Control'#7#10'cbLeftAxis'#21'AnchorSideTop.Control'#7 + +#10'cbLeftAxis'#18'AnchorSideTop.Side'#7#9'asrBottom'#4'Left'#3#128#1#6'Heig' + +'ht'#2#19#3'Top'#2';'#5'Width'#2'L'#7'Caption'#6#10'Show grid '#7'Checked'#9 + +#8'OnChange'#7#24'edShowGridCheckBoxChange'#5'State'#7#9'cbChecked'#8'TabOrd' + +'er'#2#15#0#0#9'TCheckBox'#16'cbShowAxisTitles'#4'Left'#3#240#1#6'Height'#2 + +#19#3'Top'#2';'#5'Width'#2'H'#7'Caption'#6#11'Axis titles'#8'OnChange'#7#22 + +'cbShowAxisTitlesChange'#8'TabOrder'#2#16#0#0#0#0 ]); diff --git a/components/tachart/demo/unit1.pas b/components/tachart/demo/unit1.pas index ae3575cf5d..2391d538fe 100644 --- a/components/tachart/demo/unit1.pas +++ b/components/tachart/demo/unit1.pas @@ -20,6 +20,7 @@ type btnAddPie: TButton; btnAddLine: TButton; btnAddArea: TButton; + cbShowAxisTitles: TCheckBox; Chart1: TChart; cbBottomAxis: TCheckBox; cbLeftAxis: TCheckBox; @@ -27,10 +28,10 @@ type cbFooter: TCheckBox; cbInverted: TCheckBox; cbLegend: TCheckBox; - ShowGridCheckBox: TCheckBox; - Label1: TLabel; + edShowGridCheckBox: TCheckBox; + lblAddCount: TLabel; lblAdd: TLabel; - lblAdd1: TLabel; + lblClear: TLabel; Panel1: TPanel; edAddCount: TSpinEdit; procedure btnClearAreaClick(Sender: TObject); @@ -44,10 +45,11 @@ type procedure btnAddPieClick(Sender: TObject); procedure cbBottomAxisChange(Sender: TObject); procedure cbLeftAxisChange(Sender: TObject); + procedure cbShowAxisTitlesChange(Sender: TObject); procedure cbTitleChange(Sender: TObject); procedure cbFooterChange(Sender: TObject); procedure cbLegendChange(Sender: TObject); - procedure ShowGridCheckBoxChange(Sender: TObject); + procedure edShowGridCheckBoxChange(Sender: TObject); private FArea: TAreaSeries; FBar: TBarSeries; @@ -163,10 +165,12 @@ begin Chart1.Legend.Visible := cbLegend.Checked; end; -procedure TForm1.ShowGridCheckBoxChange(Sender: TObject); +procedure TForm1.cbShowAxisTitlesChange(Sender: TObject); begin - Chart1.LeftAxis.Grid.Visible := ShowGridCheckBox.Checked; - Chart1.BottomAxis.Grid.Visible := ShowGridCheckBox.Checked; + with Chart1.BottomAxis.Title do + if cbShowAxisTitles.Checked then Caption := 'X axis' else Caption := ''; + with Chart1.LeftAxis.Title do + if cbShowAxisTitles.Checked then Caption := 'Y axis' else Caption := ''; end; procedure TForm1.cbLeftAxisChange(Sender: TObject); @@ -179,6 +183,12 @@ begin Chart1.Title.Visible := cbTitle.Checked; end; +procedure TForm1.edShowGridCheckBoxChange(Sender: TObject); +begin + Chart1.LeftAxis.Grid.Visible := edShowGridCheckBox.Checked; + Chart1.BottomAxis.Grid.Visible := edShowGridCheckBox.Checked; +end; + procedure TForm1.InitArea; begin FArea := TAreaSeries.Create(Chart1); diff --git a/components/tachart/tachartlazaruspkg.lpk b/components/tachart/tachartlazaruspkg.lpk index 2b86da71df..eb27e5d230 100644 --- a/components/tachart/tachartlazaruspkg.lpk +++ b/components/tachart/tachartlazaruspkg.lpk @@ -32,6 +32,10 @@ + + + + diff --git a/components/tachart/tachartlazaruspkg.pas b/components/tachart/tachartlazaruspkg.pas index c6445f95df..5d51031b1b 100644 --- a/components/tachart/tachartlazaruspkg.pas +++ b/components/tachart/tachartlazaruspkg.pas @@ -1,5 +1,5 @@ -{ This file was automatically created by Lazarus. Do not edit! -This source is only used to compile and install the package. +{ This file was automatically created by Lazarus. do not edit! + This source is only used to compile and install the package. } unit TAChartLazarusPkg; @@ -7,7 +7,7 @@ unit TAChartLazarusPkg; interface uses - TASeries, TAGraph, LazarusPackageIntf; +TASeries, TAGraph, TAChartUtils, LazarusPackageIntf; implementation diff --git a/components/tachart/tagraph.pas b/components/tachart/tagraph.pas index 9a704b6ed9..641c8b3c71 100644 --- a/components/tachart/tagraph.pas +++ b/components/tachart/tagraph.pas @@ -35,15 +35,8 @@ uses {$ELSE} Windows, {$ENDIF} - SysUtils, Classes, Controls, Graphics, Dialogs, StdCtrls, Clipbrd; - -const - MinDouble = -1.7e308; - MaxDouble = 1.7e308; - MaxColor = 15; - Colors: array [1..MaxColor] of TColor = ( - clRed, clGreen, clYellow, clBlue, clWhite, clGray, clFuchsia, - clTeal, clNavy, clMaroon, clLime, clOlive, clPurple, clSilver, clAqua); + SysUtils, Classes, Controls, Graphics, Dialogs, StdCtrls, Clipbrd, + TAChartUtils; type @@ -146,7 +139,6 @@ type property Font: TFont read FFont write SetFont; end; - TAxisScale = (asIncreasing, asDecreasing, asLogIncreasing, asLogDecreasing); TChartAxis = class(TPersistent) private FVisible: Boolean; @@ -172,13 +164,13 @@ type property Grid: TChartPen read FGrid write SetGrid; end; + TBasicChartSeries = class(TComponent) + end; + { TChart } TChart = class(TCustomChart) private - TmpBrush: TBrush; - TmpPen: TPen; - TmpFont: TFont; FSeries: TFPList; // List of series FMirrorX: Boolean; // From right to left ? YMarkWidth: Integer; // Depend on Y marks @@ -380,29 +372,11 @@ procedure Register; implementation uses - TASeries; + Math, TASeries; -procedure RotateLabel( - Canvas: TCanvas; x, y: Integer; const St: String; RotDegree: Integer); -var - OldFont, - NewFont: HFONT; - LogRec: TLOGFONT; - DC: HDC; -begin - with Canvas do begin - Brush.Style := bsClear; - GetObject(Font.Handle, SizeOf(LogRec), @LogRec); - LogRec.lfEscapement := RotDegree * 10; - LogRec.lfOrientation := 0; - LogRec.lfOutPrecision := OUT_TT_ONLY_PRECIS; - NewFont := CreateFontIndirect(LogRec); - DC := Handle; - end; - OldFont := SelectObject(DC, NewFont); - TextOut(DC, X, Y, @St[1], Length(St)); - DeleteObject(SelectObject(DC, OldFont)); -end; +const + MinDouble = -1.7e308; + MaxDouble = 1.7e308; procedure TChartPen.SetVisible(Value: Boolean); begin @@ -675,162 +649,9 @@ begin end; -procedure CalculateIntervals( - Mini, Maxi: Double; AxisScale: TAxisScale; var Debut, Pas: Double); -var - Etendue, EtendueTmp: Double; - NbPas, Mult: array [1..3] of Double; - - Index: array [1..3] of Byte; - Trouve: Boolean; - DTmp: Double; - BTmp: Byte; - i, j: Integer; -begin - if Maxi > 59 then Sleep(1); - Etendue := Maxi - Mini; - if Etendue <= 0 then begin Debut := Mini; Pas := 1; exit; end; - Mult[1] := 1; - EtendueTmp := Etendue; - NbPas[1] := EtendueTmp; - if NbPas[1] >= 10 then - while NbPas[1] > 10 do begin - EtendueTmp := EtendueTmp / 10; - Mult[1] := Mult[1] / 10; - NbPas[1] := EtendueTmp; - end - else - while EtendueTmp * 10 <= 10 do begin - EtendueTmp := EtendueTmp * 10; - Mult[1] := Mult[1] * 10; - NbPas[1] := EtendueTmp; - end; - Mult[2] := 1; - EtendueTmp := Etendue; - NbPas[2] := EtendueTmp / 0.5; - if NbPas[2] >= 10 then - while NbPas[2]>10 do begin - EtendueTmp := EtendueTmp / 10; - Mult[2] := Mult[2] / 10; - NbPas[2] := EtendueTmp / 0.5; - end - else - while EtendueTmp * 10 / 0.5 <= 10 do begin - EtendueTmp := EtendueTmp * 10; - Mult[2] := Mult[2] * 10; - NbPas[2] := EtendueTmp / 0.5; - end; - Mult[3] := 1; - EtendueTmp := Etendue; - NbPas[3] := EtendueTmp / 0.2; - if NbPas[3] >= 10 then - while NbPas[3] > 10 do begin - EtendueTmp := EtendueTmp / 10; - Mult[3] := Mult[3] / 10; - NbPas[3] := EtendueTmp / 0.2; - end - else - while EtendueTmp * 10 / 0.2 <= 10 do begin - EtendueTmp := EtendueTmp * 10; - Mult[3] := Mult[3] * 10; - NbPas[3] := EtendueTmp / 0.2; - end; - for i := 1 to 3 do Index[i] := i; - Trouve := true; - while Trouve do begin - Trouve := false; - for i := 1 to 2 do - if NbPas[i] > NbPas[i + 1] then begin - Trouve := True; - DTmp := NbPas[i]; - NbPas[i] := NbPas[i + 1]; - NbPas[i + 1] := DTmp; - BTmp := Index[i]; - Index[i] := Index[i + 1]; - Index[i + 1] := BTmp; - end; - end; - if NbPas[3] <= 10 then j := 3 - else if NbPas[2] <= 10 then j := 2 - else if NbPas[1] <= 10 then j := 1 - else begin - // ShowMessage('Error'); - exit; - end; - if Index[j] = 1 then Pas := 1; - if Index[j] = 2 then Pas := 0.5; - if Index[j] = 3 then Pas := 0.2; - Pas := Pas / Mult[Index[j]]; - case AxisScale of - asIncreasing: begin - // Sets 0 as a mark, in case it is in the interval - if (Mini < 0) and (Maxi > 0) then begin - Debut := 0; - while (Debut > Mini) do Debut := Debut - Pas; - end - else begin - // Don''t work if mini is negative and > 1 - // if Abs(Mini)<1 then - Debut := Round((Mini - Pas) * Mult[Index[j]]) / Mult[Index[j]]; - // else - // Debut := System.Int(Mini)-Pas; //null - end; - end; - asDecreasing: begin - // Sets 0 as a mark, in case it is in the interval - if (Mini < 0) and (Maxi > 0) then begin - Debut := 0; - while (Debut < Maxi) do Debut := Debut + Pas; - end - else begin - // Don''t work if mini is negative and > 1 - // if Abs(Mini)<1 then - Debut := Round((Maxi + Pas) * Mult[Index[j]]) / Mult[Index[j]]; - // else - // Debut := System.Int(Mini)-Pas; //null - end; - end; - asLogIncreasing: begin - // FIXME: asLogIncreasing is still not implemented. - // The following is the same code for asIncreasing; - // Sets 0 as a mark, in case it is in the interval - if (Mini < 0) and (Maxi > 0) then begin - Debut := 0; - while (Debut > Mini) do Debut := Debut - Pas; - end - else begin - // Don''t work if mini is negative and > 1 - // if Abs(Mini)<1 then - Debut := Round((Mini - Pas) * Mult[Index[j]]) / Mult[Index[j]]; - // else - // Debut := System.Int(Mini) - Pas; //null - end; - end; - asLogDecreasing: begin - // FIXME: asLogDecreasing is still not implemented. - // The following is the same code for asIncreasing; - // Sets 0 as a mark, in case it is in the interval - if (Mini < 0) and (Maxi > 0) then begin - Debut := 0; - while (Debut > Mini) do Debut := Debut - Pas; - end - else begin - // Don''t work if mini is negative and > 1 - // if Abs(Mini) < 1 then - Debut := Round((Mini - Pas) * Mult[Index[j]]) / Mult[Index[j]]; - // else - // Debut := System.Int(Mini)-Pas; //null - end; - end; - end; {case AxisScale} -end; - constructor TChart.Create(AOwner: TComponent); begin inherited Create(AOwner); - TmpBrush := TBrush.Create; - TmpPen := TPen.Create; - TmpFont := TFont.Create; FAllowZoom := True; FAxisVisible := true; @@ -906,10 +727,6 @@ begin FSeries.Free; FGraphBrush.Free; - TmpBrush.Destroy; - TmpPen.Destroy; - TmpFont.Destroy; - FLegend.Destroy; FTitle.Destroy; FFoot.Destroy; @@ -933,24 +750,29 @@ end; procedure TChart.PaintOnCanvas(ACanvas: TCanvas; ARect: TRect); var i: Integer; + pbf: TPenBrushFontRecall; begin YImageMin := ARect.Bottom - 5; YImageMax := ARect.Top + 5; - if FTitle.Visible then begin - TmpFont.Assign(ACanvas.Font); - ACanvas.Font.Assign( FTitle.Font ); - for i := 0 to FTitle.Text.Count - 1 do - YImageMax := YImageMax + 5 + ACanvas.TextHeight(FTitle.Text[i]); - ACanvas.Font.Assign(TmpFont); - end; + if FTitle.Visible or FFoot.Visible then + pbf := TPenBrushFontRecall.Create(ACanvas, [pbfFont]) + else + pbf := nil; + try + if FTitle.Visible then begin + ACanvas.Font.Assign(FTitle.Font); + for i := 0 to FTitle.Text.Count - 1 do + YImageMax := YImageMax + 5 + ACanvas.TextHeight(FTitle.Text[i]); + end; - if FFoot.Visible then begin - TmpFont.Assign(ACanvas.Font); - ACanvas.Font.Assign(FFoot.Font); - for i := 0 to FFoot.Text.Count - 1 do - YImageMin := YImageMin - 5 - ACanvas.TextHeight(FFoot.Text[i]); - ACanvas.Font.Assign(TmpFont); + if FFoot.Visible then begin + ACanvas.Font.Assign(FFoot.Font); + for i := 0 to FFoot.Text.Count - 1 do + YImageMin := YImageMin - 5 - ACanvas.TextHeight(FFoot.Text[i]); + end; + finally + pbf.Free; end; if FBottomAxis.Visible and FAxisVisible then begin @@ -982,119 +804,197 @@ begin end; procedure TChart.DrawTitleFoot(ACanvas: TCanvas; ARect: TRect); -var - i: Integer; - t, xpos: Integer; -begin - if FTitle.Visible and (FTitle.Text.Count > 0) then begin - TmpBrush.Assign(ACanvas.Brush); - TmpFont.Assign(ACanvas.Font); - ACanvas.Brush.Assign(FTitle.Brush); - ACanvas.Font.Assign(FTitle.Font); - t := 5 + ARect.Top; - for i := 0 to FTitle.Text.Count - 1 do begin - case FTitle.Alignment of - taLeftJustify: xpos := XImageMin; - taCenter: xpos := (ARect.Left + ARect.Right - ACanvas.TextWidth(FTitle.Text[i])) div 2; - taRightJustify: xpos := XImageMax - ACanvas.TextWidth(FTitle.Text[i]); - end; - ACanvas.TextOut(xpos , t, FTitle.Text[i]); - t := t + ACanvas.TextHeight(FTitle.Text[i]); + function GetTextPos(AAlign: TAlignment; const AText: String): Integer; + begin + case AAlign of + taLeftJustify: + Result := XImageMin; + taCenter: + Result := (ARect.Left + ARect.Right - ACanvas.TextWidth(AText)) div 2; + taRightJustify: + Result := XImageMax - ACanvas.TextWidth(AText); end; - ACanvas.Brush.Assign(TmpBrush); - ACanvas.Font.Assign(TmpFont); end; - if FFoot.Visible and (FFoot.Text.Count > 0) then begin - TmpBrush.Assign(ACanvas.Brush); - TmpFont.Assign(ACanvas.Font); - ACanvas.Brush.Assign(FFoot.Brush); - ACanvas.Font.Assign(FFoot.Font); - t := ARect.Bottom - 5 - ACanvas.TextHeight(FFoot.Text[0]); - for i := FFoot.Text.Count - 1 downto 0 do begin - case FFoot.Alignment of - taLeftJustify: xpos := XImageMin; - taCenter: xpos := (ARect.Left + ARect.Right - ACanvas.TextWidth(FFoot.Text[i])) div 2; - taRightJustify: xpos := XImageMax - ACanvas.TextWidth(FFoot.Text[i]); + +var + i, y: Integer; + pbf: TPenBrushFontRecall; + t: String; +begin + pbf := TPenBrushFontRecall.Create(ACanvas, [pbfBrush, pbfFont]); + try + with FTitle do + if Visible and (Text.Count > 0) then begin + ACanvas.Brush.Assign(Brush); + ACanvas.Font.Assign(Font); + y := 5 + ARect.Top; + for i := 0 to Text.Count - 1 do begin + t := Text[i]; + ACanvas.TextOut(GetTextPos(Alignment, t), y, t); + y += ACanvas.TextHeight(t); + end; end; - ACanvas.TextOut(xpos , t, FFoot.Text[i]); - t := t - ACanvas.TextHeight(FFoot.Text[i]); - end; - ACanvas.Brush.Assign(TmpBrush); - ACanvas.Font.Assign(TmpFont); + with FFoot do + if Visible and (Text.Count > 0) then begin + ACanvas.Brush.Assign(Brush); + ACanvas.Font.Assign(Font); + y := ARect.Bottom - 5; + for i := Text.Count - 1 downto 0 do begin + t := Text[i]; + y -= ACanvas.TextHeight(t); + ACanvas.TextOut(GetTextPos(Alignment, t), y, t); + end; + end; + finally + pbf.Free; end; end; procedure TChart.DrawAxis(ACanvas: TCanvas; ARect: TRect); + + function MarkToText(AMark: Double): String; + begin + if Abs(AMark) <= 1e-16 then AMark := 0; + Result := Trim(FloatToStr(AMark)); + end; + + function CenteredPos(const AText: String; minPos, maxPos: Integer): Integer; + begin + Result := (minPos + maxPos - ACanvas.TextWidth(AText)) div 2; + end; + + procedure DrawAxisLabels; + var + x: Integer; + begin + if FLeftAxis.Visible and FAxisVisible then begin + x := 5; + if FMirrorX then + x += ARect.Right - ACanvas.TextWidth(FLeftAxis.Title.Caption); + RotateLabel( + ACanvas, x, + CenteredPos(FLeftAxis.Title.Caption, YImageMin, YImageMax), + FLeftAxis.Title.Caption, FLeftAxis.Title.Angle) + end; + + if FBottomAxis.Visible and FAxisVisible then begin + RotateLabel( + ACanvas, + CenteredPos(FBottomAxis.Title.Caption, XImageMin, XImageMax), + YImageMin + 5 + ACanvas.TextHeight(FBottomAxis.Title.Caption), + FBottomAxis.Title.Caption, FBottomAxis.Title.Angle); + end; + end; + + procedure DrawXMark(AMark: Double); + var + x, w: Integer; + markText: String; + begin + XGraphToImage(AMark, x); + ACanvas.Brush.Assign(FGraphBrush); + + if FBottomAxis.Grid.Visible then begin + ACanvas.Pen.Assign(FBottomAxis.Grid); + if (x <> XImageMax) and (x <> XImageMin) then begin + ACanvas.MoveTo(x, YImageMin); + ACanvas.LineTo(x, YImageMax); + end; + end; + + ACanvas.Pen.Color := AxisColor; + ACanvas.Pen.Style := psSolid; + ACanvas.Pen.Mode := pmCopy; + ACanvas.MoveTo(x, YImageMin - 4); + ACanvas.LineTo(x, YImageMin + 4); + ACanvas.Brush.Color := Color; + + markText := MarkToText(AMark); + w := ACanvas.TextWidth(markText); + ACanvas.TextOut( + EnsureRange(x - w div 2, 1, ARect.Right - w), YImageMin + 4, markText); + end; + + procedure DrawYMark(AMark: Double); + var + y, w, h: Integer; + markText: String; + begin + YGraphToImage(AMark, y); + ACanvas.Brush.Assign(FGraphBrush); + + if FLeftAxis.Grid.Visible then begin + ACanvas.Pen.Assign(FLeftAxis.Grid); + if (y <> YImageMax) and (y <> YImageMin) then begin + ACanvas.MoveTo(XImageMin, y); + ACanvas.LineTo(XImageMax, y); + end; + end; + + ACanvas.Pen.Color := AxisColor; + ACanvas.Pen.Style := psSolid; + ACanvas.Pen.Mode := pmCopy; + ACanvas.MoveTo(XImageMin - 4, y); + ACanvas.LineTo(XImageMin + 4, y); + ACanvas.Brush.Color := Color; + + markText := MarkToText(AMark); + w := ACanvas.TextWidth(markText); + h := ACanvas.TextHeight(markText) div 2; + if FMirrorX then + ACanvas.TextOut(XImageMin + 6, y - h, markText) + else + ACanvas.TextOut(XImageMin - 7 - w, y - h, markText); + end; + var - LargTexte, MaxLargTexte, HautTexte: Integer; - XTemp, YTemp, XPos: Integer; - MyText: String; - Marque, Debut, Pas: Double; - T: Integer; - LeftAxisWidth: Integer; + leftAxisWidth, maxWidth: Integer; LeftAxisScale, BottomAxisScale: TAxisScale; + step, mark: Double; +const + INV_TO_SCALE: array [Boolean] of TAxisScale = (asIncreasing, asDecreasing); begin // Check AxisScale for both axes - case LeftAxis.Inverted of - true : LeftAxisScale := asDecreasing; - false: LeftAxisScale := asIncreasing; - end; - case BottomAxis.Inverted of - true : BottomAxisScale := asDecreasing; - false: BottomAxisScale := asIncreasing; - end; + LeftAxisScale := INV_TO_SCALE[LeftAxis.Inverted]; + BottomAxisScale := INV_TO_SCALE[BottomAxis.Inverted]; + // Find max mark width - MaxLargTexte := 0; - Debut := FYGraphMax; - Pas := 1; - CalculateIntervals(FYGraphMin, FYGraphMax, LeftAxisScale, Debut, Pas); + maxWidth := 0; if FYGraphMin <> FYGraphMax then begin - Marque := Debut; + CalculateIntervals(FYGraphMin, FYGraphMax, LeftAxisScale, mark, step); case LeftAxisScale of - asIncreasing: begin - while Marque <= FYGraphMax + Pas * 10e-10 do begin - if Marque >= FYGraphMin then begin - YGraphToImage(Marque, YTemp); - if (Marque < 1e-16) and (Marque > -1e-16) then Marque := 0; - MyText := Trim(FloatToStr(Marque)); - LargTexte := ACanvas.TextWidth(MyText); - if LargTexte > MaxLargTexte then MaxLargTexte := LargTexte; - end; - Marque := Marque + Pas; + asIncreasing: + while mark <= FYGraphMax + step * 10e-10 do begin + if mark >= FYGraphMin then + maxWidth := Max(ACanvas.TextWidth(MarkToText(mark)), maxWidth); + mark += step; end; - end; - asDecreasing: begin - while Marque >= FYGraphMin - Pas * 10e-10 do begin - if Marque <= FYGraphMax then begin - YGraphToImage(Marque, YTemp); - if (Marque < 1e-16) and (Marque > -1e-16) then Marque := 0; - MyText := Trim(FloatToStr(Marque)); - LargTexte := ACanvas.TextWidth(MyText); - if LargTexte > MaxLargTexte then MaxLargTexte := LargTexte; - end; - Marque := Marque-Pas; + asDecreasing: + while mark >= FYGraphMin - step * 10e-10 do begin + if mark <= FYGraphMax then + maxWidth := Max(ACanvas.TextWidth(MarkToText(mark)), maxWidth); + mark -= step; end; - end; - end; {case LeftAxisScale} + end; end; YMarkWidth := 10; //only consider this width if visible if FLeftAxis.Visible and FAxisVisible then - LeftAxisWidth := ACanvas.TextHeight(FLeftAxis.Title.Caption) + 16 + leftAxisWidth := ACanvas.TextHeight(FLeftAxis.Title.Caption) + 16 else - LeftAxisWidth := 0; + leftAxisWidth := 0; - if MaxLargTexte + LeftAxisWidth > YMarkWidth then begin - YMarkWidth := MaxLargTexte+LeftAxisWidth; + if maxWidth + leftAxisWidth > YMarkWidth then begin + YMarkWidth := maxWidth + leftAxisWidth; if FMirrorX then begin XImageMin := ARect.Right - YMarkWidth - GetLegendWidth(ACanvas); XImageMax := ARect.Left + 10; end else begin - XImageMin := ARect.Left+YMarkWidth; - XImageMax := ARect.Right-10-GetLegendWidth(ACanvas); + XImageMin := ARect.Left + YMarkWidth; + XImageMax := ARect.Right - 10 - GetLegendWidth(ACanvas); end; // Update coefs @@ -1102,7 +1002,7 @@ begin case BottomAxisScale of asIncreasing: begin ax := (XImageMax - XImageMin) / (FXGraphMax - FXGraphMin); - bx := XImageMax - ax*FXGraphMax; + bx := XImageMax - ax * FXGraphMax; end; asDecreasing: begin ax := (XImageMax - XImageMin) / (FXGraphMin - FXGraphMax); @@ -1122,198 +1022,58 @@ begin end; end; - // Back + // Background ACanvas.Pen.Style := psClear; ACanvas.Brush.Color := FBackColor; ACanvas.Rectangle(XImageMin, YImageMin, XImageMax, YImageMax); - // Axes - if FFrame.Visible then begin - ACanvas.Pen.Assign( FFrame ); - ACanvas.MoveTo(XImageMin, YImageMin); - ACanvas.LineTo(XImageMin, YImageMax); - ACanvas.MoveTo(XImageMin, YImageMin); - ACanvas.LineTo(XImageMax, YImageMin); - ACanvas.MoveTo(XImageMin, YImageMax); - ACanvas.LineTo(XImageMax, YImageMax); - ACanvas.MoveTo(XImageMax, YImageMin); - ACanvas.LineTo(XImageMax, YImageMax); - end; + if FFrame.Visible then + with ACanvas do begin + Pen.Assign(FFrame); + MoveTo(XImageMin, YImageMin); + LineTo(XImageMin, YImageMax); + LineTo(XImageMax, YImageMax); + LineTo(XImageMax, YImageMin); + LineTo(XImageMin, YImageMin); + end; - // Axis Labels - if FLeftAxis.Visible and FAxisVisible then begin - {Canvas.Brush.Color := Color; - Canvas.Font.Color := clBlack;} - if FMirrorX then - T := ARect.Right - ACanvas.TextWidth(FLeftAxis.Title.Caption) + 5 - else - T := 5; - if FTitle.Visible then - RotateLabel(ACanvas, T, - YImageMin + (YImageMax - YImageMin) div 2 + - ACanvas.TextWidth(FLeftAxis.Title.Caption) div 2, - FLeftAxis.Title.Caption, FLeftAxis.Title.Angle) - else - RotateLabel(ACanvas, T, - YImageMin + (YImageMax - YImageMin) div 2 + - ACanvas.TextWidth(FLeftAxis.Title.Caption) div 2, - FLeftAxis.Title.Caption, FLeftAxis.Title.Angle); - end; - - if FBottomAxis.Visible and FAxisVisible then begin - RotateLabel(ACanvas, - XImageMin + (XImageMax-XImageMin) div 2 - - ACanvas.TextWidth(FBottomAxis.Title.Caption) div 2, - YImageMin + 5 + ACanvas.TextHeight(FBottomAxis.Title.Caption), - FBottomAxis.Title.Caption, FBottomAxis.Title.Angle); - end; + DrawAxisLabels; // X graduations - if FBottomAxis.Visible and FAxisVisible then begin - Debut := FXGraphMax; - Pas := 1; - CalculateIntervals(FXGraphMin, FXGraphMax, BottomAxisScale, Debut, Pas); - if FXGraphMin<>FXGraphMax then begin - Marque := Debut; - case BottomAxisScale of - asIncreasing: begin - while Marque <= FXGraphMax + Pas * 10e-10 do begin - if Marque >= FXGraphMin then begin - XGraphToImage(Marque, XTemp); - ACanvas.Brush.Assign(FGraphBrush); - if FBottomAxis.Grid.Visible then begin - ACanvas.Pen.Assign(FBottomAxis.Grid); - if (XTemp <> XImageMax) and (XTemp <> XImageMin) then begin - ACanvas.MoveTo(XTemp, YImageMin); - ACanvas.LineTo(XTemp, YImageMax); - end; - end; - ACanvas.Pen.Color := AxisColor; - ACanvas.Pen.Style := psSolid; - ACanvas.Pen.Mode := pmCopy; - ACanvas.MoveTo(XTemp, YImageMin - 4); - ACanvas.LineTo(XTemp, YImageMin + 4); - ACanvas.Brush.Color := Color; - if (Marque < 1e-16) and (Marque > -1e-16) then Marque := 0; - MyText := Trim(FloatToStr(Marque)); - LargTexte := ACanvas.TextWidth(MyText) div 2; - XPos := XTemp - LargTexte; - if XPos < 1 then Xpos := 1; - if XPos + LargTexte * 2 > ARect.Right then - Xpos := ARect.Right - LargTexte * 2 - 1; - ACanvas.TextOut(Xpos, YImageMin + 4, MyText); - end; - Marque := Marque + Pas; - end; + if FBottomAxis.Visible and FAxisVisible and (FXGraphMin <> FXGraphMax) then begin + CalculateIntervals(FXGraphMin, FXGraphMax, BottomAxisScale, mark, step); + case BottomAxisScale of + asIncreasing: + while mark <= FXGraphMax + step * 10e-10 do begin + if mark >= FXGraphMin then + DrawXMark(mark); + mark += step; end; - asDecreasing: begin - while Marque >= FXGraphMin - Pas * 10e-10 do begin - if Marque <= FXGraphMax then begin - XGraphToImage(Marque, XTemp); - ACanvas.Brush.Assign(FGraphBrush); - if FBottomAxis.Grid.Visible then begin - ACanvas.Pen.Assign(FBottomAxis.Grid); - if (XTemp <> XImageMax) and (XTemp <> XImageMin) then begin - ACanvas.MoveTo(XTemp, YImageMin); - ACanvas.LineTo(XTemp, YImageMax); - end; - end; - ACanvas.Pen.Color := AxisColor; - ACanvas.Pen.Style := psSolid; - ACanvas.Pen.Mode := pmCopy; - ACanvas.MoveTo(XTemp, YImageMin - 4); - ACanvas.LineTo(XTemp, YImageMin + 4); - ACanvas.Brush.Color := Color; - if (Marque < 1e-16) and (Marque > -1e-16) then Marque := 0; - MyText := Trim(FloatToStr(Marque)); - LargTexte := ACanvas.TextWidth(MyText) div 2; - XPos := XTemp - LargTexte; - if XPos < 1 then Xpos := 1; - if XPos + LargTexte * 2 > ARect.Right then - Xpos := ARect.Right - LargTexte * 2 - 1; - ACanvas.TextOut(Xpos, YImageMin + 4, MyText); - end; - Marque := Marque - Pas; - end; + asDecreasing: + while mark >= FXGraphMin - step * 10e-10 do begin + if mark <= FXGraphMax then + DrawXMark(mark); + mark -= step; end; - end; {case BottomAxisScale} end; end; // Y graduations - if FLeftAxis.Visible and AxisVisible then begin - MaxLargTexte := 0; - Debut := FYGraphMax; - Pas := 1; - CalculateIntervals(FYGraphMin, FYGraphMax, LeftAxisScale, Debut, Pas); - if FYGraphMin <> FYGraphMax then begin - Marque := Debut; - case LeftAxisScale of - asIncreasing: begin - while Marque <= FYGraphMax + Pas * 10e-10 do begin - if Marque >= FYGraphMin then begin - YGraphToImage(Marque, YTemp); - ACanvas.Brush.Assign(FGraphBrush); - //draw grid - if FLeftAxis.Grid.Visible then begin - ACanvas.Pen.Assign(FLeftAxis.Grid); - if (YTemp <> YImageMax) and (YTemp <> YImageMin) then begin - ACanvas.MoveTo(XImageMin, YTemp); - ACanvas.LineTo(XImageMax, YTemp); - end; - end; - ACanvas.Pen.Color := AxisColor; - ACanvas.Pen.Style := psSolid; - ACanvas.Pen.Mode := pmCopy; - ACanvas.MoveTo(XImageMin-4, YTemp); - ACanvas.LineTo(XImageMin+4, YTemp); - ACanvas.Brush.Color := Color; - if (Marque<1e-16) and (Marque>-1e-16) then Marque := 0; - MyText := Trim(FloatToStr(Marque)); - LargTexte := ACanvas.TextWidth(MyText); - if LargTexte > MaxLargTexte then MaxLargTexte := LargTexte; - HautTexte := ACanvas.TextHeight(MyText) div 2; - if FMirrorX then - ACanvas.TextOut(XImageMin + 6, YTemp - HautTexte, MyText) - else - ACanvas.TextOut(XImageMin - 7 - LargTexte, YTemp - HautTexte, MyText); - end; - Marque := Marque + Pas; - end; + if FLeftAxis.Visible and AxisVisible and (FYGraphMin <> FYGraphMax) then begin + CalculateIntervals(FYGraphMin, FYGraphMax, LeftAxisScale, mark, step); + case LeftAxisScale of + asIncreasing: + while mark <= FYGraphMax + step * 10e-10 do begin + if mark >= FYGraphMin then + DrawYMark(mark); + mark += step; end; - asDecreasing: begin - while Marque >= FYGraphMin - Pas * 10e-10 do begin - if Marque <= FYGraphMax then begin - YGraphToImage(Marque, YTemp); - ACanvas.Brush.Assign(FGraphBrush); - //draw grid - if FLeftAxis.Grid.Visible then begin - ACanvas.Pen.Assign(FLeftAxis.Grid); - if (YTemp <> YImageMax) and (YTemp <> YImageMin) then begin - ACanvas.MoveTo(XImageMin, YTemp); - ACanvas.LineTo(XImageMax, YTemp); - end; - end; - ACanvas.Pen.Color := AxisColor; - ACanvas.Pen.Style := psSolid; - ACanvas.Pen.Mode := pmCopy; - ACanvas.MoveTo(XImageMin - 4, YTemp); - ACanvas.LineTo(XImageMin + 4, YTemp); - ACanvas.Brush.Color := Color; - If (Marque < 1e-16) and (Marque > -1e-16) then Marque := 0; - MyText := Trim(FloatToStr(Marque)); - LargTexte := ACanvas.TextWidth(MyText); - if LargTexte > MaxLargTexte then MaxLargTexte := LargTexte; - HautTexte := ACanvas.TextHeight(MyText) div 2; - if FMirrorX then - ACanvas.TextOut(XImageMin + 6, YTemp - HautTexte, MyText) - else - ACanvas.TextOut(XImageMin - 7 - LargTexte, YTemp - HautTexte, MyText); - end; - Marque := Marque - Pas; - end; + asDecreasing: + while mark >= FYGraphMin - step * 10e-10 do begin + if mark <= FYGraphMax then + DrawYMark(mark); + mark -= step; end; - end; {case LeftAxisScale} end; end; end; @@ -1322,80 +1082,80 @@ procedure TChart.DrawLegend(ACanvas: TCanvas; ARect: TRect); var w, h, x1, y1, x2, y2, i, j, TH: Integer; MySerie: TChartSeries; + pbf: TPenBrushFontRecall; begin - TmpBrush.Assign(ACanvas.Brush); - TmpPen.Assign(ACanvas.Pen); - TmpFont.Assign(ACanvas.Font); + pbf := TPenBrushFontRecall.Create(ACanvas, [pbfPen, pbfBrush, pbfFont]); - w := GetLegendWidth(ACanvas); - TH := ACanvas.TextHeight('I'); + try + w := GetLegendWidth(ACanvas); + TH := ACanvas.TextHeight('I'); - if OnlyPie then begin //if only one pie show diferent legend - MySerie := GetPie; - h := 5 + MySerie.Count * (TH + 5); - end else - h := 5 + SeriesInLegendCount * (TH + 5); - x1 := ARect.Right - w - 5; - y1 := YImageMax; - x2 := x1 + w; - y2 := y1 + h; + if OnlyPie then begin //if only one pie show diferent legend + MySerie := GetPie; + h := 5 + MySerie.Count * (TH + 5); + end else + h := 5 + SeriesInLegendCount * (TH + 5); + x1 := ARect.Right - w - 5; + y1 := YImageMax; + x2 := x1 + w; + y2 := y1 + h; - // Border - ACanvas.Brush.Assign(FGraphBrush); - ACanvas.Pen.Assign(FLegend.Frame); - ACanvas.Font.Assign(FLegend.Font); - ACanvas.Rectangle(x1, y1, x2, y2); + // Border + ACanvas.Brush.Assign(FGraphBrush); + ACanvas.Pen.Assign(FLegend.Frame); + ACanvas.Font.Assign(FLegend.Font); + ACanvas.Rectangle(x1, y1, x2, y2); - // Lines and Series titles - if OnlyPie then begin //if only one pie show diferent legend - MySerie := GetPie; - for i := 0 to MySerie.Count - 1 do begin //clean this coord should not be published - ACanvas.Pen.Color := FLegend.Frame.Color; - ACanvas.Brush.Color := FGraphBrush.Color; - ACanvas.TextOut(x1 + 25, y1 + 5 + i * (TH + 5), - Format('%1.2g', [PChartCoord(MySerie.Coord.Items[i])^.y]) + ' ' + - PChartCoord(MySerie.Coord.Items[i])^.Text); - ACanvas.Pen.Color := clBlack; - ACanvas.Brush.Color := PChartCoord(MySerie.Coord.Items[i])^.Color; - ACanvas.Rectangle( - x1 + 5, y1 + i * (TH + 5) + TH div 2, - x1 + 22, y1 + 10 + i * (TH + 5) + TH div 2); - end; - end - else begin - j := 0; - for i := 0 to SeriesCount - 1 do begin - MySerie := Series[i]; - if MySerie.Active and MySerie.ShowInLegend then begin - ACanvas.Brush.Assign(FGraphBrush); - ACanvas.TextOut(x1 + 25, y1 + 5 + j * (TH + 5), MySerie.Title); - ACanvas.Pen.Color := MySerie.SeriesColor; - if MySerie is TBarSeries then begin - ACanvas.Pen.Color := clBlack; - ACanvas.Brush.Assign((MySerie as TBarSeries).BarBrush); - ACanvas.Rectangle( - x1 + 5, y1 + j * (TH + 5) + TH div 2, - x1 + 22, y1 + 10 + j * (TH + 5) + TH div 2); - end - else if MySerie is TAreaSeries then begin - ACanvas.Pen.Color := clBlack; - ACanvas.Brush.Color := MySerie.SeriesColor;; - ACanvas.Rectangle( - x1 + 5, y1 + j * (TH + 5) + TH div 2, - x1 + 22, y1 + 10 + j * (TH + 5) + TH div 2); - end - else if (MySerie is TLine) or (MySerie is TSerie) then begin - ACanvas.MoveTo(x1 + 5, y1 + 5 + j * (TH + 5) + TH div 2); - ACanvas.LineTo(x1 + 22, y1 + 5 + j * (TH + 5) + TH div 2); - end - else if MySerie is TPieSeries then begin end; //don't draw - j += 1; + // Lines and Series titles + if OnlyPie then begin //if only one pie show diferent legend + MySerie := GetPie; + for i := 0 to MySerie.Count - 1 do begin //clean this coord should not be published + ACanvas.Pen.Color := FLegend.Frame.Color; + ACanvas.Brush.Color := FGraphBrush.Color; + ACanvas.TextOut(x1 + 25, y1 + 5 + i * (TH + 5), + Format('%1.2g', [PChartCoord(MySerie.Coord.Items[i])^.y]) + ' ' + + PChartCoord(MySerie.Coord.Items[i])^.Text); + ACanvas.Pen.Color := clBlack; + ACanvas.Brush.Color := PChartCoord(MySerie.Coord.Items[i])^.Color; + ACanvas.Rectangle( + x1 + 5, y1 + i * (TH + 5) + TH div 2, + x1 + 22, y1 + 10 + i * (TH + 5) + TH div 2); + end; + end + else begin + j := 0; + for i := 0 to SeriesCount - 1 do begin + MySerie := Series[i]; + if MySerie.Active and MySerie.ShowInLegend then begin + ACanvas.Brush.Assign(FGraphBrush); + ACanvas.TextOut(x1 + 25, y1 + 5 + j * (TH + 5), MySerie.Title); + ACanvas.Pen.Color := MySerie.SeriesColor; + if MySerie is TBarSeries then begin + ACanvas.Pen.Color := clBlack; + ACanvas.Brush.Assign((MySerie as TBarSeries).BarBrush); + ACanvas.Rectangle( + x1 + 5, y1 + j * (TH + 5) + TH div 2, + x1 + 22, y1 + 10 + j * (TH + 5) + TH div 2); + end + else if MySerie is TAreaSeries then begin + ACanvas.Pen.Color := clBlack; + ACanvas.Brush.Color := MySerie.SeriesColor;; + ACanvas.Rectangle( + x1 + 5, y1 + j * (TH + 5) + TH div 2, + x1 + 22, y1 + 10 + j * (TH + 5) + TH div 2); + end + else if (MySerie is TLine) or (MySerie is TSerie) then begin + ACanvas.MoveTo(x1 + 5, y1 + 5 + j * (TH + 5) + TH div 2); + ACanvas.LineTo(x1 + 22, y1 + 5 + j * (TH + 5) + TH div 2); + end + else if MySerie is TPieSeries then begin end; //don't draw + j += 1; + end; end; end; + finally + pbf.Free; end; - ACanvas.Brush.Assign(TmpBrush); - ACanvas.Pen.Assign(TmpPen); - ACanvas.Font.Assign(TmpFont); end; procedure TChart.SetAutoUpdateXMin(Value: Boolean); @@ -2016,19 +1776,19 @@ end; procedure TChart.DrawVerticalReticule(ACanvas: TCanvas; X: Integer); begin - Canvas.Pen.Style := psSolid; - Canvas.Pen.Mode := pmXor; - Canvas.Pen.Color := clWhite; - Canvas.Pen.Style := psSolid; - Canvas.Pen.Width := 1; + ACanvas.Pen.Style := psSolid; + ACanvas.Pen.Mode := pmXor; + ACanvas.Pen.Color := clWhite; + ACanvas.Pen.Style := psSolid; + ACanvas.Pen.Width := 1; - Canvas.MoveTo(X, YImageMin); - Canvas.LineTo(X, YImageMax); + ACanvas.MoveTo(X, YImageMin); + ACanvas.LineTo(X, YImageMax); end; procedure TChart.MouseMove(Shift: TShiftState; X, Y: Integer); var - i, SerieNumber, PointNumber, XMin, Xmax, YMin, YMax, Temp: Integer; + i, SerieNumber, PointNumber, XMin, Xmax, YMin, YMax: Integer; begin if Down then begin Canvas.Brush.Style := bsClear; @@ -2049,16 +1809,10 @@ begin XMax := XImageMax; YMin := YImageMin; YMax := YImageMax; - if XMin > XMax then begin - Temp := XMin; - XMin := XMax; - XMax := Temp; - end; - if YMin > YMax then begin - Temp := YMin; - YMin := YMax; - YMax := Temp; - end; + if XMin > XMax then + Exchange(Xmin, Xmax); + if YMin > YMax then + Exchange(YMin, YMax); for i := 0 to SeriesCount - 1 do begin if FShowVerticalReticule then begin diff --git a/components/tachart/taseries.pas b/components/tachart/taseries.pas index c940527d32..2c0b754ceb 100644 --- a/components/tachart/taseries.pas +++ b/components/tachart/taseries.pas @@ -1,7 +1,7 @@ { /*************************************************************************** - TASeries.pp - ---------- + TASeries.pas + ------------ Component Library Standard Graph Series @@ -69,7 +69,7 @@ type { TChartSeries } - TChartSeries = class(TComponent) + TChartSeries = class(TBasicChartSeries) private // Graph = coordinates in the graph FXGraphMin, FYGraphMin: Double; // Max Graph value of points @@ -311,25 +311,8 @@ type implementation uses - math; - -procedure Exchange(var A, B: Integer); overload; -var - t: Integer; -begin - t := A; - A := B; - B := t; -end; - -procedure Exchange(var A, B: Double); overload; -var - t: Double; -begin - t := A; - A := B; - B := t; -end; + math, + TAChartUtils; constructor TChartSeries.Create(AOwner: TComponent); begin