home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 September / Chip_2002-09_cd1.bin / zkuste / delphi / kompon / d6 / YPPARSER.ZIP / Components / GraphBldr.pas < prev    next >
Pascal/Delphi Source File  |  2002-06-14  |  21KB  |  677 lines

  1. {********************************************************}
  2. {                                                        }
  3. {                    TGraphBldr                          }
  4. {             IMPORTANT-READ CAREFULLY:                  }
  5. {                                                        }
  6. {    This End-User License Agreement is a legal          }
  7. {    agreement between you (either an individual         }
  8. {    or a single entity) and Pisarev Yuriy for           }
  9. {    the software product identified above, which        }
  10. {    includes computer software and may include          }
  11. {    associated media, printed materials, and "online"   }
  12. {    or electronic documentation ("SOFTWARE PRODUCT").   }
  13. {    By installing, copying, or otherwise using the      }
  14. {    SOFTWARE PRODUCT, you agree to be bound by the      }
  15. {    terms of this LICENSE AGREEMENT.                    }
  16. {                                                        }
  17. {    If you do not agree to the terms of this            }
  18. {    LICENSE AGREEMENT, do not install or use            }
  19. {    the SOFTWARE PRODUCT.                               }
  20. {                                                        }
  21. {    License conditions                                  }
  22. {                                                        }
  23. {    No part of the software or the manual may be        }
  24. {    multiplied, disseminated or processed in any        }
  25. {    way without the written consent of Pisarev          }
  26. {    Yuriy. Violations of these conditions will be       }
  27. {    prosecuted in every case.                           }
  28. {                                                        }
  29. {    The use of the software is done at your own         }
  30. {    risk. The manufacturer and developer accepts        }
  31. {    no liability for any damages, either as direct      }
  32. {    or indirect consequence of the use of this          }
  33. {    product or software.                                }
  34. {                                                        }
  35. {    Only observance of these conditions allows you      }
  36. {    to use the hardware and software in your computer   }
  37. {    system.                                             }
  38. {                                                        }
  39. {    All rights reserved.                                }
  40. {    Copyright 2002 Pisarev Yuriy                        }
  41. {                                                        }
  42. {                 yuriy_mbox@hotmail.com                 }
  43. {                                                        }
  44. {********************************************************}
  45.  
  46. unit GraphBldr;
  47.  
  48. interface
  49.  
  50. uses
  51.   Windows, Messages, SysUtils, Classes, Controls, ExtCtrls, Graphics, Math,
  52.   DataEditor;
  53.  
  54. type
  55.   TPoints = array of array of TPoint;
  56.   TCoord = record
  57.     X, Y: Double;
  58.   end;
  59.   TTraceEvent = procedure(Sender: TObject; X, Y: Double) of object;
  60.   TGraphBldr = class(TCustomControl)
  61.   private
  62.     FTracing: Boolean;
  63.     FShowAxis: Boolean;
  64.     FShowText: Boolean;
  65.     FShowGrid: Boolean;
  66.     FVertSpacing: Double;
  67.     FHorzSpacing: Double;
  68.     FCurrXValue: Double;
  69.     FMargin: Integer;
  70.     FXValueID: Integer;
  71.     FBorderSize: Integer;
  72.     FYMaxValue: Integer;
  73.     FXMaxValue: Integer;
  74.     FDetailLevel: Integer;
  75.     FPicture: TBitmap;
  76.     FSavedBrush: TBrush;
  77.     FDataEditor: TDataEditor;
  78.     FAxisFont: TFont;
  79.     FTextFont: TFont;
  80.     FGridPen: TPen;
  81.     FSaved: TPen;
  82.     FTracePen: TPen;
  83.     FGraphPen: TPen;
  84.     FAxisPen: TPen;
  85.     FPoints: TPoints;
  86.     FTracePoints: TPoints;
  87.     FOnTrace: TTraceEvent;
  88.     procedure DeletePoints(var Points: TPoints);
  89.     function NumFunction(FunctionID: Integer; TypeID: Integer;
  90.       var Value1: Double; Value2, Value3: Double): Boolean;
  91.     procedure WMMouseMove(var Message: TWMMouseMove); message WM_MOUSEMOVE;
  92.     procedure WMSize(var Message: TWMSize); message WM_SIZE;
  93.     function GetBevelWidth: TBevelWidth;
  94.     function GetBorderWidth: TBorderWidth;
  95.     function GetText: string;
  96.     procedure SetAxisFont(const Value: TFont);
  97.     procedure SetBevelWidth(const Value: TBevelWidth);
  98.     procedure SetBorderWidth(const Value: TBorderWidth);
  99.     procedure SetFont(const Value: TFont);
  100.     procedure SetMargin(const Value: Integer);
  101.     procedure SetText(const Value: string);
  102.   protected
  103.     procedure FilterPoints(var Points: TPoints; X, Y: Integer);
  104.     procedure Paint; override;
  105.     property CurrXValue: Double read FCurrXValue write FCurrXValue;
  106.     property Points: TPoints read FPoints write FPoints;
  107.     property SavedBrush: TBrush read FSavedBrush write FSavedBrush;
  108.     property Saved: TPen read FSaved write FSaved;
  109.     property TracePoints: TPoints read FTracePoints write FTracePoints;
  110.     property XValueID: Integer read FXValueID write FXValueID;
  111.   public
  112.     constructor Create (AOwner: TComponent); override;
  113.     destructor Destroy; override;
  114.     procedure Draw; virtual;
  115.     procedure Calculate; virtual;
  116.     procedure Clear; virtual;
  117.     function XCoord(X: Double): Double;
  118.     function YCoord(Y: Double): Double;
  119.     function Coordinates(X, Y: Double): TCoord;
  120.     property BorderSize: Integer read FBorderSize;
  121.     property Picture: TBitmap read FPicture write FPicture;
  122.     property DataEditor: TDataEditor read FDataEditor write FDataEditor;
  123.     property DockManager;
  124.   published
  125.     property Align;
  126.     property Anchors;
  127.     property AutoSize;
  128.     property AxisFont: TFont read FAxisFont write SetAxisFont;
  129.     property AxisPen: TPen read FAxisPen write FAxisPen;
  130.     property BevelInner default bvLowered;
  131.     property BevelOuter default bvRaised;
  132.     property BevelWidth: TBevelWidth read GetBevelWidth write SetBevelWidth;
  133.     property BiDiMode;
  134.     property BorderWidth: TBorderWidth read GetBorderWidth
  135.       write SetBorderWidth default 5;
  136.     property Color;
  137.     property Constraints;
  138.     property Ctl3D;
  139.     property Cursor default crCross;
  140.     property UseDockManager;
  141.     property DetailLevel: Integer read FDetailLevel write FDetailLevel default 1;
  142.     property DockSite;
  143.     property DragCursor;
  144.     property DragKind;
  145.     property DragMode;
  146.     property Enabled;
  147.     property Font;
  148.     property GraphPen: TPen read FGraphPen write FGraphPen;
  149.     property GridPen: TPen read FGridPen write FGridPen;
  150.     property Height default 150;
  151.     property HorzSpacing: Double read FHorzSpacing write FHorzSpacing;
  152.     property Margin: Integer read FMargin write SetMargin default 5;
  153.     property ParentBiDiMode;
  154.     property ParentColor;
  155.     property ParentCtl3D;
  156.     property ParentFont;
  157.     property ParentShowHint;
  158.     property PopupMenu;
  159.     property ShowAxis: Boolean read FShowAxis write FShowAxis default True;
  160.     property ShowGrid: Boolean read FShowGrid write FShowGrid default True;
  161.     property ShowHint;
  162.     property ShowText: Boolean read FShowText write FShowText default False;
  163.     property TabOrder;
  164.     property TabStop;
  165.     property Text: string read GetText write SetText;
  166.     property TextFont: TFont read FTextFont write SetFont;
  167.     property TracePen: TPen read FTracePen write FTracePen;
  168.     property Tracing: Boolean read FTracing write FTracing default True;
  169.     property VertSpacing: Double read FVertSpacing write FVertSpacing;
  170.     property Visible;
  171.     property Width default 300;
  172.     property XMaxValue: Integer read FXMaxValue write FXMaxValue default 5;
  173.     property YMaxValue: Integer read FYMaxValue write FYMaxValue default 5;
  174.     property OnCanResize;
  175.     property OnClick;
  176.     property OnConstrainedResize;
  177.     property OnContextPopup;
  178.     property OnDockDrop;
  179.     property OnDockOver;
  180.     property OnDblClick;
  181.     property OnDragDrop;
  182.     property OnDragOver;
  183.     property OnEndDock;
  184.     property OnEndDrag;
  185.     property OnEnter;
  186.     property OnExit;
  187.     property OnGetSiteInfo;
  188.     property OnMouseDown;
  189.     property OnMouseMove;
  190.     property OnMouseUp;
  191.     property OnResize;
  192.     property OnStartDock;
  193.     property OnStartDrag;
  194.     property OnUnDock;
  195.     property OnTrace: TTraceEvent read FOnTrace write FOnTrace;
  196.   end;
  197.  
  198. procedure Register;
  199.  
  200. implementation
  201.  
  202. procedure Register;
  203. begin
  204.   RegisterComponents('Samples', [TGraphBldr]);
  205. end;
  206.  
  207. { TGraphBldr }
  208.  
  209. procedure TGraphBldr.Calculate;
  210.  
  211.   procedure Split(var Points: TPoints; var Index: Integer);
  212.   begin
  213.     if Length(FPoints[Index]) > 0 then begin
  214.       Index := Length(FPoints);
  215.       SetLength(FPoints, Index + 1);
  216.     end;
  217.   end;
  218.  
  219. var
  220.   I, J: Integer;
  221.   Index, Value1, Value2, Factor1, Factor2, Factor3: Double;
  222.   Center: TCoord;
  223.   Rect: TRect;
  224. begin
  225.   FDataEditor.StringToNumScript(AnsiLowerCase(GetText));
  226.   I := ClientWidth;
  227.   J := ClientHeight;
  228.   Center.X := I / 2;
  229.   Center.Y := J / 2;
  230.   Dec(I, FBorderSize);
  231.   Dec(J, FBorderSize);
  232.   Factor1 := (Center.X - FBorderSize) / FXMaxValue;
  233.   Factor2 := (Center.Y - FBorderSize) / FYMaxValue;
  234.   Factor3 := FXMaxValue / I / FDetailLevel;
  235.   Rect := Classes.Rect(FBorderSize, FBorderSize, I, J);
  236.   DeletePoints(FPoints);
  237.   DeletePoints(FTracePoints);
  238.   J := 0;
  239.   SetLength(FPoints, J + 1);
  240.   Index := - FXMaxValue;
  241.   while Index <= FXMaxValue do begin
  242.     FCurrXValue := Index;
  243.     try
  244.       Value2 := Center.Y - FDataEditor.ExecuteNum * Factor2;
  245.       Value1 := Center.X + Index * Factor1;
  246.       if (Value1 >= Rect.Left) and (Value1 <= Rect.Right) and
  247.         (Value2 >= Rect.Top) and (Value2 <= Rect.Bottom) then begin
  248.           I := Length(FPoints[J]);
  249.           SetLength(FPoints[J], I + 1);
  250.           FPoints[J][I].X := Round(Value1);
  251.           FPoints[J][I].Y := Round(Value2);
  252.         end else Split(FPoints, J);
  253.     except
  254.       Split(FPoints, J);
  255.     end;
  256.     Index := Index + Factor3;
  257.   end;
  258.   FilterPoints(FPoints, 1, 1);
  259. end;
  260.  
  261. procedure TGraphBldr.Clear;
  262. begin
  263.   SetText('');
  264.   FDataEditor.Script := nil;
  265.   DeletePoints(FPoints);
  266.   DeletePoints(FTracePoints);
  267. end;
  268.  
  269. function TGraphBldr.Coordinates(X, Y: Double): TCoord;
  270. begin
  271.   Result.X := XCoord(X);
  272.   Result.Y := YCoord(Y);
  273. end;
  274.  
  275. constructor TGraphBldr.Create(AOwner: TComponent);
  276. begin
  277.   inherited;
  278.   BevelInner := bvLowered;
  279.   BevelOuter := bvRaised;
  280.   ControlStyle := [csAcceptsControls, csCaptureMouse, csClickEvents,
  281.     csSetCaption, csOpaque, csDoubleClicks, csReplicatable];
  282.   Cursor := crCross;
  283.   Height := 150;
  284.   Width := 300;
  285.   TabStop := False;
  286.   FAxisFont := TFont.Create;
  287.   FAxisPen := TPen.Create;
  288.   FShowAxis := True;
  289.   inherited BorderWidth := 5;
  290.   FMargin := 5;
  291.   FBorderSize := GetBevelWidth + GetBorderWidth + FMargin;
  292.   FDataEditor := TDataEditor.Create(Self);
  293.   with FDataEditor do begin
  294.     RegisterNumFunction(FXValueID, 'x', False, False);
  295.     SortNumFunctionsData;
  296.     OnNumFunction := NumFunction;
  297.     with AttrsManager do begin
  298.       Strings.Add('x');
  299.       UpdateStrings;
  300.     end;
  301.   end;
  302.   FDetailLevel := 1;
  303.   FGraphPen := TPen.Create;
  304.   FGraphPen.Color := clRed;
  305.   FGridPen := TPen.Create;
  306.   with FGridPen do begin
  307.     Color := clGray;
  308.     Style := psDot;
  309.   end;
  310.   FSaved := TPen.Create;
  311.   FSaved.Assign(Canvas.Pen);
  312.   FTextFont := TFont.Create;
  313.   FTracePen := TPen.Create;
  314.   with FTracePen do begin
  315.     Mode := pmNotXor;
  316.     Color := clBlue;
  317.     Style := psDot;
  318.   end;
  319.   FTracing := True;
  320.   FShowGrid := True;
  321.   FHorzSpacing := 1;
  322.   FPicture := TBitmap.Create;
  323.   FPicture.PixelFormat := pf24bit;
  324.   FShowGrid := True;
  325.   FShowText := False;
  326.   FVertSpacing := 1;
  327.   FXMaxValue := 5;
  328.   FYMaxValue := 5;
  329. end;
  330.  
  331. procedure TGraphBldr.DeletePoints(var Points: TPoints);
  332. var
  333.   I: Integer;
  334. begin
  335.   for I := Low(Points) to High(Points) do Points[I] := nil;
  336.   Points := nil;
  337. end;
  338.  
  339. destructor TGraphBldr.Destroy;
  340. begin
  341.   DeletePoints(FPoints);
  342.   DeletePoints(FTracePoints);
  343.   FAxisFont.Free;
  344.   FAxisPen.Free;
  345.   FGraphPen.Free;
  346.   FGridPen.Free;
  347.   FSaved.Free;
  348.   FTextFont.Free;
  349.   FTracePen.Free;
  350.   FPicture.Free;
  351.   inherited;
  352. end;
  353.  
  354. procedure TGraphBldr.Draw;
  355. begin
  356.   Paint;
  357. end;
  358.  
  359. procedure TGraphBldr.FilterPoints(var Points: TPoints; X, Y: Integer);
  360. var
  361.   I, J, K: Integer;
  362.   Point, NewPoint: TPoint;
  363.   NewPoints: TPoints;
  364. begin
  365.   SetLength(NewPoints, Length(Points));
  366.   for I := Low(Points) to High(Points) do
  367.     for J := Low(Points[I]) to High(Points[I]) do
  368.       if J = Low(Points[I]) then Point := Points[I][J]
  369.       else begin
  370.         NewPoint.X := Abs(Points[I][J].X - Point.X);
  371.         NewPoint.Y := Abs(Points[I][J].Y - Point.Y);
  372.         if (NewPoint.X >= X) or (NewPoint.Y >= Y) then begin
  373.           K := Length(NewPoints[I]);
  374.           SetLength(NewPoints[I], K + 1);
  375.           NewPoints[I][K] := Points[I][J];
  376.           Point := Points[I][J];
  377.         end;
  378.       end;
  379.   Points := nil;
  380.   Points := NewPoints;
  381. end;
  382.  
  383. function TGraphBldr.GetBevelWidth: TBevelWidth;
  384. begin
  385.   Result := inherited BevelWidth;
  386. end;
  387.  
  388. function TGraphBldr.GetBorderWidth: TBorderWidth;
  389. begin
  390.   Result := inherited BorderWidth;
  391. end;
  392.  
  393. function TGraphBldr.GetText: string;
  394. begin
  395.   Result := FDataEditor.Text;
  396. end;
  397.  
  398. function TGraphBldr.NumFunction(FunctionID, TypeID: Integer;
  399.   var Value1: Double; Value2, Value3: Double): Boolean;
  400. begin
  401.   if FunctionID = FXValueID then Value1 := FCurrXValue
  402.   else begin
  403.     Result := True;
  404.     Exit;
  405.   end;
  406.   Result := False;
  407. end;
  408.  
  409. procedure TGraphBldr.Paint;
  410. const
  411.   Alignments: array[TAlignment] of Longint = (DT_LEFT, DT_RIGHT, DT_CENTER);
  412. var
  413.   I, J, K: Integer;
  414.   Factor1, Factor2: Double;
  415.   Center: TPoint;
  416.   Points: array of TPoint;
  417.   Value: string;
  418.   Rect: TRect;
  419.   TopColor, BottomColor: TColor;
  420.  
  421.   procedure AdjustColors(Bevel: TBevelCut);
  422.   begin
  423.     TopColor := clBtnHighlight;
  424.     if Bevel = bvLowered then TopColor := clBtnShadow;
  425.     BottomColor := clBtnShadow;
  426.     if Bevel = bvLowered then BottomColor := clBtnHighlight;
  427.   end;
  428.  
  429. begin
  430.   inherited;
  431.   DeletePoints(FTracePoints);
  432.   with FPicture, Canvas do begin
  433.     I := ClientWidth;
  434.     J := ClientHeight;
  435.     Width := I;
  436.     Height := J;
  437.     Center.X := I div 2;
  438.     Center.Y := J div 2;
  439.     Dec(I, FBorderSize);
  440.     Dec(J, FBorderSize);
  441.     Brush.Color := Color;
  442.     FillRect(ClientRect);
  443.     if FShowGrid and ((FHorzSpacing > 0) or (FVertSpacing > 0)) then begin
  444.       Pen.Assign(FGridPen);
  445.       if FHorzSpacing > 0 then begin
  446.         // ─δΦφα ∩εδεΓΦφ√ ε±Φ X:
  447.         Factor1 := I - Center.X;
  448.         // ─δΦφα Φφ≥σ≡Γαδα:
  449.         Factor2 := Factor1 * FHorzSpacing / FXMaxValue;
  450.         if Factor2 <= Factor1 then begin
  451.           SetRoundMode(rmDown);
  452.           Factor1 := Center.X;
  453.           while Round(Factor1) <= I do begin
  454.             MoveTo(Round(Factor1), FBorderSize);
  455.             LineTo(Round(Factor1), J);
  456.             Factor1 := Factor1 + Factor2;
  457.           end;
  458.           SetRoundMode(rmUp);
  459.           Factor1 := Center.X;
  460.           while Round(Factor1) >= FBorderSize do begin
  461.             MoveTo(Round(Factor1), FBorderSize);
  462.             LineTo(Round(Factor1), J);
  463.             Factor1 := Factor1 - Factor2;
  464.           end;
  465.         end;
  466.       end;
  467.       if FVertSpacing > 0 then begin
  468.         // ─δΦφα ∩εδεΓΦφ√ ε±Φ Y:
  469.         Factor1 := J - Center.Y;
  470.         // ─δΦφα Φφ≥σ≡Γαδα:
  471.         Factor2 := Factor1 * FVertSpacing / FYMaxValue;
  472.         if Factor2 <= Factor1 then begin
  473.           SetRoundMode(rmDown);
  474.           Factor1 := Center.Y;
  475.           while Round(Factor1) <= J do begin
  476.             MoveTo(FBorderSize, Round(Factor1));
  477.             LineTo(I, Round(Factor1));
  478.             Factor1 := Factor1 + Factor2;
  479.           end;
  480.           SetRoundMode(rmUp);
  481.           Factor1 := Center.Y;
  482.           while Round(Factor1) >= FBorderSize do begin
  483.             MoveTo(FBorderSize, Round(Factor1));
  484.             LineTo(I, Round(Factor1));
  485.             Factor1 := Factor1 - Factor2;
  486.           end;
  487.         end;
  488.       end;
  489.       SetRoundMode(rmNearest);
  490.     end;
  491.     if FShowAxis then begin
  492.       Pen.Assign(FAxisPen);
  493.       K := FAxisPen.Width - 1;
  494.       // ╬±ⁿ X:
  495.       MoveTo(FBorderSize + K, Center.Y);
  496.       LineTo(I - K, Center.Y);
  497.       // ╬±ⁿ Y:
  498.       MoveTo(Center.X, J - K);
  499.       LineTo(Center.X, FBorderSize + K);
  500.       Pen.Width := 1;
  501.       Brush.Color := Pen.Color;
  502.       SetLength(Points, 3);
  503.       try
  504.         // ┬σ≡°Φφα ε±Φ X:
  505.         Points[0].X := I - 15;
  506.         Points[0].Y := Center.Y - 10;
  507.         Points[1].X := I;
  508.         Points[1].Y := Center.Y;
  509.         Points[2].X := I - 15;
  510.         Points[2].Y := Center.Y + 10;
  511.         Polygon(Points);
  512.         // ┬σ≡°Φφα ε±Φ Y:
  513.         SetLength(Points, 3);
  514.         Points[0].X := Center.X - 10;
  515.         Points[0].Y := FBorderSize + 15;
  516.         Points[1].X := Center.X;
  517.         Points[1].Y := FBorderSize;
  518.         Points[2].X := Center.X + 10;
  519.         Points[2].Y := FBorderSize + 15;
  520.         Polygon(Points);
  521.       finally
  522.         Points := nil;
  523.       end;
  524.       Brush.Style := bsClear;
  525.       Font.Assign(FAxisFont);
  526.       TextOut(I - TextWidth('X'), Center.Y - 20 - TextHeight('X'), 'X');
  527.       Value := IntToStr(FXMaxValue);
  528.       TextOut(I - TextWidth(Value), Center.Y + 20, Value);
  529.       TextOut(FBorderSize, Center.Y + 20, '-' + Value);
  530.       TextOut(Center.X - 20 - TextWidth('Y'), FBorderSize, 'Y');
  531.       Value := IntToStr(FYMaxValue);
  532.       TextOut(Center.X + 20, FBorderSize, Value);
  533.       TextOut(Center.X + 20, J - TextHeight('-' + Value), '-' + Value);
  534.     end;
  535.     if FShowText then begin
  536.       Brush.Style := bsClear;
  537.       Font.Assign(FTextFont);
  538.       Value := Trim(GetText);
  539.       if Value <> '' then TextOut(FBorderSize, FBorderSize,
  540.         Format('Y = %s', [Value]));
  541.     end;
  542.     Pen.Assign(FGraphPen);
  543.     //for I := Low(FPoints) to High(FPoints) do Polyline(FPoints[I]);
  544.     for I := Low(FPoints) to High(FPoints) do
  545.       for J := Low(FPoints[I]) to High(FPoints[I]) do
  546.         with FPoints[I][J] do if J = Low(FPoints[I]) then MoveTo(X, Y)
  547.         else LineTo(X, Y);
  548.   end;
  549.   Canvas.Pen.Assign(FSaved);
  550.   Canvas.Draw(0, 0, FPicture);
  551.   Rect := ClientRect;
  552.   if BevelOuter <> bvNone then
  553.   begin
  554.     AdjustColors(BevelOuter);
  555.     Frame3D(Canvas, Rect, TopColor, BottomColor, GetBevelWidth);
  556.   end;
  557.   Frame3D(Canvas, Rect, Color, Color, GetBorderWidth);
  558.   if BevelInner <> bvNone then
  559.   begin
  560.     AdjustColors(BevelInner);
  561.     Frame3D(Canvas, Rect, TopColor, BottomColor, GetBevelWidth);
  562.   end;
  563. end;
  564.  
  565. procedure TGraphBldr.SetAxisFont(const Value: TFont);
  566. begin
  567.   FAxisFont.Assign(Value);
  568. end;
  569.  
  570. procedure TGraphBldr.SetBevelWidth(const Value: TBevelWidth);
  571. begin
  572.   inherited BevelWidth := Value;
  573.   FBorderSize := Value + GetBorderWidth + FMargin;
  574. end;
  575.  
  576. procedure TGraphBldr.SetBorderWidth(const Value: TBorderWidth);
  577. begin
  578.   inherited BorderWidth := Value;
  579.   FBorderSize := Value + GetBevelWidth + FMargin;
  580. end;
  581.  
  582. procedure TGraphBldr.SetFont(const Value: TFont);
  583. begin
  584.   FTextFont.Assign(Value);
  585. end;
  586.  
  587. procedure TGraphBldr.SetMargin(const Value: Integer);
  588. begin
  589.   FMargin := Value;
  590.   FBorderSize := Value + GetBevelWidth + GetBorderWidth;
  591. end;
  592.  
  593. procedure TGraphBldr.SetText(const Value: string);
  594. begin
  595.   FDataEditor.Text := Value;
  596. end;
  597.  
  598. procedure TGraphBldr.WMMouseMove(var Message: TWMMouseMove);
  599.  
  600.   procedure DrawLines;
  601.   var
  602.     I: Integer;
  603.   begin
  604.     with Canvas do begin
  605.       Pen.Assign(FTracePen);
  606.       for I := Low(FTracePoints) to High(FTracePoints) do
  607.         Polyline(FTracePoints[I]);
  608.     end;
  609.   end;
  610.  
  611. var
  612.   I, J: Integer;
  613.   Center: TCoord;
  614.   Value1, Value2, Factor: Double;
  615.   Rect: TRect;
  616. begin
  617.   inherited;
  618.   if not FTracing or (Trim(GetText) = '') then Exit;
  619.   DrawLines;
  620.   I := ClientWidth;
  621.   J := ClientHeight;
  622.   Center.X := I / 2;
  623.   Center.Y := J / 2;
  624.   Dec(I, FBorderSize);
  625.   Dec(J, FBorderSize);
  626.   Factor := (Center.Y - FBorderSize) / FYMaxValue;
  627.   Rect := Classes.Rect(FBorderSize, FBorderSize, I, J);
  628.   FCurrXValue := XCoord(Message.XPos);
  629.   try
  630.     Value1 := FDataEditor.ExecuteNum;
  631.     Value2 := Center.Y - Value1 * Factor;
  632.     if (Message.XPos >= Rect.Left) and (Message.XPos <= Rect.Right) and
  633.       (Value2 >= Rect.Top) and (Value2 <= Rect.Bottom) then begin
  634.         if Assigned(FOnTrace) then FOnTrace(Self, FCurrXValue, Value1);
  635.         SetLength(FTracePoints, 2);
  636.         SetLength(FTracePoints[0], 2);
  637.         SetLength(FTracePoints[1], 2);
  638.         FTracePoints[0][0].X := Round(Message.XPos);
  639.         FTracePoints[0][0].Y := FBorderSize;
  640.         FTracePoints[0][1].X := Round(Message.XPos);
  641.         FTracePoints[0][1].Y := J;
  642.         FTracePoints[1][0].X := FBorderSize;
  643.         FTracePoints[1][0].Y := Round(Value2);
  644.         FTracePoints[1][1].X := I;
  645.         FTracePoints[1][1].Y := Round(Value2);
  646.       end else DeletePoints(FTracePoints);
  647.   except
  648.     DeletePoints(FTracePoints);
  649.   end;
  650.   DrawLines;
  651. end;
  652.  
  653. procedure TGraphBldr.WMSize(var Message: TWMSize);
  654. begin
  655.   inherited;
  656.   if Trim(GetText) <> '' then Calculate else DeletePoints(FPoints);
  657.   Paint;
  658. end;
  659.  
  660. function TGraphBldr.XCoord(X: Double): Double;
  661. var
  662.   Center: Double;
  663. begin
  664.   Center := ClientWidth / 2 - FBorderSize;
  665.   Result := (X - FBorderSize - Center) * FXMaxValue / Center;
  666. end;
  667.  
  668. function TGraphBldr.YCoord(Y: Double): Double;
  669. var
  670.   Center: Double;
  671. begin
  672.   Center := ClientHeight / 2 - FBorderSize;
  673.   Result := (Center - (Y - FBorderSize)) * FYMaxValue / Center;
  674. end;
  675.  
  676. end.
  677.