關於Tchart滑鼠座標取得 |
答題得分者是:st33chen
|
windheartalan
一般會員 發表:21 回覆:23 積分:8 註冊:2005-03-24 發送簡訊給我 |
各位先進,又有問題想請教各位,
現在已知在MouseMove可以取得滑鼠座標x,y(非指座標軸之x,y), 問題來了,假設chart中有一條線(series),我想要知道, 我依照目前滑鼠所點的位置劃一直線,與該條線相交那個點的座標(視窗座標,非chart座標軸), 該如何得知呢? 因為滑鼠的位置,並不一定會落在線上, 所以這麼做是希望,可以透過滑鼠的移動,自動畫直線對應到該數列線上, 現在畫直線是ok,該數列的x,y座標值也可取得, 我想進一步於該數列x,y座標軸出畫出橫線,即針對直線與數列交會點處劃橫線,使得數列上該點呈現十字狀. 但這是需要知道該點視窗座標位置的, 想請問各位先進,有無什麼method,可以取得視窗座標值,或是說有什麼其他的做法可以指教,感恩. |
st33chen
尊榮會員 發表:15 回覆:591 積分:1201 註冊:2005-09-30 發送簡訊給我 |
|
windheartalan
一般會員 發表:21 回覆:23 積分:8 註冊:2005-03-24 發送簡訊給我 |
感謝st33chen 大大的回覆,我知道mouseover 事件可取得 x, y,但這只是A點, A點未必會落在series的線上,所以我是要根據x座標畫直線之後,取得該直線與series曲線交會的B點座標, B點的x,y座標軸值我知道,但無法取得B點視窗的座標位置(x座標一樣,但y座標不同) 目的是在取得B的Y座標後,劃一橫線,在B點處形成十字線的展現, 不知這樣敘述,能否了解我的問題所在,再煩請指導,感恩. ===================引 用 st33chen 文 章=================== 您好,
chart 元件的 mouseover 事件的 x, y 不就是您所要的嗎? (若要得到 form 的 mouse 座標, 分別加 chart 元件的 left, top) 不知是否切題 ? |
st33chen
尊榮會員 發表:15 回覆:591 積分:1201 註冊:2005-09-30 發送簡訊給我 |
了解了, 很有趣的問題, 我再想想或找找 不過, 現在想到的是笨方法 : 由 mouse 的 x 值可以換算出該點是落在哪兩個數點的中間 再用中學所教的一個線段已知 x 求線段上 y 值的方法算出來 (忘了是不是叫作 插補法 差補法) ============================================ 找到一個嫌疑犯 : chart1.Series[0].CalcYPosvalue( mouse x 值換成 line 的 x 值); 對不起, 好像也不是 ============================================== 您可以在 editing chart 的左下角的 help 中找到 Calculating Co-ordinates 這一段 好像答案在裏面 ================================================== 終於測好答案了 : 終究還是要用 已知 x 求線段上 y 值的方法 : unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, TeEngine, Series, StdCtrls, ExtCtrls, TeeProcs, Chart; type TForm1 = class(TForm) Chart1: TChart; Button1: TButton; Series1: TLineSeries; Label1: TLabel; Label2: TLabel; Label5: TLabel; Label6: TLabel; Label7: TLabel; Label8: TLabel; Label9: TLabel; Label3: TLabel; Label4: TLabel; Label10: TLabel; Label11: TLabel; procedure Button1Click(Sender: TObject); procedure Chart1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); private { Private declarations } public { Public declarations } end; var Form1: TForm1; chartx, charty : integer; x0, x2, y0, y2 : double; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin chart1.Series[0].AddXY(10,10); chart1.Series[0].AddXY(20,40); chart1.Series[0].AddXY(30,20); chart1.Series[0].AddXY(40,10); chart1.Series[0].AddXY(50,40); chart1.Series[0].AddXY(60,20); chart1.Refresh; x0 := chart1.Series[0].MinXValue; x2 := chart1.Series[0].maxxvalue; y0 := chart1.Series[0].MinYValue; y2 := chart1.Series[0].MaxYValue; end; procedure TForm1.Chart1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var xval, yval, yval2, yval3 : real; ii : integer; begin label1.Caption := inttostr(x); label2.Caption := inttostr(y); if x2 < > x0 then begin xval := chart1.Series[0].xScreenToValue(x); for ii:=1 to chart1.Series[0].Count-1 do begin if xval < c h a r t 1 . S e r i e s [ 0 ] . x V a l u e [ i i ] t h e n b e g i n x0 := chart1.Series[0].XValue[ii-1]; x2 := chart1.Series[0].XValue[ii]; y0 := chart1.Series[0].yValue[ii-1]; y2 := chart1.Series[0].yValue[ii]; if y2>y0 then yval := (xval-x0)/(x2-x0)*(y2-y0) y0 else begin yval := (x2-xval)/(x2-x0)*(y0-y2) y2; end; break; end; end; // mouse 所在的 圖的 x 值 label5.caption := floattostr(xval); // 由 xval 算出來的 線上 的 y 值 label6.Caption := floattostr(yval); // mouse 在 圖中的 y 值, 如果把 mouse 移到線上, 值應和 label6 非常接近 label8.caption := floattostr(chart1.Series[0].yScreenToValue(y)); // 答案 label7.Caption := floattostr(chart1.Series[0].CalcYSizeValue(yval)); end; end; end.
------
IS IT WHAT IT IS 我是 李慕白 請倒著唸. 又想把老話拿出來說, 請用台語發音 : 專家專家全是ROBOT CAR (滷肉腳啦); 都已接手這麼久了, 績效還是那麼爛, 講話還那麼大聲.
編輯記錄
st33chen 重新編輯於 2008-12-11 18:42:58, 註解 無‧
st33chen 重新編輯於 2008-12-11 18:46:04, 註解 無‧ st33chen 重新編輯於 2008-12-11 18:56:31, 註解 無‧ st33chen 重新編輯於 2008-12-11 23:27:08, 註解 無‧ st33chen 重新編輯於 2008-12-11 23:28:14, 註解 無‧ st33chen 重新編輯於 2008-12-11 23:29:49, 註解 無‧ st33chen 重新編輯於 2008-12-11 23:32:21, 註解 無‧ st33chen 重新編輯於 2008-12-11 23:34:53, 註解 無‧ |
windheartalan
一般會員 發表:21 回覆:23 積分:8 註冊:2005-03-24 發送簡訊給我 |
十分感謝您~ 相當的用心回覆,
的確,大大所說的兩種方法都可以, CalcYPosvalue也是可以的,他是把value轉換成座標的樣子, 我昨天後來有從tchart的範例程式其中一個form找到一些方向, 再加上大大所說,測試後,兩種方法都可以達到我要的效果,再次謝謝您~ ===================引 用 st33chen 文 章=================== 了解了, 很有趣的問題, 我再想想或找找 不過, 現在想到的是笨方法 : 由 mouse 的 x 值可以換算出該點是落在哪兩個數點的中間 再用中學所教的一個線段已知 x 求線段上 y 值的方法算出來 (忘了是不是叫作 插補法 差補法) ============================================ 找到一個嫌疑犯 : chart1.Series[0].CalcYPosvalue( mouse x 值換成 line 的 x 值); 對不起, 好像也不是 ============================================== 您可以在 editing chart 的左下角的 help 中找到 Calculating Co-ordinates 這一段 好像答案在裏面 ================================================== 終於測好答案了 : 終究還是要用 已知 x 求線段上 y 值的方法 : unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, TeEngine, Series, StdCtrls, ExtCtrls, TeeProcs, Chart; type TForm1 = class(TForm) Chart1: TChart; Button1: TButton; Series1: TLineSeries; Label1: TLabel; Label2: TLabel; Label5: TLabel; Label6: TLabel; Label7: TLabel; Label8: TLabel; Label9: TLabel; Label3: TLabel; Label4: TLabel; Label10: TLabel; Label11: TLabel; procedure Button1Click(Sender: TObject); procedure Chart1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); private { Private declarations } public { Public declarations } end; var Form1: TForm1; chartx, charty : integer; x0, x2, y0, y2 : double; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin chart1.Series[0].AddXY(10,10); chart1.Series[0].AddXY(20,40); chart1.Series[0].AddXY(30,20); chart1.Series[0].AddXY(40,10); chart1.Series[0].AddXY(50,40); chart1.Series[0].AddXY(60,20); chart1.Refresh; x0 := chart1.Series[0].MinXValue; x2 := chart1.Series[0].maxxvalue; y0 := chart1.Series[0].MinYValue; y2 := chart1.Series[0].MaxYValue; end; procedure TForm1.Chart1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var xval, yval, yval2, yval3 : real; ii : integer; begin label1.Caption := inttostr(x); label2.Caption := inttostr(y); if x2 < > x0 then begin xval := chart1.Series[0].xScreenToValue(x); for ii:=1 to chart1.Series[0].Count-1 do begin if xval < c h a r t 1 . S e r i e s [ 0 ] . x V a l u e [ i i ] t h e n b e g i n x0 := chart1.Series[0].XValue[ii-1]; x2 := chart1.Series[0].XValue[ii]; y0 := chart1.Series[0].yValue[ii-1]; y2 := chart1.Series[0].yValue[ii]; if y2>y0 then yval := (xval-x0)/(x2-x0)*(y2-y0) y0 else begin yval := (x2-xval)/(x2-x0)*(y0-y2) y2; end; break; end; end; // mouse 所在的 圖的 x 值 label5.caption := floattostr(xval); // 由 xval 算出來的 線上 的 y 值 label6.Caption := floattostr(yval); // mouse 在 圖中的 y 值, 如果把 mouse 移到線上, 值應和 label6 非常接近 label8.caption := floattostr(chart1.Series[0].yScreenToValue(y)); // 答案 label7.Caption := floattostr(chart1.Series[0].CalcYSizeValue(yval)); end; end; end.
|
st33chen
尊榮會員 發表:15 回覆:591 積分:1201 註冊:2005-09-30 發送簡訊給我 |
可以 show 一下 大大您的作法 嗎?
謝謝 我另一個想法是 固定 x, 用一個 loop 去改變 y 直到 碰壁 或 點的顏色等於線的顏色 這樣就不必套公式去算 不過後來沒試 ====================================================== 2008-10-15 謝謝您, 我了解您我解法的差別了.
------
IS IT WHAT IT IS 我是 李慕白 請倒著唸. 又想把老話拿出來說, 請用台語發音 : 專家專家全是ROBOT CAR (滷肉腳啦); 都已接手這麼久了, 績效還是那麼爛, 講話還那麼大聲. |
windheartalan
一般會員 發表:21 回覆:23 積分:8 註冊:2005-03-24 發送簡訊給我 |
大大您好,
程式改了很多次,您說的插補法的部份,後來已經沒有留,感覺比較複雜, 後來直接利用現有的method來做處理,大概內容如下, //先取得滑鼠所在座標軸位置x1,y1 TmpSeies := TChart(Sender).SeriesList.items[0]; TmpSeies.GetCursorValues(x1,y1); if x1 > 0 then begin //該座標值含小數,截取x1整數部份 ipos := pos('.',FloatToStr(x1))-1; if ipos = -1 then begin i:= StrToint(FloatToStr(x1)); end else begin i:= StrToint(copy(FloatToStr(x1),1,ipos)); end; //由x1值,取得該點對應的y軸value值 yvalue := TChart(Sender).SeriesList.Items[0].Yvalue[i]; //透過y軸value值,取得y軸座標位置 YPosition:=chart1.LeftAxis.CalcYPosValue(yvalue); //區域內畫線 if (x1 > 0) and (x1 <=300) then begin Chart1.Canvas.Pen.color := clskyblue; //畫縱線 Chart1.Canvas.MoveTo(x,0); Chart1.Canvas.LineTo(x,Chart1.Height-10); //畫橫線 Chart1.Canvas.MoveTo(0,YPosition); Chart1.Canvas.LineTo(Chart1.Width-10,YPosition); end; end; ===================引 用 st33chen 文 章=================== 可以 show 一下 大大您的作法 嗎? 謝謝 我另一個想法是 固定 x, 用一個 loop 去改變 y 直到 碰壁 或 點的顏色等於線的顏色 這樣就不必套公式去算 不過後來沒試 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |