diff --git a/components/tachart/demo/radial/main.lfm b/components/tachart/demo/radial/main.lfm index e301991f19..b5dcac5306 100644 --- a/components/tachart/demo/radial/main.lfm +++ b/components/tachart/demo/radial/main.lfm @@ -1,17 +1,17 @@ object Form1: TForm1 - Left = 459 - Height = 482 - Top = 346 + Left = 443 + Height = 559 + Top = 340 Width = 580 Caption = 'Form1' - ClientHeight = 482 + ClientHeight = 559 ClientWidth = 580 OnCreate = FormCreate Position = poScreenCenter LCLVersion = '2.1.0.0' object PageControl1: TPageControl Left = 0 - Height = 482 + Height = 559 Top = 0 Width = 580 ActivePage = tsPie @@ -20,12 +20,12 @@ object Form1: TForm1 TabOrder = 0 object tsPie: TTabSheet Caption = 'Pie' - ClientHeight = 454 + ClientHeight = 531 ClientWidth = 572 object ChartPie: TChart Left = 0 - Height = 336 - Top = 118 + Height = 384 + Top = 147 Width = 572 AxisList = < item @@ -65,26 +65,27 @@ object Form1: TForm1 object Panel1: TPanel AnchorSideTop.Side = asrCenter Left = 0 - Height = 118 + Height = 147 Top = 0 Width = 572 Align = alTop Alignment = taLeftJustify + Anchors = [akTop, akRight] AutoSize = True Caption = ' Click on a slice to explode/unexplode it' - ClientHeight = 118 + ClientHeight = 147 ClientWidth = 572 TabOrder = 1 object seWords: TSpinEdit AnchorSideTop.Control = Panel1 AnchorSideRight.Control = lblInnerRadius - Left = 326 + Left = 324 Height = 23 Top = 7 Width = 72 Anchors = [akTop, akRight] BorderSpacing.Top = 6 - BorderSpacing.Right = 16 + BorderSpacing.Right = 24 MaxValue = 10 OnChange = seWordsChange TabOrder = 0 @@ -94,7 +95,7 @@ object Form1: TForm1 AnchorSideTop.Control = seWords AnchorSideTop.Side = asrCenter AnchorSideRight.Control = seWords - Left = 255 + Left = 253 Height = 15 Top = 11 Width = 63 @@ -109,7 +110,7 @@ object Form1: TForm1 AnchorSideTop.Side = asrBottom AnchorSideRight.Control = seWords AnchorSideRight.Side = asrBottom - Left = 326 + Left = 324 Height = 23 Top = 34 Width = 72 @@ -125,7 +126,7 @@ object Form1: TForm1 AnchorSideTop.Control = seLabelAngle AnchorSideTop.Side = asrCenter AnchorSideRight.Control = seLabelAngle - Left = 258 + Left = 256 Height = 15 Top = 38 Width = 60 @@ -135,31 +136,32 @@ object Form1: TForm1 ParentColor = False end object cbRotate: TCheckBox - AnchorSideLeft.Control = cbMarkPositions - AnchorSideTop.Control = cbMarkPositions + AnchorSideTop.Control = cbMarkAttachment AnchorSideTop.Side = asrBottom + AnchorSideRight.Control = cbMarkAttachment AnchorSideRight.Side = asrBottom - Left = 255 + Left = 309 Height = 19 - Top = 90 + Top = 121 Width = 87 - BorderSpacing.Bottom = 8 + Alignment = taLeftJustify + Anchors = [akTop, akRight] + BorderSpacing.Top = 6 + BorderSpacing.Bottom = 6 Caption = 'Rotate labels' OnChange = cbRotateChange TabOrder = 2 end object cbMarkPositions: TComboBox - AnchorSideLeft.Control = lblWords - AnchorSideTop.Control = lblLabelAngle - AnchorSideTop.Side = asrBottom - AnchorSideRight.Control = seLabelAngle + AnchorSideTop.Control = cbMarkAttachment + AnchorSideRight.Control = seDepthBrightnessDelta AnchorSideRight.Side = asrBottom - Left = 255 + Left = 438 Height = 23 - Top = 61 - Width = 143 - Anchors = [akTop, akLeft, akRight] - BorderSpacing.Top = 8 + Top = 92 + Width = 127 + Anchors = [akTop, akRight] + AutoSize = False BorderSpacing.Bottom = 6 ItemHeight = 15 ItemIndex = 0 @@ -177,7 +179,7 @@ object Form1: TForm1 AnchorSideLeft.Control = lblInnerRadius AnchorSideTop.Control = seLabelAngle AnchorSideTop.Side = asrCenter - Left = 414 + Left = 420 Height = 19 Top = 36 Width = 34 @@ -189,12 +191,12 @@ object Form1: TForm1 AnchorSideTop.Control = seWords AnchorSideRight.Control = Panel1 AnchorSideRight.Side = asrBottom - Left = 497 + Left = 503 Height = 23 Top = 7 Width = 62 Anchors = [akTop, akRight] - BorderSpacing.Right = 12 + BorderSpacing.Right = 6 OnChange = seInnerRadiusChange TabOrder = 5 end @@ -202,7 +204,7 @@ object Form1: TForm1 AnchorSideLeft.Side = asrBottom AnchorSideTop.Control = lblWords AnchorSideRight.Control = seInnerRadius - Left = 414 + Left = 420 Height = 15 Top = 11 Width = 75 @@ -217,7 +219,7 @@ object Form1: TForm1 AnchorSideTop.Control = Cb3D AnchorSideTop.Side = asrCenter AnchorSideRight.Control = seDepth - Left = 457 + Left = 463 Height = 15 Top = 38 Width = 32 @@ -234,12 +236,12 @@ object Form1: TForm1 AnchorSideTop.Side = asrCenter AnchorSideRight.Control = Panel1 AnchorSideRight.Side = asrBottom - Left = 497 + Left = 503 Height = 23 Top = 34 Width = 62 Anchors = [akTop, akRight] - BorderSpacing.Right = 12 + BorderSpacing.Right = 6 Enabled = False OnChange = seDepthChange TabOrder = 6 @@ -251,13 +253,13 @@ object Form1: TForm1 AnchorSideTop.Side = asrBottom AnchorSideRight.Control = Panel1 AnchorSideRight.Side = asrBottom - Left = 497 + Left = 503 Height = 23 Top = 61 Width = 62 Anchors = [akTop, akRight] BorderSpacing.Top = 4 - BorderSpacing.Right = 12 + BorderSpacing.Right = 6 Enabled = False MaxValue = 255 MinValue = -255 @@ -267,22 +269,104 @@ object Form1: TForm1 end object lblDepthBrightnessDelta: TLabel AnchorSideLeft.Control = cbMarkPositions - AnchorSideLeft.Side = asrBottom AnchorSideTop.Control = seDepthBrightnessDelta AnchorSideTop.Side = asrCenter AnchorSideRight.Control = seDepthBrightnessDelta - Left = 398 + Left = 411 Height = 15 Top = 65 - Width = 91 + Width = 84 Alignment = taRightJustify - Anchors = [akTop, akLeft, akRight] + Anchors = [akTop, akRight] BorderSpacing.Right = 8 Caption = 'Brightness delta' Enabled = False ParentColor = False WordWrap = True end + object cbShowLabels: TCheckBox + AnchorSideTop.Control = seWords + AnchorSideTop.Side = asrCenter + AnchorSideRight.Control = lblWords + Left = 155 + Height = 19 + Top = 9 + Width = 82 + Anchors = [akTop, akRight] + BorderSpacing.Right = 16 + Caption = 'Show labels' + Checked = True + OnChange = cbShowLabelsChange + State = cbChecked + TabOrder = 8 + end + object lblDistance: TLabel + AnchorSideTop.Control = seDistance + AnchorSideTop.Side = asrCenter + AnchorSideRight.Control = seDistance + Left = 271 + Height = 15 + Top = 67 + Width = 45 + Anchors = [akTop, akRight] + BorderSpacing.Right = 8 + Caption = 'Distance' + ParentColor = False + end + object seDistance: TSpinEdit + AnchorSideTop.Control = seLabelAngle + AnchorSideTop.Side = asrBottom + AnchorSideRight.Control = seLabelAngle + AnchorSideRight.Side = asrBottom + Left = 324 + Height = 23 + Top = 63 + Width = 72 + Anchors = [akTop, akRight] + BorderSpacing.Top = 6 + OnChange = seDistanceChange + TabOrder = 9 + Value = 40 + end + object cbMarkAttachment: TComboBox + AnchorSideLeft.Control = lblDistance + AnchorSideTop.Control = seDistance + AnchorSideTop.Side = asrBottom + AnchorSideRight.Control = seDistance + AnchorSideRight.Side = asrBottom + Left = 271 + Height = 23 + Top = 92 + Width = 125 + Anchors = [akTop, akLeft, akRight] + BorderSpacing.Top = 6 + BorderSpacing.Bottom = 6 + ItemHeight = 15 + ItemIndex = 0 + Items.Strings = ( + 'Default' + 'Edge' + 'Center' + ) + OnChange = cbMarkAttachmentChange + Style = csDropDownList + TabOrder = 10 + Text = 'Default' + end + object cbMarkPositionsCentered: TCheckBox + AnchorSideTop.Control = cbRotate + AnchorSideRight.Control = cbMarkPositions + AnchorSideRight.Side = asrBottom + Left = 418 + Height = 19 + Top = 121 + Width = 147 + Alignment = taLeftJustify + Anchors = [akTop, akRight] + Caption = 'Mark positions centered' + OnChange = cbMarkPositionsCenteredChange + TabOrder = 11 + end end end object tsPolar: TTabSheet @@ -423,7 +507,7 @@ object Form1: TForm1 end object ListChartSource1: TListChartSource DataPoints.Strings = ( - '0|5|?|' + '0|7|?|' '0|3|?|' '0|1|?|' '0.20000000000000001|0.20000000000000001|?|' diff --git a/components/tachart/demo/radial/main.pas b/components/tachart/demo/radial/main.pas index 91c3f290af..07ca3dda5c 100644 --- a/components/tachart/demo/radial/main.pas +++ b/components/tachart/demo/radial/main.pas @@ -7,13 +7,14 @@ interface uses Classes, ComCtrls, ExtCtrls, Spin, StdCtrls, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, TAGraph, TARadialSeries, TASeries, TASources, - TATools; + TATools, TACustomSeries; type { TForm1 } TForm1 = class(TForm) + cbMarkAttachment: TComboBox; ChartPolar: TChart; ChartPolarSeries1: TPolarSeries; ChartPolarSeries2: TPolarSeries; @@ -26,6 +27,9 @@ type cbShowPoints: TCheckBox; cbFilled: TCheckBox; Cb3D: TCheckBox; + cbShowLabels: TCheckBox; + cbMarkPositionsCentered: TCheckBox; + lblDistance: TLabel; seDepth: TSpinEdit; seDepthBrightnessDelta: TSpinEdit; lblInnerRadius: TLabel; @@ -43,18 +47,23 @@ type seWords: TSpinEdit; seLabelAngle: TSpinEdit; seInnerRadius: TSpinEdit; + seDistance: TSpinEdit; tsPolar: TTabSheet; tsPie: TTabSheet; procedure cbCloseCircleChange(Sender: TObject); procedure cbFilledChange(Sender: TObject); + procedure cbMarkAttachmentChange(Sender: TObject); + procedure cbMarkPositionsCenteredChange(Sender: TObject); procedure cbMarkPositionsChange(Sender: TObject); procedure cbRotateChange(Sender: TObject); + procedure cbShowLabelsChange(Sender: TObject); procedure ChartPieMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure cbShowPointsChange(Sender: TObject); procedure Cb3DChange(Sender: TObject); procedure seDepthBrightnessDeltaChange(Sender: TObject); procedure seDepthChange(Sender: TObject); + procedure seDistanceChange(Sender: TObject); procedure seInnerRadiusChange(Sender: TObject); procedure FormCreate(Sender: TObject); procedure sbTransparencyChange(Sender: TObject); @@ -70,7 +79,7 @@ implementation {$R *.lfm} uses - TAChartUtils; + TAChartUtils, TATextElements; { TForm1 } @@ -86,6 +95,17 @@ begin ChartPolarSeries2.Filled := cbFilled.Checked; end; +procedure TForm1.cbMarkAttachmentChange(Sender: TObject); +begin + ChartPiePieSeries1.Marks.Attachment := + TChartMarkAttachment(cbMarkAttachment.ItemIndex); +end; + +procedure TForm1.cbMarkPositionsCenteredChange(Sender: TObject); +begin + ChartPiePieSeries1.MarkPositionCentered := cbMarkPositionsCentered.Checked; +end; + procedure TForm1.cbMarkPositionsChange(Sender: TObject); begin ChartPiePieSeries1.MarkPositions := @@ -97,6 +117,22 @@ begin ChartPiePieSeries1.RotateLabels := cbRotate.Checked; end; +procedure TForm1.cbShowLabelsChange(Sender: TObject); +begin + if cbShowLabels.Checked then + ChartPiePieSeries1.Marks.Style := smsLabel + else + ChartPiePieSeries1.Marks.Style := smsNone; + seWords.Enabled := cbShowLabels.Checked; + lblWords.Enabled := cbShowLabels.Checked; + seLabelAngle.Enabled := cbShowLabels.Checked; + lblLabelAngle.Enabled := cbShowLabels.Checked; + cbMarkPositions.Enabled := cbShowLabels.Checked; + cbMarkAttachment.Enabled := cbShowlabels.Checked; + cbMarkPositionsCentered.Enabled := cbShowLabels.Checked; + cbRotate.Enabled := cbShowLabels.Checked; +end; + procedure TForm1.cbShowPointsChange(Sender: TObject); begin ChartPolarSeries1.ShowPoints := cbShowPoints.Checked; @@ -125,6 +161,11 @@ begin ChartPiePieSeries1.Depth := seDepth.Value; end; +procedure TForm1.seDistanceChange(Sender: TObject); +begin + ChartPiePieSeries1.Marks.Distance := seDistance.Value; +end; + procedure TForm1.seInnerRadiusChange(Sender: TObject); begin ChartPiePieSeries1.InnerRadiusPercent := seInnerRadius.Value; @@ -174,6 +215,12 @@ var var i, j: Integer; begin + if seWords.Value = 0 then begin + ChartPiePieSeries1.Marks.Style := smsValue; + exit; + end; + + ChartPiePieSeries1.Marks.Style := smsLabel; r := TMWCRandomGenerator.Create; try r.Seed := 9823743; diff --git a/components/tachart/demo/radial/radialdemo.lpi b/components/tachart/demo/radial/radialdemo.lpi index 837630d277..cb34f1252a 100644 --- a/components/tachart/demo/radial/radialdemo.lpi +++ b/components/tachart/demo/radial/radialdemo.lpi @@ -65,13 +65,6 @@ - - - - - - - diff --git a/components/tachart/taradialseries.pas b/components/tachart/taradialseries.pas index e363c60756..38123e0429 100644 --- a/components/tachart/taradialseries.pas +++ b/components/tachart/taradialseries.pas @@ -63,6 +63,7 @@ type private FCenter: TPoint; FMarkDistancePercent: Boolean; + FMarkPositionCentered: Boolean; FMarkPositions: TPieMarkPositions; FRadius: Integer; FInnerRadiusPercent: Integer; @@ -78,6 +79,7 @@ type procedure SetFixedRadius(AValue: TChartDistance); procedure SetInnerRadiusPercent(AValue: Integer); procedure SetMarkDistancePercent(AValue: Boolean); + procedure SetMarkPositionCentered(AValue: Boolean); procedure SetMarkPositions(AValue: TPieMarkPositions); procedure SetRotateLabels(AValue: Boolean); function SliceColor(AIndex: Integer): TColor; @@ -85,9 +87,11 @@ type protected function CalcInnerRadius: Integer; inline; procedure GetLegendItems(AItems: TChartLegendItems); override; - property Radius: Integer read FRadius; property InnerRadiusPercent: Integer read FInnerRadiusPercent write SetInnerRadiusPercent default 0; + property MarkPositionCentered: Boolean + read FMarkPositionCentered write SetMarkPositionCentered default false; + property Radius: Integer read FRadius; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; @@ -249,6 +253,8 @@ begin Self.FExploded := FExploded; Self.FFixedRadius := FFixedRadius; Self.FInnerRadiusPercent := FInnerRadiusPercent; + Self.FMarkDistancePercent := FMarkDistancePercent; + Self.FMarkPositionCentered := FMarkPositionCentered; Self.FRotateLabels := FRotateLabels; end; inherited Assign(ASource); @@ -376,7 +382,7 @@ var end; end; - procedure DrawPieRing(ASlice: TPieSlice); + procedure DrawRing(ASlice: TPieSlice); var i: Integer; a, angle1, angle2: Double; @@ -433,9 +439,21 @@ var AIndex := 0; end; + procedure FindRegionIndexes(out AIndex14: Integer); + var + j: Integer; + begin + AIndex14 := 0; + for j := 0 to High(FSlices) do + if FSlices[j].FPrevAngle > PI_1_4 then begin + AIndex14 := j; + break; + end; + end; + var prevLabelPoly: TPointArray = nil; - i, iL: Integer; + i, iL, i14: Integer; begin if IsEmpty then exit; @@ -447,6 +465,7 @@ begin if Depth > 0 then begin scaled_depth := ADrawer.Scale(Depth); FindLeftMostIndex(iL); + FindRegionIndexes(i14); if FSlices[iL].FVisible then begin if StartEdgeVisible(FSlices[iL]) then @@ -477,8 +496,19 @@ begin end; // Draw arcs - for i:= iL-1 downto 0 do + if FSlices[iL].FNextAngle > PI_7_4 then dec(iL); + if FSlices[i14].FNextAngle > PI_7_4 then dec(i14); + for i := iL downto i14 do DrawVisibleArc3D(FSlices[i]); + + for i := 0 to i14 do begin + if EndEdgeVisible(FSlices[i]) then DrawEndEdge3D(FSlices[i]); + DrawVisibleArc3D(FSlices[i]); + end; + { + for i:= iL downto 0 do + DrawVisibleArc3D(FSlices[i]); + } end; ADrawer.SetPen(EdgePen); @@ -491,7 +521,7 @@ begin ps.FBase.X + FRadius, ps.FBase.Y + FRadius, RadToDeg16(ps.FPrevAngle), RadToDeg16(ps.Angle)) else - DrawPieRing(ps); + DrawRing(ps); end; if not Marks.IsMarkLabelsVisible then exit; @@ -653,6 +683,13 @@ begin UpdateParentChart; end; +procedure TCustomPieSeries.SetMarkPositionCentered(AValue: Boolean); +begin + if FMarkPositionCentered = AValue then exit; + FMarkPositionCentered := AValue; + UpdateParentChart; +end; + procedure TCustomPieSeries.SetMarkPositions(AValue: TPieMarkPositions); begin if FMarkPositions = AValue then exit; @@ -746,7 +783,7 @@ function TCustomPieSeries.TryRadius(ADrawer: IChartDrawer): TRect; with ALabel do begin FCenter := FAttachment; if not Marks.IsMarkLabelsVisible then exit; - FText := FormattedMark(AIndex); + FText := FormattedMark(AIndex); if FText = '' then exit; if RotateLabels then Marks.SetAdditionalAngle(AAngle); @@ -801,17 +838,21 @@ begin ExpandRect( Result, FBase + Point(scaled_depth, -scaled_depth), FRadius, -FPrevAngle, -FNextAngle); - FLabel.FAttachment := EndPoint(a, FRadius) + FBase; + if FMarkPositionCentered then + FLabel.FAttachment := EndPoint(a, (CalcInnerRadius + FRadius) div 2) + FBase + else + FLabel.FAttachment := EndPoint(a, FRadius) + FBase; PrepareLabel(FLabel, i, a); end; prevAngle := FNextAngle; end; - j += 1; + inc(j); end; SetLength(FSlices, j); InflateRect(Result, MARGIN, MARGIN); end; + { TPolarSeries } procedure TPolarSeries.Assign(ASource: TPersistent); diff --git a/components/tachart/taseries.pas b/components/tachart/taseries.pas index c41abf86a1..6828e4b348 100644 --- a/components/tachart/taseries.pas +++ b/components/tachart/taseries.pas @@ -130,6 +130,7 @@ type property FixedRadius; property InnerRadiusPercent; property MarkDistancePercent; + property MarkPositionCentered; property MarkPositions; property Marks; property RotateLabels;