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

📄 teemapseries.pas

📁 BCB第三方组件
💻 PAS
📖 第 1 页 / 共 3 页
字号:
{******************************************}
{    TeeChart Map Series                   }
{ Copyright (c) 2000-2007 by David Berneda }
{    All Rights Reserved                   }
{******************************************}
unit TeeMapSeries;
{$I TeeDefs.inc}

interface

Uses {$IFNDEF LINUX}
     Windows, Messages,
     {$ENDIF}
     SysUtils, Classes,
     {$IFDEF CLX}
     QGraphics, Types,
     {$ELSE}
     Graphics,
      {$IFDEF D6}
      Types,
      {$ENDIF}
     {$ENDIF}
     TeEngine, TeCanvas, TeeProcs, TeeSurfa;

type
  TTeePolygon=class;

  TPolygonSeries=class(TChartSeries)
  protected
    Procedure DrawLegendShape(ValueIndex:Integer; Const Rect:TRect); override;
    Procedure NotifyValue(ValueEvent:TValueEvent; ValueIndex:Integer); override;
    procedure PrepareLegendCanvas(ValueIndex:Integer; Var BackColor:TColor;
                                Var BrushStyle:TBrushStyle); override;
    Procedure SetActive(Value:Boolean); override;
    Procedure SetSeriesColor(AColor:TColor); override;
  public
    Procedure FillSampleValues(NumValues:Integer); override;
    Function Polygon:TTeePolygon; {$IFDEF D9}inline;{$ENDIF}
  end;

  TMapSeries=class;

  TTeePolygon=class(TCollectionItem)
  private
    FClosed      : Boolean;
    FGradient    : TChartGradient;
    FParentBrush : Boolean;
    FParentPen   : Boolean;
    FPoints      : TPolygonSeries;
    FTransparency: TTeeTransparency;

    {$IFDEF CLR}
    procedure CanvasChanged(Sender: TObject);
    {$ENDIF}

    function GetBrush: TChartBrush;
    function GetColor: TColor;
    function GetGradient: TChartGradient;
    function GetPen: TChartPen;
    Function GetText:String;
    function GetTransparent: Boolean;
    function GetZ: Double;

    function PointRect:TRect;
    procedure SetBrush(const Value: TChartBrush);
    procedure SetClosed(const Value: Boolean);
    procedure SetColor(const Value: TColor);
    procedure SetGradient(const Value: TChartGradient);
    procedure SetParentBrush(const Value: Boolean);
    procedure SetParentPen(const Value: Boolean);
    procedure SetPen(const Value: TChartPen);
    Procedure SetText(Const Value:String);
    procedure SetTransparency(const Value: TTeeTransparency);
    procedure SetTransparent(const Value: Boolean);
    procedure SetZ(const Value: Double);
  protected
    IPoints      : TPointArray;

    procedure DefineProperties(Filer: TFiler); override;
    procedure DoDraw(ACanvas:TCanvas3D; Index:Integer; AColor:TColor;
                     ATransp:TTeeTransparency; DrawGradient:Boolean);
  public
    ParentSeries : TMapSeries;

    Constructor Create(Collection:TCollection); override;
    Destructor Destroy; override;

    Function AddXY(Const Point:TFloatPoint):Integer; overload;
    Function AddXY(Const X,Y:Double):Integer; overload;
    Procedure Draw(ACanvas:TCanvas3D; ValueIndex:Integer);
    Function GetPoints:TPointArray;
    Function Visible:Boolean;

    Function Bounds:TRect;
    property Points:TPolygonSeries read FPoints;
  published
    property Brush:TChartBrush read GetBrush write SetBrush;
    property Closed:Boolean read FClosed write SetClosed default True;
    property Color:TColor read GetColor write SetColor default clWhite;
    property Gradient:TChartGradient read GetGradient write SetGradient;
    property ParentBrush:Boolean read FParentBrush write SetParentBrush default True;
    property ParentPen:Boolean read FParentPen write SetParentPen default True;
    property Pen:TChartPen read GetPen write SetPen;
    property Text:String read GetText write SetText;
    property Transparency:TTeeTransparency read FTransparency write SetTransparency default 0;
    property Transparent:Boolean read GetTransparent write SetTransparent default False;
    property Z:Double read GetZ write SetZ;
  end;

  TTeePolygonList=class(TOwnedCollection)
  private
    Procedure Delete(Start,Quantity:Integer); overload;
    Function Get(Index:Integer):TTeePolygon; {$IFDEF D10}inline;{$ENDIF} // 7.05
    function GetByName(const AName: String): TTeePolygon;
    Procedure Put(Index:Integer; Const Value:TTeePolygon);
  public
    Function Add:TTeePolygon;
    Function Owner:TMapSeries; {$IFDEF D10}inline;{$ENDIF}
    property Polygon[Index:Integer]:TTeePolygon read Get write Put; default;
    property ByName[const AName:String]:TTeePolygon read GetByName;  // 7.0
  end;

  TMapSeries=class(TCustom3DPaletteSeries)
  private
    FPointSize    : Integer;
    FShadow       : TTeeShadow;
    FShapes       : TTeePolygonList;
    FTransparency : TTeeTransparency;
    FTransparent  : Boolean;

    I3DList : Array of TTeePolygon;

    Function CompareOrder(a,b:Integer):Integer;
    Function GetPolygon(Index:Integer):TTeePolygon; {$IFDEF D10}inline;{$ENDIF} // 7.05
    procedure SetPointSize(const Value: Integer);
    procedure SetShadow(const Value: TTeeShadow);
    procedure SetShapes(const Value: TTeePolygonList);
    procedure SetTransparency(const Value:TTeeTransparency);
    procedure SetTransparent(const Value:Boolean);
    Procedure SwapPolygon(a,b:Integer);
  protected
    CanSaveData : Boolean;

    Procedure AddSampleValues(NumValues:Integer; OnlyMandatory:Boolean=False); override;
    Procedure CalcHorizMargins(Var LeftMargin,RightMargin:Integer); override;
    procedure CalcSelectionPos(ValueIndex:Integer; out X,Y:Integer); override;
    Procedure CalcVerticalMargins(Var TopMargin,BottomMargin:Integer); override;
    class procedure CreateSubGallery(AddSubChart: TChartSubGalleryProc); override;
    procedure DefineProperties(Filer: TFiler); override;
    Procedure DrawAllValues; override;
    Procedure DrawMark( ValueIndex:Integer; Const St:String;
                        APosition:TSeriesMarkPosition); override;
    Procedure DrawValue(ValueIndex:Integer); override;
    Procedure GalleryChanged3D(Is3D:Boolean); override;
    class Function GetEditorClass:String; override;
    procedure PrepareForGallery(IsEnabled:Boolean); override;
    class procedure SetSubGallery(ASeries: TChartSeries; Index: Integer); override;
  public
    Constructor Create(AOwner:TComponent); override;
    Destructor Destroy; override;

    procedure Assign(Source:TPersistent); override;
    Procedure Clear; override;
    Function Clicked(x,y:Integer):Integer; override;
    Procedure Delete(ValueIndex:Integer); overload; override;
    Procedure Delete(Start,Quantity:Integer; RemoveGap:Boolean=False); overload; override;
    Function MaxXValue:Double; override;
    Function MaxYValue:Double; override;
    Function MinXValue:Double; override;
    Function MinYValue:Double; override;
    Function NumSampleValues:Integer; override;
    procedure SwapValueIndex(a,b:Integer); override;

    property Polygon[Index:Integer]:TTeePolygon read GetPolygon; default; // 7.0
  published
    { Published declarations }
    property Active;
    property ColorSource;
    property Cursor;
    property HorizAxis;
    property Marks;
    property ParentChart;
    property DataSource;
    property PercentFormat;
    property SeriesColor;
    property ShowInLegend;
    property Title;
    property ValueFormat;
    property VertAxis;
    property XLabelsSource;

    property Brush;
    property EndColor;
    property MidColor;
    property LegendEvery;
    property Pen;
    property PaletteMin;
    property PaletteStep;
    property PaletteSteps;
    property PointSize:Integer read FPointSize write SetPointSize default 1;
    property Shadow:TTeeShadow read FShadow write SetShadow;
    property Shapes:TTeePolygonList read FShapes write SetShapes;
    property StartColor;
    property Transparent:Boolean read FTransparent write SetTransparent default False;
    property Transparency:TTeeTransparency read FTransparency write SetTransparency default 0;
    property UseColorRange;
    property UsePalette;
    property UsePaletteMin;
    property TimesZOrder;
    property XValues;
    property YValues;
    property ZValues;

    { events }
    property AfterDrawValues;
    property BeforeDrawValues;
    property OnAfterAdd;
    property OnBeforeAdd;
    property OnClearValues;
    property OnClick;
    property OnDblClick;
    property OnGetColor;
    property OnGetMarkText;
    property OnMouseEnter;
    property OnMouseLeave;
  end;

function PolygonArea(const P:TPointArray): Double;
function PolygonCentroid(const P:TPointArray):TPointFloat;

implementation

Uses Math,
     {$IFDEF CLR}
     Variants,
     {$ENDIF}
     TeeConst, TeeProCo, Chart;

{$IFNDEF CLR}
type
  TSeriesAccess=class(TCustomChartElement);
{$ENDIF}

{ TTeePolygon }
constructor TTeePolygon.Create(Collection: TCollection);
begin
  inherited;
  ParentSeries:=TTeePolygonList(Collection).Owner as TMapSeries;

  FClosed:=True;
  FPoints:=TPolygonSeries.Create(nil);  // 7.0
  FPoints.Tag:={$IFDEF CLR}Variant{$ELSE}Integer{$ENDIF}(Self);
  FPoints.XValues.Order:=loNone;
  FPoints.ShowInLegend:=False;

  FParentPen:=True;
  FParentBrush:=True;

  FTransparency:=ParentSeries.Transparency;

  while ParentSeries.Count<ParentSeries.Shapes.Count do // 8.0
        ParentSeries.AddXY(0,0);
end;

Destructor TTeePolygon.Destroy;
begin
  IPoints:=nil;
  FPoints.Tag:=0;
  FPoints.Free;
  FGradient.Free;

  inherited;
end;

function TTeePolygon.AddXY(const Point:TFloatPoint): Integer;
begin
  result:=FPoints.AddXY(Point.X,Point.Y);
end;

function TTeePolygon.AddXY(const X,Y: Double): Integer;
begin
  result:=FPoints.AddXY(X,Y);
end;

{ return the array of Points in screen (pixel) coordinates }
Function TTeePolygon.GetPoints:TPointArray;
var t : Integer;
    tmpHoriz : TChartAxis;
    tmpVert  : TChartAxis;
    tmpX     : TChartValues;
    tmpY     : TChartValues;
    tmpCount : Integer;
begin
  tmpCount:=FPoints.Count;
  SetLength(IPoints,tmpCount);
  result:=TPointArray(IPoints);

  tmpHoriz:=ParentSeries.GetHorizAxis;
  tmpVert:=ParentSeries.GetVertAxis;

  tmpX:=FPoints.XValues.Value;
  tmpY:=FPoints.YValues.Value;

  for t:=0 to tmpCount-1 do
  begin
    result[t].X:=tmpHoriz.CalcPosValue(tmpX[t]);
    result[t].Y:=tmpVert.CalcPosValue(tmpY[t]);
  end;
end;

// Returns True if the polygon contains points that lie inside
// the chart "ChartRect" (the visible chart area).
Function TTeePolygon.Visible:Boolean;

  // optimized version of InteresectRect
  function ContainsRect(R1:TRect; const R2:TRect): Boolean;
  begin
    if R2.Left > R1.Left then R1.Left := R2.Left;
    if R2.Right < R1.Right then R1.Right := R2.Right;

    if R2.Top > R1.Top then R1.Top := R2.Top;
    if R2.Bottom < R1.Bottom then R1.Bottom := R2.Bottom;
    result := not ((R1.Right < R1.Left) or (R1.Bottom < R1.Top));
  end;

var tmpR : TRect;
    tmpChart : TCustomAxisPanel;
begin
  tmpChart:=ParentSeries.ParentChart;
  result:=not tmpChart.ClipPoints;

  if not result then
  begin
    with ParentSeries.GetHorizAxis do
    begin
      tmpR.Left:=CalcPosValue(FPoints.XValues.MinValue);
      tmpR.Right:=CalcPosValue(FPoints.XValues.MaxValue);

      if Inverted then
         SwapInteger(tmpR.Left,tmpR.Right);  // 7.01
    end;

    with ParentSeries.GetVertAxis do
    begin
      tmpR.Top:=CalcPosValue(FPoints.YValues.MaxValue);
      tmpR.Bottom:=CalcPosValue(FPoints.YValues.MinValue);

      if Inverted then
         SwapInteger(tmpR.Top,tmpR.Bottom);  // 7.01
    end;

    result:=ContainsRect(tmpChart.ChartRect, tmpR);
  end;
end;

function TTeePolygon.PointRect:TRect;
var tmpA : Integer;
    tmpB : Integer;
begin
  tmpA:=((ParentSeries.PointSize+1) div 2)-1;
  if (ParentSeries.PointSize+1) mod 2 = 0 then
     tmpB:=tmpA+1
  else
     tmpB:=tmpA+2;

  with result do
  begin
    Left:=IPoints[0].X-tmpA;
    Top:=IPoints[0].Y-tmpA;
    Right:=IPoints[0].X+tmpB;
    Bottom:=IPoints[0].Y+tmpB;
  end;
end;

procedure TTeePolygon.DoDraw(ACanvas:TCanvas3D; Index:Integer; AColor:TColor;
                             ATransp:TTeeTransparency; DrawGradient:Boolean);
var tmpIs3D  : Boolean;
    tmpBlend : TTeeBlend;
    tmpZ     : Integer;
    tmpP     : TPointArray;
    tmpR     : TRect;
begin
  tmpP:=nil;

  tmpIs3D:=ParentSeries.ParentChart.View3D;

  // Calculate "Z" depth position
  if tmpIs3D then tmpZ:=ParentSeries.CalcZPos(Index)
             else tmpZ:=0;

  if ATransp>0 then
  begin
    if tmpIs3D then
    begin
      tmpP:=ACanvas.Calc3DPoints(IPoints,tmpZ);
      try
        tmpR:=PolygonBounds(tmpP);
      finally
        tmpP:=nil;
      end;
    end
    else
       tmpR:=PolygonBounds(IPoints);

    tmpBlend:=ACanvas.BeginBlending(tmpR {ACanvas.RectFromRectZ(tmpR,tmpZ)},ATransp)
  end
  else
     tmpBlend:=nil;

  // Fill background with gradient...
  if DrawGradient and Assigned(FGradient) and FGradient.Visible
     and ParentSeries.ParentChart.CanClip then
  begin
    Gradient.Draw(ACanvas,IPoints,tmpZ,tmpIs3D);
    ACanvas.Brush.Style:=bsClear;
  end;

  // Draw the shape...

  with ACanvas do
  begin
    // Special case for shapes with just a single point
    if FPoints.Count=1 then
       if ParentSeries.PointSize>1 then
       begin
         if ParentSeries.PointSize<3 then
            Pen.Style:=psClear;

         if tmpIs3D then
            Rectangle(PointRect,tmpZ)
         else
            Rectangle(PointRect);
       end
       else
          if tmpIs3D then
             Pixels3D[IPoints[0].X,IPoints[0].Y,tmpZ]:=AColor
          else
             Pixels[IPoints[0].X,IPoints[0].Y]:=AColor

    else
    // Normal polygon shapes...
    if tmpIs3D then
    begin
      if Self.Closed then
         PolygonWithZ(IPoints,tmpZ)
      else

⌨️ 快捷键说明

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