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!
Drawing boxes on TColorGridSeries
-
- Site Admin
- Posts: 14730
- Joined: Mon Jun 09, 2003 4:00 am
- Location: Banyoles, Catalonia
- Contact:
Hi leaf,
Yes, this can be done custom drawing on TChart's canvas using code similar to:
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;
//...
Best Regards,
Narcís Calvet / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
Instructions - How to post in this forum |
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...
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...
-
- Site Admin
- Posts: 14730
- Joined: Mon Jun 09, 2003 4:00 am
- Location: Banyoles, Catalonia
- Contact:
Hi leaf,
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.
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.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.
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.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?
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.
Best Regards,
Narcís Calvet / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
Instructions - How to post in this forum |