繁体   English   中英

如何用鼠标在图表控件中绘制图形

[英]How to draw a graph in chart control with mouse

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

我尝试用鼠标绘制图形。 这是正常的Graph外观。 在此处输入图片说明 用鼠标绘制后,看起来像: 在此处输入图片说明 我用来绘制图形的代码是:

    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点。

我使用C#VS 2010 Win-forms。

Chart 的内容与其控制表面使用的坐标系统不同,即鼠标的位置; 有转换函数,但它们带有警告:仅保证它们可以在Paint事件中使用。

这是将像素点转换为图表点值的示例 你可以看到两个图形叠加非常漂亮:将DataPoints都连接在蓝线和虚线红线的像素点..:

在此处输入图片说明

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

请注意,这将始终清除 DataPoints并根据像素点列表使用PixelPositionToValue方法根据当前图表布局重新创建它们。 当标签大小,其他缩放比例,其他最小/最大值等发生变化时,布局将始终更改。

也许您真的想 ValueToPixelPosition 工作 ,那就是使用ValueToPixelPosition更改单击的点。

下面是本变形例,保持所述DataPoints并重新计算像素点:

    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和图形,他们弥补缩放和往常一样,并选取的像素点完全遵循:

在此处输入图片说明在此处输入图片说明

(当您调整第一个版本的大小时,您可以看到没有任何东西在按比例放大或缩小,只有图表的网格线发生变化。)

请注意,我从一开始就做了一些设置,所以并不是我添加的每个点都会强制进行太多的布局更改。 另请注意,有时在新点更改时仍会发生反馈循环,例如标签大小,这会强制更改布局和绘制循环。要解决此问题,您可能应该控制标签的格式!

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM