【问题标题】:Get all DataPoints within a 'rubber-band' rectangle in a Chart control获取图表控件中“橡皮筋”矩形内的所有数据点
【发布时间】:2016-02-12 07:52:57
【问题描述】:

我在 .NET 4.0 WinForms 图表控件中有一个 X-Y 图。我正在尝试实现橡皮筋选择,以便用户可以单击并拖动鼠标以在绘图上创建一个矩形,从而选择该矩形内的所有点。

虽然我能够对矩形的绘图进行编码,但我现在正在尝试识别位于该矩形内的数据点。以下是相关代码:

public partial class Form1 : Form
{
    System.Drawing.Point _fromPosition;
    Rectangle _selectionRectangle;

    public Form1()
    {
        InitializeComponent();            
    }

    private void chart1_MouseMove(object sender, MouseEventArgs e)
    {
        // As the mouse moves, update the dimensions of the rectangle
        if (e.Button == MouseButtons.Left)
        {
            Point p = e.Location;
            int x = Math.Min(_fromPosition.X, p.X);
            int y = Math.Min(_fromPosition.Y, p.Y);
            int w = Math.Abs(p.X - _fromPosition.X);
            int h = Math.Abs(p.Y - _fromPosition.Y);
            _selectionRectangle = new Rectangle(x, y, w, h);

            // Reset Data Point Attributes
            foreach (DataPoint point in chart1.Series[0].Points)
            {
                point.BackSecondaryColor = Color.Black;
                point.BackHatchStyle = ChartHatchStyle.None;
                point.BorderWidth = 1;
            }   
            this.Invalidate();
        }                     
    }

    private void chart1_MouseDown(object sender, MouseEventArgs e)
    {
        // This is the starting position of the rectangle
        _fromPosition = e.Location;
    }

    private void chart1_Paint(object sender, PaintEventArgs e)
    {
        e.Graphics.DrawRectangle(new Pen(Color.Blue, 2), _selectionRectangle);
        foreach (DataPoint point in chart1.Series[0].Points)
        {                
            // Check if the data point lies within the rectangle 
            if (_selectionRectangle.Contains(???))))
            {
                // How do I convert DataPoint into Point?
            }
        }
    }
}

我想要做的是查询系列中的每个数据点并检查它是否位于矩形内。在这里,我无法将每个 DataPoint 转换为其对应的 Point。看起来很简单,所以我要么在这里遗漏了一些基本的东西,要么错误地解决了这个问题。

我还应该补充一点,我提到了类似的问题 herehere,但他们没有谈论如何实际识别矩形内的 DataPoints。

任何方向都将不胜感激!

【问题讨论】:

    标签: c# .net winforms charts microsoft-chart-controls


    【解决方案1】:

    我已经展示了如何在Paint 事件here 中欺骗Chart 帮助获得DataPoints 的坐标。

    但无论如何你都想在Paint活动中捡到它们,所以不需要作弊..:

    我定义了一个列表来收集套索DataPoints

    List<DataPoint> dataPoints = new List<DataPoint>();
    

    我会在每个新选择中清除它:

    void chart1_MouseDown(object sender, MouseEventArgs e)
    {
        _fromPosition = e.Location;
        dataPoints.Clear();
    }
    

    最后我可以写出结果:

    void chart1_MouseUp(object sender, MouseEventArgs e)
    {
        foreach(DataPoint pt in dataPoints)
            Console.WriteLine("found:" + pt.ToString() +
                " at " + chart1.Series[0].Points.IndexOf(pt));
    }
    

    而在Paint事件中,我们使用了两个轴的ValueToPixelPosition方法:

    void chart1_Paint(object sender, PaintEventArgs e)
    {
        using (Pen pen = new Pen(Color.Blue, 2) // dispose of my Pen
              {DashStyle = System.Drawing.Drawing2D.DashStyle.Dot})
           e.Graphics.DrawRectangle(pen, _selectionRectangle);
        foreach (DataPoint point in chart1.Series[0].Points)
        {   // !! officially these functions are only reliable in a paint event!!
            double x = chart1.ChartAreas[0].AxisX.ValueToPixelPosition(point.XValue);
            double y = chart1.ChartAreas[0].AxisY.ValueToPixelPosition(point.YValues[0]);
            PointF pt = new PointF((float)x,(float)y);
    
            // Check if the data point lies within the rectangle 
            if (_selectionRectangle.Contains(Point.Round(pt)))
            {
                if (!dataPoints.Contains(point)) dataPoints.Add(point);
            }
        }      
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-28
      • 1970-01-01
      • 2010-09-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多