Page 1 of 1
CursorTool Question
Posted: Tue May 13, 2008 6:38 pm
by 10546441
This time I need help with an CursorTool :
The situation is a Y/X Point Chart where I like to "select" points which I do and symbolize with this "toolSelect: TCursorTool".
The Problem is, I don't want the Tool to be movable. I only set the x/y Position of the tool by code, and don't want it to show the move cursor or move by the mouse.
I already tried "Active=False" which does not help.
Any good ideas on this ? Maybe there is a different way in showing up "selected Points" (They have to have a colored circle around which is bigger than the point itself)
For the moment the Tool is implemented the following way
Many thanks in advance.
Code: Select all
toolSelected := TCursorTool.Create(Chart);
with toolSelected do
begin
ParentChart := Chart;
Series := seriesP;
Brush.Style := bsClear;
Pen.EndStyle := esFlat;
Pen.Color := clBlue;
Pen.Width := 5;
FollowMouse := False;//True;
Snap := False; //True;
SnapStyle := ssDefault;
Style := cssScope;
ScopeStyle := scsCircle; //Rectangle;
ScopeSize := 13;
YValue := 0;
XValue := 0;
Visible := False;
ClickTolerance := 0;
Active := False;
end;
[/code]
Posted: Wed May 14, 2008 7:59 am
by yeray
Hi ChZiegelt,
If you only want to mark the last clicked point, let me suggest you another way to achieve that. I think you don't need a cursor tool. Simply using OnClicked event from the series to store the index of the point that has been clicked and GetPointerStyle event to modify the pointer of the point.
Here is a simple example of how to do that:
Code: Select all
procedure TForm1.Series1Click(Sender: TChartSeries; ValueIndex: Integer;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
ClickedIndex := ValueIndex;
Caption := IntToStr(ClickedIndex);
Chart1.Draw;
end;
function TForm1.Series1GetPointerStyle(Sender: TChartSeries;
ValueIndex: Integer): TSeriesPointerStyle;
begin
if ClickedIndex = ValueIndex then
begin
Series1.Pointer.HorizSize := 10;
Series1.Pointer.VertSize := 10;
end
else
begin
Series1.Pointer.HorizSize := 5;
Series1.Pointer.VertSize := 5;
end;
Result := psRectangle;
Caption := IntToStr(ClickedIndex);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Chart1.View3D := false;
Chart1.Legend.Visible := false;
ClickedIndex := -1;
Caption := IntToStr(ClickedIndex);
end;
BTW: If you still prefer to use a cursor tool or another method, and you still have problems on it, please, feel free to ask how to do it.
Posted: Wed May 14, 2008 8:13 am
by 10546441
Hi Yeray,
thanks for the reply first.
I think for only this one problem on "marking" selected Points it could be a solution. I will give it a try.
the second or even bigger problem is, besides selecting points, each point could have many different states at the same time.
It can be chosen as a Reference point and being selected, es well as the color is used to symbolize a Z Value for that point.
Now it will become really difficult to vary the symbols in a way, it comes out clear which states it has. This for I use different CursorTools, one with a blue Circle, one with a black Rectangle, and so on.
There is even the problem, that this "view" is allready printed in manuals and earlier software releases, so I can't simply switch.
If there is a way of disabling the tool but still letting it be visible I would be really glad.
The problem occurs now, that 2 Tools above a point sometimes makes it impossible to "click" the Point. The OnPointerClicked Event does not fire as I only reach the Tools.
Thanks in advance again
Posted: Thu May 15, 2008 8:46 am
by yeray
Hi ChZiegelt,
If you want to continue using your cursor tools to update the state of each point, I suggest you to use a table to store the state of each point (in order to allow more than one point to stay in the same state). And update this table at OnChartTool change event. Note that in the following example I use the labels list as states table.
Then I use two global variables. One to choose which tool (or state) is going to be moved (or set) and the other to choose which the series point.
And after assigning them to the desired values, you should call the previous mentioned event in order to update the states table and you could do this, for example, moving the cursor tool to the point.
And finally, I draw the state identifier lines in OnAfterDraw event because I have all the states saved and they don't depend on Cursor tools position or activation/deactivation.
Code: Select all
var
Form1: TForm1;
ActualIndex: Integer;
ActualTool: Integer;
...
procedure TForm1.ChartTool1Change(Sender: TCursorTool; x, y: Integer;
const XValue, YValue: Double; Series: TChartSeries; ValueIndex: Integer);
begin
if ActualIndex <> -1 then
begin
if Sender=ChartTool1 then
Series1.Labels[ActualIndex]:='A';
if Sender=ChartTool2 then
Series1.Labels[ActualIndex]:='B';
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
ChartTool1.ScopeStyle := scsEmpty;
ChartTool1.Style := cssScopeOnly;
ChartTool1.FollowMouse := false;
ChartTool2.ScopeStyle := scsEmpty;
ChartTool2.Style := cssScopeOnly;
ChartTool2.FollowMouse := false;
ChartTool1.Active:=false;
ChartTool2.Active:=false;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ActualTool := 1;
ActualIndex := 8;
(Chart1.Tools.Items[ActualTool-1] as TCursorTool).XValue := Series1.XValue[ActualIndex];
(Chart1.Tools.Items[ActualTool-1] as TCursorTool).YValue := Series1.YValue[ActualIndex];
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
ActualTool := 2;
ActualIndex := 5;
(Chart1.Tools.Items[ActualTool-1] as TCursorTool).XValue := Series1.XValue[ActualIndex];
(Chart1.Tools.Items[ActualTool-1] as TCursorTool).YValue := Series1.YValue[ActualIndex];
end;
procedure TForm1.Chart1AfterDraw(Sender: TObject);
var i, xpixels, ypixels: Integer;
begin
for i:=0 to Chart1[0].Count -1 do
begin
if Chart1[0].Labels[i] = 'A' then
begin
xpixels := Chart1.Axes.Bottom.CalcXPosValue(Chart1[0].XValue[i]);
ypixels := Chart1.Axes.Left.CalcYPosValue(Chart1[0].YValue[i]);
Chart1.Canvas.Pen.Color := clRed;
Chart1.Canvas.Line(xpixels-10,ypixels,xpixels+10,ypixels);
Chart1.Canvas.Line(xpixels,ypixels-10,xpixels,ypixels+10);
end;
if Chart1[0].Labels[i] = 'B' then
begin
xpixels := Chart1.Axes.Bottom.CalcXPosValue(Chart1[0].XValue[i]);
ypixels := Chart1.Axes.Left.CalcYPosValue(Chart1[0].YValue[i]);
Chart1.Canvas.Pen.Color := clWhite;
Chart1.Canvas.Line(xpixels-10,ypixels,xpixels+10,ypixels);
Chart1.Canvas.Line(xpixels,ypixels-10,xpixels,ypixels+10);
end;
end;
end;
Posted: Thu May 15, 2008 10:27 am
by 10546441
The first question is:
where do I find cssScopeOnly ?
I cant find the declaration.
Posted: Thu May 15, 2008 11:12 am
by yeray
Hi ChZiegelt,
This property should work if you are using TeeChart v8 and TeeTools unit is included in your project. Nevertheless, since we are going to deactivate the cursor tools, you could simply delete these lines from FormCreate:
Code: Select all
ChartTool1.ScopeStyle := scsEmpty;
ChartTool1.Style := cssScopeOnly;
ChartTool1.FollowMouse := false;
ChartTool2.ScopeStyle := scsEmpty;
ChartTool2.Style := cssScopeOnly;
ChartTool2.FollowMouse := false;