Cross hair not drawn when labels are on Chart

TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
Post Reply
ChartIt
Newbie
Newbie
Posts: 29
Joined: Tue Mar 13, 2007 12:00 am

Cross hair not drawn when labels are on Chart

Post by ChartIt » Wed Nov 24, 2010 7:56 pm

Hello,

It seems like I have an issue with TChart 2010.

I use the following code to draw a cross hair on a Chart that follows the mouse when moved on the Chart.
The cross hair is following the mouse perfectly if I don't place the two labels "lblHorizontalAxis" and "lblVerticalAxis" directly on the Chart (but place them on the form behind the Chart). The labels are showing some values that are extracted from the Chart while the mouse is moving.

The problem occurs if I place the labels on the Chart itself (where they actually belong).
The labels are getting updated, and following the mouse as they should, but the cross hair is only drawn ones when pressing the mouse, but not following the mouse (which means it doesn't get deleted and redrawn in the OnMouseMove event).

I'm pretty sure I didn't have this problem with TChart 7.
Do you know what has happened, or do you need more explanation/code?
Thanks in advance!

procedure TfrDataLogger.DrawCross(AX, AY: Integer);
begin
with Chart1, Canvas do
begin
Pen.Color := clWhite;
Pen.Style := psSolid;
Pen.Mode := pmXor;
Pen.Width := 1;
//Vertical line:
MoveTo(ax, ChartRect.Top);
LineTo(ax, ChartRect.Bottom);
//Horizontal line:
MoveTo(ChartRect.Left, ay);
LineTo(ChartRect.Right, ay);
end;
end;

procedure TfrDataLogger.Chart1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if ((FAnalyzeMode = Rule) or (FAnalyzeMode = Tracker) or (FAnalyzeMode = Vernier)) and (Button = MBLeft) then
begin
Chart1[0].GetCursorValues(FStartVernierX, FStartVernierY);
lblHorizontalAxis.Visible := True;
lblVerticalAxis.Visible := True;

if PtInRect(Chart1.ChartRect, Point(X-Chart1.Width3D,Y+Chart1.Height3D)) then //Check if mouse is inside Chart rectangle.
begin
FDrawCrossActive := True;
DrawCross(x, y); //Draw crosshair at current position.
//Store current position:
FOldX := x;
FOldY := y;
//In case of Vernier the first drawn crossHair must remain:
if (FAnalyzeMode = Vernier) then
FOldX := -1;
end;
end;
end;

procedure TfrDataLogger.Chart1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var
tmpX, tmpY: Double;
begin
Chart1[0].GetCursorValues(tmpX, tmpY);

if FAnalyzeMode = Rule then
begin
lblHorizontalAxis.Caption := FloatToStr(RoundTo(tmpX,-2));
lblHorizontalAxis.Top := Chart1.Axes.Bottom.PosLabels;
lblHorizontalAxis.Left := Chart1.GetCursorPos.X - round(lblHorizontalAxis.Width/2);

lblVerticalAxis.Caption := FloatToStr(RoundTo(tmpY,-2));
lblVerticalAxis.Top := Chart1.GetCursorPos.Y - round(lblVerticalAxis.Height/2);
lblVerticalAxis.Left := Chart1[0].GetVertAxis.PosLabels - lblVerticalAxis.Width;
end;

if (FAnalyzeMode = Tracker) and (Chart1[0].Count <> 0) then
begin
lblHorizontalAxis.Caption := FloatToStr(RoundTo(tmpX,-2));
lblHorizontalAxis.Top := Chart1.Axes.Bottom.PosLabels;
lblHorizontalAxis.Left := Chart1.GetCursorPos.X - round(lblHorizontalAxis.Width/2);

lblVerticalAxis.Caption := FloatToStr(Chart1[0].YValue[Round(tmpX)]);
//lblVerticalAxis.Caption := FloatToStr(RoundTo(tmpY,-2));
lblVerticalAxis.Top := Chart1.GetCursorPos.Y - round(lblVerticalAxis.Height/2);
lblVerticalAxis.Left := Chart1[0].GetVertAxis.PosLabels - lblVerticalAxis.Width;
end;

if FAnalyzeMode = Vernier then
begin
lblHorizontalAxis.Caption := FloatToStr(RoundTo(tmpX - FStartVernierX, -2));
lblHorizontalAxis.Top := Chart1.Axes.Bottom.PosLabels;
lblHorizontalAxis.Left := Chart1.GetCursorPos.X - round(lblHorizontalAxis.Width/2);

lblVerticalAxis.Caption := FloatToStr(RoundTo(tmpY - FStartVernierY, -2));
lblVerticalAxis.Top := Chart1.GetCursorPos.Y - round(lblVerticalAxis.Height/2);
lblVerticalAxis.Left := Chart1[0].GetVertAxis.PosLabels - lblVerticalAxis.Width;
end;

//Delete old crossHair:
if ((FAnalyzeMode = Rule) or (FAnalyzeMode = Tracker) or (FAnalyzeMode = Vernier)) and (FDrawCrossActive) then
begin
if (FOldX <> -1) then
begin
DrawCross(FOldX, FOldY); //Delete old crossHair.
FOldX := -1;
end;

//Check if mouse is inside Chart rectangle:
if PtInRect(Chart1.ChartRect, Point(X-Chart1.Width3D,Y+Chart1.Height3D)) then
begin
DrawCross(x, y); //Draw crosshair at current position.
//Store current position:
FOldX := x;
FOldY := y;
end;
end;
end;

Yeray
Site Admin
Site Admin
Posts: 9602
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Cross hair not drawn when labels are on Chart

Post by Yeray » Thu Nov 25, 2010 9:37 am

Hi ChartIt,

There are some variables in your code snipped undefined so we can't run it as-is. Please, try to arrange a simple example project we can run as-is to reproduce the problem here.
However, if I understood well, you are trying to achieve something similar to the Cursor Tool. Take a look at the examples under "All features\Welcome !\Tools\Cursor\".
Here you have a simple example:

Code: Select all

uses Series, TeeTools;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Chart1.View3D:=false;
  Chart1.Legend.Visible:=false;

  with Chart1.AddSeries(TPointSeries) do FillSampleValues;

  with Chart1.Tools.Add(TCursorTool) as TCursorTool do
    FollowMouse:=true;
end;
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

ChartIt
Newbie
Newbie
Posts: 29
Joined: Tue Mar 13, 2007 12:00 am

Re: Cross hair not drawn when labels are on Chart

Post by ChartIt » Thu Nov 25, 2010 1:46 pm

Hi,

I didn't know that function, thanks for that!

Anyway, the problem seems to be here too.
Put a label to a new Chart, and add this code:

procedure TForm1.Chart1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
var
tmpX, tmpY: Double;
begin
Chart1[0].GetCursorValues(tmpX, tmpY);
Label1.Caption := FloatToStr(Round(tmpX));
end;

procedure TForm1.FormCreate(Sender: TObject);
var
i: Integer;
begin
Chart1.View3D := False;
Chart1.Legend.Visible := False;

Chart1.AddSeries(TFastLineSeries);
for i := 0 to 200 do
Chart1.Series[0].AddXY(i, i, '', clRed);

with Chart1.Tools.Add(TCursorTool) as TCursorTool do
FollowMouse := True;
end;

Without updating the label in OnMouseMove everything works fine.
When updating the label (like in the code above) the cursor tool doesn't get drawn.

What do you say?

Yeray
Site Admin
Site Admin
Posts: 9602
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Cross hair not drawn when labels are on Chart

Post by Yeray » Thu Nov 25, 2010 3:38 pm

Hi ChartIt,

The attached project seems to run fine for me here. Could you please tell us what we have to do to reproduce the problem with it?
MouseMoveUpdate.zip
(1.74 KiB) Downloaded 878 times
Are you using the latest TeeChart version available (v2010.01)?
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

ChartIt
Newbie
Newbie
Posts: 29
Joined: Tue Mar 13, 2007 12:00 am

Re: Cross hair not drawn when labels are on Chart

Post by ChartIt » Thu Nov 25, 2010 4:39 pm

I use the latest version. Downloaded yesterday :)

If you delete the line:
Chart1.Title.Text.Text:=FloatToStr(Round(tmpX));

you should also see the problem.

ChartIt
Newbie
Newbie
Posts: 29
Joined: Tue Mar 13, 2007 12:00 am

Re: Cross hair not drawn when labels are on Chart

Post by ChartIt » Thu Nov 25, 2010 5:02 pm

By adding the line
Chart1.Repaint;
or
Chart1.Refresh;

at the end of the MouseMove event the cross hair gets redrawn, but then it draws on top of the label.

This is not the case when using the line
Chart1.Title.Text.Text := FloatToStr(Round(tmpX));

Yeray
Site Admin
Site Admin
Posts: 9602
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Cross hair not drawn when labels are on Chart

Post by Yeray » Fri Nov 26, 2010 9:52 am

Hi ChartIt,

Excuse me, I'm not sure how I was looking at this.
Yes, it seems that, for some reason, when updating a label (with the chart as parent) in the OnMouseMove event (also happens with the tool's OnChange event), the Cursor Tool stops following the mouse. I've added it to the wish list to be investigated for further releases (TV52015292).
As you say, the Chart1.Repaint and the Chart1.Refresh methods work around this. Also you could consider using Annotation tools, Rectangle tools or custom drawing the text on top of the chart instead of using labels.
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

ChartIt
Newbie
Newbie
Posts: 29
Joined: Tue Mar 13, 2007 12:00 am

Re: Cross hair not drawn when labels are on Chart

Post by ChartIt » Fri Nov 26, 2010 9:58 am

Hi Yeray,

OK, but please note that Repaint and Refresh don't solve the problem completely, see my previous post.

Do you happen to be able to help me out with my newest post in this forum regarding retrieving YValues? :)

Yeray
Site Admin
Site Admin
Posts: 9602
Joined: Tue Dec 05, 2006 12:00 am
Location: Girona, Catalonia
Contact:

Re: Cross hair not drawn when labels are on Chart

Post by Yeray » Fri Nov 26, 2010 10:11 am

Hi ChartIt,

And what about this?

Code: Select all

Chart1.Tools[0].Repaint;
ChartIt wrote:Do you happen to be able to help me out with my newest post in this forum regarding retrieving YValues? :)
Of course, as soon as possible.
Best Regards,
ImageYeray Alonso
Development & Support
Steema Software
Av. Montilivi 33, 17003 Girona, Catalonia (SP)
Image Image Image Image Image Image Please read our Bug Fixing Policy

ChartIt
Newbie
Newbie
Posts: 29
Joined: Tue Mar 13, 2007 12:00 am

Re: Cross hair not drawn when labels are on Chart

Post by ChartIt » Fri Nov 26, 2010 10:18 am

That seems to work, thanks!

Post Reply