c# chart控件添加邊界值線條以及擴展性功能


最近一致在開發能源平台,平台中很多能耗數據都是通過使用微軟的chart控件進行圖形呈現的。考慮到要給用戶更為直觀的呈現效果,需要對原有控件的功能進行擴展。微軟chart控件沒有第三方樣chart樣式炫酷,但是勝在可定制性強,中文手冊詳細,很多效果能夠自己寫出來。

  主要實現功能:1.最大值,最小值,平均值展示   2.鼠標移動到數據點繪制豎線,用tooltip的方式展示數據

  最終呈現效果如圖:

解決方案:

(1)最大值,最小值,平均值呈現

  之前在網上找了好久都沒有想要的效果,第三方控件往往都能直接設置。最開始我的解決方法是在ChartArea中添加單獨的series展示最值,但是呈現效果不佳:

  在看了微軟的技術手冊后,發現可以在ChartArea中添加Stripline實現。以插入最大值線條為例,代碼如下:

 //最大線條
                        double max = ammeter.Max();
                        StripLine stripMax = new StripLine(); stripMax.Text = string.Format("最大:{0:F}", max);//展示文本 stripMax.BackColor = Color.FromArgb(208, 109, 106);//背景色 stripMax.Interval = 0;//間隔 stripMax.IntervalOffset = max;//偏移量 stripMax.StripWidth = 0.001;//線寬 stripMax.ForeColor = Color.White;//前景色 stripMax.TextAlignment = StringAlignment.Near;//文本對齊方式 chartInfo.ChartAreas["ammeter"].AxisY.StripLines.Add(stripMax);//添加到ChartAreas中

(2)實現鼠標移動到數據點繪制豎線,用tooltip的方式展示數據

  chart中可以對畫圖區域使用HitTest進行數據點檢測,之前的方案是在鼠標移動的過程中對當前鼠標的坐標區域(x為當前坐標,y為畫圖區域的高 )進行數據檢測,移動的過程中繪制跟隨鼠標的線條。實現后發現效果並不是很好,HitTest在數據點周圍的series都會判定為數據點,所以線條一直在繪制,而想要的效果鼠標移動的過程中僅在數據點時才繪制豎線。

  要在數據點位置繪制線條需要獲得數據點的相對坐標,網上一直沒有找到解決辦法。起初通過x,y軸的偏移量,0點的坐標,繪圖區域的坐標可以實現相對坐標的獲取,但是發現這樣有時計算會有很大的偏差。同樣通過查找技術手冊后,發現微軟給了獲取x,y軸相對坐標的方法。

  Point lastPoint = new Point();//上次點的坐標
        ToolTip tp = new ToolTip();//tooltip展示條
        //繪制豎線坐標
        Point p1 = new Point(0, 0);
        Point p2 = new Point(0, 0);
        /// <summary>
        /// 鼠標移動事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void chartInfo_MouseMove(object sender, MouseEventArgs e)
        {
            this.Refresh();//刷新chart,使用clear會使chart上的圖形完全清空
            Pen pen = new Pen(Color.Yellow);
            Graphics g = chartInfo.CreateGraphics();
            string seriesInfo = ""; //tooltip文本
            if (e.Location != lastPoint)//如果在上次點的位置不進行操作,此處操作會引發chart控件的refresh操作造成界面閃爍
            {
                for (int y = 0; y <= chartInfo.Size.Height; y++)//線條范圍進行碰撞檢測
                {
                    HitTestResult result = chartInfo.HitTest(e.X, y);
                    if (result.ChartElementType == ChartElementType.DataPoint)
                    {
                        foreach (DataPoint dpp in result.Series.Points)//數據點默認樣式 使用索引的方式修改偶爾會出現無法正常修改完
                        {
                            dpp.MarkerStyle = MarkerStyle.Diamond;
                            dpp.MarkerColor = Color.White;
                            dpp.MarkerSize = 5;
                        }
                        int i = result.PointIndex;
                        DataPoint dp = result.Series.Points[i];
                        dp.MarkerStyle = MarkerStyle.Star4;//捕獲到數據點的樣式
                        dp.MarkerColor = Color.Orange;
                        dp.MarkerSize = 15;
                        //獲取數據點的相對坐標
                        p1 = new Point((int)chartInfo.ChartAreas["ammeter"].AxisX.ValueToPixelPosition(dp.XValue), 0);
                        p2 = new Point((int)chartInfo.ChartAreas["ammeter"].AxisX.ValueToPixelPosition(dp.XValue), chartInfo.Size.Height);
                        seriesInfo = string.Format("分項:{0}  時間:{1}  能耗值:{2}", result.Series.LegendText, DateTime.FromOADate(dp.XValue), dp.YValues[0]);
                        break;
                    }
                }
                tp.AutoPopDelay = 5000;//展示tooltip
                tp.ShowAlways = false;
                tp.IsBalloon = true;
                tp.SetToolTip(chartInfo, seriesInfo);
            }
            lastPoint = e.Location;//記錄本次位置
            g.DrawLine(pen, p1, p2);//繪制豎線
        }

 

寫在最后

  微軟技術手冊真香


免責聲明!

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



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