⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 teedatatabletool.pas

📁 第三方控件:PaintGrid.pas 网格型仪表控件源文件 Mymeter.pas 圆型仪表控件源文件 Project1是这两个控件的使用范例。 该
💻 PAS
📖 第 1 页 / 共 2 页
字号:
{**********************************************}
{   TeeChart DataTable Tool                    }
{   Copyright (c) 2005 by David Berneda        }
{   All Rights Reserved                        }
{**********************************************}
unit TeeDataTableTool;
{$I TeeDefs.inc}

interface

uses
  Windows, Classes, SysUtils, TeCanvas, TeeProcs, TeEngine, Chart;

type
  TTableLegend=class(TTeeCustomShape)
  private
    FFontColor : Boolean;
    FSymbol    : TLegendSymbol;
    FOtherSide: Boolean;

    function CalcSymbolHeight:Integer;
    procedure SetFontColor(const Value: Boolean);
    procedure SetSymbol(const Value: TLegendSymbol);
    procedure SetOtherSide(const Value: Boolean);
  protected
    Procedure SetParent(Value:TCustomTeePanel); override;
  public
    Constructor Create(AOwner: TCustomTeePanel); overload; override;
    Destructor Destroy; override;

    Procedure Assign(Source:TPersistent); override;
  published
    property Brush;
    property Color;
    property Font;
    property FontSeriesColor:Boolean read FFontColor write SetFontColor default False;
    property Gradient;
    property OtherSide:Boolean read FOtherSide write SetOtherSide default False;
    property Pen;
    property Symbol:TLegendSymbol read FSymbol write SetSymbol;
    property Transparency;
    property Transparent default True;
    property Visible;
  end;

  TDataTableTool=class(TTeeCustomTool)
  private
    FAutoPos     : Boolean;
    FClipText    : Boolean;
    FColumnPen   : TChartPen;
    FFont        : TTeeFont;
    FInverted    : Boolean;
    FLeft        : Integer;
    FLegend      : TTableLegend;
    FTop         : Integer;

    function CalcMaxSeriesCount:Integer;
    function CalcPosLabels(Axis:TChartAxis; Value:Integer):Integer;
    function Chart:TCustomChart;
    procedure Draw;
    function GetRowPen: TChartPen;
    function GuessAxis:TChartAxis;
    function LegendWidth(var SymbolWidth:Integer):Integer;
    procedure SetAutoPos(const Value: Boolean);
    procedure SetClipText(const Value: Boolean);
    procedure SetColumnPen(const Value: TChartPen);
    procedure SetFont(const Value: TTeeFont);
    procedure SetInverted(const Value: Boolean);
    procedure SetLeft(const Value: Integer);
    procedure SetLegend(const Value: TTableLegend);
    procedure SetRowPen(const Value: TChartPen);
    procedure SetTop(const Value: Integer);
    function TableSize:Integer;
    function VisibleSeriesCount:Integer;
  protected
    Procedure ChartEvent(AEvent:TChartToolEvent); override;
    class function GetEditorClass: String; override;
    Procedure SetParentChart(Const Value:TCustomAxisPanel); override;
  public
    Constructor Create(AOwner:TComponent); override;
    Destructor Destroy; override;

    class Function Description:String; override;
  published
    property Active;
    property AutoPosition:Boolean read FAutoPos write SetAutoPos default True;
    property Brush;
    property ClipText:Boolean read FClipText write SetClipText default True;
    property ColumnPen:TChartPen read FColumnPen write SetColumnPen;
    property Font:TTeeFont read FFont write SetFont;
    property Inverted:Boolean read FInverted write SetInverted default False;
    property Left:Integer read FLeft write SetLeft default 0;
    property Legend:TTableLegend read FLegend write SetLegend;
    property RowPen:TChartPen read GetRowPen write SetRowPen;
    property Top:Integer read FTop write SetTop default 0;
  end;

implementation

uses
  Math, TeeProCo;

Constructor TDataTableTool.Create(AOwner: TComponent);
begin
  inherited;
  FAutoPos:=True;
  FClipText:=True;
  FLegend:=TTableLegend.Create(nil);
  FFont:=TTeeFont.Create(CanvasChanged);
  FColumnPen:=TChartPen.Create(CanvasChanged);
end;

Destructor TDataTableTool.Destroy;
begin
  FColumnPen.Free;
  FFont.Free;
  FLegend.Free;
  inherited;
end;

function TDataTableTool.GuessAxis:TChartAxis;
var t : Integer;
begin
  // Guess Axis
  for t:=0 to Chart.SeriesCount-1 do
      with Chart[t] do
      if (not HasZValues) and Visible then
      begin
        if YMandatory then
           result:=GetHorizAxis
        else
           result:=GetVertAxis;

        Exit;
      end;

  result:=nil;
end;

function TDataTableTool.CalcMaxSeriesCount:Integer;
var t : Integer;
begin
  result:=0;

  for t:=0 to Chart.SeriesCount-1 do
      if (not Chart[t].HasZValues) and Chart[t].Visible then
         result:=Math.Max(result,Chart[t].Count);
end;

function TDataTableTool.VisibleSeriesCount:Integer;
var t : Integer;
begin
  result:=0;
  for t:=0 to Chart.SeriesCount-1 do
      if (not Chart[t].HasZValues) and Chart[t].Visible then
         Inc(result);
end;

type
  TSymbolAccess=class(TLegendSymbol);

function TDataTableTool.LegendWidth(var SymbolWidth:Integer):Integer;
var t : Integer;
begin
  result:=0;

  Chart.Canvas.AssignFont(FLegend.Font);

  for t:=0 to Chart.SeriesCount-1 do
      if (not Chart[t].HasZValues) and Chart[t].Visible then
         result:=Math.Max(result,Chart.Canvas.TextWidth(SeriesTitleOrName(Chart[t])));

  Inc(result,Chart.Canvas.FontHeight);

  if Legend.Symbol.Visible then
     SymbolWidth:=TSymbolAccess(Legend.Symbol).CalcWidth(result)
  else
     SymbolWidth:=0;

  Inc(result,SymbolWidth);
end;

type
  TAxis=class(TChartAxis);

procedure TDataTableTool.Draw;
var tmpItemSize,
    MaxSeriesCount : Integer;
    Axis : TChartAxis;
    TableHorizontal : Boolean;
    tmpOffset : Integer;
    tmpPos : Integer;

  function ColRowPos(SeriesIndex:Integer):Integer;
  var tmp,t : Integer;
  begin
    tmp:=0;

    if Inverted then
    begin
      for t:=Chart.SeriesCount-1 downto SeriesIndex+1 do
          if (not Chart[t].HasZValues) and Chart[t].Visible then
             Inc(tmp);
    end
    else
    for t:=0 to SeriesIndex-1 do
        if (not Chart[t].HasZValues) and Chart[t].Visible then
           Inc(tmp);

    tmp:=10+(tmpItemSize*(tmp+1));
    if Axis.OtherSide then
       tmp:=-tmp;

    if TableHorizontal then
       result:=tmpPos+tmp
    else
       result:=tmpPos-tmp;
  end;

  procedure ColDivider(Pos:Integer);
  var tmpMax : Integer;
      tmp    : Integer;
  begin
    if Inverted then
       tmpMax:=ColRowPos(-1)
    else
       tmpMax:=ColRowPos(Chart.SeriesCount);

    if AutoPosition then
       tmp:=tmpPos
    else
    begin
      if Inverted then
         tmp:=ColRowPos(Chart.SeriesCount)
      else
         tmp:=ColRowPos(-1);
    end;

    with TAxis(Axis) do
    if TableHorizontal then
       if OtherSide then
          Chart.Canvas.DoVertLine(tmpOffset+Pos, tmp, tmpMax-1)
       else
          Chart.Canvas.DoVertLine(tmpOffset+Pos, tmp, tmpMax+1)
    else
       Chart.Canvas.DoHorizLine(tmp, tmpMax, tmpOffset+Pos)
  end;

  function SeriesToPos(SeriesIndex:Integer):Integer;
  begin
    if TableHorizontal then
    begin
      if Axis.OtherSide then
         if Inverted then
            result:=SeriesIndex-1
         else
            result:=SeriesIndex+1
      else
         result:=SeriesIndex;
    end
    else
    begin
      if Inverted then
         result:=SeriesIndex-1
      else
         result:=SeriesIndex+1;

      if Axis.OtherSide then
         if Inverted then
            Inc(result)
         else
            Dec(result);
    end;
  end;

  procedure DoText(Pos,TextIndex,SeriesIndex:Integer);
  var s        : String;
      tmp      : Integer;
      tmpValue : TChartValue;
  begin
    with Chart[SeriesIndex] do
    if Visible then
    begin
      tmp:=MaxSeriesCount-TextIndex;

      if (tmp>=0) and (Count>tmp) and (not IsNull(tmp)) then
      begin
        tmpValue:=GetMarkValue(tmp);

        if MandatoryValueList.DateTime then
           DateTimeToString(s,DateTimeDefaultFormat(tmpValue),tmpValue)
        else
           s:=FormatFloat(ValueFormat,tmpValue);

        tmp:=ColRowPos(SeriesToPos(SeriesIndex));

        if TableHorizontal then
           Chart.Canvas.TextOut(tmpOffset+Pos, tmp, s)
        else
           Chart.Canvas.TextOut(tmp+4, tmpOffset+Pos-(Chart.Canvas.FontHeight div 2), s);
      end;
    end;
  end;

  procedure DrawLegend(x0,x1:Integer);
  var w              : Integer;
      tmpSymbolWidth : Integer;

    procedure DrawLegendItem(Index:Integer);
    var s   : String;
        tmp : Integer;
        p   : Integer;
        r   : TRect;
    begin
      if (not Chart[Index].HasZValues) and Chart[Index].Visible then
      begin
        s:=SeriesTitleOrName(Chart[Index]);

        tmp:=ColRowPos(SeriesToPos(Index));

        Chart.Canvas.BackMode:=cbmTransparent;

        p:=x0+4;

        if Legend.Symbol.Visible then
           if Legend.Symbol.Position=spLeft then
              Inc(p,tmpSymbolWidth+4);

        if Legend.FFontColor then
           Chart.Canvas.Font.Color:=Chart[Index].Color;

        if TableHorizontal then
           Chart.Canvas.TextOut(p,tmp,s)
        else
        if Legend.Symbol.Visible and (Legend.Symbol.Position=spRight) then
           Chart.Canvas.RotateLabel(tmp+4,x1+w-4,s,90)
        else
           Chart.Canvas.RotateLabel(tmp+4,x1+w-4-tmpSymbolWidth-4,s,90);

        if Legend.Symbol.Visible then
        begin
          if TableHorizontal then
             if Legend.Symbol.Position=spLeft then
                r:=TeeRect(x0+4,tmp+4,x0+4+tmpSymbolWidth,tmp+12)
             else
                r:=TeeRect(x0+w-4-tmpSymbolWidth,tmp+4,x0+w-4,tmp+12)
          else
          if Legend.Symbol.Position=spLeft then
             r:=TeeRect(tmp+6,x1+w-4,tmp+6+12,x1+w-4-tmpSymbolWidth)
          else
             r:=TeeRect(tmp+6,x1+4,tmp+6+tmpSymbolWidth,x1+4+tmpSymbolWidth);

         if Legend.Symbol.Gradient.Visible then
            TSymbolAccess(Legend.Symbol).Draw(Chart[Index].Color,r)
         else
            Chart[Index].DrawLegend(-1,r);
        end;
      end;
    end;

  var t : Integer;
      tmp : Integer;
  begin
    Chart.Canvas.AssignFont(FLegend.Font);
    Chart.Canvas.TextAlign:=TA_LEFT;

    w:=LegendWidth(tmpSymbolWidth);

    if TableHorizontal then
    begin
      if Legend.OtherSide then tmp:=x1
                          else tmp:=x0;

      Chart.Canvas.DoVertLine(tmp,ColRowPos(-1),ColRowPos(Chart.SeriesCount));
    end
    else
    begin
      tmp:=x1;
      if Legend.OtherSide then Inc(tmp,w);

      Chart.Canvas.DoHorizLine(ColRowPos(-1),ColRowPos(Chart.SeriesCount),tmp);
    end;

    if Inverted then
       for t:=Chart.SeriesCount-1 downto 0 do
           DrawLegendItem(t)
    else
       for t:=0 to Chart.SeriesCount-1 do
           DrawLegendItem(t);
  end;

  procedure CalcPositions;
  begin
    if AutoPosition then
    begin
      tmpPos:=Axis.PosAxis;
      tmpOffset:=0;

      if TableHorizontal then
      begin
        if Axis.OtherSide and Chart.View3D then
        begin
          tmpPos:=tmpPos-Chart.SeriesWidth3D;
          tmpOffset:=Chart.SeriesWidth3D;
        end;

        Top:=tmpPos;
        Left:=0;
      end
      else
      begin
        if Axis.OtherSide and Chart.View3D then
        begin

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -