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