Prepare
本文將使用一個NuGet公開的組件來實現曲線的顯示,包含了多種顯示的模式和配置來知足各類不一樣的應用場景,方便你們進行快速的開發系統。html
聯繫做者及加羣方式(激活碼在羣裏發放):http://www.hslcommunication.cn/Cooperationgit
在Visual Studio 中的NuGet管理器中能夠下載安裝,也能夠直接在NuGet控制檯輸入下面的指令安裝:github
Install-Package HslCommunication
NuGet安裝教程 http://www.cnblogs.com/dathlin/p/7705014.html數組
更強大的歷史曲線控件參考:http://www.javashuo.com/article/p-mjxsjqwi-db.html
Summary
曲線控件屬於組件裏諸多控件中的一種,爲何單獨拿出來寫一篇博客呢,就是由於曲線控件相對於其餘控件都要複雜不少,並非幾個屬性那麼簡單,下面列舉了本曲線控件的特性:緩存
- 提供便捷的API調用便可顯示曲線信息內容,不須要複雜的配置
- 曲線界面的一些信息能夠自由定製,好比座標軸的顏色,是否顯示虛線等等
- 高度的大小自適應,不管你怎麼調整控件的大小,始終都能友好顯示
- 支持數據拉伸填充和像素點填充兩種模式,具體區別參照下面的代碼
- 多曲線支持,支持同時顯示多個曲線信息,每一個曲線可獨立的指定顏色,線寬等等。
- 支持左右兩個參考系,就是說一個控件中容許顯示2種數據跨度不一致的曲線,每種曲線能夠顯示多條不一樣的曲線
其餘控件的說明地址:http://www.cnblogs.com/dathlin/p/8150516.htmldom
組件的完整API說明:http://www.cnblogs.com/dathlin/p/7703805.html工具
要想使用組件的控件,除了使用NuGet來安裝組件外,還須要將組件的dll文件(在你的項目的packages裏面能夠找到,若是你原本就是引用本地的,就直接拖拽本地的便可)拖拽到工具欄:oop
拖拽完成後效果以下:測試
先定義一個方法,獲取指定範圍的,指定個數的隨機數數組,供下方的代碼調用大數據
private float[] GetRandomValueByCount( int count, float min, float max ) { float[] data = new float[count]; for (int i = 0; i < data.Length; i++) { data[i] = (float)random.NextDouble( ) * (max - min) + min; } return data; }
1.單曲線使用
把控件拖拽到窗口界面上去後,如今界面以下,你能夠隨意的拉伸大小,調整到一個虛線看着比較清晰的時刻中止:
咱們看到左右縱軸的數據跨度都是0-100,如今咱們有個需求,手裏有300個0-200的數據須要顯示,那麼就要先設置左右縱軸的數據跨度
接下來就能夠編寫顯示的代碼了,一下數據隨機:
private void userButton1_Click( object sender, EventArgs e ) { userCurve1.SetLeftCurve( "A", GetRandomValueByCount( 300, 0, 200 ), Color.DodgerBlue ); }
顯示結果以下:
看吧,至關簡單方便,若是你以爲目前的數據太密了,想要寬鬆一點,但願數據拉伸滿整個X軸,沒問題,由於目前默認的模式是像素點模式,因此切換爲拉伸模式便可。
而後在運行看看效果:
接下來咱們要對曲線「A」進行數據更新,咱們假設你的data數組的數據已經更新了,有可能只更新了一個數據,有可能所有更新了,在數據更新的時候就不須要在指定顏色了,由於指定了顏色也沒有用了。
private void userButton3_Click( object sender, EventArgs e ) { // 假設你的data數組已經更新了 // 以前已經給A指定過顏色了,之後後續的數據更新不須要從新指定,指定了也無效 // 若是須要從新設置顏色,或是線寬,須要先RemoveCurve,而後從新建立曲線信息 userCurve1.SetLeftCurve( "A", GetRandomValueByCount( 300, 100, 200 ) ); }
從上面的數據更新咱們發現,只要更新了數據,就不停的調用數據顯示,那麼咱們就能夠顯示實時數據了,而惟一的麻煩之處在於咱們須要維護本身的data數組。因此當前的這種方式只適合靜態數據顯示
2.舉個經典的例子
當咱們須要顯示一些統計數據的時候,好比說我要顯示十二個月的銷售金額,那麼咱們應該怎麼寫
咱們先選擇拉伸模式,而後設置拉伸模式下最大的數據量爲12;
private void userButton9_Click( object sender, EventArgs e ) { // 模擬的數據 string[] text = new string[] { "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月" }; userCurve1.SetCurveText( text ); userCurve1.SetLeftCurve( "A", GetRandomValueByCount( 12, 0, 200 ), Color.Tomato ); // 每月用戶1的銷售金額 }
效果圖以下:
若是我有兩條曲線須要顯示,以方便對比的話:
private void userButton9_Click( object sender, EventArgs e ) { // 模擬的數據 string[] text = new string[] { "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月" }; userCurve1.SetCurveText( text ); userCurve1.SetLeftCurve( "A", GetRandomValueByCount( 12, 0, 200 ), Color.Tomato ); // 每月用戶1的銷售金額 userCurve1.SetLeftCurve( "B", GetRandomValueByCount( 12, 0, 200 ), Color.DodgerBlue ); // 每月用戶2的銷售金額 }
圖形效果以下:
即時3條曲線或者是更多的曲線,以此類推。重複設定數據便可,只是每條曲線的關鍵字須要區分開來。
控件支持移除曲線,主要包含了下面的兩個方法,移除單個的曲線,或者是移除全部的曲線。
userCurve1.RemoveCurve( "A" ); // 移除指定的曲線 userCurve1.RemoveAllCurve( ); // 移除全部的曲線
在上面設置曲線數據的時候發現,是經過調用 SetLeftCurve 方法來設置曲線信息的,這個方法有個left單詞,很明顯是設置左曲線的,控件裏還有設置右曲線的,SetLeftCurve 方法就是設置右曲線,那麼這裏的左右曲線都是指什麼呢?
咱們在上面的曲線控件上看到,縱軸的刻度線分左右兩邊,那麼設置左曲線就是以左邊的刻度線爲標準繪製的曲線,而設置右曲線則以右刻度線爲標準,在上圖中,左右刻度的信息是一致的,因此無所謂左曲線仍是右曲線,可是若是咱們設置不一致後,那麼咱們就能夠實現顯示2種不一樣範圍的數據信息,例如咱們右曲線設置爲0-10,再隨便顯示2條曲線
private void userButton9_Click( object sender, EventArgs e ) { // 模擬的數據 string[] text = new string[] { "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月" }; userCurve1.SetCurveText( text ); userCurve1.SetLeftCurve( "A", GetRandomValueByCount( 12, 0, 200 ), Color.Tomato ); // 每月用戶1的銷售金額 userCurve1.SetLeftCurve( "B", GetRandomValueByCount( 12, 0, 200 ), Color.DodgerBlue ); // 每月用戶2的銷售金額 userCurve1.SetRightCurve( "C", GetRandomValueByCount( 12, 3, 6 ), Color.LimeGreen ); userCurve1.SetRightCurve( "D", GetRandomValueByCount( 12, 3, 6 ), Color.Orchid ); }
效果圖以下:
高級使用舉例,動態座標軸,
根據上面的狀況,咱們看到若是咱們獲取到的一組數據,範圍不肯定的,須要來動態調整的,好比咱們有一個12個數據的float數組,咱們設置左座標軸爲數據的上下限
private void userButton10_Click( object sender, EventArgs e ) { // 模擬的數據 string[] text = new string[] { "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月" }; float[] data = GetRandomValueByCount( 12, 40, 150 ); userCurve1.ValueMaxLeft = (float)Math.Ceiling( data.Max( ) );// 向上取整 userCurve1.ValueMinLeft = (float)Math.Floor( data.Min( ) );// 向下取整 userCurve1.SetCurveText( text ); userCurve1.SetLeftCurve( "A", data, Color.Tomato ); // 每月用戶1的銷售金額 }
效果圖以下:
能夠看到,不停的刷新數據後,左座標軸的數據一直在更新中。
總結下:若是每次都是強行更新全部的數據,也能達到實時刷新的效果,可是若是是一個數據一個數據的採集顯示,將按照下面的實時數據模式使用更加合理
3.實時數據顯示使用
當咱們須要顯示一些實時數據時,也就是說,每隔1秒(隨便舉個栗子)就有新的數據採集上來,而後追加到曲線中去,曲線進行挪動,一般就是這種狀況。
3.1 像素點模式(請確認 IsAbscissaStrech 爲False):
咱們先講解默認的模式,所謂像素點模式是指在橫軸上,一個像素點顯示一個數據,若是你的橫軸像素長度爲1000,那麼你就能夠顯示1000個數據了,固然在實時顯示的狀況下,不須要你管那麼多,你只須要負責按期往裏面塞數據便可。
第一步先進行初始化:先增長指定名字的曲線信息,曲線顏色,曲線寬度等等
private void userButton4_Click( object sender, EventArgs e ) { // 這裏傳入了數組長度爲空的數據,不能傳NULL userCurve1.SetLeftCurve( "B", new float[] { }, Color.Tomato ); }
咱們再寫一個按鈕,啓動定時器,去新增數據,來模擬咱們從其餘設備讀取到的數據信息:
private void userButton5_Click( object sender, EventArgs e ) { Timer timer = new Timer( ); timer.Interval = 100; timer.Tick += ( sender1, e1 ) => { userCurve1.AddCurveData( "B", random.Next( 50, 201 ) ); }; timer.Start( ); }
如上面的兩個按鈕信息,必須先點擊按鈕4進行曲線初始化,按鈕5的點擊纔有效果。最終你會看到曲線每隔100ms刷新一次,不停的有新的數據遞增。
當曲線數量超過當前可顯示的點數時,曲線會自動的往左挪動,即時你拉伸的整個控件,它依然能夠正常的工做,可顯示的數據點數會自動更新,內存中會緩存2048個數據點來支持拉伸的效果轉換。
固然,它也支持一次更新多個數據,雖然這種狀況不多,只是須要注意的是,一次更新的數據必須少於2048。
userCurve1.AddCurveData( "B", new float[] { random.Next( 50, 201 ), random.Next( 50, 201 ), random.Next( 50, 201 ) } );
2.2 拉伸模式(請確認 IsAbscissaStrech 爲True):
拉伸模式的意思是不管你的data數組有多少個點,都強行按照最大數據點拉伸完整個橫軸界面
先設置 StrechDataCountMax 屬性爲 300 ,意思是強行顯示300個點,最大300個點,僅僅在拉伸模式下有效果
private void userButton4_Click( object sender, EventArgs e ) { // 這裏傳入了數組長度爲空的數據,不能傳NULL userCurve1.SetLeftCurve( "B", new float[] { }, Color.Tomato); // 指定上限500個數據,該上限只對拉伸模式有效 } private void userButton5_Click( object sender, EventArgs e ) { Timer timer = new Timer( ); timer.Interval = 100; timer.Tick += ( sender1, e1 ) => { userCurve1.AddCurveData( "B", random.Next( 50, 201 ) ); }; timer.Start( ); }
咱們再看拉伸模式的曲線:
你再拉伸控件試試看?拉伸模式的意思是不管你的控件多少大小,你規定了300個點,它就是300個點,即便你的控件拉伸了,它仍是300個點,只是沒有那麼密罷了
至於一次增長多個數據是和上面的像素點模式是一致的。
2.3 模式區別及選擇
像素點模式下,隨便看着數據比較密,可是好處在於分辨率高的顯示器,能夠顯示的數據更多。
拉伸模式雖然在控件拉伸的狀況下顯示的數據量不會增加,可是能夠控制疏密程度。
各有優劣,建議先使用像素點模式,看看效果怎麼樣,通常數據變化都是慢慢來的,因此曲線不會像測試數據那樣亂串。若是數據亂串比較厲害,再使用拉伸模式。
3.多曲線,雙座標使用
多曲線和單曲線模式很類似,無非是多幾條曲線而已,每條曲線的操做,新增數據都是如出一轍的,只是多曲線的模式都是統一的,要麼所有是像素點模式,要麼所有是拉伸模式,全部的特性和上兩節是類似的。
爲了說明使用,舉個例子,你有多個設備(2個及以上),每一個設備都有一個溫度信息,如今要進行實時數據的直接對比,固然最好將三條曲線放到一塊兒顯示。
咱們命名三個曲線爲「A」,「B」,「C」 而後假設全部的數據都是100-200之間,數據A是160-180隨機,數據B是150-170隨機,數據C是155-165隨機
此處測試方便,使用了 像素點模式。在 拉伸模式 下代碼也是一致的
咱們接下來看一種至關複雜的使用場景,假設咱們有一臺設備,須要監控4條曲線,2條溫度,2條壓力,溫度的範圍是0-200,壓力的範圍爲0-5 mpa,那麼想要在一個控件裏顯示,也是能夠實現的。先調整左右的座標範圍。
此處仍然使用像素點模式,咱們接下來寫初始化代碼和新增數據的代碼:
private void userButton4_Click( object sender, EventArgs e ) { userCurve1.SetLeftCurve( "A", new float[] { }, Color.Tomato ); // 溫度1 userCurve1.SetLeftCurve( "B", new float[] { }, Color.DodgerBlue ); // 溫度2 userCurve1.SetRightCurve( "C", new float[] { }, Color.LimeGreen ); // 壓力1 userCurve1.SetRightCurve( "D", new float[] { }, Color.Purple ); // 壓力2 } private void userButton5_Click( object sender, EventArgs e ) { Timer timer = new Timer( ); timer.Interval = 100; timer.Tick += ( sender1, e1 ) => { userCurve1.AddCurveData( new string[] { "A", "B", "C", "D" }, new float[] { random.Next( 160, 181 ), random.Next( 150, 171 ), (float)random.NextDouble( ) * 2.5f + 1, (float)random.NextDouble( ) * 1f } ); }; timer.Start( ); }
效果以下圖:
4.橫座標文本格式調整
上述的實時曲線在顯示的時候,咱們看到橫座標的文本是小時加分鐘的模式,若是咱們改爲只顯示分鐘和秒鐘怎麼辦
這個屬性就是DateTime的格式化字符串,理論上你能夠獲取到任務時間相關的文本信息,按照當前的需求,調整成 mm:ss 便可
5.輔助線添加
我想在實時數據顯示中設置一條曲線數據的報警上限的輔助線,用來提醒以及更加相當的查看信息,是否異常,能夠調用控件的方法來完成
新增的輔助線是左右兩個參考座標系區分出來了,好比我新增左輔助線,192的一條線,顏色爲紅色
userCurve1.AddLeftAuxiliary( 192, Color.Red);
移除的代碼爲
userCurve1.RemoveAuxiliary( 192 );
輔助線效果以下:
若是你新增的輔助線和原有的虛線重疊時,原有的虛線會自動屏蔽掉。
6.背景顏色調整
我修改下背景爲暗黑色,瞬間就有黑科技的效果了。固然,線條的顏色能夠調整的更加好一點
4.結束語
感謝閱讀。