Page 1 of 1
"Clicked' method of a TLineSeries created dynamically
Posted: Mon Mar 23, 2009 11:30 pm
by 10045871
I want to click on a TLineSeries which is created dynamically (during runtime) in order to check its data and properties.
For a TLineSeries created in design time, I know how to do it, but for the runtime case, I don't know how to link the event to the TLinesSeries.
Could you provide an example about doing this ?
Thanking you in advance.
Patrick
Posted: Tue Mar 24, 2009 10:26 am
by yeray
Hi Patrick,
Here is an example:
Code: Select all
private
{ Private declarations }
procedure OnClickLine(Sender: TChartSeries; ValueIndex: Integer;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
//...
procedure TForm1.FormCreate(Sender: TObject);
var lineSeries: TLineSeries;
begin
lineSeries := TLineSeries.Create(nil);
Chart1.AddSeries(lineSeries);
lineSeries.FillSampleValues(25);
lineSeries.OnClick := OnClickLine;
end;
procedure TForm1.OnClickLine(Sender: TChartSeries; ValueIndex: Integer;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
Caption := 'Line clicked!!!';
end;
Thank you
Posted: Tue Mar 24, 2009 5:05 pm
by 10045871
Great. Thank you so much for your fast reply.
Patrick
How to know a line is clicked ?
Posted: Wed Mar 25, 2009 9:23 am
by 10045871
In the above example, you create a single procedure OnClickLine and assign the OnClick event of the dynamically created Line to that procedure. My difficulty is if I create many lines, always dynamically, and assign their OnClick events to a single OnClickLine procedure, and I want to click to select a line among others, I couldn't be able to process the line clicked, because I don't know what line is clicked.
If the clicked line has a "clicked" property, this will be fine. But I don't see such a property.
Would you have any solution ?
Thanking you in advance.
Patrick
Posted: Wed Mar 25, 2009 9:50 am
by yeray
Hi Patrick,
What TeeChart version are you using? In v8 there is a clicked method for series that returns -1 if the series hasn't been clicked and the order in the series' value list of the point clicked.
Also, why do you need the series' index in the clicked event when you have the series? You could assign the same event to all your series and when one of them is clicked,
Sender in OnClickLine procedure is the series.
Anyway if you want to retrieve the index of the clicked line, here is another example:
Code: Select all
procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
for i:=0 to 10 do
begin
Chart1.AddSeries(TLineSeries.Create(nil));
Chart1[i].FillSampleValues(25);
Chart1[i].OnClick := OnClickLine;
end;
end;
procedure TForm1.OnClickLine(Sender: TChartSeries; ValueIndex: Integer;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
Caption := 'Line ' + inttostr(Chart1.SeriesList.IndexOf(Sender)) + ' clicked!!! ';
end;
Thank you
Posted: Wed Mar 25, 2009 12:01 pm
by 10045871
This works quite well. Thank you for your support.
Problem with CalcPosPoint
Posted: Wed Dec 21, 2011 11:14 pm
by 10045871
Hello,
I create a curve with the following commands:
SPKT_Ch0_curve:= TFastLineSeries.Create(nil);
SPKT_Ch0_curve.title:='SPKT channel 0'; SPKT_Ch0_curve.color:= SPKT_Ch0_color.brush.color;
SPKT_Ch0_curve.OnClick := SPKT_Chart_OnClickLine;
SPKT_Ch0_curve.FillSampleValues(SPKT_curve_length.value);
SPKT_Chart.AddSeries(SPKT_Ch0_curve);
then make running curve:
with SPKT_Ch0_curve do begin
tmpTch:=XValues[1]-XValues[0];
if (Count>SPKT_curve_length.value) then repeat Delete(count-1) until count<= SPKT_curve_length.value;
AddXY(XValues.First-tmpTch,SPKT_ADCin_V[0]); // SPKT_ADCin_V[0]: input from an analog to digital converter
end;
then make time measurement by clicking on the graphic:
procedure TImpedance.SPKT_ChartMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
SPKT_chart.Canvas.pen.color:= clRed;
SPKT_chart.Canvas.pen.mode:= pmCopy;
SPKT_chart.Canvas.brush.color:= clNone;
if SPKT_CursorsOn.tag=1 then begin // enable cursors
if SPKT_Chart_clickcount=0 then begin
SPKT_cursor1.X:= X; SPKT_cursor1.Y:= Y;
SPKT_cursor1.Xvalue:= SPKT_chart.BottomAxis.CalcPosPoint(X);
SPKT_cursor1.Yvalue:= SPKT_chart.LeftAxis.CalcPosPoint(Y);
SPKT_cursor1.plotted:= true;
end else if SPKT_Chart_clickcount=1 then begin
SPKT_cursor2.X:= X; SPKT_cursor2.Y:= Y;
SPKT_cursor2.Xvalue:= SPKT_chart.BottomAxis.CalcPosPoint(X);
SPKT_cursor2.Yvalue:= SPKT_chart.LeftAxis.CalcPosPoint(Y);
SPKT_cursor2.plotted:= true;
// plot rectangle
if SPKT_Chart_clickcount=1 then begin
SPKT_chart.Canvas.MoveTo(SPKT_cursor1.X,SPKT_cursor1.Y);
SPKT_chart.Canvas.lineto(SPKT_cursor2.X,SPKT_cursor1.Y);
SPKT_chart.Canvas.lineto(SPKT_cursor2.X,SPKT_cursor2.Y);
SPKT_chart.Canvas.lineto(SPKT_cursor1.X,SPKT_cursor2.Y);
SPKT_chart.Canvas.lineto(SPKT_cursor1.X,SPKT_cursor1.Y);
end;
if SPKT_zoom_zone.checked then begin
SPKT_Chart.leftaxis.automatic:= false; SPKT_autoaxis.checked:= SPKT_Chart.leftaxis.automatic;
SPKT_chart.leftaxis.minimum:= SPKT_cursor2.Yvalue;
SPKT_chart.leftaxis.maximum:= SPKT_cursor1.Yvalue;
end;
end;
end else begin // clear cursors
end;
end;
I use the procedure above for measuring the time between 2 clicked points on the graphic.
The problem is Xvalue:= SPKT_chart.BottomAxis.CalcPosPoint(X) does not indicate the order of the data points. I had to divide the difference between 2 differents Xvalues by 50 in order to obtain the exact difference in number of points.
Later, I tried to load new data on the Chart with these commands:
If OpenDialog1.Execute then begin
AssignFile(SPKT_readbck_file,OpenDialog1.filename);
Reset(SPKT_readbck_file);
SPKT_Ch0_curve.clear;
while not(eof(SPKT_readbck_file)) do begin
readln(SPKT_readbck_file,v0);
SPKT_Ch0_curve.AddY(v0);
end;
CloseFile(SPKT_readbck_file);
end; // end of browse file
This time, the ratio between the Xvalue given by the BottomAxis.CalcPosPoint(X) method is still different befor (ratio is no longer 50), so that time measurement is quite false.
Would you advice a method to obtain good values of the clicked points using CalcPosPoint(X) ?
Thank you in advance
Patrick
Sciensoria
email :
info@sciensoria.fr
21/12/2011
Re: "Clicked' method of a TLineSeries created dynamically
Posted: Thu Dec 22, 2011 4:25 pm
by yeray
Hi Patrick,
There are some variables in your code snipped I can't know their values so I cannot run that code. However, I think I understand what you are doing. The following code does something similar:
Code: Select all
uses Series;
type
MyPoint = class
X, Y: Integer;
XValue, YValue: Double;
end;
var P1, P2: MyPoint;
isFirst: Boolean;
procedure TForm1.FormCreate(Sender: TObject);
begin
Chart1.View3D:=false;
Chart1.AddSeries(TFastLineSeries).FillSampleValues();
isFirst:=true;
P1:=MyPoint.Create;
P2:=MyPoint.Create;
end;
procedure TForm1.Chart1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var XDiff: Double;
begin
if isFirst then
begin
P1.X:=X;
P1.Y:=Y;
P1.XValue:=Chart1.Axes.Bottom.CalcPosPoint(X);
P1.YValue:=Chart1.Axes.Left.CalcPosPoint(Y);
Caption:='P1.X: ' + IntToStr(P1.X) + ', P1.Y: ' + IntToStr(P1.Y) + ', P1.XValue: ' + FormatFloat('#0.##', P1.XValue) + ', P1.YValue: ' + FormatFloat('#0.##', P1.YValue);
end
else
begin
P2.X:=X;
P2.Y:=Y;
P2.XValue:=Chart1.Axes.Bottom.CalcPosPoint(X);
P2.YValue:=Chart1.Axes.Left.CalcPosPoint(Y);
Caption:=Caption + ' - P2.X: ' + IntToStr(P2.X) + ', P2.Y: ' + IntToStr(P2.Y) + ', P2.XValue: ' + FormatFloat('#0.##', P2.XValue) + ', P2.YValue: ' + FormatFloat('#0.##', P2.YValue);
XDiff:=Abs(P1.XValue-P2.XValue);
Caption:=Caption + ' - XDiff: ' + FormatFloat('#0.##', XDiff)
end;
isFirst:=not isFirst;
end;
procedure TForm1.Button1Click(Sender: TObject);
var i: Integer;
diff: Double;
begin
with Chart1[0] do
for i:=0 to 25 do
begin
diff:=YValues.Range/10;
Add(YValue[Count-1] + random*(diff) - diff/2);
end;
end;
However, I'm not sure to understand this part:
Sciensoria wrote:The problem is Xvalue:= SPKT_chart.BottomAxis.CalcPosPoint(X) does not indicate the order of the data points. I had to divide the difference between 2 differents Xvalues by 50 in order to obtain the exact difference in number of points.
I'm not sure about why do you have to divide the difference by 50. You'll see in the example above the calculation of the difference looks correct, isn't it?
Even if you were working with DateTime in the XValues, they are actually doubles so the calculations should be the same, just the format function to output the result should vary.