"Clicked' method of a TLineSeries created dynamically

TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
Post Reply
Sciensoria
Newbie
Newbie
Posts: 20
Joined: Tue Jul 03, 2007 12:00 am
Contact:

"Clicked' method of a TLineSeries created dynamically

Post by Sciensoria » Mon Mar 23, 2009 11:30 pm

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

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

Post by Yeray » Tue Mar 24, 2009 10:26 am

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;
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

Sciensoria
Newbie
Newbie
Posts: 20
Joined: Tue Jul 03, 2007 12:00 am
Contact:

Thank you

Post by Sciensoria » Tue Mar 24, 2009 5:05 pm

Great. Thank you so much for your fast reply.

Patrick

Sciensoria
Newbie
Newbie
Posts: 20
Joined: Tue Jul 03, 2007 12:00 am
Contact:

How to know a line is clicked ?

Post by Sciensoria » Wed Mar 25, 2009 9:23 am

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

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

Post by Yeray » Wed Mar 25, 2009 9:50 am

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;
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

Sciensoria
Newbie
Newbie
Posts: 20
Joined: Tue Jul 03, 2007 12:00 am
Contact:

Thank you

Post by Sciensoria » Wed Mar 25, 2009 12:01 pm

This works quite well. Thank you for your support.

Sciensoria
Newbie
Newbie
Posts: 20
Joined: Tue Jul 03, 2007 12:00 am
Contact:

Problem with CalcPosPoint

Post by Sciensoria » Wed Dec 21, 2011 11:14 pm

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

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

Re: "Clicked' method of a TLineSeries created dynamically

Post by Yeray » Thu Dec 22, 2011 4:25 pm

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.
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

Post Reply