C# 曲線控件 曲線繪製 實時曲線 多曲線控件 開發

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.結束語


感謝閱讀。

相關文章
相關標籤/搜索