teetools.pas

来自「Delphi TeeChartPro.6.01的源代码」· PAS 代码 · 共 2,188 行 · 第 1/5 页

PAS
2,188
字号
begin
  result:=TeeMsg_DrawLineTool
end;

type TCustomTeePanelAccess=class(TCustomTeePanel);

procedure TDrawLineTool.RedrawLine(ALine:TDrawLine);
var tmp : TColor;
begin
  // draw current selected or dragged line with "not xor" pen mode
  With ParentChart.Canvas do
  begin
    tmp:=ColorToRGB(TCustomTeePanelAccess(ParentChart).GetBackColor);
    AssignVisiblePenColor(Self.Pen,(clWhite-tmp) xor Self.Pen.Color);
    Pen.Mode:=pmNotXor;
    if Assigned(ALine) then
       DrawLine(FromPoint,ToPoint,ALine.Style)
    else
       DrawLine(FromPoint,ToPoint,dlLine);
    Pen.Mode:=pmCopy;
  end;
end;

class function TDrawLineTool.GetEditorClass: String;
begin
  result:='TDrawLineEdit';
end;

function TDrawLineTool.AxisPoint(const P: TFloatPoint): TPoint;
begin
  // convert from axis double XY to screen pixels XY
  result.X:=GetHorizAxis.CalcPosValue(P.X);
  result.Y:=GetVertAxis.CalcPosValue(P.Y);
end;

function TDrawLineTool.ScreenPoint(P: TPoint): TFloatPoint;
begin
  // convert from screen pixels XY position to axis double XY
  result.X:=GetHorizAxis.CalcPosPoint(P.X);
  result.Y:=GetVertAxis.CalcPosPoint(P.Y);
end;

procedure TDrawLineTool.SetEnableSelect(Value: Boolean);
begin
  if FEnableSelect<>Value then
  begin
    FEnableSelect:=Value;
    if not FEnableSelect then
    begin
      if Assigned(ISelected) then
      begin
        ISelected:=nil;
        Repaint;
      end;
    end;
  end;
end;

procedure TDrawLineTool.DeleteSelected;
begin
  if Assigned(ISelected) then
  begin
    IDrawing:=False; // 5.02
    IHandle:=chNone; // 5.02
    FreeAndNil(ISelected);
    Repaint;
  end;
end;

procedure TDrawLineTool.SetSelected(Value: TDrawLine);
begin
  ISelected:=Value;
  Repaint;
end;

procedure TDrawLineTool.SetLines(const Value: TDrawLines);
begin
  FLines.Assign(Value);
end;

{ TNearestTool }
Constructor TNearestTool.Create(AOwner: TComponent);
begin
  inherited;
  Point:=-1;
  FullRepaint:=True;
  Brush.Style:=bsClear;
  Pen.Style:=psDot;
  Pen.Color:=clWhite;
  FSize:=20;
  FDrawLine:=True;
  FStyle:=hsCircle;
end;

procedure TNearestTool.PaintHint;
var x : Integer;
    y : Integer;
    R : TRect;
    P : TFourPoints;
begin
  if Assigned(Series) and (Point<>-1) and (Series.Count>Point) then  // 6.01
  With ParentChart.Canvas do
  begin
    AssignVisiblePen(Self.Pen);
    if not FullRepaint then Pen.Mode:=pmNotXor;

    x:=Series.CalcXPos(Point);
    y:=Series.CalcYPos(Point);

    if Self.Style<>hsNone then
    begin
      AssignBrush(Self.Brush,clBlack);
      Case Self.Style of
        hsCircle: if ParentChart.View3D then
                     EllipseWithZ(x-FSize,y-FSize,x+FSize,y+FSize,Series.StartZ)
                  else
                     Ellipse(x-FSize,y-FSize,x+FSize,y+FSize);
     hsRectangle: begin
                    R:=TeeRect(x-FSize,y-FSize,x+FSize,y+FSize);
                    if ParentChart.View3D then RectangleWithZ(R,Series.StartZ)
                                          else Rectangle(R);
                  end;
       hsDiamond: begin
                    P[0]:=TeePoint(x,y-FSize);
                    P[1]:=TeePoint(x+FSize,y);
                    P[2]:=TeePoint(x,y+FSize);
                    P[3]:=TeePoint(x-FSize,y);
                    PolygonWithZ(P,Series.StartZ);
                  end;
      end;
    end;

    if FDrawLine then
    begin
      Pen.Style:=psSolid;
      MoveTo(IMouse.X,IMouse.Y);
      LineTo(x,y);
    end;
    if not FullRepaint then Pen.Mode:=pmCopy;
  end;
end;

procedure TNearestTool.ChartMouseEvent(AEvent: TChartMouseEvent;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);

  Function GetNearestPoint:Integer;
  var t      : Integer;
      Dif    : Integer;
      Dist   : Integer;
      tmpMin : Integer;
      tmpMax : Integer;
      tmpX   : Integer;
      tmpY   : Integer;
  begin
    result:=-1;
    Dif:=10000;

    if TeeGetFirstLastSeries(Series,tmpMin,tmpMax) then
    for t:=tmpMin to tmpMax do { <-- traverse all points in a Series... }
    begin
      { calculate position in pixels }
      tmpX:=Series.CalcXPos(t);
      tmpY:=Series.CalcYPos(t);

      if PointInRect(ParentChart.ChartRect,tmpX,tmpY) then { 5.01 }
      begin
        { calculate distance in pixels... }
        Dist:=Round(TeeDistance(X-tmpX,Y-tmpY));

        if Dist<Dif then { store if distance is lower... }
        begin
          Dif:=Dist;
          result:=t;  { <-- set this point to be the nearest... }
        end;
      end;
    end;
  end;

begin
  inherited;
  if (AEvent=cmeMove) and Assigned(Series) then
  begin
    if not FullRepaint then PaintHint;
    Point:=GetNearestPoint;
    IMouse:=TeePoint(x,y);
    if not FullRepaint then PaintHint;
    if Assigned(FOnChange) then FOnChange(Self);
    if FullRepaint then Repaint;
  end;
end;

procedure TNearestTool.ChartEvent(AEvent: TChartToolEvent);
begin
  inherited;
  if AEvent=cteAfterDraw then PaintHint;
end;

class Function TNearestTool.Description:String;
begin
  result:=TeeMsg_NearestTool
end;

procedure TNearestTool.SetSize(const Value: Integer);
begin
  SetIntegerProperty(FSize,Value);
end;

class function TNearestTool.GetEditorClass: String;
begin
  result:='TNearestToolEdit';
end;

procedure TNearestTool.SetStyle(const Value: TNearestToolStyle);
begin
  if FStyle<>Value then
  begin
    FStyle:=Value;
    Repaint;
  end;
end;

{ TColorBandTool }
Constructor TColorBandTool.Create(AOwner: TComponent);
begin
  inherited;
  FGradient:=TChartGradient.Create(CanvasChanged);
  FColor:=clWhite;
  FDrawBehind:=True;
end;

destructor TColorBandTool.Destroy;
begin
  FGradient.Free;
  inherited;
end;

procedure TColorBandTool.PaintBand;
var R    : TRect;
    tmpR : TRect;
    tmp0 : Double;
    tmp1 : Double;
    tmpDraw : Boolean;
    tmpRectBlend : TRect;
    tmpZ         : Integer;
    tmpBlend     : TTeeBlend;
begin
  if Assigned(Axis) then
  begin
    R:=ParentChart.ChartRect;
    tmp0:=FStart;
    tmp1:=FEnd;

    With Axis do
    begin
      if Inverted then
      begin
        if tmp0<tmp1 then SwapDouble(tmp0,tmp1);
        tmpDraw:=(tmp1<=Maximum) and (tmp0>=Minimum);
      end
      else
      begin
        if tmp0>tmp1 then SwapDouble(tmp0,tmp1);
        tmpDraw:=(tmp0<=Maximum) and (tmp1>=Minimum);
      end;

      if tmpDraw then
      begin
        if DrawBehind then tmpZ:=ParentChart.Width3D else tmpZ:=0; // 5.03

        if Horizontal then
        begin
          R.Left:=Math.Max(IStartPos,CalcPosValue(tmp0));
          R.Right:=Math.Min(IEndPos,CalcPosValue(tmp1));
          if not Self.Pen.Visible then Inc(R.Right);
        end
        else
        begin
          R.Top:=Math.Max(IStartPos,CalcPosValue(tmp1));
          R.Bottom:=Math.Min(IEndPos,CalcPosValue(tmp0));
          Inc(R.Left);
          if not Self.Pen.Visible then
          begin
            Inc(R.Bottom);
            Inc(R.Right);
          end;
        end;
        With ParentChart,Canvas do
        begin
          AssignBrush(Self.Brush,Self.Color);
          AssignVisiblePen(Self.Pen);

          if Self.Gradient.Visible and View3DOptions.Orthogonal then
          begin
            tmpR:=R;
            Dec(tmpR.Right);
            Dec(tmpR.Bottom);
            Self.Gradient.Draw(Canvas,CalcRect3D(tmpR,tmpZ));
            Brush.Style:=bsClear;
          end;

          if Transparency=0 then
          begin
            if View3D then RectangleWithZ(R,tmpZ)
                      else Rectangle(R);
          end
          else
          begin
            if View3D then tmpRectBlend:=RectFromRectZ(R,tmpZ)
                      else tmpRectBlend:=R;

            tmpBlend:=ParentChart.Canvas.BeginBlending(tmpRectBlend,Transparency);
            if View3D then RectangleWithZ(R,tmpZ)
                      else Rectangle(R);
            ParentChart.Canvas.EndBlending(tmpBlend);
          end;
        end;
      end;
    end;
  end;
end;

procedure TColorBandTool.ChartEvent(AEvent: TChartToolEvent);
begin
  inherited;
  if ((AEvent=cteBeforeDrawSeries) and DrawBehind) or
     ((AEvent=cteAfterDraw) and (not DrawBehind)) then PaintBand;
end;

class function TColorBandTool.Description: String;
begin
  result:=TeeMsg_ColorBandTool
end;

class function TColorBandTool.GetEditorClass: String;
begin
  result:='TColorBandToolEditor';
end;

procedure TColorBandTool.SetEnd(const Value: Double);
begin
  SetDoubleProperty(FEnd,Value);
end;

procedure TColorBandTool.SetStart(const Value: Double);
begin
  SetDoubleProperty(FStart,Value);
end;

procedure TColorBandTool.SetGradient(const Value: TChartGradient);
begin
  FGradient.Assign(Value);
end;

procedure TColorBandTool.SetColor(Value: TColor);
begin
  SetColorProperty(FColor,Value);
end;

procedure TColorBandTool.SetTransparency(const Value: TTeeTransparency);
begin
  if FTransparency<>Value then
  begin
    FTransparency:=Value;
    Repaint;
  end;
end;

procedure TColorBandTool.SetDrawBehind(const Value: Boolean);
begin
  SetBooleanProperty(FDrawBehind,Value);
end;

{ TColorLineTool }
constructor TColorLineTool.Create(AOwner: TComponent);
begin
  inherited;
  FAllowDrag:=True;
  FDraw3D:=True;
end;

Function TColorLineTool.CalcValue:Double;
begin
  Case Self.FStyle of
    clMaximum: result:=Axis.Maximum;
    clCenter: result:=(Axis.Maximum+Axis.Minimum)*0.5;
    clMinimum: result:=Axis.Minimum;
  else
    result:=FValue;  // clCustom
  end;
end;

Function TColorLineTool.LimitValue(const AValue:Double):Double;
var tmpLimit : Double;
begin
  result:=AValue;

  { do not use Axis Minimum & Maximum, we need the
    "real" min and max }
  if Axis.Horizontal then
  begin
    tmpLimit:=Axis.CalcPosPoint(Axis.IStartPos);
    if result<tmpLimit then result:=tmpLimit
    else
    begin
      tmpLimit:=Axis.CalcPosPoint(Axis.IEndPos);
      if result>tmpLimit then result:=tmpLimit;
    end;
  end
  else
  begin
    tmpLimit:=Axis.CalcPosPoint(Axis.IEndPos);
    if result<tmpLimit then result:=tmpLimit
    else
    begin
      tmpLimit:=Axis.CalcPosPoint(Axis.IStartPos);
      if result>tmpLimit then result:=tmpLimit;
    end;
  end;
end;

Procedure TColorLineTool.DrawColorLine(Back:Boolean);
var tmp : Integer;
begin
  { check inside axis limits }
  if not NoLimitDrag then
     FValue:=LimitValue(FValue);

  tmp:=Axis.CalcPosValue(CalcValue);

  With ParentChart,Canvas do
  begin
    if Back then
    begin
      if Axis.Horizontal then
      begin
        if Draw3D then ZLine3D(tmp,ChartRect.Botto

⌨️ 快捷键说明

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