如何使用鼠标在图表控件中绘制图形 [英] How to draw a graph in chart control with mouse

查看:161
本文介绍了如何使用鼠标在图表控件中绘制图形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的任务是使用鼠标在图表控件中绘制图形,并从图形中检索(X,Y)点。

My task is to draw a graph in chart control using mouse and retrieve the (X,Y) points from the Graph.

我试图用鼠标绘制图形。
这是正常的Graph看起来像。
使用鼠标绘制后,它看起来像:
我用来绘制图形的代码是: / p>

I tried of drawing a graph with mouse. Here is the normal Graph looks like. After drawing with mouse, it looks like : The code which i used to draw graph is :

    private void Form1_Load(object sender, EventArgs e)
    {
    chart1.ChartAreas[0].AxisX.Minimum =0170101;
    chart1.ChartAreas[0].AxisX.Maximum =0175951;
    chart1.ChartAreas[0].AxisY.Minimum=0780101;
    chart1.ChartAreas[0].AxisY.Maximum=0785951;
    double range = chart1.ChartAreas[0].AxisX.Maximum - chart1.ChartAreas[0].AxisX.Minimum;
        chart1.ChartAreas[0].AxisX.Interval = range / 5;

        range = chart1.ChartAreas[0].AxisY.Maximum - chart1.ChartAreas[0].AxisY.Minimum;
        chart1.ChartAreas[0].AxisY.Interval = range / 5;
    }
    private void chart1_MouseMove(object sender, MouseEventArgs e)
    {
        if (!(FirstPoint == null))
        {
            Graphics g = chart1.CreateGraphics();
            Pen ErasePen = new Pen(Color.Transparent);
            g.DrawLine(ErasePen, FirstPoint, TempPoint);
            TempPoint = new Point(e.X, e.Y);
            this.Refresh();
        }
    }
    private void chart1_MouseDown_1(object sender, MouseEventArgs e)
    {
        FirstPoint = new Point(e.X, e.Y);
        TempPoint = new Point(e.X, e.Y);
    }

    private void chart1_MouseUp_1(object sender, MouseEventArgs e)
    {
        LineEndPoints Line = new LineEndPoints
        {
            StartPoint = FirstPoint,
            endPont = new Point(e.X, e.Y)
        };
        LinesList.Add(Line);
        // FirstPoint = null;
        this.Refresh();
    }

    private void chart1_Paint_1(object sender, PaintEventArgs e)
    {
        foreach (LineEndPoints line in LinesList)
        {
            e.Graphics.DrawLine(Pens.Green, line.StartPoint, line.endPont);
        }
        if (!(FirstPoint == null))
        {
            e.Graphics.DrawLine(Pens.Red, FirstPoint, TempPoint);
        }
    }

当我用来绘制图形时,从图表控件的最大值和最小值。
现在我需要知道的是:
1)我的图表不应该离开图表控件的X和Y轴点。
2)我需要知道相对于图表轴绘制的图形的X,Y点,而不是形式轴。

When I used to draw a graph it is moving away from the max and min values of the chart control. Now what I need to know is: 1) My graph should not move away from the X and Y axis points of the chart control. 2) I need to know the X,Y points of the graph which is drawn with respect to chart axis but not with form axis.

我使用C# VS 2010 Win-forms。

I use C# VS 2010 Win-forms.

推荐答案

图表使用不同的其内容的坐标系比其控件表面,即小鼠的空隙;有转换函数,但是它们带有一个警告:它们只能保证在Paint事件中工作。

Chart uses a different coordinate system for its content than its Control surface, ie the mouse loacation; there are conversion functions but they come with a caveat: They are only guaranteed to work in the Paint events..

ValueToPixelPosition

这是一个示例,将像素点转换为图表点值。您可以看到两个图形叠加非常好: DataPoints 以蓝色线连接,像素点由红色虚线连接..:

Here is an example that translates the pixel points to chart point values. You can see the two graphics overlaying very nicely: The DataPoints are connected in blue lines and the pixel points by dotted red lines..:

>

    public Form1()
    {
        InitializeComponent();
        chart1.Series[0].ChartType = SeriesChartType.Line;
        chart1.ChartAreas[0].AxisX.Minimum = 0;
        chart1.ChartAreas[0].AxisX.Maximum = 500;
        chart1.ChartAreas[0].AxisY.Minimum = 0;
        chart1.ChartAreas[0].AxisY.Maximum = 500;
    }

    List<Point> points = new List<Point>();

    private void chart1_MouseClick(object sender, MouseEventArgs e)
    {
        points.Add(e.Location);
        chart1.Invalidate();
    }

    private void chart1_Paint(object sender, PaintEventArgs e)
    {
        chart1.Series[0].Points.Clear();
        foreach(Point pt in points)
        {
            double dx = chart1.ChartAreas[0].AxisX.PixelPositionToValue(pt.X);
            double dy = chart1.ChartAreas[0].AxisY.PixelPositionToValue(pt.Y);
            chart1.Series[0].Points.AddXY(dx, dy);
        }
        if (points.Count > 1)
            using (Pen pen = new Pen(Color.Red, 2.5f))
               e.Graphics.DrawLines(pen, points.ToArray());
    }

请注意,这将始终清除 c $ c> DataPoints ,并根据当前图表布局使用 PixelPositionToValue 方法从像素点列表中重新创建它们。当诸如标签大小,其他缩放,其他最小/最大值等的改变时,布局将总是改变。

Note that this will always clear the DataPoints and recreate them from the pixel points list, according to the current chart layout using the PixelPositionToValue method. The layout will always change when things like label sizes, other scaling, other minimum/maximum values etc change.

也许你真的要反向工作,那就是使用 ValueToPixelPosition code>。

Maybe you really want to work the other way round, that is change the clicked points using the ValueToPixelPosition.

下面是保存 DataPoints 并重新计算像素点的修改示例:

Here is the modified example that keeps the DataPoints and recalculates the pixel points:

    List<Point> points = new List<Point>();
    Point lastPoint = Point.Empty;

    private void chart1_MouseClick(object sender, MouseEventArgs e)
    {
        lastPoint = e.Location;
        chart1.Invalidate();
    }

    private void chart1_Paint(object sender, PaintEventArgs e)
    {
        // if we have a new point, convert to DataPoint and add to Series.Points:
        if (lastPoint != Point.Empty)
        {
            double dx = chart1.ChartAreas[0].AxisX.PixelPositionToValue(lastPoint.X);
            double dy = chart1.ChartAreas[0].AxisY.PixelPositionToValue(lastPoint.Y);
            chart1.Series[0].Points.AddXY(dx, dy);
        }
        lastPoint = Point.Empty;
        // now recalculate all pixel points:
        points.Clear();
        foreach (DataPoint pt in chart1.Series[0].Points)
        {
            double x = chart1.ChartAreas[0].AxisX.ValueToPixelPosition(pt.XValue);
            double y = chart1.ChartAreas[0].AxisY.ValueToPixelPosition(pt.YValues[0]);
            points.Add(new Point((int)x, (int)y));
        }

        if (points.Count > 1)
            using (Pen pen = new Pen(Color.Red, 2.5f))
            {
                pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
                e.Graphics.DrawLines(pen, points.ToArray());
            }
    }

这更有意义,因为 DataPoints 始终绑定到图表的缩放,因此它们是真实的东西。当你调整图表的大小时, DataPoints 和他们构成的图形照常被缩放,绘制的像素点完全符合:

This makes a lot more sense, since the DataPoints are always bound to the chart's scaling, so they are the 'real thing'. When you resize the Chart the DataPoints and the Graphic they make up are scaled as usual and the drawn pixel points follow perfectly:

(当你调整第一个版本的大小时,你可以看到没有什么被放大或缩小,网格线变化。)

(When you resize the first version you can see how nothing is being scaled up or down and only the chart's grid lines change..)

请注意,我设置了一些开始,所以不是我添加的每一个点都强制执行太多的布局更改。还要注意,有时当新的点改变时,仍然发生反馈回路。

Note that I set up a few things to start with, so that not every point I add enforces too many layout changes. Also note that sometimes there still occurs a feedback loop when the new points change e.g. the label sizes, which enforces a layout change and the paint loop.. To fix this you should probably control the labels' formats!

还要注意,这两种转换方法只能工作在一起(正确)在 Paint 事件,可能是因为只有当前的布局正在解决。

Also note that both conversion methods only work (correctly) in the Paint event(s), probably because only then the current layout is being settled.

这篇关于如何使用鼠标在图表控件中绘制图形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆