I'm using TAreaSeries. How can I calculate the YValue on the drawn Line by a given XValue?
Example:
Point 1 in the Serie: X=1 Y=10
Point 2 in the Serie: X=3 Y=30
I'm geting the XValue=2 by the Cursortool(between two points). The result must be Y=20 if stairs:=false.
I've tried to calulate it myself, therefore I need the the Serie Values at the left and the right of the cursorposition.If tried it with 'GetCursorValueIndex',
but the function returns -1 sometimes.
TChart7.04 Get drawn YValue by known XValue
-
- Site Admin
- Posts: 14730
- Joined: Mon Jun 09, 2003 4:00 am
- Location: Banyoles, Catalonia
- Contact:
Hi Achim,
If you're using a TCursorTool you can do something like:
If you're using a TCursorTool you can do something like:
Code: Select all
procedure TForm1.ChartTool1Change(Sender: TCursorTool; x, y: Integer;
const XValue, YValue: Double; Series: TChartSeries; ValueIndex: Integer);
begin
if (Series1.Clicked(X,Y)<>-1) then
Chart1.Title.Text.Text:=FloatToStr(Series.YValues[Series.Clicked(X,Y)]);
end;
Best Regards,
Narcís Calvet / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
Instructions - How to post in this forum |
Unfortunately 'Clicked' dosen't work, too.'Clicked' needs to hit the line _exactly_, but I need the point of intersection between the vertical line of the cursortool and the line of the series.narcis wrote:Hi,
Code: Select all
procedure TForm1.ChartTool1Change(Sender: TCursorTool; x, y: Integer; const XValue, YValue: Double; Series: TChartSeries; ValueIndex: Integer); begin if (Series1.Clicked(X,Y)<>-1) then Chart1.Title.Text.Text:=FloatToStr(Series.YValues[Series.Clicked(X,Y)]); end;
The reason is, I want to use two Charts, both with identical x-axis,
but different y-axis. Therefore I want to use two cursortools and
synchronize them by time. If the user move the cursor to a point at time X in Chart1, I want to show the YValue of the series in Chart2 at the choosen time X.
Here is sample code for the 'clicked' behavior:
Use a Form,TChart,Lineseries and cusortool.
Code: Select all
procedure TForm6.FormShow(Sender: TObject);
var
i:integer;
begin
ChartTool1.FollowMouse:=true;
ChartTool1.Style:=cssVertical;
ChartTool1.ClickTolerance:=100; // dosen't work
for i:= 0 to 59 do
begin
Series1.AddXY(i,i);
end;
end;
procedure TForm6.ChartTool1Change(Sender: TCursorTool; x, y: Integer;
const XValue, YValue: Double; Series: TChartSeries; ValueIndex: Integer);
var
Index:integer;
begin
Index:=Series1.Clicked(x,y);
Chart1.Title.Text[0]:=IntToStr(Index);
end;
-
- Site Admin
- Posts: 14730
- Joined: Mon Jun 09, 2003 4:00 am
- Location: Banyoles, Catalonia
- Contact:
Hi Achim,
Ah, ok, now I've understood what you want to do. Replacing your ChartTool1Change implementation for the code below should do.
Ah, ok, now I've understood what you want to do. Replacing your ChartTool1Change implementation for the code below should do.
Code: Select all
procedure TForm1.ChartTool1Change(Sender: TCursorTool; x, y: Integer;
const XValue, YValue: Double; Series: TChartSeries; ValueIndex: Integer);
begin
Chart1.Title.Text.Text:=FormatFloat('#.00',YValue);
end;
Best Regards,
Narcís Calvet / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
Instructions - How to post in this forum |
Hi Narcís,narcis wrote:Code: Select all
procedure TForm1.ChartTool1Change(Sender: TCursorTool; x, y: Integer; const XValue, YValue: Double; Series: TChartSeries; ValueIndex: Integer); begin Chart1.Title.Text.Text:=FormatFloat('#.00',YValue); end;
Code like this, I've tried first. But the YValue is the value of the mouse cursor, not the Value of the series line crossing by the vertical Cursortool line.
But I think, I have a solution. For everyone how has the same problem, here is it :
first some math:
X1,Y1 is a point on the line at the left side of XValue
X2,Y2 is a point on the line at the right side of XValue
YValue=m*XValue + b
with m=(y2-y1)/(x2-x1) and b=y1-m*x1
YValue=(XValue-x1)*(y2-y1)/(x2-x1)+y1
Code: Select all
procedure TForm6.FormShow(Sender: TObject);
var
i:integer;
begin
ChartTool1.FollowMouse:=true;
ChartTool1.Style:=cssVertical;
for i:= 0 to 59 do
begin
Series1.AddXY(i,i);
end;
end;
procedure TForm6.ChartTool1Change(Sender: TCursorTool; x, y: Integer;
const XValue, YValue: Double; Series: TChartSeries; ValueIndex: Integer);
Var
j:integer;
LeftIndex,RightIndex:integer;
found:boolean;
X1,X2:double;
Y1,Y2:double;
YV:double;
begin
if Series1.FirstValueIndex > 0 then
LeftIndex:=Series1.FirstValueIndex - 1 // FirstValueIndex is inside of the Chart
else
LeftIndex:=0;
RightIndex:=Series1.LastValueIndex; // LastValueIndex is outside of the chart
// search x1,x2,y1,y2
found:=false;
for j:= LeftIndex to RightIndex -1 do
begin
if (XValue >= Series1.XValue[j]) and
(XValue <= Series1.XValue[j+1]) then
begin
X1:=Series1.XValue[j];
Y1:=Series1.YValue[j];
X2:=Series1.XValue[j+1];
Y2:=Series1.YValue[j+1];
found:=true;
break;
end;
end;
// calculate
if found and (X2 <> X1) then
begin
YV:=(XValue-X1)*(Y2-Y1)/(X2-X1)+Y1; // YV is the result
Chart1.Title.Text.Text:=FloatToStrF(YV,ffFixed,5,2);
end;
end;