How to draw a graph in chart control with mouse

不想你离开。 提交于 2019-12-29 09:22:33

问题


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

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);
        }
    }

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.

I use C# VS 2010 Win-forms.


回答1:


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..

  • PixelPositionToValue

  • ValueToPixelPosition

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());
    }

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.

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

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());
            }
    }

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!

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



来源:https://stackoverflow.com/questions/29902288/how-to-draw-a-graph-in-chart-control-with-mouse

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!