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

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

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

      

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

      下面看看完整的代码:

ExpandedBlockStart.gif 代码
         ///   <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();
        }

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

ExpandedBlockStart.gif 代码
        #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,  0 0 );

        }

        
///   <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( 3 3 );
            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 ),  6 6 );
                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

 

 

转载于:https://www.cnblogs.com/wangyong/archive/2010/08/23/1806480.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值