获取图表控件中 'rubber-band' 矩形内的所有数据点
Get all DataPoints within a 'rubber-band' rectangle in a Chart control
我在 .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。这看起来很简单,所以我要么在这里遗漏了一些基本的东西,要么错误地解决了这个问题。
我还应该补充一点,我提到了类似的问题 here and here,但他们没有讨论如何实际识别矩形内的数据点。
任何方向将不胜感激!
我已经展示了如何欺骗 Chart
以帮助获得 Paint
事件 Paint
中 DataPoints
的坐标 。
但是既然你想在Paint
活动中捡到它们,就不需要作弊..:[=22=]
我定义了一个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);
}
}
}
我在 .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。这看起来很简单,所以我要么在这里遗漏了一些基本的东西,要么错误地解决了这个问题。
我还应该补充一点,我提到了类似的问题 here and here,但他们没有讨论如何实际识别矩形内的数据点。
任何方向将不胜感激!
我已经展示了如何欺骗 Chart
以帮助获得 Paint
事件 Paint
中 DataPoints
的坐标
但是既然你想在Paint
活动中捡到它们,就不需要作弊..:[=22=]
我定义了一个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);
}
}
}