TeEngine.pas
Upload User: waiaoji
Upload Date: 2010-04-10
Package Size: 2693k
Code Size: 341k
Category:

Delphi VCL

Development Platform:

Delphi

  1. {********************************************}
  2. {  TeeChart Pro Charting Library             }
  3. {  For Borland Delphi, C++ Builder & Kylix   }
  4. {  Copyright (c) 1995-2005 by David Berneda  }
  5. {  All Rights Reserved                       }
  6. {********************************************}
  7. unit TeEngine;
  8. {$I TeeDefs.inc}
  9. interface
  10. uses {$IFNDEF LINUX}
  11.      Windows,
  12.      Messages,
  13.      {$ENDIF}
  14.      SysUtils, Classes, 
  15.      {$IFDEF CLX}
  16.      QGraphics, QControls, QDialogs, Types,
  17.      {$ELSE}
  18.      Graphics, Controls,
  19.      {$ENDIF}
  20.      {$IFDEF TEETRIAL}
  21.      TeeAbout,
  22.      {$ENDIF}
  23.      {$IFDEF CLR}
  24.      System.ComponentModel,
  25.      {$ENDIF}
  26.      TeeProcs, TeCanvas;
  27. Const ChartMarkColor   = clInfoBk (* $80FFFF *);  { default Series Mark back color }
  28.       MinAxisIncrement :Double = 0.000000000001;  { <-- "double" for BCB }
  29.       MinAxisRange     :Double = 0.0000000001;    { <-- "double" for BCB }
  30.       TeeAllValues     = -1;
  31.       {$IFDEF D6}
  32.       clTeeColor       =TColor(clDefault);
  33.       {$ELSE}
  34.       clTeeColor       =TColor($20000000);
  35.       {$ENDIF}
  36.       ChartSamplesMax   = 1000;
  37.       TeeAutoZOrder     = -1;
  38.       TeeAutoDepth      = -1;
  39.       TeeNoPointClicked = -1;
  40.       TeeDef3DPercent   = 15;
  41.       TeeColumnSeparator: {$IFDEF CLR}Char{$ELSE}AnsiChar{$ENDIF} = #6;  // To separate columns in Legend
  42.       TeeLineSeparator  : {$IFDEF CLR}Char{$ELSE}AnsiChar{$ENDIF} = #13; // To separate lines of text
  43.       // Index of first custom axis (0 to 5 are pre-created axes: Left,Top,
  44.       // Right,Bottom,Depth and DepthTop.
  45.       TeeInitialCustomAxis = 6;
  46. var   TeeCheckMarkArrowColor : Boolean=False; // when True, the Marks arrow pen
  47.                                               // color is changed if the point has
  48.                                               // the same color.
  49.       TeeRandomAtRunTime     : Boolean=False; // adds random values at run-time too
  50.       clTeeGallery1:Integer = 0; // index of ColorPalette[] global variable
  51.       clTeeGallery2:Integer = 3; // index of ColorPalette[] global variable
  52. type
  53.   TCustomAxisPanel=class;
  54.   {$IFDEF CLR}
  55.   [ToolBoxItem(False)]
  56.   {$ENDIF}
  57.   TCustomChartElement=class(TComponent)
  58.   private
  59.     FActive : Boolean;
  60.     FBrush  : TChartBrush;
  61.     FParent : TCustomAxisPanel;
  62.     FPen    : TChartPen;
  63.   protected
  64.     InternalUse : Boolean;  // 7.0
  65.     Procedure CanvasChanged(Sender:TObject); virtual;
  66.     Function CreateChartPen:TChartPen;
  67.     class Function GetEditorClass:String; virtual;
  68.     Procedure SetActive(Value:Boolean); virtual;
  69.     Procedure SetBooleanProperty(Var Variable:Boolean; Value:Boolean); {$IFDEF D9}inline;{$ENDIF}
  70.     procedure SetBrush(const Value: TChartBrush);
  71.     Procedure SetColorProperty(Var Variable:TColor; Value:TColor);
  72.     Procedure SetDoubleProperty(Var Variable:Double; Const Value:Double);
  73.     Procedure SetIntegerProperty(Var Variable:Integer; Value:Integer);
  74.     Procedure SetParentChart(Const Value:TCustomAxisPanel); virtual;
  75.     {$IFNDEF CLR}
  76.     procedure SetParentComponent(AParent: TComponent); override;
  77.     {$ENDIF}
  78.     procedure SetPen(const Value: TChartPen); virtual;
  79.     Procedure SetStringProperty(Var Variable:String; Const Value:String);
  80.   public
  81.     Constructor Create(AOwner: TComponent); override;
  82.     Destructor Destroy; override;
  83.     procedure Assign(Source:TPersistent); override;
  84.     class Function EditorClass:String;  // 7.01 returns class name of editor form
  85.     Function GetParentComponent: TComponent; override;
  86.     Function HasParent:Boolean; override;
  87.     {$IFDEF CLR}
  88.     procedure SetParentComponent(AParent: TComponent); override;
  89.     {$ENDIF}
  90.     Procedure Repaint;
  91.     property Active:Boolean read FActive write SetActive default True;
  92.     property Brush:TChartBrush read FBrush write SetBrush;
  93.     property ParentChart:TCustomAxisPanel read FParent write SetParentChart stored False;
  94.     property Pen:TChartPen read FPen write SetPen;
  95.     // Alias for Active property.
  96.     property Visible:Boolean read FActive write SetActive default True;
  97.   end;
  98.   TCustomChartSeries=class;
  99.   TChartSeries=class;
  100.   {$IFDEF TEEVALUESINGLE}
  101.   TChartValue=Single;
  102.   {$ELSE}
  103.   {$IFDEF TEEVALUEDOUBLE}
  104.   TChartValue=Double;
  105.   {$ELSE}
  106.   {$IFDEF TEEVALUEEXTENDED}
  107.   TChartValue=Extended;
  108.   {$ELSE}
  109.   TChartValue=Double;  { <-- default }
  110.   {$ENDIF}
  111.   {$ENDIF}
  112.   {$ENDIF}
  113.   {$IFDEF TEEARRAY}
  114.   TChartValues=Array of TChartValue;
  115.   {$ELSE}
  116.   PChartValue=^TChartValue;
  117.   {$ENDIF}
  118.   TChartListOrder=(loNone,loAscending,loDescending);
  119.   // CLR: cannot be sealed due to cast tricks
  120.   TChartValueList=class(TPersistent)
  121.   private
  122.     FDateTime    : Boolean;
  123.     {$IFNDEF TEEARRAY}
  124.     FList        : TList;
  125.     {$ENDIF}
  126.     FMaxValue    : TChartValue;
  127.     FMinValue    : TChartValue;
  128.     {$IFDEF TEEMULTIPLIER}
  129.     FMultiplier  : Double;  { obsolete }
  130.     {$ENDIF}
  131.     FName        : String;
  132.     FOrder       : TChartListOrder;
  133.     FOwner       : TChartSeries;
  134.     FTempValue   : TChartValue;
  135.     FTotal       : Double;
  136.     FTotalABS    : Double;
  137.     FValueSource : String;
  138.     { internal }
  139.     IDefDateTime : Boolean;
  140.     {$IFOPT C+}
  141.     FCount       : Integer;
  142.     function GetCount:Integer;
  143.     procedure SetCount(const Value:Integer);
  144.     {$ENDIF}
  145.     Function CompareValueIndex(a,b:Integer):Integer;
  146.     Function GetMaxValue:TChartValue;
  147.     Function GetMinValue:TChartValue;
  148.     Function GetTotal:Double;
  149.     Function GetTotalABS:Double;
  150.     function IsDateStored: Boolean;
  151.     procedure SetDateTime(Const Value:Boolean);
  152.     {$IFDEF TEEMULTIPLIER}
  153.     Function IsMultiStored:Boolean;
  154.     Procedure SetMultiplier(Const Value:Double); { obsolete }
  155.     {$ELSE}
  156.     procedure ReadMultiplier(Reader: TReader);
  157.     {$ENDIF}
  158.     Procedure SetValueSource(Const Value:String);
  159.   protected
  160.     IData       : TObject;
  161.     Function AddChartValue:Integer; overload;
  162.     Function AddChartValue(Const AValue:TChartValue):Integer; overload; virtual;
  163.     Procedure ClearValues; virtual;
  164.     {$IFNDEF TEEMULTIPLIER}
  165.     procedure DefineProperties(Filer: TFiler); override;
  166.     {$ENDIF}
  167.     Function GetValue(ValueIndex:Integer):TChartValue;
  168.     Procedure InitDateTime(Value:Boolean);
  169.     Procedure InsertChartValue(ValueIndex:Integer; Const AValue:TChartValue); virtual;
  170.     Procedure RecalcStats; overload;
  171.     procedure RecalcStats(StartIndex:Integer); overload;
  172.     Procedure SetValue(ValueIndex:Integer; Const AValue:TChartValue);
  173.   public
  174.     {$IFDEF TEEARRAY}
  175.     Value    : TChartValues;
  176.     {$IFOPT C-}  // When not using runtime assertions
  177.     Count    : Integer;
  178.     {$ENDIF}
  179.     {$ENDIF}
  180.     Modified : Boolean;
  181.     Constructor Create(AOwner:TChartSeries; Const AName:String); virtual;
  182.     Destructor Destroy; override;
  183.     Procedure Assign(Source:TPersistent); override;
  184.     {$IFNDEF TEEARRAY}
  185.     Function Count:Integer; virtual;
  186.     {$ELSE}
  187.     {$IFOPT C+}
  188.     property Count:Integer read GetCount write SetCount;
  189.     {$ENDIF}
  190.     {$ENDIF}
  191.     Procedure Delete(ValueIndex:Integer); overload; virtual;
  192.     Procedure Delete(Start,Quantity:Integer); overload;
  193.     {$IFDEF TEEARRAY}
  194.     Procedure Exchange(Index1,Index2:Integer);
  195.     {$ENDIF}
  196.     Procedure FillSequence;
  197.     Function First:TChartValue;
  198.     Function Last:TChartValue;
  199.     Function Locate(Const AValue:TChartValue):Integer; overload;
  200.     Function Locate(Const AValue:TChartValue; FirstIndex,LastIndex:Integer):Integer; overload;  // 7.0
  201.     Function Range:TChartValue;
  202.     Procedure Scroll; dynamic;
  203.     Procedure Sort;
  204.     property MaxValue:TChartValue read GetMaxValue;
  205.     property MinValue:TChartValue read GetMinValue;
  206.     property Owner:TChartSeries read FOwner;
  207.     property TempValue:TChartValue read FTempValue write FTempValue;
  208.     Function ToString(Index:Integer):String; {$IFDEF CLR}reintroduce;{$ENDIF}
  209.     property Total:Double read GetTotal;
  210.     property TotalABS:Double read GetTotalABS write FTotalABS;
  211.     {$IFDEF TEEARRAY}
  212.     property Items[Index:Integer]:TChartValue read GetValue write SetValue; default;
  213.     {$ELSE}
  214.     property Value[Index:Integer]:TChartValue read GetValue write SetValue; default;
  215.     {$ENDIF}
  216.   published
  217.     property DateTime:Boolean read FDateTime write SetDateTime stored IsDateStored;
  218.     property Name:String read FName write FName;
  219.     {$IFDEF TEEMULTIPLIER}
  220.     property Multiplier:Double read FMultiplier write SetMultiplier stored IsMultiStored; { obsolete }
  221.     {$ENDIF}
  222.     property Order:TChartListOrder read FOrder write FOrder;
  223.     property ValueSource:String read FValueSource write SetValueSource;
  224.   end;
  225.   TChartAxisTitle=class {$IFDEF CLR}sealed{$ENDIF} (TTeeCustomShape)
  226.   private
  227.     FAngle        : Integer;
  228.     FCaption      : String;
  229.     IDefaultAngle : Integer;
  230.     Function IsAngleStored:Boolean;
  231.     Procedure SetAngle(const Value:Integer);
  232.     Procedure SetCaption(Const Value:String);
  233.   public
  234.     Procedure Assign(Source:TPersistent); override;
  235.   published
  236.     property Angle:Integer read FAngle write SetAngle stored IsAngleStored;
  237.     property Caption:String read FCaption write SetCaption;
  238.     property Font;
  239.     property Visible default True;
  240.   end;
  241.   AxisException=class {$IFDEF CLR}sealed{$ENDIF} (Exception);
  242.   TAxisLabelStyle=(talAuto,talNone,talValue,talMark,talText);
  243.   TAxisLabelAlign=(alDefault,alOpposite);
  244.   TAxisCalcPos=function(const Value:TChartValue):Integer of object;
  245.   TCustomSeriesList=class;
  246.   TAxisGridPen=class {$IFDEF CLR}sealed{$ENDIF} (TDottedGrayPen)
  247.   private
  248.     FZ : Double;
  249.     IDefaultZ : Double;
  250.     FCentered: Boolean;
  251.     function IsZStored:Boolean;
  252.     procedure SetZ(const Value:Double);
  253.     procedure SetCentered(const Value: Boolean);
  254.   public
  255.     // (pending to move Centered to "published" after removing Axis.GridCentered)
  256.     property Centered:Boolean read FCentered write SetCentered default False;
  257.   published
  258.     property ZPosition:Double read FZ write SetZ stored IsZStored;
  259.   end;
  260.   TAxisTicks=Array of Integer;
  261. //  TAxisTickValues=TChartValues;
  262.   TChartAxis=class;
  263.   TAxisItems=class;
  264.   TAxisItem=class(TTeeCustomShape)
  265.   private
  266.     FValue : Double;
  267.     FText  : String;
  268.     IAxisItems : TAxisItems;
  269.     procedure SetText(const Value: String);
  270.     procedure SetValue(const Value: Double);
  271.   public
  272.     procedure Repaint;
  273.   published
  274.     property Bevel;
  275.     property BevelWidth;
  276.     property Color;
  277.     property Font;
  278.     property Gradient;
  279.     property Shadow;
  280.     property ShapeStyle;
  281.     property Text:String read FText write SetText;
  282.     property Transparency;
  283.     property Transparent default True;
  284.     property Value:Double read FValue write SetValue;
  285.   end;
  286.   TAxisItems=class {$IFDEF CLR}sealed{$ENDIF} (TList)
  287.   private
  288.     FFormat: TTeeShape;
  289.     IAxis : TChartAxis;
  290.     function Get(Index:Integer):TAxisItem;
  291.   public
  292.     Constructor Create(Axis:TChartAxis);
  293.     Destructor Destroy; override;
  294.     Function Add(const Value: Double):TAxisItem; overload;
  295.     Function Add(const Value: Double; const Text:String):TAxisItem; overload;
  296.     Procedure CopyFrom(Source:TAxisItems);
  297.     Procedure Clear; override;
  298.     property Format:TTeeShape read FFormat;
  299.     property Item[Index:Integer]:TAxisItem read Get; default;
  300.   end;
  301.   TChartAxisPen=class {$IFDEF CLR}sealed{$ENDIF} (TChartPen)
  302.   private
  303.   public
  304.     Constructor Create(OnChangeEvent:TNotifyEvent);
  305.   published
  306.     property Width default 2;
  307.   end;
  308.   TAxisDrawLabelEvent=procedure(Sender:TChartAxis; var X,Y,Z:Integer; var Text:String;
  309.                                 var DrawLabel:Boolean) of object;
  310.   // internal event, used at TGridBandTool class (only)
  311.   TAxisDrawGrids=procedure(Sender:TChartAxis) of object;
  312.   TChartAxis=class(TCollectionItem)
  313.   private
  314.     { scales }
  315.     FAutomatic        : Boolean;
  316.     FAutomaticMaximum : Boolean;
  317.     FAutomaticMinimum : Boolean;
  318.     FDesiredIncrement : Double;
  319.     FMaximumValue     : Double;
  320.     FMinimumValue     : Double;
  321.     FLogarithmic      : Boolean;
  322.     FLogarithmicBase  : Double; // 6.0
  323.     FMaximumOffset    : Integer;
  324.     FMinimumOffset    : Integer;
  325.     { axis }
  326.     FAxis             : TChartAxisPen;
  327.     FPosAxis          : Integer;
  328.     FZPosition        : Double;
  329.     { title }
  330.     FAxisTitle        : TChartAxisTitle;
  331.     FTitleSize        : Integer;
  332.     FPosTitle         : Integer;
  333.     { grid }
  334.     FGrid             : TAxisGridPen;
  335.     { labels }
  336.     FLabelsAlign      : TAxisLabelAlign;
  337.     FLabelsAlternate  : Boolean;
  338.     FLabelsAngle      : Integer;
  339.     FItems            : TAxisItems;
  340.     FLabelsOnAxis     : Boolean;
  341.     FLabelsSeparation : Integer;
  342.     FLabelsSize       : Integer;
  343.     FLabelStyle       : TAxisLabelStyle;
  344.     FLabelsExponent   : Boolean;
  345.     FLabelsMultiLine  : Boolean;
  346.     FPosLabels        : Integer;
  347.     FAxisValuesFormat : String;
  348.     FDateTimeFormat   : String;
  349.     FExactDateTime    : Boolean;
  350.     FRoundFirstLabel  : Boolean;
  351.     { ticks }
  352.     FMinorGrid        : TChartHiddenPen;
  353.     FMinorTickCount   : Integer;
  354.     FMinorTickLength  : Integer;
  355.     FMinorTicks       : TDarkGrayPen;
  356.     FTicks            : TDarkGrayPen;
  357.     FTicksInner       : TDarkGrayPen;
  358.     FTickInnerLength  : Integer;
  359.     FTickLength       : Integer;
  360.     FTickOnLabelsOnly : Boolean;
  361.     { other }
  362.     FInverted         : Boolean;
  363.     FHorizontal       : Boolean;
  364.     FOtherSide        : Boolean;
  365.     FParentChart      : TCustomAxisPanel;
  366.     FVisible          : Boolean;
  367.     FStartPosition    : Double;
  368.     FEndPosition      : Double;
  369.     FPositionPercent  : Double;
  370.     FPosUnits         : TTeeUnits;
  371.     // Events
  372.     FOnDrawLabel      : TAxisDrawLabelEvent;
  373.     FMaster           : TChartAxis;
  374.     { internal }
  375.     IAxisDateTime     : Boolean;
  376.     IAxisLogSizeRange : TChartValue;
  377.     IAxisSizeRange    : TChartValue;
  378.     ICenterPos        : Integer;
  379.     IDepthAxis        : Boolean;
  380.     ILogMax           : Double;
  381.     ILogMin           : Double;
  382.     IMaximum          : Double;
  383.     IMinimum          : Double;
  384.     IRange            : TChartValue;
  385.     IRangeLog         : Double;
  386.     IRangeZero        : Boolean;
  387.     ISeriesList       : TCustomSeriesList;
  388.     IsVisible         : Boolean;
  389.     IZPos             : Integer;
  390.     Function DepthAxisAlign:Integer;
  391.     Function DepthAxisPos:Integer;
  392.     Function RoundLogPower(const Value:Double):Double;
  393.     Procedure SetAutomatic(Value:Boolean);
  394.     Procedure SetAutomaticMinimum(Value:Boolean);
  395.     Procedure SetAutomaticMaximum(Value:Boolean);
  396.     Procedure SetAutoMinMax(Var Variable:Boolean; Var2,Value:Boolean);
  397.     Procedure SetAxis(Value:TChartAxisPen);
  398.     procedure SetAxisTitle(Value:TChartAxisTitle);
  399.     Procedure SetDateTimeFormat(Const Value:String);
  400.     Procedure SetDesiredIncrement(Const Value:Double);
  401.     Procedure SetExactDateTime(Value:Boolean);
  402.     Procedure SetGrid(Value:TAxisGridPen);
  403.     procedure SetGridCentered(Value:Boolean);
  404.     Procedure SetLabels(Value:Boolean);
  405.     Procedure SetLabelsAlign(Value:TAxisLabelAlign);
  406.     Procedure SetLabelsAlternate(Value:Boolean);
  407.     Procedure SetLabelsAngle(const Value:Integer);
  408.     Procedure SetLabelsFont(Value:TTeeFont);
  409.     Procedure SetLabelsMultiLine(Value:Boolean);
  410.     Procedure SetLabelsOnAxis(Value:Boolean);
  411.     Procedure SetLabelsSeparation(Value:Integer);
  412.     Procedure SetLabelsSize(Value:Integer);
  413.     Procedure SetLabelStyle(Value:TAxisLabelStyle);
  414.     Procedure SetLogarithmic(Value:Boolean);
  415.     Procedure SetLogarithmicBase(const Value:Double);
  416.     Procedure SetMaximum(Const Value:Double);
  417.     Procedure SetMinimum(Const Value:Double);
  418.     Procedure SetMinorGrid(Value:TChartHiddenPen);
  419.     Procedure SetMinorTickCount(Value:Integer);
  420.     Procedure SetMinorTickLength(Value:Integer);
  421.     Procedure SetMinorTicks(Value:TDarkGrayPen);
  422.     procedure SetStartPosition(Const Value:Double);
  423.     procedure SetEndPosition(Const Value:Double);
  424.     procedure SetPositionPercent(Const Value:Double);
  425.     procedure SetPosUnits(const Value: TTeeUnits);
  426.     procedure SetRoundFirstLabel(Value:Boolean);
  427.     Procedure SetTickLength(Value:Integer);
  428.     Procedure SetTickInnerLength(Value:Integer);
  429.     Procedure SetTicks(Value:TDarkGrayPen);
  430.     Procedure SetTicksInner(Value:TDarkGrayPen);
  431.     procedure SetTickOnLabelsOnly(Value:Boolean);
  432.     Procedure SetTitleSize(Value:Integer);
  433.     Procedure SetValuesFormat(Const Value:String);
  434.     Procedure SetVisible(Value:Boolean);
  435.     Function ApplyPosition(APos:Integer; Const R:TRect):Integer;
  436.     Function CalcDateTimeIncrement(MaxNumLabels:Integer):Double;
  437.     Function CalcLabelsIncrement(MaxNumLabels:Integer):Double;
  438.     Procedure CalcRect(Var R:TRect; InflateChartRectangle:Boolean);
  439.     Function CalcZPos:Integer;
  440.     Procedure DrawGridLine(tmp:Integer);
  441.     Procedure DrawTitle(x,y:Integer);
  442.     Function GetGridCentered:Boolean;
  443.     Function GetLabels:Boolean;
  444.     Function GetLabelsFont:TTeeFont;
  445.     Function GetRectangleEdge(Const R:TRect):Integer;
  446.     Procedure IncDecDateTime( Increment:Boolean;
  447.                               Var Value:Double;
  448.                               Const AnIncrement:Double;
  449.                               tmpWhichDateTime:TDateTimeStep );
  450.     Function LogXPosValue(Const Value:TChartValue):Integer;
  451.     Function LogYPosValue(Const Value:TChartValue):Integer;
  452.     Function InternalCalcDepthPosValue(Const Value:TChartValue):Integer;
  453.     Procedure InternalCalcRange;
  454.     Procedure InternalCalcPositions;
  455.     Function InternalCalcSize( tmpFont:TTeeFont;
  456.                                tmpAngle:Integer;
  457.                                Const tmpText:String;
  458.                                tmpSize:Integer):Integer;
  459.     Function InternalLabelSize(Const Value:Double; IsWidth:Boolean):Integer;
  460.     function IsAxisValuesFormatStored:Boolean;
  461.     function IsLogBaseStored: Boolean;
  462.     Function IsMaxStored:Boolean;
  463.     Function IsMinStored:Boolean;
  464.     Function IsPosStored:Boolean;
  465.     Function IsStartStored:Boolean;
  466.     Function IsEndStored:Boolean;
  467.     Function IsCustom:Boolean;
  468.     function IsZStored: Boolean;
  469.     Procedure RecalcSizeCenter;
  470.     procedure SetHorizontal(const Value: Boolean);
  471.     procedure SetOtherSide(const Value: Boolean);
  472.     procedure SetLabelsExponent(Value: Boolean);
  473.     Procedure SetCalcPosValue;
  474.     procedure SetMaximumOffset(const Value: Integer);
  475.     procedure SetMinimumOffset(const Value: Integer);
  476.     procedure SetZPosition(const Value: Double);
  477.     Function XPosValue(Const Value:TChartValue):Integer;
  478.     Function YPosValue(Const Value:TChartValue):Integer;
  479.     Function XPosValueCheck(Const Value:TChartValue):Integer;
  480.     Function YPosValueCheck(Const Value:TChartValue):Integer;
  481.   protected
  482.     IHideBackGrid : Boolean;
  483.     IHideSideGrid : Boolean;
  484.     OnDrawGrids   : TAxisDrawGrids;
  485.     Function AxisRect:TRect;
  486.     Procedure DrawGrids(NumTicks:Integer);
  487.     Function InternalCalcLabelStyle:TAxisLabelStyle; virtual;
  488.     Procedure InternalSetInverted(Value:Boolean);
  489.     Procedure InternalSetMaximum(Const Value:Double);
  490.     Procedure InternalSetMinimum(Const Value:Double);
  491.     Procedure SetInverted(Value:Boolean); virtual;
  492.     Function SizeLabels:Integer;
  493.     Function SizeTickAxis:Integer;
  494.   public
  495.     IStartPos     : Integer;
  496.     IEndPos       : Integer;
  497.     IAxisSize     : Integer;
  498.     CalcXPosValue : TAxisCalcPos;
  499.     CalcYPosValue : TAxisCalcPos;
  500.     CalcPosValue  : TAxisCalcPos;
  501.     Tick          : TAxisTicks;  // 7.0 moved from protected
  502.     {$IFDEF D5}
  503.     Constructor Create(Chart:TCustomAxisPanel); reintroduce; overload;
  504.     {$ENDIF}
  505.     Constructor Create(Collection:TCollection); {$IFDEF D5}overload;{$ENDIF} override;
  506.     Destructor Destroy; override;
  507.     Procedure AdjustMaxMin;
  508.     Procedure AdjustMaxMinRect(Const Rect:TRect);
  509.     procedure Assign(Source: TPersistent); override;
  510.     Function CalcIncrement:Double;
  511.     Function CalcLabelStyle:TAxisLabelStyle;
  512.     Procedure CalcMinMax(Var AMin,AMax:Double);
  513.     Function CalcPosPoint(Value:Integer):Double;
  514.     Function CalcSizeValue(Const Value:Double):Integer;
  515.     Function CalcXYIncrement(MaxLabelSize:Integer):Double;
  516.     Procedure CustomDraw( APosLabels,APosTitle,APosAxis:Integer;
  517.                           GridVisible:Boolean);
  518.     Procedure CustomDrawMinMax( APosLabels,
  519.                                 APosTitle,
  520.                                 APosAxis:Integer;
  521.                                 GridVisible:Boolean;
  522.                                 Const AMinimum,AMaximum,AIncrement:Double);
  523.     Procedure CustomDrawMinMaxStartEnd( APosLabels,
  524.                                         APosTitle,
  525.                                         APosAxis:Integer;
  526.                                         GridVisible:Boolean;
  527.                                         Const AMinimum,AMaximum,AIncrement:Double;
  528.                                         AStartPos,AEndPos:Integer);
  529.     Procedure CustomDrawStartEnd( APosLabels,APosTitle,APosAxis:Integer;
  530.                                   GridVisible:Boolean; AStartPos,AEndPos:Integer);
  531.     Function Clicked(x,y:Integer):Boolean;
  532.     Procedure Draw(CalcPosAxis:Boolean);
  533.     procedure DrawAxisLabel(x,y,Angle:Integer; Const St:String; Format:TTeeCustomShape=nil);
  534.     Function IsDateTime:Boolean;
  535.     Function LabelWidth(Const Value:Double):Integer;
  536.     Function LabelHeight(Const Value:Double):Integer;
  537.     Function LabelValue(Const Value:Double):String; virtual; // 7.0
  538.     Function MaxLabelsWidth:Integer;
  539.     Procedure Scroll(Const Offset:Double; CheckLimits:Boolean=False);
  540.     Procedure SetMinMax(AMin,AMax:Double);
  541.     { public }
  542.     property IsDepthAxis  : Boolean read IDepthAxis;
  543.     property Items        : TAxisItems read FItems;
  544.     property MasterAxis   : TChartAxis read FMaster write FMaster; // 7.0
  545.     property PosAxis      : Integer read FPosAxis;
  546.     property PosLabels    : Integer read FPosLabels;
  547.     property PosTitle     : Integer read FPosTitle;
  548.     property ParentChart  : TCustomAxisPanel read FParentChart;
  549.   published
  550.     property Automatic:Boolean read FAutomatic write SetAutomatic default True;
  551.     property AutomaticMaximum:Boolean read FAutomaticMaximum write SetAutomaticMaximum default True;
  552.     property AutomaticMinimum:Boolean read FAutomaticMinimum write SetAutomaticMinimum default True;
  553.     property Axis:TChartAxisPen read FAxis write SetAxis;
  554.     property AxisValuesFormat:String read FAxisValuesFormat
  555.                                      write SetValuesFormat stored IsAxisValuesFormatStored;
  556.     property DateTimeFormat:String read FDateTimeFormat write SetDateTimeFormat;
  557.     property ExactDateTime:Boolean read FExactDateTime write SetExactDateTime default True;
  558.     property Grid:TAxisGridPen read FGrid write SetGrid;
  559.     property GridCentered:Boolean read GetGridCentered write SetGridCentered default False;
  560.     property Increment:Double read FDesiredIncrement write SetDesiredIncrement;
  561.     property Inverted:Boolean read FInverted write SetInverted default False;
  562.     property Horizontal : Boolean read FHorizontal write SetHorizontal stored IsCustom;
  563.     property OtherSide  : Boolean read FOtherSide write SetOtherSide stored IsCustom;
  564.     property Labels:Boolean read GetLabels write SetLabels default True;
  565.     property LabelsAlign:TAxisLabelAlign read FLabelsAlign write SetLabelsAlign default alDefault;
  566.     property LabelsAlternate:Boolean read FLabelsAlternate write SetLabelsAlternate default False;
  567.     property LabelsAngle:Integer read FLabelsAngle write SetLabelsAngle default 0;
  568.     property LabelsExponent:Boolean read FLabelsExponent write SetLabelsExponent default False;
  569.     property LabelsFont:TTeeFont read GetLabelsFont write SetLabelsFont {stored IsFontStored};
  570.     property LabelsMultiLine:Boolean read FLabelsMultiLine write SetLabelsMultiLine default False;
  571.     property LabelsOnAxis:Boolean read FLabelsOnAxis write SetLabelsOnAxis default True;
  572.     property LabelsSeparation:Integer read FLabelsSeparation
  573.                                       write SetLabelsSeparation default 10;
  574.     property LabelsSize:Integer read FLabelsSize write SetLabelsSize default 0;
  575.     property LabelStyle:TAxisLabelStyle read FLabelStyle write SetLabelStyle default talAuto;
  576.     property Logarithmic:Boolean read FLogarithmic write SetLogarithmic default False;
  577.     property LogarithmicBase:Double read FLogarithmicBase write SetLogarithmicBase stored IsLogBaseStored;
  578.     property Maximum:Double read FMaximumValue write SetMaximum stored IsMaxStored;
  579.     property MaximumOffset:Integer read FMaximumOffset write SetMaximumOffset default 0;
  580.     property Minimum:Double read FMinimumValue write SetMinimum stored IsMinStored;
  581.     property MinimumOffset:Integer read FMinimumOffset write SetMinimumOffset default 0;
  582.     property MinorGrid:TChartHiddenPen read FMinorGrid write SetMinorGrid;
  583.     property MinorTickCount:Integer read FMinorTickCount write SetMinorTickCount default 3;
  584.     property MinorTickLength:Integer read FMinorTickLength write SetMinorTickLength default 2;
  585.     property MinorTicks:TDarkGrayPen read FMinorTicks write SetMinorTicks;
  586.     property StartPosition:Double read FStartPosition write SetStartPosition
  587.                                     stored IsStartStored;
  588.     property EndPosition:Double read FEndPosition write SetEndPosition
  589.                                     stored IsEndStored;
  590.     property PositionPercent:Double read FPositionPercent write SetPositionPercent
  591.                                     stored IsPosStored;
  592.     property PositionUnits:TTeeUnits read FPosUnits write SetPosUnits default muPercent;
  593.     property RoundFirstLabel:Boolean read FRoundFirstLabel write SetRoundFirstLabel default True;
  594.     property TickInnerLength:Integer read FTickInnerLength write SetTickInnerLength default 0;
  595.     property TickLength:Integer read FTickLength write SetTickLength default 4;
  596.     property Ticks:TDarkGrayPen read FTicks write SetTicks;
  597.     property TicksInner:TDarkGrayPen read FTicksInner write SetTicksInner;
  598.     property TickOnLabelsOnly:Boolean read FTickOnLabelsOnly write SetTickOnLabelsOnly default True;
  599.     property Title:TChartAxisTitle read FAxisTitle write SetAxisTitle;
  600.     property TitleSize:Integer read FTitleSize write SetTitleSize default 0;
  601.     property Visible:Boolean read FVisible write SetVisible default True;
  602.     property ZPosition:Double read FZPosition write SetZPosition stored IsZStored;
  603.     // Events
  604.     property OnDrawLabel:TAxisDrawLabelEvent read FOnDrawLabel write FOnDrawLabel; // 7.0
  605.   end;
  606.   TChartDepthAxis=class(TChartAxis)
  607.   protected
  608.     Function InternalCalcLabelStyle:TAxisLabelStyle; override;
  609.     Procedure SetInverted(Value:Boolean); override;
  610.   published
  611.     property Visible default False;
  612.   end;
  613.   TAxisOnGetLabel=Procedure( Sender:TChartAxis; Series:TChartSeries;
  614.                              ValueIndex:Integer; Var LabelText:String) of object;
  615.   TAxisOnGetNextLabel=Procedure( Sender:TChartAxis; LabelIndex:Integer;
  616.                                  Var LabelValue:Double; Var Stop:Boolean) of object;
  617.   TSeriesClick=procedure( Sender:TChartSeries;
  618.                           ValueIndex:Integer;
  619.                           Button:TMouseButton;
  620.                           Shift: TShiftState;
  621.                           X, Y: Integer) of object;
  622.   TValueEvent=(veClear,veAdd,veDelete,veRefresh,veModify);
  623.   THorizAxis = (aTopAxis,aBottomAxis,aBothHorizAxis,aCustomHorizAxis);
  624.   TVertAxis  = (aLeftAxis,aRightAxis,aBothVertAxis,aCustomVertAxis);
  625.   TChartClickedPartStyle=( cpNone,
  626.                            cpLegend,
  627.                            cpAxis,
  628.                            cpSeries,
  629.                            cpTitle,
  630.                            cpFoot,
  631.                            cpChartRect,
  632.                            cpSeriesMarks,
  633.                            cpSubTitle,
  634.                            cpSubFoot );
  635.   TChartClickedPart=Packed Record
  636.     Part       : TChartClickedPartStyle;
  637.     PointIndex : Integer;
  638.     ASeries    : TChartSeries;
  639.     AAxis      : TChartAxis;
  640.   end;
  641.   TCustomSeriesList=class(TList)
  642.   private
  643.     FOwner : TCustomAxisPanel;
  644.     procedure Put(Index:Integer; Value:TChartSeries);
  645.     function Get(Index:Integer):TChartSeries;
  646.   public
  647.     procedure ClearValues;
  648.     procedure FillSampleValues(Num:Integer=0);
  649.     property Items[Index:Integer]:TChartSeries read Get write Put; default;
  650.     property Owner:TCustomAxisPanel read FOwner;
  651.   end;
  652.   TSeriesGroup=class;
  653.   TSeriesGroups=class;
  654.   TChartSeriesList=class {$IFDEF CLR}sealed{$ENDIF} (TCustomSeriesList)
  655.   private
  656.     FGroups : TSeriesGroups;
  657.     function GetAllActive: Boolean;
  658.     procedure SetAllActive(const Value: Boolean);
  659.   public
  660.     Destructor Destroy; override;
  661.     Function AddGroup(const Name:String):TSeriesGroup;
  662.     property AllActive:Boolean read GetAllActive write SetAllActive;
  663.     property Groups:TSeriesGroups read FGroups;
  664.   end;
  665.   TSeriesGroupActive=(gaYes, gaNo, gaSome);
  666.   TSeriesGroup=class {$IFDEF CLR}sealed{$ENDIF} (TCollectionItem)
  667.   private
  668.     FName   : String;
  669.     FSeries : TCustomSeriesList;
  670.     procedure SetActive(const Value:TSeriesGroupActive);
  671.     function IsSeriesStored: Boolean;
  672.     procedure SetSeries(const Value: TCustomSeriesList);
  673.     function GetActive: TSeriesGroupActive;
  674.   public
  675.     Constructor Create(Collection:TCollection); {$IFDEF D5}overload;{$ENDIF} override;
  676.     Destructor Destroy; override;
  677.     procedure Add(Series:TChartSeries);
  678.     procedure Hide;
  679.     procedure Show;
  680.   published
  681.     property Active:TSeriesGroupActive read GetActive write SetActive default gaYes;
  682.     property Name:String read FName write FName;
  683.     property Series:TCustomSeriesList read FSeries write SetSeries stored IsSeriesStored;
  684.   end;
  685.   TSeriesGroups=class {$IFDEF CLR}sealed{$ENDIF} (TOwnedCollection)
  686.   private
  687.     Function Get(Index:Integer):TSeriesGroup;
  688.     Procedure Put(Index:Integer; Const Value:TSeriesGroup);
  689.   public
  690.     Function Contains(Series:TChartSeries):Integer;
  691.     property Items[Index:Integer]:TSeriesGroup read Get write Put; default;
  692.   end;
  693.   TChartAxes=class {$IFDEF CLR}sealed{$ENDIF} (TList)
  694.   private
  695.     FChart    : TCustomAxisPanel;
  696.     IFastCalc : Boolean;  // default False
  697.     function Get(Index:Integer):TChartAxis;
  698.     function GetBottomAxis:TChartAxis;
  699.     function GetDepthAxis:TChartDepthAxis;
  700.     function GetDepthTopAxis:TChartDepthAxis;
  701.     function GetLeftAxis:TChartAxis;
  702.     function GetRightAxis:TChartAxis;
  703.     function GetTopAxis:TChartAxis;
  704.     procedure SetFastCalc(const Value: Boolean);
  705.     function GetBehind: Boolean;
  706.     function GetVisible: Boolean;
  707.     procedure SetBehind(const Value: Boolean);
  708.     procedure SetVisible(const Value: Boolean);
  709.   public
  710.     procedure Clear; override;
  711.     procedure Hide; // 7.04
  712.     procedure Reset;
  713.     property Items[Index:Integer]:TChartAxis read Get; default;
  714.     property Bottom:TChartAxis read GetBottomAxis;
  715.     property Depth:TChartDepthAxis read GetDepthAxis;
  716.     property DepthTop:TChartDepthAxis read GetDepthTopAxis;
  717.     property Left:TChartAxis read GetLeftAxis;
  718.     property Right:TChartAxis read GetRightAxis;
  719.     property Top:TChartAxis read GetTopAxis;
  720.     property Behind:Boolean read GetBehind write SetBehind;
  721.     property FastCalc:Boolean read IFastCalc write SetFastCalc;
  722.     property Visible:Boolean read GetVisible write SetVisible;
  723.   end;
  724.   TChartCustomAxes=class {$IFDEF CLR}sealed{$ENDIF} (TOwnedCollection)
  725.   private
  726.     Function Get(Index:Integer):TChartAxis;
  727.     Procedure Put(Index:Integer; Const Value:TChartAxis);
  728.   public
  729.     procedure ResetScales(Axis:TChartAxis);
  730.     property Items[Index:Integer]:TChartAxis read Get write Put; default;
  731.   end;
  732.   TTeeCustomDesigner=class(TObject)
  733.   public
  734.     Procedure Refresh; dynamic;
  735.     Procedure Repaint; dynamic;
  736.   end;
  737.   TChartSeriesEvent=( seAdd, seRemove, seChangeTitle, seChangeColor, seSwap,
  738.                       seChangeActive, seDataChanged);
  739.   TChartChangePage=class {$IFDEF CLR}sealed{$ENDIF} (TTeeEvent);
  740.   TChartToolEvent=( cteAfterDraw,
  741.                     cteBeforeDrawSeries,
  742.                     cteBeforeDraw,
  743.                     cteBeforeDrawAxes,    // 7.0
  744.                     cteAfterDrawSeries,  // 7.0
  745.                     cteMouseLeave);  // 7.0
  746.   TChartMouseEvent=(cmeDown,cmeMove,cmeUp);
  747.   TTeeCustomTool=class(TCustomChartElement)
  748.   protected
  749.     Procedure ChartEvent(AEvent:TChartToolEvent); virtual;
  750.     Procedure ChartMouseEvent( AEvent: TChartMouseEvent;
  751.                                Button:TMouseButton;
  752.                                Shift: TShiftState; X, Y: Integer); virtual;
  753.     procedure SetParentChart(const Value: TCustomAxisPanel); override;
  754.   public
  755.     class Function Description:String; virtual;
  756.   end;
  757.   TTeeCustomToolClass=class of TTeeCustomTool;
  758.   TChartTools=class {$IFDEF CLR}sealed{$ENDIF} (TList)
  759.   private
  760.     Owner : TCustomAxisPanel;
  761.     Function Get(Index:Integer):TTeeCustomTool;
  762.     procedure SetActive(Value:Boolean);
  763.   public
  764.     Function Add(Tool:TTeeCustomTool):TTeeCustomTool;
  765.     procedure Clear; override;
  766.     property Active:Boolean write SetActive;
  767.     property Items[Index:Integer]:TTeeCustomTool read Get; default;
  768.   end;
  769.   // Base object for tools that have a Series property
  770.   TTeeCustomToolSeries=class(TTeeCustomTool)
  771.   private
  772.     FSeries : TChartSeries;
  773.   protected
  774.     class Function GetEditorClass:String; override;
  775.     Function GetHorizAxis:TChartAxis;
  776.     Function GetVertAxis:TChartAxis;
  777.     procedure Notification(AComponent: TComponent; Operation: TOperation); override;
  778.     procedure SetSeries(const Value: TChartSeries); virtual;
  779.   public
  780.     property Series:TChartSeries read FSeries write SetSeries;
  781.   end;
  782.   // Base object for tools that have an Axis property
  783.   TTeeCustomToolAxis=class(TTeeCustomTool)
  784.   private
  785.     FAxis: TChartAxis;
  786.     procedure ReadAxis(Reader: TReader);
  787.     procedure WriteAxis(Writer: TWriter);
  788.   protected
  789.     procedure DefineProperties(Filer: TFiler); override;
  790.     class Function GetEditorClass:String; override;
  791.     procedure SetAxis(const Value: TChartAxis); virtual;
  792.   public
  793.     property Axis:TChartAxis read FAxis write SetAxis stored False;
  794.   end;
  795.   TTeeEventClass=class of TTeeEvent;
  796.   TTeeSeriesEvent=class(TTeeEvent)
  797.     Event  : TChartSeriesEvent;
  798.     Series : TCustomChartSeries;
  799.   end;
  800.   TChartSeriesClass=class of TChartSeries;
  801.   TCustomAxisPanel=class(TCustomTeePanelExtended)
  802.   private
  803.     { Private declarations }
  804.     F3DPercent        : Integer;
  805.     FAxes             : TChartAxes;
  806.     FAxisBehind       : Boolean;
  807.     FAxisVisible      : Boolean;
  808.     FClipPoints       : Boolean;
  809.     FCustomAxes       : TChartCustomAxes;
  810.     FSeriesList       : TChartSeriesList;
  811.     FDepthAxis        : TChartDepthAxis;
  812.     FDepthTopAxis     : TChartDepthAxis;
  813.     FTopAxis          : TChartAxis;
  814.     FBottomAxis       : TChartAxis;
  815.     FLeftAxis         : TChartAxis;
  816.     FRightAxis        : TChartAxis;
  817.     FView3DWalls      : Boolean;
  818.     FOnGetAxisLabel   : TAxisOnGetLabel;
  819.     FOnGetNextAxisLabel:TAxisOnGetNextLabel;
  820.     FOnPageChange     : TNotifyEvent;
  821.     FOnBeforeDrawChart: TNotifyEvent;
  822.     FOnBeforeDrawAxes : TNotifyEvent;
  823.     FOnBeforeDrawSeries:TNotifyEvent;
  824.     FPage             : Integer;
  825.     FMaxPointsPerPage : Integer;
  826.     FScaleLastPage    : Boolean;
  827.     FMaxZOrder        : Integer;
  828.     FSeriesWidth3D    : Integer;
  829.     FSeriesHeight3D   : Integer;
  830.     FTools            : TChartTools;
  831.     InvertedRotation  : Boolean;
  832.     Procedure BroadcastTeeEventClass(Event:TTeeEventClass);
  833.     Procedure BroadcastToolEvent(AEvent:TChartToolEvent);
  834.     Procedure CalcInvertedRotation;
  835.     Procedure CheckOtherSeries(Dest,Source:TChartSeries);
  836.     Function GetAxisSeriesMaxPoints(Axis:TChartAxis):TChartSeries;
  837.     Function GetSeries(Index:Integer):TChartSeries; {$IFDEF D9}inline;{$ENDIF}
  838.     Procedure InternalAddSeries(ASeries:TCustomChartSeries);
  839.     Function InternalMinMax(AAxis:TChartAxis; IsMin,IsX:Boolean):Double;
  840.     Function NoActiveSeries(AAxis:TChartAxis):Boolean;
  841.     Procedure Set3DPercent(Value:Integer);
  842.     Procedure SetAxisBehind(Value:Boolean);
  843.     Procedure SetAxisVisible(Value:Boolean);
  844.     Procedure SetBottomAxis(Value:TChartAxis);
  845.     procedure SetClipPoints(Value:Boolean);
  846.     Procedure SetCustomAxes(Value:TChartCustomAxes);
  847.     Procedure SetDepthAxis(Value:TChartDepthAxis);
  848.     procedure SetDepthTopAxis(const Value: TChartDepthAxis);
  849.     Procedure SetLeftAxis(Value:TChartAxis);
  850.     Procedure SetMaxPointsPerPage(Value:Integer);
  851.     Procedure SetRightAxis(Value:TChartAxis);
  852.     Procedure SetScaleLastPage(Value:Boolean);
  853.     Procedure SetTopAxis(Value:TChartAxis);
  854.     procedure SetView3DWalls(Value:Boolean);
  855.     function IsCustomAxesStored: Boolean;
  856.   protected
  857.     { Protected declarations }
  858.     LegendColor      : TColor;
  859.     LegendPen        : TChartPen;
  860.     Procedure BroadcastSeriesEvent(ASeries:TCustomChartSeries; Event:TChartSeriesEvent);
  861.     Function CalcIsAxisVisible(Axis:TChartAxis):Boolean;
  862.     Procedure CalcWallsRect; virtual; abstract;
  863.     Function CalcWallSize(Axis:TChartAxis):Integer; virtual; abstract;
  864.     Function CheckMouseSeries(x,y:Integer):Boolean;
  865.     procedure ColorPaletteChanged;
  866.     procedure DoOnAfterDraw; virtual;
  867.     procedure DoOnBeforeDrawAxes; virtual;
  868.     procedure DoOnBeforeDrawChart; virtual;
  869.     procedure DoOnBeforeDrawSeries; virtual;
  870.     procedure DrawTitlesAndLegend(BeforeSeries:Boolean); virtual; abstract;
  871.     Function DrawBackWallAfter(Z:Integer):Boolean; virtual;
  872.     Procedure DrawWalls; virtual; abstract;
  873.     Procedure InternalDraw(Const UserRectangle: TRect); override;
  874.     Function IsAxisVisible(Axis:TChartAxis):Boolean;
  875.     Function MultiLineTextWidth(S:String; Var NumLines:Integer):Integer;
  876.     procedure RemovedDataSource( ASeries: TChartSeries;
  877.                                  AComponent: TComponent ); dynamic;
  878.     Procedure SetPage(Value:Integer);
  879.     {$IFNDEF CLR}
  880.     Procedure GetChildren(Proc:TGetChildProc; Root:TComponent); override;
  881.     {$ENDIF}
  882.     {$IFNDEF CLX}
  883.     procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
  884.     {$ELSE}
  885.     procedure MouseLeave(AControl: TControl); override;
  886.     {$ENDIF}
  887.   public
  888.     { Public declarations }
  889.     Designer : TTeeCustomDesigner; { used only at Design-Time }
  890.     ColorPalette : TColorArray;
  891.     Constructor Create(AOwner: TComponent); override;
  892.     Destructor Destroy; override;
  893.     { public methods }
  894.     procedure Assign(Source:TPersistent); override;
  895.     Function ActiveSeriesLegend(ItemIndex:Integer):TChartSeries;
  896.     Function AddSeries(const ASeries:TChartSeries):TChartSeries; overload;  { 5.01 }
  897.     Function AddSeries({$IFNDEF BCB}const{$ENDIF} ASeriesClass:TChartSeriesClass):TChartSeries; overload;
  898.     {$IFNDEF BCB}
  899.     procedure AddSeries(const SeriesArray:Array of TChartSeries); overload;
  900.     {$ENDIF}
  901.     Procedure CalcSize3DWalls;
  902.     Procedure CheckDatasource(ASeries:TChartSeries); virtual;
  903.     Function CountActiveSeries:Integer;
  904.     Procedure ExchangeSeries(a,b:Integer); overload;
  905.     Procedure ExchangeSeries(a,b:TCustomChartSeries); overload;
  906.     Function FormattedValueLegend(ASeries:TChartSeries; ValueIndex:Integer):String; virtual;
  907.     Procedure FreeAllSeries( SeriesClass:TChartSeriesClass=nil );
  908.     Function GetAxisSeries(Axis:TChartAxis):TChartSeries;
  909.     {$IFDEF CLR}
  910.     Procedure GetChildren(Proc:TGetChildProc; Root:TComponent); override;
  911.     {$ENDIF}
  912.     Function GetDefaultColor(Index:Integer):TColor;
  913.     Function GetFreeSeriesColor(CheckBackground:Boolean=True; Series:TChartSeries=nil):TColor;
  914.     Function GetMaxValuesCount:Integer;
  915.     Function IsFreeSeriesColor(AColor: TColor; CheckBackground: Boolean;
  916.                                Series:TChartSeries=nil):Boolean; virtual; abstract;
  917.     Function IsValidDataSource(ASeries: TChartSeries; AComponent: TComponent):Boolean; dynamic;
  918.     Function MaxXValue(AAxis: TChartAxis):Double;
  919.     Function MaxYValue(AAxis: TChartAxis):Double;
  920.     Function MinXValue(AAxis: TChartAxis):Double;
  921.     Function MinYValue(AAxis: TChartAxis):Double;
  922.     Function MaxMarkWidth:Integer;
  923.     Function MaxTextWidth:Integer;
  924.     Function NumPages:Integer; dynamic;
  925.     procedure PrintPages(FromPage: Integer=1; ToPage: Integer=0);
  926.     Procedure RemoveSeries(ASeries: TCustomChartSeries); overload;
  927.     Procedure RemoveSeries(SeriesIndex: Integer); overload;
  928.     property Series[Index: Integer]:TChartSeries read GetSeries; default;
  929.     Function SeriesCount:Integer; //{$IFDEF D9}inline;{$ENDIF}
  930.     Function SeriesLegend(ItemIndex: Integer; OnlyActive: Boolean):TChartSeries;
  931.     Function SeriesTitleLegend(SeriesIndex: Integer; OnlyActive: Boolean=False):String;
  932.     { public properties }
  933.     property Axes:TChartAxes read FAxes;
  934.     property AxesList:TChartAxes read FAxes; // compatibility v4
  935.     property CustomAxes:TChartCustomAxes read FCustomAxes write SetCustomAxes stored IsCustomAxesStored;
  936.     property MaxZOrder:Integer read FMaxZOrder write FMaxZOrder;
  937.     property SeriesWidth3D:Integer read FSeriesWidth3D;
  938.     property SeriesHeight3D:Integer read FSeriesHeight3D;
  939.     { to be published properties }
  940.     property AxisBehind:Boolean read FAxisBehind write SetAxisBehind default True;
  941.     property AxisVisible:Boolean read FAxisVisible write SetAxisVisible default True;
  942.     property BottomAxis:TChartAxis read FBottomAxis write SetBottomAxis;
  943.     property Chart3DPercent:Integer read F3DPercent write Set3DPercent
  944.                                     default TeeDef3DPercent;  // obsolete;
  945.     property ClipPoints:Boolean read FClipPoints write SetClipPoints default True;
  946.     property Color;
  947.     property DepthAxis:TChartDepthAxis read FDepthAxis write SetDepthAxis;
  948.     property DepthTopAxis:TChartDepthAxis read FDepthTopAxis write SetDepthTopAxis; // 7.0
  949.     property LeftAxis:TChartAxis read FLeftAxis write SetLeftAxis;
  950.     property MaxPointsPerPage:Integer read FMaxPointsPerPage write SetMaxPointsPerPage default 0;
  951.     property Page:Integer read FPage write SetPage default 1;
  952.     property RightAxis:TChartAxis read FRightAxis write SetRightAxis;
  953.     property ScaleLastPage:Boolean read FScaleLastPage write SetScaleLastPage default True;
  954.     property SeriesList:TChartSeriesList read FSeriesList;
  955.     property Tools:TChartTools read FTools;
  956.     property TopAxis:TChartAxis read FTopAxis write SetTopAxis;
  957.     property View3DWalls:Boolean read FView3DWalls write SetView3DWalls default True;
  958.     { to be published events }
  959.     property OnBeforeDrawChart: TNotifyEvent read FOnBeforeDrawChart write FOnBeforeDrawChart;
  960.     property OnBeforeDrawAxes:TNotifyEvent read FOnBeforeDrawAxes write FOnBeforeDrawAxes;
  961.     property OnBeforeDrawSeries:TNotifyEvent read FOnBeforeDrawSeries write FOnBeforeDrawSeries;
  962.     property OnGetAxisLabel:TAxisOnGetLabel read FOnGetAxisLabel write FOnGetAxisLabel;
  963.     property OnGetNextAxisLabel:TAxisOnGetNextLabel read FOnGetNextAxisLabel
  964.                                                     write FOnGetNextAxisLabel;
  965.     property OnPageChange:TNotifyEvent read FOnPageChange write FOnPageChange;
  966.   end;
  967.   TSeriesMarkPosition=class
  968.   public
  969.     ArrowFrom : TPoint;
  970.     ArrowFix  : Boolean;
  971.     ArrowTo   : TPoint;
  972.     Custom    : Boolean;
  973.     Height    : Integer;
  974.     LeftTop   : TPoint;
  975.     Width     : Integer;
  976.     Procedure Assign(Source:TSeriesMarkPosition);
  977.     Function Bounds:TRect;
  978.   end;
  979.   TSeriesMarksPositions=class {$IFDEF CLR}sealed{$ENDIF} (TList)
  980.   private
  981.     Function Get(Index:Integer):TSeriesMarkPosition;
  982.     Procedure Put(Index:Integer; APosition:TSeriesMarkPosition);
  983.   public
  984.     Procedure Automatic(Index:Integer);
  985.     procedure Clear; override;
  986.     Function ExistCustom:Boolean;
  987.     property Position[Index:Integer]:TSeriesMarkPosition read Get
  988.                                     write Put; default;
  989.   end;
  990.   TMarksItem=class {$IFDEF CLR}sealed{$ENDIF} (TTeeCustomShape)
  991.   published
  992.     property Bevel;
  993.     property BevelWidth;
  994.     property Color default ChartMarkColor;
  995.     property Font;
  996.     property Gradient;
  997.     property Shadow;
  998.     property ShapeStyle;
  999.     property Transparency;
  1000.     property Transparent;
  1001.   end;
  1002.   TMarksItems=class {$IFDEF CLR}sealed{$ENDIF} (TList)
  1003.   private
  1004.     IMarks : TTeeCustomShape;
  1005.     ILoadingCustom : Boolean;
  1006.     function Get(Index:Integer):TMarksItem;
  1007.   public
  1008.     Procedure Clear; override;
  1009.     property Format[Index:Integer]:TMarksItem read Get; default;
  1010.   end;
  1011.   TSeriesMarksStyle=( smsValue,             { 1234 }
  1012.                       smsPercent,           { 12 % }
  1013.                       smsLabel,             { Cars }
  1014.                       smsLabelPercent,      { Cars 12 % }
  1015.                       smsLabelValue,        { Cars 1234 }
  1016.                       smsLegend,            { (Legend.Style) }
  1017.                       smsPercentTotal,      { 12 % of 1234 }
  1018.                       smsLabelPercentTotal, { Cars 12 % of 1234 }
  1019.                       smsXValue,            { 1..2..3.. or 21/6/1996 }
  1020.                       smsXY                 { 123 456 }
  1021.                       );
  1022.   TSeriesMarksGradient=class {$IFDEF CLR}sealed{$ENDIF} (TChartGradient)
  1023.   public
  1024.     Constructor Create(ChangedEvent:TNotifyEvent); override;
  1025.   published
  1026.     property Direction default gdRightLeft;
  1027.     property EndColor default clWhite;
  1028.     property StartColor default clSilver;
  1029.   end;
  1030.   TSeriesPointerStyle=( psRectangle,psCircle,psTriangle,psDownTriangle,
  1031.                         psCross,psDiagCross,psStar,psDiamond,psSmallDot,
  1032.                         psNothing,psLeftTriangle,psRightTriangle );
  1033.   TSeriesPointer=class(TTeeCustomShapeBrushPen)
  1034.   private
  1035.     FDark3D    : Boolean;
  1036.     FDraw3D    : Boolean;
  1037.     FGradient  : TTeeGradient;
  1038.     FHorizSize : Integer;
  1039.     FInflate   : Boolean;
  1040.     FSeries    : TChartSeries;
  1041.     FStyle     : TSeriesPointerStyle;
  1042.     FTransparency : TTeeTransparency; // 6.02
  1043.     FVertSize  : Integer;
  1044.     Procedure CheckPointerSize(Value:Integer);
  1045.     function GetColor: TColor;
  1046.     function GetSize:Integer; // 7.01
  1047.     function GetStartZ:Integer;   // 6.01
  1048.     function GetMiddleZ:Integer;  // 6.01
  1049.     function GetEndZ:Integer;     // 6.01
  1050.     procedure SetColor(const Value: TColor);
  1051.     Procedure SetDark3D(Value:Boolean);
  1052.     Procedure SetDraw3D(Value:Boolean);
  1053.     procedure SetGradient(const Value: TTeeGradient);
  1054.     Procedure SetHorizSize(Value:Integer);
  1055.     Procedure SetInflate(Value:Boolean);
  1056.     procedure SetSize(const Value:Integer); // 7.01
  1057.     Procedure SetStyle(Value:TSeriesPointerStyle);
  1058.     procedure SetTransparency(const Value: TTeeTransparency);
  1059.     Procedure SetVertSize(Value:Integer);
  1060.   protected
  1061.     AllowChangeSize : Boolean;
  1062.     FullGradient    : Boolean;
  1063.     Procedure CalcHorizMargins(Var LeftMargin,RightMargin:Integer);
  1064.     Procedure CalcVerticalMargins(Var TopMargin,BottomMargin:Integer);
  1065.     Procedure Change3D(Value:Boolean);
  1066.     Procedure ChangeHorizSize(NewSize:Integer);
  1067.     Procedure ChangeStyle(NewStyle:TSeriesPointerStyle);
  1068.     Procedure ChangeVertSize(NewSize:Integer);
  1069.     Procedure Prepare;
  1070.   public
  1071.     Constructor Create(AOwner:TChartSeries);
  1072.     Destructor Destroy; override;
  1073.     Procedure Assign(Source:TPersistent); override;
  1074.     Procedure Draw(P:TPoint); overload;
  1075.     Procedure Draw(X,Y:Integer); overload;
  1076.     Procedure Draw(px,py:Integer; ColorValue:TColor; AStyle:TSeriesPointerStyle); overload;
  1077.     Procedure DrawPointer( ACanvas:TCanvas3D;
  1078.                            Is3D:Boolean; px,py,tmpHoriz,tmpVert:Integer;
  1079.                            ColorValue:TColor; AStyle:TSeriesPointerStyle);
  1080.     Procedure PrepareCanvas(ACanvas:TCanvas3D; ColorValue:TColor);
  1081.     property Color:TColor read GetColor write SetColor;
  1082.     property ParentSeries:TChartSeries read FSeries;
  1083.     property Size:Integer read GetSize write SetSize;  // do not move to published
  1084.   published
  1085.     property Brush;
  1086.     property Dark3D:Boolean read FDark3D write SetDark3D default True;
  1087.     Property Draw3D:Boolean read FDraw3D write SetDraw3D default True;
  1088.     property Gradient:TTeeGradient read FGradient write SetGradient; // 6.0
  1089.     Property HorizSize:Integer read FHorizSize write SetHorizSize default 4;
  1090.     property InflateMargins:Boolean read FInflate write SetInflate;
  1091.     property Pen;
  1092.     property Style:TSeriesPointerStyle read FStyle write SetStyle;
  1093.     property Transparency:TTeeTransparency read FTransparency write SetTransparency default 0;
  1094.     Property VertSize:Integer read FVertSize write SetVertSize default 4;
  1095.     Property Visible;
  1096.   end;
  1097.   TArrowHeadStyle=(ahNone,ahLine,ahSolid);
  1098.   TChartArrowPen=TWhitePen;
  1099.   TCallout=class(TSeriesPointer)
  1100.   private
  1101.     FArrow     : TChartArrowPen;
  1102.     FArrowHead : TArrowHeadStyle;
  1103.     FDistance  : Integer;
  1104.     FArrowHeadSize: Integer;
  1105.     procedure SetDistance(const Value: Integer);
  1106.     procedure SetArrow(const Value: TChartArrowPen);
  1107.     procedure SetArrowHead(const Value: TArrowHeadStyle);
  1108.     procedure SetArrowHeadSize(const Value: Integer);
  1109.   protected
  1110.     procedure Draw(AColor:TColor; AFrom,ATo:TPoint; Z:Integer); overload;
  1111.   public
  1112.     Constructor Create(AOwner:TChartSeries);
  1113.     Procedure Assign(Source:TPersistent); override;
  1114.     destructor Destroy; override;
  1115.   published
  1116.     property Arrow:TChartArrowPen read FArrow write SetArrow;
  1117.     property ArrowHead:TArrowHeadStyle read FArrowHead write SetArrowHead default ahNone;
  1118.     property ArrowHeadSize:Integer read FArrowHeadSize write SetArrowHeadSize default 8;
  1119.     property Distance:Integer read FDistance write SetDistance default 0;
  1120.     property Draw3D default False;
  1121.     property InflateMargins default True;
  1122.     property Style default psRectangle;
  1123.     property Visible default True;
  1124.   end;
  1125.   TMarksCallout=class(TCallout)
  1126.   private
  1127.     FLength : Integer;
  1128.     procedure ApplyArrowLength(APosition:TSeriesMarkPosition);
  1129.     Function IsLengthStored:Boolean;
  1130.     procedure SetLength(const Value:Integer);
  1131.   protected
  1132.     DefaultLength : Integer;
  1133.   public
  1134.     Constructor Create(AOwner: TChartSeries);
  1135.     Procedure Assign(Source:TPersistent); override;
  1136.   published
  1137.     property Length:Integer read FLength write SetLength stored IsLengthStored;
  1138.     property Visible default False;
  1139.   end;
  1140.   TSeriesMarksSymbol=class {$IFDEF CLR}sealed{$ENDIF} (TTeeCustomShape)
  1141.   private
  1142.     Function ShouldDraw:Boolean;
  1143.   public
  1144.     Constructor Create(AOwner:TCustomTeePanel); override;
  1145.   published
  1146.     property Bevel;  { 5.01 }
  1147.     property BevelWidth;  { 5.01 }
  1148.     property Brush;
  1149.     property Frame;
  1150.     property Gradient;
  1151.     property Pen;
  1152.     property Shadow;
  1153.     property ShapeStyle;
  1154.     property Transparency; { 5.01 }
  1155.     property Visible default False;
  1156.   end;
  1157.   // CLR Note: This class cannot be marked as "sealed"
  1158.   // due to required cast access tricks.
  1159.   TSeriesMarks=class(TTeeCustomShape)
  1160.   private
  1161.     FAngle       : Integer;
  1162.     FCallout     : TMarksCallout;
  1163.     FClip        : Boolean;
  1164.     FDrawEvery   : Integer;
  1165.     FItems       : TMarksItems;
  1166.     FMarkerStyle : TSeriesMarksStyle;
  1167.     FMultiLine   : Boolean;
  1168.     FSeries      : TChartSeries;
  1169.     FPositions   : TSeriesMarksPositions;
  1170.     FSymbol      : TSeriesMarksSymbol;
  1171.     FZPosition   : Integer;
  1172.     function GetArrowLength: Integer;
  1173.     function GetArrowPen: TChartArrowPen;
  1174.     Function GetBackColor:TColor;
  1175.     Function GetCallout:TMarksCallout;
  1176.     function GetItem(Index:Integer):TMarksItem;
  1177.     Function GetSymbol: TSeriesMarksSymbol;
  1178.     Procedure InternalDraw(Index:Integer; AColor:TColor; Const St:String; APosition:TSeriesMarkPosition);
  1179.     procedure ReadItems(Stream: TStream);
  1180.     Procedure SetAngle(Value:Integer);
  1181.     procedure SetCallout(const Value: TMarksCallout);
  1182.     Procedure SetArrowPen(const Value:TChartArrowPen);
  1183.     Procedure SetArrowLength(Value:Integer);
  1184.     Procedure SetBackColor(Value:TColor);
  1185.     Procedure SetClip(Value:Boolean);
  1186.     Procedure SetDrawEvery(Value:Integer);
  1187.     Procedure SetMultiline(Value:Boolean);
  1188.     Procedure SetStyle(Value:TSeriesMarksStyle);
  1189.     procedure SetSymbol(const Value: TSeriesMarksSymbol);
  1190.     procedure WriteItems(Stream: TStream);
  1191.   protected
  1192.     Procedure AntiOverlap(First, ValueIndex:Integer; APosition:TSeriesMarkPosition);
  1193.     Procedure ConvertTo2D(Point:TPoint; var P:TPoint);
  1194.     procedure DefineProperties(Filer: TFiler); override;
  1195.     Function GetGradientClass:TChartGradientClass; override;
  1196.     Procedure InitShadow(AShadow:TTeeShadow); override;
  1197.     Function MarkItem(ValueIndex:Integer):TTeeCustomShape;
  1198.     procedure SetParent(Value:TCustomTeePanel); override;
  1199.     Function TextWidth(ValueIndex:Integer):Integer;
  1200.     Procedure UsePosition(Index:Integer; Var MarkPosition:TSeriesMarkPosition);
  1201.   public
  1202.     Constructor Create(AOwner:TChartSeries); overload;
  1203.     Destructor Destroy; override;
  1204.     Procedure ApplyArrowLength(APosition:TSeriesMarkPosition);
  1205.     Procedure Assign(Source:TPersistent); override;
  1206.     procedure Clear;
  1207.     Function Clicked(X,Y:Integer):Integer;
  1208.     Procedure DrawText(Const R:TRect; Const St:String);
  1209.     property Item[Index:Integer]:TMarksItem read GetItem; default;
  1210.     property Items:TMarksItems read FItems;
  1211.     property ParentSeries:TChartSeries read FSeries;
  1212.     property Positions:TSeriesMarksPositions read FPositions;
  1213.     procedure ResetPositions;
  1214.     property ZPosition : Integer read FZPosition write FZPosition;
  1215.   published
  1216.     property Angle:Integer read FAngle write SetAngle default 0;
  1217.     property Arrow:TChartArrowPen read GetArrowPen write SetArrowPen; // obsolete
  1218.     property ArrowLength:Integer read GetArrowLength write SetArrowLength stored False; // obsolete
  1219.     property Callout:TMarksCallout read GetCallout write SetCallout;  // 6.0
  1220.     property BackColor:TColor read GetBackColor write SetBackColor default ChartMarkColor;
  1221.     property Bevel;  { 5.01 }
  1222.     property BevelWidth;  { 5.01 }
  1223.     property Brush;
  1224.     property Clip:Boolean read FClip write SetClip default False;
  1225.     property Color default ChartMarkColor;
  1226.     property DrawEvery:Integer read FDrawEvery write SetDrawEvery default 1;
  1227.     property Font;
  1228.     property Frame;
  1229.     property Gradient;
  1230.     property MultiLine:Boolean read FMultiLine write SetMultiLine default False;
  1231.     property Shadow;
  1232.     property ShapeStyle;
  1233.     property Style:TSeriesMarksStyle read FMarkerStyle
  1234.                                      write SetStyle default smsLabel;
  1235.     property Symbol:TSeriesMarksSymbol read GetSymbol write SetSymbol;
  1236.     property Transparency; { 5.01 }
  1237.     property Transparent;
  1238.     property Visible;
  1239.   end;
  1240.   TSeriesOnBeforeAdd=Function(Sender:TChartSeries):Boolean of object;
  1241.   TSeriesOnAfterAdd=Procedure(Sender:TChartSeries; ValueIndex:Integer) of object;
  1242.   TSeriesOnClear=Procedure(Sender:TChartSeries) of object;
  1243.   TSeriesOnGetMarkText=Procedure(Sender:TChartSeries; ValueIndex:Integer; Var MarkText:String) of object;
  1244.   TSeriesRecalcOptions=set of (rOnDelete, rOnModify, rOnInsert, rOnClear);
  1245.   TFunctionPeriodStyle=( psNumPoints, psRange );
  1246.   TFunctionPeriodAlign=( paFirst,paCenter,paLast );
  1247.   {$IFDEF CLR}
  1248.   [ToolBoxItem(False)]
  1249.   {$ENDIF}
  1250.   TTeeFunction=class(TComponent)
  1251.   private
  1252.     FPeriod      : Double;
  1253.     FPeriodStyle : TFunctionPeriodStyle;
  1254.     FPeriodAlign : TFunctionPeriodAlign;
  1255.     FParent      : TChartSeries;
  1256.     IUpdating    : Boolean;
  1257.     Procedure SetPeriod(Const Value:Double);
  1258.     Procedure SetParentSeries(AParent:TChartSeries);
  1259.     Procedure SetPeriodAlign(Value:TFunctionPeriodalign);
  1260.     Procedure SetPeriodStyle(Value:TFunctionPeriodStyle);
  1261.   protected
  1262.     CanUsePeriod     : Boolean;  // function uses Period property ?
  1263.     NoSourceRequired : Boolean;  // function requires source Series ?
  1264.     SingleSource     : Boolean;  // function allows more than one source ?
  1265.     HideSourceList   : Boolean;  // For single-source, allow select value-list ?
  1266.     Procedure AddFunctionXY(YMandatorySource:Boolean; const tmpX,tmpY:Double);
  1267.     Procedure CalculatePeriod( Source:TChartSeries;
  1268.                                Const tmpX:Double;
  1269.                                FirstIndex,LastIndex:Integer); virtual;
  1270.     Procedure CalculateAllPoints(Source:TChartSeries; NotMandatorySource:TChartValueList); virtual;
  1271.     Procedure CalculateByPeriod(Source:TChartSeries; NotMandatorySource:TChartValueList); virtual;
  1272.     procedure Clear; dynamic;
  1273.     Procedure DoCalculation( Source:TChartSeries;
  1274.                              NotMandatorySource:TChartValueList); virtual;
  1275.     class Function GetEditorClass:String; virtual;
  1276.     Procedure InternalSetPeriod(Const APeriod:Double);
  1277.     Function IsValidSource(Value:TChartSeries):Boolean; dynamic;
  1278.     class Procedure PrepareForGallery(Chart:TCustomAxisPanel); virtual;
  1279.     {$IFNDEF CLR}
  1280.     procedure SetParentComponent(Value: TComponent); override;
  1281.     {$ENDIF}
  1282.     Function ValueList(ASeries:TChartSeries):TChartValueList;
  1283.   public
  1284.     Constructor Create(AOwner: TComponent); override;
  1285.     Procedure Assign(Source:TPersistent); override;
  1286.     procedure AddPoints(Source:TChartSeries); dynamic;
  1287.     procedure BeginUpdate;
  1288.     Function Calculate(SourceSeries:TChartSeries; First,Last:Integer):Double; virtual;
  1289.     Function CalculateMany(SourceSeriesList:TList; ValueIndex:Integer):Double; virtual;
  1290.     procedure EndUpdate;
  1291.     function GetParentComponent: TComponent; override;
  1292.     function HasParent: Boolean; override;
  1293.     property ParentSeries:TChartSeries read FParent write SetParentSeries;
  1294.     Procedure ReCalculate;
  1295.     {$IFDEF CLR}
  1296.     procedure SetParentComponent(Value: TComponent); override;
  1297.     {$ENDIF}
  1298.   published
  1299.     property Period:Double read FPeriod write SetPeriod;
  1300.     property PeriodAlign:TFunctionPeriodAlign read FPeriodAlign
  1301.                                               write SetPeriodAlign default paCenter;
  1302.     property PeriodStyle:TFunctionPeriodStyle read FPeriodStyle
  1303.                                               write SetPeriodStyle default psNumPoints;
  1304.   end;
  1305.   TTeeMovingFunction=class(TTeeFunction)
  1306.   protected
  1307.     Procedure DoCalculation( Source:TChartSeries;
  1308.                              NotMandatorySource:TChartValueList); override;
  1309.   public
  1310.     Constructor Create(AOwner:TComponent); override;
  1311.   published
  1312.     property Period;
  1313.   end;
  1314.   TChartValueLists=class {$IFDEF CLR}sealed{$ENDIF} (TList)
  1315.   private
  1316.     Function Get(Index:Integer):TChartValueList;
  1317.   public
  1318.     Procedure Clear; override;
  1319.     property ValueList[Index:Integer]:TChartValueList read Get; default;
  1320.   end;
  1321.   TChartSeriesStyle=set of ( tssIsTemplate,
  1322.                              tssDenyChangeType,
  1323.                              tssDenyDelete,
  1324.                              tssDenyClone,
  1325.                              tssIsPersistent,
  1326.                              tssHideDataSource );
  1327.   TCustomChartSeries=class(TCustomChartElement)
  1328.   private
  1329.     FShowInLegend : Boolean;
  1330.     FTitle        : String;
  1331.     FIdentifier   : String;  { DecisionCube }
  1332.     FStyle        : TChartSeriesStyle; { DecisionCube }
  1333.     procedure ReadIdentifier(Reader: TReader);
  1334.     procedure WriteIdentifier(Writer: TWriter);
  1335.     procedure ReadStyle(Reader: TReader);
  1336.     procedure WriteStyle(Writer: TWriter);
  1337.     Procedure RepaintDesigner;
  1338.     Procedure SetShowInLegend(Value:Boolean);
  1339.     Procedure SetTitle(Const Value:String);
  1340.   protected
  1341.     Procedure Added; dynamic;
  1342.     Procedure CalcHorizMargins(Var LeftMargin,RightMargin:Integer); virtual;
  1343.     Procedure CalcVerticalMargins(Var TopMargin,BottomMargin:Integer); virtual;
  1344.     procedure DefineProperties(Filer: TFiler); override;
  1345.     procedure DoBeforeDrawChart; virtual;
  1346.     Procedure GalleryChanged3D(Is3D:Boolean); dynamic;
  1347.     Procedure Removed; dynamic;
  1348.     Procedure SetActive(Value:Boolean); override;
  1349.   public
  1350.     Constructor Create(AOwner: TComponent); override;
  1351.     procedure Assign(Source:TPersistent); override;
  1352.     Function SameClass(tmpSeries:TChartSeries):Boolean;
  1353.     property ShowInLegend:Boolean read FShowInLegend write SetShowInLegend default True;
  1354.     property Title:String read FTitle write SetTitle;
  1355.     { DSS, hidden }
  1356.     property Identifier:String read FIdentifier write FIdentifier;
  1357.     property Style:TChartSeriesStyle read FStyle write FStyle default [];
  1358.   end;
  1359.   TSeriesRandomBounds=packed record
  1360.     tmpX,StepX,tmpY,MinY,DifY:Double;
  1361.   end;
  1362.   TTeeFunctionClass=class of TTeeFunction;
  1363.   {$IFDEF CLR}
  1364.   PString=string;
  1365.   {$ENDIF}
  1366.   TTeeSeriesType=class {$IFDEF CLR}sealed{$ENDIF} (TObject)
  1367.     SeriesClass      : TChartSeriesClass;
  1368.     FunctionClass    : TTeeFunctionClass;
  1369.     Description      : PString;
  1370.     GalleryPage      : PString;
  1371.     NumGallerySeries : Integer;
  1372.   end;
  1373.   TChartSubGalleryProc=Function(Const AName:String):TCustomAxisPanel of object;
  1374.   TLegendTextStyle=( ltsPlain,ltsLeftValue,ltsRightValue,
  1375.                      ltsLeftPercent,ltsRightPercent,ltsXValue,ltsValue,
  1376.                      ltsPercent,ltsXAndValue,ltsXAndPercent);
  1377.   TeeFormatFlags = (tfNoMandatory,tfColor,tfLabel,tfMarkPosition);
  1378.   TeeFormatFlag  = set of TeeFormatFlags;
  1379.   TLabelsList=class {$IFDEF CLR}sealed{$ENDIF} (TList)
  1380.   private
  1381.     Series : TChartSeries;
  1382.     Procedure DeleteLabel(ValueIndex:Integer);
  1383.     Function GetLabel(ValueIndex:Integer):String;
  1384.     Procedure SetLabel(ValueIndex:Integer; Const ALabel:String);
  1385.     Procedure InsertLabel(ValueIndex:Integer; Const ALabel:String);
  1386.   public
  1387.     procedure Assign(Source:TLabelsList);
  1388.     procedure Clear; override;
  1389.     Function IndexOfLabel(const ALabel:String; CaseSensitive:Boolean=True):Integer;
  1390.     property Labels[Index:Integer]:String read GetLabel write SetLabel; default;
  1391.   end;
  1392.   TDataSourcesList=class {$IFDEF CLR}sealed{$ENDIF} (TList)  // 6.02
  1393.   private
  1394.     Series : TChartSeries;
  1395.     function InheritedAdd(Value:TComponent):Integer;
  1396.     procedure InheritedClear;
  1397.   {$IFDEF D5}
  1398.   protected
  1399.     {$IFDEF CLR}
  1400.     procedure Notify(Instance:TObject; Action: TListNotification); override;
  1401.     {$ELSE}
  1402.     procedure Notify(Ptr: Pointer; Action: TListNotification); override;
  1403.     {$ENDIF}
  1404.   {$ENDIF}
  1405.   public
  1406.     function Add(Value:TComponent):Integer;
  1407.     procedure Clear; override;
  1408.   end;
  1409.   TChartSeries=class(TCustomChartSeries)
  1410.   private
  1411.     FColor              : TColor;
  1412.     FColorEachPoint     : Boolean;
  1413.     FColors             : TList;
  1414.     FColorSource        : String;
  1415.     FCursor             : TCursor;
  1416.     FDataSources        : TDataSourcesList;
  1417.     FDepth              : Integer;
  1418.     FGetHorizAxis       : TChartAxis;
  1419.     FGetVertAxis        : TChartAxis;
  1420.     FLabelsSource       : String;
  1421.     FLinkedSeries       : TCustomSeriesList;
  1422.     FMarks              : TSeriesMarks;
  1423.     FPercentFormat      : String;
  1424.     FTempDataSources    : TStringList;
  1425.     FValueFormat        : String;
  1426.     FValuesList         : TChartValueLists;
  1427.     FX                  : TChartValueList;
  1428.     FLabels             : TLabelsList;
  1429.     FY                  : TChartValueList;
  1430.     FHorizAxis          : THorizAxis;
  1431.     FCustomHorizAxis    : TChartAxis;
  1432.     FCustomVertAxis     : TChartAxis;
  1433.     FZOrder             : Integer;
  1434.     FVertAxis           : TVertAxis;
  1435.     FRecalcOptions      : TSeriesRecalcOptions;
  1436.     FTeeFunction        : TTeeFunction;
  1437.     { Private }
  1438.     IsMouseInside       : Boolean;
  1439.     ILabelOrder         : TChartListOrder;
  1440.     ISeriesColor        : TColor; // Color assigned when creating the Series.
  1441.     { Events }
  1442.     FAfterDrawValues    : TNotifyEvent;
  1443.     FBeforeDrawValues   : TNotifyEvent;
  1444.     FOnAfterAdd         : TSeriesOnAfterAdd;
  1445.     FOnBeforeAdd        : TSeriesOnBeforeAdd;
  1446.     FOnClearValues      : TSeriesOnClear;
  1447.     FOnClick            : TSeriesClick;
  1448.     FOnDblClick         : TSeriesClick;
  1449.     FOnGetMarkText      : TSeriesOnGetMarkText;
  1450.     FOnMouseEnter       : TNotifyEvent;
  1451.     FOnMouseLeave       : TNotifyEvent;
  1452.     Function CanAddRandomPoints:Boolean;
  1453.     Procedure ChangeInternalColor(Value:TColor);
  1454.     Function CompareLabelIndex(a,b:Integer):Integer;
  1455.     Function GetDataSource:TComponent;
  1456.     Function GetZOrder:Integer;
  1457.     Procedure GrowColors;
  1458.     Function InternalAddDataSource(Value:TComponent):Integer;
  1459.     Function InternalSetDataSource(Value:TComponent; ClearAll:Boolean):Integer;
  1460.     Procedure InternalRemoveDataSource(Value:TComponent);
  1461.     Function IsColorStored:Boolean;
  1462.     Function IsPercentFormatStored:Boolean;
  1463.     Function IsValueFormatStored:Boolean;
  1464.     Procedure NotifyColorChanged;
  1465.     procedure ReadCustomHorizAxis(Reader: TReader);
  1466.     procedure ReadCustomVertAxis(Reader: TReader);
  1467.     procedure ReadDataSources(Reader: TReader);
  1468.     Procedure RecalcGetAxis;
  1469.     Procedure RemoveAllLinkedSeries;
  1470.     Procedure SetColorSource(Const Value:String);
  1471.     Procedure SetCustomHorizAxis(Value:TChartAxis);
  1472.     Procedure SetCustomVertAxis(Value:TChartAxis);
  1473.     Procedure SetDataSource(Value:TComponent);
  1474.     procedure SetDepth(const Value: Integer);
  1475.     Procedure SetHorizAxis(const Value:THorizAxis);
  1476.     Procedure SetLabelsSource(Const Value:String);
  1477.     procedure SetMarks(Value:TSeriesMarks);
  1478.     Procedure SetPercentFormat(Const Value:String);
  1479.     Procedure SetValueColor(ValueIndex:Integer; AColor:TColor);
  1480.     Procedure SetValueFormat(Const Value:String);
  1481.     Procedure SetVertAxis(const Value:TVertAxis);
  1482.     Procedure SetXValue(Index:Integer; Const Value:Double);
  1483.     Procedure SetYValue(Index:Integer; Const Value:Double);
  1484.     Procedure SetZOrder(Value:Integer);
  1485.     procedure WriteCustomHorizAxis(Writer: TWriter);
  1486.     procedure WriteCustomVertAxis(Writer: TWriter);
  1487.     procedure WriteDataSources(Writer: TWriter);
  1488.     function GetXLabel(Index: Integer): String;
  1489.     procedure SetXLabel(Index: Integer; const Value: String);
  1490.   protected
  1491.     DontSaveData     : Boolean;
  1492.     ForceSaveData    : Boolean;
  1493.     ManualData       : Boolean;
  1494.     FFirstVisibleIndex  : Integer;
  1495.     FLastVisibleIndex   : Integer;
  1496.     INumSampleValues : Integer;
  1497.     IUpdating        : Integer;
  1498.     IUseSeriesColor  : Boolean;
  1499.     IUseNotMandatory : Boolean;
  1500.     IZOrder          : Integer;
  1501.     ILegend          : TTeeCustomShape;
  1502.     IFirstDrawIndex  : Integer;
  1503.     Function AddChartValue(Source:TChartSeries; ValueIndex:Integer):Integer; virtual;
  1504.     Procedure Added; override;
  1505.     Procedure AddedValue(Source:TChartSeries; ValueIndex:Integer); virtual;
  1506.     Procedure AddLinkedSeries(ASeries:TChartSeries);
  1507.     Procedure AddSampleValues(NumValues:Integer; OnlyMandatory:Boolean=False); dynamic;
  1508.     Procedure AddValues(Source:TChartSeries); virtual;
  1509.     procedure CalcFirstLastPage(var First,Last:Integer);
  1510.     Procedure CalcFirstLastVisibleIndex; virtual;
  1511.     Procedure CalcZOrder; virtual;
  1512.     procedure CalcDepthPositions; virtual;
  1513.     Function CheckMouse(x,y:Integer):Boolean;
  1514.     Procedure ClearLists; virtual;
  1515.     class Procedure CreateSubGallery(AddSubChart:TChartSubGalleryProc); virtual;
  1516.     procedure DefineProperties(Filer: TFiler); override;
  1517.     Procedure DeletedValue(Source:TChartSeries; ValueIndex:Integer); virtual;
  1518.     procedure DoAfterDrawValues; virtual;
  1519.     procedure DoBeforeDrawValues; virtual;
  1520.     procedure DrawAllValues; virtual;
  1521.     Procedure DrawLegendShape(ValueIndex:Integer; Const Rect:TRect); virtual;
  1522.     Procedure DrawMark(ValueIndex:Integer; Const St:String; APosition:TSeriesMarkPosition); virtual;
  1523.     procedure DrawMarks;
  1524.     procedure DrawValue(ValueIndex:Integer); virtual;
  1525.     Function FirstInZOrder:Boolean;
  1526.     Procedure GetChildren(Proc:TGetChildProc; Root:TComponent); override;
  1527.     Function GetMarkText(ValueIndex:Integer):String;
  1528.     Function GetSeriesColor:TColor;
  1529.     Function GetValueColor(ValueIndex:Integer):TColor; virtual;
  1530.     Function GetxValue(ValueIndex:Integer):Double; virtual;  { conflicts with c++ wingdi.h }
  1531.     Function GetyValue(ValueIndex:Integer):Double; virtual;  { conflicts with c++ wingdi.h }
  1532.     Function InternalColor(ValueIndex:Integer):TColor;
  1533.     Procedure Loaded; override;
  1534.     Function MandatoryAxis:TChartAxis; // 6.02
  1535.     procedure Notification( AComponent: TComponent;
  1536.                             Operation: TOperation); override;
  1537.     Procedure NotifyNewValue(Sender:TChartSeries; ValueIndex:Integer); virtual;
  1538.     Procedure NotifyValue(ValueEvent:TValueEvent; ValueIndex:Integer); virtual;
  1539.     Function MoreSameZOrder:Boolean; virtual;
  1540.     Procedure PrepareForGallery(IsEnabled:Boolean); dynamic;
  1541.     Procedure PrepareLegendCanvas( ValueIndex:Integer; Var BackColor:TColor;
  1542.                                    Var BrushStyle:TBrushStyle); virtual;
  1543.     class Function RandomValue(const Range:Integer):Integer;
  1544.     procedure ReadData(Stream: TStream);
  1545.     Procedure Removed; override;
  1546.     Procedure RemoveLinkedSeries(ASeries:TChartSeries);
  1547.     Procedure SetChartValueList( AValueList:TChartValueList;
  1548.                                  Value:TChartValueList);
  1549.     Procedure SetColorEachPoint(Value:Boolean); virtual;
  1550.     Procedure SetHorizontal;
  1551.     procedure SetMarkText(ValueIndex:Integer; const Value:String); // 7.02
  1552.     Procedure SetParentChart(Const Value:TCustomAxisPanel); override;
  1553.     Procedure SetSeriesColor(AColor:TColor); virtual;
  1554.     class Procedure SetSubGallery(ASeries:TChartSeries; Index:Integer); virtual;
  1555.     Procedure SetXValues(Value:TChartValueList);
  1556.     Procedure SetYValues(Value:TChartValueList);
  1557.     Function ValueListOfAxis(Axis:TChartAxis):TChartValueList; virtual;
  1558.     procedure WriteData(Stream: TStream); dynamic;
  1559.   public
  1560.     CalcVisiblePoints     : Boolean;
  1561.     DrawBetweenPoints     : Boolean;
  1562.     AllowSinglePoint      : Boolean;
  1563.     HasZValues            : Boolean;
  1564.     StartZ                : Integer;
  1565.     MiddleZ               : Integer;
  1566.     EndZ                  : Integer;
  1567.     MandatoryValueList    : TChartValueList;
  1568.     NotMandatoryValueList : TChartValueList;
  1569.     YMandatory            : Boolean;
  1570.     Constructor Create(AOwner: TComponent); override;
  1571.     Destructor Destroy; override;
  1572.     Function Add(Const AValue:Double; Const ALabel:String='';
  1573.                        AColor:TColor=clTeeColor):Integer; virtual;
  1574.     Function AddArray(Const Values:Array of TChartValue):Integer; overload;
  1575.     Function AddNull(Const Value:Double):Integer; overload;
  1576.     Function AddNull(Const ALabel:String=''):Integer; overload; virtual;
  1577.     Function AddNullXY(Const X,Y:Double; Const ALabel:String=''):Integer; virtual;
  1578.     Function AddX(Const AXValue:Double; Const ALabel:String='';
  1579.                          AColor:TColor=clTeeColor):Integer;
  1580.     Function AddXY(Const AXValue,AYValue:Double; Const ALabel:String='';
  1581.                          AColor:TColor=clTeeColor):Integer; virtual;
  1582.     Function AddY(Const AYValue:Double; Const ALabel:String='';
  1583.                          AColor:TColor=clTeeColor):Integer;
  1584.     procedure Assign(Source:TPersistent); override;
  1585.     procedure AssignFormat(Source:TChartSeries);
  1586.     Function AssociatedToAxis(Axis:TChartAxis):Boolean; virtual;
  1587.     Procedure BeginUpdate; 
  1588.     Procedure CheckOrder; dynamic;
  1589.     Procedure Clear; virtual;
  1590.     Function Count:Integer; {$IFOPT C-}{$IFDEF D9}inline;{$ENDIF}{$ENDIF}
  1591.     Function CountLegendItems:Integer; virtual;
  1592.     Procedure Delete(ValueIndex:Integer); overload; virtual;
  1593.     Procedure Delete(Start,Quantity:Integer; RemoveGap:Boolean=False); overload; virtual;
  1594.     Procedure EndUpdate;
  1595.     Procedure FillSampleValues(NumValues:Integer=0); dynamic;
  1596.     Function FirstDisplayedIndex:Integer;
  1597.     Function IsNull(ValueIndex:Integer):Boolean;
  1598.     Function IsValidSourceOf(Value:TChartSeries):Boolean; dynamic;
  1599.     Function IsValidSeriesSource(Value:TChartSeries):Boolean; dynamic;
  1600.     Function LegendToValueIndex(LegendIndex:Integer):Integer; virtual;
  1601.     Function LegendItemColor(LegendIndex:Integer):TColor; virtual;
  1602.     Function LegendString(LegendIndex:Integer; LegendTextStyle:TLegendTextStyle):String; virtual;
  1603.     property LinkedSeries:TCustomSeriesList read FLinkedSeries;
  1604.     Function MaxXValue:Double; virtual;
  1605.     Function MaxYValue:Double; virtual;
  1606.     Function MaxZValue:Double; virtual;
  1607.     Function MinXValue:Double; virtual;
  1608.     Function MinYValue:Double; virtual;
  1609.     Function MinZValue:Double; virtual;
  1610.     Function NumSampleValues:Integer; dynamic;
  1611.     Function RandomBounds(NumValues:Integer):TSeriesRandomBounds;
  1612.     Procedure RemoveDataSource(Value:TComponent);
  1613.     Procedure SetNull(ValueIndex:Integer; Null:Boolean=True); // 6.0
  1614.     Procedure SortByLabels(Order:TChartListOrder=loAscending); // 6.0
  1615.     Function VisibleCount:Integer; { <-- Number of VISIBLE points (Last-First+1) }
  1616.     property ValuesList:TChartValueLists read FValuesList;
  1617.     property XValue[Index:Integer]:Double read GetxValue write SetXValue;
  1618.     property YValue[Index:Integer]:Double read GetyValue write SetYValue;
  1619.     property ZOrder:Integer read GetZOrder write SetZOrder default TeeAutoZOrder;
  1620.     Function MaxMarkWidth:Integer;
  1621.     Function CalcXPos(ValueIndex:Integer):Integer; virtual;
  1622.     Function CalcXPosValue(Const Value:Double):Integer; {$IFDEF D9}inline;{$ENDIF}
  1623.     Function CalcXSizeValue(Const Value:Double):Integer; {$IFDEF D9}inline;{$ENDIF}
  1624.     Function CalcYPos(ValueIndex:Integer):Integer; virtual;
  1625.     Function CalcYPosValue(Const Value:Double):Integer; {$IFDEF D9}inline;{$ENDIF}
  1626.     Function CalcYSizeValue(Const Value:Double):Integer; {$IFDEF D9}inline;{$ENDIF}
  1627.     Function CalcPosValue(Const Value:Double):Integer;
  1628.     Function XScreenToValue(ScreenPos:Integer):Double; {$IFDEF D9}inline;{$ENDIF}
  1629.     Function YScreenToValue(ScreenPos:Integer):Double; {$IFDEF D9}inline;{$ENDIF}
  1630.     Function XValueToText(Const AValue:Double):String;
  1631.     Function YValueToText(Const AValue:Double):String;
  1632.     Procedure ColorRange( AValueList:TChartValueList;
  1633.                           Const FromValue,ToValue:Double;
  1634.                           AColor:TColor);
  1635.     Procedure CheckDataSource;
  1636.     { Public Properties }
  1637.     property Labels:TLabelsList read FLabels;
  1638.     property XLabel[Index:Integer]:String read GetXLabel write SetXLabel;  // deprecated (obsolete)
  1639.     property ValueMarkText[Index:Integer]:String read GetMarkText write SetMarkText;
  1640.     property ValueColor[Index:Integer]:TColor read GetValueColor write SetValueColor;
  1641.     property XValues:TChartValueList read FX write SetXValues;
  1642.     property YValues:TChartValueList read FY write SetYValues;
  1643.     Function GetYValueList(AListName:String):TChartValueList; virtual;
  1644.     property GetVertAxis:TChartAxis read FGetVertAxis;
  1645.     property GetHorizAxis:TChartAxis read FGetHorizAxis;
  1646.     Function MarkPercent(ValueIndex:Integer; AddTotal:Boolean=False):String;
  1647.     Function Clicked(x,y:Integer):Integer; overload; virtual;
  1648.     Function Clicked(P:TPoint):Integer; overload;
  1649.     Procedure RefreshSeries;
  1650.     property FirstValueIndex:Integer read FFirstVisibleIndex;
  1651.     property LastValueIndex:Integer read FLastVisibleIndex;
  1652.     Function GetOriginValue(ValueIndex:Integer):Double; virtual;
  1653.     Function GetMarkValue(ValueIndex:Integer):Double; virtual;
  1654.     Procedure AssignValues(Source:TChartSeries);
  1655.     Function DrawValuesForward:Boolean; virtual;
  1656.     Function DrawSeriesForward(ValueIndex:Integer):Boolean; virtual;
  1657.     procedure SwapValueIndex(a,b:Integer); dynamic;
  1658.     property RecalcOptions: TSeriesRecalcOptions read FRecalcOptions
  1659.                                                  write FRecalcOptions
  1660.                                        default [ rOnDelete,
  1661.                                                  rOnModify,
  1662.                                                  rOnInsert,
  1663.                                                  rOnClear];
  1664.     Function GetCursorValueIndex:Integer;
  1665.     Procedure GetCursorValues(Var XValue,YValue:Double);
  1666.     Procedure DrawLegend(ValueIndex:Integer; Const Rect:TRect); virtual;
  1667.     Function UseAxis:Boolean; virtual;
  1668.     procedure SetFunction(AFunction:TTeeFunction); virtual;
  1669.     property SeriesColor:TColor read GetSeriesColor write SetSeriesColor stored IsColorStored;  // deprecated
  1670.     { other }
  1671.     property DataSources:TDataSourcesList read FDataSources;
  1672.     property FunctionType:TTeeFunction read FTeeFunction write SetFunction;
  1673.     Procedure CheckOtherSeries(Source:TChartSeries);
  1674.     Procedure ReplaceList(OldList,NewList:TChartValueList);
  1675.     property CustomHorizAxis:TChartAxis read FCustomHorizAxis write SetCustomHorizAxis;
  1676.     property CustomVertAxis:TChartAxis read FCustomVertAxis write SetCustomVertAxis;
  1677.     { to be published }
  1678.     property Active;
  1679.     property Color:TColor read GetSeriesColor write SetSeriesColor stored IsColorStored;  // replaces SeriesColor
  1680.     property ColorEachPoint:Boolean read FColorEachPoint write SetColorEachPoint default False;
  1681.     property ColorSource:String read FColorSource write SetColorSource;
  1682.     property Cursor:TCursor read FCursor write FCursor default crDefault;
  1683.     property Depth:Integer read FDepth write SetDepth default TeeAutoDepth;
  1684.     property HorizAxis:THorizAxis read FHorizAxis write SetHorizAxis default aBottomAxis;
  1685.     property Marks:TSeriesMarks read FMarks write SetMarks;
  1686.     property ParentChart;
  1687.     { datasource below parentchart }
  1688.     property DataSource:TComponent read GetDataSource write SetDataSource;
  1689.     property PercentFormat:String read FPercentFormat write SetPercentFormat stored IsPercentFormatStored;
  1690.     property ShowInLegend;
  1691.     property Title;
  1692.     property ValueFormat:String read FValueFormat write SetValueFormat stored IsValueFormatStored;
  1693.     property VertAxis:TVertAxis read FVertAxis write SetVertAxis default aLeftAxis;
  1694.     property XLabelsSource:String read FLabelsSource write SetLabelsSource;
  1695.     { events }
  1696.     property AfterDrawValues:TNotifyEvent read FAfterDrawValues
  1697.                                            write FAfterDrawValues;
  1698.     property BeforeDrawValues:TNotifyEvent read FBeforeDrawValues
  1699.                                            write FBeforeDrawValues;
  1700.     property OnAfterAdd:TSeriesOnAfterAdd read FOnAfterAdd write FOnAfterAdd;
  1701.     property OnBeforeAdd:TSeriesOnBeforeAdd read FOnBeforeAdd write FOnBeforeAdd;
  1702.     property OnClearValues:TSeriesOnClear read FOnClearValues
  1703.                                           write FOnClearValues;
  1704.     property OnClick:TSeriesClick read FOnClick write FOnClick;
  1705.     property OnDblClick:TSeriesClick read FOnDblClick write FOnDblClick;
  1706.     property OnGetMarkText:TSeriesOnGetMarkText read FOnGetMarkText
  1707.                                                 write FOnGetMarkText;
  1708.     property OnMouseEnter:TNotifyEvent read FOnMouseEnter write FOnMouseEnter;
  1709.     property OnMouseLeave:TNotifyEvent read FOnMouseLeave write FOnMouseLeave;
  1710.   end;
  1711.   ChartException=class(Exception);
  1712.   TTeeSeriesSource=class(TComponent)
  1713.   private
  1714.     FActive : Boolean;
  1715.     FSeries : TChartSeries;
  1716.     procedure SetSeries(const Value: TChartSeries);
  1717.   protected
  1718.     Procedure Loaded; override;
  1719.     procedure Notification( AComponent: TComponent;
  1720.                             Operation: TOperation); override;
  1721.     procedure SetActive(const Value: Boolean); virtual;
  1722.   public
  1723.     Constructor Create(AOwner: TComponent); override;
  1724.     Destructor Destroy; override;
  1725.     class Function Available(AChart:TCustomAxisPanel):Boolean; virtual;
  1726.     class Function Description:String; virtual; { bcos BCB, do not make abstract }
  1727.     class Function Editor:TComponentClass; virtual; { bcos BCB, do not make abstract }
  1728.     class Function HasNew:Boolean; virtual;
  1729.     class Function HasSeries(ASeries:TChartSeries):Boolean; virtual;
  1730.     Procedure Close; virtual;
  1731.     Procedure Load; virtual; // abstract;
  1732.     Procedure Open; virtual;
  1733.     Procedure Refresh;
  1734.     property Active:Boolean read FActive write SetActive default False;
  1735.     property Series:TChartSeries read FSeries write SetSeries;
  1736.   end;
  1737.   TTeeSeriesSourceClass=class of TTeeSeriesSource;
  1738. Var TeeAxisClickGap    : Integer=3;    { minimum pixels distance to trigger axis click }
  1739.     TeeDefaultCapacity : Integer=1000; { default TList.Capacity to speed-up Lists }
  1740. Function TeeSources: TList; { List of registered Series Source components }
  1741. Function SeriesTitleOrName(ASeries:TCustomChartSeries):String;
  1742. Procedure FillSeriesItems(AItems:TStrings; AList:TCustomSeriesList; UseTitles:Boolean=True);
  1743. Procedure ShowMessageUser(Const S:String);
  1744. { Returns if a Series has "X" values }
  1745. Function HasNoMandatoryValues(ASeries:TChartSeries):Boolean;
  1746. { Returns True if ASeries has text labels }
  1747. Function HasLabels(ASeries:TChartSeries):Boolean;
  1748. { Returns True if ASeries has colors }
  1749. Function HasColors(ASeries:TChartSeries):Boolean;
  1750. { Returns set indicating Series contents (colors, labels, etc) }
  1751. Function SeriesGuessContents(ASeries:TChartSeries):TeeFormatFlag;
  1752. // Draws the associated series bitmap icon at the specified LeftTop location
  1753. procedure TeeDrawBitmapEditor(Canvas: TCanvas; Element:TCustomChartElement; Left,Top:Integer);
  1754. implementation
  1755. Uses {$IFDEF CLX}
  1756.      QPrinters,
  1757.      {$ELSE}
  1758.      Printers,
  1759.      {$ENDIF}
  1760.      {$IFDEF D6}
  1761.       {$IFNDEF CLX}
  1762.       Types,
  1763.       {$ENDIF}
  1764.      {$ENDIF}
  1765.      {$IFDEF TEEARRAY}
  1766.       {$IFOPT R+}
  1767.        {$IFDEF D6}
  1768.        RtlConsts,
  1769.        {$ELSE}
  1770.        Consts,
  1771.        {$ENDIF}
  1772.       {$ENDIF}
  1773.      {$ENDIF}
  1774.      {$IFNDEF D5}
  1775.      TypInfo,
  1776.      {$ENDIF}
  1777.      Math,
  1778.      TeeHtml, TeeConst;
  1779. { Returns a "good" value, bigger than "OldStep", as 2..5..10..etc }
  1780. Function TeeNextStep(Const OldStep:Double):Double;
  1781. Begin
  1782.   if OldStep >= 10 then result := 10*TeeNextStep(0.1*OldStep)
  1783.   else
  1784.   if OldStep < 1 then result := 0.1*TeeNextStep(OldStep*10)
  1785.   else
  1786.   if OldStep < 2 then result:=2 else
  1787.   if OldStep < 5 then result:=5 else result:=10
  1788. end;
  1789. { Determine what a Series point is made of }
  1790. Function SeriesGuessContents(ASeries:TChartSeries):TeeFormatFlag;
  1791. begin
  1792.   if HasNoMandatoryValues(ASeries) then result:=[tfNoMandatory]
  1793.                                    else result:=[];
  1794.   if HasColors(ASeries) then result:=result+[tfColor];
  1795.   if HasLabels(ASeries) then result:=result+[tfLabel];
  1796.   if ASeries.Marks.Positions.ExistCustom then result:=result+[tfMarkPosition];
  1797. end;
  1798. { TChartAxisTitle }
  1799. Procedure TChartAxisTitle.Assign(Source:TPersistent);
  1800. Begin
  1801.   if Source is TChartAxisTitle then
  1802.   With TChartAxisTitle(Source) do
  1803.   Begin
  1804.     Self.FAngle  :=FAngle;
  1805.     Self.FCaption:=FCaption;
  1806.   end;
  1807.   inherited;
  1808. end;
  1809. Function TChartAxisTitle.IsAngleStored:Boolean;
  1810. begin
  1811.   result:=FAngle<>IDefaultAngle;
  1812. end;
  1813. type TTeePanelAccess=class {$IFDEF CLR}sealed{$ENDIF} (TCustomTeePanel);
  1814. Procedure TChartAxisTitle.SetAngle(const Value:Integer);
  1815. Begin
  1816.   TTeePanelAccess(ParentChart).SetIntegerProperty(FAngle,Value mod 360); { 5.01 }
  1817. end;
  1818. Procedure TChartAxisTitle.SetCaption(Const Value:String);
  1819. Begin
  1820.   TTeePanelAccess(ParentChart).SetStringProperty(FCaption,Value);
  1821. end;
  1822. { TChartAxisPen }
  1823. Constructor TChartAxisPen.Create(OnChangeEvent:TNotifyEvent);
  1824. Begin
  1825.   inherited;
  1826.   Width:=2;
  1827. end;
  1828. {$IFNDEF CLR}
  1829. type
  1830.   TOwnedCollectionAccess=class(TOwnedCollection);
  1831. {$ENDIF}
  1832. { TChartAxis }
  1833. Constructor TChartAxis.Create(Collection:TCollection);
  1834. {$IFDEF CLR}
  1835. var tmp : TCustomAxisPanel;
  1836. {$ENDIF}
  1837. Begin
  1838.   {$IFDEF CLR}
  1839.   tmp:=TCustomAxisPanel(Collection.Owner);
  1840.   if tmp.Axes.Count>=6 then inherited Create(Collection)
  1841.                        else inherited Create(nil);
  1842.   FParentChart:=tmp;
  1843.   {$ELSE}
  1844.   FParentChart:=TCustomAxisPanel(TOwnedCollectionAccess(Collection).GetOwner);
  1845.   if FParentChart.Axes.Count>=TeeInitialCustomAxis then
  1846.      inherited Create(Collection)
  1847.   else
  1848.      inherited Create(nil);
  1849.   {$ENDIF}
  1850.   SetCalcPosValue;
  1851.   ISeriesList:=TCustomSeriesList.Create;
  1852.   FItems:=TAxisItems.Create(Self);
  1853.   FLogarithmicBase:=10;
  1854.   FAutomatic:=True;
  1855.   FAutomaticMaximum:=True;
  1856.   FAutomaticMinimum:=True;
  1857.   FLabelsSeparation:=10; { % }
  1858.   FAxisValuesFormat:=TeeMsg_DefValueFormat;
  1859.   FLabelsAlign:=alDefault;
  1860.   FLabelStyle:=talAuto;
  1861.   FLabelsOnAxis:=True;
  1862.   FTickOnLabelsOnly:=True;
  1863.   FAxisTitle:=TChartAxisTitle.Create(ParentChart);
  1864.   FAxisTitle.IDefaultAngle:=0;
  1865.   FTicks:=TDarkGrayPen.Create(ParentChart.CanvasChanged);
  1866.   FTickLength:=4;
  1867.   FMinorTicks:=TDarkGrayPen.Create(ParentChart.CanvasChanged);
  1868.   FMinorTickLength :=2;
  1869.   FMinorTickCount  :=3;
  1870.   FTicksInner:=TDarkGrayPen.Create(ParentChart.CanvasChanged);
  1871.   FGrid:=TAxisGridPen.Create(ParentChart.CanvasChanged);
  1872.   FMinorGrid:=TChartHiddenPen.Create(ParentChart.CanvasChanged);
  1873.   FAxis:=TChartAxisPen.Create(ParentChart.CanvasChanged);
  1874.   FVisible         :=True;
  1875.   FRoundFirstLabel  :=True;
  1876.   FExactDateTime   :=True;
  1877.   FEndPosition     :=100;
  1878.   FParentChart.FAxes.Add(Self);
  1879. end;
  1880. Destructor TChartAxis.Destroy;
  1881.   Procedure ResetSeriesAxes;
  1882.   var t : Integer;
  1883.   begin
  1884.     With FParentChart do
  1885.     for t:=0 to SeriesCount-1 do
  1886.     With TChartSeries(Series[t]) do
  1887.     begin
  1888.       if CustomHorizAxis=Self then
  1889.       begin
  1890.         CustomHorizAxis:=nil;
  1891.         HorizAxis:=aBottomAxis;
  1892.       end;
  1893.       if CustomVertAxis=Self then
  1894.       begin
  1895.         CustomVertAxis:=nil;
  1896.         VertAxis:=aLeftAxis;
  1897.       end;
  1898.     end;
  1899.   end;
  1900. begin
  1901.   FMinorTicks.Free;
  1902.   FTicks.Free;
  1903.   FTicksInner.Free;
  1904.   FGrid.Free;
  1905.   FMinorGrid.Free;
  1906.   FAxis.Free;
  1907.   FAxisTitle.Free;
  1908.   FItems.Free;
  1909.   ResetSeriesAxes;
  1910.   ISeriesList.Free;
  1911.   FParentChart.FAxes.Remove(Self);
  1912.   Tick:=nil;
  1913.   inherited;
  1914. end;
  1915. Procedure TChartAxis.IncDecDateTime( Increment:Boolean;
  1916.                                            Var Value:Double;
  1917.                                            Const AnIncrement:Double;
  1918.                                            tmpWhichDateTime:TDateTimeStep);
  1919. begin
  1920.   TeeDateTimeIncrement( FExactDateTime and IAxisDateTime and
  1921.                         (tmpWhichDateTime>=dtHalfMonth),
  1922.                         Increment,
  1923.                         Value,
  1924.                         AnIncrement,
  1925.                         tmpWhichDateTime );
  1926. end;
  1927. { An axis is "DateTime" if at least one Active Series with
  1928.   datetime values is associated to it }
  1929. Function TChartAxis.IsDateTime:Boolean;
  1930. Var tmpSeries : Integer;
  1931.     tmpList   : TChartValueList;
  1932. Begin
  1933.   With ParentChart do
  1934.   for tmpSeries:=0 to SeriesCount-1 do
  1935.       With Series[tmpSeries] do
  1936.       if Active then
  1937.       begin
  1938.         tmpList:=ValueListOfAxis(Self);
  1939.         if Assigned(tmpList) then
  1940.         begin
  1941.           result:=tmpList.DateTime;
  1942.           exit;
  1943.         end;
  1944.       end;
  1945.   result:=False;
  1946. end;
  1947. Procedure TChartAxis.SetTicks(Value:TDarkGrayPen);
  1948. Begin
  1949.   FTicks.Assign(Value);
  1950. end;
  1951. Procedure TChartAxis.SetMinorTicks(Value:TDarkGrayPen);
  1952. Begin
  1953.   FMinorTicks.Assign(Value);
  1954. end;
  1955. Procedure TChartAxis.SetTicksInner(Value:TDarkGrayPen);
  1956. Begin
  1957.   FTicksInner.Assign(Value);
  1958. end;
  1959. Procedure TChartAxis.SetGrid(Value:TAxisGridPen);
  1960. Begin
  1961.   FGrid.Assign(Value);
  1962. end;
  1963. Procedure TChartAxis.SetMinorGrid(Value:TChartHiddenPen);
  1964. Begin
  1965.   FMinorGrid.Assign(Value);
  1966. end;
  1967. Procedure TChartAxis.SetGridCentered(Value:Boolean);
  1968. Begin
  1969.   Grid.Centered:=Value;
  1970. end;
  1971. Procedure TChartAxis.SetAxis(Value:TChartAxisPen);
  1972. Begin
  1973.   FAxis.Assign(Value);
  1974. end;
  1975. Function TChartAxis.IsPosStored:Boolean;
  1976. begin
  1977.   result:=FPositionPercent<>0;
  1978. end;
  1979. Function TChartAxis.IsStartStored:Boolean;
  1980. begin
  1981.   result:=FStartPosition<>0;
  1982. end;
  1983. Function TChartAxis.IsEndStored:Boolean;
  1984. begin
  1985.   result:=FEndPosition<>100;
  1986. end;
  1987. Function TChartAxis.IsCustom:Boolean;
  1988. begin
  1989.   result:=ParentChart.Axes.IndexOf(Self)>=TeeInitialCustomAxis;
  1990. end;
  1991. procedure TChartAxis.SetHorizontal(const Value: Boolean);
  1992. begin
  1993.   ParentChart.SetBooleanProperty(FHorizontal,Value);
  1994.   SetCalcPosValue;
  1995. end;
  1996. procedure TChartAxis.SetOtherSide(const Value: Boolean);
  1997. begin
  1998.   ParentChart.SetBooleanProperty(FOtherSide,Value);
  1999. end;
  2000. Function TChartAxis.CalcPosPoint(Value:Integer):Double;
  2001.   Function InternalCalcPos(Const A,B:Double):Double;
  2002.   begin
  2003.     if (Horizontal and FInverted) or
  2004.        ((not Horizontal) and (not FInverted)) then result:=A
  2005.                                               else result:=B
  2006.   end;
  2007. var tmp : Double;
  2008. Begin
  2009.   if FLogarithmic then
  2010.   Begin
  2011.     if Value=IStartPos then result:=InternalCalcPos(IMaximum,IMinimum)
  2012.     else
  2013.     if Value=IEndPos then result:=InternalCalcPos(IMinimum,IMaximum)
  2014.     else
  2015.     begin
  2016.       tmp:=IRangeLog;
  2017.       if (tmp=0) or (IAxisSize=0) then result:=IMinimum // 5.03
  2018.       else
  2019.       begin
  2020.         if FInverted then tmp:=((IEndPos-Value)*tmp/IAxisSize)
  2021.                      else tmp:=((Value-IStartPos)*tmp/IAxisSize);
  2022.         if Horizontal then result:=Exp(ILogMin+tmp)
  2023.                       else result:=Exp(ILogMax-tmp);
  2024.       end;
  2025.     end;
  2026.   end
  2027.   else
  2028.   if IAxisSize>0 then
  2029.   begin
  2030.     if FInverted then tmp:=IEndPos-Value
  2031.                  else tmp:=Value-IStartPos;
  2032.     tmp:=tmp*IRange/IAxisSize;
  2033.     
  2034.     if Horizontal then result:=IMinimum+tmp
  2035.                   else result:=IMaximum-tmp;
  2036.   end
  2037.   else result:=0;
  2038. end;
  2039. Procedure TChartAxis.SetDateTimeFormat(Const Value:String);
  2040. Begin
  2041.   ParentChart.SetStringProperty(FDateTimeFormat,Value);
  2042. end;
  2043. procedure TChartAxis.SetAxisTitle(Value:TChartAxisTitle);
  2044. begin
  2045.   FAxisTitle.Assign(Value);
  2046. end;
  2047. procedure TChartAxis.SetStartPosition(Const Value:Double);
  2048. begin
  2049.   ParentChart.SetDoubleProperty(FStartPosition,Value);
  2050. end;
  2051. procedure TChartAxis.SetEndPosition(Const Value:Double);
  2052. begin
  2053.   ParentChart.SetDoubleProperty(FEndPosition,Value);
  2054. end;
  2055. procedure TChartAxis.SetPositionPercent(Const Value:Double);
  2056. begin
  2057.   ParentChart.SetDoubleProperty(FPositionPercent,Value);
  2058. end;
  2059. procedure TChartAxis.SetRoundFirstLabel(Value:Boolean);
  2060. begin
  2061.   ParentChart.SetBooleanProperty(FRoundFirstLabel,Value);
  2062. end;
  2063. Procedure TChartAxis.SetLabelsMultiLine(Value:Boolean);
  2064. begin
  2065.   ParentChart.SetBooleanProperty(FLabelsMultiLine,Value);
  2066. end;
  2067. Procedure TChartAxis.SetLabelsExponent(Value:Boolean);
  2068. begin
  2069.   ParentChart.SetBooleanProperty(FLabelsExponent,Value);
  2070. end;
  2071. procedure TChartAxis.SetZPosition(const Value: Double);
  2072. begin
  2073.   ParentChart.SetDoubleProperty(FZPosition,Value);
  2074.   if FZPosition=0 then FZPosition:=0.01;  // VCL bug double=0 streaming
  2075. end;
  2076. procedure TChartAxis.SetTickOnLabelsOnly(Value:Boolean);
  2077. begin
  2078.   ParentChart.SetBooleanProperty(FTickOnLabelsOnly,Value);
  2079. end;
  2080. function TChartAxis.CalcDateTimeIncrement(MaxNumLabels:Integer):Double;
  2081. var TempNumLabels : Integer;
  2082. begin
  2083.   result:=Math.Max(FDesiredIncrement,DateTimeStep[Low(DateTimeStep)]);
  2084.   if (result>0) and (MaxNumLabels>0) then
  2085.   begin
  2086.     if (IRange/Result)>1000000 then Result:=IRange/1000000;
  2087.     Repeat
  2088.       TempNumLabels:=Round(IRange/result);
  2089.       if TempNumLabels>MaxNumLabels then
  2090.          if result<DateTimeStep[dtOneYear] then
  2091.          begin
  2092.             if result<DateTimeStep[dtOneSecond] then
  2093.                result:=TeeNextStep(result)  // less than one second
  2094.             else
  2095.                result:=NextDateTimeStep(result) // regular datetime steps
  2096.          end
  2097.          else
  2098.             result:=2.0*result;  // years
  2099.     Until (TempNumLabels<=MaxNumLabels){ or (result=DateTimeStep[dtOneYear])};
  2100.   end;
  2101.   result:=Math.Max(result,DateTimeStep[Low(DateTimeStep)]);
  2102. end;
  2103. {$IFNDEF D6}
  2104. function IsInfinite(const AValue: Double): Boolean;
  2105. begin
  2106.   Result := ((PInt64(@AValue)^ and $7FF0000000000000) = $7FF0000000000000) and
  2107.             ((PInt64(@AValue)^ and $000FFFFFFFFFFFFF) = $0000000000000000);
  2108. end;
  2109. {$ENDIF}
  2110. Function TChartAxis.RoundLogPower(const Value:Double):Double;
  2111. begin
  2112.   result:=Power(LogarithmicBase,Round(LogN(LogarithmicBase,Value))); // 7.0
  2113. end;
  2114. Function TChartAxis.CalcLabelsIncrement(MaxNumLabels:Integer):Double;
  2115.   procedure InternalCalcLabelsIncrement;
  2116.     Function AnySeriesHasLessThan(Num:Integer):Boolean;
  2117.     var t : Integer;
  2118.     begin
  2119.       result:=False;
  2120.       for t:=0 to ParentChart.SeriesCount-1 do
  2121.       with ParentChart[t] do
  2122.       if Active then
  2123.          if (YMandatory and Self.Horizontal) or
  2124.             ((not YMandatory) and (not Self.Horizontal)) then
  2125.            if AssociatedToAxis(Self) then
  2126.            begin
  2127.              result:=Count<=Num;
  2128.              if result then break;
  2129.            end;
  2130.     end;
  2131.   var TempNumLabels : Integer;
  2132.       tmp           : Double;
  2133.       tmpInf        : Boolean;
  2134.   begin
  2135.     TempNumLabels:=MaxNumLabels+1;
  2136.     if FDesiredIncrement<=0 then
  2137.     begin
  2138.       if IRange=0 then result:=1
  2139.       else
  2140.       begin
  2141.         result:=Abs(IRange)/Succ(MaxNumLabels);
  2142.         if Logarithmic then
  2143.            result:=RoundLogPower(result); // 7.0
  2144.         if (IRange>=1) and AnySeriesHasLessThan(MaxNumLabels) then // MS : 7.04
  2145.            result:=Math.Max(1,result);
  2146.       end;
  2147.     end
  2148.     else result:=FDesiredIncrement;
  2149.     tmpInf:=False;
  2150.     if LabelsSeparation>0 then
  2151.     Repeat
  2152.       tmp:=IRange/result;
  2153.       if Abs(tmp)<MaxLongint then
  2154.       begin
  2155.         TempNumLabels:=Round(tmp);
  2156.         if TempNumLabels>MaxNumLabels then
  2157.            if Logarithmic then
  2158.               result:=result*LogarithmicBase
  2159.            else
  2160.               result:=TeeNextStep(result);
  2161.       end
  2162.       else
  2163.       if Logarithmic then
  2164.          result:=result*LogarithmicBase
  2165.       else
  2166.          result:=TeeNextStep(result);
  2167.       tmpInf:=IsInfinite(result);
  2168.     Until (TempNumLabels<=MaxNumLabels) or (result>IRange) or tmpInf;
  2169.     if tmpInf then result:=IRange
  2170.               else result:=Math.Max(result,MinAxisIncrement);
  2171.   end;
  2172. Begin
  2173.   if MaxNumLabels>0 then
  2174.   Begin
  2175.     if IAxisDateTime then result:=CalcDateTimeIncrement(MaxNumLabels)
  2176.                      else InternalCalcLabelsIncrement;
  2177.   end
  2178.   else
  2179.   if IAxisDateTime then result:=DateTimeStep[Low(DateTimeStep)]
  2180.                    else result:=MinAxisIncrement;
  2181. end;
  2182. Function TChartAxis.LabelWidth(Const Value:Double):Integer;
  2183. begin
  2184.   result:=InternalLabelSize(Value,True);
  2185. end;
  2186. Function TChartAxis.LabelHeight(Const Value:Double):Integer;
  2187. begin
  2188.   result:=InternalLabelSize(Value,False);
  2189. end;
  2190. Function TChartAxis.InternalLabelSize(Const Value:Double; IsWidth:Boolean):Integer;
  2191. var tmp      : Integer;
  2192.     tmpMulti : Boolean;
  2193. Begin
  2194.   result:=ParentChart.MultiLineTextWidth(LabelValue(Value),tmp);
  2195.   if IsWidth then
  2196.      tmpMulti:=(FLabelsAngle=90) or (FLabelsAngle=270)
  2197.   else
  2198.      tmpMulti:=(FLabelsAngle=0) or (FLabelsAngle=180);
  2199.   if tmpMulti then result:=ParentChart.Canvas.FontHeight*tmp;
  2200. end;
  2201. Function TChartAxis.IsMaxStored:Boolean;
  2202. Begin { dont store max property if automatic }
  2203.   result:=(not FAutomatic) and (not FAutomaticMaximum);
  2204. end;
  2205. Function TChartAxis.IsMinStored:Boolean;
  2206. Begin{ dont store min property if automatic }
  2207.   result:=(not FAutomatic) and (not FAutomaticMinimum);
  2208. end;
  2209. Function TChartAxis.CalcXYIncrement(MaxLabelSize:Integer):Double;
  2210. var tmp : Integer;
  2211. begin
  2212.   if MaxLabelSize>0 then
  2213.   begin
  2214.     if FLabelsSeparation>0 then
  2215.        Inc(MaxLabelSize,Round(0.01*FLabelsSeparation*MaxLabelSize));
  2216.     tmp:=Round((1.0*IAxisSize)/MaxLabelSize)
  2217.   end
  2218.   else tmp:=1;
  2219.   result:=CalcLabelsIncrement(tmp)
  2220. end;
  2221. Function TChartAxis.CalcIncrement:Double;
  2222. begin
  2223.   result:=CalcXYIncrement(Math.Max(InternalLabelSize(IMinimum,Horizontal),
  2224.                                    InternalLabelSize(IMaximum,Horizontal)));
  2225.   if LabelsAlternate then
  2226.      if Logarithmic then
  2227.         result:=result/LogarithmicBase
  2228.      else
  2229.         result:=result*0.5;
  2230. end;
  2231. Procedure TChartAxis.AdjustMaxMinRect(Const Rect:TRect);
  2232. Var tmpMin : Double;
  2233.     tmpMax : Double;
  2234.   Procedure RecalcAdjustedMinMax(Pos1,Pos2:Integer);
  2235.   Var OldStart : Integer;
  2236.       OldEnd   : Integer;
  2237.   Begin
  2238.     OldStart :=IStartPos;
  2239.     OldEnd   :=IEndPos;
  2240.     Inc(IStartPos,Pos1);
  2241.     Dec(IEndPos,Pos2);
  2242.     IAxisSize:=IEndPos-IStartPos;
  2243.     tmpMin:=CalcPosPoint(OldStart);
  2244.     tmpMax:=CalcPosPoint(OldEnd);
  2245.   end;
  2246. Begin
  2247.   With ParentChart do
  2248.   begin
  2249.     with Rect do
  2250.     if Horizontal then ReCalcAdjustedMinMax(Left,Right)
  2251.                   else ReCalcAdjustedMinMax(Top,Bottom);
  2252.     InternalCalcPositions;
  2253.     IMaximum:=tmpMax;
  2254.     IMinimum:=tmpMin;
  2255.   end;
  2256.   if IMinimum>IMaximum then SwapDouble(IMinimum,IMaximum);
  2257.   InternalCalcRange;
  2258. end;
  2259. Procedure TChartAxis.CalcMinMax(Var AMin,AMax:Double);
  2260. Begin
  2261.   if FAutomatic or FAutomaticMaximum then
  2262.      AMax:=ParentChart.InternalMinMax(Self,False,Horizontal);
  2263.   if FAutomatic or FAutomaticMinimum then
  2264.      AMin:=ParentChart.InternalMinMax(Self,True,Horizontal);
  2265. end;
  2266. Procedure TChartAxis.InternalCalcRange;
  2267. begin
  2268.   IRange:=IMaximum-IMinimum;
  2269.   IRangeZero:=IRange=0;
  2270.   if IRangeZero then IAxisSizeRange:=0
  2271.                 else IAxisSizeRange:=IAxisSize/IRange;
  2272.   if FLogarithmic then
  2273.   begin
  2274.     if IMinimum<=0 then ILogMin:=0 else ILogMin:=ln(IMinimum);
  2275.     if IMaximum<=0 then ILogMax:=0 else ILogMax:=ln(IMaximum);
  2276.     IRangeLog:=ILogMax-ILogMin;
  2277.     if IRangeLog=0 then IAxisLogSizeRange:=0
  2278.                    else IAxisLogSizeRange:=IAxisSize/IRangeLog;
  2279.   end;
  2280.   IZPos:=CalcZPos;
  2281. end;
  2282. Procedure TChartAxis.AdjustMaxMin;
  2283. Begin
  2284.   CalcMinMax(FMinimumValue,FMaximumValue);
  2285.   IMaximum:=FMaximumValue;
  2286.   IMinimum:=FMinimumValue;
  2287.   InternalCalcRange;
  2288. end;
  2289. procedure TChartAxis.Assign(Source: TPersistent);
  2290. Begin
  2291.   if Source is TChartAxis then
  2292.   With TChartAxis(Source) do
  2293.   Begin
  2294.     Self.FAxis.Assign(FAxis);
  2295.     Self.FItems.CopyFrom(FItems);
  2296.     Self.FLabelsAlign         :=FLabelsAlign;
  2297.     Self.FLabelsAlternate     :=FLabelsAlternate;
  2298.     Self.FLabelsAngle         :=FLabelsAngle;
  2299.     Self.FLabelsExponent      :=FLabelsExponent;
  2300.     Self.FLabelsMultiLine     :=FLabelsMultiLine;
  2301.     Self.FLabelsSeparation    :=FLabelsSeparation;
  2302.     Self.FLabelsSize          :=FLabelsSize;
  2303.     Self.FLabelStyle          :=FLabelStyle;
  2304.     Self.FLabelsOnAxis        :=FLabelsOnAxis;
  2305.     Self.Ticks                :=FTicks;
  2306.     Self.TicksInner           :=FTicksInner;
  2307.     Self.FTitleSize           :=FTitleSize;
  2308.     Self.Grid                 :=FGrid;
  2309.     Self.MinorTicks           :=FMinorTicks;
  2310.     Self.MinorGrid            :=FMinorGrid;
  2311.     Self.FTickLength          :=FTickLength;
  2312.     Self.FMinorTickLength     :=FMinorTickLength;
  2313.     Self.FMinorTickCount      :=FMinorTickCount;
  2314.     Self.FTickInnerLength     :=FTickInnerLength;
  2315.     Self.FAxisValuesFormat    :=FAxisValuesFormat;
  2316.     Self.FDesiredIncrement    :=FDesiredIncrement;
  2317.     Self.FMaximumValue        :=FMaximumValue;
  2318.     Self.FMaximumOffset       :=FMaximumOffset;
  2319.     Self.FMinimumValue        :=FMinimumValue;
  2320.     Self.FMinimumOffset       :=FMinimumOffset;
  2321.     Self.FAutomatic           :=FAutomatic;
  2322.     Self.FAutomaticMaximum    :=FAutomaticMaximum;
  2323.     Self.FAutomaticMinimum    :=FAutomaticMinimum;
  2324.     Self.Title                :=FAxisTitle;
  2325.     Self.FDateTimeFormat      :=FDateTimeFormat;
  2326.     Self.GridCentered         :=GridCentered;
  2327.     Self.FLogarithmic         :=FLogarithmic;
  2328.     Self.FLogarithmicBase     :=FLogarithmicBase;
  2329.     Self.FInverted            :=FInverted;
  2330.     Self.FExactDateTime       :=FExactDateTime;
  2331.     Self.FRoundFirstLabel     :=FRoundFirstLabel;
  2332.     Self.FTickOnLabelsOnly    :=FTickOnLabelsOnly;
  2333.     Self.IDepthAxis           :=IDepthAxis;
  2334.     Self.FStartPosition       :=FStartPosition;
  2335.     Self.FEndPosition         :=FEndPosition;
  2336.     Self.FPositionPercent     :=FPositionPercent;
  2337.     Self.FPosUnits            :=FPosUnits;
  2338.     Self.FVisible             :=FVisible;
  2339.     Self.FHorizontal          :=FHorizontal;
  2340.     Self.FOtherSide           :=FOtherSide;
  2341.   end
  2342.   else inherited;
  2343. end;
  2344. Function TChartAxis.LabelValue(Const Value:Double):String;
  2345. var tmp : String;
  2346. Begin
  2347.   if IAxisDateTime then
  2348.   begin
  2349.     if Value>=0 then
  2350.     Begin
  2351.       if FDateTimeFormat='' then tmp:=DateTimeDefaultFormat(IRange)
  2352.                             else tmp:=FDateTimeFormat;
  2353.       DateTimeToString(result,tmp,Value);
  2354.     end
  2355.     else result:='';
  2356.   end
  2357.   else result:=FormatFloat(FAxisValuesFormat,Value);
  2358.   if Assigned(ParentChart.FOnGetAxisLabel) then
  2359.      ParentChart.FOnGetAxisLabel(TChartAxis(Self),nil,-1,Result);
  2360.   if FLabelsMultiLine then
  2361.      result:=ReplaceChar(result,' ',TeeLineSeparator);
  2362. end;
  2363. Function TChartAxis.InternalCalcLabelStyle:TAxisLabelStyle;
  2364. var t : Integer;
  2365. begin
  2366.   result:=talNone;
  2367.   for t:=0 to ParentChart.SeriesCount-1 do
  2368.   With ParentChart.Series[t] do
  2369.   if Active and AssociatedToAxis(Self) then
  2370.   begin
  2371.     result:=talValue;
  2372.     if not HasZValues then // 7.0  (ie: MapSeries should not use text)
  2373.       if (Horizontal and YMandatory) or
  2374.        ((not Horizontal) and (not YMandatory)) then
  2375.        if (FLabels.Count>0) and (FLabels.First<>nil) then
  2376.        begin
  2377.          result:=talText;
  2378.          break;
  2379.        end;
  2380.   end;
  2381. end;
  2382. Function TChartAxis.CalcLabelStyle:TAxisLabelStyle;
  2383. Begin
  2384.  if FLabelStyle=talAuto then result:=InternalCalcLabelStyle
  2385.                         else result:=FLabelStyle;
  2386. End;
  2387. Function TChartAxis.MaxLabelsWidth:Integer;
  2388.   Function MaxLabelsValueWidth:Integer;
  2389.   var tmp    : Double;
  2390.       tmpA   : Double;
  2391.       tmpB   : Double;
  2392.       OldGetAxisLabel : TAxisOnGetLabel;
  2393.       tmpNum : Integer;
  2394.   begin
  2395.     if (IsDateTime and FExactDateTime) or RoundFirstLabel then
  2396.     begin
  2397.       tmp:=CalcIncrement;
  2398.       tmpA:=tmp*Int(IMinimum/tmp);
  2399.       tmpB:=tmp*Int(IMaximum/tmp);
  2400.     end
  2401.     else
  2402.     begin
  2403.       tmpA:=IMinimum;
  2404.       tmpB:=IMaximum;
  2405.     end;
  2406.     With ParentChart do
  2407.     begin
  2408.       OldGetAxisLabel:=FOnGetAxisLabel;
  2409.       FOnGetAxisLabel:=nil;
  2410.       With Canvas do
  2411.            result:=TextWidth(' ')+
  2412.                    Math.Max(MultiLineTextWidth(LabelValue(tmpA),tmpNum),
  2413.                             MultiLineTextWidth(LabelValue(tmpB),tmpNum));
  2414.       FOnGetAxisLabel:=OldGetAxisLabel;
  2415.     end;
  2416.   end;
  2417. var t   : Integer;
  2418.     tmp : Integer;
  2419. begin
  2420.   if Items.Count=0 then
  2421.     Case CalcLabelStyle of
  2422.       talValue : result:=MaxLabelsValueWidth;
  2423.       talMark  : result:=ParentChart.MaxMarkWidth;
  2424.       talText  : result:=ParentChart.MaxTextWidth;
  2425.     else
  2426.     {talNone : } result:=0;
  2427.     end
  2428.   else
  2429.   begin
  2430.     result:=0;
  2431.     for t:=0 to Items.Count-1 do
  2432.     begin
  2433.       ParentChart.Canvas.AssignFont(Items[t].Font);
  2434.       result:=Max(result,ParentChart.MultiLineTextWidth(Items[t].Text,tmp));
  2435.     end;
  2436.   end;
  2437. end;
  2438. Function TChartAxis.GetLabels:Boolean;
  2439. begin
  2440.   result:=FItems.Format.Visible;
  2441. end;
  2442. Function TChartAxis.GetLabelsFont:TTeeFont;
  2443. begin
  2444.   result:=FItems.Format.Font;
  2445. end;
  2446. Procedure TChartAxis.SetLabels(Value:Boolean);
  2447. Begin
  2448.   FItems.Format.Visible:=Value;
  2449. end;
  2450. Procedure TChartAxis.SetLabelsFont(Value:TTeeFont);
  2451. begin
  2452.   FItems.Format.Font:=Value;
  2453. end;
  2454. Function TChartAxis.DepthAxisAlign:Integer;
  2455. begin
  2456.   if OtherSide then result:=TA_LEFT
  2457.                else result:=TA_RIGHT;
  2458. end;
  2459. Function TChartAxis.DepthAxisPos:Integer;
  2460. begin
  2461.   if OtherSide then
  2462.      result:=ParentChart.ChartRect.Bottom-CalcZPos  // 7.04
  2463.   else
  2464.      result:=ParentChart.ChartRect.Top+CalcZPos // 7.04 TV52010193
  2465. end;
  2466. Procedure TChartAxis.SetAutomatic(Value:Boolean);
  2467. Begin
  2468.   ParentChart.SetBooleanProperty(FAutomatic,Value);
  2469.   if not (csLoading in ParentChart.ComponentState) then
  2470.   begin
  2471.     FAutomaticMinimum:=Value;
  2472.     FAutomaticMaximum:=Value;
  2473.   end;
  2474. end;
  2475. Procedure TChartAxis.SetAutoMinMax(Var Variable:Boolean; Var2,Value:Boolean);
  2476. Begin
  2477.   ParentChart.SetBooleanProperty(Variable,Value);
  2478.   if Value then
  2479.   begin { if both are automatic, then Automatic should be True too }
  2480.     if Var2 then FAutomatic:=True;
  2481.   end
  2482.   else FAutomatic:=False;
  2483. end;
  2484. Procedure TChartAxis.SetAutomaticMinimum(Value:Boolean);
  2485. Begin
  2486.   SetAutoMinMax(FAutomaticMinimum,FAutomaticMaximum,Value);
  2487. end;
  2488. Procedure TChartAxis.SetAutomaticMaximum(Value:Boolean);
  2489. Begin
  2490.   SetAutoMinMax(FAutomaticMaximum,FAutomaticMinimum,Value);
  2491. end;
  2492. Function TChartAxis.IsAxisValuesFormatStored:Boolean;
  2493. begin
  2494.   result:=FAxisValuesFormat<>TeeMsg_DefValueFormat;
  2495. end;
  2496. Procedure TChartAxis.SetValuesFormat(Const Value:String);
  2497. Begin
  2498.   ParentChart.SetStringProperty(FAxisValuesFormat,Value);
  2499. end;
  2500. Procedure TChartAxis.SetInverted(Value:Boolean);
  2501. Begin
  2502.   ParentChart.SetBooleanProperty(FInverted,Value);
  2503. end;
  2504. Procedure TChartAxis.InternalSetInverted(Value:Boolean);
  2505. Begin
  2506.   FInverted:=Value;
  2507. end;
  2508. Procedure TChartAxis.SetLogarithmicBase(const Value:Double);
  2509. begin
  2510.   if (Value=1) or (Value<=0) then
  2511.      raise AxisException.Create(TeeMsg_AxisLogBase);
  2512.   ParentChart.SetDoubleProperty(FLogarithmicBase,Value);
  2513. end;
  2514. Procedure TChartAxis.SetLogarithmic(Value:Boolean);
  2515. Begin
  2516.   if Value and IsDateTime then
  2517.      Raise AxisException.Create(TeeMsg_AxisLogDateTime);
  2518.   if Value then
  2519.   begin
  2520.     AdjustMaxMin;
  2521.     if ((IMinimum<0) or (IMaximum<0)) then
  2522.        Raise AxisException.Create(TeeMsg_AxisLogNotPositive);
  2523.   end;
  2524.   ParentChart.SetBooleanProperty(FLogarithmic,Value);
  2525.   SetCalcPosValue;
  2526. end;
  2527. Procedure TChartAxis.SetCalcPosValue;
  2528. begin
  2529.   if IDepthAxis then
  2530.   begin
  2531.     CalcXPosValue:=InternalCalcDepthPosValue;
  2532.     CalcYPosValue:=InternalCalcDepthPosValue;
  2533.   end
  2534.   else
  2535.   if Logarithmic then
  2536.   begin
  2537.     CalcXPosValue:=LogXPosValue;
  2538.     CalcYPosValue:=LogYPosValue;
  2539.   end
  2540.   else
  2541.   begin
  2542.     if ParentChart.Axes.IFastCalc then
  2543.     begin
  2544.       CalcXPosValue:=XPosValue;
  2545.       CalcYPosValue:=YPosValue;
  2546.     end
  2547.     else
  2548.     begin
  2549.       CalcXPosValue:=XPosValueCheck;
  2550.       CalcYPosValue:=YPosValueCheck;
  2551.     end;
  2552.   end;
  2553.   if Horizontal then CalcPosValue:=CalcXPosValue
  2554.                 else CalcPosValue:=CalcYPosValue;
  2555. end;
  2556. Procedure TChartAxis.SetLabelsAlign(Value:TAxisLabelAlign);
  2557. Begin
  2558.   if FLabelsAlign<>Value then
  2559.   begin
  2560.     FLabelsAlign:=Value;
  2561.     ParentChart.Invalidate;
  2562.   end;
  2563. end;
  2564. Procedure TChartAxis.SetLabelsAlternate(Value:Boolean);
  2565. Begin
  2566.   ParentChart.SetBooleanProperty(FLabelsAlternate,Value);
  2567. end;
  2568. Procedure TChartAxis.SetLabelsAngle(const Value:Integer);
  2569. Begin
  2570.   ParentChart.SetIntegerProperty(FLabelsAngle,Value mod 360);
  2571. end;
  2572. Procedure TChartAxis.SetLabelsSeparation(Value:Integer);
  2573. Begin
  2574.   if Value<0 then Raise AxisException.Create(TeeMsg_AxisLabelSep);
  2575.   ParentChart.SetIntegerProperty(FLabelsSeparation,Value);
  2576. end;
  2577. Procedure TChartAxis.SetLabelsSize(Value:Integer);
  2578. Begin
  2579.   ParentChart.SetIntegerProperty(FLabelsSize,Value);
  2580. end;
  2581. Procedure TChartAxis.SetTitleSize(Value:Integer);
  2582. Begin
  2583.   ParentChart.SetIntegerProperty(FTitleSize,Value);
  2584. end;
  2585. Procedure TChartAxis.SetLabelsOnAxis(Value:Boolean);
  2586. Begin
  2587.   ParentChart.SetBooleanProperty(FLabelsOnAxis,Value);
  2588. end;
  2589. Procedure TChartAxis.SetExactDateTime(Value:Boolean);
  2590. begin
  2591.   ParentChart.SetBooleanProperty(FExactDateTime,Value);
  2592. end;
  2593. Procedure TChartAxis.SetLabelStyle(Value:TAxisLabelStyle);
  2594. begin
  2595.   if FLabelStyle<>Value then
  2596.   begin
  2597.     FLabelStyle:=Value;
  2598.     ParentChart.Invalidate;
  2599.   end;
  2600. end;
  2601. Procedure TChartAxis.SetVisible(Value:Boolean);
  2602. Begin
  2603.   ParentChart.SetBooleanProperty(FVisible,Value);
  2604. end;
  2605. Procedure TChartAxis.SetDesiredIncrement(Const Value:Double);
  2606. Begin
  2607.   {$IFNDEF CLR}
  2608.   if Value<0 then Raise AxisException.Create(TeeMsg_AxisIncrementNeg);
  2609.   {$ENDIF}
  2610.   
  2611.   if IsDateTime then DateTimeToStr(Value);
  2612.   ParentChart.SetDoubleProperty(FDesiredIncrement,Value);
  2613. end;
  2614. Procedure TChartAxis.SetMinimum(Const Value:Double);
  2615. Begin
  2616.   if (not (csReading in ParentChart.ComponentState)) and
  2617.      (Value>FMaximumValue) then
  2618.        Raise AxisException.Create(TeeMsg_AxisMinMax);
  2619.   InternalSetMinimum(Value);
  2620. end;
  2621. Procedure TChartAxis.InternalSetMinimum(Const Value:Double);
  2622. Begin
  2623.   ParentChart.SetDoubleProperty(FMinimumValue,Value);
  2624. end;
  2625. Procedure TChartAxis.SetMaximum(Const Value:Double);
  2626. Begin
  2627.   if (not (csReading in ParentChart.ComponentState)) and
  2628.      (Value<FMinimumValue) then
  2629.        Raise AxisException.Create(TeeMsg_AxisMaxMin);
  2630.   InternalSetMaximum(Value);
  2631. end;
  2632. Procedure TChartAxis.SetMinMax(AMin,AMax:Double);
  2633. Begin
  2634.   FAutomatic:=False;
  2635.   FAutomaticMinimum:=False;
  2636.   FAutomaticMaximum:=False;
  2637.   if AMin>AMax then SwapDouble(AMin,AMax);
  2638.   InternalSetMinimum(AMin);
  2639.   InternalSetMaximum(AMax);
  2640.   if (FMaximumValue-FMinimumValue)<MinAxisRange then
  2641.      InternalSetMaximum(FMinimumValue+MinAxisRange);
  2642.   ParentChart.CustomAxes.ResetScales(Self);
  2643. end;
  2644. Procedure TChartAxis.InternalSetMaximum(Const Value:Double);
  2645. Begin
  2646.   ParentChart.SetDoubleProperty(FMaximumValue,Value);
  2647. end;
  2648. Procedure TChartAxis.SetTickLength(Value:Integer);
  2649. Begin
  2650.   ParentChart.SetIntegerProperty(FTickLength,Value);
  2651. end;
  2652. Procedure TChartAxis.SetMinorTickLength(Value:Integer);
  2653. Begin
  2654.   ParentChart.SetIntegerProperty(FMinorTickLength,Value);
  2655. end;
  2656. Procedure TChartAxis.SetMinorTickCount(Value:Integer);
  2657. Begin
  2658.   ParentChart.SetIntegerProperty(FMinorTickCount,Value);
  2659. End;
  2660. Procedure TChartAxis.SetTickInnerLength(Value:Integer);
  2661. Begin
  2662.   ParentChart.SetIntegerProperty(FTickInnerLength,Value);
  2663. end;
  2664. Procedure TChartAxis.DrawTitle(x,y:Integer);
  2665. var Old : Boolean;
  2666. begin
  2667.   With ParentChart,Canvas do
  2668.   begin
  2669.     AssignFont(FAxisTitle.Font);
  2670.     BackMode:=cbmTransparent;
  2671.     if IsDepthAxis then
  2672.     begin
  2673.       TextAlign:=DepthAxisAlign;
  2674.       TextOut3D(x,y,Width3D div 2,FAxisTitle.FCaption);
  2675.     end
  2676.     else
  2677.     begin
  2678.       Old:=FLabelsExponent;
  2679.       FLabelsExponent:=False;  // 5.02
  2680.       DrawAxisLabel(x,y,FAxisTitle.FAngle,FAxisTitle.FCaption);
  2681.       FLabelsExponent:=Old;
  2682.     end;
  2683.   end;
  2684. end;
  2685. // pending: cache into variable (for speed)
  2686. Function TChartAxis.CalcZPos:Integer;
  2687. begin
  2688.   if IDepthAxis then result:=ParentChart.ChartHeight
  2689.                 else result:=ParentChart.Width3D;
  2690.   result:=Round(result*ZPosition*0.01); // 6.0
  2691. end;
  2692. procedure TChartAxis.DrawAxisLabel(x,y,Angle:Integer; Const St:String; Format:TTeeCustomShape=nil);
  2693. Const Aligns:Array[Boolean,Boolean] of Integer=(
  2694.               (TA_RIGHT +TA_TOP, TA_LEFT  +TA_TOP    ),    { vertical }
  2695.               (TA_CENTER+TA_TOP, TA_CENTER+TA_BOTTOM ) );  { horizontal }
  2696. Var tmpSt2 : String;
  2697.     tmpZ   : Integer;
  2698.   Procedure DrawExponentLabel;
  2699.   var tmpW : Integer;
  2700.       tmpH : Integer;
  2701.       i    : Integer;
  2702.       tmp  : String;
  2703.       tmpSub : String;
  2704.       Old  : Integer;
  2705.   begin
  2706.     i:=Pos('E',Uppercase(tmpSt2));
  2707.     With ParentChart.Canvas do
  2708.     if i=0 then TextOut3D(x,y,tmpZ,tmpSt2)
  2709.     else
  2710.     begin
  2711.       tmp:=Copy(tmpSt2,1,i-1);
  2712.       tmpSub:=Copy(tmpSt2,i+1,Length(tmpSt2)-1);
  2713.       tmpH:=FontHeight-1;
  2714.       Old:=Font.Size;
  2715.       if TextAlign=TA_LEFT then
  2716.       begin
  2717.         TextOut3D(x,y,tmpZ,tmp);
  2718.         tmpW:=TextWidth(tmp)+1;
  2719.         Font.Size:=Font.Size-(Font.Size div 4);
  2720.         TextOut3D(x+tmpW,y-(tmpH div 2)+2,tmpZ,tmpSub);
  2721.       end
  2722.       else
  2723.       begin
  2724.         Font.Size:=Font.Size-(Font.Size div 4);
  2725.         TextOut3D(x,y-(tmpH div 2)+2,tmpZ,tmpSub);
  2726.         tmpW:=TextWidth(tmpSub)+1;
  2727.         Font.Size:=Old;
  2728.         TextOut3D(x-tmpW,y,tmpZ,tmp);
  2729.       end;
  2730.       Font.Size:=Old;
  2731.     end;
  2732.   end;
  2733.   { Returns 1 + how many times "TeeLineSeparator #13" is found
  2734.     inside string St parameter }
  2735.   Function TeeNumTextLines(St:String):Integer;
  2736.   var i : Integer;
  2737.   begin
  2738.     result:=0;
  2739.     i:={$IFDEF CLR}Pos{$ELSE}AnsiPos{$ENDIF}(TeeLineSeparator,St);
  2740.     while i>0 do
  2741.     begin
  2742.       Inc(result);
  2743.       Delete(St,1,i);
  2744.       i:={$IFDEF CLR}Pos{$ELSE}AnsiPos{$ENDIF}(TeeLineSeparator,St);
  2745.     end;
  2746.     if St<>'' then Inc(result);
  2747.   end;
  2748. var Delta    : Integer;
  2749.     t        : Integer;
  2750.     n        : Integer;
  2751.     i        : Integer;
  2752.     tmp      : Double;
  2753.     tmpSt    : String;
  2754.     tmpH     : Integer;
  2755.     tmpD     : Integer;
  2756.     tmpAlign : TCanvasTextAlign;
  2757.     tmpAlign2: TCanvasTextAlign;
  2758.     tmpW     : Integer;
  2759.     tmpNum   : Integer;
  2760.     tmpSize  : Integer;
  2761.     tmpDraw  : Boolean;
  2762. begin
  2763.   tmpH:=ParentChart.Canvas.FontHeight div 2;
  2764.   Case Angle of
  2765.  0,360: begin
  2766.           if Horizontal or (FLabelsAlign=alDefault) then
  2767.              tmpAlign:=Aligns[Horizontal,OtherSide]
  2768.           else
  2769.             if OtherSide then
  2770.             begin
  2771.               tmpAlign:=TA_RIGHT;
  2772.               Inc(X,SizeLabels);
  2773.             end
  2774.             else
  2775.             begin
  2776.               tmpAlign:=TA_LEFT;
  2777.               Dec(X,SizeLabels);
  2778.             end;
  2779.           if not Horizontal then Dec(Y,tmpH);
  2780.         end;
  2781.     90: begin
  2782.           if Horizontal then
  2783.           begin
  2784.             tmpAlign:=Aligns[False,OtherSide];
  2785.             Dec(X,tmpH);
  2786.           end
  2787.           else tmpAlign:=Aligns[True,not OtherSide];
  2788.         end;
  2789.    180: begin
  2790.           tmpAlign:=Aligns[Horizontal,not OtherSide];
  2791.           if not Horizontal then Inc(Y,tmpH);
  2792.         end;
  2793.    270: begin
  2794.           if Horizontal then
  2795.           begin
  2796.             tmpAlign:=Aligns[False,not OtherSide];
  2797.             Inc(X,tmpH);
  2798.           end
  2799.           else tmpAlign:=Aligns[True,OtherSide];
  2800.         end;
  2801.     45: begin // 5.03
  2802.           tmpAlign:=TA_LEFT;
  2803.           if Horizontal then
  2804.           begin
  2805.             if OtherSide then
  2806.             begin
  2807.               i:=Round(ParentChart.Canvas.TextWidth('Wj'));
  2808.               Dec(x,i);
  2809.               Dec(y,i);
  2810.             end
  2811.             else
  2812.             begin
  2813.               tmp:=Sin(Angle*TeePiStep);
  2814.               i:=Round(ParentChart.Canvas.TextWidth(St)*tmp);
  2815.               Dec(x,i);
  2816.               Inc(y,i);
  2817.             end;
  2818.           end;
  2819.         end;
  2820.    else
  2821.    begin
  2822.      tmpAlign:=TA_LEFT; { non-supported angles }
  2823.    end;
  2824.   end;
  2825.   tmpZ:=IZPos; // 6.0
  2826.   n:=TeeNumTextLines(St);
  2827.   Delta:=ParentChart.Canvas.FontHeight;
  2828.   if (Angle=180) or (Angle=270) then Delta:=-Delta;
  2829.   tmpD:=Round(Delta*n);
  2830.   if Horizontal then
  2831.   begin
  2832.     if Angle=0 then
  2833.        if OtherSide then y:=y-tmpD else y:=y-Delta
  2834.     else
  2835.     if Angle=180 then
  2836.        if OtherSide then y:=y-Delta else y:=y-tmpD
  2837.     else
  2838.     if (Angle=90) or (Angle=270) then
  2839.        x:=x-Round(0.5*Delta*(n+1));
  2840.   end
  2841.   else
  2842.     if (Angle=0) or (Angle=180) then
  2843.        y:=y-Round(0.5*Delta*(n+1))
  2844.     else
  2845.     if OtherSide then
  2846.     begin
  2847.        if Angle=90 then x:=x-Delta
  2848.                    else if Angle=270 then x:=x-tmpD
  2849.     end
  2850.     else
  2851.     if Angle=90 then x:=x-tmpD
  2852.                 else if Angle=270 then x:=x-Delta;
  2853.     // 6.0
  2854.     if not Assigned(Format) then Format:=FItems.Format;
  2855.     with Format do
  2856.     if not Transparent then
  2857.     begin
  2858.       with ShapeBounds do
  2859.       begin
  2860.         tmpSize:=Self.ParentChart.Canvas.TextWidth('W') shr 1;
  2861.         Left:=x;
  2862.         Top:=y+Delta;
  2863.         tmpW:=Self.ParentChart.MultiLineTextWidth(St,tmpNum);
  2864.         tmpH:=ParentChart.Canvas.FontHeight*tmpNum;
  2865.         tmpAlign2:=tmpAlign;
  2866.         if tmpAlign2>=TA_BOTTOM then
  2867.         begin
  2868.           Dec(Top,tmpH);
  2869.           Dec(tmpAlign2,TA_BOTTOM);
  2870.         end;
  2871.         Bottom:=Top+tmpH;
  2872.         Right:=Left+tmpW;
  2873.         if tmpAlign2=TA_RIGHT then
  2874.         begin
  2875.           Right:=Left;
  2876.           Left:=Right-tmpW;
  2877.         end
  2878.         else
  2879.         if tmpAlign2=TA_CENTER then
  2880.         begin
  2881.           tmpW:=(Right-Left) div 2;
  2882.           Dec(Right,tmpW);
  2883.           Dec(Left,tmpW);
  2884.         end;
  2885.         Dec(Left,tmpSize);
  2886.         Inc(Right,tmpSize);
  2887.       end;
  2888.       if tmpZ<>0 then ShapeBounds:=ParentChart.Canvas.CalcRect3D(ShapeBounds,tmpZ);
  2889.       DrawRectRotated(ShapeBounds,FLabelsAngle,tmpZ);
  2890.       with ParentChart.Canvas do
  2891.       begin
  2892.         // trick
  2893.         Brush.Style:=bsSolid;
  2894.         Brush.Style:=bsClear;
  2895.         {$IFDEF CLX}
  2896.         BackMode:=cbmTransparent;
  2897.         {$ENDIF}
  2898.       end;
  2899.     end;
  2900.   ParentChart.Canvas.TextAlign:=tmpAlign;
  2901.   tmpSt:=St;
  2902.   tmpDraw:=True;
  2903.   if Assigned(FOnDrawLabel) then  // 7.0
  2904.   begin
  2905.     FOnDrawLabel(Self,X,Y,tmpZ,tmpSt,tmpDraw);
  2906.     if tmpDraw then
  2907.        n:=TeeNumTextLines(tmpSt);
  2908.   end;
  2909.   if tmpDraw then // 7.0
  2910.   for t:=1 to n do
  2911.   begin
  2912.     i:={$IFDEF CLR}Pos{$ELSE}AnsiPos{$ENDIF}(TeeLineSeparator,tmpSt);
  2913.     if i>0 then tmpSt2:=Copy(tmpSt,1,i-1) else tmpSt2:=tmpSt;
  2914.     if Angle=0 then
  2915.     begin
  2916.       y:=y+Delta;
  2917.       if FLabelsExponent then DrawExponentLabel
  2918.                          else ParentChart.Canvas.TextOut3D(X,Y,tmpZ,tmpSt2);
  2919.     end
  2920.     else
  2921.     begin
  2922.       if Angle=180 then y:=y+Delta
  2923.       else
  2924.       if (Angle=90) or (Angle=270) then x:=x+Delta;
  2925.       ParentChart.Canvas.RotateLabel3D(X,Y,tmpZ,tmpSt2,Angle);
  2926.     end;
  2927.     Delete(tmpSt,1,i);
  2928.   end;
  2929.   ParentChart.Canvas.TextAlign:=TA_LEFT;
  2930. end;
  2931. Procedure TChartAxis.Scroll(Const Offset:Double; CheckLimits:Boolean=False);
  2932. Begin
  2933.   if (not CheckLimits) or
  2934.      ( ((Offset>0) and (FMaximumValue<ParentChart.InternalMinMax(Self,False,Horizontal))) or
  2935.        ((Offset<0) and (FMinimumValue>ParentChart.InternalMinMax(Self,True,Horizontal)))
  2936.      ) then
  2937.   begin
  2938.     FAutomatic:=False;
  2939.     FAutomaticMaximum:=False;
  2940.     FMaximumValue:=FMaximumValue+Offset;
  2941.     FAutomaticMinimum:=False;
  2942.     FMinimumValue:=FMinimumValue+Offset;
  2943.     ParentChart.Invalidate;
  2944.   end;
  2945. end;
  2946. Function TChartAxis.InternalCalcDepthPosValue(Const Value:TChartValue):Integer;
  2947. begin
  2948.   if IRangeZero then result:=ICenterPos
  2949.   else
  2950.   if FInverted then result:=Round(IAxisSizeRange*(IMaximum-Value))
  2951.                else result:=Round(IAxisSizeRange*(Value-IMinimum));
  2952. end;
  2953. Function TChartAxis.LogXPosValue(Const Value:TChartValue):Integer;
  2954. begin
  2955.   if IRangeLog=0 then result:=ICenterPos
  2956.   else
  2957.   begin
  2958.     if Value<=0 then
  2959.        if FInverted then result:=IEndPos
  2960.                     else result:=IStartPos
  2961.     else
  2962.     begin
  2963.       if FInverted then result:=Round((ILogMax-ln(Value))*IAxisLogSizeRange)
  2964.                    else result:=Round((ln(Value)-ILogMin)*IAxisLogSizeRange);
  2965.       result:=IStartPos+result;
  2966.     end;
  2967.   end;
  2968. end;
  2969. Function TChartAxis.LogYPosValue(Const Value:TChartValue):Integer;
  2970. begin
  2971.   if IRangeLog=0 then result:=ICenterPos
  2972.   else
  2973.   begin
  2974.     if Value<=0 then
  2975.        if not FInverted then result:=IEndPos
  2976.                         else result:=IStartPos
  2977.     else
  2978.     begin
  2979.       if FInverted then result:=Round((ILogMax-ln(Value))*IAxisLogSizeRange)
  2980.                    else result:=Round((ln(Value)-ILogMin)*IAxisLogSizeRange);
  2981.       result:=IEndPos-result;
  2982.     end;
  2983.   end;
  2984. end;
  2985. // The following routines perform axis calculations WITH overflow checking
  2986. // to avoid Windows GDI limits on pixel coordinates.
  2987. // See below for faster routines.
  2988. //
  2989. // To switch between slow and fast, use Chart1.Axes.FastCalc property.
  2990. var TeeMaxPixelPos:Integer=0;
  2991. Function TChartAxis.XPosValueCheck(Const Value:TChartValue):Integer;
  2992. var tmp : Double;
  2993. begin
  2994.   if IRangeZero then result:=ICenterPos
  2995.   else
  2996.   begin
  2997.     tmp:=(Value-IMinimum)*IAxisSizeRange;
  2998.     if FInverted then tmp:=IEndPos-tmp
  2999.                  else tmp:=IStartPos+tmp;
  3000.     if tmp> TeeMaxPixelPos then result:=TeeMaxPixelPos
  3001.     else
  3002.     if tmp<-TeeMaxPixelPos then result:=-TeeMaxPixelPos
  3003.     else
  3004.        result:=Round(tmp);
  3005.   end;
  3006. end;
  3007. Function TChartAxis.YPosValueCheck(Const Value:TChartValue):Integer;
  3008. var tmp : Double;
  3009. begin
  3010.   if IRangeZero then result:=ICenterPos
  3011.   else
  3012.   begin
  3013.     tmp:=(Value-IMinimum)*IAxisSizeRange;
  3014.     if FInverted then tmp:=IStartPos+tmp
  3015.                  else tmp:=IEndPos-tmp;
  3016.     if tmp> TeeMaxPixelPos then result:= TeeMaxPixelPos
  3017.     else
  3018.     if tmp<-TeeMaxPixelPos then result:=-TeeMaxPixelPos
  3019.     else
  3020.        result:=Round(tmp);
  3021.   end;
  3022. end;
  3023. // The following routines perform axis calculations WITHOUT overflow checking.
  3024. // These are 5 to 10% faster than the above ones.
  3025. // See above for slower (with checking) routines.
  3026. //
  3027. // To switch between slow and fast, use Chart1.Axes.FastCalc property.
  3028. Function TChartAxis.XPosValue(Const Value:TChartValue):Integer;
  3029. begin
  3030.   if IRangeZero then result:=ICenterPos
  3031.   else
  3032.   begin
  3033.     {$IFNDEF TEENOASM}
  3034.     asm
  3035.       fld Value
  3036.       fsub qword ptr [eax+IMinimum]
  3037.       {$IFDEF TEEVALUESINGLE}
  3038.       fmul dword ptr [eax+IAxisSizeRange]
  3039.       sub esp, 4
  3040.       fistp dword ptr [esp]
  3041.       pop [result]
  3042.       {$ELSE}
  3043.       fmul qword ptr [eax+IAxisSizeRange]
  3044.       sub esp, 8
  3045.       fistp qword ptr [esp]
  3046.       pop [result]
  3047.       pop ecx
  3048.       {$ENDIF}
  3049.     end;
  3050.     if Inverted then result:=IEndPos  -result
  3051.                 else Inc(result,IStartPos);
  3052.     {$ELSE}
  3053.     if FInverted then
  3054.        result:=IEndPos  -Round( (Value-IMinimum)*IAxisSizeRange )
  3055.     else
  3056.        result:=IStartPos+Round( (Value-IMinimum)*IAxisSizeRange );
  3057.     {$ENDIF}
  3058.   end;
  3059. end;
  3060. Function TChartAxis.YPosValue(Const Value:TChartValue):Integer;
  3061. begin
  3062.   if IRangeZero then result:=ICenterPos
  3063.   else
  3064.   begin
  3065.     {$IFNDEF TEENOASM}
  3066.     asm
  3067.       fld Value
  3068.       fsub qword ptr [eax+IMinimum]
  3069.       {$IFDEF TEEVALUESINGLE}
  3070.       fmul dword ptr [eax+IAxisSizeRange]
  3071.       sub esp, 4
  3072.       fistp dword ptr [esp]
  3073.       pop [result]
  3074.       {$ELSE}
  3075.       fmul qword ptr [eax+IAxisSizeRange]
  3076.       sub esp, 8
  3077.       fistp qword ptr [esp]
  3078.       pop [result]
  3079.       pop ecx
  3080.       {$ENDIF}
  3081.     end;
  3082.     if Inverted then Inc(result,IStartPos)
  3083.                 else result:=IEndPos  -result;
  3084.     {$ELSE}
  3085.     if FInverted then
  3086.        result:=IStartPos+Round( (Value-IMinimum)*IAxisSizeRange )
  3087.     else
  3088.        result:=IEndPos  -Round( (Value-IMinimum)*IAxisSizeRange )
  3089.     {$ENDIF}
  3090.   end;
  3091. end;
  3092. Function TChartAxis.CalcSizeValue(Const Value:Double):Integer;
  3093. begin
  3094.   result:=0;
  3095.   if Value>0 then
  3096.     if FLogarithmic then
  3097.     Begin
  3098.       if IRangeLog<>0 then result:=Round(ln(Value)*IAxisLogSizeRange);
  3099.     end
  3100.     else
  3101.     if IRange<>0 then result:=Round(Value*IAxisSizeRange);
  3102. end;
  3103. Function TChartAxis.AxisRect:TRect;
  3104. Var tmpPos1 : Integer;
  3105.     Pos1    : Integer;
  3106.     tmpPos2 : Integer;
  3107.     Pos2    : Integer;
  3108. begin
  3109.   if IStartPos>IEndPos then
  3110.   begin
  3111.     tmpPos1:=IEndPos;
  3112.     tmpPos2:=IStartPos;
  3113.   end
  3114.   else
  3115.   begin
  3116.     tmpPos1:=IStartPos;
  3117.     tmpPos2:=IEndPos;
  3118.   end;
  3119.   if PosAxis>FPosLabels then
  3120.   begin
  3121.     Pos1:=FPosLabels;
  3122.     Pos2:=PosAxis+TeeAxisClickGap;
  3123.   end
  3124.   else
  3125.   begin
  3126.     Pos1:=PosAxis-TeeAxisClickGap;
  3127.     Pos2:=FPosLabels;
  3128.   end;
  3129.   if Horizontal then result:=TeeRect(tmpPos1,Pos1,tmpPos2,Pos2)
  3130.                 else result:=TeeRect(Pos1,tmpPos1,Pos2,tmpPos2);
  3131. end;
  3132. Function TChartAxis.Clicked(x,y:Integer):Boolean;
  3133. var tmpR : TRect;
  3134.     tmpZ : Integer;
  3135. Begin
  3136.   result:=ParentChart.IsAxisVisible(Self);
  3137.   if result then
  3138.   begin
  3139.     if ParentChart.View3D then
  3140.     begin
  3141.       if OtherSide then tmpZ:=ParentChart.Width3D else tmpZ:=0;
  3142.       tmpR:=ParentChart.Canvas.CalcRect3D(AxisRect,tmpZ);
  3143.     end
  3144.     else tmpR:=AxisRect;
  3145.     result:=PointInRect(tmpR,x,y);
  3146.     // pending: DepthAxis and click hit detection with 3D rotation.
  3147.   end;
  3148. end;
  3149. Procedure TChartAxis.CustomDrawMinMaxStartEnd( APosLabels,
  3150.                                                APosTitle,
  3151.                                                APosAxis:Integer;
  3152.                                                GridVisible:Boolean;
  3153.                                                Const AMinimum,AMaximum,
  3154.                                                      AIncrement:Double;
  3155.                                                AStartPos,AEndPos:Integer);
  3156.   Procedure SetInternals;
  3157.   begin
  3158.     IMaximum :=FMaximumValue;
  3159.     IMinimum :=FMinimumValue;
  3160.     InternalCalcRange;
  3161.   end;
  3162. var OldMin       : Double;
  3163.     OldMax       : Double;
  3164.     OldIncrement : Double;
  3165.     OldAutomatic : Boolean;
  3166. begin
  3167.   OldMin      :=FMinimumValue;
  3168.   OldMax      :=FMaximumValue;
  3169.   OldIncrement:=FDesiredIncrement;
  3170.   OldAutomatic:=FAutomatic;
  3171.   try
  3172.     FAutomatic       :=False;
  3173.     FMinimumValue    :=AMinimum;
  3174.     FMaximumValue    :=AMaximum;
  3175.     FDesiredIncrement:=AIncrement;
  3176.     SetInternals;
  3177.     CustomDrawStartEnd(APosLabels,APosTitle,APosAxis,GridVisible,AStartPos,AEndPos);
  3178.   finally
  3179.     FMinimumValue    :=OldMin;
  3180.     FMaximumValue    :=OldMax;
  3181.     FDesiredIncrement:=OldIncrement;
  3182.     FAutomatic       :=OldAutomatic;
  3183.     SetInternals;
  3184.   end;
  3185. end;
  3186. Procedure TChartAxis.CustomDrawMinMax( APosLabels,
  3187.                                        APosTitle,
  3188.                                        APosAxis:Integer;
  3189.                                        GridVisible:Boolean;
  3190.                                        Const AMinimum,AMaximum,
  3191.                                        AIncrement:Double);
  3192. begin
  3193.   CustomDrawMinMaxStartEnd(APosLabels,APosTitle,APosAxis,GridVisible,
  3194.         AMinimum,AMaximum,AIncrement,IStartPos,IEndPos);
  3195. end;
  3196. Procedure TChartAxis.CustomDraw( APosLabels,APosTitle,APosAxis:Integer;
  3197.                                        GridVisible:Boolean);
  3198. begin
  3199.   InternalCalcPositions;
  3200.   CustomDrawStartEnd(APosLabels,APosTitle,APosAxis,GridVisible,IStartPos,IEndPos);
  3201. End;
  3202. Procedure TChartAxis.CustomDrawStartEnd( APosLabels,APosTitle,APosAxis:Integer;
  3203.                                          GridVisible:Boolean; AStartPos,AEndPos:Integer);
  3204. var OldGridVisible : Boolean;
  3205.     OldChange      : TNotifyEvent;
  3206. Begin
  3207.   FPosLabels:=APosLabels;
  3208.   FPosTitle :=APosTitle;
  3209.   FPosAxis  :=APosAxis;
  3210.   IStartPos :=AStartPos;
  3211.   IEndPos   :=AEndPos;
  3212.   RecalcSizeCenter;
  3213.   OldGridVisible:=FGrid.Visible;
  3214.   OldChange:=FGrid.OnChange;
  3215.   FGrid.OnChange:=nil;
  3216.   FGrid.Visible:=GridVisible;
  3217.   Draw(False);
  3218.   FGrid.Visible:=OldGridVisible;
  3219.   FGrid.OnChange:=OldChange;
  3220. end;
  3221. Procedure TChartAxis.RecalcSizeCenter;
  3222. begin
  3223.   IAxisSize:=IEndPos-IStartPos;
  3224.   ICenterPos:=(IStartPos+IEndPos) div 2;
  3225.   InternalCalcRange;
  3226. end;
  3227. Procedure TChartAxis.InternalCalcPositions;
  3228.   Procedure DoCalculation(AStartPos:Integer; ASize:Integer);
  3229.   begin
  3230.     IStartPos:=AStartPos+Round(0.01*ASize*FStartPosition);
  3231.     IEndPos:=AStartPos+Round(0.01*ASize*FEndPosition);
  3232.   end;
  3233. begin
  3234.   With ParentChart do
  3235.   if IsDepthAxis then DoCalculation(0,Width3D) else
  3236.   if Horizontal then DoCalculation(ChartRect.Left,ChartWidth)
  3237.                 else DoCalculation(ChartRect.Top,ChartHeight);
  3238.   RecalcSizeCenter;
  3239. end;
  3240. Function TChartAxis.ApplyPosition(APos:Integer; Const R:TRect):Integer;
  3241. Var tmpSize : Integer;
  3242. begin
  3243.   result:=APos;
  3244.   if FPositionPercent<>0 then
  3245.   With R do
  3246.   begin
  3247.     if FPosUnits=muPercent then
  3248.     begin
  3249.       if Horizontal then tmpSize:=Bottom-Top else tmpSize:=Right-Left;
  3250.       tmpSize:=Round(0.01*FPositionPercent*tmpSize);
  3251.     end
  3252.     else tmpSize:=Round(FPositionPercent);  // pixels
  3253.     if OtherSide then tmpSize:=-tmpSize;
  3254.     if Horizontal then tmpSize:=-tmpSize;
  3255.     result:=APos+tmpSize;
  3256.   end;
  3257. end;
  3258. Function TChartAxis.GetRectangleEdge(Const R:TRect):Integer;
  3259. begin
  3260.   With R do
  3261.   if OtherSide then
  3262.      if Horizontal then result:=Top else result:=Right
  3263.   else
  3264.      if Horizontal then result:=Bottom else result:=Left;
  3265. end;
  3266. Procedure TChartAxis.DrawGridLine(tmp:Integer);
  3267. var tmpZ : Integer;
  3268. begin
  3269.   if (tmp>IStartPos) and (tmp<IEndPos) then
  3270.   With ParentChart,Canvas,ChartRect do
  3271.   begin
  3272.     if IsDepthAxis then
  3273.     begin
  3274.       VertLine3D(Left,Top,Bottom,tmp);
  3275.       HorizLine3D(Left,Right,Bottom,tmp);
  3276.     end
  3277.     else
  3278.     begin
  3279.       if View3D then
  3280.       begin
  3281.         if AxisBehind then
  3282.         begin
  3283.           if not IHideBackGrid then { 6.0 }
  3284.              if Horizontal then VertLine3D(tmp,Top,Bottom,Width3D)
  3285.                            else HorizLine3D(Left,Right,tmp,Width3D);
  3286.           if not IHideSideGrid then
  3287.           begin
  3288.             tmpZ:=Round(Width3D*Grid.ZPosition*0.01); // 6.0
  3289.             if (tmpZ<>Width3D) then
  3290.                if Horizontal then ZLine3D(tmp,PosAxis,tmpZ,Width3D)
  3291.                              else ZLine3D(PosAxis,tmp,tmpZ,Width3D);
  3292.           end;
  3293.         end
  3294.         else
  3295.         if Horizontal then VertLine3D(tmp,Top,Bottom,0) // in-front grid
  3296.                       else HorizLine3D(Left,Right,tmp,0); // in-front grid
  3297.       end
  3298.       else
  3299.       if Horizontal then DoVertLine(tmp,Top+1,Bottom) { 5.02 (+1) }
  3300.                     else DoHorizLine(Left+1,Right,tmp); { 5.02 (+1) }
  3301.     end;
  3302.   end;
  3303. end;
  3304. Procedure TChartAxis.DrawGrids(NumTicks:Integer);
  3305. var t : Integer;
  3306. begin
  3307.   if Assigned(OnDrawGrids) then
  3308.      OnDrawGrids(Self);
  3309.   if FGrid.Visible then
  3310.   begin
  3311.     with ParentChart.Canvas do
  3312.     begin
  3313.       BackMode:=cbmTransparent;
  3314.       if FGrid.Color=clTeeColor then
  3315.          AssignVisiblePenColor(FGrid,clGray)
  3316.       else
  3317.          AssignVisiblePen(FGrid);
  3318.     end;
  3319.     if Grid.Centered then
  3320.        for t:=1 to NumTicks-1 do
  3321.            DrawGridLine(Round(0.5*(Tick[t]+Tick[t-1])))
  3322.     else
  3323.        for t:=0 to NumTicks-1 do
  3324.            DrawGridLine(Tick[t]);
  3325.   end;
  3326. end;
  3327. type
  3328.   TTeeMinorTickProc=Procedure(AMinorTickPos:Integer);
  3329. Procedure TChartAxis.Draw(CalcPosAxis:Boolean);
  3330. Var tmpValue    : Double;
  3331.     tmpNumTicks : Integer;
  3332.   Procedure DrawTicksGrid;
  3333.   Var tmpWallSize : Integer;
  3334.     Procedure InternalDrawTick(tmp,Delta,tmpTickLength:Integer);
  3335.     Begin
  3336.       with ParentChart,Canvas do
  3337.       Begin
  3338.         if IsDepthAxis then
  3339.            if OtherSide then
  3340.               HorizLine3D(PosAxis+Delta,PosAxis+Delta+tmpTickLength,DepthAxisPos,tmp)
  3341.            else
  3342.               HorizLine3D(PosAxis-Delta,PosAxis-Delta-tmpTickLength,DepthAxisPos,tmp)
  3343.         else
  3344.         if OtherSide then
  3345.         Begin
  3346.           if Horizontal then
  3347.              VertLine3D(tmp,PosAxis-Delta,PosAxis-Delta-tmpTickLength,IZPos)
  3348.           else
  3349.           begin
  3350.             Inc(Delta,tmpWallSize);
  3351.             HorizLine3D(PosAxis+Delta,PosAxis+Delta+tmpTickLength,tmp,IZPos)
  3352.           end;
  3353.         end
  3354.         else
  3355.         begin
  3356.           Inc(Delta,tmpWallSize);
  3357.           if Horizontal then
  3358.              if View3D then
  3359.                 VertLine3D(tmp,PosAxis+Delta,PosAxis+Delta+tmpTickLength,IZPos)
  3360.              else
  3361.                 DoVertLine(tmp,PosAxis+Delta,PosAxis+Delta+tmpTickLength)
  3362.           else
  3363.              if View3D then
  3364.                 HorizLine3D(PosAxis-Delta,PosAxis-Delta-tmpTickLength,tmp,IZPos)
  3365.              else
  3366.                 DoHorizLine(PosAxis-Delta,PosAxis-Delta-tmpTickLength,tmp);
  3367.         end;
  3368.       end;
  3369.     end;
  3370.     Procedure DrawAxisLine;
  3371.     var tmp  : Integer;
  3372.     begin
  3373.       With ParentChart,Canvas do
  3374.       if IsDepthAxis then
  3375.       begin
  3376.         if OtherSide then
  3377.            tmp:=ChartRect.Bottom+CalcWallSize(BottomAxis)-IZPos
  3378.         else
  3379.            tmp:=ChartRect.Top-IZPos;
  3380.         MoveTo3D(PosAxis,tmp,IStartPos);
  3381.         LineTo3D(PosAxis,tmp,IEndPos);
  3382.       end
  3383.       else
  3384.       begin
  3385.         if Horizontal then
  3386.            if OtherSide then
  3387.               // Top axis
  3388.               HorizLine3D(IStartPos,IEndPos,PosAxis,IZPos)
  3389.            else
  3390.               // Bottom axis
  3391.               HorizLine3D(IStartPos-CalcWallSize(LeftAxis),
  3392.                           IEndPos+CalcWallSize(RightAxis),
  3393.                           PosAxis+tmpWallSize,IZPos)
  3394.         else
  3395.         begin
  3396.           if OtherSide then tmp:=tmpWallSize
  3397.                        else tmp:=-tmpWallSize;
  3398.           VertLine3D(PosAxis+tmp,IStartPos,IEndPos+CalcWallSize(BottomAxis),IZPos);
  3399.         end;
  3400.       end;
  3401.     end;
  3402.     Procedure ProcessMinorTicks(IsGrid:Boolean);
  3403.       Procedure AProc(APos:Integer);
  3404.       begin
  3405.         if (APos>IStartPos) and (APos<IEndPos) then
  3406.            if IsGrid then DrawGridLine(APos)
  3407.                      else InternalDrawTick(APos,1,FMinorTickLength);
  3408.       end;
  3409.     var tmpInvCount : Double;
  3410.         tmpTicks    : TChartValues;
  3411.       procedure DrawLogMinorTicks(tmpValue:Double);
  3412.       var tmpDelta    : Double;
  3413.           tt          : Integer;
  3414.           tmpLength   : Integer;
  3415.       begin
  3416.         tmpLength:=Length(tmpTicks);
  3417.         for tt:=0 to tmpLength-1 do
  3418.         if tmpTicks[tt]=tmpValue then exit;
  3419.         SetLength(tmpTicks,tmpLength+1);
  3420.         tmpTicks[tmpLength]:=tmpValue;
  3421.         tmpDelta:=((tmpValue*FLogarithmicBase)-tmpValue)*tmpInvCount;
  3422.         for tt:=1 to FMinorTickCount do
  3423.         begin
  3424.           tmpValue:=tmpValue+tmpDelta;
  3425.           if (tmpValue<=IMaximum) and (tmpValue>=IMinimum) then
  3426.              AProc(CalcPosValue(tmpValue));
  3427.         end;
  3428.       end;
  3429.     var t        : Integer;
  3430.         tt       : Integer;
  3431.         tmpDelta : Double;
  3432.         tmpValue : Double;
  3433.     begin
  3434.       tmpInvCount:=1.0/Succ(FMinorTickCount);
  3435.       if tmpNumTicks>1 then
  3436.       if not FLogarithmic then
  3437.       begin
  3438.         tmpDelta:=1.0*(Tick[1]-Tick[0])*tmpInvCount;
  3439.         for t:=1 to FMinorTickCount do
  3440.         begin
  3441.           AProc(Tick[0]-Round(t*tmpDelta));
  3442.           AProc(Tick[tmpNumTicks-1]+Round(t*tmpDelta));
  3443.         end;
  3444.       end;
  3445.       if FLogarithmic then
  3446.       begin
  3447.         tmpTicks:=nil;
  3448.         try
  3449.           if tmpNumTicks>0 then  // 7.0 fix first tick
  3450.           begin
  3451.             tmpValue:=CalcPosPoint(Tick[tmpNumTicks-1])/LogarithmicBase;
  3452.             DrawLogMinorTicks(tmpValue);
  3453.             for t:=1 to tmpNumTicks do
  3454.             begin
  3455.               tmpValue:=CalcPosPoint(Tick[t-1]);
  3456.               DrawLogMinorTicks(tmpValue);
  3457.             end;
  3458.             DrawLogMinorTicks(tmpValue*LogarithmicBase);
  3459.           end;
  3460.         finally
  3461.           tmpTicks:=nil;
  3462.         end;
  3463.       end
  3464.       else
  3465.       for t:=1 to tmpNumTicks-1 do
  3466.       begin
  3467.         tmpDelta:=1.0*(Tick[t]-Tick[t-1])*tmpInvCount;
  3468.         for tt:=1 to FMinorTickCount do AProc(Tick[t]-Round(tt*tmpDelta));
  3469.       end;
  3470.     end;
  3471.     Procedure ProcessTicks(APen:TChartPen; AOffset,ALength:Integer);
  3472.     var t : Integer;
  3473.     begin
  3474.       if APen.Visible then
  3475.       begin
  3476.         ParentChart.Canvas.AssignVisiblePen(APen);
  3477.         for t:=0 to tmpNumTicks-1 do
  3478.             InternalDrawTick(Tick[t],AOffset,ALength);
  3479.       end;
  3480.     end;
  3481.     Procedure ProcessMinor(APen:TChartPen; IsGrid:Boolean);
  3482.     begin
  3483.       if (tmpNumTicks>0) and APen.Visible then
  3484.       begin
  3485.         With ParentChart.Canvas do
  3486.         begin
  3487.           BackMode:=cbmTransparent; { 5.01 }
  3488.           Brush.Style:=bsClear;
  3489.           AssignVisiblePen(APen);
  3490.         end;
  3491.         ProcessMinorTicks(IsGrid);
  3492.       end;
  3493.     end;
  3494.   begin
  3495.     With ParentChart.Canvas do
  3496.     begin
  3497.       Brush.Style:=bsClear;
  3498.       BackMode:=cbmTransparent;
  3499.     end;
  3500.     tmpWallSize:=ParentChart.CalcWallSize(Self);
  3501.     if FAxis.Visible then
  3502.     begin
  3503.       ParentChart.Canvas.AssignVisiblePen(FAxis);
  3504.       DrawAxisLine;
  3505.     end;
  3506.     ProcessTicks(FTicks,1,FTickLength);
  3507.     DrawGrids(tmpNumTicks);
  3508.     ProcessTicks(FTicksInner,-1,-FTickInnerLength);
  3509.     ProcessMinor(FMinorTicks,False);
  3510.     ProcessMinor(FMinorGrid,True);
  3511.     ParentChart.Canvas.BackMode:=cbmOpaque;
  3512.   end;
  3513.   Procedure AddTick(Const APos:Integer);
  3514.   begin
  3515.     SetLength(Tick,Length(Tick)+1);
  3516.     Tick[tmpNumTicks]:=APos;
  3517.     Inc(tmpNumTicks);
  3518.   end;
  3519. var tmpAlternate : Boolean;
  3520.   Procedure DrawThisLabel(LabelPos:Integer; Const tmpSt:String; Format:TTeeCustomShape=nil);
  3521.   var tmpZ   : Integer;
  3522.       tmpPos : Integer;
  3523.   begin
  3524.     if TickOnLabelsOnly then
  3525.        AddTick(LabelPos);
  3526.     With ParentChart,Canvas do
  3527.     begin
  3528.       if Assigned(Format) then AssignFont(Format.Font)
  3529.                           else AssignFont(Items.Format.Font);
  3530.       // trick
  3531.       Brush.Style:=bsSolid;
  3532.       Brush.Style:=bsClear;
  3533.       {$IFDEF CLX}
  3534.       BackMode:=cbmTransparent;
  3535.       {$ENDIF}
  3536.       if IsDepthAxis then
  3537.       begin
  3538.         TextAlign:=DepthAxisAlign;
  3539.         if (View3DOptions.Rotation=360) or View3DOptions.Orthogonal then
  3540.            tmpZ:=LabelPos+(FontHeight div 2)
  3541.         else
  3542.            tmpZ:=LabelPos;
  3543.         if OtherSide then tmpPos:=PosLabels
  3544.                      else tmpPos:=PosLabels-2-(TextWidth('W') div 2);
  3545.         TextOut3D(tmpPos,DepthAxisPos,tmpZ,tmpSt);
  3546.       end
  3547.       else
  3548.       begin
  3549.         if LabelsAlternate then
  3550.         begin
  3551.           if tmpAlternate then
  3552.              tmpPos:=PosLabels