2

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

My main problem is the placement.

E.g. I'd like to draw sg where my x and y axes are crossing, but I did not find any effective way to convert graph coordinates (in my example 0,0) to pixel coordinates.

How can I do this? How can I convert chart coords to pixels?

.net4/winforms/vs2010/c#

Tom
  • 3,899
  • 22
  • 78
  • 137

3 Answers3

3

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.

Community
  • 1
  • 1
TaW
  • 53,122
  • 8
  • 69
  • 111
3

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);
        }
    }
Tom
  • 3,899
  • 22
  • 78
  • 137
1

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

MikeyKennethR
  • 600
  • 4
  • 16