Set a c# polar diagram to a specific amout of ring

2019-07-23 12:57发布

问题:

I want to create a polar diagram in C# (no libary) that has a fixed amout of rings and segments. Is it also possible to change the digrees on the side so the 0 is on the right? If it is not possible in C# is there a libary for it?

回答1:

This is not hard at all using the MSChart control.

You can use its Polar ChartType and set the various properties of the two Axes to achieve what you want:

Here is an example; add a Chart chart1 to you Form and set it up like this:

Series s = chart1.Series[0];           // a reference to the default series
ChartArea ca = chart1.ChartAreas[0];   // a reference to the default chart area..
Axis ax = ca.AxisX;                    // and the ewo.. 
Axis ay = ca.AxisY;                    // ..axes  

s.ChartType = SeriesChartType.Polar;   // set the charttype of the series
s.MarkerStyle = MarkerStyle.Circle;    // display data as..
s.SetCustomProperty("PolarDrawingStyle", "Marker");  //.. points, not lines

To let the spokes go from 0° to 360° in steps of 15° with a rotation of 90° set these axes values:

ax.Minimum = 0;    
ax.Maximum = 360;
ax.Interval = 15;
ax.Crossing = 90;

Controlling the rings is trickier, as it eventually must take your data values into account! Assuming y-values going from 0-100 we can use these settings to get 10 rings:

ay.Minimum = 0;    
ay.Maximum = 100;  
ay.Interval = (ay.Maximum - ay.Minimum) / 10;

If your data values have a different range you should adapt these values!

So the number of spokes is (Maximum - Minimum) / Interval for the X-Axis. And the number of rings is the same but for the Y-Axis. To control both is is best to set them all and not rely on the default automatic setting!

If you want an empty center you should

  • include a buffer in the y-mimimum value or -1 or -2 intervals
  • make 1 or 2 rings more
  • draw a white circle over the center, which is a little tricky..

As an alternative you could add a dummy Datapoint to the center and style it:

int cc = s.Points.AddXY(0, ay.Minimum);
DataPoint dpc = s.Points[cc];
dpc.MarkerColor = Color.White;
dpc.MarkerSize = centerwidth;  // tricky!

To find the right size for centerwidth you would have to either test or, if you want scaling to work, do a measurement in a xxxPaint event; this goes beyond the scope of this answer..



回答2:

This is fairly easy to implement with GDI in winforms. Create a new UserControl, override the OnPaint functionality to:

  1. draw your circle (e.Graphics.DrawArc)
  2. draw the labels (e.Graphics.DrawString)
  3. draw the datapoints and lines (e.Graphics.DrawLine)

---------------- EDIT ------------------ Create a new UserControl: right click project -> add -> User Control

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
        }

        private void UserControl1_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.DrawEllipse(Pens.Blue, 0, 0, this.Width, this.Height);
            e.Graphics.DrawString("90", this.Font, Brushes.Black, new PointF(0, 0));
            e.Graphics.DrawLine(Pens.Red, 0,0, this.Width, this.Height );
        }
    }
}