获取“橡皮筋”中的所有DataPoints'图表控件中的矩形

时间:2016-02-02 04:43:46

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

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

虽然我能够编写矩形的图形,但我现在正在尝试识别位于此矩形内的Datapoints。以下是相关代码:

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并检查它是否位于Rectangle内。在这里,我无法将每个DataPoint转换为其对应的Point。这看起来非常简单,所以我要么缺少基本的东西,要么错误地解决问题。

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

任何方向都会受到赞赏!

1 个答案:

答案 0 :(得分:0)

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

但是你想在Paint事件中挑选它们,不需要作弊..:

我定义了一个List来收集套索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);
        }
    }      
}