Page 1 of 1

Drawing boxes on TColorGridSeries

Posted: Thu Oct 20, 2005 3:31 pm
by 8572663
What is the best way to draw a box on a TColorGridSeries. I want to be able to access the Y data inside the box. I have been using the Zoom box via the Chart1.DrawZoomRectangle in the Mouse Down, Mouse Move and Mouse Up events. This works ok, but when the window looses focus and is partially covered by another window, the boxes are erased.

Is there a better way to do this? For example using the TRectangleTool. I was not able to get that tool to work. Is there an example somewhere?

Thanks in advance!

Posted: Fri Oct 21, 2005 1:28 pm
by narcis
Hi leaf,

Yes, this can be done custom drawing on TChart's canvas using code similar to:

Code: Select all

//...

var
  Form1: TForm1;
  X0,Y0,X1,Y1,XIndex,YIndex: Integer;
  DrawRect: Boolean;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Series1.FillSampleValues(10);
  Chart1.Zoom.Allow:=false;
end;

procedure TForm1.Chart1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  Memo1.Clear;

  X0:=X;
  Y0:=Y;

  XIndex:=Series1.Clicked(X0,Y0);
  DrawRect := true;
end;

procedure TForm1.Chart1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if DrawRect then
  begin
     X1:=X;
     Y1:=Y;

     Chart1.Repaint;
  end;
end;

procedure TForm1.Chart1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  DrawRect := false;

  YIndex:=Series1.Clicked(X1,Y1);
  GetRectIndexes;

  Chart1.Repaint;
end;

procedure TForm1.Chart1AfterDraw(Sender: TObject);
begin
  With Chart1.Canvas  do
  begin
    Pen.Color:=clWhite;
    Pen.Width:=2;
    Brush.Style:=bsClear;
    Rectangle(X0,Y0,X1,Y1);
  end;
end;

procedure TForm1.GetRectIndexes;
var
  Col0,Row0,Col1,Row1,x,z: Integer;
begin
  Col0:=GetColumn(XIndex);
  Row0:=GetRow(XIndex);
  Col1:=GetColumn(YIndex);
  Row1:=GetRow(YIndex);

  for x:=Min(Col0,Col1) to Max(Col0,Col1) do
    for z:=Min(Row0,Row1) to Max(Row0,Row1) do
      Memo1.Lines.Add(FloatToStr(Series1.YValues[(x*10)+z]));
end;

function TForm1.GetColumn(ValueIndex: Integer): Integer;
begin
  result:=ValueIndex div Series1.NumXValues;
end;

function TForm1.GetRow(ValueIndex: Integer): Integer;
begin
  result:=ValueIndex mod Series1.NumZValues;
end;

//...

Posted: Thu Oct 27, 2005 10:03 pm
by 8572663
Narcis,

Thank you for your response. Foir the most part this all works very good for me. However I do have 2 questions.

1.)

I see that you also responded to another user in a thread called "Getting YValues from a TColorGridSeries". In that thread you say that "Clicked method doesn't work for those series types. This is a known problem which is listed on our defect list to be fixed for future releases."

Does this apply to what I am trying to do here? If so, it may be part of the problem I am talking about below in number 2.

2.)

Once my box is drawn on the screen, I need some information about it to access/modify the data in a local structure. I do the following in the MouseUp event...

ind := Chart1.Series[0].XScreenToValue(X);
fIERRecList[Len].iX0 := ind;
fIERRecList[Len].Left := -1;

// Here i need to find
for i := 0 to High(DblImageData[0]) do
if Abs(xScaleOff + (xScaleMul * i)) -
Abs(ind) < 0.00000001 then
begin
fIERRecList[Len].Left := Max(i-1, 0);
break;
end;

...
I do the same for Top, bottom and right and get ind using YScreenToValue
...

This gives me the index's required to access and modify the data in DblImageData used to generate the image. My problem is that the For loop is very slow and inefficient. I was hoping that the Clicked routine and GetColumn and GetRow would give me the same information. If so then I should get the same information in the for loop when executing this code:

fCol0 := GetColumn(fIERxIndex);
fRow0 := GetRow(fIERxIndex);
fCol1 := GetColumn(fIERyIndex);
fRow1 := GetRow(fIERyIndex);

StatusBar1.SimpleText := 'r0/c0/r1/c1 = ' +
FloatToStr(xScaleOff + (xScaleMul * fRow0)) + ' / ' +
FloatToStr(zScaleOff + (zScaleMul * fCol0)) + ' / ' +
FloatToStr(xScaleOff + (xScaleMul * fRow1)) + ' / ' +
FloatToStr(zScaleOff + (zScaleMul * fCol1));

The problem is that I do not. What am I missing?

What does the clicked routine and the GetColumn and GetRow routines in your example give me?

Thanks again...

Posted: Fri Oct 28, 2005 10:37 am
by narcis
Hi leaf,
Does this apply to what I am trying to do here? If so, it may be part of the problem I am talking about below in number 2.
Sorry leaf, I confused myself. I can see that Clicked method works fine with v7.05 and as you can check in the code I posted previously.
The problem is that I do not. What am I missing?

What does the clicked routine and the GetColumn and GetRow routines in your example give me?
I don't understand what you are exactly doing but I'll try to explain myself. In the code I posted, Clicked method gives me the left-top and right-bottom points for determining the rectangle. Then I implemented GetColumn and GetRow functions to be able to loop through all the rectangle cells and retrieve its value.

If you are having problems here could you please send us an example we can run "as-is" to reproduce the problem here? You can post your files at [url]news://www.steema.net/steema.public.attachments[/url] newsgroup.