unit AnyChart;

interface
{$I AnyLib.inc}
uses
  Windows, Messages, SysUtils, {$IFNDEF Delphi6}FileCtrl{$ELSE}Variants{$ENDIF},
  Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ObjList,{$IFDEF DelphiXE2}VCLTee.TeeShape{$ELSE}TeeShape{$ENDIF},
  {$IFDEF DelphiXE2}VCLTee.ArrowCha{$ELSE}ArrowCha{$ENDIF},
  {$IFDEF DelphiXE2}VCLTee.GanttCh{$ELSE}GanttCh{$ENDIF},
  {$IFDEF DelphiXE2}VCLTee.BubbleCh{$ELSE}BubbleCh{$ENDIF},Math,
  {$IFDEF DelphiXE2}VCLTee.Series{$ELSE}Series{$ENDIF},
  ExtCtrls,{$IFDEF DelphiXE2}VCLTee.TeeProcs{$ELSE}TeeProcs{$ENDIF},
  {$IFDEF DelphiXE2}VCLTee.TeEngine{$ELSE}TeEngine{$ENDIF},
  {$IFDEF DelphiXE2}VCLTee.Chart{$ELSE}Chart{$ENDIF};

type
  TSeriesType=(stLine,stArea,stPoint,stVertBar,stHorzBar,stPie,stShape,stFastLine,
    stArrows,stGantt,stBubble);
  TMarkStyle=(msValue,msPercent,msLabel,msLabelPercent,msLabelValue,msLegend,
    msPercentTotal,msLabelPercentTotal,msXValue);
  TAnyChartTitle=class;  
  IChartTitleAdapter = interface
    ['{234F43E0-1A64-11DA-89D6-00024413CFA7}']
    procedure ReferenceChartTitle(ChartTitle: TAnyChartTitle);//用参数ChartTitle更新内部ChartTitle
    procedure ReleaseChartTitle; //设置内部ChartTitle为nil
  end;
  TNewChart=class;
  TAnyChartTitle=class(TObject)
  private
    FChartTitleAdapter:IChartTitleAdapter;
    FTitle:TChartTitle;
    FFont: TFont;
    FDefColor:TColor;
    procedure FontChange(Sneder:TObject);
    procedure SetChartTitleAdapter(const Value: IChartTitleAdapter);
    procedure SetAdjustFrame(const Value: Boolean);
    procedure SetAlignment(const Value: TAlignment);
    procedure SetBrushColor(const Value: TColor);
    procedure SetBrushStyle(const Value: TBrushStyle);
    procedure SetFont(const Value: TFont);
    procedure SetText(const Value: string);
    procedure SetVisible(const Value: Boolean);
    function GetAdjustFrame: Boolean;
    function GetAlignment: TAlignment;
    function GetBrushColor: TColor;
    function GetBrushStyle: TBrushStyle;
    function GetText: string;
    function GetVisible: Boolean;
  public
    constructor Create;
    destructor Destroy;override;
    property AdjustFrame:Boolean read GetAdjustFrame write SetAdjustFrame;
    property Alignment:TAlignment read GetAlignment write SetAlignment;
    property BrushColor:TColor read GetBrushColor write SetBrushColor;
    property BrushStyle:TBrushStyle read GetBrushStyle write SetBrushStyle;
    property Font:TFont read FFont write SetFont;
    property Text:string read GetText write SetText;
    property Visible:Boolean read GetVisible write SetVisible;
    property ChartTitleAdapter:IChartTitleAdapter read FChartTitleAdapter write SetChartTitleAdapter;
  end;
  TAnySeries=class;
  ISeriesAdapter = interface
    ['{234F43E1-1A64-11DA-89D6-00024413CFA7}']
    procedure ReferenceSeries(Series: TAnySeries);
    procedure ReleaseSeries;
  end;
  TAnyChartValueList=class;
  IValueListAdapter = interface
    ['{46977A20-3AA8-11DA-89D4-00024413CFA7}']
    procedure ReferenceValueList(ValueList: TAnyChartValueList);
    procedure ReleaseValueList;
  end;
  TAnyChartValueList=class(TObject)
  private
    FValueList:TChartValueList;
    FValueListAdapter: IValueListAdapter;
    function GetMaxValue: Double;
    function GetMinValue: Double;
    function GetTotalValue: Double;
    procedure SetValueListAdapter(const Value: IValueListAdapter);
  public
    constructor Create;
    function Value(Index:integer):Double;
    procedure SetValue(Index:integer;Value:Double);
    function Count: Longint;
    procedure Delete( ValueIndex: Longint);
    function First: Double;
    function Last: Double;
    function Locate (Const Value:Double):Longint;
    property MaxValue: Double read GetMaxValue;
    property MinValue: Double read GetMinValue;
    property Total: Double read GetTotalValue;
    property ValueListAdapter:IValueListAdapter read FValueListAdapter write SetValueListAdapter;
  end;
  TShapeStyle=(ssRectangle,ssCircle,ssVertLine,ssHorizLine,ssTriangle,
    ssInvertTriangle,ssLine,ssDiamond);
  TAnySeries=class(TObject)
  private
    FXValueList:TAnyChartValueList;
    FYValueList:TAnyChartValueList;
    FStartXValueList:TAnyChartValueList;
    FStartYValueList:TAnyChartValueList;
    FEndXValueList:TAnyChartValueList;
    FEndYValueList:TAnyChartValueList;
    FStartValueList:TAnyChartValueList;
    FEndValueList:TAnyChartValueList;
    FRadiusValueList:TAnyChartValueList;
    FPieValues:TAnyChartValueList;
    FSeries:TChartSeries;
    FSeriesType: TSeriesType;
    FSeriesAdapter: ISeriesAdapter;
    function GetMarkStyle: TMarkStyle;
    function GetMarkVisible: Boolean;
    procedure SetMarkStyle(const Value: TMarkStyle);
    procedure SetMarkVisible(const Value: Boolean);
    procedure SetSeriesAdapter(const Value: ISeriesAdapter);
    function GetTitle: string;
    procedure SetTitle(const Value: string);
    function GetShapeColor: TColor;
    function GetShapeFrameColor: TColor;
    function GetShapeX0: Double;
    function GetShapeX1: Double;
    function GetShapeY0: Double;
    function GetShapeY1: Double;
    function GetStyle: TShapeStyle;
    procedure SetShapeColor(const Value: TColor);
    procedure SetShapeFrameColor(const Value: TColor);
    procedure SetShapeX0(const Value: Double);
    procedure SetShapeX1(const Value: Double);
    procedure SetShapeY0(const Value: Double);
    procedure SetShapeY1(const Value: Double);
    procedure SetStyle(const Value: TShapeStyle);
  public
    constructor Create;
    destructor Destroy;override;
    procedure Add(Const AValue:Double; Const ALabel:String; AColor:TColor);
    procedure AddNull(Const ALabel:String);
    procedure AddXY(Const AXValue, AYValue: Double; Const AXLabel: String; AColor: TColor);
    procedure AddArrow(Const X0, Y0, X1, Y1: Double; Const ALabel: String; AColor: TColor);
    procedure AddGantt(Const AStart,AEnd,AY: Double; Const AXLabel: String);
    procedure AddBubble(Const AX,AY,ARadius:Double; Const AXLabel:String; AColor:TColor);
    function XScreenToValue(ScreenPos:Longint): Double;
    function YScreenToValue(ScreenPos:Longint): Double;
    procedure Delete(ValueIndex:integer);
    function Count: Longint;
    procedure Clear;
    procedure FillSampleValues(NumValues : Longint);
    procedure Rotate(Angle:Integer);
    property MarkVisible:Boolean read GetMarkVisible write SetMarkVisible;
    property MarkStyle:TMarkStyle read GetMarkStyle write SetMarkStyle;
    property SeriesStyle:TSeriesType read FSeriesType;
    property Title:string read GetTitle write SetTitle;
    property XValues:TAnyChartValueList read FXValueList;
    property YValues:TAnyChartValueList read FYValueList;
    property StartXValues:TAnyChartValueList read FStartXValueList;
    property StartYValues:TAnyChartValueList read FStartYValueList;
    property EndXValues:TAnyChartValueList read FEndXValueList;
    property EndYValues:TAnyChartValueList read FEndYValueList;
    property StartValues:TAnyChartValueList read FStartValueList;
    property EndValues:TAnyChartValueList read FEndValueList;
    property RadiusValues:TAnyChartValueList read FRadiusValueList;
    property PieValues:TAnyChartValueList read FPieValues;
    property ShapeStyle: TShapeStyle read GetStyle write SetStyle;
    property ShapeColor: TColor read GetShapeColor write SetShapeColor;
    property ShapeFrameColor: TColor read GetShapeFrameColor write SetShapeFrameColor;
    property ShapeX0:Double read GetShapeX0 write SetShapeX0;
    property ShapeY0:Double read GetShapeY0 write SetShapeY0;
    property ShapeX1:Double read GetShapeX1 write SetShapeX1;
    property ShapeY1:Double read GetShapeY1 write SetShapeY1;
    property SeriesAdapter:ISeriesAdapter read FSeriesAdapter write SetSeriesAdapter;
  end;
  TAnyChart=class;
  IChartAdapter = interface
    ['{234F43E2-1A64-11DA-89D6-00024413CFA7}']
    procedure ReferenceChart(Chart: TAnyChart);
    procedure ReleaseChart;
  end;
  TNewChart=class(TChart)
  private
    FDrawFrame:Boolean;
  protected
    procedure Paint;override;
  public
    AnyChart:TAnyChart;
    constructor Create(AOwner:TComponent);override;
  end;
  TAnyGradientDirection = (agdTopBottom, agdBottomTop,
                       agdLeftRight, agdRightLeft,
                       agdFromCenter, agdFromTopLeft,
                       agdFromBottomLeft, agdRadial,
                       agdDiagonalUp, agdDiagonalDown );
  TAnyChart=class(TObject)
  private
    FChart:TNewChart;
    FFoot: TAnyChartTitle;
    FTitle: TAnyChartTitle;
    FSeriesList:TObjList;
    FChartAdapter: IChartAdapter;
    procedure DeleteItems;
    procedure SetAxisVisible(const Value: Boolean);
    procedure SetBorderVisible(const Value: Boolean);
    procedure SetColor(const Value: TColor);
    procedure SetEnable(const Value: Boolean);
    procedure SetFoot(const Value: TAnyChartTitle);
    procedure SetHeight(const Value: integer);
    procedure SetLegendVisible(const Value: Boolean);
    procedure SetTitle(const Value: TAnyChartTitle);
    procedure SetView3D(const Value: Boolean);
    procedure SetVisible(const Value: Boolean);
    procedure SetWidth(const Value: integer);
    procedure InitChart;
    procedure SetChartAdapter(const Value: IChartAdapter);
    function GetLeft: integer;
    function GetTop: integer;
    procedure SetLeft(const Value: integer);
    procedure SetTop(const Value: integer);
    function GetHorzGridLine: Boolean;
    function GetVertGridLine: Boolean;
    procedure SetHorzGridLine(const Value: Boolean);
    procedure SetVertGridLine(const Value: Boolean);
    function GetChart3DPercent: integer;
    procedure SetChart3DPercent(const Value: integer);
    function GetAxisVisible: Boolean;
    function GetBorderVisible: Boolean;
    function GetColor: TColor;
    function GetEnable: Boolean;
    function GetHeight: integer;
    function GetLegendVisible: Boolean;
    function GetView3D: Boolean;
    function GetVisible: Boolean;
    function GetWidth: integer;
    function GetHorzGridLineColor: TColor;
    function GetHorzGridLineStyle: TPenStyle;
    function GetHorzGridLineWidth: integer;
    function GetVertGridLineColor: TColor;
    function GetVertGridLineStyle: TPenStyle;
    function GetVertGridLineWidth: integer;
    procedure SetHorzGridLineColor(const Value: TColor);
    procedure SetHorzGridLineStyle(const Value: TPenStyle);
    procedure SetHorzGridLineWidth(const Value: integer);
    procedure SetVertGridLineColor(const Value: TColor);
    procedure SetVertGridLineStyle(const Value: TPenStyle);
    procedure SetVertGridLineWidth(const Value: integer);
    function GetGradientDirection: TAnyGradientDirection;
    function GetGradientEndColor: TColor;
    function GetGradientStartColor: TColor;
    function GetGradientVisible: Boolean;
    procedure SetGradientDirection(const Value: TAnyGradientDirection);
    procedure SetGradientEndColor(const Value: TColor);
    procedure SetGradientStartColor(const Value: TColor);
    procedure SetGradientVisible(const Value: Boolean);
  protected

  public
    constructor Create;
    destructor Destroy;override;
    function AddSeries(SeriesType:TSeriesType):TAnySeries;
    procedure DeleteSeries(Index:integer);
    function Series(Index:integer):TAnySeries;
    procedure SaveToStream(Stream:TStream);
    procedure LoadFromStream(Stream:TStream);
    property Title:TAnyChartTitle read FTitle write SetTitle;
    property Foot:TAnyChartTitle read FFoot write SetFoot;
    property LegendVisible:Boolean read GetLegendVisible write SetLegendVisible;
    property AxisVisible:Boolean read GetAxisVisible write SetAxisVisible;
    property BorderVisible:Boolean read GetBorderVisible write SetBorderVisible;
    property View3D:Boolean read GetView3D write SetView3D;
    property Color:TColor read GetColor write SetColor;
    property Visible:Boolean read GetVisible write SetVisible;
    property Enable:Boolean read GetEnable write SetEnable;
    property Height:integer read GetHeight write SetHeight;
    property Width:integer read GetWidth write SetWidth;
    property Left:integer read GetLeft write SetLeft;
    property Top:integer read GetTop write SetTop;
    property HorzGridLineColor:TColor read GetHorzGridLineColor write SetHorzGridLineColor;
    property HorzGridLineStyle:TPenStyle read GetHorzGridLineStyle write SetHorzGridLineStyle;
    property HorzGridLineWidth:integer read GetHorzGridLineWidth write SetHorzGridLineWidth;
    property VertGridLineColor:TColor read GetVertGridLineColor write SetVertGridLineColor;
    property VertGridLineStyle:TPenStyle read GetVertGridLineStyle write SetVertGridLineStyle;
    property VertGridLineWidth:integer read GetVertGridLineWidth write SetVertGridLineWidth;
    property HorzGridLine:Boolean read GetHorzGridLine write SetHorzGridLine;
    property VertGridLine:Boolean read GetVertGridLine write SetVertGridLine;
    property Chart3DPercent:integer read GetChart3DPercent write SetChart3DPercent;
    property GradientVisible:Boolean read GetGradientVisible write SetGradientVisible;
    property GradientDirection:TAnyGradientDirection read GetGradientDirection write SetGradientDirection;
    property GradientStartColor:TColor read GetGradientStartColor write SetGradientStartColor;
    property GradientEndColor:TColor read GetGradientEndColor write SetGradientEndColor;
    property Chart:TNewChart read FChart;
    property ChartAdapter:IChartAdapter read FChartAdapter write SetChartAdapter;
  end;

procedure SaveTeeChartToFile(AChart:TCustomChart; Const AFileName:String);
procedure LoadTeeChartFromFile(AChart:TCustomChart;const AName:String);
procedure SaveTeeChartToStream(AChart:TCustomChart; AStream:TStream);
procedure LoadTeeChartFromStream(AChart:TCustomChart;AStream:TStream);

implementation

uses {$IFDEF DelphiXE2}VCLTee.TeCanvas{$ELSE}TeCanvas{$ENDIF};

Const
  MagicTeeFile  =$3060;
  VersionTeeFile=$0120;


type
  TFileHeader=Packed Record
    Magic   : Word;
    Version : Word;
  end;
 TeeFormatFlags = (tfNoMandatory,tfColor,tfLabel,tfMarkPosition);
 TeeFormatFlag  = set of TeeFormatFlags;
 TSeriesAccess=class(TChartSeries);

procedure SaveTextToStream(Stream:TStream;Text:string);
var
  Len:integer;
  Buf:string;
begin
  Buf:=Text;
  Len:=Length(Buf);
  Stream.Write(Len,4);
  if Len>0  then
  Stream.Write(Buf[1],Len);
end;
function LoadTextFromStream(Stream:TStream):string;
var
  Len:integer;
  Buf:string;
begin
  Result:='';
  Stream.Read(Len,4);
  if Len>0  then
  begin
    SetLength(Buf,Len);
    Stream.Read(Buf[1],Len);
    Result:=Buf;
  end;
end;
 
function HasNoMandatoryValues(ASeries:TChartSeries):Boolean;
begin
  result:=False;
end;

function HasColors(ASeries:TChartSeries):Boolean;
var
  t        : Integer;
  tmpCount : Integer;
  tmpColor : TColor;
  tmpSeriesColor:TColor;
begin
  result:=False;
  With ASeries do
  begin
    tmpSeriesColor:=SeriesColor;
    tmpCount:=Math.Min(10000,Count-1);
    for t:=0 to tmpCount do
    begin
      tmpColor:=ValueColor[t];
      if (tmpColor<>clTeeColor) and
         (tmpColor<>tmpSeriesColor) then
      begin
        result:=True;
        exit;
      end;
    end;
  end;
end;

function HasLabels(ASeries:TChartSeries):Boolean;
begin
  result:=True;
end;

function SeriesGuessContents(ASeries:TChartSeries):TeeFormatFlag;
begin
  if HasNoMandatoryValues(ASeries) then result:=[tfNoMandatory]
                                   else result:=[];
  if HasColors(ASeries) then result:=result+[tfColor];
  if HasLabels(ASeries) then result:=result+[tfLabel];
end;

procedure WriteSeriesData(AStream:TStream; ASeries:TChartSeries);

  procedure WriteLabel(Const AString:String);
  var
    L : Byte;
  begin
    L:=Length(AString);
    AStream.Write(L,SizeOf(L));
    AStream.Write(PChar(AString)^,L);
  end;

var
  tmpFormat      : TeeFormatFlag;
  tmpNoMandatory : TChartValueList;

  procedure WriteSeriesPoint(Index:Integer);
  var
    tmpFloat : Double;
    tmpColor : TColor;
    tt       : Integer;
  begin
    if tfNoMandatory in tmpFormat then
    begin
      tmpFloat:=tmpNoMandatory.Value[Index];
      AStream.Write(tmpFloat,Sizeof(tmpFloat));
    end;
    tmpFloat:=ASeries.MandatoryValueList.Value[Index];
    AStream.Write(tmpFloat,Sizeof(tmpFloat));
    if tfColor in tmpFormat then
    begin
      tmpColor:=ASeries.ValueColor[Index];
      AStream.Write(tmpColor,Sizeof(tmpColor));
    end;
    if tfLabel in tmpFormat then WriteLabel(ASeries.XLabel[Index]);
    {$IFDEF TeeChart7}
    for tt:=2 to ASeries.ValuesList.Count-1 do
    begin
      tmpFloat:=ASeries.ValuesList[tt].Value[Index];
      AStream.Write(tmpFloat,SizeOf(tmpFloat));
    end;
    {$ELSE}
    for tt:=2 to ASeries.ValuesLists.Count-1 do
    begin
      tmpFloat:=ASeries.ValuesLists[tt].Value[Index];
      AStream.Write(tmpFloat,SizeOf(tmpFloat));
    end;
    {$ENDIF}
    if tfMarkPosition in tmpFormat then
    begin
      With ASeries.Marks.Positions[Index],AStream do
      begin
        Write(ArrowFrom,SizeOf(ArrowFrom));
        Write(ArrowTo,SizeOf(ArrowTo));
        Write(Custom,SizeOf(Custom));
        Write(Height,SizeOf(Height));
        Write(LeftTop,SizeOf(LeftTop));
        Write(Width,SizeOf(Width));
      end;
    end;
  end;

var
  t   : Integer;
  tmp : Integer;
begin
  tmpFormat:=SeriesGuessContents(ASeries);
  AStream.Write(tmpFormat,SizeOf(tmpFormat));
  tmp:=ASeries.Count;
  AStream.Write(tmp,Sizeof(tmp));
  for t:=0 to tmp-1 do WriteSeriesPoint(t);
end;

{$IFDEF Delphi5}
type
  TWriterAccess=class(TWriter);
{$ENDIF}

procedure WriteChartData(AStream:TStream; AChart:TCustomChart);
var
  t : Integer;
begin
  with AChart do
    for t:=0 to SeriesCount-1 do WriteSeriesData(AStream,Series[t]);
end;

procedure SaveTeeChartToStream(AChart:TCustomChart; AStream:TStream);
var
  Header   : TFileHeader;
  tmp      : TCustomChart;
  OldName  : TComponentName;
  ms       : TMemoryStream;
  blValue  : Boolean;
  clValue  : TColor;
  bsValue  : TBrushStyle;
  psValue  : TPenStyle;
  intValue : integer;
  smsValue : TSeriesMarksStyle;
  Buf      : AnsiString;
  Len      : integer;
  i        : integer;
  ASeries  : TChartSeries;
  SeriesType:TSeriesType;
  bdValue  :TBorderStyle;
  alValue  : TAlignment;
  pValue   : TPenMode;
  axValue  : TAxisLabelStyle;
  bcValue  : TBevelCut;
  pmValue  : TPanningMode;
  csValue  : {$IFDEF DelphiXE2}smallint{$ELSE}TCursor{$ENDIF};
  gdValue  : TGradientDirection;
  laValue  : TLegendAlignment;
  ltsValue : TLegendTextStyle;
  vaValue  : TVertAxis;
  haValue  : THorizAxis;
  lsValue  : TLegendStyle;
  procedure SaveFont(AStream:TStream;AFont:TFont);
  var
    Buf:string;
    Len:integer;
    intValue:integer;
    clValue:TColor;
    blValue:Boolean;
    ch:TFontCharSet;
  begin
    Buf := AFont.Name;
    Len := Length(Buf);
    AStream.Write(Len, 4);
    if Len > 0 then
      AStream.Write(Buf[1], Length(Buf));

    intValue := AFont.Size;
    AStream.Write(intValue, 4);

    ch := AFont.Charset;
    AStream.Write(ch, 1);

    clValue := AFont.Color;
    AStream.Write(clValue, SizeOf(TColor));

    blValue := fsBold in AFont.Style;
    AStream.Write(blValue, 1);

    blValue := fsItalic in AFont.Style;
    AStream.Write(blValue, 1);

    blValue := fsUnderline in AFont.Style;
    AStream.Write(blValue, 1);

    blValue := fsStrikeOut in AFont.Style;
    AStream.Write(blValue, 1);
  end;
  procedure SaveTitle(AStream:TStream;Title:TChartTitle);
  begin
    with AStream do
    begin
      blValue:=Title.AdjustFrame;
      Write(blValue,SizeOf(Boolean));
      alValue:=Title.Alignment;
      Write(alValue,SizeOf(TAlignment));
      clValue:=Title.Brush.Color;
      Write(clValue,SizeOf(TColor));
      bsValue:=Title.Brush.Style;
      Write(bsValue,SizeOf(TBrushStyle));
      blValue:=Title.Visible;
      Write(blValue,SizeOf(Boolean));
      Len:=Length(Title.Text.Text);
      Buf:=Title.Text.Text;
      Write(Len,4);
      if Len>0 then
        Write(Buf[1],Len);
      SaveFont(AStream,Title.Font);
    end;
  end;
  procedure SaveChartPen(AStream:TStream;APen:TChartPen);
  begin
    with AStream do
    begin
      clValue:=APen.Color;
      Write(clValue,SizeOf(TColor));
      pValue:=APen.Mode;
      Write(pValue,1);
      psValue:=APen.Style;
      Write(psValue,1);
      blValue:=APen.Visible;
      Write(blValue,1);
      intValue:= APen.Width;
      Write(intValue,4);
    end;
  end;
  procedure SaveChartAxis(AStream:TStream;Axis:TChartAxis);
  var
    blValue:Boolean;
    exValue:Double;
  begin
    with AStream do
    begin
      blValue:=Axis.Automatic;
      Write(blValue,1);
      blValue:=Axis.AutomaticMaximum;
      Write(blValue,1);
      blValue:=Axis.AutomaticMinimum;
      Write(blValue,1);
      SaveChartPen(AStream,Axis.Axis);
      SaveTextToStream(AStream,Axis.AxisValuesFormat);
      SaveTextToStream(AStream,Axis.DateTimeFormat);
      Write(Axis.ExactDateTime,1);
      SaveChartPen(AStream,Axis.Grid);
      blValue:=Axis.GridCentered;
      Write(blValue,1);
      exValue:=Axis.Increment;
      Write(exValue,4);
      blValue:=Axis.Inverted;
      Write(blValue,1);
      blValue:=Axis.Labels;
      Write(blValue,1);
      intValue:=Axis.LabelsAngle;
      Write(intValue,4);
      SaveFont(AStream,Axis.LabelsFont);
      blValue:=Axis.LabelsMultiline;
      Write(blValue,1);
      blValue:=Axis.LabelsOnAxis;
      Write(blValue,1);
      intValue:=Axis.LabelsSeparation;
      Write(intValue,4);
      intValue:=Axis.LabelsSize;
      Write(intValue,4);
      axValue:=Axis.LabelStyle;
      Write(axValue,1);
      blValue:=Axis.Logarithmic;
      Write(blValue,1);
      exValue:=Axis.Maximum;
      Write(exValue,4);
      exValue:=Axis.Minimum;
      Write(exValue,4);
      intValue:=Axis.MinorTickCount;
      Write(intValue,4);
      intValue:=Axis.MinorTickLength;
      Write(intValue,4);
      SaveChartPen(AStream,Axis.MinorTicks);
      blValue:=Axis.RoundFirstLabel;
      Write(blValue,1);
      intValue:=Axis.TickInnerLength;
      Write(intValue,4);
      intValue:=Axis.TickLength;
      Write(intValue,4);
      blValue:=Axis.TickOnLabelsOnly;
      Write(blValue,1);
      SaveChartPen(AStream,Axis.Ticks);
      SaveChartPen(AStream,Axis.TicksInner);
      intValue:=Axis.Title.Angle;
      Write(intValue,4);
      SaveTextToStream(AStream,Axis.Title.Caption);
      SaveFont(AStream,Axis.Title.Font);
      intValue:=Axis.TitleSize;
      Write(intValue,4);
      blValue:=Axis.Visible;
      Write(blValue,1);
    end;
  end;
  procedure SaveChartWall(AStream:TStream;Wall:TChartWall);
  begin
    with AStream do
    begin
      clValue:=Wall.Brush.Color;
      write(clValue,SizeOf(TColor));
      bsValue:=Wall.Brush.Style;
      write(bsValue,1);
      clValue:=Wall.Color;
      write(clValue,SizeOf(TColor));
      SaveChartPen(AStream,Wall.Pen);
      intValue:=Wall.Size;
      Write(intValue,4);
    end;
  end;
begin
  Header.Magic:=MagicTeeFile;
  Header.Version:=VersionTeeFile;
  AStream.Write(Header,SizeOf(Header));
  tmp:=AChart;
  if not (csDesigning in AChart.ComponentState) then
  begin
    OldName:=AChart.Name;
    AChart.Name:='';
  end;
  ms:=TMemoryStream.Create;
  clValue:=AChart.Color;
  ms.Write(clValue,SizeOf(TColor));           // Color
  blValue:=AChart.Enabled;                         // Enabled
  ms.Write(blValue,SizeOf(Boolean));
  blValue:=AChart.Visible;
  ms.Write(blValue,SizeOf(Boolean));        // Visible
  blValue:=AChart.View3D;
  ms.Write(blValue,SizeOf(Boolean));         // View3D
  bcValue:=AChart.BevelOuter;
  ms.Write(bcValue,SizeOf(TBevelCut));   // BevelOuter
  blValue:=AChart.AxisVisible;
  ms.Write(blValue,SizeOf(Boolean));    // AxisVisible
  blValue:=AChart.Legend.Visible;
  ms.Write(blValue,SizeOf(Boolean)); // Legend.Visible
  intValue:=AChart.Width;
  ms.Write(intValue,4);                        // Width
  intValue:=AChart.Height;
  ms.Write(intValue,4);                       // Height
  blValue:=AChart.Frame.Visible;                   // Frame.Visible
  ms.Write(blValue,SizeOf(Boolean));
  SaveTitle(ms,AChart.Title);                      // Title
  SaveTitle(ms,AChart.Foot);                       // Foot
  blValue:=AChart.View3DWalls;                     // View3DWalls
  ms.Write(blValue,SizeOf(Boolean));
  blValue:=AChart.ClipPoints;                      // ClipPoints
  ms.Write(blValue,SizeOf(Boolean));
  //----------------------------------------------------------------------------
  pmValue:=AChart.AllowPanning;
  ms.Write(pmValue,1);
  blValue:=AChart.AllowZoom;
  ms.Write(blValue,1);
  blValue:=AChart.AnimatedZoom;
  ms.Write(blValue,1);
  intValue:=AChart.AnimatedZoomSteps;
  ms.Write(intValue,4);
  blValue:=AChart.AutoSize;
  ms.Write(blValue,1);
  clValue:=AChart.BackColor;
  ms.Write(clValue,SizeOf(TColor));
  clValue:=AChart.BackWall.Brush.Color;
  ms.Write(clValue,SizeOf(TColor));
  bsValue:=AChart.BackWall.Brush.Style;
  ms.Write(bsValue,1);
  clValue:=AChart.BackWall.Color;
  ms.Write(clValue,SizeOf(TColor));
  SaveChartPen(ms,AChart.BackWall.Pen);
  intValue:=AChart.BackWall.Size;
  ms.Write(intValue,4);
  bcValue:=AChart.BevelInner;
  ms.Write(bcValue,1);
  intValue:=AChart.BevelWidth;
  ms.Write(intValue,4);
  bdValue:=AChart.BorderStyle;
  ms.Write(bdValue,1);
  intValue:=AChart.BorderWidth;
  ms.Write(intValue,4);
  if AChart is TNewChart then
  begin
    Buf:='NewChart';
    ms.Write(Buf[1],8);
    ms.Write(TNewChart(AChart).FDrawFrame,1);
  end
  else
  begin
    Buf:='OldChart';
    ms.Write(Buf[1],8);
  end;
  SaveChartAxis(ms,AChart.BottomAxis);
  SaveChartWall(ms,AChart.BottomWall);
  intValue:=AChart.Chart3DPercent;
  ms.Write(intValue,4);
  csValue:=AChart.Cursor;
  ms.Write(csValue,1);
  SaveChartAxis(ms,TChartAxis(AChart.DepthAxis));
  SaveChartPen(ms,AChart.Frame);
  gdValue:=AChart.Gradient.Direction;
  ms.Write(gdValue,1);
  clValue:=AChart.Gradient.StartColor;
  ms.Write(clValue,SizeOf(TColor));
  clValue:=AChart.Gradient.EndColor;
  ms.Write(clValue,SizeOf(TColor));
  blValue:=AChart.Gradient.Visible;
  ms.Write(blValue,1);
  SaveTextToStream(ms,AChart.Hint);
  SaveChartAxis(ms,AChart.LeftAxis);
  SaveChartWall(ms,AChart.LeftWall);
  laValue:=AChart.Legend.Alignment;
  ms.Write(laValue,1);
  clValue:=AChart.Legend.Color;
  ms.Write(clValue,SizeOf(TColor));
  intValue:=AChart.Legend.ColorWidth;
  ms.Write(intValue,4);
  SaveChartPen(ms,AChart.Legend.DividingLines);
  intValue:=AChart.Legend.FirstValue;
  ms.Write(intValue,4);
  SaveFont(ms,AChart.Legend.Font);
  SaveChartPen(ms,AChart.Legend.Frame);
  intValue:=AChart.Legend.HorizMargin;
  ms.Write(intValue,4);
  blValue:=AChart.Legend.Inverted;
  ms.Write(blValue,1);
  lsValue:=AChart.Legend.LegendStyle;
  ms.Write(lsValue,1);
  blValue:=AChart.Legend.ResizeChart;
  ms.Write(blValue,1);
  clValue:=AChart.Legend.ShadowColor;
  ms.Write(clValue,SizeOf(TColor));
  intValue:=AChart.Legend.ShadowSize;
  ms.Write(intValue,4);
  ltsValue:=AChart.Legend.TextStyle;
  ms.Write(ltsValue,1);
  intValue:=AChart.Legend.TopPos;
  ms.Write(intValue,4);
  intValue:=AChart.Legend.VertMargin;
  ms.Write(intValue,4);
  blValue:=AChart.Legend.Visible;
  ms.Write(blValue,1);
  intValue:=AChart.MarginBottom;
  ms.Write(intValue,4);
  intValue:=AChart.MarginLeft;
  ms.Write(intValue,4);
  intValue:=AChart.MarginRight;
  ms.Write(intValue,4);
  intValue:=AChart.MarginTop;
  ms.Write(intValue,4);
  intValue:=AChart.MaxPointsPerPage;
  ms.Write(intValue,4);
  blValue:=AChart.Monochrome;
  ms.Write(blValue,1);
  intValue:=AChart.Page;
  ms.Write(intValue,4);
  SaveChartAxis(ms,AChart.RightAxis);
  blValue:=AChart.ScaleLastPage;
  ms.Write(blValue,1);
  blValue:=AChart.ShowHint;
  ms.Write(blValue,1);
  SaveChartAxis(ms,AChart.TopAxis);
  intValue:=AChart.View3DOptions.Elevation;
  ms.Write(intValue,4);
  intValue:=AChart.View3DOptions.HorizOffset;
  ms.Write(intValue,4);
  blValue:=AChart.View3DOptions.Orthogonal;
  ms.Write(blValue,1);
  intValue:=AChart.View3DOptions.Rotation;
  ms.Write(intValue,4);
  intValue:=AChart.View3DOptions.Tilt;
  ms.Write(intValue,4);
  intValue:=AChart.View3DOptions.VertOffset;
  ms.Write(intValue,4);
  intValue:=AChart.View3DOptions.Zoom;
  ms.Write(intValue,4);
  
  Len:=ms.Size;
  ms.Position:=0;
  AStream.Write(Len,4);
  AStream.CopyFrom(ms,Len);
  AChart:=tmp;
  if not (csDesigning in AChart.ComponentState) then
     AChart.Name:=OldName;
  intValue:=AChart.SeriesCount;
  AStream.Write(intValue,4);
  for i:=0 to AChart.SeriesCount-1 do
  begin
    ms.Size:=0;
    ASeries:=AChart.Series[i];
    if  ASeries is TLineSeries then
      SeriesType:=stLine
    else if ASeries is TAreaSeries then
      SeriesType:=stArea
    else if ASeries is TPointSeries then
      SeriesType:=stPoint
    else if ASeries is TBarSeries then
      SeriesType:=stVertBar
    else if ASeries is THorizBarSeries then
      SeriesType:=stHorzBar
    else if ASeries is TPieSeries then
      SeriesType:=stPie
    else if ASeries is TChartShape then
      SeriesType:=stShape
    else if ASeries is TFastLineSeries then
      SeriesType:=stFastLine
    else if ASeries is TArrowSeries then
      SeriesType:=stArrows
    else if ASeries is TGanttSeries then
      SeriesType:=stGantt
    else
      SeriesType:=stBubble;
    ms.Write(SeriesType,SizeOf(TSeriesType));
    blValue:=ASeries.Marks.Visible;
    ms.Write(blValue,SizeOf(Boolean));
    smsValue:=ASeries.Marks.Style;
    ms.Write(smsValue,SizeOf(smsValue));
    intValue:=ASeries.Marks.ArrowLength;
    ms.Write(intValue,4);
    SaveChartPen(ms,ASeries.Marks.Arrow);
    clValue:=ASeries.Marks.BackColor;
    ms.Write(clValue,SizeOf(TColor));
    blValue:=ASeries.Marks.Clip;
    ms.Write(blValue,1);
    SaveFont(ms,ASeries.Marks.Font);
    blValue:=ASeries.Marks.Transparent;
    ms.Write(blValue,1);
    SaveChartPen(ms,ASeries.Marks.Frame);
    SaveTextToStream(ms,ASeries.PercentFormat);
    clValue:=ASeries.SeriesColor;
    ms.Write(clValue,SizeOf(TColor));
    blValue:=ASeries.ShowInLegend;
    ms.Write(blValue,1);
    SaveTextToStream(ms,ASeries.Title);
    SaveTextToStream(ms,ASeries.ValueFormat);
    vaValue:=ASeries.VertAxis;
    ms.Write(vaValue,1);
    blValue:=ASeries.Active;
    ms.Write(blValue,1);
    blValue:=ASeries.AllowSinglePoint;
    ms.Write(blValue,1);
    blValue:=ASeries.ColorEachPoint;
    ms.Write(blValue,1);
    clValue:=ASeries.Cursor;
    ms.Write(clValue,1);
    haValue:=ASeries.HorizAxis;
    ms.Write(haValue,1);
    Len:=ms.Size;
    AStream.Write(Len,4);
    AStream.CopyFrom(ms,0);
  end;
  ms.Free;
  WriteChartData(AStream,AChart);
end;
type
  TProcTeeCheckError=function(const Message: string): Boolean of object;
  TChartReader=class(TReader)
  protected
    function Error(const Message: string): Boolean; override;
  public
    CheckError:TProcTeeCheckError;
  end;

function TChartReader.Error(const Message: string): Boolean;
begin
  if Assigned(CheckError) then result:=CheckError(Message)
                          else result:=True;
end;

procedure ReadSeriesData(AStream:TStream; ASeries:TChartSeries);

  function ReadLabel:String;
  Var L : Byte;
  begin
    L:=0;
    AStream.Read(L, SizeOf(L));
    SetString(Result, PChar(nil), L);
    AStream.Read(Pointer(Result)^, L);
  end;

var
  tmpFormat       : TeeFormatFlag;
  ValuesListCount : Integer;
  NotYMandatory   : Boolean;

  procedure SwapDouble(var a,b:Double);
  var
    tmp : Double;
  begin
    tmp:=a; a:=b; b:=tmp;
  end;

  procedure SwapInteger(var a,b:Integer);
  var
    tmp : Integer;
  begin
    tmp:=a; a:=b; b:=tmp;
  end;

  procedure ReadSeriesPoint(Index:Integer);
  var
    tmpFloat : Double;
    Ax       : Double;
    Ay       : Double;
    AColor   : TColor;
    ALabel   : String;
    tt       : Integer;
    tmp      : TSeriesMarkPosition;
  begin
    if tfNoMandatory in tmpFormat then AStream.Read(AX,Sizeof(AX))
                                  else AX:=Index;
    AStream.Read(AY,Sizeof(AY));
    if NotYMandatory then SwapDouble(AX,AY);
    if tfColor in tmpFormat then AStream.Read(AColor,Sizeof(AColor))
                            else AColor:=clTeeColor;
    if tfLabel in tmpFormat then ALabel:=ReadLabel
                            else ALabel:='';

    With ASeries do
    begin
      for tt:=2 to ValuesListCount-1 do
      begin
        AStream.Read(tmpFloat,SizeOf(tmpFloat));
        {$IFDEF TeeChart7}
        ValuesList[tt].TempValue:=tmpFloat;
        {$ELSE}
        ValuesLists[tt].TempValue:=tmpFloat;
        {$ENDIF}
      end;
      AddXY(AX,AY,ALabel,AColor);

      if tfMarkPosition in tmpFormat then
      begin
        tmp:=TSeriesMarkPosition.Create;
        With tmp,AStream do
        begin
          Read(ArrowFrom,SizeOf(ArrowFrom));
          Read(ArrowTo,SizeOf(ArrowTo));
          Read(Custom,SizeOf(Custom));
          Read(Height,SizeOf(Height));
          Read(LeftTop,SizeOf(LeftTop));
          Read(Width,SizeOf(Width));
        end;
        Marks.Positions.Add(tmp);
      end;
    end;
  end;

var
  tmpCount : Integer;
  t        : Integer;
begin
  ASeries.Clear;
  AStream.Read(tmpFormat,SizeOf(tmpFormat));
  AStream.Read(tmpCount,Sizeof(tmpCount));
  NotYMandatory:=ASeries.MandatoryValueList<>ASeries.YValues;
  {$IFDEF TeeChart7}
  ValuesListCount:=ASeries.ValuesList.Count;
  {$ELSE}
  ValuesListCount:=ASeries.ValuesLists.Count;
  {$ENDIF}
  for t:=0 to tmpCount-1 do ReadSeriesPoint(t);
end;

procedure ReadChartData(AStream:TStream; AChart:TCustomChart);
var
  t : Integer;
begin
  for t:=0 to AChart.SeriesCount-1 do ReadSeriesData(AStream,AChart.Series[t]);
end;
type
  THackAxis=class(TChartAxis);
procedure LoadTeeChartFromStream(AChart:TCustomChart;AStream:TStream);
var
  Header  : TFileHeader;
  ms       : TMemoryStream;
  blValue  : Boolean;
  pnmValue : TPanningMode;
  lgsValue : TLegendStyle;
  lgtsValue: TLegendTextStyle;
  clValue  : TColor;
  bsValue  : TBrushStyle;
  bvValue  : TBevelCut;
  csrValue : TCursor;
  intValue : integer;
  lalvalue : TLegendAlignment;
  gdValue  : TGradientDirection;
  smsValue : TSeriesMarksStyle;
  Len      : integer;
  i        : integer;
  dlValue  : Double;
  ASeries:TChartSeries;
  SeriesType:TSeriesType;
  axlsValue:TAxisLabelStyle;
  m:TPenMode;
  psValue:TPenStyle;
  bdsValue:TBorderStyle;
  vaxValue:TVertAxis;
  haxValue:THorizAxis;
  Buf     : string;
  procedure LoadFont(AStream:TStream;AFont:TFont);
  var
    Buf:string;
    Len:integer;
    intValue:integer;
    clValue:TColor;
    blValue:Boolean;
    ch:TFontCharSet;
  begin
    AStream.Read(Len, 4);
    if Len > 0 then
    begin
      SetLength(Buf,Len);
      AStream.read(Buf[1], Len);
      AFont.Name:=Buf;
    end;
    AStream.Read(intValue, 4);
    AFont.Size:=intValue;

    AStream.Read(ch, 1);
    AFont.Charset:=ch;

    AStream.Read(clValue, SizeOf(TColor));
    AFont.Color:=clValue;

    AStream.Read(blValue, 1);
    if blValue then
      AFont.Style:=AFont.Style+[fsBold]
    else
      AFont.Style:=AFont.Style-[fsBold];

    AStream.Read(blValue, 1);
    if blValue then
      AFont.Style:=AFont.Style+[fsItalic]
    else
      AFont.Style:=AFont.Style-[fsItalic];

    AStream.Read(blValue, 1);
    if blValue then
      AFont.Style:=AFont.Style+[fsUnderline]
    else
      AFont.Style:=AFont.Style-[fsUnderline];

    AStream.Read(blValue, 1);
    if blValue then
      AFont.Style:=AFont.Style+[fsStrikeOut]
    else
      AFont.Style:=AFont.Style-[fsStrikeOut];
  end;
  procedure LoadTitle(AStream:TStream;Title:TChartTitle);
  var
    blValue:Boolean;
    alValue:TAlignment;
    clValue:TColor;
    Buf:string;
  begin
    with AStream do
    begin
      Read(blValue,SizeOf(Boolean));
      Title.AdjustFrame:=blValue;
      Read(alValue,SizeOf(TAlignment));
      Title.Alignment:=alValue;
      Read(clValue,SizeOf(TColor));
      Title.Brush.Color:=clValue;
      Read(bsValue,SizeOf(TBrushStyle));
      Title.Brush.Style:=bsValue;
      Read(blValue,SizeOf(Boolean));
      Title.Visible:=blValue;
      Read(Len,4);
      if Len>0 then
      begin
        SetLength(Buf,Len);
        Read(Buf[1],Len);
        Title.Text.Text:=Buf;
      end
      else
        Title.Text.Text:='';
      LoadFont(AStream,Title.Font);
    end;
  end;
  procedure LoadChartPen(AStream:TStream;APen:TChartPen);
  begin
    with AStream do
    begin
      Read(clValue,SizeOf(TColor));
      APen.Color:=clValue;
      Read(m,1);
      APen.Mode:=m;
      Read(psValue,1);
      APen.Style:=psValue;
      Read(blValue,1);
      APen.Visible:=blValue;
      Read(intValue,4);
      APen.Width:=intValue;
    end;
  end;
  procedure LoadChartAxis(AStream:TStream;Axis:TChartAxis);
  begin
    with AStream do
    begin
      Read(blValue,1);
      Axis.Automatic:=blValue;
      Read(blValue,1);
      Axis.AutomaticMaximum:=blValue;
      Read(blValue,1);
      Axis.AutomaticMinimum:=blValue;
      LoadChartPen(AStream,Axis.Axis);
      Axis.AxisValuesFormat:=LoadTextFromStream(AStream);
      Axis.DateTimeFormat:=LoadTextFromStream(AStream);
      Read(blValue,1);
      Axis.ExactDateTime:=blValue;
      LoadChartPen(AStream,Axis.Grid);
      Read(blValue,1);
      Axis.GridCentered:=blValue;
      Read(dlValue,4);
      Axis.Increment:=dlValue;
      Read(blValue,1);
      Axis.Inverted:=blValue;
      Read(blValue,1);
      Axis.Labels:=blValue;
      Read(intValue,4);
      Axis.LabelsAngle:=intValue;
      LoadFont(AStream,Axis.LabelsFont);
      Read(blValue,1);
      Axis.LabelsMultiline:=blValue;
      Read(blValue,1);
      Axis.LabelsOnAxis:=blValue;
      Read(intValue,4);
      Axis.LabelsSeparation:=intValue;
      Read(intValue,4);
      Axis.LabelsSize:=intValue;
      Read(axlsValue,1);
      Axis.LabelStyle:=axlsValue;
      Read(blValue,1);
      Axis.Logarithmic:=blValue;
      Read(dlValue,4);
      THackAxis(Axis).InternalSetMaximum(dlValue);
      Read(dlValue,4);
      THackAxis(Axis).InternalSetMinimum(dlValue);
      Read(intValue,4);
      Axis.MinorTickCount:=intValue;
      Read(intValue,4);
      Axis.MinorTickLength:=intValue;
      LoadChartPen(AStream,Axis.MinorTicks);
      Read(blValue,1);
      Axis.RoundFirstLabel:=blValue;
      Read(intValue,4);
      Axis.TickInnerLength:=intValue;
      Read(intValue,4);
      Axis.TickLength:=intValue;
      Read(blValue,1);
      Axis.TickOnLabelsOnly:=blValue;
      LoadChartPen(AStream,Axis.Ticks);
      LoadChartPen(AStream,Axis.TicksInner);
      Read(intValue,4);
      Axis.Title.Angle:=intValue;
      Axis.Title.Caption:=LoadTextFromStream(AStream);
      LoadFont(AStream,Axis.Title.Font);
      Read(intValue,4);
      Axis.TitleSize:=intValue;
      Read(blValue,1);
      Axis.Visible:=blValue;
    end;
  end;
  procedure LoadChartWall(AStream:TStream;Wall:TChartWall);
  begin
    with AStream do
    begin
      Read(clValue,SizeOf(TColor));
      Wall.Brush.Color:=clValue;
      Read(bsValue,1);
      Wall.Brush.Style:=bsValue;
      Read(clValue,SizeOf(TColor));
      Wall.Color:=clValue;
      LoadChartPen(AStream,Wall.Pen);
      Read(intValue,4);
      Wall.Size:=intValue;
    end;
  end;
begin
  if AStream.Size=0 then
    Exit;
  AStream.Read(Header,SizeOf(Header));
  if Header.Magic=MagicTeeFile then
  begin
    AChart.FreeAllSeries;
    AStream.Read(Len,4);
    ms:=TMemoryStream.Create;
    if Len>0 then
    begin
      ms.CopyFrom(AStream,Len);
      ms.Position:=0;

      ms.Read(clValue,SizeOf(TColor));
      AChart.Color:=clValue;
      ms.Read(blValue,SizeOf(Boolean));
      AChart.Enabled:=blValue;
      ms.Read(blValue,SizeOf(Boolean));
      AChart.Visible:=blValue;
      ms.Read(blValue,SizeOf(Boolean));
      AChart.View3D:=blValue;
      ms.Read(bvValue,SizeOf(TBevelCut));
      AChart.BevelOuter:=bvValue;
      ms.Read(blValue,SizeOf(Boolean));
      AChart.AxisVisible:=blValue;
      ms.Read(blValue,SizeOf(Boolean));
      AChart.Legend.Visible:=blValue;
      ms.Read(intValue,4);
      AChart.Width:=intValue;               
      ms.Read(intValue,4);
      AChart.Height:=intValue;
      ms.Read(blValue,SizeOf(Boolean));
      AChart.Frame.Visible:=blValue;
      LoadTitle(ms,AChart.Title);
      LoadTitle(ms,AChart.Foot);
      ms.Read(blValue,SizeOf(Boolean));
      AChart.View3DWalls:=blValue;
      ms.Read(blValue,SizeOf(Boolean));
      AChart.ClipPoints:=blValue;
      //----------------------------------------------------------------------------
      ms.Read(pnmValue,1);
      AChart.AllowPanning:=pnmValue;
      ms.Read(blValue,1);
      AChart.AllowZoom:=blValue;
      ms.Read(blValue,1);
      AChart.AnimatedZoom:=blValue;
      ms.Read(intValue,4);
      AChart.AnimatedZoomSteps:=intValue;
      ms.Read(blValue,1);
      AChart.AutoSize:=blValue;
      ms.Read(clValue,SizeOf(TColor));
      AChart.BackColor:=clValue;
      ms.Read(clValue,SizeOf(TColor));
      AChart.BackWall.Brush.Color:=clValue;
      ms.Read(bsValue,1);
      AChart.BackWall.Brush.Style:=bsValue;
      ms.Read(clValue,SizeOf(TColor));
      AChart.BackWall.Color:=clValue;
      LoadChartPen(ms,AChart.BackWall.Pen);
      ms.Read(intValue,4);
      AChart.BackWall.Size:=intValue;
      ms.Read(bvValue,1);
      AChart.BevelInner:=bvValue;
      ms.Read(intValue,4);
      AChart.BevelWidth:=intValue;
      ms.Read(bdsValue,1);
      AChart.BorderStyle:=bdsValue;
      ms.Read(intValue,4);
      AChart.BorderWidth:=intValue;
      SetLength(Buf,8);
      ms.Read(Buf[1],8);
      if Buf='NewChart' then
      begin
         ms.Read(blvalue,1);
         TNewChart(AChart).FDrawFrame:=blValue;
      end;
      LoadChartAxis(ms,AChart.BottomAxis);
      LoadChartWall(ms,AChart.BottomWall);
      ms.Read(intValue,4);
      AChart.Chart3DPercent:=intValue;
      ms.Read(csrValue,1);
      AChart.Cursor:=csrValue;
      LoadChartAxis(ms,TChartAxis(AChart.DepthAxis));
      LoadChartPen(ms,AChart.Frame);
      ms.Read(gdValue,1);
      AChart.Gradient.Direction:=gdValue;
      ms.Read(clValue,SizeOf(TColor));
      AChart.Gradient.StartColor:=clValue;
      ms.Read(clValue,SizeOf(TColor));
      AChart.Gradient.EndColor:=clvalue;
      ms.Read(blValue,1);
      AChart.Gradient.Visible:=blValue;
      AChart.Hint:=LoadTextFromStream(ms);
      LoadChartAxis(ms,AChart.LeftAxis);
      LoadChartWall(ms,AChart.LeftWall);
      ms.Read(lalValue,1);
      AChart.Legend.Alignment:=lalValue;
      ms.Read(clValue,SizeOf(TColor));
      AChart.Legend.Color:=clValue;
      ms.Read(intValue,4);
      AChart.Legend.ColorWidth:=intValue;
      LoadChartPen(ms,AChart.Legend.DividingLines);
      ms.Read(intValue,4);
      AChart.Legend.FirstValue:=intValue;
      LoadFont(ms,AChart.Legend.Font);
      LoadChartPen(ms,AChart.Legend.Frame);
      ms.Read(intValue,4);
      AChart.Legend.HorizMargin:=intValue;
      ms.Read(blvalue,1);
      AChart.Legend.Inverted:=blValue;
      ms.Read(lgsValue,1);
      AChart.Legend.LegendStyle:=lgsValue;
      ms.Read(blvalue,1);
      AChart.Legend.ResizeChart:=blvalue;
      ms.Read(clValue,SizeOf(TColor));
      AChart.Legend.ShadowColor:=clValue;
      ms.Read(intValue,4);
      AChart.Legend.ShadowSize:=intValue;
      ms.Read(lgtsValue,1);
      AChart.Legend.TextStyle:=lgtsValue;
      ms.Read(intValue,4);
      AChart.Legend.TopPos:=intValue;
      ms.Read(intValue,4);
      AChart.Legend.VertMargin:=intValue;
      ms.Read(blValue,1);
      AChart.Legend.Visible:=blValue;
      ms.Read(intValue,4);
      AChart.MarginBottom:=intValue;
      ms.Read(intValue,4);
      AChart.MarginLeft:=intValue;
      ms.Read(intValue,4);
      AChart.MarginRight:=intValue;
      ms.Read(intValue,4);
      AChart.MarginTop:=intValue;
      ms.Read(intValue,4);
      AChart.MaxPointsPerPage:=intValue;
      ms.Read(blValue,1);
      AChart.Monochrome:=blValue;
      ms.Read(intValue,4);
      AChart.Page:=intValue;
      LoadChartAxis(ms,AChart.RightAxis);
      ms.Read(blValue,1);
      AChart.ScaleLastPage:=blValue;
      ms.Read(blValue,1);
      AChart.ShowHint:=blValue;
      LoadChartAxis(ms,AChart.TopAxis);
      ms.Read(intValue,4);
      AChart.View3DOptions.Elevation:=intvalue;
      ms.Read(intValue,4);
      AChart.View3DOptions.HorizOffset:=intValue;
      ms.Read(blValue,1);
      AChart.View3DOptions.Orthogonal:=blValue;
      ms.Read(intValue,4);
      AChart.View3DOptions.Rotation:=intValue;
      ms.Read(intValue,4);
      AChart.View3DOptions.Tilt:=intValue;
      ms.Read(intValue,4);
      AChart.View3DOptions.VertOffset:=intValue;
      ms.Read(intValue,4);
      AChart.View3DOptions.Zoom:=intValue;
    end;
    AStream.Read(intValue,4);
    for i:=0 to intValue-1 do
    begin
      ms.Size:=0;
      AStream.Read(Len,4);
      ms.CopyFrom(AStream,Len);
      ms.Position:=0;
      ms.Read(SeriesType,SizeOf(TSeriesType));
      ASeries:=nil;
      case SeriesType of
        stLine:      ASeries:=TLineSeries.Create(AChart);
        stArea:      ASeries:=TAreaSeries.Create(AChart);
        stPoint:     ASeries:=TPointSeries.Create(AChart);
        stVertBar:   ASeries:=TBarSeries.Create(AChart);
        stHorzBar:   ASeries:=THorizBarSeries.Create(AChart);
        stPie:       ASeries:=TPieSeries.Create(AChart);
        stShape:     ASeries:=TChartShape.Create(AChart);
        stFastLine:  ASeries:=TFastLineSeries.Create(AChart);
        stArrows:    ASeries:=TArrowSeries.Create(AChart);
        stGantt:     ASeries:=TGanttSeries.Create(AChart);
        stBubble:    ASeries:=TBubbleSeries.Create(AChart);
      end;
      ms.Read(blValue,SizeOf(Boolean));
      ASeries.Marks.Visible:=blValue;
      ms.Read(smsValue,SizeOf(smsValue));
      ASeries.Marks.Style:=smsValue;
      ms.Read(intValue,4);
      ASeries.Marks.ArrowLength:=intValue;
      //------------------------------------------------------------------------
      LoadChartPen(ms,ASeries.Marks.Arrow);
      ms.Read(clValue,SizeOf(TColor));
      ASeries.Marks.BackColor:=clValue;
      ms.Read(blValue,1);
      ASeries.Marks.Clip:=blValue;
      LoadFont(ms,ASeries.Marks.Font);
      ms.Read(blvalue,1);
      ASeries.Marks.Transparent:=blValue;
      LoadChartPen(ms,ASeries.Marks.Frame);
      ASeries.PercentFormat:=LoadTextFromStream(ms);
      ms.Read(clValue,SizeOf(TColor));
      ASeries.SeriesColor:=clValue;
      ms.Read(blValue,1);
      ASeries.ShowInLegend:=blValue;
      ASeries.Title:=LoadTextFromStream(ms);
      ASeries.ValueFormat:=LoadTextFromStream(ms);
      ms.Read(vaxValue,1);
      ASeries.VertAxis:=vaxValue;
      ms.Read(blvalue,1);
      ASeries.Active:=blValue;
      ms.Read(blValue,1);
      ASeries.AllowSinglePoint:=blValue;
      ms.Read(blValue,1);
      ASeries.ColorEachPoint:=blValue;
      ms.Read(csrValue,1);
      ASeries.Cursor:=csrValue;
      ms.Read(haxValue,1);
      ASeries.HorizAxis:=haxValue;
      if ASeries<>nil then
        AChart.AddSeries(ASeries);
    end;
    ms.Free;
    if Assigned(AChart) then
    begin
      if AStream.Size>AStream.Position then
         ReadChartData(AStream,AChart);
      AChart.Invalidate;
    end;
  end;
end;

procedure SaveTeeChartToFile(AChart:TCustomChart; Const AFileName:String);
var
  tmp : TFileStream;
begin
  tmp:=TFileStream.Create(AFileName,fmCreate);
  try
    SaveTeeChartToStream(AChart,tmp);
  finally
    tmp.Free;
  end;
end;

procedure LoadTeeChartFromFile(AChart:TCustomChart;const AName:String);
var
  tmp : TFileStream;
begin
  tmp:=TFileStream.Create(AName,fmOpenRead);
  try
    LoadTeeChartFromStream(AChart,tmp);
  finally
    tmp.Free;
  end;
end;

{ TAnySeries }

procedure TAnySeries.Add(const AValue: Double; const ALabel: String;
  AColor: TColor);
begin
  FSeries.Add(AValue,ALabel,AColor);
end;

procedure TAnySeries.AddArrow(const X0, Y0, X1, Y1: Double;
  const ALabel: String; AColor: TColor);
begin
  if FSeries is TArrowSeries then
    (FSeries as TArrowSeries).AddArrow(X0,Y0,X1,Y1,ALabel,AColor);
end;

procedure TAnySeries.AddBubble(const AX, AY, ARadius: Double;
  const AXLabel: String; AColor: TColor);
begin
  if FSeries is TBubbleSeries then
    (FSeries as TBubbleSeries).AddBubble(AX,AY,ARadius,AXLabel,AColor);
end;

procedure TAnySeries.AddGantt(const AStart, AEnd, AY: Double;
  const AXLabel: String);
begin
  if FSeries is TGanttSeries then
    (FSeries as TGanttSeries).AddGantt(AStart,AEnd,AY,AXLabel);
end;

procedure TAnySeries.AddNull(const ALabel: String);
begin
  FSeries.AddNull(ALabel);
end;

procedure TAnySeries.AddXY(const AXValue, AYValue: Double;
  const AXLabel: String; AColor: TColor);
begin
  FSeries.AddXY(AXValue,AYValue,AXLabel,AColor);
end;

procedure TAnySeries.Clear;
begin
  FSeries.Clear;
end;

function TAnySeries.Count: Longint;
begin
  Result:=FSeries.Count;
end;

constructor TAnySeries.Create;
begin
  FXValueList:=TAnyChartValueList.Create;
  FYValueList:=TAnyChartValueList.Create;
  FStartXValueList:=TAnyChartValueList.Create;
  FStartYValueList:=TAnyChartValueList.Create;
  FEndXValueList:=TAnyChartValueList.Create;
  FEndYValueList:=TAnyChartValueList.Create;
  FRadiusValueList:=TAnyChartValueList.Create;
  FPieValues:=TAnyChartValueList.Create;
  FStartValueList:=TAnyChartValueList.Create;
  FEndValueList:=TAnyChartValueList.Create;
end;

procedure TAnySeries.Delete(ValueIndex: integer);
begin
  FSeries.Delete(ValueIndex);
end;

destructor TAnySeries.Destroy;
begin
  FXValueList.Free;
  FYValueList.Free;
  FStartXValueList.Free;
  FStartYValueList.Free;
  FEndXValueList.Free;
  FEndYValueList.Free;
  FRadiusValueList.Free;
  FPieValues.Free;
  FStartValueList.Free;
  FEndValueList.Free;
  inherited;
end;

procedure TAnySeries.FillSampleValues(NumValues: Integer);
begin
  FSeries.FillSampleValues(NumValues);
end;

function TAnySeries.GetMarkStyle: TMarkStyle;
begin
  Result:=TMarkStyle(Ord(FSeries.Marks.Style));
end;

function TAnySeries.GetMarkVisible: Boolean;
begin
  Result:=FSeries.Marks.Visible;
end;

function TAnySeries.GetShapeColor: TColor;
begin
  if FSeries is TChartShape then
    Result:=(FSeries as TChartShape).Brush.Color
  else
    Result:=clWhite;
end;

function TAnySeries.GetShapeFrameColor: TColor;
begin
  if FSeries is TChartShape then
    Result:=(FSeries as TChartShape).Pen.Color
  else
    Result:=clBlack;
end;

function TAnySeries.GetShapeX0: Double;
begin
  if FSeries is TChartShape then
    Result:=(FSeries as TChartShape).X0
  else
    Result:=0;
end;

function TAnySeries.GetShapeX1: Double;
begin
  if FSeries is TChartShape then
    Result:=(FSeries as TChartShape).X1
  else
    Result:=0;
end;

function TAnySeries.GetShapeY0: Double;
begin
  if FSeries is TChartShape then
    Result:=(FSeries as TChartShape).Y0
  else
    Result:=0;
end;

function TAnySeries.GetShapeY1: Double;
begin
  if FSeries is TChartShape then
    Result:=(FSeries as TChartShape).Y1
  else
    Result:=0;
end;

function TAnySeries.GetStyle: TShapeStyle;
begin
  if FSeries is TChartShape then
    Result:=TShapeStyle(Ord((FSeries as TChartShape).Style))
  else
    Result:=ssRectangle;
end;

function TAnySeries.GetTitle: string;
begin
  Result:=FSeries.Title;
end;

procedure TAnySeries.Rotate(Angle: Integer);
begin
  if FSeries is TCircledSeries then
    TCircledSeries(FSeries).Rotate(Angle);
end;

procedure TAnySeries.SetMarkStyle(const Value: TMarkStyle);
begin
  FSeries.Marks.Style:=TSeriesMarksStyle(Ord(Value));
end;

procedure TAnySeries.SetMarkVisible(const Value: Boolean);
begin
  FSeries.Marks.Visible:=Value;
end;

procedure TAnySeries.SetSeriesAdapter(const Value: ISeriesAdapter);
begin
  if FSeriesAdapter <> nil then FSeriesAdapter.ReleaseSeries;
  FSeriesAdapter := Value;
  if FSeriesAdapter <> nil then FSeriesAdapter.ReferenceSeries(Self);
end;

procedure TAnySeries.SetShapeColor(const Value: TColor);
begin
  if FSeries is TChartShape then
    (FSeries as TChartShape).Brush.Color:=Value;
end;

procedure TAnySeries.SetShapeFrameColor(const Value: TColor);
begin
  if FSeries is TChartShape then
    (FSeries as TChartShape).Pen.Color:=Value;
end;

procedure TAnySeries.SetShapeX0(const Value: Double);
begin
  if FSeries is TChartShape then
    (FSeries as TChartShape).X0:=Value;
end;

procedure TAnySeries.SetShapeX1(const Value: Double);
begin
  if FSeries is TChartShape then
    (FSeries as TChartShape).X1:=Value;
end;

procedure TAnySeries.SetShapeY0(const Value: Double);
begin
  if FSeries is TChartShape then
    (FSeries as TChartShape).Y0:=Value;
end;

procedure TAnySeries.SetShapeY1(const Value: Double);
begin
  if FSeries is TChartShape then
    (FSeries as TChartShape).Y1:=Value;
end;

procedure TAnySeries.SetStyle(const Value: TShapeStyle);
begin
  if FSeries is TChartShape then
    (FSeries as TChartShape).Style:=TChartShapeStyle(Ord(Value));
end;

procedure TAnySeries.SetTitle(const Value: string);
begin
  FSeries.Title:=Value;
end;

function TAnySeries.XScreenToValue(ScreenPos: Integer): Double;
begin
  Result:=FSeries.XScreenToValue(ScreenPos)
end;

function TAnySeries.YScreenToValue(ScreenPos: Integer): Double;
begin
  Result:=FSeries.YScreenToValue(ScreenPos)
end;

{ TAnyChart }

function TAnyChart.AddSeries(SeriesType: TSeriesType): TAnySeries;
var
  ASeries:TChartSeries;
  S:TAnySeries;
begin
  ASeries:=nil;
  case SeriesType of
    stLine:      ASeries:=TLineSeries.Create(FChart);
    stArea:      ASeries:=TAreaSeries.Create(FChart);
    stPoint:     ASeries:=TPointSeries.Create(FChart);
    stVertBar:   ASeries:=TBarSeries.Create(FChart);
    stHorzBar:   ASeries:=THorizBarSeries.Create(FChart);
    stPie:       ASeries:=TPieSeries.Create(FChart);
    stShape:     ASeries:=TChartShape.Create(FChart);
    stFastLine:  ASeries:=TFastLineSeries.Create(FChart);
    stArrows:    ASeries:=TArrowSeries.Create(FChart);
    stGantt:     ASeries:=TGanttSeries.Create(FChart);
    stBubble:    ASeries:=TBubbleSeries.Create(FChart);
  end;
  if ASeries<>nil then
  begin
    FChart.AddSeries(ASeries);
    S:=TAnySeries.Create;
    S.FSeries:=ASeries;
    S.FSeriesType:=SeriesType;
    S.FXValueList.FValueList:=ASeries.XValues;
    S.FYValueList.FValueList:=ASeries.YValues;
    if SeriesType=stPie then
      S.FPieValues.FValueList:=(ASeries as TPieSeries).PieValues;
    if SeriesType=stArrows then
    begin
      S.FStartXValueList.FValueList:=TArrowSeries(ASeries).StartXValues;
      S.FStartYValueList.FValueList:=TArrowSeries(ASeries).StartYValues;
      S.FEndXValueList.FValueList:=TArrowSeries(ASeries).EndXValues;
      S.FEndYValueList.FValueList:=TArrowSeries(ASeries).EndYValues;
    end;
    if SeriesType=stGantt then
    begin
      S.FStartValueList.FValueList:=TGanttSeries(ASeries).StartValues;
      S.FEndValueList.FValueList:=TGanttSeries(ASeries).EndValues;
    end;
    if SeriesType=stBubble then
      S.FRadiusValueList.FValueList:=TBubbleSeries(ASeries).RadiusValues;
    FSeriesList.Add(S);
    Result:=S;
  end
  else Result:=nil;
end;

constructor TAnyChart.Create;
begin
  FChart:=TNewChart.Create(nil);
  FChart.Width:=185;
  FChart.Height:=105;
  FChart.BackWall.Pen.Visible:=False;
  //FChart.Chart3DPercent:=30;
  FChart.Color:=clWhite;
  //FChart.LeftAxis.Grid.Visible:=False;
  //FChart.BottomAxis.Grid.Visible:=False;
  //FChart.View3D:=False;
  //FChart.AxisVisible:=False;
  FChart.BevelOuter:=bvNone;
  //FChart.Title.Frame.Visible:=True;
  //FChart.Foot.Frame.Visible:=True;
  FSeriesList:=TObjList.Create;
  FFoot:=TAnyChartTitle.Create;
  FFoot.FDefColor:=FChart.Foot.Brush.Color;
  FTitle:=TAnyChartTitle.Create;
  FTitle.FDefColor:=FChart.Title.Brush.Color;
  FFoot.FTitle:=FChart.Foot;
  FTitle.FTitle:=FChart.Title;
  InitChart;
end;

procedure TAnyChart.DeleteItems;
var
  i:integer;
begin
  for i:=0 to FSeriesList.Count-1 do
    TAnySeries(FSeriesList.Items[i]).Free;
  FSeriesList.Clear;
end;

procedure TAnyChart.DeleteSeries(Index: integer);
var
  ASeries:TChartSeries;
  S:TAnySeries;
begin
  if (Index>=0) and (Index<=FSeriesList.Count-1) then
  begin
    S:=TAnySeries(FSeriesList.Items[Index]);
    if S<>nil then
    begin
      ASeries:=S.FSeries;
      if ASeries<>nil then
        ASeries.Free;
      S.Free;
      FSeriesList.Delete(Index);
    end;
  end;
end;

destructor TAnyChart.Destroy;
begin
  FChart.Free;
  DeleteItems;
  FSeriesList.Free;
  FFoot.Free;
  FTitle.Free;
  inherited;
end;

function TAnyChart.GetAxisVisible: Boolean;
begin
  Result:=FChart.AxisVisible;
end;

function TAnyChart.GetBorderVisible: Boolean;
begin
  Result:=FChart.FDrawFrame;
end;

function TAnyChart.GetChart3DPercent: integer;
begin
  Result:=FChart.Chart3DPercent;
end;

function TAnyChart.GetColor: TColor;
begin
  Result:=FChart.Color;
end;

function TAnyChart.GetEnable: Boolean;
begin
  Result:=FChart.Enabled;
end;

function TAnyChart.GetGradientDirection: TAnyGradientDirection;
begin
  Result:=TAnyGradientDirection(Ord(FChart.Gradient.Direction));
end;

function TAnyChart.GetGradientEndColor: TColor;
begin
  Result:=FChart.Gradient.EndColor;
end;

function TAnyChart.GetGradientStartColor: TColor;
begin
  Result:=FChart.Gradient.StartColor;
end;

function TAnyChart.GetGradientVisible: Boolean;
begin
  Result:=FChart.Gradient.Visible;
end;

function TAnyChart.GetHeight: integer;
begin
  Result:=FChart.Height;
end;

function TAnyChart.GetHorzGridLine: Boolean;
begin
  Result:=FChart.LeftAxis.Grid.Visible;
end;

function TAnyChart.GetHorzGridLineColor: TColor;
begin
  Result:=FChart.LeftAxis.Grid.Color;
end;

function TAnyChart.GetHorzGridLineStyle: TPenStyle;
begin
  Result:=FChart.LeftAxis.Grid.Style;
end;

function TAnyChart.GetHorzGridLineWidth: integer;
begin
  Result:=FChart.LeftAxis.Grid.Width;
end;

function TAnyChart.GetLeft: integer;
begin
  Result:=FChart.Left;
end;

function TAnyChart.GetLegendVisible: Boolean;
begin
  Result:=FChart.Legend.Visible;
end;

function TAnyChart.GetTop: integer;
begin
  Result:=FChart.Top;
end;

function TAnyChart.GetVertGridLine: Boolean;
begin
  Result:=FChart.BottomAxis.Grid.Visible;
end;

function TAnyChart.GetVertGridLineColor: TColor;
begin
  Result:=FChart.BottomAxis.Grid.Color;
end;

function TAnyChart.GetVertGridLineStyle: TPenStyle;
begin
  Result:=FChart.BottomAxis.Grid.Style;
end;

function TAnyChart.GetVertGridLineWidth: integer;
begin
  Result:=FChart.BottomAxis.Grid.Width;
end;

function TAnyChart.GetView3D: Boolean;
begin
  Result:=FChart.View3D;
end;

function TAnyChart.GetVisible: Boolean;
begin
  Result:=FChart.Visible;
end;

function TAnyChart.GetWidth: integer;
begin
  Result:=FChart.Width;
end;

procedure TAnyChart.InitChart;
begin
  FFoot.AdjustFrame:=FChart.Foot.AdjustFrame;
  FFoot.Alignment:=FChart.Foot.Alignment;
  {$IFNDEF Delphi5}
  FFoot.BrushColor:=FChart.Foot.Brush.Color;
  {$ELSE}
  FFoot.BrushColor:=FChart.Foot.Color;
  {$ENDIF}
  FFoot.BrushStyle:=FChart.Foot.Brush.Style;
  FFoot.Font.Assign(FChart.Foot.Font);
  FFoot.Text:=FChart.Foot.Text.Text;
  FFoot.Visible:=FChart.Foot.Visible;

  FTitle.AdjustFrame:=FChart.Title.AdjustFrame;
  FTitle.Alignment:=FChart.Title.Alignment;
  {$IFNDEF Delphi5}
  FTitle.BrushColor:=FChart.Title.Brush.Color;
  {$ELSE}
  FTitle.BrushColor:=FChart.Title.Color;
  {$ENDIF}
  FTitle.BrushStyle:=FChart.Title.Brush.Style;
  FTitle.Font.Assign(FChart.Title.Font);
  FTitle.Text:=FChart.Title.Text.Text;
  FTitle.Visible:=FChart.Title.Visible;
end;

procedure TAnyChart.LoadFromStream(Stream: TStream);
var
  i:integer;
  ASeries:TChartSeries;
  S:TAnySeries;
begin
  DeleteItems;
  FChart.FreeAllSeries;
  LoadTeeChartFromStream(FChart,Stream);
  for i:=0 to FChart.SeriesCount-1 do
  begin
    ASeries:=FChart.Series[i];
    S:=TAnySeries.Create;
    S.FSeries:=ASeries;
    if  ASeries is TLineSeries then
      S.FSeriesType:=stLine
    else if ASeries is TAreaSeries then
      S.FSeriesType:=stArea
    else if ASeries is TPointSeries then
      S.FSeriesType:=stPoint
    else if ASeries is TBarSeries then
      S.FSeriesType:=stVertBar
    else if ASeries is THorizBarSeries then
      S.FSeriesType:=stHorzBar
    else if ASeries is TPieSeries then
      S.FSeriesType:=stPie
    else if ASeries is TChartShape then
      S.FSeriesType:=stShape
    else if ASeries is TFastLineSeries then
      S.FSeriesType:=stFastLine
    else if ASeries is TArrowSeries then
      S.FSeriesType:=stArrows
    else if ASeries is TGanttSeries then
      S.FSeriesType:=stGantt
    else if ASeries is TBubbleSeries then
      S.FSeriesType:=stBubble;
    FSeriesList.Add(S);
  end;
end;

procedure TAnyChart.SaveToStream(Stream: TStream);
begin
  SaveTeeChartToStream(FChart,Stream);
end;

function TAnyChart.Series(Index: integer): TAnySeries;
begin
  if (Index>=0) and (Index<=FSeriesList.Count-1) then
    Result:=TAnySeries(FSeriesList.Items[Index])
  else
    Result:=nil;  
end;

procedure TAnyChart.SetAxisVisible(const Value: Boolean);
begin
  FChart.AxisVisible:=Value;
end;

procedure TAnyChart.SetBorderVisible(const Value: Boolean);
begin
  FChart.FDrawFrame:=Value;
end;

procedure TAnyChart.SetChart3DPercent(const Value: integer);
begin
  FChart.Chart3DPercent:=Value;
end;

procedure TAnyChart.SetChartAdapter(const Value: IChartAdapter);
begin
  if FChartAdapter <> nil then FChartAdapter.ReleaseChart;
  FChartAdapter := Value;
  if FChartAdapter <> nil then FChartAdapter.ReferenceChart(Self);
end;

procedure TAnyChart.SetColor(const Value: TColor);
begin
  FChart.Color:=Value;
end;

procedure TAnyChart.SetEnable(const Value: Boolean);
begin
  FChart.Enabled:=Value;
end;

procedure TAnyChart.SetFoot(const Value: TAnyChartTitle);
begin
  FFoot.AdjustFrame:=Value.AdjustFrame;
  FFoot.Alignment:=Value.Alignment;
  FFoot.BrushColor:=Value.BrushColor;
  FFoot.BrushStyle:=Value.BrushStyle;
  FFoot.Font.Assign(Value.Font);
  FFoot.Text:=Value.Text;
  FFoot.Visible:=Value.Visible;

  FChart.Foot.AdjustFrame:=Value.AdjustFrame;
  FChart.Foot.Alignment:=Value.Alignment;
  FChart.Foot.Brush.Color:=Value.BrushColor;
  FChart.Foot.Brush.Style:=Value.BrushStyle;
  FChart.Foot.Font.Assign(Value.Font);
  FChart.Foot.Text.Text:=Value.Text;
  FChart.Foot.Visible:=Value.Visible;
end;

procedure TAnyChart.SetGradientDirection(
  const Value: TAnyGradientDirection);
begin
  FChart.Gradient.Direction:=TGradientDirection(Ord(Value));
end;

procedure TAnyChart.SetGradientEndColor(const Value: TColor);
begin
  FChart.Gradient.EndColor:=Value;
end;

procedure TAnyChart.SetGradientStartColor(const Value: TColor);
begin
  FChart.Gradient.StartColor:=Value;
end;

procedure TAnyChart.SetGradientVisible(const Value: Boolean);
begin
  FChart.Gradient.Visible:=Value;
end;

procedure TAnyChart.SetHeight(const Value: integer);
begin
  FChart.Height:=Value;
end;

procedure TAnyChart.SetHorzGridLine(const Value: Boolean);
begin
   FChart.LeftAxis.Grid.Visible:=Value;
end;

procedure TAnyChart.SetHorzGridLineColor(const Value: TColor);
begin
  FChart.LeftAxis.Grid.Color:=Value;
end;

procedure TAnyChart.SetHorzGridLineStyle(const Value: TPenStyle);
begin
  FChart.LeftAxis.Grid.Style:=Value;
end;

procedure TAnyChart.SetHorzGridLineWidth(const Value: integer);
begin
  FChart.LeftAxis.Grid.Width:=Value;
end;

procedure TAnyChart.SetLeft(const Value: integer);
begin
  FChart.Left:=Value;
end;

procedure TAnyChart.SetLegendVisible(const Value: Boolean);
begin
  FChart.Legend.Visible:=Value;
end;

procedure TAnyChart.SetTitle(const Value: TAnyChartTitle);
begin
  FTitle.AdjustFrame:=Value.AdjustFrame;
  FTitle.Alignment:=Value.Alignment;
  FTitle.BrushColor:=Value.BrushColor;
  FTitle.BrushStyle:=Value.BrushStyle;
  FTitle.Font.Assign(Value.Font);
  FTitle.Text:=Value.Text;
  FTitle.Visible:=Value.Visible;

  FChart.Title.AdjustFrame:=Value.AdjustFrame;
  FChart.Title.Alignment:=Value.Alignment;
  FChart.Title.Brush.Color:=Value.BrushColor;
  FChart.Title.Brush.Style:=Value.BrushStyle;
  FChart.Title.Font.Assign(Value.Font);
  FChart.Title.Text.Text:=Value.Text;
  FChart.Title.Visible:=Value.Visible;
end;

procedure TAnyChart.SetTop(const Value: integer);
begin
  FChart.Top:=Value;
end;

procedure TAnyChart.SetVertGridLine(const Value: Boolean);
begin
  FChart.BottomAxis.Grid.Visible:=Value;
end;

procedure TAnyChart.SetVertGridLineColor(const Value: TColor);
begin
  FChart.BottomAxis.Grid.Color:=Value;
end;

procedure TAnyChart.SetVertGridLineStyle(const Value: TPenStyle);
begin
  FChart.BottomAxis.Grid.Style:=Value;
end;

procedure TAnyChart.SetVertGridLineWidth(const Value: integer);
begin
  FChart.BottomAxis.Grid.Width:=Value;
end;

procedure TAnyChart.SetView3D(const Value: Boolean);
begin
  FChart.View3D:=Value;
end;

procedure TAnyChart.SetVisible(const Value: Boolean);
begin
  FChart.Visible:=Value;
end;

procedure TAnyChart.SetWidth(const Value: integer);
begin
  FChart.Width:=Value;
end;

{ TAnyChartTitle }

constructor TAnyChartTitle.Create;
begin
  FFont:=TFont.Create;
  FFont.OnChange:=FontChange;
end;

destructor TAnyChartTitle.Destroy;
begin
  FFont.Free;
  inherited;
end;

procedure TAnyChartTitle.FontChange(Sneder: TObject);
begin
  FTitle.Font.Assign(FFont);
end;

function TAnyChartTitle.GetAdjustFrame: Boolean;
begin
  Result:=FTitle.AdjustFrame;
end;

function TAnyChartTitle.GetAlignment: TAlignment;
begin
  Result:=FTitle.Alignment;
end;

function TAnyChartTitle.GetBrushColor: TColor;
begin
  Result:=FTitle.Brush.Color;
end;

function TAnyChartTitle.GetBrushStyle: TBrushStyle;
begin
  Result:=FTitle.Brush.Style;
end;

function TAnyChartTitle.GetText: string;
begin
  Result:=FTitle.Text.Text;
end;

function TAnyChartTitle.GetVisible: Boolean;
begin
  Result:=FTitle.Visible;
end;

procedure TAnyChartTitle.SetAdjustFrame(const Value: Boolean);
begin
  FTitle.AdjustFrame:=Value;
end;

procedure TAnyChartTitle.SetAlignment(const Value: TAlignment);
begin
  FTitle.Alignment:=Value;
end;

procedure TAnyChartTitle.SetBrushColor(const Value: TColor);
begin
  {$IFNDEF Delphi5}
  FTitle.Brush.Color:=Value;
  FTitle.Frame.Visible:=(FTitle.Text.Text<>'') and (FTitle.Brush.Color<>FDefColor);
  if FTitle.Frame.Visible then
    FTitle.Frame.Color:=FTitle.Brush.Color;
  {$ELSE}
  FTitle.Color:=Value;
  {$ENDIF}
end;

procedure TAnyChartTitle.SetBrushStyle(const Value: TBrushStyle);
begin
  FTitle.Brush.Style:=Value;
end;

procedure TAnyChartTitle.SetChartTitleAdapter(
  const Value: IChartTitleAdapter);
begin
  if FChartTitleAdapter <> nil then FChartTitleAdapter.ReleaseChartTitle;
  FChartTitleAdapter := Value;
  if FChartTitleAdapter <> nil then FChartTitleAdapter.ReferenceChartTitle(Self);
end;

procedure TAnyChartTitle.SetFont(const Value: TFont);
begin
  FFont.Assign(Value);
  FTitle.Font.Assign(Value);
end;

procedure TAnyChartTitle.SetText(const Value: string);
begin
  FTitle.Text.Text:=Value;
  {$IFNDEF Delphi5}
  FTitle.Frame.Visible:=(Value<>'') and (FTitle.Brush.Color<>FDefColor);
  if FTitle.Frame.Visible then
    FTitle.Frame.Color:=FTitle.Brush.Color;  
  {$ENDIF}
end;

procedure TAnyChartTitle.SetVisible(const Value: Boolean);
begin
  FTitle.Visible:=Value;
end;

{ TNewChart }

constructor TNewChart.Create(AOwner: TComponent);
begin
  FDrawFrame:=True;
  inherited Create(AOwner);
end;

procedure TNewChart.Paint;
begin
  inherited;
  if FDrawFrame and (BevelOuter=bvNone) and (BevelInner=bvNone) and (BorderStyle=bsNone) then
  begin
    Canvas.Pen.Color:=clBlack;
    Canvas.Pen.Style:=psSolid;
    Canvas.MoveTo(0,Height);
    Canvas.LineTo(0,0);
    Canvas.LineTo(Width-1,0);
    Canvas.LineTo(Width-1,Height-1);
    Canvas.LineTo(0,Height-1);
  end;
end;

{ TAnyChartValueList }

function TAnyChartValueList.Count: Longint;
begin
  if FValueList<>nil then
    Result:=FValueList.Count
  else
    Result:=0;
end;

constructor TAnyChartValueList.Create;
begin
  FValueList:=nil;
end;

procedure TAnyChartValueList.Delete(ValueIndex: Integer);
begin
  if FValueList<>nil then
    FValueList.Delete(ValueIndex)
end;

function TAnyChartValueList.First: Double;
begin
  if FValueList<>nil then
    Result:=FValueList.First
  else
    Result:=0;
end;

function TAnyChartValueList.GetMaxValue: Double;
begin
  if FValueList<>nil then
    Result:=FValueList.MaxValue
  else
    Result:=0;
end;

function TAnyChartValueList.GetMinValue: Double;
begin
  if FValueList<>nil then
    Result:=FValueList.MinValue
  else
    Result:=0;
end;

function TAnyChartValueList.GetTotalValue: Double;
begin
  if FValueList<>nil then
    Result:=FValueList.Total
  else
    Result:=0;
end;

function TAnyChartValueList.Last: Double;
begin
  if FValueList<>nil then
    Result:=FValueList.Last
  else
    Result:=0;
end;

function TAnyChartValueList.Locate(const Value: Double): Longint;
begin
  if FValueList<>nil then
    Result:=FValueList.Locate(Value)
  else
    Result:=-1;  
end;

procedure TAnyChartValueList.SetValue(Index: integer; Value: Double);
begin
  if FValueList<>nil then
    FValueList.Value[Index]:=Value;
end;

procedure TAnyChartValueList.SetValueListAdapter(
  const Value: IValueListAdapter);
begin
  if FValueListAdapter <> nil then FValueListAdapter.ReleaseValueList;
  FValueListAdapter := Value;
  if FValueListAdapter <> nil then FValueListAdapter.ReferenceValueList(Self);
end;

function TAnyChartValueList.Value(Index: integer): Double;
begin
  if FValueList<>nil then
    Result:=FValueList.Value[Index]
  else
    Result:=0;  
end;

end.
