Cross hair not drawn when labels are on Chart
Posted: 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;
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;