Convert chart coords to pixels

前端 未结 3 1037
花落未央
花落未央 2021-01-22 17:52

I should draw a circle inside a polar chart with some text on it.

I started to play with PostPaint, got chart graphics, so I am able to draw and write custom things on i

相关标签:
3条回答
  • 2021-01-22 18:10

    Find the ratio ? if cord is 100x100 where units are pseudo, then when transforming to 200x200 pixel you just need to use ratio 2.0 if coord is 200x100 and physically 100x100 X has ratio 2.0 and Y has ratio 1.0 When I do SVG i have to offset 0,0 (upper left corner) to Cartesian coordinates (0,0 in center) by offseting all by +1000 http://en.wikipedia.org/wiki/Cartesian_coordinate_system

    0 讨论(0)
  • 2021-01-22 18:29

    The self-answered solution neither works in a more general case nor does it actually transform DataPoint values to pixel-coordinates.

    Here is a solution to draw the circle that will always work:

    private void chart1_PostPaint(object sender, ChartPaintEventArgs e)
    {
        RectangleF ipp = InnerPlotPositionClientRectangle(chart1, chart1.ChartAreas[0]);
        using (Graphics g = chart1.CreateGraphics())
            g.DrawEllipse(Pens.Red, new RectangleF(ipp.Location, ipp.Size));
    }
    

    It makes use of two helper functions:

    RectangleF ChartAreaClientRectangle(Chart chart, ChartArea CA)
    {
        RectangleF CAR = CA.Position.ToRectangleF();
        float pw = chart.ClientSize.Width / 100f;
        float ph = chart.ClientSize.Height / 100f;
        return new RectangleF(pw * CAR.X, ph * CAR.Y, pw * CAR.Width, ph * CAR.Height);
    }
    
    RectangleF InnerPlotPositionClientRectangle(Chart chart, ChartArea CA)
    {
        RectangleF IPP = CA.InnerPlotPosition.ToRectangleF();
        RectangleF CArp = ChartAreaClientRectangle(chart, CA);
    
        float pw = CArp.Width / 100f;
        float ph = CArp.Height / 100f;
    
        return new RectangleF(CArp.X + pw * IPP.X, CArp.Y + ph * IPP.Y,
                                pw * IPP.Width, ph * IPP.Height);
    }
    

    And here is a link to a general coordinate transformation function for polar charts.

    0 讨论(0)
  • 2021-01-22 18:34

    So, I solved it.

    I handle mschart's postpaint event:

    private void chartMain_PostPaint(object sender, ChartPaintEventArgs e)
        {
            try
            {
                if (chartMain.ChartAreas.FirstOrDefault(a=>a.Name == "Default") == null)
                    return;
    
                Graphics graph = e.ChartGraphics.Graphics;
    
                var day = Date.GetBoundaries(daySelectorMain.DateTimePickerDay.Value);
                var toDate = day.Item2; //it is maxdate value (max value of x axis)
    
                var centerY = (float)chartMain.ChartAreas["Default"].AxisY.ValueToPixelPosition(-80); //-80 is the min value of y (y axis)
                var centerX = (float)chartMain.ChartAreas["Default"].AxisX.ValueToPixelPosition(toDate.ToOADate());
    
                var origoY = (float)chartMain.ChartAreas["Default"].AxisY.ValueToPixelPosition(0);
                var origoX = (float)chartMain.ChartAreas["Default"].AxisX.ValueToPixelPosition(toDate.ToOADate());
    
                var radius = (float)(centerY - origoY) - 1;
    
                graph.DrawLine(System.Drawing.Pens.Blue,
                               new PointF(origoX, origoY),
                               new PointF(centerX, centerY));
    
                graph.FillEllipse(new SolidBrush(Color.White), centerX - radius, centerY - radius, radius * 2, radius * 2);
            }
            catch (System.Exception exc)
            {
                Debug.Assert(false, exc.Message);
            }
        }
    
    0 讨论(0)
提交回复
热议问题