• 带滑块的趋势图(slider control in chart)


          如果没记错的话,好像是第一次在用趋势图显示数据的时候,就遇到过这个问题,当时是在一个趋势图中显示一个月中每天的数据趋势变化,结果就是根本在一张图中显示不下,X轴的文字标注都重叠到一起,当时用的是PB,里面的图形显示功能非常强大,后来好像是将文字直立显示的,避免了标注的重叠。

          最近同时好像在搞趋势图,又想起这个问题,就试着在里面加个slider实现拖动以便可以显示“被多出”的部分。老规矩,先看图。

          

          嘿嘿,其实也没用到什么,纯GDI+,用到的也不外乎就是双缓存和坐标变换。主要处理的事件就是MouseDown和MouseMove,重绘Paint。在MouseDown中变化X轴的值和Value值(这里也有变换坐标),在MouseMove中变换坐标,Paint中绘制轴、趋势图、滑块。

          下面看看完整的代码:

    代码
            /// <summary>
            
    /// X轴和Value值重加载
            
    /// </summary>
            private void lbchart_MouseDown(object sender, MouseEventArgs e)
            {
                
    //是否点中滑块
                IsClick = IsClickSlider(new Point(e.X, e.Y));
                
    //左键有效
                if (e.Button == MouseButtons.Left)
                {
                    
    double disvalue = 0//位移
                    if (curPoint.X != e.X || curPoint.Y != e.Y)
                    {
                        curPoint.X 
    = e.X;
                        curPoint.Y 
    = e.Y;
                        Capture 
    = true;
                        
    //是否需要移动
                        if (IsClick)
                        {
                            IsNeedMove 
    = true;
                        }
                        
    //位移差
                        disvalue =curPoint.X - oldPoint.X;
                    }
                    
    else
                    {
                        IsNeedMove 
    = false;
                        
    //位移差
                        disvalue = dx;
                    }

                    
    //重新复制PartValue中的值
                    
    //****x轴移动的位移
                    int xd = (int)Math.Round(disvalue / xdvalue);
                    curArrPos 
    = curArrPos + xd;
                    
    if (curArrPos < 0)
                    {
                        curArrPos 
    = 0;
                    }
                    
    if (curArrPos > 6)
                    {
                        curArrPos 
    = 6;
                    }
                    
    for (int i = curArrPos; i < curArrPos + 7; i++)
                    {
                        xPartValue[i 
    - curArrPos] = xValue[i];
                        partValue[i 
    - curArrPos] = value[i];
                    }
                }
                
    if (e.Button == MouseButtons.Right)
                {
                    Capture 
    = false;
                }
                dx 
    = 0;
                
    this.lbchart.Invalidate();
            }


            
    /// <summary>
            
    /// 鼠标移动
            
    /// </summary>
            private void lbchart_MouseMove(object sender, MouseEventArgs e)
            {
                Graphics g2 
    = CreateGraphics();
                
    if (IsNeedMove)
                {
                    dx 
    = dx + (e.X - oldPoint.X);
                    curPoint 
    = new Point(e.X, e.Y);
                }
                
    this.lbchart.Invalidate();
            }

           上面是两个主要的鼠标事件,下面看看绘制代码:

    代码
           #region 重绘
           
    private void lbchart_Paint(object sender, PaintEventArgs e)
           {
                
    //初始化值
                g0 = e.Graphics;
                bitmap 
    = new Bitmap(lbchart.Width, lbchart.Height);
                g1 
    = Graphics.FromImage(bitmap);
                g1.Clear(
    this.lbchart.BackColor);
                g1.SmoothingMode 
    = SmoothingMode.AntiAlias;

                
    #region 绘制
                
    //
                DrawAxes();
                
    //趋势图
                DrawChart();
                
    //滑块
                DrawSlider();
                
    #endregion

                
    //绘制到lb上
                g0.DrawImage(bitmap, 00);

            }

            
    /// <summary>
            
    /// 绘制轴
            
    /// </summary>
            private void DrawAxes()
            {
                Brush axesbrush 
    = new SolidBrush(Color.Black);
                Font axesfont 
    = new Font("宋体"15, FontStyle.Bold);
                Font valuefont 
    = new Font("宋体"10, FontStyle.Regular);

                
    //箭头
                AdjustableArrowCap cap = new AdjustableArrowCap(33);
                cap.WidthScale 
    = 3;
                cap.BaseCap 
    = LineCap.Square;
                cap.Height 
    = 3;
                axesPen.CustomStartCap 
    = cap;

                
    //****Y轴
                g1.DrawLine(axesPen, lbPosX + 10, lbPosY + 10, lbPosX + 10, lbHeight - 30);
                g1.DrawString(
    "Y", axesfont, axesbrush, lbPosX + 15, lbPosY + 10);
                
    //*****Y轴差值
                ydvalue = ((lbHeight - 15- (lbPosY + 10)) / (yValue.Length + 1);
                
    for (int i = 0; i < yValue.Length; i++)
                {
                    
    float y = (float)(lbHeight - 15 - (i + 1* ydvalue);
                    g1.DrawString(yValue[i].ToString(), valuefont, axesbrush, lbPosX 
    + 12, y);
                    g1.DrawLine(valuePen, lbPosX 
    + 10, y, lbPosX + 15, y);
                }

                
    //****X轴
                g1.DrawLine(axesPen, lbWidth - 5, lbHeight - 30, lbPosX + 10, lbHeight - 30);
                g1.DrawString(
    "X", axesfont, axesbrush, lbWidth - 15, lbHeight - 55);
                
    //******X轴差值
                xdvalue = (lbWidth - 5 - (lbPosX + 10)) / (partValue.Length - 1);
                
    for (int i = 0; i < xPartValue.Length; i++)
                {
                    
    float x = (float)(lbPosX + 10 + (i) * xdvalue);
                    
    if (Convert.ToDouble(xPartValue[i].ToString()) >= 10)
                    {
                        g1.DrawString(xPartValue[i].ToString(), valuefont, axesbrush, x 
    - 12, lbHeight - 28);
                    }
                    
    else
                    {
                        g1.DrawString(xPartValue[i].ToString(), valuefont, axesbrush, x 
    - 5, lbHeight - 28);
                    }
                    g1.DrawLine(valuePen, x, lbHeight 
    - 30, x, lbHeight - 35);
                }
            }

            
    /// <summary>
            
    /// 绘制趋势图
            
    /// </summary>
            private void DrawChart()
            {
                
    //****绘制曲线图
                double dvalue = ydvalue / 5.0;
                
    for (int i = 0; i < partValue.Length - 1; i++)
                {
                    
    double startX = lbPosX + 10 + (i) * xdvalue;
                    
    double endX = startX + xdvalue;
                    
    double startY = Convert.ToDouble(partValue[i].ToString()) * dvalue;
                    
    double endY = Convert.ToDouble(partValue[i + 1].ToString()) * dvalue;
                    g1.DrawEllipse(
    new Pen(Color.Red), (float)(startX - 3), (float)(startY - 3), 66);
                    g1.DrawLine(valuePen, (
    float)endX, (float)endY, (float)startX, (float)startY);
                }
            }

            
    /// <summary>
            
    /// 绘制滑块
            
    /// </summary>
            private void DrawSlider()
            {
                
    //绘制滑块
                if (curPoint.X != 0 && curPoint.Y != 0)
                {
                    oldPoint 
    = curPoint;
                    g1.DrawLine(sliderPen, lbPosX 
    + curPoint.X, lbPosY, lbPosX + curPoint.X, lbPosY + lbHeight);
                }
                
    else
                {
                    g1.DrawLine(sliderPen, lbWidth 
    / 2, lbPosY, lbWidth / 2, lbPosY + lbHeight);
                }
            }

            
    #endregion
  • 相关阅读:
    关于登录或授权页面的错误提示
    弱网环境模拟工具
    Android Fragment 深度解析
    排序算法(七)
    排序算法(六)
    排序算法(五)
    java之数组
    排序算法(四)
    排序算法(三)
    排序算法(二)
  • 原文地址:https://www.cnblogs.com/wangyong/p/1806480.html
Copyright © 2020-2023  润新知