Page 1 of 1

Drawing lines on a tColorGridSeries

Posted: Tue May 10, 2016 7:50 pm
by 16577760
The idea here is to draw a polygon on my image with Polyline. So, while holding the CTRL key
down, click points on the chart. A line should be drawn between points and stretch between
the last point clicked and the mouse.

To close the polygon, release the CTRL key and click the final point.
This also stops the drawing.

In the Mouse move event, the old "polyline" should be XOR'd off the chart and the new line
drawn, giving the rubber band effect. The XOR is not happening. Why?

Also, once the final polygon is drawn, if you move the mouse the image refreahes deleting the
polygon. If I turn off AutoRepaint, the old lines are never removed.

How do I get the polygon to stay on the image? Can you make any suggestions?

I tried to attach a small application to demonstrate. Did you get it? I don't see it...have my upload permissions changed? I can resend the files if you allow me to.

Here is the application text

Code: Select all

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, VclTee.TeeGDIPlus, Vcl.StdCtrls,
  VCLTee.TeEngine, VCLTee.TeeProcs, VCLTee.Chart, Vcl.ExtCtrls,
  VCLTee.TeeSurfa, VCLTee.TeeEdit;

type
  TForm1 = class(TForm)
    Chart1: TChart;
    Panel1: TPanel;
    Memo1: TMemo;
    procedure Chart1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Chart1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    PTarray : array of TPoint;
    Drawing : boolean;

  public
    { Public declarations }
  end;

const
  pmode : TPenMode = pmNot;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Chart1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
   if (ssCtrl in Shift) then
     begin
       // Check if we are starting to draw a new polygon
       if Length(PTarray) <= 0  then
         begin
           // Initialize the array to hold the polygon vertex list.
           // Allocate an extra element to hold the curent mouse position
           // and use it for the last/next vertex.
           SetLength(PTarray, 1);
           PTarray[0].X := X;
           PTarray[0].Y := Y;
           Drawing := True;
         end

       else if Length(PTarray) > 1 then
         begin
           //
           // Clear the old line we were stretching to the last vertex
           //
           Chart1.Canvas.Pen.Width := 0;
           Chart1.Canvas.Pen.Color := clWhite;
           Chart1.Canvas.Brush.Style := bsClear;
           //Chart1.Canvas.Pen.Mode := pmXor;
           //Chart1.Canvas.Pen.Mode := pmode;
           Chart1.Canvas.Pen.Mode := pmNotCopy;
           Chart1.Canvas.Polyline(PTarray);
           Chart1.Repaint;
           Application.ProcessMessages;
         end;

       // Increase the array to hold the new vertex.
       SetLength(PTarray, Length(PTarray)+1);

       // Save the new vertex
       PTarray[High(PTarray)].X := X;
       PTarray[High(PTarray)].Y := Y;

       //
       // Draw a line from the previous vertex to this new one
       //
       Chart1.Canvas.Pen.Width := 1;
       Chart1.Canvas.Pen.Color := clWhite;
       Chart1.Canvas.Brush.Style := bsClear;
       //Chart1.Canvas.Pen.Mode := pmXor;
       Chart1.Canvas.Pen.Mode := pmode;
       Chart1.Canvas.Polyline(PTarray);
       Chart1.Repaint;
       Application.ProcessMessages;
     end
   else
     begin
       //
       // Clear the old line we were stretching to the last vertex
       //
       Chart1.Canvas.Pen.Width := 0;
       Chart1.Canvas.Pen.Color := clWhite;
       Chart1.Canvas.Brush.Style := bsClear;
       //Chart1.Canvas.Pen.Mode := pmXor;
       Chart1.Canvas.Pen.Mode := pmode;
       Chart1.Canvas.Polyline(PTarray);

       // Close the polygon;
       Chart1.Canvas.Pen.Width := 1;
       Chart1.Canvas.Pen.Mode := pmode;

       SetLength(PTarray, Length(PTarray)+1);
       PTarray[High(PTarray)] := PTarray[0];
       Chart1.Canvas.Polyline(PTarray);
       Chart1.Repaint;
       Application.ProcessMessages;

       Drawing := False;
       SetLength(PTarray, 0);
     end;
end;


procedure TForm1.Chart1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  // Check if we are drawing the polygon
  if Drawing then
    begin
      Chart1.Canvas.Pen.Color := clWhite;
      Chart1.Canvas.Brush.Style := bsClear;
      //Chart1.Canvas.Pen.Mode := pmXor;
      Chart1.Canvas.Pen.Mode := pmode;

      //
      // Remove the old line
      //
      Chart1.Canvas.Pen.Width := 0;
      Chart1.Canvas.Polyline(PTarray);

      // Save new point
      PTarray[High(PTarray)].X := X;
      PTarray[High(PTarray)].Y := Y;

      //
      // Draw the new line
      //
      Chart1.Canvas.Pen.Width := 1;
      //Chart1.Canvas.Pen.Mode := pmXor;
      Chart1.Canvas.Pen.Mode := pmode;
      Chart1.Canvas.Polyline(PTarray);
      Chart1.Repaint;
      Application.ProcessMessages;
    end
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  chart1.AddSeries(TColorGridSeries).FillSampleValues();
  chart1.AutoRepaint := True;
end;

end.

Re: Drawing lines on a tColorGridSeries

Posted: Thu May 12, 2016 9:37 am
by yeray
Hello,

Since you have the TeeChart sources, you can take a look at how the TCursorTool draws the lines with XOR techniques.
An alternative would be to maintain the arrays of points at the OnMouseDown&OnMouseMove events and to draw them at OnAfterDraw.

Re: Drawing lines on a tColorGridSeries

Posted: Thu May 12, 2016 12:03 pm
by 16577760
Thanks Yeray,

Can you direct my into the source code file(s) to look at. The way the cursor works is preferable I think. Otherwise I can put them in the OnAfterDraw event as you say.

Thanks

Re: Drawing lines on a tColorGridSeries

Posted: Thu May 12, 2016 3:04 pm
by yeray
Hello,
dave wrote:Can you direct my into the source code file(s) to look at. The way the cursor works is preferable I think.
Take a look at the TCursorTool.ChartMouseEvent and TCursorTool.RedrawCursor methods in TeeTools.pas.

Re: Drawing lines on a tColorGridSeries

Posted: Thu May 12, 2016 3:26 pm
by 16577760
Thanks!