mirror of
				https://gitlab.com/freepascal.org/lazarus/lazarus.git
				synced 2025-11-04 08:19:53 +01:00 
			
		
		
		
	TAChart: Add Marks.YIndex property, implement labels for stacked series
git-svn-id: trunk@30588 -
This commit is contained in:
		
							parent
							
								
									88a88c1b2b
								
							
						
					
					
						commit
						553a073919
					
				@ -165,7 +165,7 @@ type
 | 
			
		||||
    function Count: Integer; inline;
 | 
			
		||||
    procedure Delete(AIndex: Integer); virtual;
 | 
			
		||||
    function Extent: TDoubleRect; virtual;
 | 
			
		||||
    function FormattedMark(AIndex: Integer): String;
 | 
			
		||||
    function FormattedMark(AIndex: Integer; AYIndex: Integer = 0): String;
 | 
			
		||||
    function IsEmpty: Boolean; override;
 | 
			
		||||
    function ListSource: TListChartSource;
 | 
			
		||||
    property Source: TCustomChartSource
 | 
			
		||||
@ -192,7 +192,6 @@ type
 | 
			
		||||
    function GetLabelDirection(AIndex: Integer): TLabelDirection;
 | 
			
		||||
    procedure SetMarkPositions(AValue: TLinearMarkPositions);
 | 
			
		||||
    procedure SetUseReticule(AValue: Boolean);
 | 
			
		||||
 | 
			
		||||
  protected
 | 
			
		||||
    FGraphPoints: array of TDoublePoint;
 | 
			
		||||
    FLoBound: Integer;
 | 
			
		||||
@ -555,12 +554,12 @@ begin
 | 
			
		||||
  Result := Source.ExtentCumulative;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
function TChartSeries.FormattedMark(AIndex: integer): String;
 | 
			
		||||
function TChartSeries.FormattedMark(AIndex, AYIndex: Integer): String;
 | 
			
		||||
begin
 | 
			
		||||
  if Assigned(FOnGetMark) then
 | 
			
		||||
    FOnGetMark(Result, AIndex)
 | 
			
		||||
  else
 | 
			
		||||
    Result := Source.FormatItem(Marks.Format, AIndex);
 | 
			
		||||
    Result := Source.FormatItem(Marks.Format, AIndex, AYIndex);
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
procedure TChartSeries.GetBounds(var ABounds: TDoubleRect);
 | 
			
		||||
@ -767,14 +766,26 @@ var
 | 
			
		||||
 | 
			
		||||
var
 | 
			
		||||
  g: TDoublePoint;
 | 
			
		||||
  i: Integer;
 | 
			
		||||
  i, si: Integer;
 | 
			
		||||
  ld: TLabelDirection;
 | 
			
		||||
begin
 | 
			
		||||
  if not Marks.IsMarkLabelsVisible then exit;
 | 
			
		||||
  for i := 0 to Count - 1 do begin
 | 
			
		||||
    g := GetGraphPoint(i);
 | 
			
		||||
    with ParentChart do
 | 
			
		||||
      if IsPointInViewPort(g) then
 | 
			
		||||
        DrawLabel(FormattedMark(i), GraphToImage(g), GetLabelDirection(i));
 | 
			
		||||
    ld := GetLabelDirection(i);
 | 
			
		||||
    for si := 0 to Source.YCount - 1 do begin
 | 
			
		||||
      if si > 0 then
 | 
			
		||||
        if IsRotated then
 | 
			
		||||
          g.X += AxisToGraphY(Source[i]^.YList[si - 1])
 | 
			
		||||
        else
 | 
			
		||||
          g.Y += AxisToGraphY(Source[i]^.YList[si - 1]);
 | 
			
		||||
      with ParentChart do
 | 
			
		||||
        if
 | 
			
		||||
          (Marks.YIndex = MARKS_YINDEX_ALL) or (Marks.YIndex = si) and
 | 
			
		||||
          IsPointInViewPort(g)
 | 
			
		||||
        then
 | 
			
		||||
          DrawLabel(FormattedMark(i, si), GraphToImage(g), ld);
 | 
			
		||||
    end;
 | 
			
		||||
  end;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -32,11 +32,15 @@ type
 | 
			
		||||
  // Like TColor, but avoiding dependency on Graphics.
 | 
			
		||||
  TChartColor = -$7FFFFFFF-1..$7FFFFFFF;
 | 
			
		||||
 | 
			
		||||
  TChartDataItem = record
 | 
			
		||||
  { TChartDataItem }
 | 
			
		||||
 | 
			
		||||
  TChartDataItem = object
 | 
			
		||||
  public
 | 
			
		||||
    X, Y: Double;
 | 
			
		||||
    Color: TChartColor;
 | 
			
		||||
    Text: String;
 | 
			
		||||
    YList: TDoubleDynArray;
 | 
			
		||||
    function GetY(AIndex: Integer): Double;
 | 
			
		||||
  end;
 | 
			
		||||
  PChartDataItem = ^TChartDataItem;
 | 
			
		||||
 | 
			
		||||
@ -73,7 +77,8 @@ type
 | 
			
		||||
    function ExtentCumulative: TDoubleRect;
 | 
			
		||||
    function ExtentList: TDoubleRect;
 | 
			
		||||
    procedure FindBounds(AXMin, AXMax: Double; out ALB, AUB: Integer);
 | 
			
		||||
    function FormatItem(const AFormat: String; AIndex: Integer): String;
 | 
			
		||||
    function FormatItem(
 | 
			
		||||
      const AFormat: String; AIndex, AYIndex: Integer): String;
 | 
			
		||||
    function IsSorted: Boolean; virtual;
 | 
			
		||||
    procedure ValuesInRange(
 | 
			
		||||
      AMin, AMax: Double; const AFormat: String; AUseY: Boolean;
 | 
			
		||||
@ -130,6 +135,17 @@ begin
 | 
			
		||||
    AItem.YList[i] := 0;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
{ TChartDataItem }
 | 
			
		||||
 | 
			
		||||
function TChartDataItem.GetY(AIndex: Integer): Double;
 | 
			
		||||
begin
 | 
			
		||||
  AIndex := EnsureRange(AIndex, 0, Length(YList));
 | 
			
		||||
  if AIndex = 0 then
 | 
			
		||||
    Result := Y
 | 
			
		||||
  else
 | 
			
		||||
    Result := YList[AIndex - 1];
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
{ TChartSourceBuffer }
 | 
			
		||||
 | 
			
		||||
procedure TChartSourceBuffer.AddFirst(const AItem: TChartDataItem);
 | 
			
		||||
@ -357,19 +373,20 @@ begin
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
function TCustomChartSource.FormatItem(
 | 
			
		||||
  const AFormat: String; AIndex: Integer): String;
 | 
			
		||||
  const AFormat: String; AIndex, AYIndex: Integer): String;
 | 
			
		||||
const
 | 
			
		||||
  TO_PERCENT = 100;
 | 
			
		||||
var
 | 
			
		||||
  total, percent: Double;
 | 
			
		||||
  total, percent, vy: Double;
 | 
			
		||||
begin
 | 
			
		||||
  total := ValuesTotal;
 | 
			
		||||
  if total = 0 then
 | 
			
		||||
    percent := 0
 | 
			
		||||
  else
 | 
			
		||||
    percent := TO_PERCENT / total;
 | 
			
		||||
  with Item[AIndex]^ do begin
 | 
			
		||||
    if total = 0 then
 | 
			
		||||
      percent := 0
 | 
			
		||||
    else
 | 
			
		||||
      percent := Y / total * TO_PERCENT;
 | 
			
		||||
    Result := Format(AFormat, [y, percent, Text, total, X]);
 | 
			
		||||
    vy := GetY(AYIndex);
 | 
			
		||||
    Result := Format(AFormat, [vy, vy * percent, Text, total, X]);
 | 
			
		||||
  end;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
@ -409,7 +426,7 @@ begin
 | 
			
		||||
    v := IfThen(AUseY, Item[i]^.Y, Item[i]^.X);
 | 
			
		||||
    if not InRange(v, AMin, AMax) then continue;
 | 
			
		||||
    AValues[cnt] := v;
 | 
			
		||||
    ATexts[cnt] := FormatItem(AFormat, i);
 | 
			
		||||
    ATexts[cnt] := FormatItem(AFormat, i, 0);
 | 
			
		||||
    cnt += 1;
 | 
			
		||||
  end;
 | 
			
		||||
  SetLength(AValues, cnt);
 | 
			
		||||
 | 
			
		||||
@ -1089,7 +1089,6 @@ begin
 | 
			
		||||
      for i := 1 to n2 - 2 do
 | 
			
		||||
        ADrawer.DrawLineDepth(pts[i], pts[i + 1], Depth);
 | 
			
		||||
    ADrawer.Polygon(pts, 0, numPts);
 | 
			
		||||
    DrawLabels(ADrawer);
 | 
			
		||||
  end;
 | 
			
		||||
  if AreaLinesPen.Style <> psClear then begin
 | 
			
		||||
    ADrawer.Pen := AreaLinesPen;
 | 
			
		||||
@ -1099,6 +1098,7 @@ begin
 | 
			
		||||
      ADrawer.Line(ParentChart.GraphToImage(a), ParentChart.GraphToImage(b));
 | 
			
		||||
    end;
 | 
			
		||||
  end;
 | 
			
		||||
  DrawLabels(ADrawer);
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
function TAreaSeries.Extent: TDoubleRect;
 | 
			
		||||
 | 
			
		||||
@ -37,6 +37,7 @@ const
 | 
			
		||||
  DEF_MARGIN = 4;
 | 
			
		||||
  DEF_MARKS_DISTANCE = 20;
 | 
			
		||||
  DEF_POINTER_SIZE = 4;
 | 
			
		||||
  MARKS_YINDEX_ALL = -1;
 | 
			
		||||
 | 
			
		||||
type
 | 
			
		||||
  TCustomChart = class(TCustomControl)
 | 
			
		||||
@ -130,12 +131,14 @@ type
 | 
			
		||||
  TGenericChartMarks = class(TChartElement)
 | 
			
		||||
  {$ENDIF}
 | 
			
		||||
  private
 | 
			
		||||
    FYIndex: Integer;
 | 
			
		||||
    procedure AddMargins(ADrawer: IChartDrawer; var ASize: TPoint);
 | 
			
		||||
    function GetDistanceToCenter: Boolean;
 | 
			
		||||
    function LabelAngle: Double; inline;
 | 
			
		||||
    procedure PutLabelFontTo(ADrawer: IChartDrawer);
 | 
			
		||||
    procedure SetAttachment(AValue: TChartMarkAttachment);
 | 
			
		||||
    procedure SetDistanceToCenter(AValue: Boolean);
 | 
			
		||||
    procedure SetYIndex(AValue: Integer);
 | 
			
		||||
  protected
 | 
			
		||||
    FAdditionalAngle: Double;
 | 
			
		||||
    FAttachment: TChartMarkAttachment;
 | 
			
		||||
@ -194,6 +197,7 @@ type
 | 
			
		||||
    property Distance: TChartDistance read FDistance write SetDistance;
 | 
			
		||||
    property LabelFont: TFont read FLabelFont write SetLabelFont;
 | 
			
		||||
    property Visible default true;
 | 
			
		||||
    property YIndex: Integer read FYIndex write SetYIndex default 0;
 | 
			
		||||
  end;
 | 
			
		||||
 | 
			
		||||
  TChartLinkPen = class(TChartPen)
 | 
			
		||||
@ -728,6 +732,13 @@ begin
 | 
			
		||||
  StyleChanged(Self);
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
procedure TGenericChartMarks.SetYIndex(AValue: Integer);
 | 
			
		||||
begin
 | 
			
		||||
  if FYIndex = AValue then exit;
 | 
			
		||||
  FYIndex := AValue;
 | 
			
		||||
  StyleChanged(Self);
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
{ TChartMarks }
 | 
			
		||||
 | 
			
		||||
procedure TChartMarks.Assign(Source: TPersistent);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user