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?

- 109
- 1
- 12
2 Answers
This is fairly easy to implement with GDI in winforms. Create a new UserControl, override the OnPaint functionality to:
- draw your circle (e.Graphics.DrawArc)
- draw the labels (e.Graphics.DrawString)
- 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 );
}
}
}

- 4,408
- 1
- 17
- 41
-
could you give me an example please or a source to one I dont know UserControl .... – Mr_Grennn7 Aug 14 '16 at 10:02
-
ok I added it but how to I call the Paint function? I added the usercontrol into the form but now i can only (in form) call a Paint event? – Mr_Grennn7 Aug 14 '16 at 10:29
-
Subscribe it to the user controls paint event. Any time the control needs to be redrawn this will fire. If you need to explicitly redraw call .Refresh() – FloatingKiwi Aug 14 '16 at 10:32
-
See here on [hooking up] (http://stackoverflow.com/questions/33275763/copy-datagridview-values-to-textbox/33276161?s=14|0.0000#33276161) events (which is 'subscribing' to them ;-) – TaW Aug 14 '16 at 10:43
-
Thank you so much. – Mr_Grennn7 Aug 14 '16 at 10:44
-
Ok sorry but what do i write into the event i can not call it like that userControl11_Paint(); – Mr_Grennn7 Aug 14 '16 at 10:46
-
Drawing the whole thing is rather tedious (read: not exactly 'faily easy') but will give ultimate control of the result, provided one is in command of the GDI drawing routines.. If pressed, I think I would try to go for Chart, maybe combining with a few GDI drawing to brush it up.. Still one up for the spirit. Btw: DoubleBuffering would be nice.. – TaW Aug 14 '16 at 10:47
-
The paint event is fired by the control as part of the winforms framework when it needs to be painted. You don't ever call it explicitly. Instead call either .Invalidate() or .Refresh() to make the window redraw itself. This in turn will call your Paint event handler. – FloatingKiwi Aug 14 '16 at 13:01
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..

- 53,122
- 8
- 69
- 111
-
Thank you so much. How would I have to change the parameters to look like the second picture in my post so 10 rings and 24 segments? – Mr_Grennn7 Aug 14 '16 at 10:27
-
This will depend on your values. For the spokes it is easy: They go from x-minimum=0 to x-maximum = 360 with an x-interval = 15. The rings are trickier. The are a bit hard to read, but it seems they are going inside out? And don't they all have quite different values ?? This is not such a simple thing to achieve. Is there some data-based logic to it or is it a chart that defines the data rather than displaying them? - Getting ten rings as such is not a problem with the above formula, but in the end you probably want all the labels to appear..?! – TaW Aug 14 '16 at 10:41
-
yes sorry i only need 10 rings the number in the pictures a irrelevant for the chart. – Mr_Grennn7 Aug 14 '16 at 10:42
-
Ah, ok then anything will do, as long as the range/10 = interval: y-minimum=0 to y-maximum = 100 with an y-interval = 10. But maybe you rather add one ring to make up for the crowded inner ring: maximum = 110 . I have added an example that is rotated, too. – TaW Aug 14 '16 at 12:30
-