Winform開發框架之數據曲線報表


在項目開發中,往往會碰到一些非常規的需求,每次碰到這種情況,都需要花費時間來整理自己的思路,然后參考網絡上其他人的實現方式或者作法,有時候可以找到一些相同的模塊進行改進即可符合需求,但往往很多是需要自己潛心研究,然后提煉優化,雖然探索過程還是比較開心,不過時間肯定是需要花不少的。我每次碰到這種情況,都會沉下心來,力求把這種的模塊做得更好一點,方便以后的重用,這樣每次抱着這樣的態度,着實積累了不少好的東西,也可以為后面的項目夯實基礎。

在一次Winform的項目開發過程中,客戶需要對一些體檢數據等參數進行曲線展示,其實圖表控件有很多,但是我印象比較深的還是開源的ZedGraph控件,這個既可以用在Web上,也可以用在Winform上的開源控件,有着簡單易用的特點,因此我會先考慮是否可以滿足要求。在需求中,我需要定制顯示曲線報表的內容,按照每行一個人員的數據,然后再每行中展現該人員的相關圖表信息,而且這種的報表要可以實現打印的功能。在經過一段時間的摸索及實現提煉,得到了比較滿意的效果,先來進行總體的介紹先把。

通過把好的思路,有用的技巧進行積累整合到Winform開發框架中,方便自己,也方便別人,提高工作效率。

1、按每行一個用戶的數據顯示曲線報表圖形

一行一個人員的曲線數據,可以對同一曲線項目進行對比,方便用戶的實際業務對比操作。

2、每個曲線圖形可以雙擊打開,進行放大縮小的操作,方便用戶查看。

由於在一個界面中展示多個圖表圖形的時候,會比較小,為了更直觀顯示曲線數據,可以通過單獨打開一個新的窗口進行曲線縮放操作,支持鼠標的滾動放大縮小,同時ZedGraph支持繪圖點的信息提示,非常友好。

3、提供自定義打印及文檔導出功能

由於用戶控件是自定義組裝的,因此要實現自定義的打印功能才可以,這個自定義打印的東西確實需要慢慢測試研究,這個地方花了不少時間。

通過在DevExpress打印界面中展示預覽效果,方便可以進行打印確認操作,以及預覽最終的效果,並支持把文檔導出到PDF或者圖片中,非常方便易用。

以上就是這個曲線報表的主要幾個特點,不過這樣的曲線,基本上能夠滿足我們日常的一些數據曲線的展現的了。

實現上我們需要把需求和界面拆分,首先我們在一個設計主界面,在住界面上防止一個TableLayout的布局控件,方便我們動態添加每個單一的控件進去。

4、曲線報表具體實現過程及思路

1)設計報表顯示主界面

2)設計曲線報表組件

然后設計一個空白的布局FlowLayout控件,用來擺放一個或者多個的曲線報表項目,例如體重曲線、視力曲線、血壓曲線等項目的,實現代碼如下所示。

        public void BindData()
        {  
           switch (CurveData.CurveType)
            {
                case CurveType.體重:
                    BindWeight();
                    break;
               case CurveType.身長:
                   BindHeight();
                   break;
                case CurveType.脈搏:
                    BindPulse();
                    break;
                case CurveType.血壓:
                    BindBlood();
                    break;
                case CurveType.視力:
                    BindSight();
                    break;
               case CurveType.暗適應時間:
                    BindDarkAdapTime();
                    break;
                case CurveType.體溫:
                    BindTemperature();
                    break;
                case CurveType.全部:
                    #region 全部
                    if (CurveData.CheckType == CheckType.季度小體檢)
                    {
                        BindWeight();
                        BindPulse();
                        BindBlood();
                        BindSight();
                        BindDarkAdapTime();
                    }
                    else if (CurveData.CheckType == CheckType.年度大體檢)
                    {
                        BindWeight();
                        BindHeight();
                        BindPulse();
                        BindBlood();
                        BindSight();
                    }
                    else if (CurveData.CheckType == CheckType.飛行前體檢)
                    {
                        BindTemperature();
                        BindPulse();
                        BindBlood();
                    }                     
                    break;

                    #endregion
            }
        }
        private void BindWeight()
        {
            DataTable dt = null;
            if (CurveData.CheckType == CheckType.年度大體檢)
            {
                dt = BLLFactory<LargeCheckSurgical>.Instance.GetWeightData(CurveData.StartDate,
                    CurveData.EndDate, CurveData.PilotID);
            }
            else if (CurveData.CheckType == CheckType.季度小體檢)
            {
                dt = BLLFactory<SmallCheck>.Instance.GetWeightData(CurveData.StartDate,
                    CurveData.EndDate, CurveData.PilotID);
            }

            WeightCurve curve = new WeightCurve();
            curve.CurveData = CurveData;
            curve.dataTable = dt;
            this.layoutPanel1.Controls.Add(curve);
        }

其他代碼不在贅述。

3)設計曲線項目組件

由於曲線報表涉及很多展示的項目,每項又有一些不同,因此我們為不同的項目設計一個組件,如體重曲線如下所示,在一個自定義控件上面放置一個ZedGraph組件,設計好這個組件的相關屬性和事件。

這個控件默認是英文的,所以如果需要使用中文菜單,需要自己漢化一下代碼,然后編譯出來自己使用即可。

實現代碼如下所示

            GraphPane myPane = zgc.GraphPane;
            myPane.CurveList.Clear();

            // 設置標題及坐標軸的說明
            myPane.Title.Text = string.Format("【{0}】體重曲線", CurveData.PilotName);
            myPane.XAxis.Title.Text = "體檢日期";
            myPane.YAxis.Title.Text = "體重(Kg)";

            PointPairList list = new PointPairList();
            foreach(DataRow row in dataTable.Rows)
            {
                DateTime checkDate = Convert.ToDateTime(row["CheckDate"].ToString());
                double x = (double) new XDate(checkDate);
                double y = Convert.ToInt32(row["Weight"].ToString());

                list.Add(x, y);
            }

            LineItem myCurve = myPane.AddCurve("體重", list, Color.Red, SymbolType.Diamond);
            myCurve.Symbol.Fill = new Fill(Color.White);

4)設計圖表打印模塊

打印的時候,需要自己在打印原件上進行圖形的繪制,這一個是比較復雜的調試過程,開始總是想着是否可以把控件打印出來就OK,可是這種操作,一旦界面遮擋,就打印不出實際的效果了,所以只好類似繪圖一樣,使用自定義繪制方式。

這樣我計算好每個控件的大小尺寸(包括Lable控件、曲線圖表控件),然后挨着繪制即可,主要代碼如下所示。

        protected virtual void DrawRow(BrickGraphics graph, int rowIndex, int col, Control ctrl, float left)
        {
            graph.BackColor = Color.White;

            RectangleF bounds = new RectangleF(left, 0, ctrl.Width, ctrl.Height);
            bounds.Y = (rowIndex - 1) * bounds.Height;

            if (ctrl is Label)
            {
                TextBrick brick = graph.DrawString(ctrl.Text, bounds);
                brick.HorzAlignment = DevExpress.Utils.HorzAlignment.Center;
                brick.VertAlignment = DevExpress.Utils.VertAlignment.Center;
                const int LeftPadding = 4;
                brick.Padding = new PaddingInfo(LeftPadding, brick.Padding.Right, brick.Padding.Top, brick.Padding.Bottom);
            }
            else
            {
                int width = ctrl.Size.Width;
                int height = ctrl.Size.Height;
                Bitmap bm = new Bitmap(width, height);
                ctrl.DrawToBitmap(bm, new Rectangle(0, 0, width, height));

                ImageBrick brick = graph.DrawImage(bm, bounds);
                brick.SizeMode = ImageSizeMode.ZoomImage;
            }
        }

好了,整個曲線報表的顯示效果及實現思路及部分核心代碼,都已經介紹完畢了,在整個過程中,除了經驗外,我覺得最重要的就是要細心、耐心及用心,項目開發就是把各種技巧、各種思路都集中起來,才可以快速高效的開發出高質量、客戶反映好的項目出來。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM