home *** CD-ROM | disk | FTP | other *** search
/ Delphi 5 for Professionals / DELPHI5.iso / AddOns / Components / TEECHART / Src Code / SERIES.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1998-10-24  |  107.9 KB  |  3,597 lines

  1. {*********************************************}
  2. {  TeeChart Standard Series Types             }
  3. {  Copyright (c) 1995-1998 by David Berneda   }
  4. {  All Rights Reserved                        }
  5. {                                             }
  6. {   TCustomSeries                             }
  7. {     TLineSeries                             }
  8. {     TAreaSeries                             }
  9. {     TPointSeries                            }
  10. {   TCustomBarSeries                          }
  11. {     TBarSeries                              }
  12. {     THorizBarSeries                         }
  13. {   TCircledSeries                            }
  14. {     TPieSeries                              }
  15. {   TFastLineSeries                           }
  16. {*********************************************}
  17. {$I teedefs.inc}
  18. unit Series;
  19.  
  20. interface
  21.  
  22. Uses Graphics,WinTypes,WinProcs,TeEngine,Chart,SysUtils,Classes,TeCanvas,
  23.      TeeProcs;
  24.  
  25. Const TwoPi    : Double = 2.0*pi;
  26.       HalfPi   : Double = 0.5*pi;
  27.       PiDegree : Double = pi/180.0;
  28.  
  29. Type
  30.   TSeriesPointerStyle=( psRectangle,psCircle,psTriangle,psDownTriangle,
  31.                         psCross,psDiagCross,psStar,psDiamond,psSmallDot );
  32.  
  33.   TOnGetPointerStyle=Function( Sender:TChartSeries;
  34.                                ValueIndex:Longint):TSeriesPointerStyle of object;
  35.  
  36.   TSeriesPointer=class(TPersistent)
  37.   private
  38.     FDark3D    : Boolean;
  39.     FDraw3D    : Boolean;
  40.     FBrush     : TChartBrush;
  41.     FHorizSize : Integer;
  42.     FInflateMargins:Boolean;
  43.     FOwner     : TChartSeries;
  44.     FPen       : TChartPen;
  45.     FStyle     : TSeriesPointerStyle;
  46.     FVertSize  : Integer;
  47.     FVisible   : Boolean;
  48.     Procedure CheckPointerSize(Value:Integer);
  49.     Procedure SetDark3D(Value:Boolean);
  50.     Procedure SetDraw3D(Value:Boolean);
  51.     Procedure SetBrush(Value:TChartBrush);
  52.     Procedure SetHorizSize(Value:Integer);
  53.     Procedure SetInflateMargins(Value:Boolean);
  54.     Procedure SetPen(Value:TChartPen);
  55.     Procedure SetStyle(Value:TSeriesPointerStyle);
  56.     Procedure SetVertSize(Value:Integer);
  57.     Procedure SetVisible(Value:Boolean);
  58.   protected
  59.     Procedure SetBooleanProperty(Var Variable:Boolean; Value:Boolean);
  60.     Procedure SetIntegerProperty(Var Variable:Integer; Value:Integer);
  61.   public
  62.     AllowChangeSize:Boolean;
  63.  
  64.     Constructor Create(AOwner:TChartSeries);
  65.     Destructor Destroy; override;
  66.  
  67.     Procedure Assign(Source:TPersistent); override;
  68.     Procedure CalcHorizMargins(Var LeftMargin,RightMargin:Integer);
  69.     Procedure CalcVerticalMargins(Var TopMargin,BottomMargin:Integer);
  70.     Procedure Change3D(Value:Boolean);
  71.     Procedure ChangeHorizSize(NewSize:Integer);
  72.     Procedure ChangeStyle(NewStyle:TSeriesPointerStyle);
  73.     Procedure ChangeVertSize(NewSize:Integer);
  74.     Procedure Draw(px,py:Integer; ColorValue:TColor; AStyle:TSeriesPointerStyle);
  75.     Procedure DrawLegendShape(AColor:TColor; Const Rect:TRect; DrawPen:Boolean);
  76.     Procedure DrawPointer(Is3D:Boolean; px,py,tmpHoriz,tmpVert:Integer; ColorValue:TColor; AStyle:TSeriesPointerStyle);
  77.     Procedure PrepareCanvas(ColorValue:TColor);
  78.  
  79.     property ParentSeries:TChartSeries read FOwner;
  80.   published
  81.     property Brush:TChartBrush read FBrush write SetBrush;
  82.     property Dark3D:Boolean read FDark3D write SetDark3D default True;
  83.     Property Draw3D:Boolean read FDraw3D write SetDraw3D default True;
  84.     Property HorizSize:Integer read FHorizSize write SetHorizSize default 4;
  85.     property InflateMargins:Boolean read FInflateMargins write SetInflateMargins;
  86.     property Pen:TChartPen read FPen write SetPen;
  87.     Property Style:TSeriesPointerStyle read FStyle write SetStyle;
  88.     Property VertSize:Integer read FVertSize write SetVertSize default 4;
  89.     Property Visible:Boolean read FVisible write SetVisible;
  90.   end;
  91.  
  92.   TCustomSeries=class;
  93.  
  94.   TSeriesClickPointerEvent=Procedure( Sender:TCustomSeries;
  95.                                       ValueIndex:Longint;
  96.                                       X, Y: Integer) of object;
  97.  
  98.   TCustomSeries=Class(TChartSeries)
  99.   private
  100.     FAreaBrush          : TBrushStyle;
  101.     FAreaColor          : TColor;
  102.     FAreaLinesPen       : TChartPen;
  103.     FClickableLine      : Boolean;
  104.     FDark3D             : Boolean;
  105.     FDrawArea           : Boolean;
  106.     FDrawLine           : Boolean;
  107.     FInvertedStairs     : Boolean;
  108.     FLineBrush          : TBrushStyle;
  109.     FLineHeight         : Integer;
  110.     FLinePen            : TChartPen;
  111.     FPointer            : TSeriesPointer;
  112.     FStairs             : Boolean;
  113.  
  114.     { events }
  115.     FOnClickPointer     : TSeriesClickPointerEvent;
  116.     FOnGetPointerStyle  : TOnGetPointerStyle;
  117.  
  118.     { internal }
  119.     BottomPos      : Longint;
  120.     OldBottomPos   : Longint;
  121.     OldX           : Longint;
  122.     OldY           : Longint;
  123.     OldColor       : TColor;
  124.     tmpDark3DRatio : Double;
  125.     Procedure SetAreaBrush(Value:TBrushStyle);
  126.     Procedure SetAreaColor(Value:TColor);
  127.     Procedure SetAreaLinesPen(Value:TChartPen);
  128.     Procedure SetBrushProperty(Var ABrush:TBrushStyle; Value:TBrushStyle);
  129.     Procedure SetDark3D(Value:Boolean);
  130.     Procedure SetDrawArea(Value:Boolean);
  131.     Procedure SetInvertedStairs(Value:Boolean);
  132.     Procedure SetLineBrush(Value:TBrushStyle);
  133.     Procedure SetLineHeight(Value:Integer);
  134.     Procedure SetLinePen(Value:TChartPen);
  135.     Procedure SetPointer(Value:TSeriesPointer);
  136.     Procedure SetStairs(Value:Boolean);
  137.   protected
  138.     Function ClickedPointer( ValueIndex,tmpX,tmpY:Longint;
  139.                              x,y:Longint):Boolean; virtual;
  140.     Procedure DrawMark( ValueIndex:Longint; Const St:String;
  141.                         APosition:TSeriesMarkPosition); override;
  142.     Procedure DrawPointer(AX,AY:Longint; AColor:TColor; ValueIndex:Longint); virtual;
  143.     procedure DrawValue(ValueIndex:Longint); override;
  144.     Function GetAreaBrushColor(AColor:TColor):TColor;
  145.     procedure LinePrepareCanvas(tmpCanvas:TCanvas3D; tmpColor:TColor);
  146.   public
  147.     Constructor Create(AOwner: TComponent); override;
  148.     Destructor Destroy; override;
  149.  
  150.     Procedure Assign(Source:TPersistent); override;
  151.     Procedure CalcHorizMargins(Var LeftMargin,RightMargin:Integer); override;
  152.     Procedure CalcVerticalMargins(Var TopMargin,BottomMargin:Integer); override;
  153.     Function Clicked(x,y:Integer):Longint; override;
  154.     Procedure DrawLegendShape(ValueIndex:Longint; Const Rect:TRect); override;
  155.     Function GetEditorClass:String; override;
  156.     Function GetOriginPos(ValueIndex:Longint):Longint; virtual;
  157.  
  158.     property AreaBrush:TBrushStyle read FAreaBrush write SetAreaBrush default bsSolid;
  159.     property AreaColor:TColor read FAreaColor write SetAreaColor default clTeeColor;
  160.     property AreaLinesPen:TChartPen read FAreaLinesPen write SetAreaLinesPen;
  161.     property ClickableLine:Boolean read FClickableLine write FClickableLine;
  162.     property Dark3D:Boolean read FDark3D write SetDark3D default True;
  163.     property DrawArea:Boolean read FDrawArea write SetDrawArea default False;
  164.     property InvertedStairs:Boolean read FInvertedStairs write SetInvertedStairs default False;
  165.     property LineBrush:TBrushStyle read FLineBrush write SetLineBrush default bsSolid;
  166.     property LineHeight:Integer read FLineHeight write SetLineHeight default 0;
  167.     property LinePen:TChartPen read FLinePen write SetLinePen;
  168.     property OnClickPointer:TSeriesClickPointerEvent read FOnClickPointer
  169.                                                      write FOnClickPointer;
  170.     property Pointer:TSeriesPointer read FPointer write SetPointer;
  171.     property Stairs:Boolean read FStairs write SetStairs default False;
  172.   published
  173.     { events }
  174.     property OnGetPointerStyle:TOnGetPointerStyle read FOnGetPointerStyle
  175.                                                   write FOnGetPointerStyle;
  176.  
  177.   end;
  178.  
  179.   TLineSeries=Class(TCustomSeries)
  180.   public
  181.     Constructor Create(AOwner: TComponent); override;
  182.     Procedure Assign(Source:TPersistent); override;
  183.     Procedure PrepareLegendCanvas( ValueIndex:Longint; Var BackColor:TColor;
  184.                                    Var BrushStyle:TBrushStyle); override;
  185.   published
  186.     property Dark3D;
  187.     property InvertedStairs;
  188.     property LineBrush;
  189.     property LineHeight;
  190.     property LinePen;
  191.     property Pointer;
  192.     property Stairs;
  193.     property XValues;
  194.     property YValues;
  195.   end;
  196.  
  197.   TPointSeries=Class(TCustomSeries)
  198.   protected
  199.     Procedure SetColorEachPoint(Value:Boolean); override;
  200.   public
  201.     Constructor Create(AOwner: TComponent); override;
  202.     Procedure Assign(Source:TPersistent); override;
  203.     Function GetEditorClass:String; override;
  204.     Procedure PrepareForGallery(IsEnabled:Boolean); override;
  205.   published
  206.     property Pointer;
  207.     property XValues;
  208.     property YValues;
  209.    { events }
  210.     property OnClickPointer;
  211.   end;
  212.  
  213.   TMultiArea=(maNone,maStacked,maStacked100);
  214.  
  215.   TAreaSeries=Class(TCustomSeries)
  216.   private
  217.     FMultiArea : TMultiArea;
  218.     Procedure SetMultiArea(Value:TMultiArea);
  219.     Procedure SetOtherMultiArea;
  220.     Function InternalCalcStackedYPos(ValueIndex:Integer; Value:Double):Integer;
  221.   public
  222.     Constructor Create(AOwner: TComponent); override;
  223.     Procedure Assign(Source:TPersistent); override;
  224.     Procedure CalcZOrder; override;
  225.     Function CalcYPos(ValueIndex:Longint):Integer; override;
  226.     Function GetEditorClass:String; override;
  227.     Function GetOriginPos(ValueIndex:Longint):Longint; override;
  228.     Procedure PrepareLegendCanvas( ValueIndex:Longint; Var BackColor:TColor;
  229.                                    Var BrushStyle:TBrushStyle); override;
  230.     Function MaxYValue:Double; override;
  231.     Function MinYValue:Double; override;
  232.   published
  233.     property AreaBrush;
  234.     property AreaColor;
  235.     property AreaLinesPen;
  236.     property Dark3D;
  237.     property DrawArea;
  238.     property InvertedStairs;
  239.     property LinePen;
  240.     property MultiArea:TMultiArea read FMultiArea write SetMultiArea default maNone;
  241.     property Stairs;
  242.     property XValues;
  243.     property YValues;
  244.   end;
  245.  
  246.   BarException=class(Exception);
  247.  
  248.   TMultiBar=(mbNone,mbSide,mbStacked,mbStacked100{$IFDEF TEE5},mbSeries{$ENDIF});
  249.  
  250.   TCustomBarSeries=class;
  251.  
  252.   TBarStyle=( bsRectangle,bsPyramid,bsInvPyramid,
  253.               bsCilinder,bsEllipse,bsArrow,bsRectGradient );
  254.  
  255.   TGetBarStyleEvent=Procedure( Sender:TCustomBarSeries; ValueIndex:Longint;
  256.                                Var TheBarStyle:TBarStyle) of object;
  257.  
  258.   TCustomBarSeries=Class(TChartSeries)
  259.   private
  260.     FAutoBarSize     : Boolean;
  261.     FAutoMarkPosition: Boolean;
  262.     FBarBrush        : TChartBrush;
  263.     FBarPen          : TChartPen;
  264.     FBarStyle        : TBarStyle;
  265.     FBarWidthPercent : Integer;
  266.     FCustomBarSize   : Integer;
  267.     FDark3D          : Boolean;
  268.     FMultiBar        : TMultiBar;
  269.     FOffsetPercent   : Integer;
  270.     FSideMargins     : Boolean;
  271.     FUseOrigin       : Boolean;
  272.     FOrigin          : Double;
  273.     { events }
  274.     FOnGetBarStyle   : TGetBarStyleEvent;
  275.  
  276.     { internal }
  277.     IBarSize   : Longint;
  278.     FBarBounds : TRect;
  279.     Procedure CalcBarWidth;
  280.     Function InternalCalcMarkLength(ValueIndex:Longint):Longint; virtual; abstract;
  281.     Procedure SetAutoBarSize(Value:Boolean);
  282.     Procedure SetAutoMarkPosition(Value:Boolean);
  283.     Procedure SetBarWidthPercent(Value:Integer);
  284.     Procedure SetOffsetPercent(Value:Integer);
  285.     Procedure SetBarStyle(Value:TBarStyle);
  286.     Procedure SetDark3d(Value:Boolean);
  287.     Procedure SetUseOrigin(Value:Boolean);
  288.     Procedure SetSideMargins(Value:Boolean);
  289.     Procedure SetBarPen(Value:TChartPen);
  290.     Procedure SetBarBrush(Value:TChartBrush);
  291.     Procedure SetOrigin(Const Value:Double);
  292.     Procedure SetMultiBar(Value:TMultiBar);
  293.     Procedure SetOtherMultiBar;
  294.  
  295.     Procedure AdjustGradientRectPen(Var R:TRect);
  296.     Function BarOrderPos:Longint;
  297.     Function BarSeriesCount:Longint;
  298.     Function MaxMandatoryValue( Const Value:Double;
  299.                                 AList:TChartValueList):Double;
  300.     Function MinMandatoryValue(Const Value:Double):Double;
  301.     Procedure InternalApplyBarMargin(Var MarginA,MarginB:Integer);
  302.   protected
  303.     Function InternalClicked(ValueIndex:Longint; Const APoint:TPoint):Boolean; virtual;
  304.     Function InternalGetOriginPos(ValueIndex:Longint; DefaultOrigin:Longint):Longint;
  305.     Procedure SetCustomBarSize(Value:Integer);
  306.   public
  307.     NormalBarColor:TColor;
  308.     Constructor Create(AOwner:TComponent); override;
  309.     Destructor Destroy; override;
  310.  
  311.     Function AddBar(Const AValue:Double; Const ALabel:String; AColor:TColor):Longint;
  312.     Function ApplyBarOffset(Position:Longint):Longint;
  313.     Procedure Assign(Source:TPersistent); override;
  314.     Function BarMargin:Longint;
  315.     Procedure BarRectangle(BarColor:TColor; ALeft,ATop,ARight,ABottom:Longint);
  316.     Function CalcMarkLength(ValueIndex:Longint):Longint;
  317.     Procedure CalcZOrder; override;
  318.     Function Clicked(x,y:Integer):Longint; override;
  319.     Procedure DrawLegendShape(ValueIndex:Longint; Const Rect:TRect); override;
  320.     Function GetBarStyle(ValueIndex:Longint):TBarStyle;
  321.     Function GetEditorClass:String; override;
  322.     Function NumSampleValues:Longint; override;
  323.     Function PointOrigin(ValueIndex:Longint; SumAll:Boolean):Double; override;
  324.     Procedure PrepareForGallery(IsEnabled:Boolean); override;
  325.     Procedure PrepareLegendCanvas( ValueIndex:Longint; Var BackColor:TColor;
  326.                                    Var BrushStyle:TBrushStyle); override;
  327.     Procedure SetPenBrushBar(BarColor:TColor);
  328.  
  329.     property BarBounds:TRect read FBarBounds;
  330.   published
  331.     property AutoBarSize:Boolean read FAutoBarSize write SetAutoBarSize default False;
  332.     property AutoMarkPosition:Boolean read FAutoMarkPosition write SetAutoMarkPosition default True;
  333.     property BarBrush:TChartBrush read FBarBrush write SetBarBrush;
  334.     property BarPen:TChartPen read FBarPen write SetBarPen;
  335.     property BarStyle:TBarStyle read FBarStyle write SetBarStyle
  336.                                 default bsRectangle;
  337.     property BarWidthPercent:Integer read FBarWidthPercent
  338.                                      write SetBarWidthPercent default 70;
  339.     property Dark3D:Boolean read FDark3D write SetDark3D default True;
  340.     property MultiBar:TMultiBar read FMultiBar write SetMultiBar default mbSide;
  341.     property OffsetPercent:Integer read FOffsetPercent
  342.                                    write SetOffsetPercent default 0;
  343.     property SideMargins:Boolean read FSideMargins write SetSideMargins default True;
  344.     property UseYOrigin:Boolean read FUseOrigin write SetUseOrigin default True;
  345.     property YOrigin:Double read FOrigin write SetOrigin;
  346.  
  347.     { inherited published }
  348.     property XValues;
  349.     property YValues;
  350.     { events }
  351.     property OnGetBarStyle:TGetBarStyleEvent read FOnGetBarStyle write
  352.                                              FOnGetBarStyle;
  353.   end;
  354.  
  355.   TBarSeries=class(TCustomBarSeries)
  356.   private
  357.     Function InternalCalcMarkLength(ValueIndex:Longint):Longint; override;
  358.   protected
  359.     procedure DrawValue(ValueIndex:Longint); override;
  360.     Procedure DrawMark( ValueIndex:Longint; Const St:String;
  361.                         APosition:TSeriesMarkPosition); override;
  362.   public
  363.     Function InternalClicked(ValueIndex:Longint; Const APoint:TPoint):Boolean; override;
  364.     Procedure CalcHorizMargins(Var LeftMargin,RightMargin:Integer); override;
  365.     Procedure CalcVerticalMargins(Var TopMargin,BottomMargin:Integer); override;
  366.     Function CalcXPos(ValueIndex:Longint):Integer; override;
  367.     Function CalcYPos(ValueIndex:Longint):Integer; override;
  368.     Procedure DrawBar(BarIndex,StartPos,EndPos:Longint); virtual;
  369.     Function DrawSeriesForward(ValueIndex:Longint):Boolean; override;
  370.     Function DrawValuesForward:Boolean; override;
  371.     Function GetOriginPos(ValueIndex:Longint):Longint;
  372.     Function MaxYValue:Double; override;
  373.     Function MinYValue:Double; override;
  374.     property BarWidth:Longint read IBarSize;
  375.   published
  376.     property CustomBarWidth:Integer read FCustomBarSize
  377.                                     write SetCustomBarSize default 0;
  378.   end;
  379.  
  380.   THorizBarSeries=class(TCustomBarSeries)
  381.   private
  382.     Function InternalCalcMarkLength(ValueIndex:Longint):Longint; override;
  383.   protected
  384.     procedure DrawValue(ValueIndex:Longint); override;
  385.     Procedure DrawMark( ValueIndex:Longint; Const St:String;
  386.                         APosition:TSeriesMarkPosition); override;
  387.   public
  388.     Function InternalClicked(ValueIndex:Longint; Const APoint:TPoint):Boolean; override;
  389.     Procedure CalcHorizMargins(Var LeftMargin,RightMargin:Integer); override;
  390.     Procedure CalcVerticalMargins(Var TopMargin,BottomMargin:Integer); override;
  391.     Function CalcXPos(ValueIndex:Longint):Integer; override;
  392.     Function CalcYPos(ValueIndex:Longint):Integer; override;
  393.     Procedure DrawBar(BarIndex,StartPos,EndPos:Longint); virtual;
  394.     Function DrawSeriesForward(ValueIndex:Longint):Boolean; override;
  395.     Function DrawValuesForward:Boolean; override;
  396.     Procedure FillSampleValues(NumValues:Longint); override;
  397.     Function GetOriginPos(ValueIndex:Longint):Longint;
  398.     Function MandatoryValueList:TChartValueList; override;
  399.     Function MaxXValue:Double; override;
  400.     Function MinXValue:Double; override;
  401.     property BarHeight:Longint read IBarSize;
  402.   published
  403.     property CustomBarHeight:Integer read FCustomBarSize
  404.                                      write SetCustomBarSize default 0;
  405.   end;
  406.  
  407.   TCircledSeries=class(TChartSeries)
  408.   private
  409.     FCircled         : Boolean;
  410.     FRotationAngle   : Integer;
  411.     FCustomXRadius   : Longint;
  412.     FCustomYRadius   : Longint;
  413.     FXRadius         : Longint;
  414.     FYRadius         : Longint;
  415.     FCircleBackColor : TColor;
  416.     { internal }
  417.     IRotDegree      : Double;
  418.     FCircleWidth    : Longint;
  419.     FCircleHeight   : Longint;
  420.     FCircleXCenter  : Longint;
  421.     FCircleYCenter  : Longint;
  422.     FCircleRect     : TRect;
  423.     procedure SetCircleBackColor(Value:TColor);
  424.     procedure SetCustomXRadius(Value:Longint);
  425.     procedure SetCustomYRadius(Value:Longint);
  426.     Procedure SetCircled(Value:Boolean);
  427.     procedure SetOtherCustomRadius(IsXRadius:Boolean; Value:Longint);
  428.     Procedure SetRotationAngle(Value:Integer);
  429.   protected
  430.     Procedure AdjustCircleRect;
  431.     Function CalcCircleBackColor:TColor;
  432.     Procedure CalcRadius;
  433.     procedure DoBeforeDrawValues; override;
  434.     Procedure SetActive(Value:Boolean); override;
  435.     Procedure SetParentChart(Value:TCustomAxisPanel); override;
  436.   public
  437.     Constructor Create(AOwner: TComponent); override;
  438.     Destructor Destroy; override;
  439.     Procedure AngleToPos( Const Angle,AXRadius,AYRadius:Double;
  440.                           Var X,Y:{$IFDEF D2C1}Longint{$ELSE}Integer{$ENDIF});
  441.     Procedure Assign(Source:TPersistent); override;
  442.     Function AssociatedToAxis(Axis:TCustomChartAxis):Boolean; override;
  443.     Function PointToAngle(x,y:Longint):Double;
  444.     Procedure PrepareLegendCanvas( ValueIndex:Longint; Var BackColor:TColor;
  445.                                    Var BrushStyle:TBrushStyle); override;
  446.     Procedure Rotate(Angle:Integer);
  447.     Procedure SetParentProperties(EnableParentProps:Boolean); virtual;
  448.     Function UseAxis:Boolean; override;
  449.     { read only properties }
  450.     property XRadius:Longint read FXRadius;
  451.     property YRadius:Longint read FYRadius;
  452.     property CircleXCenter:Longint read FCircleXCenter;
  453.     property CircleYCenter:Longint read FCircleYCenter;
  454.     property CircleWidth:Longint read FCircleWidth;
  455.     property CircleHeight:Longint read FCircleHeight;
  456.     property CircleRect:TRect read FCircleRect;
  457.     property CircleBackColor:TColor read FCircleBackColor
  458.                                     write SetCircleBackColor default clTeeColor;
  459.     property RotationAngle:Integer read FRotationAngle write SetRotationAngle
  460.                                    default 0;
  461.   published
  462.     property Circled:Boolean read FCircled write SetCircled default False;
  463.     property CustomXRadius:Longint read FCustomXRadius write SetCustomXRadius default 0;
  464.     property CustomYRadius:Longint read FCustomYRadius write SetCustomYRadius default 0;
  465.   end;
  466.  
  467.   PieException=class(ChartException);
  468.  
  469.   TPieAngle=class
  470.   public
  471.     StartAngle : Double;
  472.     MidAngle   : Double;
  473.     EndAngle   : Double;
  474.   end;
  475.  
  476.   TPieAngles=class(TList)
  477.   private
  478.     Function GetAngle(Index:Integer):TPieAngle;
  479.   public
  480.     property Angle[Index:Integer]:TPieAngle read GetAngle; {$IFNDEF D1}default;{$ENDIF}
  481.   end;
  482.  
  483.   TExplodedSlices=class(TList)
  484.   private
  485.     Procedure SetValue(Index,Value:Integer);
  486.     Function GetValue(Index:Integer):Integer;
  487.   public
  488.     OwnerSeries:TChartSeries;
  489.     property Value[Index:Integer]:Integer read GetValue write SetValue; {$IFNDEF D1}default;{$ENDIF}
  490.   end;
  491.  
  492.   TPieOtherStyle=(poNone,poBelowPercent,poBelowValue);
  493.  
  494.   TPieOtherSlice=class(TPersistent)
  495.   private
  496.     FStyle    : TPieOtherStyle;
  497.     FText     : String;
  498.     FValue    : Double;
  499.     FOwner    : TChartSeries;
  500.     procedure SetStyle(Value:TPieOtherStyle);
  501.     procedure SetText(Const Value:String);
  502.     procedure SetValue(Const Value:Double);
  503.   public
  504.     Constructor Create(AOwner:TChartSeries);
  505.     Procedure Assign(Source:TPersistent); override;
  506.   published
  507.     property Style:TPieOtherStyle read FStyle write SetStyle default poNone;
  508.     property Text:String read FText write SetText;
  509.     property Value:Double read FValue write SetValue;
  510.   end;
  511.  
  512.   TPieSeries=Class(TCircledSeries)
  513.   private
  514.     FDark3d        : Boolean;
  515.     FExplodedSlice : TExplodedSlices; { <-- Exploded slice % storage }
  516.     FExplodeBiggest: Integer;
  517.     FPiePen        : TChartPen;
  518.     FOtherSlice    : TPieOtherSlice;
  519.     FUsePatterns   : Boolean;
  520.  
  521.     Procedure DisableRotation;
  522.     Procedure FreePieAngles;
  523.     { props }
  524.     procedure SetUsePatterns(Value:Boolean);
  525.     Procedure SetDark3d(Value:Boolean);
  526.     Function GetPieValues:TChartValueList;
  527.     Procedure SetPieValues(Value:TChartValueList);
  528.     procedure SetExplodeBiggest(Value:Integer);
  529.     procedure SetPiePen(Value:TChartPen);
  530.     procedure SetOtherSlice(Value:TPieOtherSlice);
  531.     Procedure CalcExplodeBiggest;
  532.     Procedure CalcExplodedOffset( ValueIndex:Integer;
  533.                                   Var OffsetX,OffsetY:Integer);
  534.   protected
  535.     FAngles    : TPieAngles;
  536.     IniX,
  537.     IniY,
  538.     EndX,
  539.     EndY:{$IFDEF D2C1}Longint{$ELSE}Integer{$ENDIF};
  540.     IsExploded : Boolean;
  541.     Procedure CalcAngles;
  542.     Procedure CalcExplodedRadius(ValueIndex:Integer; Var AXRadius,AYRadius:Integer);
  543.     procedure DoBeforeDrawChart; override;
  544.     procedure DrawAllValues; override;
  545.     Procedure DrawPie(ValueIndex:Integer); virtual;
  546.     procedure DrawValue(ValueIndex:Longint); override;
  547.     Procedure DrawMark( ValueIndex:Longint; Const St:String;
  548.                         APosition:TSeriesMarkPosition); override;
  549.     Procedure ClearLists; override;
  550.   public
  551.     Constructor Create(AOwner: TComponent); override;
  552.     Destructor Destroy; override;
  553.     Function AddPie(Const AValue:Double; Const ALabel:String; AColor:TColor):Longint;
  554.     Procedure Assign(Source:TPersistent); override;
  555.     Function BelongsToOtherSlice(ValueIndex:Integer):Boolean;
  556.     Function CalcClickedPie(x,y:Integer):Longint;
  557.     Function CalcXPos(ValueIndex:Longint):Integer; override;
  558.     Function Clicked(x,y:Integer):Longint; override;
  559.     Function CountLegendItems:Integer; override;
  560.     Procedure FillSampleValues(NumValues:Longint); override;
  561.     Procedure GalleryChanged3D(Is3D:Boolean); override;
  562.     Function GetEditorClass:String; override;
  563.     Function LegendToValueIndex(LegendIndex:Integer):Integer; override;
  564.     Function MaxXValue:Double; override;
  565.     Function MinXValue:Double; override;
  566.     Function MaxYValue:Double; override;
  567.     Function MinYValue:Double; override;
  568.     Function NumSampleValues:Longint; override;
  569.     Procedure PrepareForGallery(IsEnabled:Boolean); override;
  570.     Procedure PrepareLegendCanvas( ValueIndex:Longint; Var BackColor:TColor;
  571.                                    Var BrushStyle:TBrushStyle); override;
  572.     procedure SwapValueIndex(a,b:Longint); override;
  573.  
  574.     property Angles:TPieAngles read FAngles;
  575.     property ExplodedSlice:TExplodedSlices read FExplodedSlice;
  576.   published
  577.     property CircleBackColor;
  578.     property ColorEachPoint default True;
  579.     property Dark3D:Boolean read FDark3D write SetDark3D default True;
  580.     property ExplodeBiggest:Integer read FExplodeBiggest write SetExplodeBiggest default 0;
  581.     property OtherSlice:TPieOtherSlice read FOtherSlice write SetOtherSlice;
  582.     property PiePen:TChartPen read FPiePen write SetPiePen;
  583.     property PieValues:TChartValueList read GetPieValues write SetPieValues;
  584.     property RotationAngle;
  585.     property UsePatterns:Boolean read FUsePatterns write SetUsePatterns default False;
  586.   end;
  587.  
  588.   TFastLineSeries=class(TChartSeries)
  589.   private
  590.     FAutoRepaint : Boolean;
  591.     FLinePen     : TChartPen;
  592.     { internal }
  593.     OldX         : Longint;
  594.     OldY         : Longint;
  595.     Procedure SetLinePen(Value:TChartPen);
  596.   protected
  597.     procedure DrawValue(ValueIndex:Longint); override;
  598.     procedure DrawAllValues; override;
  599.     Procedure SetSeriesColor(AColor:TColor); override;
  600.     procedure PrepareCanvas;
  601.     Procedure DrawMark( ValueIndex:Longint; Const St:String;
  602.                         APosition:TSeriesMarkPosition); override;
  603.   public
  604.     Constructor Create(AOwner: TComponent); override;
  605.     Destructor Destroy; override;
  606.     Procedure Assign(Source:TPersistent); override;
  607.     Function Clicked(x,y:Integer):Longint; override;
  608.     Procedure DrawLegendShape(ValueIndex:Longint; Const Rect:TRect); override;
  609.     Function GetEditorClass:String; override;
  610.     Procedure NotifyNewValue(Sender:TChartSeries; ValueIndex:Longint); override;
  611.   published
  612.     property AutoRepaint:Boolean read FAutoRepaint write FAutoRepaint default True;
  613.     property LinePen:TChartPen read FLinePen write SetLinePen;
  614.     property XValues;
  615.     property YValues;
  616.   end;
  617.  
  618. implementation
  619.  
  620. Uses TeeConst;
  621.  
  622. { TSeriesPointer }
  623. Constructor TSeriesPointer.Create(AOwner:TChartSeries);
  624. Begin
  625.   inherited Create;
  626.   AllowChangeSize:=True;
  627.  
  628.   FOwner:=AOwner;
  629.   FInflateMargins:=True;
  630.   FVisible:=True;
  631.   FHorizSize:=4;
  632.   FVertSize:=4;
  633.   FDark3D:=True;
  634.   FDraw3D:=True;
  635.   FStyle:=psRectangle;
  636.   FPen:=FOwner.CreateChartPen;
  637.   FBrush:=TChartBrush.Create(FOwner.CanvasChanged);
  638. end;
  639.  
  640. Destructor TSeriesPointer.Destroy;
  641. begin
  642.   FPen.Free;
  643.   FBrush.Free;
  644.   inherited Destroy;
  645. end;
  646.  
  647. Procedure TSeriesPointer.ChangeStyle(NewStyle:TSeriesPointerStyle);
  648. Begin
  649.   FStyle:=NewStyle;
  650. end;
  651.  
  652. Procedure TSeriesPointer.ChangeHorizSize(NewSize:Integer);
  653. Begin
  654.   FHorizSize:=NewSize;
  655. End;
  656.  
  657. Procedure TSeriesPointer.ChangeVertSize(NewSize:Integer);
  658. Begin
  659.   FVertSize:=NewSize;
  660. End;
  661.  
  662. Procedure TSeriesPointer.SetIntegerProperty(Var Variable:Integer; Value:Integer);
  663. begin
  664.   FOwner.SetIntegerProperty(Variable,Value);
  665. end;
  666.  
  667. Procedure TSeriesPointer.SetBooleanProperty(Var Variable:Boolean; Value:Boolean);
  668. begin
  669.   FOwner.SetBooleanProperty(Variable,Value);
  670. end;
  671.  
  672. Procedure TSeriesPointer.CheckPointerSize(Value:Integer);
  673. begin
  674.   if Value<1 then Raise ChartException.Create(TeeMsg_CheckPointerSize)
  675. end;
  676.  
  677. Procedure TSeriesPointer.SetHorizSize(Value:Integer);
  678. Begin
  679.   CheckPointerSize(Value);
  680.   SetIntegerProperty(FHorizSize,Value);
  681. end;
  682.  
  683. Procedure TSeriesPointer.SetInflateMargins(Value:Boolean);
  684. begin
  685.   SetBooleanProperty(FInflateMargins,Value);
  686. end;
  687.  
  688. Procedure TSeriesPointer.SetVertSize(Value:Integer);
  689. Begin
  690.   CheckPointerSize(Value);
  691.   SetIntegerProperty(FVertSize,Value);
  692. end;
  693.  
  694. Procedure TSeriesPointer.SetPen(Value:TChartPen);
  695. Begin
  696.   FPen.Assign(Value);
  697. end;
  698.  
  699. Procedure TSeriesPointer.SetBrush(Value:TChartBrush);
  700. Begin
  701.   FBrush.Assign(Value);
  702. end;
  703.  
  704. Procedure TSeriesPointer.SetDark3D(Value:Boolean);
  705. Begin
  706.   SetBooleanProperty(FDark3D,Value);
  707. end;
  708.  
  709. Procedure TSeriesPointer.SetDraw3D(Value:Boolean);
  710. Begin
  711.   SetBooleanProperty(FDraw3D,Value);
  712. end;
  713.  
  714. Procedure TSeriesPointer.Change3D(Value:Boolean);
  715. Begin
  716.   FDraw3D:=Value;
  717. end;
  718.  
  719. Procedure TSeriesPointer.CalcHorizMargins(Var LeftMargin,RightMargin:Integer);
  720. begin
  721.   if FVisible and FInflateMargins then
  722.   begin
  723.     LeftMargin :=MaxLong(LeftMargin, HorizSize+1);
  724.     RightMargin:=MaxLong(RightMargin,HorizSize+1);
  725.   end;
  726. end;
  727.  
  728. Procedure TSeriesPointer.CalcVerticalMargins(Var TopMargin,BottomMargin:Integer);
  729. begin
  730.   if FVisible and FInflateMargins then
  731.   begin
  732.     TopMargin   :=MaxLong(TopMargin,   VertSize+1);
  733.     BottomMargin:=MaxLong(BottomMargin,VertSize+1);
  734.   end;
  735. end;
  736.  
  737. Procedure TSeriesPointer.SetVisible(Value:Boolean);
  738. Begin
  739.   SetBooleanProperty(FVisible,Value);
  740. end;
  741.  
  742. Procedure TSeriesPointer.SetStyle(Value:TSeriesPointerStyle);
  743. Begin
  744.   if FStyle<>Value then
  745.   begin
  746.     FStyle:=Value;
  747.     FOwner.Repaint;
  748.   end;
  749. end;
  750.  
  751. Procedure TSeriesPointer.PrepareCanvas(ColorValue:TColor);
  752. Begin
  753.   With FOwner.ParentChart.Canvas do
  754.   Begin
  755.     AssignVisiblePen(FPen);
  756.     if (FPen.Visible) and (FPen.Color=clTeeColor) then Pen.Color:=ColorValue;
  757.     Brush.Assign(FBrush);
  758.     if Brush.Color=clTeeColor then Brush.Color:=ColorValue;
  759.   end;
  760. end;
  761.  
  762. Procedure TSeriesPointer.DrawPointer( Is3D:Boolean;
  763.                                       px,py,tmpHoriz,tmpVert:Integer;
  764.                                       ColorValue:TColor;
  765.                                       AStyle:TSeriesPointerStyle);
  766.  
  767. Var PXMinus : Integer;
  768.     PXPlus  : Integer;
  769.     PYMinus : Integer;
  770.     PYPlus  : Integer;
  771.  
  772.   Procedure DrawDiagonalCross;
  773.   Begin
  774.     With FOwner,ParentChart.Canvas do
  775.     Begin
  776.       Pen.Color:=ColorValue; { added in 1.03 }
  777.       if Is3D then
  778.       begin
  779.         LineWithZ(PXMinus, PYMinus, PXPlus+1,PYPlus+1,StartZ);
  780.         LineWithZ(PXPlus,  PYMinus, PXMinus-1,PYPlus+1,StartZ);
  781.       end
  782.       else
  783.       begin
  784.         Line(PXMinus, PYMinus, PXPlus+1,PYPlus+1);
  785.         Line(PXPlus , PYMinus, PXMinus-1,PYPlus+1);
  786.       end;
  787.     end;
  788.   end;
  789.  
  790.   Procedure DrawCross;
  791.   Begin
  792.     With FOwner,ParentChart.Canvas do
  793.     Begin
  794.       Pen.Color:=ColorValue;  { added in 1.03 }
  795.       if Is3D then
  796.       begin
  797.         VertLine3D(PX,PYMinus,PYPlus+1,StartZ);
  798.         HorizLine3D(PXMinus,PXPlus+1,PY,StartZ);
  799.       end
  800.       else
  801.       begin
  802.         DoVertLine(PX,PYMinus,PYPlus+1);
  803.         DoHorizLine(PXMinus,PXPlus+1,PY);
  804.       end;
  805.     end;
  806.   end;
  807.  
  808.   Procedure DoTriangle3D(DeltaY:Integer);
  809.   begin
  810.     With FOwner,ParentChart.Canvas do
  811.     if Self.FDraw3D then
  812.        Pyramid( True, PXMinus,PY-DeltaY,PXPlus,PY+DeltaY,StartZ,EndZ,FDark3D)
  813.     else
  814.        TriangleWithZ( Point(PXMinus,PY+DeltaY),
  815.                       Point(PXPlus,PY+DeltaY),
  816.                       Point(PX,PY-DeltaY),StartZ )
  817.   end;
  818.  
  819. Begin
  820.   PXMinus:=PX-tmpHoriz;
  821.   PXPlus :=PX+tmpHoriz;
  822.   PYMinus:=PY-tmpVert;
  823.   PYPlus :=PY+tmpVert;
  824.   With FOwner,ParentChart.Canvas do
  825.   Begin
  826.     if Is3D then
  827.     Case AStyle of
  828.     psRectangle: if Self.FDraw3D then
  829.                     Cube(PXMinus,PXPlus,PYMinus,PYPlus,StartZ,EndZ,FDark3D)
  830.                  else
  831.                     RectangleWithZ(Rect(PXMinus,PYMinus,PXPlus+1,PYPlus+1),StartZ);
  832.        psCircle: EllipseWithZ(PXMinus,PYMinus,PXPlus,PYPlus,StartZ);
  833.      psTriangle: DoTriangle3D( tmpVert);
  834.  psDownTriangle: DoTriangle3D(-tmpVert);
  835.         psCross: DrawCross;
  836.     psDiagCross: DrawDiagonalCross;
  837.          psStar: Begin DrawCross; DrawDiagonalCross; end;
  838.       psDiamond: PlaneWithZ( Point(PXMinus,PY),
  839.                              Point(PX,PYMinus),
  840.                              Point(PXPlus,PY),
  841.                              Point(PX,PYPlus),StartZ);
  842.      psSmallDot: Pixels3D[PX,PY,StartZ]:=ColorValue
  843.     end
  844.     else
  845.     Case AStyle of
  846.     psRectangle: Rectangle(PXMinus,PYMinus,PXPlus+1,PYPlus+1);
  847.        psCircle: Ellipse(PXMinus,PYMinus,PXPlus,PYPlus);
  848.      psTriangle: Polygon([ Point(PXMinus,PYPlus),
  849.                            Point(PXPlus,PYPlus),
  850.                            Point(PX,PYMinus)]);
  851.  psDownTriangle: Polygon([ Point(PXMinus,PYMinus),
  852.                            Point(PXPlus,PYMinus),
  853.                            Point(PX,PYPlus)]);
  854.         psCross: DrawCross;
  855.     psDiagCross: DrawDiagonalCross;
  856.          psStar: Begin DrawCross; DrawDiagonalCross; end;
  857.       psDiamond: Polygon([Point(PXMinus,PY),
  858.                           Point(PX,PYMinus),
  859.                           Point(PXPlus,PY),
  860.                           Point(PX,PYPlus)] );
  861.      psSmallDot: Pixels[PX,PY]:=ColorValue;
  862.     end;
  863.   end;
  864. end;
  865.  
  866. Procedure TSeriesPointer.Draw(px,py:Integer; ColorValue:TColor; AStyle:TSeriesPointerStyle);
  867. Begin
  868.   DrawPointer(FOwner.ParentChart.View3D,px,py,FHorizSize,FVertSize,ColorValue,AStyle);
  869. end;
  870.  
  871. Procedure TSeriesPointer.Assign(Source:TPersistent);
  872. begin
  873.   if Source is TSeriesPointer then
  874.   With TSeriesPointer(Source) do
  875.   begin
  876.     Self.FBrush.Assign(FBrush);
  877.     Self.FDark3D     :=FDark3D;
  878.     Self.FDraw3D     :=FDraw3D;
  879.     Self.FHorizSize  :=FHorizSize;
  880.     Self.FInflateMargins:=FInflateMargins;
  881.     Self.FPen.Assign(FPen);
  882.     Self.FStyle      :=FStyle;
  883.     Self.FVertSize   :=FVertSize;
  884.     Self.FVisible    :=FVisible;
  885.   end
  886.   else inherited Assign(Source);
  887. end;
  888.  
  889. Procedure TSeriesPointer.DrawLegendShape(AColor:TColor; Const Rect:TRect; DrawPen:Boolean);
  890. var tmpHoriz : Integer;
  891.     tmpVert  : Integer;
  892. begin
  893.   PrepareCanvas(AColor);
  894.   With Rect do
  895.   begin
  896.     if DrawPen then
  897.     begin
  898.       tmpHoriz:=(Right-Left) div 3;
  899.       tmpVert :=(Bottom-Top) div 3;
  900.     end
  901.     else
  902.     begin
  903.       tmpHoriz:=1+((Right-Left) div 2);
  904.       tmpVert :=1+((Bottom-Top) div 2);
  905.     end;
  906.     DrawPointer(False, (Left+Right) div 2,(Top+Bottom) div 2,
  907.                        MinLong(HorizSize,tmpHoriz),
  908.                        MinLong(VertSize,tmpVert),AColor,FStyle);
  909.   end;
  910. end;
  911.  
  912. { TCustomSeries }
  913. Constructor TCustomSeries.Create(AOwner: TComponent);
  914. Begin
  915.   inherited Create(AOwner);
  916.   ClickableLine:=True;
  917.   DrawBetweenPoints:=True;
  918.   FPointer:=TSeriesPointer.Create(Self);
  919.   FAreaLinesPen:=CreateChartPen;
  920.   FLinePen:=CreateChartPen;
  921.   FLineHeight:=0;
  922.   FAreaColor:=clTeeColor;
  923.   FDark3D:=True;
  924. end;
  925.  
  926. Destructor TCustomSeries.Destroy;
  927. Begin
  928.   FLinePen.Free;
  929.   FAreaLinesPen.Free;
  930.   FPointer.Free;
  931.   inherited Destroy;
  932. end;
  933.  
  934. Procedure TCustomSeries.DrawMark( ValueIndex:Longint; Const St:String;
  935.                                   APosition:TSeriesMarkPosition);
  936. var tmp : Integer;
  937. begin
  938.   Marks.ZPosition:=StartZ;
  939.   tmp:=Marks.ArrowLength;
  940.   With APosition do
  941.   begin
  942.     Dec(LeftTop.Y,tmp);
  943.     Dec(ArrowTo.Y,tmp);
  944.   end;
  945.   inherited DrawMark(ValueIndex,St,APosition);
  946. end;
  947.  
  948. Function TCustomSeries.ClickedPointer( ValueIndex,tmpX,tmpY:Longint;
  949.                                        x,y:Longint):Boolean;
  950. begin
  951.   result:=(Abs(tmpX-X)<FPointer.FHorizSize) and
  952.           (Abs(tmpY-Y)<FPointer.FVertSize);
  953. end;
  954.  
  955. Procedure TCustomSeries.Assign(Source:TPersistent);
  956. begin
  957.   if Source is TCustomSeries then
  958.   With TCustomSeries(Source) do
  959.   begin
  960.     Self.ClickableLine   :=ClickableLine;
  961.     Self.FAreaBrush      :=FAreaBrush;
  962.     Self.FAreaColor      :=FAreaColor;
  963.     Self.FAreaLinesPen.Assign(FAreaLinesPen);
  964.     Self.FDark3D         :=FDark3D;
  965.     Self.FDrawArea       :=FDrawArea;
  966.     Self.FDrawLine       :=FDrawLine;
  967.     Self.FInvertedStairs :=FInvertedStairs;
  968.     Self.FLinePen.Assign(FLinePen);
  969.     Self.FLineBrush      :=FLineBrush;
  970.     Self.FLineHeight     :=FLineHeight;
  971.     Self.FPointer.Assign(FPointer);
  972.     Self.FStairs         :=FStairs;
  973.   end;
  974.   inherited Assign(Source);
  975. end;
  976.  
  977. Function TCustomSeries.Clicked(x,y:Integer):Longint;
  978. var t        : Integer;
  979.     OldXPos  : Integer;
  980.     OldYPos  : Integer;
  981.     tmpX     : Integer;
  982.     tmpY     : Integer;
  983.     P        : TPoint;
  984.  
  985.     Function CheckPointInLine:Boolean;
  986.  
  987.       Function PointInVertLine(x0,y0,y1:Integer):Boolean;
  988.       begin
  989.         result:=PointInLine(P,x0,y0,x0,y1);
  990.       end;
  991.  
  992.       Function PointInHorizLine(x0,y0,x1:Integer):Boolean;
  993.       begin
  994.         result:=PointInLine(P,x0,y0,x1,y0);
  995.       end;
  996.  
  997.     begin
  998.       With ParentChart do
  999.       if View3D then
  1000.  
  1001.          result:=PointInPolygon( P,[ Point(tmpX,tmpY),
  1002.                                      Point(tmpX+SeriesWidth3D,tmpY-SeriesHeight3D),
  1003.                                      Point(OldXPos+SeriesWidth3D,OldYPos-SeriesHeight3D),
  1004.                                      Point(OldXPos,OldYPos) ])
  1005.       else
  1006.          if FStairs then
  1007.          begin
  1008.             if FInvertedStairs then result:= PointInVertLine(OldXPos,OldYPos,tmpY) or
  1009.                                              PointInHorizLine(OldXPos,tmpY,tmpX)
  1010.                                else result:= PointInHorizLine(OldXPos,OldYPos,tmpX) or
  1011.                                              PointInVertLine(tmpX,OldYPos,tmpY);
  1012.          end
  1013.          else
  1014.             result:=PointInLine(P,tmpX,tmpY,OldXPos,OldYPos)
  1015.     end;
  1016.  
  1017. begin
  1018.   if (ParentChart<>nil) then ParentChart.Canvas.Calculate2DPosition(X,Y,StartZ);
  1019.   result:=inherited Clicked(x,y);
  1020.   if (result=TeeNoPointClicked) and
  1021.      (FirstValueIndex>-1) and (LastValueIndex>-1) then
  1022.   begin
  1023.     OldXPos:=0;
  1024.     OldYPos:=0;
  1025.     OldBottomPos:=0;
  1026.     P.X:=X;
  1027.     P.Y:=Y;
  1028.     for t:=FirstValueIndex to LastValueIndex do
  1029.     begin
  1030.       tmpX:=CalcXPos(t);
  1031.       tmpY:=CalcYPos(t);
  1032.       if FPointer.FVisible then
  1033.       begin
  1034.         if ClickedPointer(t,tmpX,tmpY,x,y) then
  1035.         begin
  1036.           if Assigned(FOnClickPointer) then FOnClickPointer(Self,t,x,y);
  1037.           result:=t;
  1038.           break;
  1039.         end;
  1040.       end;
  1041.       if (tmpX=X) and (tmpY=Y) then
  1042.       begin
  1043.         result:=t;
  1044.         break;
  1045.       end;
  1046.       if (t>FirstValueIndex) and ClickableLine then
  1047.          if CheckPointInLine or
  1048.             ( FDrawArea and
  1049.                PointInPolygon( P,[ Point(OldXPos,OldYPos), Point(tmpX,tmpY),
  1050.                                    Point(tmpX,GetOriginPos(t)),
  1051.                                    Point(OldXPos,GetOriginPos(t-1)) ] )
  1052.             ) then
  1053.          begin
  1054.            result:=t-1;
  1055.            break;
  1056.          end;
  1057.       OldXPos:=tmpX;
  1058.       OldYPos:=tmpY;
  1059.       OldBottomPos:=BottomPos;
  1060.     end;
  1061.   end;
  1062. end;
  1063.  
  1064. Procedure TCustomSeries.SetDrawArea(Value:Boolean);
  1065. Begin
  1066.   SetBooleanProperty(FDrawArea,Value);
  1067. end;
  1068.  
  1069. Procedure TCustomSeries.SetPointer(Value:TSeriesPointer);
  1070. Begin
  1071.   FPointer.Assign(Value);
  1072. end;
  1073.  
  1074. Procedure TCustomSeries.SetAreaLinesPen(Value:TChartPen);
  1075. Begin
  1076.   FAreaLinesPen.Assign(Value);
  1077. end;
  1078.  
  1079. Procedure TCustomSeries.SetLinePen(Value:TChartPen);
  1080. Begin
  1081.   FLinePen.Assign(Value);
  1082. end;
  1083.  
  1084. Procedure TCustomSeries.SetLineHeight(Value:Integer);
  1085. Begin
  1086.   SetIntegerProperty(FLineHeight,Value);
  1087. end;
  1088.  
  1089. Procedure TCustomSeries.SetStairs(Value:Boolean);
  1090. Begin
  1091.   SetBooleanProperty(FStairs,Value);
  1092. end;
  1093.  
  1094. Procedure TCustomSeries.SetInvertedStairs(Value:Boolean);
  1095. Begin
  1096.   SetBooleanProperty(FInvertedStairs,Value);
  1097. end;
  1098.  
  1099. Procedure TCustomSeries.SetAreaColor(Value:TColor);
  1100. Begin
  1101.   SetColorProperty(FAreaColor,Value);
  1102. end;
  1103.  
  1104. Procedure TCustomSeries.SetBrushProperty(Var ABrush:TBrushStyle; Value:TBrushStyle);
  1105. Begin
  1106.   if ABrush<>Value then
  1107.   begin
  1108.     ABrush:=Value;
  1109.     Repaint;
  1110.   end;
  1111. end;
  1112.  
  1113. Procedure TCustomSeries.SetAreaBrush(Value:TBrushStyle);
  1114. Begin
  1115.   SetBrushProperty(FAreaBrush,Value);
  1116. end;
  1117.  
  1118. Procedure TCustomSeries.SetLineBrush(Value:TBrushStyle);
  1119. Begin
  1120.   SetBrushProperty(FLineBrush,Value);
  1121. end;
  1122.  
  1123. Procedure TCustomSeries.DrawLegendShape(ValueIndex:Longint; Const Rect:TRect);
  1124. Var tmpColor : TColor;
  1125.  
  1126.     Procedure DrawLine(DrawRectangle:Boolean);
  1127.     begin
  1128.       LinePrepareCanvas(ParentChart.Canvas,tmpColor);
  1129.       With ParentChart.Canvas do
  1130.       if DrawRectangle then DoRectangle(Rect)
  1131.       else
  1132.       With Rect do DoHorizLine(Left,Right,(Top+Bottom) div 2);
  1133.     end;
  1134.  
  1135. begin
  1136.   if ValueIndex=TeeAllValues then tmpColor:=SeriesColor
  1137.                              else tmpColor:=ValueColor[ValueIndex];
  1138.   if FPointer.Visible then
  1139.   begin
  1140.     if FDrawLine then DrawLine(False);
  1141.     FPointer.DrawLegendShape(tmpColor,Rect,FLinePen.Visible);
  1142.   end
  1143.   else
  1144.   if FDrawLine and (not FDrawArea) then
  1145.      DrawLine(ParentChart.View3D)
  1146.   else
  1147.      inherited DrawLegendShape(ValueIndex,Rect)
  1148. end;
  1149.  
  1150. procedure TCustomSeries.LinePrepareCanvas(tmpCanvas:TCanvas3D; tmpColor:TColor);
  1151. begin
  1152.   with tmpCanvas do
  1153.   begin
  1154.     AssignVisiblePen(FLinePen);
  1155.     ParentChart.CheckPenWidth(Pen);
  1156.     if ParentChart.View3D then
  1157.     begin
  1158.       Brush.Style:=FLineBrush;
  1159.       Brush.Color:=tmpColor;
  1160.     end
  1161.     else
  1162.     begin
  1163.       Brush.Style:=bsClear;
  1164.       Pen.Color:=tmpColor;
  1165.     end;
  1166.   end;
  1167. end;
  1168.  
  1169. Function TCustomSeries.GetAreaBrushColor(AColor:TColor):TColor;
  1170. begin
  1171.   if ColorEachPoint or (FAreaColor=clTeeColor) then
  1172.      result:=AColor
  1173.   else
  1174.      result:=FAreaColor;
  1175. end;
  1176.  
  1177. procedure TCustomSeries.DrawValue(ValueIndex:Longint);
  1178. Var x : Longint;
  1179.     y : Longint;
  1180.  
  1181.   Function CalcYPosLeftRight(Const YLimit:Double; AnotherIndex:Longint):Longint;
  1182.   var tmpPredValueX : Double;
  1183.       tmpPredValueY : Double;
  1184.       tmpDif        : Double;
  1185.   begin
  1186.     tmpPredValueX:=XValue[AnotherIndex];
  1187.     tmpDif:=XValue[ValueIndex]-tmpPredValueX;
  1188.     With ParentChart do
  1189.     if tmpDif=0 then result:=CalcYPos(AnotherIndex)
  1190.     else
  1191.     begin
  1192.       tmpPredValueY:=YValue[AnotherIndex];
  1193.       result:=CalcYPosValue( 1.0*tmpPredValueY+(YLimit-tmpPredValueX)*
  1194.                              (YValue[ValueIndex]-tmpPredValueY)/tmpDif );
  1195.     end;
  1196.   end;
  1197.  
  1198. var tmpColor    : TColor;
  1199.     IsLastValue : Boolean;
  1200.  
  1201.    Procedure InternalDrawArea(BrushStyle:TBrushStyle; BrushColor:TColor);
  1202.    var tmpY:Longint;
  1203.    Begin
  1204.      With ParentChart do
  1205.      Begin
  1206.        SetBrushCanvas(BrushColor,BrushStyle,SeriesColor);
  1207.        if View3D and IsLastValue then
  1208.           Canvas.RectangleZ(X,Y,BottomPos,StartZ,EndZ);
  1209.        if FStairs then
  1210.        begin
  1211.          if FInvertedStairs then tmpY:=Y
  1212.                             else tmpY:=OldY;
  1213.          Canvas.RectangleWithZ(Rect(OldX,BottomPos,X+1,tmpY),StartZ);
  1214.        end
  1215.        else
  1216.          Canvas.PlaneWithZ( Point(OldX,OldBottomPos),Point(OldX,OldY),
  1217.                             Point(X,Y),Point(X,BottomPos),StartZ);
  1218.      end;
  1219.    end;
  1220.  
  1221.    Procedure DrawPoint(DrawOldPointer:Boolean);
  1222.    var tmpPoint     : TPoint;
  1223.        tmpOldP      : TPoint;
  1224.        tmpDifX      : Integer;
  1225.        P4           : TFourPoints;
  1226.        OldDarkColor : TColor;
  1227.    Begin
  1228.      if ((x<>OldX) or (y<>OldY)) and (tmpColor<>clNone) then { <-- if not null }
  1229.      With ParentChart,Canvas do
  1230.      Begin
  1231.        if View3D then
  1232.        Begin
  1233.          if FDrawArea or (FDrawLine and (FLineBrush<>bsClear)) then
  1234.          Begin
  1235.            Brush.Color:=GetAreaBrushColor(tmpColor);
  1236.            OldDarkColor:=Brush.Color;
  1237.            AssignVisiblePen(FLinePen);
  1238.            if FLinePen.Visible then CheckPenWidth(Pen);
  1239.            Brush.Style:=FLineBrush;
  1240.            tmpPoint.X  :=X;
  1241.            tmpPoint.Y  :=Y;
  1242.            tmpOldP.X   :=OldX;
  1243.            tmpOldP.Y   :=OldY;
  1244.            if FStairs then
  1245.            Begin
  1246.              if FInvertedStairs then
  1247.              begin
  1248.                if FDark3D then Brush.Color:=ApplyDark(Brush.Color,DarkColorQuantity);
  1249.                RectangleZ( tmpOldP.X,tmpOldP.Y, Y,StartZ,EndZ);
  1250.                if FDark3D then Brush.Color:=OldDarkColor;
  1251.                RectangleY( tmpPoint.X, tmpPoint.Y,OldX,StartZ,EndZ);
  1252.              end
  1253.              else
  1254.              begin
  1255.                RectangleY( tmpOldP.X, tmpOldP.Y, X, StartZ, EndZ);
  1256.                if FDark3D then Brush.Color:=ApplyDark(Brush.Color,DarkColorQuantity);
  1257.                RectangleZ( tmpPoint.X,tmpPoint.Y, OldY,StartZ,EndZ);
  1258.                if FDark3D then Brush.Color:=OldDarkColor;
  1259.              end;
  1260.            end
  1261.            else
  1262.            begin
  1263.              if (FLineHeight>0) and (not FDrawArea) then
  1264.              begin
  1265.                P4[0]:=tmpPoint;
  1266.                P4[1]:=tmpOldP;
  1267.                P4[2].X:=tmpOldP.X;
  1268.                P4[2].Y:=tmpOldP.Y+FLineHeight;
  1269.                P4[3].X:=tmpPoint.X;
  1270.                P4[3].Y:=tmpPoint.Y+FLineHeight;
  1271.                PlaneFour3D(P4,StartZ,StartZ);
  1272.                if IsLastValue then
  1273.                   RectangleZ(tmpPoint.X,tmpPoint.Y,tmpPoint.Y+FLineHeight,StartZ,EndZ);
  1274.              end;
  1275.              if FDark3D then
  1276.              begin
  1277.                tmpDifX:=tmpPoint.X-tmpOldP.X;
  1278.                if (tmpDifX<>0) and
  1279.                   (tmpDark3DRatio<>0) and
  1280.                   ((tmpOldP.Y-tmpPoint.Y)/tmpDifX > tmpDark3DRatio) then
  1281.                begin
  1282.                  Brush.Color:=ApplyDark(Brush.Color,DarkColorQuantity);
  1283.                  if (FLineHeight>0) and (not FDrawArea) then {special case}
  1284.                  begin
  1285.                    Inc(tmpPoint.Y,FLineHeight);
  1286.                    Inc(tmpOldP.Y,FLineHeight);
  1287.                  end;
  1288.                end;
  1289.              end;
  1290.              Plane3D(tmpPoint,tmpOldP,StartZ,EndZ);
  1291.              if FDark3D then Brush.Color:=OldDarkColor;
  1292.            end;
  1293.          end;
  1294.        end;
  1295.        if FDrawArea then
  1296.        Begin
  1297.          Brush.Color:=GetAreaBrushColor(tmpColor);
  1298.          Pen.Assign(FAreaLinesPen);
  1299.          if (Pen.Color=clTeeColor) or (not FAreaLinesPen.Visible) then
  1300.             Pen.Color:=tmpColor;
  1301.          InternalDrawArea(FAreaBrush,Brush.Color);
  1302.        end
  1303.        else
  1304.        if (not View3D) and FDrawLine then
  1305.        Begin
  1306.          LinePrepareCanvas(Canvas,tmpColor);
  1307.          if FStairs then
  1308.          begin
  1309.            if FInvertedStairs then DoVertLine(OldX,OldY,Y)
  1310.                               else DoHorizLine(OldX,X,OldY);
  1311.            LineTo(X,Y);
  1312.          end
  1313.          else Line(OldX,OldY,X,Y);
  1314.        end;
  1315.      end;
  1316.  
  1317.      { pointers }
  1318.      if FPointer.FVisible and DrawOldPointer then
  1319.      Begin
  1320.        if OldColor<>clNone then { <-- if not null }
  1321.           DrawPointer(OldX,OldY,OldColor,Pred(ValueIndex));
  1322.        if IsLastValue and (tmpColor<>clNone) then {<-- if not null }
  1323.           DrawPointer(X,Y,tmpColor,ValueIndex);
  1324.      end;
  1325.    end;
  1326.  
  1327. Const MaxShortInt=32767;
  1328. Begin
  1329.   With ParentChart.Canvas do
  1330.   Begin
  1331.     X:=CalcXPos(ValueIndex);
  1332.     Y:=CalcYPos(ValueIndex);
  1333.     { Win95 limitation. only 16bit coordinates }
  1334.     if (X>-MaxShortInt) and (X<MaxShortInt) and
  1335.        (Y>-MaxShortInt) and (Y<MaxShortInt) then
  1336.     Begin
  1337.       tmpColor:=ValueColor[ValueIndex];
  1338.       Pen.Color:=clBlack;
  1339.       Brush.Color:=tmpColor;
  1340.       if OldColor=clNone then { if null }
  1341.       begin
  1342.         OldX:=X;
  1343.         OldY:=Y;
  1344.       end;
  1345.       IsLastValue:=ValueIndex=LastValueIndex;
  1346.       BottomPos:=GetOriginPos(ValueIndex);
  1347.       if ValueIndex=FirstValueIndex then { first point }
  1348.       Begin
  1349.         if FDark3D then
  1350.         With ParentChart do
  1351.            if SeriesWidth3D<>0 then
  1352.               tmpDark3DRatio:=SeriesHeight3D/SeriesWidth3D
  1353.            else
  1354.               tmpDark3DRatio:=1;
  1355.         if ValueIndex>0 then { previous point outside left }
  1356.         Begin
  1357.           if FDrawArea then
  1358.           begin
  1359.             OldX:=CalcXPos(Pred(ValueIndex));
  1360.             OldY:=CalcYPos(Pred(ValueIndex));
  1361.             OldBottomPos:=GetOriginPos(Pred(ValueIndex));
  1362.           end
  1363.           else
  1364.           begin
  1365.             if GetHorizAxis.Inverted then OldX:=ParentChart.ChartRect.Right
  1366.                                      else OldX:=ParentChart.ChartRect.Left;
  1367.             if FStairs Then
  1368.                OldY:=CalcYPos(Pred(ValueIndex))
  1369.             else
  1370.                OldY:=CalcYPosLeftRight(XScreenToValue(OldX),Pred(ValueIndex));
  1371.           end;
  1372.           if ValueColor[Pred(ValueIndex)]<>clNone then DrawPoint(False); { if not null }
  1373.         end;
  1374.         if IsLastValue and FPointer.FVisible then
  1375.            DrawPointer(X,Y,tmpColor,ValueIndex);
  1376.       end
  1377.       else DrawPoint(True);
  1378.       OldX:=X;
  1379.       OldY:=Y;
  1380.       OldBottomPos:=BottomPos;
  1381.       OldColor:=tmpColor;
  1382.     end;
  1383.   end;
  1384. end;
  1385.  
  1386. Procedure TCustomSeries.DrawPointer(AX,AY:Longint; AColor:TColor; ValueIndex:Longint);
  1387. var tmpStyle : TSeriesPointerStyle;
  1388. begin
  1389.   FPointer.PrepareCanvas(AColor);
  1390.   if Assigned(FOnGetPointerStyle) then
  1391.      tmpStyle:=FOnGetPointerStyle(Self,ValueIndex)
  1392.   else
  1393.      tmpStyle:=FPointer.FStyle;
  1394.   FPointer.Draw(AX,AY,AColor,tmpStyle);
  1395. end;
  1396.  
  1397. Function TCustomSeries.GetEditorClass:String;
  1398. Begin
  1399.   result:='TCustomSeriesEditor'; { <-- dont translate ! }
  1400. end;
  1401.  
  1402. Procedure TCustomSeries.CalcHorizMargins(Var LeftMargin,RightMargin:Integer);
  1403. begin
  1404.   inherited CalcHorizMargins(LeftMargin,RightMargin);
  1405.   FPointer.CalcHorizMargins(LeftMargin,RightMargin);
  1406.   if FStairs and FDrawLine then
  1407.   begin
  1408.     LeftMargin :=MaxLong(LeftMargin,LinePen.Width);
  1409.     RightMargin:=MaxLong(RightMargin,LinePen.Width);
  1410.   end;
  1411. end;
  1412.  
  1413. Procedure TCustomSeries.CalcVerticalMargins(Var TopMargin,BottomMargin:Integer);
  1414. begin
  1415.   inherited CalcVerticalMargins(TopMargin,BottomMargin);
  1416.   FPointer.CalcVerticalMargins(TopMargin,BottomMargin);
  1417.   if FStairs and FDrawLine then
  1418.   begin
  1419.     TopMargin   :=MaxLong(TopMargin,LinePen.Width);
  1420.     BottomMargin:=MaxLong(BottomMargin,LinePen.Width+1);
  1421.   end;
  1422.   if (FLineHeight>0) and (not FDrawArea) then
  1423.      if FLineHeight>BottomMargin then BottomMargin:=FLineHeight;
  1424. end;
  1425.  
  1426. Function TCustomSeries.GetOriginPos(ValueIndex:Longint):Longint;
  1427. Begin
  1428.   result:=GetVertAxis.IEndPos;
  1429. end;
  1430.  
  1431. Procedure TCustomSeries.SetDark3D(Value:Boolean);
  1432. begin
  1433.   SetBooleanProperty(FDark3D,Value);
  1434. end;
  1435.  
  1436. { TLineSeries }
  1437. Constructor TLineSeries.Create(AOwner: TComponent);
  1438. Begin
  1439.   inherited Create(AOwner);
  1440.   FDrawLine:=True;
  1441.   AllowSinglePoint:=False;
  1442.   FPointer.Visible:=False; { inherited }
  1443. end;
  1444.  
  1445. Procedure TLineSeries.PrepareLegendCanvas( ValueIndex:Longint; Var BackColor:TColor;
  1446.                                            Var BrushStyle:TBrushStyle);
  1447. Begin
  1448.   ParentChart.Canvas.AssignVisiblePen(FLinePen);
  1449.   BrushStyle:=FLineBrush;
  1450. end;
  1451.  
  1452. Procedure TLineSeries.Assign(Source:TPersistent);
  1453. begin
  1454.   inherited Assign(Source);
  1455.   FPointer.Visible := False;
  1456.   FDrawArea        := False;
  1457.   FDrawLine        := True;
  1458. end;
  1459.  
  1460. { TPointSeries }
  1461. Constructor TPointSeries.Create(AOwner: TComponent);
  1462. Begin
  1463.   inherited Create(AOwner);
  1464.   FDrawLine:=False;
  1465.   Marks.ArrowLength:=0;
  1466.   ClickableLine:=False;
  1467.   FPointer.Visible:=True;
  1468. end;
  1469.  
  1470. Procedure TPointSeries.Assign(Source:TPersistent);
  1471. begin
  1472.   inherited Assign(Source);
  1473.   FPointer.Visible :=True;
  1474.   FDrawArea        :=False;
  1475.   FDrawLine        :=False;
  1476.   ClickableLine    :=False;
  1477. end;
  1478.  
  1479. Function TPointSeries.GetEditorClass:String;
  1480. begin
  1481.   result:='TSeriesPointerEditor'; { <-- do not translate }
  1482. end;
  1483.  
  1484. Procedure TPointSeries.PrepareForGallery(IsEnabled:Boolean);
  1485. begin
  1486.   inherited PrepareForGallery(IsEnabled);
  1487.   Pointer.HorizSize:=6;
  1488.   Pointer.VertSize:=6;
  1489.   With ParentChart do
  1490.   if (SeriesCount>1) and (Self=Series[1]) then Pointer.Style:=psTriangle;
  1491. end;
  1492.  
  1493. Procedure TPointSeries.SetColorEachPoint(Value:Boolean);
  1494. begin
  1495.   inherited SetColorEachPoint(Value);
  1496.   if Value then Pointer.Brush.Color:=clTeeColor;
  1497. end;
  1498.  
  1499. { TAreaSeries }
  1500. Constructor TAreaSeries.Create(AOwner: TComponent);
  1501. Begin
  1502.   inherited Create(AOwner);
  1503.   FDrawArea:=True;
  1504.   AllowSinglePoint:=False;
  1505.   FPointer.Visible:=False;
  1506.   FMultiArea:=maNone;
  1507. end;
  1508.  
  1509. Procedure TAreaSeries.PrepareLegendCanvas( ValueIndex:Longint; Var BackColor:TColor;
  1510.                                            Var BrushStyle:TBrushStyle);
  1511. Begin
  1512.   BackColor:=GetAreaBrushColor(ParentChart.Canvas.Brush.Color);
  1513.   ParentChart.Canvas.AssignVisiblePen(FAreaLinesPen);
  1514.   BrushStyle:=FAreaBrush;
  1515. end;
  1516.  
  1517. Procedure TAreaSeries.Assign(Source:TPersistent);
  1518. begin
  1519.   if Source is TAreaSeries then
  1520.   With TAreaSeries(Source) do Self.FMultiArea:=MultiArea;
  1521.   inherited Assign(Source);
  1522.   FDrawArea:=True;
  1523.   FDrawLine:=True;
  1524.   FPointer.Visible:=False;
  1525. end;
  1526.  
  1527. Procedure TAreaSeries.CalcZOrder;
  1528. Begin
  1529.   if FMultiArea=maNone then inherited CalcZOrder
  1530.                        else IZOrder:=ParentChart.MaxZOrder;
  1531. End;
  1532.  
  1533. Function TAreaSeries.GetEditorClass:String;
  1534. Begin
  1535.   result:='TAreaSeriesEditor'; { <-- dont translate ! }
  1536. end;
  1537.  
  1538. Procedure TAreaSeries.SetOtherMultiArea;
  1539. var t : Longint;
  1540. Begin
  1541.   if ParentChart<>nil then
  1542.   with ParentChart do
  1543.   for t:=0 to SeriesCount-1 do
  1544.     if Self is Series[t].ClassType then
  1545.        TAreaSeries(Series[t]).FMultiArea:=FMultiArea;
  1546. end;
  1547.  
  1548. Procedure TAreaSeries.SetMultiArea(Value:TMultiArea);
  1549. Begin
  1550.   if Value<>FMultiArea then
  1551.   Begin
  1552.     FMultiArea:=Value;
  1553.     SetOtherMultiArea;
  1554.     Repaint;
  1555.   end;
  1556. End;
  1557.  
  1558. Function TAreaSeries.InternalCalcStackedYPos(ValueIndex:Integer; Value:Double):Integer;
  1559. var tmp : Double;
  1560. begin
  1561.   Value:=Value+PointOrigin(ValueIndex,False);
  1562.   if FMultiArea=maStacked then result:=MinLong(GetVertAxis.IEndPos,CalcYPosValue(Value))
  1563.   else
  1564.   begin
  1565.     tmp:=PointOrigin(ValueIndex,True);
  1566.     if tmp<>0 then result:=CalcYPosValue(Value*100.0/tmp)
  1567.               else result:=0;
  1568.   end;
  1569. end;
  1570.  
  1571. Function TAreaSeries.GetOriginPos(ValueIndex:Longint):Longint;
  1572. Begin
  1573.   if FMultiArea=maNone then result:=inherited GetOriginPos(ValueIndex)
  1574.                        else result:=InternalCalcStackedYPos(ValueIndex,0);
  1575. end;
  1576.  
  1577. Function TAreaSeries.MaxYValue:Double;
  1578. var t : Longint;
  1579. Begin
  1580.   if FMultiArea=maStacked100 then result:=100
  1581.   else
  1582.   begin
  1583.     result:=inherited MaxYValue;
  1584.     if FMultiArea=maStacked then
  1585.     for t:=0 to Count-1 do
  1586.         result:=MaxDouble(result,PointOrigin(t,False)+YValue[t]);
  1587.   end;
  1588. end;
  1589.  
  1590. Function TAreaSeries.MinYValue:Double;
  1591. Begin
  1592.   if FMultiArea=maStacked100 then result:=0
  1593.                              else result:=inherited MinYValue;
  1594. end;
  1595.  
  1596. Function TAreaSeries.CalcYPos(ValueIndex:Longint):Integer;
  1597. Begin
  1598.   if FMultiArea=maNone then
  1599.      result:=inherited CalcYPos(ValueIndex)
  1600.   else
  1601.      result:=InternalCalcStackedYPos(ValueIndex,YValue[ValueIndex]);
  1602. End;
  1603.  
  1604. { TCustomBarSeries }
  1605. Constructor TCustomBarSeries.Create(AOwner:TComponent);
  1606. Begin
  1607.   inherited Create(AOwner);
  1608.   FBarPen:=CreateChartPen;
  1609.   FBarBrush:=TChartBrush.Create(CanvasChanged);
  1610.   FBarWidthPercent:=70; { % }
  1611.   FBarStyle:=bsRectangle;
  1612.   FUseOrigin:=True;
  1613.   FMultiBar:=mbSide;
  1614.   FAutoBarSize:=False;
  1615.   FAutoMarkPosition:=True;
  1616.   Marks.Visible:=True;
  1617.   Marks.ArrowLength:=20;
  1618.   FDark3D:=True;
  1619.   FSideMargins:=True;
  1620.   With MandatoryValueList do
  1621.   begin
  1622.     Name:=TeeMsg_ValuesBar;
  1623.     Order:=loNone;
  1624.   end;
  1625. end;
  1626.  
  1627. Destructor TCustomBarSeries.Destroy;
  1628. begin
  1629.   FBarPen.Free;
  1630.   FBarBrush.Bitmap.Free;
  1631.   FBarBrush.Free;
  1632.   inherited Destroy;
  1633. end;
  1634.  
  1635. Procedure TCustomBarSeries.CalcZOrder;
  1636. Var t         : Longint;
  1637.     tmpZOrder : Integer;
  1638. Begin
  1639.   if FMultiBar=mbNone then inherited CalcZOrder
  1640.   else
  1641.   Begin
  1642.     tmpZOrder:=-1;
  1643.     for t:=0 to ParentChart.SeriesCount-1 do
  1644.     if ParentChart[t].Active then
  1645.     begin
  1646.       if ParentChart[t]=Self then break
  1647.       else
  1648.       if SameClass(ParentChart[t]) then
  1649.       Begin
  1650.         tmpZOrder:=ParentChart[t].ZOrder;
  1651.         break;
  1652.       end;
  1653.     end;
  1654.     if tmpZOrder=-1 then inherited CalcZOrder
  1655.                     else IZOrder:=tmpZOrder;
  1656.   end;
  1657. End;
  1658.  
  1659. Function TCustomBarSeries.NumSampleValues:Longint;
  1660. Begin
  1661.   result:=6; { default number of BarSeries random sample values }
  1662. End;
  1663.  
  1664. Procedure TCustomBarSeries.SetBarWidthPercent(Value:Integer);
  1665. Begin
  1666.   if (Value<1) or (Value>100) then
  1667.      Raise BarException.Create(TeeMsg_BarWidthPercent)
  1668.   else
  1669.      SetIntegerProperty(FBarWidthPercent,Value);
  1670. end;
  1671.  
  1672. Procedure TCustomBarSeries.SetOffsetPercent(Value:Integer);
  1673. Begin
  1674.   if (Value<-100) or (Value>100) then
  1675.      Raise BarException.Create(TeeMsg_BarOffsetPercent)
  1676.   else
  1677.      SetIntegerProperty(FOffsetPercent,Value);
  1678. End;
  1679.  
  1680. Procedure TCustomBarSeries.SetCustomBarSize(Value:Integer);
  1681. Begin
  1682.   SetIntegerProperty(FCustomBarSize,Value);
  1683. end;
  1684.  
  1685. Procedure TCustomBarSeries.SetBarStyle(Value:TBarStyle);
  1686. Begin
  1687.   if FBarStyle<>Value then
  1688.   begin
  1689.     FBarStyle:=Value;
  1690.     Repaint;
  1691.   end;
  1692. end;
  1693.  
  1694. { If more than one bar series exists in chart,
  1695.   which position are we? the first, the second, the third? }
  1696. Function TCustomBarSeries.BarOrderPos:Longint;
  1697. var t : Integer;
  1698. Begin
  1699.   result:=1;
  1700.   With ParentChart do
  1701.   for t:=0 to SeriesCount-1 do
  1702.   if Series[t].Active then
  1703.   begin
  1704.     if Series[t]=Self then break
  1705.                       else if SameClass(Series[t]) then Inc(result);
  1706.   end;
  1707. End;
  1708.  
  1709. Function TCustomBarSeries.InternalClicked(ValueIndex:Longint; Const APoint:TPoint):Boolean;
  1710. Begin
  1711.   result:=False; { <-- abstract }
  1712. End;
  1713.  
  1714. Procedure TCustomBarSeries.CalcBarWidth;
  1715. Var t            : Longint;
  1716.     NumBarSeries : Longint;
  1717.     MaxBarPoints : Longint;
  1718.     tmpAxis      : TCustomChartAxis;
  1719.     tmp          : Integer;
  1720. Begin
  1721.   if FCustomBarSize<>0 then IBarSize:=FCustomBarSize
  1722.   else
  1723.   begin
  1724.     NumBarSeries:=1;
  1725.     MaxBarPoints:=Count;
  1726.     if ParentChart<>nil then
  1727.     With ParentChart do
  1728.     Begin
  1729.       if FMultiBar=mbSide then
  1730.       Begin
  1731.         NumBarSeries:=0;
  1732.         MaxBarPoints:=TeeAllValues;
  1733.         for t:=0 to SeriesCount-1 do
  1734.         if Series[t].Active and SameClass(Series[t]) then
  1735.         Begin
  1736.           Inc(NumBarSeries);
  1737.           if (MaxBarPoints=TeeAllValues) or (Series[t].Count>MaxBarPoints) then
  1738.              MaxBarPoints:=Series[t].Count;
  1739.         end;
  1740.       end;
  1741.       { this should be after calculating NumBarSeries }
  1742.       if MaxPointsPerPage>0 then MaxBarPoints:=MaxPointsPerPage;
  1743.     end;
  1744.     if MaxBarPoints>0 then
  1745.     Begin
  1746.       if FSideMargins then Inc(MaxBarPoints);
  1747.       if MandatoryValueList=XValues then tmpAxis:=GetVertAxis
  1748.                                     else tmpAxis:=GetHorizAxis;
  1749.       With ParentChart,tmpAxis do
  1750.       if FAutoBarSize then tmp:=Round(IAxisSize/(2.0+Maximum-Minimum))
  1751.                       else tmp:=IAxisSize div MaxBarPoints;
  1752.       IBarSize:=Round((FBarWidthPercent*0.01)*tmp) div NumBarSeries;
  1753.       if (IBarSize mod 2)=1 then inc(IBarSize);
  1754.     end
  1755.     else IBarSize:=0;
  1756.   end;
  1757. end;
  1758.  
  1759. Function TCustomBarSeries.CalcMarkLength(ValueIndex:Longint):Longint;
  1760. Begin
  1761.   if (Count>0) and Marks.Visible then
  1762.   Begin
  1763.     ParentChart.FontCanvas(Marks.Font);
  1764.     result:=Marks.ArrowLength+InternalCalcMarkLength(ValueIndex);
  1765.     if Marks.Frame.Visible then Inc(result,2*Marks.Frame.Width);
  1766.   end
  1767.   else result:=0;
  1768. end;
  1769.  
  1770. Procedure TCustomBarSeries.SetUseOrigin(Value:Boolean);
  1771. Begin
  1772.   SetBooleanProperty(FUseOrigin,Value);
  1773. End;
  1774.  
  1775. Procedure TCustomBarSeries.SetSideMargins(Value:Boolean);
  1776. var t : Longint;
  1777. Begin
  1778.   SetBooleanProperty(FSideMargins,Value);
  1779.   if (ParentChart<>nil) then
  1780.   with ParentChart do
  1781.   for t:=0 to SeriesCount-1 do
  1782.     if (Series[t]<>Self) and SameClass(Series[t]) then
  1783.        TCustomBarSeries(Series[t]).FSideMargins:=FSideMargins;
  1784. end;
  1785.  
  1786. Procedure TCustomBarSeries.SetDark3d(Value:Boolean);
  1787. Begin
  1788.   SetBooleanProperty(FDark3d,Value);
  1789. End;
  1790.  
  1791. Procedure TCustomBarSeries.PrepareForGallery(IsEnabled:Boolean);
  1792. Begin
  1793.   inherited PrepareForGallery(IsEnabled);
  1794.   BarWidthPercent:=85;
  1795.   MultiBar:=mbNone;
  1796. end;
  1797.  
  1798. Procedure TCustomBarSeries.SetOrigin(Const Value:Double);
  1799. Begin
  1800.   SetDoubleProperty(FOrigin,Value);
  1801. End;
  1802.  
  1803. Function TCustomBarSeries.BarSeriesCount:Longint;
  1804. var t : Longint;
  1805. Begin
  1806.   if FMultiBar=mbSide then
  1807.   Begin
  1808.     result:=0;
  1809.     with ParentChart do
  1810.     for t:=0 to SeriesCount-1 do
  1811.         if Series[t].Active and SameClass(Series[t]) then
  1812.            Inc(Result);
  1813.   end
  1814.   else result:=1;
  1815. {      if multibar mbSeries}
  1816. end;
  1817.  
  1818. Function TCustomBarSeries.Clicked(x,y:Integer):Longint;
  1819. var t : Longint;
  1820.     P : TPoint;
  1821. Begin
  1822.   if (ParentChart<>nil) then ParentChart.Canvas.Calculate2DPosition(X,Y,StartZ);
  1823.   result:=inherited Clicked(x,y);
  1824.   if (result=-1) and (FirstValueIndex>-1) and (LastValueIndex>-1) then
  1825.   begin
  1826.     P.X:=X;
  1827.     P.Y:=Y;
  1828.     for t:=FirstValueIndex to LastValueIndex do
  1829.     if t<Count then
  1830.        if InternalClicked(t,P) then
  1831.        begin
  1832.          result:=t;
  1833.          break;
  1834.        end;
  1835.   end;
  1836. end;
  1837.  
  1838. Procedure TCustomBarSeries.SetOtherMultiBar;
  1839. var t : Longint;
  1840. Begin
  1841.   if (ParentChart<>nil) then
  1842.   with ParentChart do
  1843.   for t:=0 to SeriesCount-1 do
  1844.     if SameClass(Series[t]) then
  1845.        TCustomBarSeries(Series[t]).FMultiBar:=FMultiBar;
  1846. end;
  1847.  
  1848. Procedure TCustomBarSeries.SetMultiBar(Value:TMultiBar);
  1849. Begin
  1850.   if Value<>FMultiBar then
  1851.   Begin
  1852.     FMultiBar:=Value;
  1853.     SetOtherMultiBar;
  1854.     Repaint;
  1855.   end;
  1856. End;
  1857.  
  1858. Function TCustomBarSeries.InternalGetOriginPos(ValueIndex:Longint; DefaultOrigin:Longint):Longint;
  1859. Var tmp      : Double;
  1860.     tmpValue : Double;
  1861. Begin
  1862.   tmpValue:=PointOrigin(ValueIndex,False);
  1863.   Case FMultiBar of
  1864.     mbStacked: result:=CalcPosValue(tmpValue);
  1865.     mbStacked100:
  1866.       begin
  1867.         tmp:=PointOrigin(ValueIndex,True);
  1868.         if tmp<>0 then result:=CalcPosValue(tmpValue*100.0/tmp)
  1869.                   else result:=0;
  1870.       end;
  1871.   else
  1872.     if FUseOrigin then result:=CalcPosValue(tmpValue)
  1873.                   else result:=DefaultOrigin;
  1874.   end;
  1875. end;
  1876.  
  1877. Function TCustomBarSeries.PointOrigin(ValueIndex:Longint; SumAll:Boolean):Double;
  1878. Begin
  1879.   if (FMultiBar=mbStacked) or
  1880.      (FMultiBar=mbStacked100) then
  1881.     result:=inherited PointOrigin(ValueIndex,SumAll)
  1882.   else
  1883.     result:=FOrigin;
  1884. End;
  1885.  
  1886. Procedure TCustomBarSeries.DrawLegendShape(ValueIndex:Longint; Const Rect:TRect);
  1887. begin
  1888.   if FBarBrush.Bitmap<>nil then ParentChart.Canvas.Brush.Bitmap:=FBarBrush.Bitmap;
  1889.   inherited DrawLegendShape(ValueIndex,Rect);
  1890. end;
  1891.  
  1892. Procedure TCustomBarSeries.PrepareLegendCanvas( ValueIndex:Longint; Var BackColor:TColor;
  1893.                                                 Var BrushStyle:TBrushStyle);
  1894. Begin
  1895.   ParentChart.Canvas.AssignVisiblePen(FBarPen);
  1896.   BrushStyle:=FBarBrush.Style;
  1897.   if FBarBrush.Color=clTeeColor then BackColor:=ParentChart.Color
  1898.                                 else BackColor:=FBarBrush.Color;
  1899. end;
  1900.  
  1901. Procedure TCustomBarSeries.SetPenBrushBar(BarColor:TColor);
  1902. var tmpBack : TColor;
  1903. Begin
  1904.   With ParentChart do
  1905.   begin
  1906.     Canvas.AssignVisiblePen(FBarPen);
  1907.     if FBarBrush.Bitmap=nil then
  1908.     begin
  1909.       if FBarBrush.Color=clTeeColor then tmpBack:=Color
  1910.                                     else tmpBack:=FBarBrush.Color;
  1911.       SetBrushCanvas(BarColor,FBarBrush.Style,tmpBack);
  1912.     end
  1913.     else Canvas.Brush.Bitmap:=FBarBrush.Bitmap;
  1914.   end;
  1915. end;
  1916.  
  1917. Procedure TCustomBarSeries.BarRectangle( BarColor:TColor;
  1918.                                          ALeft,ATop,ARight,ABottom:Longint);
  1919. Begin
  1920.   With ParentChart,Canvas do
  1921.   begin
  1922.     if FBarBrush.Style=bsSolid then
  1923.     Begin
  1924.       if (ARight=ALeft) or (ATop=ABottom) then
  1925.       Begin
  1926.         Pen.Color:=Brush.Color;
  1927.         if Pen.Style=psClear then Pen.Style:=psSolid;
  1928.         Line(ALeft,ATop,ARight,ABottom);
  1929.       end
  1930.       else
  1931.       if (Abs(ARight-ALeft)<Pen.Width) or
  1932.          (Abs(ABottom-ATop)<Pen.Width) then
  1933.       Begin
  1934.         Pen.Color:=Brush.Color;
  1935.         if Pen.Style=psClear then Pen.Style:=psSolid;
  1936.         Brush.Style:=bsClear;
  1937.       end;
  1938.     end;
  1939.     Rectangle(ALeft,ATop,ARight,ABottom);
  1940.   end;
  1941. End;
  1942.  
  1943. Procedure TCustomBarSeries.SetBarPen(Value:TChartPen);
  1944. Begin
  1945.   FBarPen.Assign(Value);
  1946. end;
  1947.  
  1948. Function TCustomBarSeries.GetBarStyle(ValueIndex:Longint):TBarStyle;
  1949. Begin
  1950.   result:=FBarStyle;
  1951.   if Assigned(FOnGetBarStyle) then FOnGetBarStyle(Self,ValueIndex,result);
  1952. end;
  1953.  
  1954. Procedure TCustomBarSeries.SetBarBrush(Value:TChartBrush);
  1955. Begin
  1956.   FBarBrush.Assign(Value);
  1957. end;
  1958.  
  1959. Function TCustomBarSeries.GetEditorClass:String;
  1960. Begin
  1961.   result:='TBarSeriesEditor'; { <-- dont translate ! }
  1962. end;
  1963.  
  1964. Function TCustomBarSeries.BarMargin:Longint;
  1965. Begin
  1966.   result:=IBarSize*BarSeriesCount;
  1967.   if not FSideMargins then result:=result shr 1;
  1968. end;
  1969.  
  1970. Function TCustomBarSeries.ApplyBarOffset(Position:Longint):Longint;
  1971. Begin
  1972.   result:=Position;
  1973.   if FOffsetPercent<>0 then Inc(result,Round(FOffsetPercent*IBarSize*0.01));
  1974. end;
  1975.  
  1976. Procedure TCustomBarSeries.SetAutoMarkPosition(Value:Boolean);
  1977. Begin
  1978.   SetBooleanProperty(FAutoMarkPosition,Value);
  1979. end;
  1980.  
  1981. Procedure TCustomBarSeries.SetAutoBarSize(Value:Boolean);
  1982. Begin
  1983.   SetBooleanProperty(FAutoBarSize,Value);
  1984. end;
  1985.  
  1986. Procedure TCustomBarSeries.Assign(Source:TPersistent);
  1987. begin
  1988.   if Source is TCustomBarSeries then
  1989.   With TCustomBarSeries(Source) do
  1990.   begin
  1991.     Self.FAutoMarkPosition:=FAutoMarkPosition;
  1992.     Self.FBarWidthPercent:=FBarWidthPercent;
  1993.     Self.FBarStyle       :=FBarStyle;
  1994.     Self.FBarPen.Assign(FBarPen);
  1995.     Self.FBarBrush.Assign(FBarBrush);
  1996.     Self.FCustomBarSize  :=FCustomBarSize;
  1997.     Self.FDark3d         :=FDark3D;
  1998.     Self.FMultiBar       :=FMultiBar;
  1999.     Self.FOffsetPercent  :=FOffsetPercent;
  2000.     Self.FOrigin         :=FOrigin;
  2001.     Self.FSideMargins    :=FSideMargins;
  2002.     Self.FUseOrigin      :=FUseOrigin;
  2003.   end;
  2004.   inherited Assign(Source);
  2005. end;
  2006.  
  2007. Function TCustomBarSeries.AddBar( Const AValue:Double;
  2008.                                   Const ALabel:String; AColor:TColor):Longint;
  2009. begin
  2010.   result:=Add(AValue,ALabel,AColor);
  2011. end;
  2012.  
  2013. Procedure TCustomBarSeries.AdjustGradientRectPen(Var R:TRect);
  2014. begin
  2015.   With R do
  2016.   begin
  2017.     Inc(Left);
  2018.     Inc(Top);
  2019.     Dec(Right,FBarPen.Width-1);
  2020.     Dec(Bottom,FBarPen.Width-1);
  2021.   end;
  2022. end;
  2023.  
  2024. Function TCustomBarSeries.MaxMandatoryValue( Const Value:Double;
  2025.                                              AList:TChartValueList):Double;
  2026. var t   : Longint;
  2027.     tmp : Double;
  2028. begin
  2029.   if FMultiBar=mbStacked100 then result:=100
  2030.   else
  2031.   begin
  2032.     result:=Value;
  2033.     if FMultiBar=mbStacked then
  2034.     for t:=0 to Count-1 do
  2035.     Begin
  2036.       tmp:=PointOrigin(t,False)+AList[t];
  2037.       if tmp>result then result:=tmp;
  2038.     end;
  2039.     if FUseOrigin and (result<FOrigin) then result:=FOrigin;
  2040.   end;
  2041. end;
  2042.  
  2043. Function TCustomBarSeries.MinMandatoryValue(Const Value:Double):Double;
  2044. begin
  2045.   if FMultiBar=mbStacked100 then result:=0
  2046.   else
  2047.   begin
  2048.     result:=Value;
  2049.     if FUseOrigin and (result>FOrigin) then result:=FOrigin;
  2050.   end;
  2051. end;
  2052.  
  2053. Procedure TCustomBarSeries.InternalApplyBarMargin(Var MarginA,MarginB:Integer);
  2054. var tmp : Integer;
  2055. begin
  2056.   CalcBarWidth;
  2057.   tmp:=BarMargin;
  2058.   Inc(MarginA,tmp);
  2059.   Inc(MarginB,tmp);
  2060. end;
  2061.  
  2062. { TBarSeries }
  2063.  
  2064. { The horizontal Bar position is the "real" X pos +
  2065.   the BarWidth by our BarSeries order }
  2066. Function TBarSeries.CalcXPos(ValueIndex:Longint):Integer;
  2067. Begin
  2068.   result:=inherited CalcXPos(ValueIndex);
  2069.   if FMultiBar=mbSide then
  2070.      result:=result+Round(IBarSize*((BarOrderPos-(BarSeriesCount*0.5))-1.0))
  2071.   else
  2072.      result:=result-(IBarSize shr 1);
  2073.   result:=ApplyBarOffset(result);
  2074. End;
  2075.  
  2076. Function TBarSeries.MaxYValue:Double;
  2077. Begin
  2078.   result:=MaxMandatoryValue(inherited MaxYValue,YValues);
  2079. end;
  2080.  
  2081. Function TBarSeries.MinYValue:Double;
  2082. Begin
  2083.   result:=MinMandatoryValue(inherited MinYValue);
  2084. end;
  2085.  
  2086. Procedure TBarSeries.CalcHorizMargins(Var LeftMargin,RightMargin:Integer);
  2087. begin
  2088.   inherited CalcHorizMargins(LeftMargin,RightMargin);
  2089.   InternalApplyBarMargin(LeftMargin,RightMargin);
  2090. end;
  2091.  
  2092. Procedure TBarSeries.CalcVerticalMargins(Var TopMargin,BottomMargin:Integer);
  2093. var tmp : Longint;
  2094. begin
  2095.   inherited CalcVerticalMargins(TopMargin,BottomMargin);
  2096.   tmp:=CalcMarkLength(0);
  2097.   if tmp>0 then
  2098.   begin
  2099.     Inc(tmp);
  2100.     if FUseOrigin and (inherited MinYValue<FOrigin) then
  2101.        if GetVertAxis.Inverted then Inc(TopMargin,tmp) { 4.01 }
  2102.                                else Inc(BottomMargin,tmp);
  2103.     if (not FUseOrigin) or (inherited MaxYValue>FOrigin) then
  2104.        if GetVertAxis.Inverted then Inc(BottomMargin,tmp)
  2105.                                else Inc(TopMargin,tmp);
  2106.   end;
  2107. end;
  2108.  
  2109. Function TBarSeries.InternalCalcMarkLength(ValueIndex:Longint):Longint;
  2110. Begin
  2111.   result:=ParentChart.Canvas.FontHeight;
  2112. end;
  2113.  
  2114. Procedure TBarSeries.DrawMark( ValueIndex:Longint; Const St:String;
  2115.                                APosition:TSeriesMarkPosition);
  2116. Var DifW : Integer;
  2117.     DifH : Integer;
  2118. Begin
  2119.   With APosition do
  2120.   begin
  2121.     DifW:=IBarSize div 2;
  2122.     DifH:=Marks.ArrowLength;
  2123.     if ArrowFrom.Y>GetOriginPos(ValueIndex) then DifH:=-DifH-Height;
  2124.     LeftTop.X:=LeftTop.X+DifW;
  2125.     LeftTop.Y:=LeftTop.Y-DifH;
  2126.     ArrowTo.X:=ArrowTo.X+DifW;
  2127.     ArrowTo.Y:=ArrowTo.Y-DifH;
  2128.     ArrowFrom.X:=ArrowFrom.X+DifW;
  2129.   end;
  2130.   inherited DrawMark(ValueIndex,St,APosition);
  2131. end;
  2132.  
  2133. Procedure TBarSeries.DrawBar(BarIndex,StartPos,EndPos:Longint);
  2134. Var tmpMidX     : Integer;
  2135.     tmpGradRect : TRect;
  2136. Begin
  2137.   SetPenBrushBar(NormalBarColor);
  2138.   With ParentChart,Canvas,FBarBounds do
  2139.   begin
  2140.     tmpMidX:=(Left+Right) shr 1;
  2141.     if View3D then
  2142.     Case GetBarStyle(BarIndex) of
  2143.       bsRectangle: Cube(Left,Right,StartPos,EndPos,StartZ,EndZ,FDark3D);
  2144.       bsPyramid  : Pyramid(True,Left,StartPos,Right,EndPos,StartZ,EndZ,FDark3D);
  2145.      bsInvPyramid: Pyramid(True,Left,EndPos,Right,StartPos,StartZ,EndZ,FDark3D);
  2146.       bsCilinder : Cylinder(True,Left,Top,Right,Bottom,StartZ,EndZ,FDark3D);
  2147.       bsEllipse  : EllipseWithZ(Left,Top,Right,Bottom,MiddleZ);
  2148.       bsArrow    : Arrow(True,Point(tmpMidX,EndPos),Point(tmpMidX,StartPos),(Right-Left),(Right-Left) div 2,MiddleZ);
  2149.    bsRectGradient: begin
  2150.                      Cube(Left,Right,StartPos,EndPos,StartZ,EndZ,FDark3D);
  2151.                      if View3DOptions.Orthogonal then
  2152.                      With FBarBounds do
  2153.                      begin
  2154.                        tmpGradRect.TopLeft:=Calculate3DPosition(Left,StartPos,StartZ);
  2155.                        tmpGradRect.BottomRight:=Calculate3DPosition(Right,EndPos,StartZ);
  2156.                        if BarPen.Visible then AdjustGradientRectPen(tmpGradRect);
  2157.                        GradientFill(tmpGradRect,clWhite,NormalBarColor,gdBottomTop);
  2158.                      end;
  2159.                    end;
  2160.     end
  2161.     else
  2162.     begin
  2163.       Case GetBarStyle(BarIndex) of
  2164.         bsRectangle,
  2165.         bsCilinder : BarRectangle(NormalBarColor,Left,Top,Right,Bottom);
  2166.         bsPyramid  : Polygon([ Point(Left,EndPos),Point(tmpMidX,StartPos),Point(Right,EndPos) ]);
  2167.        bsInvPyramid: Polygon([ Point(Left,StartPos),Point(tmpMidX,EndPos),Point(Right,StartPos) ]);
  2168.         bsEllipse  : Ellipse(Left,Top,Right,Bottom);
  2169.         bsArrow    : Arrow(True,Point(tmpMidX,EndPos),Point(tmpMidX,StartPos),(Right-Left),(Right-Left) div 2,MiddleZ);
  2170.      bsRectGradient: begin
  2171.                        GradientFill(Rect(Left,StartPos,Right,EndPos),clWhite,NormalBarColor,gdBottomTop);
  2172.                        if FBarPen.Visible then
  2173.                        begin
  2174.                          Brush.Style:=bsClear;
  2175.                          BarRectangle(NormalBarColor,Left,Top,Right,Bottom);
  2176.                        end;
  2177.                      end;
  2178.       end;
  2179.     end;
  2180.   end;
  2181. end;
  2182.  
  2183. procedure TBarSeries.DrawValue(ValueIndex:Longint);
  2184. Begin
  2185.   inherited DrawValue(ValueIndex); { <-- call inherited ! }
  2186.   NormalBarColor:=ValueColor[ValueIndex];
  2187.   if NormalBarColor<>clNone then { if not null }
  2188.   With FBarBounds do
  2189.   Begin
  2190.     Left  :=CalcXPos(ValueIndex);
  2191.     Right :=Left+IBarSize;
  2192.     Top   :=CalcYPos(ValueIndex);
  2193.     Bottom:=GetOriginPos(ValueIndex);
  2194.     if Bottom>Top then DrawBar(ValueIndex,Top,Bottom)
  2195.                   else DrawBar(ValueIndex,Bottom,Top);
  2196.   end;
  2197. end;
  2198.  
  2199. Function TBarSeries.CalcYPos(ValueIndex:Longint):Integer;
  2200. var tmp      : Double;
  2201.     tmpValue : Double;
  2202. Begin
  2203.   if (FMultiBar=mbNone) or (FMultiBar=mbSide) then
  2204.       result:=inherited CalcYPos(ValueIndex)
  2205.   else
  2206.   begin
  2207.     tmpValue:=YValue[ValueIndex]+PointOrigin(ValueIndex,False);
  2208.     if FMultiBar=mbStacked then result:=CalcYPosValue(tmpValue)
  2209.     else
  2210.     begin
  2211.       tmp:=PointOrigin(ValueIndex,True);
  2212.       if tmp<>0 then result:=CalcYPosValue(tmpValue*100.0/tmp)
  2213.                 else result:=0;
  2214.     end;
  2215.   end;
  2216. End;
  2217.  
  2218. Function TBarSeries.GetOriginPos(ValueIndex:Longint):Longint;
  2219. Begin
  2220.   result:=InternalGetOriginPos(ValueIndex,GetVertAxis.IEndPos);
  2221. end;
  2222.  
  2223. Function TBarSeries.InternalClicked(ValueIndex:Longint; Const APoint:TPoint):Boolean;
  2224. Var tmpSwap : Longint;
  2225.     tmpX    : Longint;
  2226.     tmpY    : Longint;
  2227.     endY    : Longint;
  2228. Begin
  2229.   result:=False;
  2230.   tmpX:=CalcXPos(ValueIndex);
  2231.   if (APoint.x>=tmpX) and (APoint.x<=(tmpX+IBarSize)) then
  2232.   Begin
  2233.     tmpY:=CalcYPos(ValueIndex);
  2234.     endY:=GetOriginPos(ValueIndex);
  2235.     if endY<tmpY then
  2236.     begin
  2237.       tmpSwap:=endY;
  2238.       endY:=tmpY;
  2239.       tmpY:=tmpSwap;
  2240.     end;
  2241.     Case FBarStyle of
  2242.    bsInvPyramid: result:=PointInTriangle(APoint,tmpX,tmpX+IBarSize,tmpY,endY);
  2243.       bsPyramid: result:=PointInTriangle(APoint,tmpX,tmpX+IBarSize,endY,tmpY);
  2244.       bsEllipse: result:=PointInEllipse(APoint,Rect(tmpX,tmpY,tmpX+IBarSize,endY));
  2245.     else
  2246.       result:=(APoint.y>=tmpY) and (APoint.y<=endY);
  2247.     end;
  2248.   end;
  2249. end;
  2250.  
  2251. Function TBarSeries.DrawValuesForward:Boolean;
  2252. begin
  2253.   result:=not GetHorizAxis.Inverted;
  2254. end;
  2255.  
  2256. Function TBarSeries.DrawSeriesForward(ValueIndex:Longint):Boolean;
  2257. begin
  2258.   if (FMultiBar=mbNone) or (FMultiBar=mbSide) then
  2259.      result:=True
  2260.   else
  2261.   begin
  2262.     result:=GetVertAxis.Inverted;
  2263.     if MandatoryValueList[ValueIndex]>=0 then result:=not result;
  2264.   end;
  2265. end;
  2266.  
  2267. { THorizBarSeries }
  2268. Function THorizBarSeries.MandatoryValueList:TChartValueList;
  2269. Begin
  2270.   result:=XValues;
  2271. End;
  2272.  
  2273. Procedure THorizBarSeries.CalcHorizMargins(Var LeftMargin,RightMargin:Integer);
  2274. var tmp : Longint;
  2275. begin
  2276.   inherited CalcHorizMargins(LeftMargin,RightMargin);
  2277.   tmp:=CalcMarkLength(TeeAllValues);
  2278.   if tmp>0 then Inc(tmp);
  2279.   if (FUseOrigin and (inherited MinXValue<FOrigin)) then
  2280.      Inc(LeftMargin,tmp);
  2281.   if (not FUseOrigin) or (inherited MaxXValue>FOrigin) then
  2282.      if GetHorizAxis.Inverted then Inc(LeftMargin,tmp)
  2283.                               else Inc(RightMargin,tmp);
  2284. end;
  2285.  
  2286. Procedure THorizBarSeries.CalcVerticalMargins(Var TopMargin,BottomMargin:Integer);
  2287. begin
  2288.   inherited CalcVerticalMargins(TopMargin,BottomMargin);
  2289.   InternalApplyBarMargin(TopMargin,BottomMargin);
  2290. end;
  2291.  
  2292. Function THorizBarSeries.CalcXPos(ValueIndex:Longint):Integer;
  2293. var tmp      : Double;
  2294.     tmpValue : Double;
  2295. Begin
  2296.   if (FMultiBar=mbNone) or (FMultiBar=mbSide) then
  2297.      result:=inherited CalcXPos(ValueIndex)
  2298.   else
  2299.   begin
  2300.     tmpValue:=XValue[ValueIndex]+PointOrigin(ValueIndex,False);
  2301.     if FMultiBar=mbStacked then result:=CalcXPosValue(tmpValue)
  2302.     else
  2303.     begin
  2304.       tmp:=PointOrigin(ValueIndex,True);
  2305.       if tmp<>0 then result:=CalcXPosValue(tmpValue*100.0/tmp)
  2306.                 else result:=0;
  2307.     end;
  2308.   end;
  2309. End;
  2310.  
  2311. Function THorizBarSeries.GetOriginPos(ValueIndex:Longint):Longint;
  2312. Begin
  2313.   result:=InternalGetOriginPos(ValueIndex,GetHorizAxis.IStartPos);
  2314. end;
  2315.  
  2316. { The vertical Bar position is the "real" Y pos +
  2317.   the Barwidth by our BarSeries order }
  2318. Function THorizBarSeries.CalcYPos(ValueIndex:Longint):Integer;
  2319. Begin
  2320.   result:=inherited CalcYPos(ValueIndex);
  2321.   if FMultiBar=mbSide then
  2322.      result:=result+Round(IBarSize*(((BarSeriesCount*0.5)-BarOrderPos)))
  2323.   else
  2324.      result:=result-(IBarSize shr 1);
  2325.   result:=ApplyBarOffset(result);
  2326. End;
  2327.  
  2328. Function THorizBarSeries.InternalClicked(ValueIndex:Longint; Const APoint:TPoint):Boolean;
  2329. Var tmpX  : Longint;
  2330.     tmpY  : Longint;
  2331.     endX  : Longint;
  2332. Begin
  2333.   result:=False;
  2334.   tmpY:=CalcYPos(ValueIndex);
  2335.   if (APoint.y>=tmpY) and (APoint.y<=(tmpY+IBarSize)) then
  2336.   Begin
  2337.     tmpX:=CalcXPos(ValueIndex);
  2338.     endX:=GetOriginPos(ValueIndex);
  2339.     if endX<tmpX then SwapLongint(tmpX,endX);
  2340.     Case FBarStyle of
  2341.    bsInvPyramid: result:=PointInHorizTriangle(APoint,tmpY,tmpY+IBarSize,endX,tmpX);
  2342.       bsPyramid: result:=PointInHorizTriangle(APoint,tmpY,tmpY+IBarSize,tmpX,endX);
  2343.       bsEllipse: result:=PointInEllipse(APoint,Rect(tmpX,tmpY,endX,tmpY+IBarSize));
  2344.     else
  2345.       result:=(APoint.x>=tmpX) and (APoint.x<=endX);
  2346.     end;
  2347.   end;
  2348. end;
  2349.  
  2350. Function THorizBarSeries.MaxXValue:Double;
  2351. Begin
  2352.   result:=MaxMandatoryValue(inherited MaxXValue,XValues);
  2353. end;
  2354.  
  2355. Function THorizBarSeries.MinXValue:Double;
  2356. Begin
  2357.   result:=MinMandatoryValue(inherited MinXValue);
  2358. end;
  2359.  
  2360. Function THorizBarSeries.InternalCalcMarkLength(ValueIndex:Longint):Longint;
  2361. Begin
  2362.   if ValueIndex<>TeeAllValues then
  2363.      result:=ParentChart.Canvas.TextWidth(GetMarkText(ValueIndex))
  2364.   else
  2365.      result:=MaxMarkWidth;
  2366. end;
  2367.  
  2368. Procedure THorizBarSeries.DrawMark( ValueIndex:Longint; Const St:String;
  2369.                                     APosition:TSeriesMarkPosition);
  2370. Var DifH : Integer;
  2371.     DifW : Integer;
  2372. Begin
  2373.   With APosition do
  2374.   begin
  2375.     DifH:=IBarSize div 2;
  2376.     DifW:=Marks.ArrowLength;
  2377.     if ArrowFrom.X<GetOriginPos(ValueIndex) then DifW:=-DifW-Width;
  2378.     LeftTop.X:=LeftTop.X+DifW+(Width div 2);
  2379.     LeftTop.Y:=LeftTop.Y+DifH+(Height div 2);
  2380.     ArrowTo.X:=ArrowTo.X+DifW;
  2381.     ArrowTo.Y:=ArrowTo.Y+DifH;
  2382.     ArrowFrom.Y:=ArrowFrom.Y+DifH;
  2383.   end;
  2384.   inherited DrawMark(ValueIndex,St,APosition);
  2385. end;
  2386.  
  2387. Procedure THorizBarSeries.DrawBar(BarIndex,StartPos,EndPos:Longint);
  2388. Var tmpMidY     : Integer;
  2389.     tmpGradRect : TRect;
  2390. Begin
  2391.   SetPenBrushBar(NormalBarColor);
  2392.   With ParentChart,Canvas,FBarBounds do
  2393.   begin
  2394.     tmpMidY:=(Top+Bottom) shr 1;
  2395.     if View3D then
  2396.     Case GetBarStyle(BarIndex) of
  2397.       bsRectangle: Cube(StartPos,EndPos,Top,Bottom,StartZ,EndZ,FDark3D);
  2398.       bsPyramid  : Pyramid(False,StartPos,Top,EndPos,Bottom,StartZ,EndZ,FDark3D);
  2399.      bsInvPyramid: Pyramid(False,EndPos,Top,StartPos,Bottom,StartZ,EndZ,FDark3D);
  2400.       bsCilinder : Cylinder(False,Left,Top,Right,Bottom,StartZ,EndZ,FDark3D);
  2401.       bsEllipse  : EllipseWithZ(Left,Top,Right,Bottom,MiddleZ);
  2402.       bsArrow    : Arrow(True,Point(StartPos,tmpMidY),Point(EndPos,tmpMidY),(Bottom-Top),(Bottom-Top) div 2,MiddleZ);
  2403.    bsRectGradient: begin
  2404.                      Cube(StartPos,EndPos,Top,Bottom,StartZ,EndZ,FDark3D);
  2405.                      if View3DOptions.Orthogonal then
  2406.                      With FBarBounds do
  2407.                      begin
  2408.                        tmpGradRect.TopLeft:=Calculate3DPosition(StartPos,Top,StartZ);
  2409.                        tmpGradRect.BottomRight:=Calculate3DPosition(EndPos,Bottom,StartZ);
  2410.                        if BarPen.Visible then AdjustGradientRectPen(tmpGradRect);
  2411.                        GradientFill(tmpGradRect,clWhite,NormalBarColor,gdLeftRight);
  2412.                      end;
  2413.                    end;
  2414.     end
  2415.     else
  2416.     begin
  2417.       Case GetBarStyle(BarIndex) of
  2418.         bsRectangle,
  2419.         bsCilinder : BarRectangle(NormalBarColor,Left,Top,Right,Bottom);
  2420.         bsPyramid  : Polygon([ Point(StartPos,Top),Point(EndPos,tmpMidY),Point(StartPos,Bottom) ]);
  2421.        bsInvPyramid: Polygon([ Point(EndPos,Top),Point(StartPos,tmpMidY),Point(EndPos,Bottom) ]);
  2422.         bsEllipse  : Ellipse(Left,Top,Right,Bottom);
  2423.         bsArrow    : Arrow(True,Point(StartPos,tmpMidY),Point(EndPos,tmpMidY),(Bottom-Top),(Bottom-Top) div 2,MiddleZ);
  2424.      bsRectGradient: begin
  2425.                        GradientFill(Rect(StartPos,Top,EndPos,Bottom),clWhite,NormalBarColor,gdLeftRight);
  2426.                        if FBarPen.Visible then
  2427.                        begin
  2428.                          Brush.Style:=bsClear;
  2429.                          BarRectangle(NormalBarColor,Left,Top,Right,Bottom);
  2430.                        end;
  2431.                      end;
  2432.       end;
  2433.     end;
  2434.   end;
  2435. end;
  2436.  
  2437. procedure THorizBarSeries.DrawValue(ValueIndex:Longint);
  2438. Begin
  2439.   inherited DrawValue(ValueIndex); { <-- call inherited ! }
  2440.   NormalBarColor:=ValueColor[ValueIndex];
  2441.   if NormalBarColor<>clNone then  { <-- if not null }
  2442.   With FBarBounds do
  2443.   Begin
  2444.     Top   :=CalcYPos(ValueIndex);
  2445.     Bottom:=Top+IBarSize;
  2446.     Right :=CalcXPos(ValueIndex);
  2447.     Left  :=GetOriginPos(ValueIndex);
  2448.     if Right>Left then DrawBar(ValueIndex,Left,Right)
  2449.                   else DrawBar(ValueIndex,Right,Left);
  2450.   end;
  2451. end;
  2452.  
  2453. Procedure THorizBarSeries.FillSampleValues(NumValues:Longint);
  2454. var t     : Longint;
  2455.     tmpX  : Double;
  2456.     tmpY  : Double;
  2457.     DifX  : Double;
  2458.     StepY : Double;
  2459. Begin
  2460.   if NumValues<=0 then Raise BarException.Create(TeeMsg_FillSample);
  2461.   Clear;
  2462.   tmpY:=GetVertAxis.Minimum;
  2463.   DifX:=1000;
  2464.   tmpX:=DifX+Random(Round(DifX));
  2465.   StepY:=1;
  2466.   for t:=1 to NumValues do
  2467.   Begin
  2468.     tmpX:=tmpX+Random(Round(DifX) div 2)-(Round(DifX) div 4);
  2469.     AddXY(tmpX,tmpY,'' {$IFNDEF D4},clTeeColor{$ENDIF});
  2470.     tmpY:=tmpY+StepY;
  2471.   end;
  2472.   RefreshSeries;
  2473. End;
  2474.  
  2475. Function THorizBarSeries.DrawValuesForward:Boolean;
  2476. begin
  2477.   result:=not GetVertAxis.Inverted;
  2478. end;
  2479.  
  2480. Function THorizBarSeries.DrawSeriesForward(ValueIndex:Longint):Boolean;
  2481. begin
  2482.   if (FMultiBar=mbNone) or (FMultiBar=mbSide) then
  2483.      result:=True
  2484.   else
  2485.   begin
  2486.     result:=GetHorizAxis.Inverted;
  2487.     if MandatoryValueList[ValueIndex]>=0 then result:=not result;
  2488.   end;
  2489. end;
  2490.  
  2491. { TCircledSeries }
  2492. Constructor TCircledSeries.Create(AOwner: TComponent);
  2493. begin
  2494.   inherited Create(AOwner);
  2495.   CalcVisiblePoints:=False; { always draw all points }
  2496.   XValues.Name:=TeeMsg_ValuesAngle;
  2497.   FCircleBackColor:=clTeeColor;
  2498. end;
  2499.  
  2500. Destructor TCircledSeries.Destroy;
  2501. begin
  2502.   SetParentProperties(True);
  2503.   inherited Destroy;
  2504. end;
  2505.  
  2506. procedure TCircledSeries.SetCircled(Value:Boolean);
  2507. var t : Longint;
  2508. Begin
  2509.   SetBooleanProperty(FCircled,Value);
  2510.   if (ParentChart<>nil) then
  2511.   with ParentChart do
  2512.   for t:=0 to SeriesCount-1 do
  2513.     if Self is Series[t].ClassType then
  2514.        TCircledSeries(Series[t]).FCircled:=Value;
  2515. end;
  2516.  
  2517. Procedure TCircledSeries.SetRotationAngle(Value:Integer);
  2518. Begin
  2519.   if Value<0 then
  2520.      Raise PieException.CreateFmt(TeeMsg_Angle,[TeeMsg_Rotation]);
  2521.   SetIntegerProperty(FRotationAngle,Value mod 360);
  2522.   IRotDegree:=FRotationAngle*PiDegree;
  2523. end;
  2524.  
  2525. procedure TCircledSeries.SetOtherCustomRadius(IsXRadius:Boolean; Value:Longint);
  2526. var t : Integer;
  2527. Begin
  2528.   if ParentChart<>nil then
  2529.   with ParentChart do
  2530.   for t:=0 to SeriesCount-1 do
  2531.   With TCircledSeries(Series[t]) do
  2532.     if Self is ClassType then
  2533.        if IsXRadius then FCustomXRadius:=Value
  2534.                     else FCustomYRadius:=Value;
  2535. end;
  2536.  
  2537. Function TCircledSeries.UseAxis:Boolean;
  2538. begin
  2539.   result:=False;
  2540. end;
  2541.  
  2542. procedure TCircledSeries.SetCustomXRadius(Value:Longint);
  2543. Begin
  2544.   SetLongintProperty(FCustomXRadius,Value);
  2545.   SetOtherCustomRadius(True,Value);
  2546. End;
  2547.  
  2548. procedure TCircledSeries.SetCustomYRadius(Value:Longint);
  2549. Begin
  2550.   SetLongintProperty(FCustomYRadius,Value);
  2551.   SetOtherCustomRadius(False,Value);
  2552. End;
  2553.  
  2554. Procedure TCircledSeries.SetParentProperties(EnableParentProps:Boolean);
  2555.  
  2556.   Function AllCircled:Boolean;
  2557.   var t:Integer;
  2558.   begin
  2559.     result:=True;
  2560.     With ParentChart do
  2561.     for t:=0 to SeriesCount-1 do
  2562.       if not (Series[t] is TCircledSeries) then
  2563.       begin
  2564.         result:=False;
  2565.         Exit;
  2566.       end;
  2567.   end;
  2568.  
  2569. begin
  2570.   if (ParentChart<>nil) then
  2571.   With ParentChart do
  2572.   if (not (csDestroying in ComponentState)) then
  2573.   begin
  2574.     if EnableParentProps and AllCircled then Exit;
  2575.  
  2576.     AxisVisible  :=EnableParentProps;
  2577.     ClipPoints   :=EnableParentProps;
  2578.     View3DWalls  :=EnableParentProps;
  2579.     if ParentChart is TCustomChart then
  2580.     With TCustomChart(ParentChart) do
  2581.     begin
  2582.       if Frame<>nil then
  2583.          Frame.Visible:=EnableParentProps;
  2584.       if BackWall<>nil then
  2585.          if EnableParentProps then
  2586.             BackWall.Brush.Style:=bsSolid
  2587.          else
  2588.             BackWall.Brush.Style:=bsClear;
  2589.       AllowZoom:=EnableParentProps;
  2590.       if AllowZoom then AllowPanning:=pmBoth
  2591.                    else AllowPanning:=pmNone;
  2592.     end;
  2593.     if not Canvas.SupportsFullRotation then
  2594.     if View3DOptions<>nil then
  2595.     With View3DOptions do
  2596.     begin
  2597.       Orthogonal:=False;
  2598.       Rotation:=360;
  2599.       Elevation:=315;
  2600.       Perspective:=0;
  2601.       Tilt:=0;
  2602.     end;
  2603.   end;
  2604. end;
  2605.  
  2606. Procedure TCircledSeries.SetParentChart(Value:TCustomAxisPanel);
  2607. Begin
  2608.   if Value=nil then SetParentProperties(True);
  2609.   if Value<>ParentChart then
  2610.   begin
  2611.     inherited SetParentChart(Value);
  2612.     if ParentChart<>nil then SetParentProperties(False);
  2613.   end;
  2614. end;
  2615.  
  2616. Procedure TCircledSeries.Rotate(Angle:Integer);
  2617. Begin
  2618.   if (Angle<0) or (Angle>360) then
  2619.      Raise PieException.CreateFmt(TeeMsg_Angle,[TeeMsg_Rotation]);
  2620.   RotationAngle:=(RotationAngle+Angle) mod 360;
  2621. End;
  2622.  
  2623. Function TCircledSeries.AssociatedToAxis(Axis:TCustomChartAxis):Boolean;
  2624. Begin
  2625.   result:=True{False};
  2626. end;
  2627.  
  2628. Procedure TCircledSeries.AdjustCircleRect;
  2629. Begin
  2630.   with FCircleRect do
  2631.   Begin
  2632.     if Odd(Right-Left) then Dec(Right);
  2633.     if Odd(Bottom-Top) then Dec(Bottom);
  2634.     if (Right-Left)<4 then Right:=Left+4;
  2635.     if (Bottom-Top)<4 then Bottom:=Top+4;
  2636.     FCircleWidth  :=Right-Left;
  2637.     FCircleHeight :=Bottom-Top;
  2638.     FCircleXCenter:=(Left+Right) shr 1;
  2639.     FCircleYCenter:=(Top+Bottom) shr 1;
  2640.   end;
  2641. End;
  2642.  
  2643. Procedure TCircledSeries.DoBeforeDrawValues;
  2644.  
  2645.   Procedure CalcCircledRatio;
  2646.   Var tmpRatio : Double;
  2647.       Ratio    : Double;
  2648.       dif      : Integer;
  2649.       tmpH     : Integer;
  2650.       tmpW     : Integer;
  2651.       DC       : HDC;
  2652.   Begin
  2653.     Ratio:=1.0*GetSystemMetrics(SM_CXSCREEN)/GetSystemMetrics(SM_CYSCREEN);
  2654.     DC:=ParentChart.Canvas.Handle;
  2655.     tmpW:=GetDeviceCaps(DC,HORZSIZE);
  2656.     tmpH:=GetDeviceCaps(DC,VERTSIZE);
  2657.     if tmpH<>0 then
  2658.     begin
  2659.       tmpRatio:=(1.0*tmpW/tmpH);
  2660.       if tmpRatio<>0 then Ratio:=1.0*Ratio/tmpRatio;
  2661.     end;
  2662.     CalcRadius;
  2663.     if Round(Ratio*FYRadius)<FXRadius then
  2664.     Begin
  2665.       dif:=(FXRadius-Round(Ratio*FYRadius));
  2666.       Inc(FCircleRect.Left,Dif);
  2667.       Dec(FCircleRect.Right,Dif);
  2668.     end
  2669.     else
  2670.     Begin
  2671.       dif:=(FYRadius-Round(1.0*FXRadius/Ratio));
  2672.       Inc(FCircleRect.Top,Dif);
  2673.       Dec(FCircleRect.Bottom,Dif);
  2674.     end;
  2675.     AdjustCircleRect;
  2676.   end;
  2677.  
  2678.   Procedure AdjustCircleMarks;
  2679.   Var tmpH     : Integer;
  2680.       tmpW     : Integer;
  2681.       tmpFrame : Integer;
  2682.   begin
  2683.     tmpFrame:=Marks.ArrowLength;
  2684.     With Marks.Frame do if Visible then Inc(tmpFrame,Width*2);
  2685.     With ParentChart do
  2686.     Begin
  2687.       FontCanvas(Marks.Font);
  2688.       tmpH:=Canvas.FontHeight+tmpFrame;
  2689.       Inc(FCircleRect.Top,tmpH);
  2690.       Dec(FCircleRect.Bottom,tmpH);
  2691.       tmpW:=MaxMarkWidth+Canvas.TextWidth(TeeCharForHeight)+tmpFrame;
  2692.       Inc(FCircleRect.Left,tmpW);
  2693.       Dec(FCircleRect.Right,tmpW);
  2694.       AdjustCircleRect;
  2695.     end;
  2696.   end;
  2697.  
  2698. begin
  2699.   inherited DoBeforeDrawValues;
  2700.   FCircleRect:=ParentChart.ChartRect;
  2701.   AdjustCircleRect;
  2702.   if Marks.Visible then AdjustCircleMarks;
  2703.   if FCircled then CalcCircledRatio;
  2704.   CalcRadius;
  2705. end;
  2706.  
  2707. Procedure TCircledSeries.CalcRadius;
  2708. Begin
  2709.   if FCustomXRadius<>0 then
  2710.   Begin
  2711.     FXRadius:=FCustomXRadius;
  2712.     FCircleWidth:=2*FXRadius;
  2713.   end
  2714.   else FXRadius:=FCircleWidth shr 1;
  2715.  
  2716.   if FCustomYRadius<>0 then
  2717.   begin
  2718.     FYRadius:=FCustomYRadius;
  2719.     FCircleHeight:=2*FYRadius;
  2720.   end
  2721.   else FYRadius:=FCircleHeight shr 1;
  2722.  
  2723.   With FCircleRect do
  2724.   begin
  2725.     Left  :=FCircleXCenter-FXRadius;
  2726.     Right :=FCircleXCenter+FXRadius;
  2727.     Top   :=FCircleYCenter-FYRadius;
  2728.     Bottom:=FCircleYCenter+FYRadius;
  2729.   end;
  2730. end;
  2731.  
  2732. procedure TCircledSeries.SetCircleBackColor(Value:TColor);
  2733. begin
  2734.   SetColorProperty(FCircleBackColor,Value);
  2735. end;
  2736.  
  2737. Procedure TCircledSeries.AngleToPos( Const Angle,AXRadius,AYRadius:Double;
  2738.                                      Var X,Y:{$IFDEF D2C1}Longint{$ELSE}Integer{$ENDIF});
  2739. var tmpSin : Extended;
  2740.     tmpCos : Extended;
  2741. Begin
  2742.   SinCos(IRotDegree+Angle,tmpSin,tmpCos);
  2743.   X:=FCircleXCenter+Round(AXRadius*tmpCos);
  2744.   Y:=FCircleYCenter-Round(AYRadius*tmpSin);
  2745. end;
  2746.  
  2747. Function TCircledSeries.CalcCircleBackColor:TColor;
  2748. begin
  2749.   result:=FCircleBackColor;
  2750.   if result=clTeeColor then result:=(ParentChart as TCustomChart).BackColor;
  2751.   if result=clTeeColor then result:=ParentChart.Color;
  2752. end;
  2753.  
  2754. Procedure TCircledSeries.PrepareLegendCanvas( ValueIndex:Longint; Var BackColor:TColor;
  2755.                                               Var BrushStyle:TBrushStyle);
  2756. Begin
  2757.   BackColor:=CalcCircleBackColor;
  2758. end;
  2759.  
  2760. Function TCircledSeries.PointToAngle(x,y:Longint):Double;
  2761. Begin
  2762. {$IFNDEF D1}
  2763.   if (x-FCircleXCenter)=0 then
  2764.   begin
  2765.     if y>FCircleYCenter then result:=-HalfPi{1.5*pi}
  2766.                         else result:=HalfPi;
  2767.   end
  2768.   else
  2769. {$ENDIF}
  2770.   if (FYRadius=0) or (FYRadius=0) then result:=0
  2771.   else
  2772.     result:=ArcTan2( ((FCircleYCenter-y)/FYRadius),
  2773.                      ((x-FCircleXCenter)/FXRadius));
  2774.   if result<0 then result:=TwoPi+result;
  2775.   result:=result-IRotDegree;
  2776.   if result<0 then result:=TwoPi+result;
  2777. End;
  2778.  
  2779. Procedure TCircledSeries.Assign(Source:TPersistent);
  2780. begin
  2781.   if Source is TCircledSeries then
  2782.   With TCircledSeries(Source) do
  2783.   begin
  2784.     Self.FCircled         := FCircled;
  2785.     Self.FRotationAngle   := FRotationAngle;
  2786.     Self.FCustomXRadius   := FCustomXRadius;
  2787.     Self.FCustomYRadius   := FCustomYRadius;
  2788.     Self.FCircleBackColor := FCircleBackColor;
  2789.   end;
  2790.   inherited Assign(Source);
  2791. end;
  2792.  
  2793. Procedure TCircledSeries.SetActive(Value:Boolean);
  2794. begin
  2795.   inherited SetActive(Value);
  2796.   SetParentProperties(not Active);
  2797. end;
  2798.  
  2799. { TPieAngles }
  2800. Function TPieAngles.GetAngle(Index:Integer):TPieAngle;
  2801. begin
  2802.   result:=TPieAngle(Items[Index]);
  2803. end;
  2804.  
  2805. { TExplodedSlices }
  2806. Function TExplodedSlices.GetValue(Index:Integer):Integer;
  2807. begin
  2808.   if (Index<Count) and (Items[Index]<>nil) then result:=Integer(Items[Index])
  2809.                                            else result:=0
  2810. end;
  2811.  
  2812. Procedure TExplodedSlices.SetValue(Index,Value:Integer);
  2813. begin
  2814.   While Index>=Count do Add(nil);
  2815.   if GetValue(Index)<>Value then
  2816.   begin
  2817.     Items[Index]:=Pointer(Value);
  2818.     OwnerSeries.Repaint;
  2819.   end;
  2820. end;
  2821.  
  2822. { TPieOtherSlice }
  2823. Constructor TPieOtherSlice.Create(AOwner:TChartSeries);
  2824. begin
  2825.   inherited Create;
  2826.   FOwner:=AOwner;
  2827.   FText:=TeeMsg_PieOther;
  2828.   FStyle:=poNone;
  2829.   FValue:=0;
  2830. end;
  2831.  
  2832. Procedure TPieOtherSlice.Assign(Source:TPersistent);
  2833. begin
  2834.   if Source is TPieOtherSlice then
  2835.   With TPieOtherSlice(Source) do
  2836.   begin
  2837.     Self.FStyle:=FStyle;
  2838.     Self.FText :=FText;
  2839.     Self.FValue:=FValue;
  2840.   end;
  2841. end;
  2842.  
  2843. procedure TPieOtherSlice.SetStyle(Value:TPieOtherStyle);
  2844. begin
  2845.   if FStyle<>Value then
  2846.   begin
  2847.     FStyle:=Value;
  2848.     FOwner.Repaint;
  2849.   end;
  2850. end;
  2851.  
  2852. procedure TPieOtherSlice.SetText(Const Value:String);
  2853. begin
  2854.   FOwner.SetStringProperty(FText,Value);
  2855. end;
  2856.  
  2857. procedure TPieOtherSlice.SetValue(Const Value:Double);
  2858. begin
  2859.   FOwner.SetDoubleProperty(FValue,Value);
  2860. end;
  2861.  
  2862. { TPieSeries }
  2863. Const TeePieBelongsToOther = -1;
  2864.       TeePieOtherFlag      = MaxLongint;
  2865.  
  2866. Constructor TPieSeries.Create(AOwner: TComponent);
  2867. begin
  2868.   inherited Create(AOwner);
  2869.   FAngles:=TPieAngles.Create;
  2870.   FPiePen:=CreateChartPen;
  2871.   FExplodedSlice:=TExplodedSlices.Create;
  2872.   FExplodedSlice.OwnerSeries:=Self;
  2873.   FOtherSlice:=TPieOtherSlice.Create(Self);
  2874.   XValues.Name:='';
  2875.   YValues.Name:=TeeMsg_ValuesPie;
  2876.   Marks.Visible:=True;
  2877.   Marks.ArrowLength:=8;
  2878.   FDark3D:=True;
  2879.   ColorEachPoint:=True;
  2880. end;
  2881.  
  2882. Procedure TPieSeries.FreePieAngles;
  2883. var t : Longint;
  2884. begin
  2885.   With FAngles do
  2886.   begin
  2887.     for t:=0 to Count-1 do Angle[t].Free;
  2888.     Clear;
  2889.   end;
  2890. end;
  2891.  
  2892. Destructor TPieSeries.Destroy;
  2893. begin
  2894.   FreePieAngles;
  2895.   FAngles.Free;
  2896.   FExplodedSlice.Free;
  2897.   FExplodedSlice:=nil;
  2898.   FOtherSlice.Free;
  2899.   FPiePen.Free;
  2900.   inherited Destroy;
  2901. end;
  2902.  
  2903. Function TPieSeries.CalcXPos(ValueIndex:Longint):Integer;
  2904. begin
  2905.   if XValues.Value[ValueIndex]=TeePieOtherFlag then  { do not try to calc }
  2906.      result:=0
  2907.   else
  2908.      result:=inherited CalcXPos(ValueIndex);
  2909. end;
  2910.  
  2911. Function TPieSeries.NumSampleValues:Longint;
  2912. Begin
  2913.   result:=8;
  2914. End;
  2915.  
  2916. Procedure TPieSeries.ClearLists;
  2917. begin
  2918.   inherited ClearLists;
  2919.   if Assigned(FExplodedSlice) then FExplodedSlice.Clear;
  2920. end;
  2921.  
  2922. Procedure TPieSeries.PrepareLegendCanvas( ValueIndex:Longint; Var BackColor:TColor;
  2923.                                           Var BrushStyle:TBrushStyle);
  2924. Begin
  2925.   inherited PrepareLegendCanvas(ValueIndex,BackColor,BrushStyle);
  2926.   if FUsePatterns then BrushStyle:=GetDefaultPattern(ValueIndex);
  2927. end;
  2928.  
  2929. Procedure TPieSeries.GalleryChanged3D(Is3D:Boolean);
  2930. begin
  2931.   inherited GalleryChanged3D(Is3D);
  2932.   DisableRotation;
  2933. end;
  2934.  
  2935. Procedure TPieSeries.FillSampleValues(NumValues:Longint);
  2936. Const PieSampleStr:Array[0..7] of String=
  2937.          ( TeeMsg_PieSample1,TeeMsg_PieSample2,TeeMsg_PieSample3,
  2938.            TeeMsg_PieSample4,TeeMsg_PieSample5,TeeMsg_PieSample6,
  2939.            TeeMsg_PieSample7,TeeMsg_PieSample8);
  2940.  
  2941. var t : Longint;
  2942. Begin
  2943.   Clear;
  2944.   for t:=0 to NumValues-1 do
  2945.       Add( 1+Random(ChartSamplesMax), { <-- Value }
  2946.            PieSampleStr[t mod 8]      { <-- Label }
  2947. {$IFNDEF D4},clTeeColor{$ENDIF} );    { <-- Color }
  2948.   RefreshSeries;
  2949. end;
  2950.  
  2951. Function TPieSeries.CalcClickedPie(x,y:Integer):Longint;
  2952. Var tmpAngle : Double;
  2953.     t        : Longint;
  2954.     tmpOffX  : Integer;
  2955.     tmpOffY  : Integer;
  2956. Begin
  2957.   result:=TeeNoPointClicked;
  2958.   if (ParentChart<>nil) then ParentChart.Canvas.Calculate2DPosition(x,y,0);
  2959.   tmpAngle:=PointToAngle(x,y);
  2960.   for t:=0 to Count-1 do
  2961.   begin
  2962.     CalcExplodedOffset(t,tmpOffX,tmpOffY);
  2963.     if (Abs(x-FCircleXCenter)<(FXRadius+tmpOffX)) and
  2964.        (Abs(y-FCircleYCenter)<(FYRadius+tmpOffY)) then
  2965.     With FAngles.Angle[t] do
  2966.     if (tmpAngle>=StartAngle) and (tmpAngle<=EndAngle) then
  2967.     Begin
  2968.       result:=t;
  2969.       Exit;
  2970.     end;
  2971.   end;
  2972. end;
  2973.  
  2974. Function TPieSeries.Clicked(x,y:Integer):Longint;
  2975. begin
  2976.   result:=inherited Clicked(x,y);
  2977.   if result=TeeNoPointClicked then result:=CalcClickedPie(x,y);
  2978. end;
  2979.  
  2980. Function TPieSeries.CountLegendItems:Integer;
  2981. var t : Integer;
  2982. begin
  2983.   result:=Count;
  2984.   for t:=0 to Count-1 do if BelongsToOtherSlice(t) then Dec(result);
  2985. end;
  2986.  
  2987. Function TPieSeries.LegendToValueIndex(LegendIndex:Integer):Integer;
  2988. var Num : Integer;
  2989.     t   : Integer;
  2990. begin
  2991.   result:=LegendIndex;
  2992.   Num:=-1;
  2993.   for t:=0 to Count-1 do
  2994.   if not BelongsToOtherSlice(t) then
  2995.   begin
  2996.     Inc(Num);
  2997.     if Num=LegendIndex then
  2998.     begin
  2999.       result:=t;
  3000.       break;
  3001.     end;
  3002.   end;
  3003. end;
  3004.  
  3005. Function TPieSeries.BelongsToOtherSlice(ValueIndex:Integer):Boolean;
  3006. begin
  3007.   result:=XValues[ValueIndex]=TeePieBelongsToOther;
  3008. end;
  3009.  
  3010. Procedure TPieSeries.CalcAngles;
  3011. Var tmpSumAbs : Double;
  3012.     AcumValue : Double;
  3013.     PiPortion : Double;
  3014.     t         : Longint;
  3015. Begin
  3016.   AcumValue:=0;
  3017.   tmpSumAbs:=YValues.TotalAbs;
  3018.   if tmpSumAbs<>0 then PiPortion:=TwoPi/tmpSumAbs
  3019.                   else PiPortion:=0;
  3020.   FreePieAngles;
  3021.   for t:=0 to Count-1 do
  3022.   begin
  3023.     FAngles.Add(TPieAngle.Create);
  3024.     With FAngles.Angle[t] do
  3025.     Begin
  3026.       if t=0 then StartAngle:=0 else StartAngle:=FAngles.Angle[t-1].EndAngle;
  3027.       if tmpSumAbs<>0 then
  3028.       Begin
  3029.         if not BelongsToOtherSlice(t) then
  3030.            AcumValue:=AcumValue+Abs(YValue[t]);
  3031.         if AcumValue=tmpSumAbs then EndAngle:=TwoPi
  3032.                                else EndAngle:=AcumValue*PiPortion;
  3033.         { prevent small pie sectors }
  3034.         if (EndAngle-StartAngle)>TwoPi then EndAngle:=StartAngle+TwoPi;
  3035.       end
  3036.       else EndAngle:=TwoPi;
  3037.       MidAngle:=(StartAngle+EndAngle)*0.5;
  3038.     end;
  3039.   end;
  3040. end;
  3041.  
  3042. Procedure TPieSeries.CalcExplodedRadius(ValueIndex:Integer; Var AXRadius,AYRadius:Integer);
  3043. var tmpExp : Double;
  3044. begin
  3045.   tmpExp:=1.0+FExplodedSlice.Value[ValueIndex]*0.01;
  3046.   AXRadius:=Round(FXRadius*tmpExp);
  3047.   AYRadius:=Round(FYRadius*tmpExp);
  3048. end;
  3049.  
  3050. Procedure TPieSeries.DrawMark( ValueIndex:Longint; Const St:String;
  3051.                                APosition:TSeriesMarkPosition);
  3052. var tmpXRadius : Integer;
  3053.     tmpYRadius : Integer;
  3054. Begin
  3055.   if not BelongsToOtherSlice(ValueIndex) then
  3056.   begin
  3057.     With ParentChart,FAngles.Angle[ValueIndex] do
  3058.     begin
  3059.       CalcExplodedRadius(ValueIndex,tmpXRadius,tmpYRadius);
  3060.  
  3061.       With APosition do
  3062.       begin
  3063.         AngleToPos( MidAngle,
  3064.                     tmpXRadius+Canvas.TextWidth(TeeCharForHeight)+Marks.ArrowLength,
  3065.                     tmpYRadius+Canvas.FontHeight+Marks.ArrowLength,
  3066.                     ArrowTo.X,ArrowTo.Y );
  3067.  
  3068.         AngleToPos( MidAngle,tmpXRadius,tmpYRadius,ArrowFrom.X,ArrowFrom.Y );
  3069.  
  3070.         With ArrowTo do
  3071.         begin
  3072.           if X>FCircleXCenter then LeftTop.X:=X
  3073.                               else LeftTop.X:=X-Width;
  3074.           if Y>FCircleYCenter then LeftTop.Y:=Y
  3075.                               else LeftTop.Y:=Y-Height;
  3076.         end;
  3077.       end;
  3078.     end;
  3079.     Marks.ZPosition:=EndZ;
  3080.     inherited DrawMark(ValueIndex,St,APosition);
  3081.   end;
  3082. end;
  3083.  
  3084. procedure TPieSeries.DrawAllValues;
  3085. Var SortedSlice:Array[0..1024] of Integer;
  3086.     j : Integer;
  3087.     x : Integer;
  3088.  
  3089.   Function CompareSliceAngle(A,B:Integer):Integer;
  3090.  
  3091.     Function GetAngleSlice(Index:Integer):Double;
  3092.     begin
  3093.       result:=FAngles.Angle[Index].MidAngle+IRotDegree;
  3094.       if result>TwoPi then result:=result-TwoPi;
  3095.       if result>HalfPi then
  3096.       begin
  3097.         result:=result-HalfPi;
  3098.         if result>Pi then result:=TwoPi-result;
  3099.       end
  3100.       else result:=HalfPi-result;
  3101.     end;
  3102.  
  3103.   Var tmpA : Double;
  3104.       tmpB : Double;
  3105.   begin
  3106.     tmpA:=GetAngleSlice(SortedSlice[A]);
  3107.     tmpB:=GetAngleSlice(SortedSlice[B]);
  3108.     if tmpA<tmpB then result:=-1 else
  3109.     if tmpA>tmpB then result:= 1 else result:= 0;
  3110.   end;
  3111.  
  3112.   procedure SortSlices(l,r:longint);
  3113.   var i : Longint;
  3114.   begin
  3115.     i:=l;
  3116.     j:=r;
  3117.     x:=(i+j) shr 1;
  3118.     while i<j do
  3119.     begin
  3120.       while CompareSliceAngle(i,x)<0 do Inc(i);
  3121.       while CompareSliceAngle(x,j)<0 do Dec(j);
  3122.       if i<j then
  3123.       begin
  3124.         SwapInteger(SortedSlice[i],SortedSlice[j]);
  3125.         if i=x then x:=j else if j=x then x:=i;
  3126.       end;
  3127.       if i<=j then
  3128.       begin
  3129.         inc(i);
  3130.         dec(j)
  3131.       end;
  3132.     end;
  3133.     if l<j then SortSlices(l,j);
  3134.     if i<r then SortSlices(i,r);
  3135.   end;
  3136.  
  3137. var t                : Integer;
  3138.     tmpCount         : Integer;
  3139.     MaxExploded      : Integer;
  3140.     MaxExplodedIndex : Integer;
  3141.     tmpOffX          : Integer;
  3142.     tmpOffY          : Integer;
  3143. begin
  3144.   if FExplodeBiggest>0 then CalcExplodeBiggest;
  3145.   MaxExplodedIndex:=-1;
  3146.   MaxExploded:=0;
  3147.   tmpCount:=Count-1;
  3148.   { calc biggest exploded index }
  3149.   for t:=0 to tmpCount do
  3150.   if FExplodedSlice.Value[t]>MaxExploded then
  3151.   begin
  3152.     MaxExploded:=Round(FExplodedSlice.Value[t]);
  3153.     MaxExplodedIndex:=t;
  3154.   end;
  3155.   { calc each slice angles }
  3156.   CalcAngles;
  3157.   { adjust circle rectangle }
  3158.   IsExploded:=MaxExplodedIndex<>-1;
  3159.   if IsExploded then
  3160.   begin
  3161.     CalcExplodedOffset(MaxExplodedIndex,tmpOffX,tmpOffY);
  3162.     InflateRect(FCircleRect,-Abs(tmpOffX) div 2,-Abs(tmpOffY) div 2);
  3163.     AdjustCircleRect;
  3164.     CalcRadius;
  3165.   end;
  3166.   { start xy pos }
  3167.   AngleToPos(0,FXRadius,FYRadius,iniX,iniY);
  3168.  
  3169.   { exploded slices drawing order... }
  3170.   if ParentChart.View3D and IsExploded then
  3171.   begin
  3172.     for t:=0 to tmpCount do SortedSlice[t]:=t;
  3173.     SortSlices(0,tmpCount);
  3174.     for t:=0 to tmpCount do DrawValue(SortedSlice[t]);
  3175.   end
  3176.   else inherited DrawAllValues;
  3177. end;
  3178.  
  3179. Procedure TPieSeries.DrawPie(ValueIndex:Integer);
  3180. var tmpOffX : Integer;
  3181.     tmpOffY : Integer;
  3182. Begin
  3183.   ParentChart.Canvas.AssignVisiblePen(PiePen);
  3184.   CalcExplodedOffset(ValueIndex,tmpOffX,tmpOffY);
  3185.   With FAngles.Angle[ValueIndex] do
  3186.   with ParentChart,Canvas do { Draw pie slice }
  3187.   if View3D then
  3188.   begin
  3189.     if SupportsFullRotation then tmpOffX:=-tmpOffX;
  3190.     Pie3D( FCircleXCenter+tmpOffX,
  3191.            FCircleYCenter-tmpOffY,
  3192.            FXRadius,FYRadius,
  3193.            StartZ,EndZ,
  3194.            StartAngle+IRotDegree,EndAngle+IRotDegree,
  3195.            FDark3D,
  3196.            IsExploded)
  3197.   end
  3198.   else
  3199.   begin
  3200.      AngleToPos(EndAngle,FXRadius,FYRadius,endX,endY);
  3201.      if ((IniX<>EndX) or (IniY<>EndY)) or (Count=1) or
  3202.        ( (Count>1) and (EndAngle-StartAngle>1))  then { bug win32 api }
  3203.      begin
  3204.        With FCircleRect do
  3205.          Pie( Left + tmpOffX,Top   -tmpOffY,
  3206.               Right+ tmpOffX,Bottom-tmpOffY,
  3207.               IniX + tmpOffX,IniY  -tmpOffY,
  3208.               EndX + tmpOffX,EndY  -tmpOffY);
  3209.        IniX:=EndX;
  3210.        IniY:=EndY;
  3211.      end;
  3212.   end;
  3213. end;
  3214.  
  3215. Procedure TPieSeries.CalcExplodedOffset( ValueIndex:Integer;
  3216.                                          Var OffsetX,OffsetY:Integer);
  3217. var tmpExp : Double;
  3218.     tmpSin : Extended;
  3219.     tmpCos : Extended;
  3220. begin
  3221.   OffsetX :=0;
  3222.   OffsetY :=0;
  3223.   if IsExploded then
  3224.   begin
  3225.     tmpExp:=FExplodedSlice.Value[ValueIndex];
  3226.     if tmpExp>0 then
  3227.     begin { Apply exploded % to radius }
  3228.       SinCos(FAngles.Angle[ValueIndex].MidAngle+IRotDegree,tmpSin,tmpCos);
  3229.       tmpExp:=tmpExp*0.01;
  3230.       OffsetX:=Round((FXRadius*tmpExp)*tmpCos);
  3231.       OffsetY:=Round((FYRadius*tmpExp)*tmpSin);
  3232.     end;
  3233.   end;
  3234. end;
  3235.  
  3236. Procedure TPieSeries.CalcExplodeBiggest;
  3237. var tmp : Longint;
  3238. begin
  3239.   With YValues do tmp:=Locate(MaxValue);
  3240.   if tmp<>-1 then FExplodedSlice.Value[tmp]:=FExplodeBiggest;
  3241. end;
  3242.  
  3243. procedure TPieSeries.SetExplodeBiggest(Value:Integer);
  3244. begin
  3245.   SetIntegerProperty(FExplodeBiggest,Value);
  3246.   CalcExplodeBiggest;
  3247. end;
  3248.  
  3249. procedure TPieSeries.SetPiePen(Value:TChartPen);
  3250. begin
  3251.   FPiePen.Assign(Value);
  3252. end;
  3253.  
  3254. procedure TPieSeries.SetOtherSlice(Value:TPieOtherSlice);
  3255. begin
  3256.   FOtherSlice.Assign(Value);
  3257. end;
  3258.  
  3259. Procedure TPieSeries.DrawValue(ValueIndex:Longint);
  3260. var tmpStyle : TBrushStyle;
  3261. Begin
  3262.   if (FCircleWidth>4) and (FCircleHeight>4) then
  3263.   if not BelongsToOtherSlice(ValueIndex) then
  3264.   begin
  3265.     { Slice pattern }
  3266.     if FUsePatterns then tmpStyle:=GetDefaultPattern(ValueIndex)
  3267.                     else tmpStyle:=bsSolid;
  3268.     { Set slice back color }
  3269.     ParentChart.SetBrushCanvas(ValueColor[ValueIndex],tmpStyle,CalcCircleBackColor);
  3270.     DrawPie(ValueIndex);
  3271.   end;
  3272. end;
  3273.  
  3274. procedure TPieSeries.SetUsePatterns(Value:Boolean);
  3275. Begin
  3276.   SetBooleanProperty(FUsePatterns,Value);
  3277. end;
  3278.  
  3279. Function TPieSeries.GetEditorClass:String;
  3280. Begin
  3281.   result:='TPieSeriesEditor'; { <-- dont translate ! }
  3282. end;
  3283.  
  3284. Function TPieSeries.GetPieValues:TChartValueList;
  3285. Begin
  3286.   result:=YValues;
  3287. end;
  3288.  
  3289. Procedure TPieSeries.SetPieValues(Value:TChartValueList);
  3290. Begin
  3291.   SetYValues(Value);
  3292. end;
  3293.  
  3294. Procedure TPieSeries.SetDark3d(Value:Boolean);
  3295. Begin
  3296.   SetBooleanProperty(FDark3d,Value);
  3297. End;
  3298.  
  3299. Function TPieSeries.MaxXValue:Double;
  3300. Begin
  3301.   result:=GetHorizAxis.Maximum;
  3302. End;
  3303.  
  3304. Function TPieSeries.MinXValue:Double;
  3305. Begin
  3306.   result:=GetHorizAxis.Minimum;
  3307. End;
  3308.  
  3309. Function TPieSeries.MaxYValue:Double;
  3310. Begin
  3311.   result:=GetVertAxis.Maximum;
  3312. End;
  3313.  
  3314. Function TPieSeries.MinYValue:Double;
  3315. Begin
  3316.   result:=GetVertAxis.Minimum;
  3317. End;
  3318.  
  3319. Procedure TPieSeries.DisableRotation;
  3320. begin
  3321.   With ParentChart.View3DOptions do
  3322.   begin
  3323.     Orthogonal:=False;
  3324.     Rotation:=0;
  3325.     Elevation:=305;
  3326.   end;
  3327. end;
  3328.  
  3329. Procedure TPieSeries.PrepareForGallery(IsEnabled:Boolean);
  3330. Begin
  3331.   inherited PrepareForGallery(IsEnabled);
  3332.   FillSampleValues(8);
  3333.   ParentChart.Chart3DPercent:=75;
  3334.   Circled:=not ParentChart.View3D;
  3335.   DisableRotation;
  3336.   ColorEachPoint:=IsEnabled;
  3337. end;
  3338.  
  3339. Procedure TPieSeries.Assign(Source:TPersistent);
  3340. begin
  3341.   if Source is TPieSeries then
  3342.   With TPieSeries(Source) do
  3343.   begin
  3344.     Self.FDark3d        :=FDark3D;
  3345.     Self.FUsePatterns   :=FUsePatterns;
  3346.     Self.FPiePen.Assign(FPiePen);
  3347.     Self.FExplodeBiggest:=FExplodeBiggest;
  3348.     Self.FOtherSlice.Assign(FOtherSlice);
  3349.   end;
  3350.   inherited Assign(Source);
  3351.   ColorEachPoint:=True;
  3352. end;
  3353.  
  3354. Function TPieSeries.AddPie( Const AValue:Double;
  3355.                             Const ALabel:String; AColor:TColor):Longint;
  3356. begin
  3357.   result:=Add(AValue,ALabel,AColor);
  3358. end;
  3359.  
  3360. procedure TPieSeries.DoBeforeDrawChart;
  3361. var t        : Integer;
  3362.     tmp      : Double;
  3363.     tmpValue : Double;
  3364. begin
  3365.   { re-order values }
  3366.   With PieValues do if Order<>loNone then Sort;
  3367.   { remove "other" slice, if exists... }
  3368.   for t:=0 to Count-1 do
  3369.   if XValues.Value[t]=TeePieOtherFlag then
  3370.   begin
  3371.     Delete(t);
  3372.     Break;
  3373.   end;
  3374.   { reset X order... }
  3375.   XValues.FillSequence;
  3376.   { calc "Other" slice... }
  3377.   if FOtherSlice.Style<>poNone then
  3378.   Begin
  3379.     tmpValue:=0;
  3380.     for t:=0 to Count-1 do
  3381.     begin
  3382.       tmp:=YValues.Value[t];
  3383.       if FOtherSlice.Style=poBelowPercent then tmp:=tmp*100.0/YValues.TotalAbs;
  3384.       if tmp<FOtherSlice.Value then
  3385.       begin
  3386.         tmpValue:=tmpValue+YValues.Value[t];
  3387.         XValues.Value[t]:=TeePieBelongsToOther; { <-- belongs to "other" }
  3388.       end;
  3389.     end;
  3390.     { Add "Other" slice }
  3391.     if tmpValue<>0 then
  3392.     begin
  3393.       AddXY(TeePieOtherFlag,tmpValue,FOtherSlice.Text {$IFNDEF D4},clTeeColor{$ENDIF});
  3394.       With YValues do TotalABS:=TotalABS-tmpValue; { reset Y total }
  3395.     end;
  3396.   end;
  3397. end;
  3398.  
  3399. procedure TPieSeries.SwapValueIndex(a,b:Longint);
  3400. begin
  3401.   inherited SwapValueIndex(a,b);
  3402.   With FExplodedSlice do
  3403.   begin
  3404.     While Self.Count>Count do SetValue(Count,0);
  3405.     Exchange(a,b);
  3406.   end;
  3407. end;
  3408.  
  3409. { TFastLineSeries }
  3410. Constructor TFastLineSeries.Create(AOwner: TComponent);
  3411. Begin
  3412.   inherited Create(AOwner);
  3413.   FLinePen:=CreateChartPen;
  3414.   AllowSinglePoint:=False;
  3415.   DrawBetweenPoints:=True;
  3416.   FAutoRepaint:=True;
  3417. End;
  3418.  
  3419. Destructor TFastLineSeries.Destroy;
  3420. Begin
  3421.   FLinePen.Free;
  3422.   inherited Destroy;
  3423. End;
  3424.  
  3425. Procedure TFastLineSeries.SetLinePen(Value:TChartPen);
  3426. Begin
  3427.   FLinePen.Assign(Value);
  3428.   SeriesColor:=FLinePen.Color;
  3429. End;
  3430.  
  3431. Procedure TFastLineSeries.NotifyNewValue(Sender:TChartSeries; ValueIndex:Longint);
  3432. {$IFNDEF TEEOCX}
  3433. Var tmpIndex : Longint;
  3434. {$ENDIF}
  3435. begin
  3436.   if AutoRepaint then inherited NotifyNewValue(Sender,ValueIndex)
  3437.   {$IFNDEF TEEOCX}
  3438.   else
  3439.   begin
  3440.     With ParentChart,Canvas do
  3441.     begin
  3442.       Pen.Assign(FLinePen);
  3443.       if ValueIndex=0 then tmpIndex:=0
  3444.                       else tmpIndex:=Pred(ValueIndex);
  3445.       if View3D then
  3446.          MoveTo3D(CalcXPos(tmpIndex),CalcYPos(tmpIndex),MiddleZ)
  3447.       else
  3448.          MoveTo(CalcXPos(tmpIndex),CalcYPos(tmpIndex));
  3449.     end;
  3450.     DrawValue(ValueIndex);
  3451.   end;
  3452.   {$ENDIF}
  3453. end;
  3454.  
  3455. Function TFastLineSeries.GetEditorClass:String;
  3456. Begin
  3457.   result:='TFastLineSeriesEditor'; { <-- dont translate ! }
  3458. End;
  3459.  
  3460. procedure TFastLineSeries.PrepareCanvas;
  3461. Begin
  3462.   With ParentChart,Canvas do
  3463.   begin
  3464.     FLinePen.Color:=SeriesColor;
  3465.     AssignVisiblePen(FLinePen);
  3466.     CheckPenWidth(Pen);
  3467.     Brush.Style:=bsClear;
  3468.   end;
  3469. end;
  3470.  
  3471. procedure TFastLineSeries.DrawAllValues;
  3472. Begin
  3473.   PrepareCanvas;
  3474.   inherited DrawAllValues;
  3475. End;
  3476.  
  3477. procedure TFastLineSeries.DrawValue(ValueIndex:Longint);
  3478. Var X     : Longint;
  3479.     Y     : Longint;
  3480.     tmpX  : Longint;
  3481.     tmpY  : Longint;
  3482.     tmp3D : Boolean;
  3483. Begin
  3484.   X:=CalcXPos(ValueIndex);
  3485.   Y:=CalcYPos(ValueIndex);
  3486.   tmp3D:=ParentChart.View3D;
  3487.   With ParentChart.Canvas do
  3488.   begin
  3489.     if ValueIndex=FirstValueIndex then
  3490.        if ValueIndex>0 then
  3491.        begin
  3492.           tmpX:=CalcXPos(ValueIndex-1);
  3493.           tmpY:=CalcYPos(ValueIndex-1);
  3494.           if tmp3D then LineWithZ(tmpX,tmpY,X,Y,MiddleZ)
  3495.                    else Line(tmpX,tmpY,X,Y)
  3496.        end
  3497.        else
  3498.        if tmp3D then MoveTo3D(X,Y,MiddleZ) else MoveTo(X,Y)
  3499.     else
  3500.        if (X<>OldX) or (Y<>OldY) then
  3501.           if tmp3D then LineTo3D(X,Y,MiddleZ) else LineTo(X,Y)
  3502.        else
  3503.           Exit;
  3504.   end;
  3505.   OldX:=X;
  3506.   OldY:=Y;
  3507. End;
  3508.  
  3509. Procedure TFastLineSeries.SetSeriesColor(AColor:TColor);
  3510. begin
  3511.   inherited SetSeriesColor(AColor);
  3512.   FLinePen.Color:=AColor;
  3513. end;
  3514.  
  3515. Procedure TFastLineSeries.DrawLegendShape(ValueIndex:Longint; Const Rect:TRect);
  3516. begin
  3517.   PrepareCanvas;
  3518.   With Rect do ParentChart.Canvas.DoHorizLine(Left,Right,(Top+Bottom) shr 1);
  3519. end;
  3520.  
  3521. Procedure TFastLineSeries.Assign(Source:TPersistent);
  3522. begin
  3523.   if Source is TFastLineSeries then
  3524.   With TFastLineSeries(Source) do
  3525.   begin
  3526.     Self.FAutoRepaint:=FAutoRepaint;
  3527.     Self.FLinePen.Assign(FLinePen);
  3528.   end;
  3529.   inherited Assign(Source);
  3530. end;
  3531.  
  3532. Function TFastLineSeries.Clicked(x,y:Integer):Longint;
  3533. var t    : Longint;
  3534.     OldX : Longint;
  3535.     OldY : Longint;
  3536.     tmpX : Longint;
  3537.     tmpY : Longint;
  3538.     P    : TPoint;
  3539. begin
  3540.   result:=TeeNoPointClicked;
  3541.   if (FirstValueIndex>-1) and (LastValueIndex>-1) then
  3542.   begin
  3543.     if (ParentChart<>nil) then ParentChart.Canvas.Calculate2DPosition(X,Y,MiddleZ);
  3544.     OldX:=0;
  3545.     OldY:=0;
  3546.     P.X:=X;
  3547.     P.Y:=Y;
  3548.     for t:=FirstValueIndex to LastValueIndex do
  3549.     begin
  3550.       tmpX:=CalcXPos(t);
  3551.       tmpY:=CalcYPos(t);
  3552.       if (tmpX=X) and (tmpY=Y) then { clicked right on point }
  3553.       begin
  3554.         result:=t;
  3555.         break;
  3556.       end
  3557.       else
  3558.       if (t>FirstValueIndex) and PointInLine(P,tmpX,tmpY,OldX,OldY) then
  3559.       begin
  3560.         result:=t-1;
  3561.         break;
  3562.       end;
  3563.       OldX:=tmpX;
  3564.       OldY:=tmpY;
  3565.     end;
  3566.   end;
  3567. end;
  3568.  
  3569. Procedure TFastLineSeries.DrawMark( ValueIndex:Longint; Const St:String;
  3570.                                     APosition:TSeriesMarkPosition);
  3571. var tmp : Integer;
  3572. begin
  3573.   tmp:=Marks.ArrowLength;
  3574.   With APosition do
  3575.   begin
  3576.     Dec(ArrowTo.Y,tmp);
  3577.     Dec(LeftTop.Y,tmp);
  3578.   end;
  3579.   inherited DrawMark(ValueIndex,St,APosition);
  3580. end;
  3581.  
  3582. Procedure RegisterStandardSeries;
  3583. begin
  3584.   RegisterTeeSeries(TLineSeries,    TeeMsg_GalleryLine,    TeeMsg_GalleryStandard,2);
  3585.   RegisterTeeSeries(TBarSeries,     TeeMsg_GalleryBar,     TeeMsg_GalleryStandard,2);
  3586.   RegisterTeeSeries(THorizBarSeries,TeeMsg_GalleryHorizBar,TeeMsg_GalleryStandard,2);
  3587.   RegisterTeeSeries(TAreaSeries,    TeeMsg_GalleryArea,    TeeMsg_GalleryStandard,2);
  3588.   RegisterTeeSeries(TPointSeries,   TeeMsg_GalleryPoint,   TeeMsg_GalleryStandard,2);
  3589.   RegisterTeeSeries(TPieSeries,     TeeMsg_GalleryPie,     TeeMsg_GalleryStandard,1);
  3590.   RegisterTeeSeries(TFastLineSeries,TeeMsg_GalleryFastLine,TeeMsg_GalleryStandard,2);
  3591. end;
  3592.  
  3593. initialization
  3594.   RegisterStandardSeries;
  3595. end.
  3596.  
  3597.