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

  1. {****************************************}
  2. {       TDBChart Component               }
  3. { Copyright (c) 1995-98 by David Berneda }
  4. {   All rights Reserved                  }
  5. {****************************************}
  6. {$I teedefs.inc}
  7. unit DBChart;
  8.  
  9. interface
  10.  
  11. uses
  12.   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  13.   Forms, Dialogs, ExtCtrls, Chart, DB, TeeProcs, Menus, TeCanvas,
  14.  {$IFNDEF D3}
  15.   DBTables,DBIErrs,
  16.  {$ENDIF}
  17.   StdCtrls,Teengine;
  18.  
  19. type
  20.   DBChartException=class(Exception);
  21.  
  22.   TListOfDataSources=class(TList)
  23.   private
  24.     procedure SetDataSource(Index:Integer; DataSource:TDataSource);
  25.     function GetDataSource(Index:Integer):TDataSource;
  26.   public
  27.     property DataSource[Index:Integer]:TDataSource read GetDataSource
  28.                                                    write SetDataSource; {$IFNDEF D1}default;{$ENDIF}
  29.   end;
  30.  
  31.   TCustomDBChart=class;
  32.  
  33.   TProcessRecordEvent=Procedure(Sender:TCustomDBChart; DataSet:TDataSet) of object;
  34.  
  35.   TCustomDBChart = class(TCustomChart)
  36.   private
  37.     FAutoRefresh     : Boolean;
  38.     FRefreshInterval : Longint;
  39.     FShowGlassCursor : Boolean;
  40.     FOnProcessRecord : TProcessRecordEvent;
  41.     { internal }
  42.     IUpdating        : Boolean; 
  43.     ITimer           : TTimer;
  44.     IDataSources     : TListOfDataSources;
  45.     Procedure CheckDataSet(ADataSet:TDataSet; ASeries:TChartSeries);
  46.     Procedure CheckNewDataSource(ADataSet:TDataSet; SingleRow:Boolean);
  47.     Procedure DataSourceRowChange(Sender:TObject; Field:TField);
  48.     Procedure DataSourceStateChange(Sender:TObject);
  49.     Procedure DataSourceUpdateData(Sender:TObject);
  50.     Procedure SetRefreshInterval(Value:Longint);
  51.     Procedure CheckTimer;
  52.     Procedure OnRefreshTimer(Sender:TObject);
  53.   protected
  54.     procedure RemovedDataSource( ASeries: TChartSeries;
  55.                                  AComponent: TComponent ); override;
  56.   public
  57.     constructor Create(AOwner: TComponent); override;
  58.     destructor Destroy; override;
  59.     Procedure Assign(Source:TPersistent); override;
  60.     Procedure CheckDatasource(ASeries:TChartSeries); override;
  61.     Function IsValidDataSource(ASeries:TChartSeries; AComponent:TComponent):Boolean; override;
  62.  
  63.     Procedure FillValueSourceItems( AValueList:TChartValueList; Proc:TGetStrProc); override;
  64.     Procedure FillSeriesSourceItems( ASeries:TChartSeries; Proc:TGetStrProc); override;
  65.  
  66.     Procedure RefreshDataSet(ADataSet:TDataSet; ASeries:TChartSeries);
  67.     Procedure RefreshData;
  68.     { properties }
  69.     property AutoRefresh:Boolean read FAutoRefresh write FAutoRefresh default True;
  70.     property RefreshInterval:Longint read FRefreshInterval write SetRefreshInterval default 0;
  71.     property ShowGlassCursor:Boolean read FShowGlassCursor write FShowGlassCursor default True;
  72.     { events }
  73.     property OnProcessRecord:TProcessRecordEvent read FOnProcessRecord
  74.                                                  write FOnProcessRecord;
  75.   published
  76.   end;
  77.  
  78.   TDBChart=class(TCustomDBChart)
  79.   published
  80.     { TCustomDBChart properties }
  81.     property AutoRefresh;
  82.     property RefreshInterval;
  83.     property ShowGlassCursor;
  84.     { TCustomDBChart events }
  85.     property OnProcessRecord;
  86.  
  87.     { TCustomChart Properties }
  88.     property AllowPanning;
  89.     property AllowZoom;
  90.     property AnimatedZoom;
  91.     property AnimatedZoomSteps;
  92.     property BackImage;
  93.     property BackImageInside;
  94.     property BackImageMode;
  95.     property BackWall;
  96.     property BottomWall;
  97.     property Foot;
  98.     property Gradient;
  99.     property LeftWall;
  100.     property MarginBottom;
  101.     property MarginLeft;
  102.     property MarginRight;
  103.     property MarginTop;
  104.     property PrintProportional;
  105.     property Title;
  106.  
  107.     { TCustomChart Events }
  108.     property OnAllowScroll;
  109.     property OnClickAxis;
  110.     property OnClickLegend;
  111.     property OnClickSeries;
  112.     property OnClickBackground;
  113.     property OnGetLegendPos;
  114.     property OnGetLegendRect;
  115.     property OnScroll;
  116.     property OnUndoZoom;
  117.     property OnZoom;
  118.  
  119.     { TCustomAxisPanel properties }
  120.     property AxisVisible;
  121.     property BackColor;
  122.     property BottomAxis;
  123.     property Chart3DPercent;
  124.     property ClipPoints;
  125.     property DepthAxis;
  126.     property Frame;
  127.     property LeftAxis;
  128.     property Legend;
  129.     property MaxPointsPerPage;
  130.     property Monochrome;
  131.     property Page;
  132.     property RightAxis;
  133.     property ScaleLastPage;
  134.     property SeriesList;
  135.     property TopAxis;
  136.     property View3D;
  137.     property View3DOptions;
  138.     property View3DWalls;
  139.  
  140.     { TCustomAxisPanel events }
  141.     property OnAfterDraw;
  142.     property OnBeforeDrawAxes;
  143.     property OnBeforeDrawSeries;
  144.     property OnGetAxisLabel;
  145.     property OnGetLegendText;
  146.     property OnGetNextAxisLabel;
  147.     property OnPageChange;
  148.  
  149.     { TPanel properties }
  150.     property Align;
  151.     property BevelInner;
  152.     property BevelOuter;
  153.     property BevelWidth;
  154.     property BorderWidth;
  155.     property BorderStyle;
  156.     property Color;
  157.     property DragCursor;
  158.     property DragMode;
  159.     property Enabled;
  160.     property ParentColor;
  161.     property ParentShowHint;
  162.     property PopupMenu;
  163.     property ShowHint;
  164.     property TabOrder;
  165.     property TabStop;
  166.     property Visible;
  167.     {$IFDEF D4}
  168.     property AutoSize;
  169.     property Constraints;
  170.     property DragKind;
  171.     {$ENDIF}
  172.  
  173.     { TPanel events }
  174.     property OnClick;
  175.     property OnDblClick;
  176.     property OnDragDrop;
  177.     property OnDragOver;
  178.     property OnEndDrag;
  179.     property OnEnter;
  180.     property OnExit;
  181.     property OnMouseDown;
  182.     property OnMouseMove;
  183.     property OnMouseUp;
  184.     property OnResize;
  185.     {$IFDEF D3}
  186.     property OnStartDrag;
  187.     {$ENDIF}
  188.     {$IFDEF D4}
  189.     property OnCanResize;
  190.     property OnConstrainedResize;
  191.     property OnDockDrop;
  192.     property OnDockOver;
  193.     property OnEndDock;
  194.     property OnStartDock;
  195.     property OnUnDock;
  196.     {$ENDIF}
  197.   end;
  198.  
  199. implementation
  200.  
  201. Uses TeeConst;
  202.  
  203. type
  204.   TDBChartDataSource=class(TDataSource)
  205.   private
  206.     FWasActive:Boolean;
  207.     Procedure SetDataSet(Value:TDataSet);
  208.   end;
  209.  
  210. Procedure TDBChartDataSource.SetDataSet(Value:TDataSet);
  211. Begin
  212.   DataSet:=Value;
  213.   FWasActive:=DataSet.Active;
  214. end;
  215.  
  216. procedure TListOfDataSources.SetDataSource(Index:Integer; DataSource:TDataSource);
  217. begin
  218.   inherited Items[Index]:=DataSource;
  219. end;
  220.  
  221. function TListOfDataSources.GetDataSource(Index:Integer):TDataSource;
  222. begin
  223.   result:=TDataSource(inherited Items[Index]);
  224. end;
  225.  
  226. { TDBChart }
  227. Constructor TCustomDBChart.Create(AOwner: TComponent);
  228. begin
  229.   inherited Create(AOwner);
  230.   IDataSources:=TListOfDataSources.Create;
  231.   FAutoRefresh:=True;
  232.   FShowGlassCursor:=True;
  233.   FRefreshInterval:=0;
  234.   ITimer:=nil;
  235.   IUpdating:=False;
  236. end;
  237.  
  238. Destructor TCustomDBChart.Destroy;
  239. var t:Longint;
  240. begin
  241.   ITimer.Free;
  242.   for t:=0 to IDataSources.Count-1 do IDataSources.DataSource[t].Free;
  243.   IDataSources.Free;
  244.   inherited Destroy;
  245. end;
  246.  
  247. procedure TCustomDBChart.RemovedDataSource( ASeries: TChartSeries;
  248.                                             AComponent: TComponent );
  249. var t:Longint;
  250.     tmp:TDataSet;
  251. begin
  252.   inherited RemovedDataSource(ASeries,AComponent);
  253.   if AComponent is TDataSet then
  254.   for t:=0 to IDataSources.Count-1 do
  255.   begin
  256.     tmp:=IDataSources.DataSource[t].DataSet;
  257.     if (not Assigned(tmp)) or (tmp=AComponent) then
  258.     begin
  259.       IDataSources.DataSource[t].Free;
  260.       IDataSources.Delete(t);
  261.       break;
  262.     end;
  263.   end;
  264. end;
  265.  
  266. Procedure TCustomDBChart.CheckTimer;
  267. Begin
  268.   if Assigned(ITimer) then ITimer.Enabled:=False;
  269.   if (FRefreshInterval>0) and (not (csDesigning in ComponentState) ) then
  270.   Begin
  271.     if not Assigned(ITimer) then
  272.     Begin
  273.       ITimer:=TTimer.Create(Self);
  274.       ITimer.Enabled:=False;
  275.       ITimer.OnTimer:=OnRefreshTimer;
  276.     end;
  277.     ITimer.Interval:=FRefreshInterval*1000;
  278.     ITimer.Enabled:=True;
  279.   end;
  280. End;
  281.  
  282. Procedure TCustomDBChart.OnRefreshTimer(Sender:TObject);
  283. var t:Longint;
  284. Begin
  285.   ITimer.Enabled:=False;  { no try..finally here ! }
  286.   for t:=0 to IDataSources.Count-1 do
  287.   With IDataSources.DataSource[t] do
  288.   Begin
  289.     if DataSet.Active then
  290.     Begin
  291.     {$IFNDEF D3}
  292.       if DataSet is TQuery then
  293.       begin
  294.         DataSet.Close;
  295.         DataSet.Open;
  296.       end
  297.       else
  298.     {$ENDIF}
  299.         DataSet.Refresh;
  300.       CheckDataSet(DataSet,nil);
  301.     end;
  302.   end;
  303.   ITimer.Enabled:=True;
  304. end;
  305.  
  306. Procedure TCustomDBChart.SetRefreshInterval(Value:Longint);
  307. Begin
  308.   if (Value<0) or (Value>60) then
  309.      Raise DBChartException.Create(TeeMsg_RefreshInterval);
  310.   FRefreshInterval:=Value;
  311.   CheckTimer;
  312. End;
  313.  
  314. Function TCustomDBChart.IsValidDataSource(ASeries:TChartSeries; AComponent:TComponent):Boolean;
  315. Begin
  316.   result:=inherited IsValidDataSource(ASeries,AComponent);
  317.   if not Result then result:=(AComponent is TDataSet) or (AComponent is TDataSource);
  318. end;
  319.  
  320. Procedure TCustomDBChart.DataSourceRowChange(Sender:TObject; Field:TField);
  321. begin
  322.   if not IUpdating then
  323.   With TDBChartDataSource(Sender) do CheckDataSet(DataSet,nil);
  324. end;
  325.  
  326. Procedure TCustomDBChart.DataSourceUpdateData(Sender:TObject);
  327. Begin
  328.   With TDBChartDataSource(Sender) do
  329.   if State=dsBrowse then CheckDataSet(DataSet,nil)
  330.                     else FWasActive:=False;
  331. End;
  332.  
  333. Procedure TCustomDBChart.DataSourceStateChange(Sender:TObject);
  334. var t:Longint;
  335. Begin
  336.   With TDBChartDataSource(Sender) do
  337.   if State=dsInactive then
  338.   Begin
  339.     FWasActive:=False;
  340.     if FAutoRefresh then
  341.        for t:=0 to SeriesCount-1 do
  342.            if Series[t].DataSource=DataSet then Series[t].Clear;
  343.   end
  344.   else
  345.   if (State=dsBrowse) and (not FWasActive) then
  346.   Begin
  347.     CheckDataSet(DataSet,nil);
  348.     FWasActive:=True;
  349.   end;
  350. end;
  351.  
  352. Procedure TCustomDBChart.CheckNewDataSource(ADataSet:TDataSet; SingleRow:Boolean);
  353. Var tmpDataSource:TDBChartDataSource;
  354. Begin
  355.   if IDataSources.IndexOf(ADataSet)<>-1 then Exit;
  356.   tmpDataSource:=TDBChartDataSource.Create(Self);
  357.   With tmpDataSource do
  358.   begin
  359.     SetDataSet(ADataSet);
  360.     OnStateChange := DataSourceStateChange;
  361.     OnUpdateData  := DataSourceUpdateData;
  362.     if SingleRow then OnDataChange  := DataSourceRowChange;
  363.   end;
  364.   IDataSources.Add(tmpDataSource);
  365. end;
  366.  
  367. Procedure TCustomDBChart.CheckDatasource(ASeries:TChartSeries);
  368. Begin
  369.   if Assigned(ASeries) then
  370.   With ASeries do
  371.   Begin
  372.     if ParentChart=Self then
  373.     Begin
  374.       if DataSource<>nil then
  375.       Begin
  376.         ASeries.Clear;
  377.         if DataSource is TDataSet then
  378.         Begin
  379.           CheckNewDataSource(TDataSet(DataSource),False);
  380.           CheckDataSet(TDataSet(DataSource),ASeries);
  381.         end
  382.         else
  383.         if DataSource is TDataSource then
  384.         begin
  385.           CheckNewDataSource(TDataSource(DataSource).DataSet,True);
  386.           CheckDataSet(TDataSource(DataSource).DataSet,ASeries);
  387.         end
  388.         else inherited CheckDataSource(ASeries);
  389.       end;
  390.     end
  391.     else Raise ChartException.Create(TeeMsg_SeriesParentNoSelf);
  392.   end;
  393. end;
  394.  
  395. Procedure TCustomDBChart.CheckDataSet(ADataSet:TDataSet; ASeries:TChartSeries);
  396. Begin
  397.   if FAutoRefresh then RefreshDataSet(ADataSet,ASeries);
  398. end;
  399.  
  400. Procedure TCustomDBChart.RefreshDataSet( ADataSet:TDataSet; ASeries:TChartSeries );
  401. Var HasAnyDataSet:Boolean;
  402.  
  403.   Procedure ProcessRecord(tmpSeries:TChartSeries);
  404.   var tmpxLabel:String;
  405.       tmpColor:TColor;
  406.       tmpX,tmpY:Double;
  407.  
  408.       Procedure AddToSeries(DestSeries:TChartSeries);
  409.       Var t,tmpIndex:Longint;
  410.       begin
  411.         With DestSeries do
  412.         begin
  413.           With ValuesLists do
  414.           for t:=2 to Count-1 do
  415.           Begin
  416.             With ValueList[t] do
  417.             if ValueSource<>'' then TempValue:=ADataSet.FieldByName(ValueSource).AsFloat
  418.                                else ClearTempValue(ValueList[t]);
  419.           end;
  420.           if YMandatory then
  421.           Begin
  422.             if XValues.ValueSource<>'' then
  423.                tmpIndex:=AddXY(tmpX,tmpY,tmpxLabel,tmpColor)
  424.             else
  425.                tmpIndex:=AddY(tmpY,tmpXLabel,tmpColor);
  426.           end
  427.           else
  428.           Begin
  429.             if YValues.ValueSource<>'' then
  430.                tmpIndex:=AddXY(tmpX,tmpY,tmpxLabel,tmpColor)
  431.             else
  432.                tmpIndex:=AddX(tmpX,tmpXLabel,tmpColor);
  433.           end;
  434.           if tmpIndex<>-1 then AddValue(tmpIndex);
  435.         end;
  436.       end;
  437.  
  438.       Procedure GetFloatField(Const FieldName:String; Var res:Double);
  439.       begin
  440.         if FieldName='' then res:=0
  441.                         else res:=ADataSet.FieldByName(FieldName).AsFloat
  442.       end;
  443.  
  444.   var t,tmpNumFields:Integer;
  445.       tmpFieldName:String;
  446.   Begin
  447.     With ADataSet,tmpSeries do
  448.     Begin
  449.       if XLabelsSource<>'' then tmpxLabel:=FieldByName(XLabelsSource).DisplayText { <-- fix }
  450.                            else tmpxLabel:='';
  451.  
  452.       if ColorSource='' then
  453.       begin
  454.         if (MandatoryValueList.ValueSource<>'') and
  455.            FieldByName(TeeExtractField(MandatoryValueList.ValueSource,1)).IsNull then
  456.            tmpColor:=clNone
  457.         else
  458.            tmpColor:=clTeeColor;
  459.       end
  460.       else tmpColor:=FieldByName(ColorSource).AsInteger;
  461.  
  462.       tmpNumFields:=TeeNumFields(MandatoryValueList.ValueSource);
  463.       if tmpNumFields=1 then
  464.       begin
  465.         tmpFieldName:=MandatoryValueList.ValueSource;
  466.         if (not HasAnyDataSet) and (XLabelsSource='') then tmpXLabel:=tmpFieldName;
  467.         if YMandatory then
  468.         begin
  469.           GetFloatField(XValues.ValueSource, tmpX);
  470.           GetFloatField(tmpFieldName, tmpY);
  471.         end
  472.         else
  473.         begin
  474.           GetFloatField(tmpFieldName, tmpX);
  475.           GetFloatField(YValues.ValueSource, tmpY);
  476.         end;
  477.         AddToSeries(tmpSeries);
  478.       end
  479.       else
  480.       for t:=1 to tmpNumFields do
  481.       begin
  482.         tmpFieldName:=TeeExtractField(MandatoryValueList.ValueSource,t);
  483.         if XLabelsSource='' then tmpXLabel:=tmpFieldName;
  484.         if YMandatory then GetFloatField(tmpFieldName, tmpY)
  485.                       else GetFloatField(tmpFieldName, tmpX);
  486.         AddToSeries(tmpSeries);
  487.       end;
  488.     end;
  489.   end;
  490.  
  491. Var FListSeries:TChartSeriesList;
  492.  
  493.   Procedure FillTempSeriesList;
  494.  
  495.    Function IsDataSet(ASeries:TChartSeries):Boolean;
  496.    begin
  497.      With ASeries do
  498.      if DataSource is TDataSet then
  499.      begin
  500.        HasAnyDataSet:=True;
  501.        result:=DataSource=ADataSet
  502.      end
  503.      else
  504.      if DataSource is TDataSource then result:=TDataSource(DataSource).DataSet=ADataSet
  505.      else
  506.         result:=False;
  507.    end;
  508.  
  509.   var t:Longint;
  510.     tmpSeries:TChartSeries;
  511.   begin
  512.     FListSeries.Clear;
  513.     if Assigned(ASeries) then
  514.     begin
  515.       FListSeries.Add(ASeries);
  516.       HasAnyDataSet:=ASeries.DataSource=ADataSet;
  517.     end
  518.     else
  519.     for t:=0 to SeriesCount-1 do
  520.     Begin
  521.       tmpSeries:=Series[t];
  522.       if IsDataSet(tmpSeries) and
  523.          (tmpSeries.MandatoryValueList.ValueSource<>'') then
  524.              FListSeries.Add(tmpSeries);
  525.     end;
  526.   end;
  527.  
  528.   Procedure TraverseDataSet;
  529.   Var b:TBookMark;
  530.       t:Integer;
  531.   begin
  532.     With ADataSet do
  533.     begin
  534.       DisableControls;
  535.       try
  536.         b:=GetBookMark;
  537.         try
  538.           First;
  539.           While not EOF do
  540.           try
  541.             if Assigned(FOnProcessRecord) then FOnProcessRecord(Self,ADataSet);
  542.             for t:=0 to FListSeries.Count-1 do
  543.                 if FListSeries.Series[t].DataSource=ADataSet then
  544.                    ProcessRecord(FListSeries[t]);
  545.             Next;
  546.           except
  547.             on EAbort do break; { <-- exit while loop !!! }
  548.           end;
  549.         finally
  550.           try
  551.             try
  552.               GotoBookMark(b);
  553.             except
  554.             {$IFNDEF D3}
  555.               on E:EDBEngineError do
  556.               if E.ErrorCount>0 then
  557.               begin
  558.                 if E.Errors[0].ErrorCode<>DBIERR_KEYORRECDELETED then
  559.                    raise;
  560.               end
  561.               else
  562.             {$ENDIF}
  563.                  raise;
  564.             end;
  565.           finally
  566.             FreeBookMark(b);
  567.           end;
  568.         end;
  569.       finally
  570.         EnableControls;
  571.       end;
  572.     end;
  573.   end;
  574.  
  575. Var OldCursor:TCursor;
  576.     t:Integer;
  577. Begin
  578.   if not IUpdating then
  579.   With ADataSet do
  580.   Begin
  581.     if Active then
  582.     Begin
  583.       IUpdating:=True;
  584.       FListSeries:=TChartSeriesList.Create;
  585.       HasAnyDataSet:=False;
  586.       try
  587.         FillTempSeriesList;
  588.         if FListSeries.Count>0 then
  589.         Begin
  590.           OldCursor:=Screen.Cursor;
  591.           if FShowGlassCursor then Screen.Cursor:=crHourGlass;
  592.           try
  593.             for t:=0 to FListSeries.Count-1 do TChartSeries(FListSeries[t]).Clear;
  594.             if HasAnyDataSet then TraverseDataSet
  595.             else
  596.             begin
  597.               if Assigned(FOnProcessRecord) then FOnProcessRecord(Self,ADataSet);
  598.               for t:=0 to FListSeries.Count-1 do
  599.                   if TDataSource(FListSeries.Series[t].DataSource).DataSet=ADataSet then
  600.                      ProcessRecord(FListSeries[t]);
  601.             end;
  602.             for t:=0 to FListSeries.Count-1 do TChartSeries(FListSeries[t]).RefreshSeries;
  603.           finally
  604.             if FShowGlassCursor then Screen.Cursor:=OldCursor;
  605.           end;
  606.         end;
  607.       finally
  608.         FListSeries.Free;
  609.         IUpdating:=False;
  610.       end;
  611.     end;
  612.   end;
  613. end;
  614.  
  615. Procedure TCustomDBChart.RefreshData;
  616. var t:Longint;
  617. Begin
  618.   for t:=0 to IDataSources.Count-1 do
  619.       RefreshDataSet(IDataSources.DataSource[t].DataSet,nil);
  620. End;
  621.  
  622. Procedure TCustomDBChart.FillSeriesSourceItems(ASeries:TChartSeries; Proc:TGetStrProc);
  623. Var t:Integer;
  624.     tmpDataSet:TDataSet;
  625. Begin
  626.   tmpDataSet:=nil;
  627.   With ASeries do
  628.   if DataSource<>nil then
  629.   begin
  630.     if DataSource is TDataSource then tmpDataSet:=TDataSource(DataSource).DataSet
  631.     else
  632.     if DataSource is TDataSet then tmpDataSet:=TDataSet(DataSource);
  633.     with tmpDataSet do
  634.     Begin
  635.       if FieldCount > 0 then
  636.       Begin
  637.         for t:=0 to FieldCount-1 do Proc(Fields[t].FieldName);
  638.       end
  639.       else
  640.       Begin
  641.         FieldDefs.Update;
  642.         for t:=0 to FieldDefs.Count-1 do Proc(FieldDefs[t].Name);
  643.       end;
  644.    end;
  645.   end;
  646. end;
  647.  
  648. Procedure TCustomDBChart.FillValueSourceItems(AValueList:TChartValueList; Proc:TGetStrProc);
  649. Begin
  650.   With AValueList.Owner do
  651.   if (DataSource<>nil) then
  652.   Begin
  653.     if (DataSource is TDataSet) or (DataSource is TDataSource) then
  654.        FillSeriesSourceItems(AValueList.Owner,Proc)
  655.     else
  656.        inherited FillValueSourceItems(AValueList,Proc);
  657.   end;
  658. end;
  659.  
  660. Procedure TCustomDBChart.Assign(Source:TPersistent);
  661. begin
  662.   if Source is TCustomDBChart then
  663.   With TCustomDBChart(Source) do
  664.   begin
  665.     Self.AutoRefresh    :=AutoRefresh;
  666.     Self.RefreshInterval:=RefreshInterval;
  667.     Self.ShowGlassCursor:=ShowGlassCursor;
  668.   end;
  669.   inherited Assign(Source);
  670. end;
  671.  
  672. end.
  673.