{**********************************************}
{   TActivityGauge                             }
{   Activity Gauge Series                     }
{                                              }
{   Copyright (c) 1999-2020 by Steema Software }
{**********************************************}
unit TeeActivityGauge;
{$I TeeDefs.inc}

interface

Uses {$IFNDEF LINUX}
     {$IFNDEF FMX}
     Windows,
     {$ENDIF}
     {$ENDIF}
     SysUtils, Classes,
     {$IFDEF FMX}
     FMX.Types, System.UITypes,
     {$ELSE}
     Graphics,
     {$ENDIF}

     {$IFDEF FMX}
     FMXTee.Engine, FMXTee.Chart, FMXTee.Canvas, FMXTee.Series, FMXTee.Series.Donut, FMXTee.Tools, FMXTee.TeeActivityDonut
     {$ELSE}
     TeEngine, Chart, TeCanvas, Series, TeeDonut, TeeTools, TeeActivityDonut
     {$ENDIF};

const
  TeeDefaultDonutPercent = 50;

type
  TActivityValues=Array of TActivityDonut;

  TActivityGauge=class(TDonutSeries)
  protected
    procedure AddSampleValues(NumValues: Integer; Sequential: Boolean=False); override;
    procedure AssignFormatting(Source: TChartSeries); override;
    class Function GetEditorClass:String; override;
    procedure DoBeforeDrawChart; override;
    procedure PrepareForGallery; override;
    procedure SetActive(Value:Boolean); override;
    Procedure SetParentChart(Const Value:TCustomAxisPanel); override;
  private
    FActivityValues : TActivityValues;
    FBackColor      : TColor;
    FCenterText     : TAnnotationTool;
    FHiddingSeries  : Boolean;
    function ConfigureActivity(Const ASeries: TActivityDonut; AValue:TChartValue;
      AIndex : integer; AColor : TColor): TActivityDonut;
    function GetActivityValues: TActivityValues;
    function GetCenterText: TAnnotationTool;
    Procedure SetBackColor(const Value:TColor);
  public
    Constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    function AddActivity(const AValue: TChartValue;
      const ALabel: String; const AColor:TColor=clTeeColor): Integer;
    procedure Clear; override;
    procedure Delete(ValueIndex:Integer); override;
    Function NumSampleValues:Integer; override;
  published
    property ActivityValues : TActivityValues read GetActivityValues write FActivityValues;
    property BackColor:TColor read FBackColor write SetBackColor default {$IFDEF FMX}TAlphaColors.Silver{$ELSE}clSilver{$ENDIF};
    property CenterText : TAnnotationTool read GetCenterText write FCenterText;
  end;

implementation

Uses
  {$IFDEF FMX}
  FMXTee.Constants, FMXTee.ProConstants, FMXTee.Procs
  {$ELSE}
  TeeConst, TeeProCo, TeeProcs
  {$ENDIF};

{ TDonutSeries }
Constructor TActivityGauge.Create(AOwner: TComponent);
begin
  inherited;

  Self.ShowInLegend:=False;
  FBackColor:={$IFDEF FMX}TAlphaColors.Silver{$ELSE}clSilver{$ENDIF};

  FCenterText:=TAnnotationTool.Create(AOwner);
  FCenterText.ShowInEditor:=False;
  FCenterText.Shape.Transparent:=True;
  FCenterText.Position:=ppCenter;
  FCenterText.Shape.Font.Size:=20;
end;

procedure TActivityGauge.Clear;
begin
  if Assigned(ParentChart) then
  begin
    if Assigned(FActivityValues) then
    begin
     FActivityValues:=nil;
    end;
  end;

  inherited Clear;
end;

function TActivityGauge.ConfigureActivity(Const ASeries : TActivityDonut; AValue:TChartValue;
    AIndex : integer; AColor : TColor) : TActivityDonut;
var I, tmpPercent, tmpOldPercent : integer;
begin
  (ASeries as TActivityDonut).MultiPie:=TMultiPie(mpDisabled);

  ASeries.Marks.Visible:=False;
  ASeries.Pen.Width:=3;

  if Assigned(ParentChart) then
  Begin
    if ParentChart.Gradient.Visible then
      ASeries.Pen.Color:=ParentChart.Gradient.StartColor
    else
     ASeries.Pen.Color:=ParentChart.Color;

    ASeries.Shadow.Visible:=False;

    //ASeries.Value:=Value;
    ASeries.ColorEachPoint:=False;

    if (AColor = clTeeColor) then
    Begin
      if Length(ParentChart.ColorPalette)>length(ActivityValues)-1 then
      begin
        ASeries.FillSampleValues(2);
        ASeries.ValueColor[0]:=BackColor;
        ASeries.ValueColor[1]:=Self.ParentChart.ColorPalette[length(ActivityValues)-1];
      end;
    end
    else
    begin
      ASeries.ValueColor[0]:=BackColor;
      ASeries.ValueColor[1]:=AColor;
    end;

    // Default Percent 50
    tmpPercent:=0;

    if (Length(FActivityValues)>1) then
      tmpPercent := (50 div (length(FActivityValues)))
    else
      Self.DonutPercent := 50;

    if (Length(FActivityValues)>1) then
      for I := 1 to length(FActivityValues)-1 do
      begin
         tmpOldPercent := 50 + (tmpPercent * (I)+1);
         FActivityValues[I].DonutPercent :=tmpOldPercent;
      end;
  end;
  result:=ASeries;
end;

function TActivityGauge.AddActivity(Const AValue:TChartValue; Const ALabel:String;
  Const AColor:TColor) : Integer;
var tmpArrayLength : Integer;
    tmpDonutSeries : TActivityDonut;
    i : integer;
begin

  if Length(FActivityValues)=0 then
    if Assigned(ParentChart) then
      ParentChart.FreeAllSeries( TActivityDonut );

  SetLength(FActivityValues, Length(FActivityValues)+1);
  tmpArrayLength:=Length(FActivityValues);

  Result:=tmpArrayLength-1;

  tmpDonutSeries:=nil;

  if tmpArrayLength>1 then
  begin
    tmpDonutSeries:=TActivityDonut.Create(ParentChart);
    ParentChart.AddSeries(tmpDonutSeries);
    tmpDonutSeries.ShowInLegend:=False;
    tmpDonutSeries.ShowInEditor:=False;
    FActivityValues[Result]:=tmpDonutSeries;

  end
  else
  begin
    FActivityValues[0]:=TActivityDonut.Create(ParentChart);
    ParentChart.AddSeries(FActivityValues[0]);
    FActivityValues[0].ShowInEditor:=False;
    FActivityValues[0].ShowInLegend:=False;
  end;

  for i := 1 to ParentChart.SeriesCount-1 do
  begin
   if (ParentChart.Series[i].ClassType <> TActivityGauge) then
      ParentChart.Series[i].ShowInEditor := False;
  end;

  if tmpArrayLength>1 then
     ConfigureActivity(tmpDonutSeries, AValue, tmpDonutSeries.SeriesIndex , AColor)
  else
     ConfigureActivity(FActivityValues[0], AValue, FActivityValues[0].SeriesIndex , AColor);

  if Assigned(ParentChart) then
     ParentChart.Enabled:=False;
end;

procedure TActivityGauge.AddSampleValues(NumValues:Integer; Sequential:Boolean=False);
var ActivitySampleStr : Array[0..2] of String;
    t : Integer;
Begin
  if NumValues <=5 then
  begin
    ActivitySampleStr[0]:=TeeMsg_PieSample1;
    ActivitySampleStr[1]:=TeeMsg_PieSample2;
    ActivitySampleStr[2]:=TeeMsg_PieSample3;

    for t:=0 to NumValues-1 do
    begin
      AddActivity( 1+RandomValue(99), { <-- Value }
           ActivitySampleStr[t mod 3]);      { <-- Label }
    end;
  end;
end;

procedure TActivityGauge.AssignFormatting(Source: TChartSeries);
begin
  if Source is TActivityGauge then
  With TActivityGauge(Source) do
  begin
    Self.BackColor:=BackColor;
    Self.CenterText:=CenterText
  end;

  inherited;

  if DonutPercent<=0 then
     SetDonutPercent(TeeDefaultDonutPercent);
end;

function TActivityGauge.GetActivityValues: TActivityValues;
begin
  Result := FActivityValues;
end;

function TActivityGauge.GetCenterText: TAnnotationTool;
begin
  if Assigned(ParentChart) then
    FCenterText.ParentChart:=ParentChart;
  Result := FCenterText;
end;

class Function TActivityGauge.GetEditorClass:String;
begin
  result:='TActivityGaugeSeriesEditor'; // Do not localize
end;

procedure TActivityGauge.PrepareForGallery;
begin
  inherited;
  AddSampleValues(3);

  if Assigned(ParentChart) then
    ParentChart.Enabled:=True;
end;

procedure TActivityGauge.SetActive(Value: Boolean);
var I : integer;
begin
  if not FHiddingSeries then
  begin
    inherited;

    if Assigned(FActivityValues) then
    begin
      FHiddingSeries:=True;
      for I := 0 to Length(ActivityValues)-1 do
        FActivityValues[I].Visible:=Visible;
      FHiddingSeries:=False;
    end;
  end;
end;

procedure TActivityGauge.Delete(ValueIndex: Integer);
var
  ALength: integer;
  i: integer;
begin
  ALength := Length(ActivityValues);
  Assert(ALength > 0);
  Assert(ValueIndex < ALength);
  for i := ValueIndex + 1 to ALength - 1 do
    ActivityValues[i - 1] := ActivityValues[i];
  SetLength(FActivityValues, ALength - 1);
end;

Destructor TActivityGauge.Destroy;
begin
  inherited;
  FreeAndNil(FCenterText);
end;

procedure TActivityGauge.DoBeforeDrawChart;
begin
  inherited;
  ParentChart.View3D:=False;
end;

function TActivityGauge.NumSampleValues: Integer;
begin
  result:=5;
end;

procedure TActivityGauge.SetBackColor(const Value: TColor);
var i : Integer;
begin
  FBackColor := Value;

  if Assigned(ParentChart) then
    for i := 0 to Length(ActivityValues)-1 do
    begin
      ActivityValues[i].ValueColor[0] := Value;
    end;
end;

procedure TActivityGauge.SetParentChart(const Value: TCustomAxisPanel);
begin
  inherited;
end;

initialization
  RegisterTeeSeries(TActivityGauge,@TeeMsg_ActivityGauge,
                                   @TeeMsg_GalleryGauges,1);
finalization
  UnRegisterTeeSeries([TActivityGauge]);
end.

