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
"Clicked' method of a TLineSeries created dynamically
-
- Newbie
- Posts: 20
- Joined: Tue Jul 03, 2007 12:00 am
- Contact:
Hi Patrick,
Here is an example:
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;
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |
-
- Newbie
- Posts: 20
- Joined: Tue Jul 03, 2007 12:00 am
- Contact:
Thank you
Great. Thank you so much for your fast reply.
Patrick
Patrick
-
- Newbie
- Posts: 20
- Joined: Tue Jul 03, 2007 12:00 am
- Contact:
How to know a line is clicked ?
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
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
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:
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;
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |
-
- Newbie
- Posts: 20
- Joined: Tue Jul 03, 2007 12:00 am
- Contact:
Thank you
This works quite well. Thank you for your support.
-
- Newbie
- Posts: 20
- Joined: Tue Jul 03, 2007 12:00 am
- Contact:
Problem with CalcPosPoint
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
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
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:
However, I'm not sure to understand this part:
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.
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;
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?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.
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.
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |