为DevExpress扩展局部缩放功能

    使用devexpress 控件能够做出美观漂亮的界面,其丰富的控件库大多能够满足我们日常开发的要求。但在有的方面DEVexpress还是做得不够完善的,比如说其图表控件(charting)库就不支持局部缩放功能,而dev默认提供的缩放功能实在是太差劲了,怎么办呢,一个图表的缩放是其亮点之一,又不能没有。怎么才能实现想要的局部缩放功能呢?

    我现在想要的效果是选定图表的局部区域,对选定的局部区域放大,同时又要保留初始的图表使放大后的图能够还原到初始状态。在此将操作分为两个功能,一是局部放大,二是还原。实现局部放大效果的操作分解为以下三个触发事件,先后顺序是:左键点击图表、向右下拖动鼠标移动、释放左键。还原操作分解为两个触发事件,先后顺序是:左键点击图表,除右下方向外的其它方向脱东鼠标移动、释放左键。这里要判断光标是否有移动,没有位移移动就不是以上的局部放大和还原操作。实现代码如下

 //======================================================================
//
//        Copyright (C)  
//        All rights reserved
//
//        created by 王超 at  10/12/2014 
//        email:[email protected]
//
//======================================================================
 
 private bool _isScale = false;//鼠标左键是否按下
 private object _maxX, _minX, _maxY, _minY,_maxX1, _minX1, _maxY1, _minY1;//原图X轴和Y轴的最大和最小值以及第二坐标轴(如果有)X轴和Y轴的最大和最小值
 private object _x0, _x1, _y0, _y1;
 private object _x00, _y00, _x11,_y11;
 private Point _p0 = new Point();
 private Point _p1 = new Point();
 
 //单击左键
  void DevUCChart_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                _p0 = e.Location;
                SetLocationClientValue(_p0, ref  _x0, ref  _y0,ref _x00,ref _y00);
                _isScale = true;
            }
        }
        
        //将屏幕坐标转换为图表的坐标
     void SetLocationClientValue(Point p,ref object x0,ref object y0,ref object x1,ref object y1)
        {
            try
            {
                XYDiagram diagram = this.Diagram as XYDiagram;
                DiagramCoordinates coord = diagram.PointToDiagram(p);
                switch (coord.ArgumentScaleType)
                {
                    case ScaleType.DateTime:
                        x0 = coord.DateTimeArgument;
                        break;
                    case ScaleType.Numerical:
                        x0 = coord.NumericalArgument;
                        break;
                    case ScaleType.Qualitative:
                        x0 = coord.QualitativeArgument;
                        break;
                }
                switch (coord.ValueScaleType)
                {
                    case ScaleType.DateTime:
                        y0 = coord.DateTimeValue;
                        break;
                    case ScaleType.Numerical:
                        y0 = coord.NumericalValue;
                        break;
                }
                if (diagram.GetAllAxesX().Count > 1)
                {
                    AxisValue ax = coord.GetAxisValue(diagram.GetAllAxesX()[1]);
                    switch (coord.ArgumentScaleType)
                    {
                        case ScaleType.DateTime:
                            x1 = ax.DateTimeValue;
                            break;
                        case ScaleType.Numerical:
                            x1 = ax.NumericalValue;
                            break;
                        case ScaleType.Qualitative:
                            x1 = ax.QualitativeValue;
                            break;
                    }

                }

                if (diagram.GetAllAxesY().Count > 1)
                {
                    AxisValue ax = coord.GetAxisValue(diagram.GetAllAxesY()[1]);
                    switch (coord.ValueScaleType)
                    {
                        case ScaleType.DateTime:
                            y1 = ax.DateTimeValue;
                            break;
                        case ScaleType.Numerical:
                            y1 = ax.NumericalValue;
                            break;
                    }
                }
            }
            catch
            {

            }
        }
        
        //拖动鼠标事件,绘制虚线矩形
           void DevUCChart_MouseMove(object sender, MouseEventArgs e)
        {
            if (_isScale)
            {
                Point pE = new Point(e.Location.X - this.Location.X, e.Location.Y - this.Location.Y);
                Graphics g = this.CreateGraphics();
                Pen pen = new Pen(new SolidBrush(Color.FromArgb(100, 100, 100)));
                pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
                g.DrawRectangle(pen, _p0.X, _p0.Y, e.Location.X - _p0.X, e.Location.Y - _p0.Y);
            }
        }
        
        //释放左键事件
        void DevUCChart_MouseUp(object sender, MouseEventArgs e)
        {
            try
            {
                if (e.Button == MouseButtons.Left)
                {
                    _p1 = e.Location;
                    SetLocationClientValue(_p1, ref  _x1, ref  _y1, ref _x11, ref _y11);
                    XYDiagram diag = (XYDiagram)this.Diagram;
                    if (_p1.X ==_p0.X && _p1.Y == _p0.Y)//没有拖动操作
                    {
                        return;
                    }
                    if (_p1.X > _p0.X && _p1.Y > _p0.Y)//右下拖动,局部方大
                    {
                        diag.AxisX.Range.MaxValue = _x1;
                        diag.AxisX.Range.MinValue = _x0;

                        if (diag.AxisY.Range.MinValue is double)
                        {
                            double __y1 = (double)_y1;
                            double __y0 = (double)_y0;
                            diag.AxisY.Range.MaxValue = __y1 > __y0 ? __y1 : __y0;
                            diag.AxisY.Range.MinValue = __y1 > __y0 ? __y0 : __y1;
                        }

                        if (diag.GetAllAxesX().Count > 1)
                        {
                            diag.GetAllAxesX()[1].Range.MinValue = _x00;
                            diag.GetAllAxesX()[1].Range.MaxValue = _x11;
                        }

                    }
                    else//其它方向拖动,还原
                    {
                        diag.AxisX.Range.MinValue = _minX;
                        diag.AxisX.Range.MaxValue = _maxX;
                        diag.AxisY.Range.MinValue = _minY;
                        diag.AxisY.Range.MaxValue = _maxY;
                        if (diag.GetAllAxesX().Count > 1)
                        {
                            diag.GetAllAxesX()[1].Range.MinValue = _minX1;
                            diag.GetAllAxesX()[1].Range.MaxValue = _maxX1;
                        }
                        else
                        {
                            diag.GetAllAxesY()[1].Range.MinValue = _minY1;
                            diag.GetAllAxesY()[1].Range.MaxValue = _maxY1;
                        }
                    }

                }
                
            }
            catch
            { }
            finally {
                _isScale = false;
            }
        }

效果如下:

1、选定区间x轴: 2月8号到3月14号,y轴:1.4到2.5

为DevExpress扩展局部缩放功能_第1张图片

2、局部方大效果

为DevExpress扩展局部缩放功能_第2张图片

以上就是我实现的对devexpress控件库图表控件的局部缩放扩展功能,虽然还是有点不完美,但基本上能满足我的要了。





你可能感兴趣的:(图表控件,DevExpress,局部缩放)